2
0
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:
Lukas
2024-07-12 16:22:40 +02:00
committed by GitHub
parent 767b76314e
commit 23a394d740
11 changed files with 292 additions and 247 deletions

View File

@ -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);
}

View File

@ -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';

View File

@ -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 />,