mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-01 13:06:45 +00:00
[UI] API Context (#8851)
* Create ApiContext provider * Utilize new context * Remove api from global context * Refactor <InvenTreeTable> - No longer need hard-coded API constant * Refactor useInstance hook * Refactoring - QueryCountDatshboardWidget - NotesEditor - RenderInstance * Refactor multiple tables * Fix typos * Refactor useFilters hook - Allow plugins to use this hook! * Further refactoring * Refactor API forms * Cleanup context routing * Fix provision order
This commit is contained in:
parent
3a62bdd276
commit
296c54a1d7
@ -682,7 +682,7 @@ class PartSerializer(
|
|||||||
Used when displaying all details of a single component.
|
Used when displaying all details of a single component.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import_exclude_fields = ['duplicate']
|
import_exclude_fields = ['duplicate', 'tags']
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Metaclass defining serializer fields."""
|
"""Metaclass defining serializer fields."""
|
||||||
|
@ -4,7 +4,7 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { type ReactNode, useCallback } from 'react';
|
import { type ReactNode, useCallback } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { api } from '../../../App';
|
import { useApi } from '../../../contexts/ApiContext';
|
||||||
import type { ModelType } from '../../../enums/ModelType';
|
import type { ModelType } from '../../../enums/ModelType';
|
||||||
import {
|
import {
|
||||||
InvenTreeIcon,
|
InvenTreeIcon,
|
||||||
@ -31,6 +31,7 @@ function QueryCountWidget({
|
|||||||
icon?: InvenTreeIconType;
|
icon?: InvenTreeIconType;
|
||||||
params: any;
|
params: any;
|
||||||
}>): ReactNode {
|
}>): ReactNode {
|
||||||
|
const api = useApi();
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import { getValueAtPath } from 'mantine-datatable';
|
|||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { api } from '../../App';
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { formatDate } from '../../defaults/formatters';
|
import { formatDate } from '../../defaults/formatters';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import type { ModelType } from '../../enums/ModelType';
|
import type { ModelType } from '../../enums/ModelType';
|
||||||
@ -101,6 +101,8 @@ function NameBadge({
|
|||||||
pk,
|
pk,
|
||||||
type
|
type
|
||||||
}: Readonly<{ pk: string | number; type: BadgeType }>) {
|
}: Readonly<{ pk: string | number; type: BadgeType }>) {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
const { data } = useQuery({
|
const { data } = useQuery({
|
||||||
queryKey: ['badge', type, pk],
|
queryKey: ['badge', type, pk],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
@ -217,6 +219,7 @@ function BooleanValue(props: Readonly<FieldProps>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function TableAnchorValue(props: Readonly<FieldProps>) {
|
function TableAnchorValue(props: Readonly<FieldProps>) {
|
||||||
|
const api = useApi();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { data } = useQuery({
|
const { data } = useQuery({
|
||||||
|
@ -7,7 +7,7 @@ import 'easymde/dist/easymde.min.css';
|
|||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import SimpleMDE from 'react-simplemde-editor';
|
import SimpleMDE from 'react-simplemde-editor';
|
||||||
|
|
||||||
import { api } from '../../App';
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import type { ModelType } from '../../enums/ModelType';
|
import type { ModelType } from '../../enums/ModelType';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
@ -31,6 +31,7 @@ export default function NotesEditor({
|
|||||||
modelId: number;
|
modelId: number;
|
||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
// In addition to the editable prop, we also need to check if the user has "enabled" editing
|
// In addition to the editable prop, we also need to check if the user has "enabled" editing
|
||||||
const [editing, setEditing] = useState<boolean>(false);
|
const [editing, setEditing] = useState<boolean>(false);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { useId } from '@mantine/hooks';
|
import { useId } from '@mantine/hooks';
|
||||||
import { notifications } from '@mantine/notifications';
|
import { notifications } from '@mantine/notifications';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
type FieldValues,
|
type FieldValues,
|
||||||
@ -23,7 +23,7 @@ import {
|
|||||||
} from 'react-hook-form';
|
} from 'react-hook-form';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { api, queryClient } from '../../App';
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import type { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import type { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import type { ModelType } from '../../enums/ModelType';
|
import type { ModelType } from '../../enums/ModelType';
|
||||||
import {
|
import {
|
||||||
@ -110,6 +110,8 @@ export function OptionsApiForm({
|
|||||||
props: ApiFormProps;
|
props: ApiFormProps;
|
||||||
id?: string;
|
id?: string;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
const props = useMemo(
|
const props = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
..._props,
|
..._props,
|
||||||
@ -205,6 +207,8 @@ export function ApiForm({
|
|||||||
props: ApiFormProps;
|
props: ApiFormProps;
|
||||||
optionsLoading: boolean;
|
optionsLoading: boolean;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [fields, setFields] = useState<ApiFormFieldSet>(
|
const [fields, setFields] = useState<ApiFormFieldSet>(
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
useFormContext
|
useFormContext
|
||||||
} from 'react-hook-form';
|
} from 'react-hook-form';
|
||||||
|
|
||||||
import { api } from '../../../App';
|
import { useApi } from '../../../contexts/ApiContext';
|
||||||
import {
|
import {
|
||||||
constructField,
|
constructField,
|
||||||
extractAvailableFields
|
extractAvailableFields
|
||||||
@ -29,6 +29,7 @@ export function DependentField({
|
|||||||
url?: string;
|
url?: string;
|
||||||
setFields?: React.Dispatch<React.SetStateAction<ApiFormFieldSet>>;
|
setFields?: React.Dispatch<React.SetStateAction<ApiFormFieldSet>>;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
const { watch, resetField } = useFormContext();
|
const { watch, resetField } = useFormContext();
|
||||||
|
|
||||||
const mappedFieldNames = useMemo(
|
const mappedFieldNames = useMemo(
|
||||||
|
@ -15,7 +15,7 @@ import {
|
|||||||
} from 'react-hook-form';
|
} from 'react-hook-form';
|
||||||
import Select from 'react-select';
|
import Select from 'react-select';
|
||||||
|
|
||||||
import { api } from '../../../App';
|
import { useApi } from '../../../contexts/ApiContext';
|
||||||
import { vars } from '../../../theme';
|
import { vars } from '../../../theme';
|
||||||
import { RenderInstance } from '../../render/Instance';
|
import { RenderInstance } from '../../render/Instance';
|
||||||
import type { ApiFormFieldType } from './ApiFormField';
|
import type { ApiFormFieldType } from './ApiFormField';
|
||||||
@ -34,6 +34,7 @@ export function RelatedModelField({
|
|||||||
fieldName: string;
|
fieldName: string;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
const fieldId = useId();
|
const fieldId = useId();
|
||||||
const {
|
const {
|
||||||
field,
|
field,
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { api } from '../../App';
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { cancelEvent } from '../../functions/events';
|
import { cancelEvent } from '../../functions/events';
|
||||||
import {
|
import {
|
||||||
@ -131,6 +131,7 @@ export default function ImporterDataSelector({
|
|||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
session: ImportSessionState;
|
session: ImportSessionState;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
const table = useTable('dataimporter');
|
const table = useTable('dataimporter');
|
||||||
|
|
||||||
const [selectedFieldNames, setSelectedFieldNames] = useState<string[]>([]);
|
const [selectedFieldNames, setSelectedFieldNames] = useState<string[]>([]);
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
import { IconCheck } from '@tabler/icons-react';
|
import { IconCheck } from '@tabler/icons-react';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { api } from '../../App';
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import type { ImportSessionState } from '../../hooks/UseImportSession';
|
import type { ImportSessionState } from '../../hooks/UseImportSession';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
@ -24,6 +24,8 @@ function ImporterColumn({
|
|||||||
column,
|
column,
|
||||||
options
|
options
|
||||||
}: Readonly<{ column: any; options: any[] }>) {
|
}: Readonly<{ column: any; options: any[] }>) {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
const [errorMessage, setErrorMessage] = useState<string>('');
|
const [errorMessage, setErrorMessage] = useState<string>('');
|
||||||
|
|
||||||
const [selectedColumn, setSelectedColumn] = useState<string>(
|
const [selectedColumn, setSelectedColumn] = useState<string>(
|
||||||
@ -78,6 +80,8 @@ function ImporterDefaultField({
|
|||||||
fieldName: string;
|
fieldName: string;
|
||||||
session: ImportSessionState;
|
session: ImportSessionState;
|
||||||
}) {
|
}) {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(value: any) => {
|
(value: any) => {
|
||||||
// Update the default value for the field
|
// Update the default value for the field
|
||||||
@ -162,6 +166,8 @@ export default function ImporterColumnSelector({
|
|||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
session: ImportSessionState;
|
session: ImportSessionState;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
const [errorMessage, setErrorMessage] = useState<string>('');
|
const [errorMessage, setErrorMessage] = useState<string>('');
|
||||||
|
|
||||||
const acceptMapping = useCallback(() => {
|
const acceptMapping = useCallback(() => {
|
||||||
|
@ -21,7 +21,7 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { api } from '../../App';
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import type { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import type { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import type { ModelType } from '../../enums/ModelType';
|
import type { ModelType } from '../../enums/ModelType';
|
||||||
import { navigateToLink } from '../../functions/navigation';
|
import { navigateToLink } from '../../functions/navigation';
|
||||||
@ -48,6 +48,7 @@ export default function NavigationTree({
|
|||||||
modelType: ModelType;
|
modelType: ModelType;
|
||||||
endpoint: ApiEndpoints;
|
endpoint: ApiEndpoints;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const treeState = useTree();
|
const treeState = useTree();
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import { Alert, Anchor, Group, Skeleton, Space, Text } from '@mantine/core';
|
|||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { type ReactNode, useCallback } from 'react';
|
import { type ReactNode, useCallback } from 'react';
|
||||||
|
|
||||||
import { api } from '../../App';
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { navigateToLink } from '../../functions/navigation';
|
import { navigateToLink } from '../../functions/navigation';
|
||||||
import { shortenString } from '../../functions/tables';
|
import { shortenString } from '../../functions/tables';
|
||||||
@ -130,6 +130,8 @@ export function RenderRemoteInstance({
|
|||||||
model: ModelType;
|
model: ModelType;
|
||||||
pk: number;
|
pk: number;
|
||||||
}>): ReactNode {
|
}>): ReactNode {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
const { data, isLoading, isFetching } = useQuery({
|
const { data, isLoading, isFetching } = useQuery({
|
||||||
queryKey: ['model', model, pk],
|
queryKey: ['model', model, pk],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
@ -10,7 +10,7 @@ import React, {
|
|||||||
} from 'react';
|
} from 'react';
|
||||||
import { useStore } from 'zustand';
|
import { useStore } from 'zustand';
|
||||||
|
|
||||||
import { api } from '../../App';
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import type { ModelType } from '../../enums/ModelType';
|
import type { ModelType } from '../../enums/ModelType';
|
||||||
import { useEditApiFormModal } from '../../hooks/UseForm';
|
import { useEditApiFormModal } from '../../hooks/UseForm';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
@ -40,6 +40,8 @@ export function SettingList({
|
|||||||
settingsState.fetchSettings();
|
settingsState.fetchSettings();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
const allKeys = useMemo(
|
const allKeys = useMemo(
|
||||||
() => settingsState?.settings?.map((s) => s.key) ?? [],
|
() => settingsState?.settings?.map((s) => s.key) ?? [],
|
||||||
[settingsState?.settings]
|
[settingsState?.settings]
|
||||||
|
31
src/frontend/src/contexts/ApiContext.tsx
Normal file
31
src/frontend/src/contexts/ApiContext.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { type QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
|
import type { AxiosInstance } from 'axios';
|
||||||
|
import { createContext, useContext } from 'react';
|
||||||
|
|
||||||
|
const ApiContext = createContext<AxiosInstance | null>(null);
|
||||||
|
|
||||||
|
export const ApiProvider = ({
|
||||||
|
api,
|
||||||
|
client,
|
||||||
|
children
|
||||||
|
}: {
|
||||||
|
api: AxiosInstance;
|
||||||
|
client: QueryClient;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<QueryClientProvider client={client}>
|
||||||
|
<ApiContext.Provider value={api}>{children}</ApiContext.Provider>
|
||||||
|
</QueryClientProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useApi = () => {
|
||||||
|
const context = useContext(ApiContext);
|
||||||
|
|
||||||
|
if (!context) {
|
||||||
|
throw new Error('useApi must be used within an ApiProvider');
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
};
|
@ -1,12 +0,0 @@
|
|||||||
import { QueryClientProvider } from '@tanstack/react-query';
|
|
||||||
|
|
||||||
import { queryClient } from '../App';
|
|
||||||
import { ThemeContext } from './ThemeContext';
|
|
||||||
|
|
||||||
export const BaseContext = ({ children }: { children: any }) => {
|
|
||||||
return (
|
|
||||||
<QueryClientProvider client={queryClient}>
|
|
||||||
<ThemeContext>{children}</ThemeContext>
|
|
||||||
</QueryClientProvider>
|
|
||||||
);
|
|
||||||
};
|
|
@ -2,8 +2,8 @@ import { t } from '@lingui/macro';
|
|||||||
import { IconPackages } from '@tabler/icons-react';
|
import { IconPackages } from '@tabler/icons-react';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { api } from '../App';
|
|
||||||
import type { ApiFormFieldSet } from '../components/forms/fields/ApiFormField';
|
import type { ApiFormFieldSet } from '../components/forms/fields/ApiFormField';
|
||||||
|
import { useApi } from '../contexts/ApiContext';
|
||||||
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||||
import { apiUrl } from '../states/ApiState';
|
import { apiUrl } from '../states/ApiState';
|
||||||
import { useGlobalSettingsState } from '../states/SettingsState';
|
import { useGlobalSettingsState } from '../states/SettingsState';
|
||||||
@ -179,6 +179,8 @@ export function usePartParameterFields({
|
|||||||
}: {
|
}: {
|
||||||
editTemplate?: boolean;
|
editTemplate?: boolean;
|
||||||
}): ApiFormFieldSet {
|
}): ApiFormFieldSet {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
// Valid field choices
|
// Valid field choices
|
||||||
const [choices, setChoices] = useState<any[]>([]);
|
const [choices, setChoices] = useState<any[]>([]);
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import { api } from '../App';
|
import { useApi } from '../contexts/ApiContext';
|
||||||
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||||
import { resolveItem } from '../functions/conversion';
|
import { resolveItem } from '../functions/conversion';
|
||||||
import { apiUrl } from '../states/ApiState';
|
import { apiUrl } from '../states/ApiState';
|
||||||
@ -20,6 +20,8 @@ type UseFilterProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function useFilters(props: UseFilterProps) {
|
export function useFilters(props: UseFilterProps) {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
enabled: true,
|
enabled: true,
|
||||||
gcTime: 500,
|
gcTime: 500,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { type QueryObserverResult, useQuery } from '@tanstack/react-query';
|
import { type QueryObserverResult, useQuery } from '@tanstack/react-query';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { api } from '../App';
|
import { useApi } from '../contexts/ApiContext';
|
||||||
import type { ApiEndpoints } from '../enums/ApiEndpoints';
|
import type { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||||
import { type PathParams, apiUrl } from '../states/ApiState';
|
import { type PathParams, apiUrl } from '../states/ApiState';
|
||||||
|
|
||||||
@ -48,6 +48,8 @@ export function useInstance<T = any>({
|
|||||||
throwError?: boolean;
|
throwError?: boolean;
|
||||||
updateInterval?: number;
|
updateInterval?: number;
|
||||||
}): UseInstanceResult {
|
}): UseInstanceResult {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
const [instance, setInstance] = useState<T | undefined>(defaultValue);
|
const [instance, setInstance] = useState<T | undefined>(defaultValue);
|
||||||
|
|
||||||
const [requestStatus, setRequestStatus] = useState<number>(0);
|
const [requestStatus, setRequestStatus] = useState<number>(0);
|
||||||
|
@ -12,7 +12,6 @@ import ReactDOM from 'react-dom/client';
|
|||||||
import 'react-grid-layout/css/styles.css';
|
import 'react-grid-layout/css/styles.css';
|
||||||
import 'react-resizable/css/styles.css';
|
import 'react-resizable/css/styles.css';
|
||||||
|
|
||||||
import { api } from './App';
|
|
||||||
import type { HostList } from './states/states';
|
import type { HostList } from './states/states';
|
||||||
import MainView from './views/MainView';
|
import MainView from './views/MainView';
|
||||||
|
|
||||||
@ -27,7 +26,6 @@ declare global {
|
|||||||
sentry_dsn?: string;
|
sentry_dsn?: string;
|
||||||
environment?: string;
|
environment?: string;
|
||||||
};
|
};
|
||||||
InvenTreeAPI: typeof api;
|
|
||||||
React: typeof React;
|
React: typeof React;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,4 +103,3 @@ if (window.location.pathname === '/') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.React = React;
|
window.React = React;
|
||||||
window.InvenTreeAPI = api;
|
|
||||||
|
@ -11,16 +11,17 @@ import {
|
|||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import { api } from '../App';
|
|
||||||
import { ActionButton } from '../components/buttons/ActionButton';
|
import { ActionButton } from '../components/buttons/ActionButton';
|
||||||
import { PageDetail } from '../components/nav/PageDetail';
|
import { PageDetail } from '../components/nav/PageDetail';
|
||||||
import { PanelGroup } from '../components/panels/PanelGroup';
|
import { PanelGroup } from '../components/panels/PanelGroup';
|
||||||
|
import { useApi } from '../contexts/ApiContext';
|
||||||
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||||
import { useTable } from '../hooks/UseTable';
|
import { useTable } from '../hooks/UseTable';
|
||||||
import { apiUrl } from '../states/ApiState';
|
import { apiUrl } from '../states/ApiState';
|
||||||
import { NotificationTable } from '../tables/notifications/NotificationTable';
|
import { NotificationTable } from '../tables/notifications/NotificationTable';
|
||||||
|
|
||||||
export default function NotificationsPage() {
|
export default function NotificationsPage() {
|
||||||
|
const api = useApi();
|
||||||
const unreadTable = useTable('unreadnotifications');
|
const unreadTable = useTable('unreadnotifications');
|
||||||
const readTable = useTable('readnotifications');
|
const readTable = useTable('readnotifications');
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@ import { type ReactNode, useMemo, useState } from 'react';
|
|||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import Select from 'react-select';
|
import Select from 'react-select';
|
||||||
|
|
||||||
import { api } from '../../App';
|
|
||||||
import AdminButton from '../../components/buttons/AdminButton';
|
import AdminButton from '../../components/buttons/AdminButton';
|
||||||
import { PrintingActions } from '../../components/buttons/PrintingActions';
|
import { PrintingActions } from '../../components/buttons/PrintingActions';
|
||||||
import {
|
import {
|
||||||
@ -63,6 +62,7 @@ import type { PanelType } from '../../components/panels/Panel';
|
|||||||
import { PanelGroup } from '../../components/panels/PanelGroup';
|
import { PanelGroup } from '../../components/panels/PanelGroup';
|
||||||
import { RenderPart } from '../../components/render/Part';
|
import { RenderPart } from '../../components/render/Part';
|
||||||
import OrderPartsWizard from '../../components/wizards/OrderPartsWizard';
|
import OrderPartsWizard from '../../components/wizards/OrderPartsWizard';
|
||||||
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { formatPriceRange } from '../../defaults/formatters';
|
import { formatPriceRange } from '../../defaults/formatters';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
@ -110,6 +110,7 @@ import PartSupplierDetail from './PartSupplierDetail';
|
|||||||
export default function PartDetail() {
|
export default function PartDetail() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
|
||||||
|
const api = useApi();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { type ReactNode, useMemo, useState } from 'react';
|
import { type ReactNode, useMemo, useState } from 'react';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { api } from '../../App';
|
|
||||||
import AdminButton from '../../components/buttons/AdminButton';
|
import AdminButton from '../../components/buttons/AdminButton';
|
||||||
import { PrintingActions } from '../../components/buttons/PrintingActions';
|
import { PrintingActions } from '../../components/buttons/PrintingActions';
|
||||||
import {
|
import {
|
||||||
@ -43,6 +42,7 @@ import { PanelGroup } from '../../components/panels/PanelGroup';
|
|||||||
import LocateItemButton from '../../components/plugins/LocateItemButton';
|
import LocateItemButton from '../../components/plugins/LocateItemButton';
|
||||||
import { StatusRenderer } from '../../components/render/StatusRenderer';
|
import { StatusRenderer } from '../../components/render/StatusRenderer';
|
||||||
import OrderPartsWizard from '../../components/wizards/OrderPartsWizard';
|
import OrderPartsWizard from '../../components/wizards/OrderPartsWizard';
|
||||||
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { formatCurrency } from '../../defaults/formatters';
|
import { formatCurrency } from '../../defaults/formatters';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
@ -78,6 +78,7 @@ import { StockTrackingTable } from '../../tables/stock/StockTrackingTable';
|
|||||||
export default function StockDetail() {
|
export default function StockDetail() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
|
||||||
|
const api = useApi();
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
const globalSettings = useGlobalSettingsState();
|
const globalSettings = useGlobalSettingsState();
|
||||||
@ -377,7 +378,7 @@ export default function StockDetail() {
|
|||||||
); // Must not be installed into another item
|
); // Must not be installed into another item
|
||||||
}, [stockitem]);
|
}, [stockitem]);
|
||||||
|
|
||||||
const showSalesAlloctions: boolean = useMemo(() => {
|
const showSalesAllocations: boolean = useMemo(() => {
|
||||||
return stockitem?.part_detail?.salable;
|
return stockitem?.part_detail?.salable;
|
||||||
}, [stockitem]);
|
}, [stockitem]);
|
||||||
|
|
||||||
@ -452,14 +453,14 @@ export default function StockDetail() {
|
|||||||
icon: <IconBookmark />,
|
icon: <IconBookmark />,
|
||||||
hidden:
|
hidden:
|
||||||
!stockitem.in_stock ||
|
!stockitem.in_stock ||
|
||||||
(!showSalesAlloctions && !showBuildAllocations),
|
(!showSalesAllocations && !showBuildAllocations),
|
||||||
content: (
|
content: (
|
||||||
<Accordion
|
<Accordion
|
||||||
multiple={true}
|
multiple={true}
|
||||||
defaultValue={['buildallocations', 'salesallocations']}
|
defaultValue={['buildAllocations', 'salesAllocations']}
|
||||||
>
|
>
|
||||||
{showBuildAllocations && (
|
{showBuildAllocations && (
|
||||||
<Accordion.Item value='buildallocations' key='buildallocations'>
|
<Accordion.Item value='buildAllocations' key='buildAllocations'>
|
||||||
<Accordion.Control>
|
<Accordion.Control>
|
||||||
<StylishText size='lg'>{t`Build Order Allocations`}</StylishText>
|
<StylishText size='lg'>{t`Build Order Allocations`}</StylishText>
|
||||||
</Accordion.Control>
|
</Accordion.Control>
|
||||||
@ -473,8 +474,8 @@ export default function StockDetail() {
|
|||||||
</Accordion.Panel>
|
</Accordion.Panel>
|
||||||
</Accordion.Item>
|
</Accordion.Item>
|
||||||
)}
|
)}
|
||||||
{showSalesAlloctions && (
|
{showSalesAllocations && (
|
||||||
<Accordion.Item value='salesallocations' key='salesallocations'>
|
<Accordion.Item value='salesAllocations' key='salesAllocations'>
|
||||||
<Accordion.Control>
|
<Accordion.Control>
|
||||||
<StylishText size='lg'>{t`Sales Order Allocations`}</StylishText>
|
<StylishText size='lg'>{t`Sales Order Allocations`}</StylishText>
|
||||||
</Accordion.Control>
|
</Accordion.Control>
|
||||||
@ -536,7 +537,7 @@ export default function StockDetail() {
|
|||||||
})
|
})
|
||||||
];
|
];
|
||||||
}, [
|
}, [
|
||||||
showSalesAlloctions,
|
showSalesAllocations,
|
||||||
showBuildAllocations,
|
showBuildAllocations,
|
||||||
showInstalledItems,
|
showInstalledItems,
|
||||||
stockitem,
|
stockitem,
|
||||||
|
@ -13,9 +13,9 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { showNotification } from '@mantine/notifications';
|
import { showNotification } from '@mantine/notifications';
|
||||||
import { api } from '../App';
|
|
||||||
import { Boundary } from '../components/Boundary';
|
import { Boundary } from '../components/Boundary';
|
||||||
import type { ApiFormFieldSet } from '../components/forms/fields/ApiFormField';
|
import type { ApiFormFieldSet } from '../components/forms/fields/ApiFormField';
|
||||||
|
import { useApi } from '../contexts/ApiContext';
|
||||||
import type { ModelType } from '../enums/ModelType';
|
import type { ModelType } from '../enums/ModelType';
|
||||||
import { resolveItem } from '../functions/conversion';
|
import { resolveItem } from '../functions/conversion';
|
||||||
import { cancelEvent } from '../functions/events';
|
import { cancelEvent } from '../functions/events';
|
||||||
@ -139,6 +139,7 @@ export function InvenTreeTable<T extends Record<string, any>>({
|
|||||||
|
|
||||||
const [fieldNames, setFieldNames] = useState<Record<string, string>>({});
|
const [fieldNames, setFieldNames] = useState<Record<string, string>>({});
|
||||||
|
|
||||||
|
const api = useApi();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { showContextMenu } = useContextMenu();
|
const { showContextMenu } = useContextMenu();
|
||||||
|
|
||||||
|
@ -16,11 +16,11 @@ import {
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Fragment } from 'react/jsx-runtime';
|
import { Fragment } from 'react/jsx-runtime';
|
||||||
|
|
||||||
import { api } from '../App';
|
|
||||||
import { Boundary } from '../components/Boundary';
|
import { Boundary } from '../components/Boundary';
|
||||||
import { ActionButton } from '../components/buttons/ActionButton';
|
import { ActionButton } from '../components/buttons/ActionButton';
|
||||||
import { ButtonMenu } from '../components/buttons/ButtonMenu';
|
import { ButtonMenu } from '../components/buttons/ButtonMenu';
|
||||||
import { PrintingActions } from '../components/buttons/PrintingActions';
|
import { PrintingActions } from '../components/buttons/PrintingActions';
|
||||||
|
import { useApi } from '../contexts/ApiContext';
|
||||||
import { useDeleteApiFormModal } from '../hooks/UseForm';
|
import { useDeleteApiFormModal } from '../hooks/UseForm';
|
||||||
import type { TableState } from '../hooks/UseTable';
|
import type { TableState } from '../hooks/UseTable';
|
||||||
import { TableColumnSelect } from './ColumnSelect';
|
import { TableColumnSelect } from './ColumnSelect';
|
||||||
@ -50,6 +50,8 @@ export default function InvenTreeTableHeader({
|
|||||||
filters: TableFilter[];
|
filters: TableFilter[];
|
||||||
toggleColumn: (column: string) => void;
|
toggleColumn: (column: string) => void;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
// Filter list visibility
|
// Filter list visibility
|
||||||
const [filtersVisible, setFiltersVisible] = useState<boolean>(false);
|
const [filtersVisible, setFiltersVisible] = useState<boolean>(false);
|
||||||
|
|
||||||
|
@ -11,12 +11,12 @@ import {
|
|||||||
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { api } from '../../App';
|
|
||||||
import { ActionButton } from '../../components/buttons/ActionButton';
|
import { ActionButton } from '../../components/buttons/ActionButton';
|
||||||
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
||||||
import { YesNoButton } from '../../components/buttons/YesNoButton';
|
import { YesNoButton } from '../../components/buttons/YesNoButton';
|
||||||
import { Thumbnail } from '../../components/images/Thumbnail';
|
import { Thumbnail } from '../../components/images/Thumbnail';
|
||||||
import ImporterDrawer from '../../components/importer/ImporterDrawer';
|
import ImporterDrawer from '../../components/importer/ImporterDrawer';
|
||||||
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { formatDecimal, formatPriceRange } from '../../defaults/formatters';
|
import { formatDecimal, formatPriceRange } from '../../defaults/formatters';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
@ -71,6 +71,7 @@ export function BomTable({
|
|||||||
partLocked?: boolean;
|
partLocked?: boolean;
|
||||||
params?: any;
|
params?: any;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const table = useTable('bom');
|
const table = useTable('bom');
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
@ -10,10 +10,10 @@ import {
|
|||||||
useState
|
useState
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { api } from '../../App';
|
|
||||||
import { PassFailButton } from '../../components/buttons/YesNoButton';
|
import { PassFailButton } from '../../components/buttons/YesNoButton';
|
||||||
import type { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
|
import type { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
|
||||||
import { RenderUser } from '../../components/render/User';
|
import { RenderUser } from '../../components/render/User';
|
||||||
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { formatDate } from '../../defaults/formatters';
|
import { formatDate } from '../../defaults/formatters';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { useTestResultFields } from '../../forms/StockForms';
|
import { useTestResultFields } from '../../forms/StockForms';
|
||||||
@ -40,6 +40,7 @@ export default function BuildOrderTestTable({
|
|||||||
}>) {
|
}>) {
|
||||||
const table = useTable('build-tests');
|
const table = useTable('build-tests');
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
// Fetch the test templates required for this build order
|
// Fetch the test templates required for this build order
|
||||||
const { data: testTemplates } = useQuery({
|
const { data: testTemplates } = useQuery({
|
||||||
|
@ -18,11 +18,11 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { api } from '../../App';
|
|
||||||
import { ActionButton } from '../../components/buttons/ActionButton';
|
import { ActionButton } from '../../components/buttons/ActionButton';
|
||||||
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
||||||
import { ProgressBar } from '../../components/items/ProgressBar';
|
import { ProgressBar } from '../../components/items/ProgressBar';
|
||||||
import { StylishText } from '../../components/items/StylishText';
|
import { StylishText } from '../../components/items/StylishText';
|
||||||
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
@ -121,6 +121,7 @@ export default function BuildOutputTable({
|
|||||||
build,
|
build,
|
||||||
refreshBuild
|
refreshBuild
|
||||||
}: Readonly<{ build: any; refreshBuild: () => void }>) {
|
}: Readonly<{ build: any; refreshBuild: () => void }>) {
|
||||||
|
const api = useApi();
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const table = useTable('build-outputs');
|
const table = useTable('build-outputs');
|
||||||
|
@ -10,10 +10,10 @@ import {
|
|||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { api } from '../../App';
|
|
||||||
import { ActionButton } from '../../components/buttons/ActionButton';
|
import { ActionButton } from '../../components/buttons/ActionButton';
|
||||||
import type { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
|
import type { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
|
||||||
import { AttachmentLink } from '../../components/items/AttachmentLink';
|
import { AttachmentLink } from '../../components/items/AttachmentLink';
|
||||||
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { formatFileSize } from '../../defaults/formatters';
|
import { formatFileSize } from '../../defaults/formatters';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import type { ModelType } from '../../enums/ModelType';
|
import type { ModelType } from '../../enums/ModelType';
|
||||||
@ -99,6 +99,7 @@ export function AttachmentTable({
|
|||||||
model_type: ModelType;
|
model_type: ModelType;
|
||||||
model_id: number;
|
model_id: number;
|
||||||
}>): ReactNode {
|
}>): ReactNode {
|
||||||
|
const api = useApi();
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const table = useTable(`${model_type}-attachments`);
|
const table = useTable(`${model_type}-attachments`);
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { api } from '../../App';
|
|
||||||
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
||||||
import { YesNoButton } from '../../components/buttons/YesNoButton';
|
import { YesNoButton } from '../../components/buttons/YesNoButton';
|
||||||
import {
|
import {
|
||||||
@ -40,6 +39,7 @@ import {
|
|||||||
TableStatusRenderer
|
TableStatusRenderer
|
||||||
} from '../../components/render/StatusRenderer';
|
} from '../../components/render/StatusRenderer';
|
||||||
import { MachineSettingList } from '../../components/settings/SettingList';
|
import { MachineSettingList } from '../../components/settings/SettingList';
|
||||||
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import {
|
import {
|
||||||
useCreateApiFormModal,
|
useCreateApiFormModal,
|
||||||
@ -103,6 +103,8 @@ export function useMachineTypeDriver({
|
|||||||
includeTypes = true,
|
includeTypes = true,
|
||||||
includeDrivers = true
|
includeDrivers = true
|
||||||
}: { includeTypes?: boolean; includeDrivers?: boolean } = {}) {
|
}: { includeTypes?: boolean; includeDrivers?: boolean } = {}) {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: machineTypes,
|
data: machineTypes,
|
||||||
isFetching: isMachineTypesFetching,
|
isFetching: isMachineTypesFetching,
|
||||||
@ -146,6 +148,7 @@ function MachineDrawer({
|
|||||||
machinePk: string;
|
machinePk: string;
|
||||||
refreshTable: () => void;
|
refreshTable: () => void;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const {
|
const {
|
||||||
data: machine,
|
data: machine,
|
||||||
|
@ -5,9 +5,9 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { api } from '../../App';
|
|
||||||
import { YesNoButton } from '../../components/buttons/YesNoButton';
|
import { YesNoButton } from '../../components/buttons/YesNoButton';
|
||||||
import type { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
|
import type { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
|
||||||
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { formatDecimal } from '../../defaults/formatters';
|
import { formatDecimal } from '../../defaults/formatters';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
@ -95,11 +95,12 @@ export default function ParametricPartTable({
|
|||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
categoryId?: any;
|
categoryId?: any;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
const table = useTable('parametric-parts');
|
const table = useTable('parametric-parts');
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const categoryParmeters = useQuery({
|
const categoryParameters = useQuery({
|
||||||
queryKey: ['category-parameters', categoryId],
|
queryKey: ['category-parameters', categoryId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
return api
|
return api
|
||||||
@ -170,13 +171,13 @@ export default function ParametricPartTable({
|
|||||||
records[partIndex].parameters[parameterIndex] = parameter;
|
records[partIndex].parameters[parameterIndex] = parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.setRecords(records);
|
table.updateRecord(records[partIndex]);
|
||||||
},
|
},
|
||||||
[table.records]
|
[table.updateRecord]
|
||||||
);
|
);
|
||||||
|
|
||||||
const parameterColumns: TableColumn[] = useMemo(() => {
|
const parameterColumns: TableColumn[] = useMemo(() => {
|
||||||
const data = categoryParmeters.data ?? [];
|
const data = categoryParameters.data ?? [];
|
||||||
|
|
||||||
return data.map((template: any) => {
|
return data.map((template: any) => {
|
||||||
let title = template.name;
|
let title = template.name;
|
||||||
@ -201,7 +202,7 @@ export default function ParametricPartTable({
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}, [user, categoryParmeters.data]);
|
}, [user, categoryParameters.data]);
|
||||||
|
|
||||||
const onParameterClick = useCallback((template: number, part: any) => {
|
const onParameterClick = useCallback((template: number, part: any) => {
|
||||||
setSelectedTemplate(template);
|
setSelectedTemplate(template);
|
||||||
|
@ -13,12 +13,12 @@ import {
|
|||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { api } from '../../App';
|
|
||||||
import { ActionButton } from '../../components/buttons/ActionButton';
|
import { ActionButton } from '../../components/buttons/ActionButton';
|
||||||
import { YesNoButton } from '../../components/buttons/YesNoButton';
|
import { YesNoButton } from '../../components/buttons/YesNoButton';
|
||||||
import { DetailDrawer } from '../../components/nav/DetailDrawer';
|
import { DetailDrawer } from '../../components/nav/DetailDrawer';
|
||||||
import PluginDrawer from '../../components/plugins/PluginDrawer';
|
import PluginDrawer from '../../components/plugins/PluginDrawer';
|
||||||
import type { PluginInterface } from '../../components/plugins/PluginInterface';
|
import type { PluginInterface } from '../../components/plugins/PluginInterface';
|
||||||
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import {
|
import {
|
||||||
useCreateApiFormModal,
|
useCreateApiFormModal,
|
||||||
@ -63,6 +63,7 @@ function PluginIcon({ plugin }: Readonly<{ plugin: PluginInterface }>) {
|
|||||||
* Table displaying list of available plugins
|
* Table displaying list of available plugins
|
||||||
*/
|
*/
|
||||||
export default function PluginListTable() {
|
export default function PluginListTable() {
|
||||||
|
const api = useApi();
|
||||||
const table = useTable('plugin');
|
const table = useTable('plugin');
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
@ -10,12 +10,12 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { DataTable } from 'mantine-datatable';
|
import { DataTable } from 'mantine-datatable';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { api } from '../../App';
|
|
||||||
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
||||||
import { PassFailButton } from '../../components/buttons/YesNoButton';
|
import { PassFailButton } from '../../components/buttons/YesNoButton';
|
||||||
import type { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
|
import type { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
|
||||||
import { AttachmentLink } from '../../components/items/AttachmentLink';
|
import { AttachmentLink } from '../../components/items/AttachmentLink';
|
||||||
import { RenderUser } from '../../components/render/User';
|
import { RenderUser } from '../../components/render/User';
|
||||||
|
import { useApi } from '../../contexts/ApiContext';
|
||||||
import { formatDate } from '../../defaults/formatters';
|
import { formatDate } from '../../defaults/formatters';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
@ -47,6 +47,7 @@ export default function StockItemTestResultTable({
|
|||||||
partId: number;
|
partId: number;
|
||||||
itemId: number;
|
itemId: number;
|
||||||
}>) {
|
}>) {
|
||||||
|
const api = useApi();
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const table = useTable('stocktests');
|
const table = useTable('stocktests');
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { QueryClientProvider } from '@tanstack/react-query';
|
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import { queryClient } from '../App';
|
import { api, queryClient } from '../App';
|
||||||
import { BaseContext } from '../contexts/BaseContext';
|
import { ApiProvider } from '../contexts/ApiContext';
|
||||||
|
import { ThemeContext } from '../contexts/ThemeContext';
|
||||||
import { defaultHostList } from '../defaults/defaultHostList';
|
import { defaultHostList } from '../defaults/defaultHostList';
|
||||||
import { base_url } from '../main';
|
import { base_url } from '../main';
|
||||||
import { routes } from '../router';
|
import { routes } from '../router';
|
||||||
@ -19,10 +19,10 @@ export default function DesktopAppView() {
|
|||||||
}, [hostList]);
|
}, [hostList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseContext>
|
<ApiProvider client={queryClient} api={api}>
|
||||||
<QueryClientProvider client={queryClient}>
|
<ThemeContext>
|
||||||
<BrowserRouter basename={base_url}>{routes}</BrowserRouter>
|
<BrowserRouter basename={base_url}>{routes}</BrowserRouter>
|
||||||
</QueryClientProvider>
|
</ThemeContext>
|
||||||
</BaseContext>
|
</ApiProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Trans } from '@lingui/macro';
|
import { Trans } from '@lingui/macro';
|
||||||
import { Anchor, Center, Container, Stack, Text, Title } from '@mantine/core';
|
import { Anchor, Center, Container, Stack, Text, Title } from '@mantine/core';
|
||||||
|
|
||||||
import { BaseContext } from '../contexts/BaseContext';
|
import { ThemeContext } from '../contexts/ThemeContext';
|
||||||
import { docLinks } from '../defaults/links';
|
import { docLinks } from '../defaults/links';
|
||||||
import { IS_DEV } from '../main';
|
import { IS_DEV } from '../main';
|
||||||
import { useLocalState } from '../states/LocalState';
|
import { useLocalState } from '../states/LocalState';
|
||||||
@ -14,7 +14,7 @@ export default function MobileAppView() {
|
|||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<BaseContext>
|
<ThemeContext>
|
||||||
<Center h='100vh'>
|
<Center h='100vh'>
|
||||||
<Container>
|
<Container>
|
||||||
<Stack>
|
<Stack>
|
||||||
@ -38,6 +38,6 @@ export default function MobileAppView() {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Container>
|
</Container>
|
||||||
</Center>
|
</Center>
|
||||||
</BaseContext>
|
</ThemeContext>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user