mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-17 12:35:46 +00:00
Fix machine request pickeling and settings (#6772)
* Fix machine request pickeling * fix precommit * fix: shared state between workers and main thread for machine registry * remove last usage of legacy PUI form framework to fix machine edit/delete modal * reset cache before initialization * update documentation * fix: invalidating cache * implement machine registry hash to check if a reload is required * trigger: ci * fix: request bug * fix: test * trigger: ci * add clear errors and improve restart hook * auto initialize not initialized machines when changing active state * fix: tests
This commit is contained in:
@ -1,20 +1,12 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { Divider, Stack } from '@mantine/core';
|
||||
import { modals } from '@mantine/modals';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { AxiosResponse } from 'axios';
|
||||
|
||||
import { api } from '../App';
|
||||
import { ApiForm, ApiFormProps } from '../components/forms/ApiForm';
|
||||
import {
|
||||
ApiFormFieldSet,
|
||||
ApiFormFieldType
|
||||
} from '../components/forms/fields/ApiFormField';
|
||||
import { StylishText } from '../components/items/StylishText';
|
||||
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||
import { PathParams, apiUrl } from '../states/ApiState';
|
||||
import { invalidResponse, permissionDenied } from './notifications';
|
||||
import { generateUniqueId } from './uid';
|
||||
|
||||
/**
|
||||
* Construct an API url from the provided ApiFormProps object
|
||||
@ -180,143 +172,3 @@ export function constructField({
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
export interface OpenApiFormProps extends ApiFormProps {
|
||||
title: string;
|
||||
cancelText?: string;
|
||||
cancelColor?: string;
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct and open a modal form
|
||||
* @param title :
|
||||
*/
|
||||
export function openModalApiForm(props: OpenApiFormProps) {
|
||||
// method property *must* be supplied
|
||||
if (!props.method) {
|
||||
notifications.show({
|
||||
title: t`Invalid Form`,
|
||||
message: t`method parameter not supplied`,
|
||||
color: 'red'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate a random modal ID for controller
|
||||
let modalId: string =
|
||||
`modal-${props.title}-${props.url}-${props.method}` + generateUniqueId();
|
||||
|
||||
props.actions = [
|
||||
...(props.actions || []),
|
||||
{
|
||||
text: props.cancelText ?? t`Cancel`,
|
||||
color: props.cancelColor ?? 'blue',
|
||||
onClick: () => {
|
||||
modals.close(modalId);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const oldFormSuccess = props.onFormSuccess;
|
||||
props.onFormSuccess = (data) => {
|
||||
oldFormSuccess?.(data);
|
||||
modals.close(modalId);
|
||||
};
|
||||
|
||||
let url = constructFormUrl(props.url, props.pk, props.pathParams);
|
||||
|
||||
// Make OPTIONS request first
|
||||
api
|
||||
.options(url)
|
||||
.then((response) => {
|
||||
// Extract available fields from the OPTIONS response (and handle any errors)
|
||||
|
||||
let fields: Record<string, ApiFormFieldType> | null = {};
|
||||
|
||||
if (!props.ignorePermissionCheck) {
|
||||
fields = extractAvailableFields(response, props.method);
|
||||
|
||||
if (fields == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const _props = { ...props };
|
||||
|
||||
if (_props.fields) {
|
||||
for (const [k, v] of Object.entries(_props.fields)) {
|
||||
_props.fields[k] = constructField({
|
||||
field: v,
|
||||
definition: fields?.[k]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
modals.open({
|
||||
title: <StylishText size="xl">{props.title}</StylishText>,
|
||||
modalId: modalId,
|
||||
size: 'xl',
|
||||
onClose: () => {
|
||||
props.onClose ? props.onClose() : null;
|
||||
},
|
||||
children: (
|
||||
<Stack gap={'xs'}>
|
||||
<Divider />
|
||||
<ApiForm id={modalId} props={props} optionsLoading={false} />
|
||||
</Stack>
|
||||
)
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.response) {
|
||||
invalidResponse(error.response.status);
|
||||
} else {
|
||||
notifications.show({
|
||||
title: t`Form Error`,
|
||||
message: error.message,
|
||||
color: 'red'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a modal form to create a new model instance
|
||||
*/
|
||||
export function openCreateApiForm(props: OpenApiFormProps) {
|
||||
let createProps: OpenApiFormProps = {
|
||||
...props,
|
||||
method: 'POST'
|
||||
};
|
||||
|
||||
openModalApiForm(createProps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a modal form to edit a model instance
|
||||
*/
|
||||
export function openEditApiForm(props: OpenApiFormProps) {
|
||||
let editProps: OpenApiFormProps = {
|
||||
...props,
|
||||
fetchInitialData: props.fetchInitialData ?? true,
|
||||
method: 'PATCH'
|
||||
};
|
||||
|
||||
openModalApiForm(editProps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a modal form to delete a model instancel
|
||||
*/
|
||||
export function openDeleteApiForm(props: OpenApiFormProps) {
|
||||
let deleteProps: OpenApiFormProps = {
|
||||
...props,
|
||||
method: 'DELETE',
|
||||
submitText: t`Delete`,
|
||||
submitColor: 'red',
|
||||
fields: {}
|
||||
};
|
||||
|
||||
openModalApiForm(deleteProps);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import '@mantine/carousel/styles.css';
|
||||
import '@mantine/charts/styles.css';
|
||||
import '@mantine/core/styles.css';
|
||||
import '@mantine/dates/styles.css';
|
||||
import '@mantine/notifications/styles.css';
|
||||
import '@mantine/spotlight/styles.css';
|
||||
import * as Sentry from '@sentry/react';
|
||||
|
@ -41,8 +41,11 @@ import {
|
||||
} from '../../components/render/StatusRenderer';
|
||||
import { MachineSettingList } from '../../components/settings/SettingList';
|
||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||
import { openDeleteApiForm, openEditApiForm } from '../../functions/forms';
|
||||
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
||||
import {
|
||||
useCreateApiFormModal,
|
||||
useDeleteApiFormModal,
|
||||
useEditApiFormModal
|
||||
} from '../../hooks/UseForm';
|
||||
import { useTable } from '../../hooks/UseTable';
|
||||
import { apiUrl } from '../../states/ApiState';
|
||||
import { TableColumn } from '../Column';
|
||||
@ -205,8 +208,39 @@ function MachineDrawer({
|
||||
[refreshAll]
|
||||
);
|
||||
|
||||
const machineEditModal = useEditApiFormModal({
|
||||
title: t`Edit machine`,
|
||||
url: ApiEndpoints.machine_list,
|
||||
pk: machinePk,
|
||||
fields: useMemo(
|
||||
() => ({
|
||||
name: {},
|
||||
active: {}
|
||||
}),
|
||||
[]
|
||||
),
|
||||
onClose: () => refreshAll()
|
||||
});
|
||||
|
||||
const machineDeleteModal = useDeleteApiFormModal({
|
||||
title: t`Delete machine`,
|
||||
successMessage: t`Machine successfully deleted.`,
|
||||
url: ApiEndpoints.machine_list,
|
||||
pk: machinePk,
|
||||
preFormContent: (
|
||||
<Text>{t`Are you sure you want to remove the machine "${machine?.name}"?`}</Text>
|
||||
),
|
||||
onFormSuccess: () => {
|
||||
refreshTable();
|
||||
navigate(-1);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Stack gap="xs">
|
||||
{machineEditModal.modal}
|
||||
{machineDeleteModal.modal}
|
||||
|
||||
<Group justify="space-between">
|
||||
<Box></Box>
|
||||
|
||||
@ -227,36 +261,11 @@ function MachineDrawer({
|
||||
actions={[
|
||||
EditItemAction({
|
||||
tooltip: t`Edit machine`,
|
||||
onClick: () => {
|
||||
openEditApiForm({
|
||||
title: t`Edit machine`,
|
||||
url: ApiEndpoints.machine_list,
|
||||
pk: machinePk,
|
||||
fields: {
|
||||
name: {},
|
||||
active: {}
|
||||
},
|
||||
onClose: () => refreshAll()
|
||||
});
|
||||
}
|
||||
onClick: machineEditModal.open
|
||||
}),
|
||||
DeleteItemAction({
|
||||
tooltip: t`Delete machine`,
|
||||
onClick: () => {
|
||||
openDeleteApiForm({
|
||||
title: t`Delete machine`,
|
||||
successMessage: t`Machine successfully deleted.`,
|
||||
url: ApiEndpoints.machine_list,
|
||||
pk: machinePk,
|
||||
preFormContent: (
|
||||
<Text>{t`Are you sure you want to remove the machine "${machine?.name}"?`}</Text>
|
||||
),
|
||||
onFormSuccess: () => {
|
||||
refreshTable();
|
||||
navigate(-1);
|
||||
}
|
||||
});
|
||||
}
|
||||
onClick: machineDeleteModal.open
|
||||
}),
|
||||
{
|
||||
icon: <IconRefresh />,
|
||||
|
Reference in New Issue
Block a user