mirror of
https://github.com/inventree/InvenTree.git
synced 2025-08-07 04:12:11 +00:00
Enhancements for "custom state" form
- More intuitive form actions
This commit is contained in:
@@ -3406,17 +3406,20 @@ class InvenTreeCustomUserStateModel(models.Model):
|
||||
"""Custom model to extends any registered state with extra custom, user defined states."""
|
||||
|
||||
key = models.IntegerField(
|
||||
verbose_name=_('Key'),
|
||||
help_text=_('Value that will be saved in the models database'),
|
||||
verbose_name=_('Value'),
|
||||
help_text=_('Numerical value that will be saved in the models database'),
|
||||
)
|
||||
|
||||
name = models.CharField(
|
||||
max_length=250, verbose_name=_('Name'), help_text=_('Name of the state')
|
||||
)
|
||||
|
||||
label = models.CharField(
|
||||
max_length=250,
|
||||
verbose_name=_('Label'),
|
||||
help_text=_('Label that will be displayed in the frontend'),
|
||||
)
|
||||
|
||||
color = models.CharField(
|
||||
max_length=10,
|
||||
choices=state_color_mappings(),
|
||||
@@ -3424,12 +3427,14 @@ class InvenTreeCustomUserStateModel(models.Model):
|
||||
verbose_name=_('Color'),
|
||||
help_text=_('Color that will be displayed in the frontend'),
|
||||
)
|
||||
|
||||
logical_key = models.IntegerField(
|
||||
verbose_name=_('Logical Key'),
|
||||
help_text=_(
|
||||
'State logical key that is equal to this custom state in business logic'
|
||||
),
|
||||
)
|
||||
|
||||
model = models.ForeignKey(
|
||||
ContentType,
|
||||
on_delete=models.SET_NULL,
|
||||
@@ -3438,6 +3443,7 @@ class InvenTreeCustomUserStateModel(models.Model):
|
||||
verbose_name=_('Model'),
|
||||
help_text=_('Model this state is associated with'),
|
||||
)
|
||||
|
||||
reference_status = models.CharField(
|
||||
max_length=250,
|
||||
verbose_name=_('Reference Status Set'),
|
||||
|
@@ -5,7 +5,7 @@ import { ModelType } from '../../enums/ModelType';
|
||||
import { resolveItem } from '../../functions/conversion';
|
||||
import { useGlobalStatusState } from '../../states/StatusState';
|
||||
|
||||
interface StatusCodeInterface {
|
||||
export interface StatusCodeInterface {
|
||||
key: string;
|
||||
label: string;
|
||||
name: string;
|
||||
@@ -13,7 +13,10 @@ interface StatusCodeInterface {
|
||||
}
|
||||
|
||||
export interface StatusCodeListInterface {
|
||||
[key: string]: StatusCodeInterface;
|
||||
statusClass: string;
|
||||
values: {
|
||||
[key: string]: StatusCodeInterface;
|
||||
};
|
||||
}
|
||||
|
||||
interface RenderStatusLabelOptionsInterface {
|
||||
@@ -33,10 +36,10 @@ function renderStatusLabel(
|
||||
let color = null;
|
||||
|
||||
// Find the entry which matches the provided key
|
||||
for (let name in codes) {
|
||||
let entry = codes[name];
|
||||
for (let name in codes.values) {
|
||||
let entry: StatusCodeInterface = codes.values[name];
|
||||
|
||||
if (entry.key == key) {
|
||||
if (entry?.key == key) {
|
||||
text = entry.label;
|
||||
color = entry.color;
|
||||
break;
|
||||
@@ -97,7 +100,7 @@ export function getStatusCodeName(
|
||||
}
|
||||
|
||||
for (let name in statusCodes) {
|
||||
let entry = statusCodes[name];
|
||||
let entry: StatusCodeInterface = statusCodes.values[name];
|
||||
|
||||
if (entry.key == key) {
|
||||
return entry.name;
|
||||
|
@@ -1,6 +1,12 @@
|
||||
import { IconUsers } from '@tabler/icons-react';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
import { ApiFormFieldSet } from '../components/forms/fields/ApiFormField';
|
||||
import {
|
||||
StatusCodeInterface,
|
||||
StatusCodeListInterface
|
||||
} from '../components/render/StatusRenderer';
|
||||
import { useGlobalStatusState } from '../states/StatusState';
|
||||
|
||||
export function projectCodeFields(): ApiFormFieldSet {
|
||||
return {
|
||||
@@ -12,16 +18,51 @@ export function projectCodeFields(): ApiFormFieldSet {
|
||||
};
|
||||
}
|
||||
|
||||
export function customStateFields(): ApiFormFieldSet {
|
||||
return {
|
||||
key: {},
|
||||
name: {},
|
||||
label: {},
|
||||
color: {},
|
||||
logical_key: {},
|
||||
model: {},
|
||||
reference_status: {}
|
||||
};
|
||||
export function useCustomStateFields(): ApiFormFieldSet {
|
||||
// Status codes
|
||||
const statusCodes = useGlobalStatusState();
|
||||
|
||||
// Selected base status class
|
||||
const [statusClass, setStatusClass] = useState<string>('');
|
||||
|
||||
// Construct a list of status options based on the selected status class
|
||||
const statusOptions: any[] = useMemo(() => {
|
||||
let options: any[] = [];
|
||||
|
||||
const valuesList = Object.values(statusCodes.status ?? {}).find(
|
||||
(value: StatusCodeListInterface) => value.statusClass === statusClass
|
||||
);
|
||||
|
||||
Object.values(valuesList?.values ?? {}).forEach(
|
||||
(value: StatusCodeInterface) => {
|
||||
options.push({
|
||||
value: value.key,
|
||||
display_name: value.label
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return options;
|
||||
}, [statusCodes, statusClass]);
|
||||
|
||||
return useMemo(() => {
|
||||
return {
|
||||
reference_status: {
|
||||
onValueChange(value) {
|
||||
setStatusClass(value);
|
||||
}
|
||||
},
|
||||
logical_key: {
|
||||
field_type: 'choice',
|
||||
choices: statusOptions
|
||||
},
|
||||
key: {},
|
||||
name: {},
|
||||
label: {},
|
||||
color: {},
|
||||
model: {}
|
||||
};
|
||||
}, [statusOptions]);
|
||||
}
|
||||
|
||||
export function customUnitsFields(): ApiFormFieldSet {
|
||||
|
@@ -35,8 +35,10 @@ export const useGlobalStatusState = create<ServerStateProps>()(
|
||||
.then((response) => {
|
||||
const newStatusLookup: StatusLookup = {} as StatusLookup;
|
||||
for (const key in response.data) {
|
||||
newStatusLookup[statusCodeList[key] || key] =
|
||||
response.data[key].values;
|
||||
newStatusLookup[statusCodeList[key] || key] = {
|
||||
statusClass: key,
|
||||
values: response.data[key].values
|
||||
};
|
||||
}
|
||||
set({ status: newStatusLookup });
|
||||
})
|
||||
|
@@ -4,7 +4,7 @@ import { useCallback, useMemo, useState } from 'react';
|
||||
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||
import { UserRoles } from '../../enums/Roles';
|
||||
import { customStateFields } from '../../forms/CommonForms';
|
||||
import { useCustomStateFields } from '../../forms/CommonForms';
|
||||
import {
|
||||
useCreateApiFormModal,
|
||||
useDeleteApiFormModal,
|
||||
@@ -60,10 +60,13 @@ export default function CustomStateTable() {
|
||||
];
|
||||
}, []);
|
||||
|
||||
const newCustomStateFields = useCustomStateFields();
|
||||
const editCustomStateFields = useCustomStateFields();
|
||||
|
||||
const newCustomState = useCreateApiFormModal({
|
||||
url: ApiEndpoints.custom_state_list,
|
||||
title: t`Add State`,
|
||||
fields: customStateFields(),
|
||||
fields: newCustomStateFields,
|
||||
table: table
|
||||
});
|
||||
|
||||
@@ -75,7 +78,7 @@ export default function CustomStateTable() {
|
||||
url: ApiEndpoints.custom_state_list,
|
||||
pk: selectedCustomState,
|
||||
title: t`Edit State`,
|
||||
fields: customStateFields(),
|
||||
fields: editCustomStateFields,
|
||||
table: table
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user