mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 11:36:44 +00:00
* Add "locked" field to Part model - Default = false * Add "locked" field to PartSerializer - Allow filtering in API * Filter CUI tables by "locked" status * Add "locked" filter to part table * Update PUI table * PUI: Update display of part details page * Add "locked" element * Ensmallen the gap * Edit "locked" field in CUI * Check BomItem before editing or deleting * Prevent bulk delete of BOM items * Check part lock for PartParameter model * Prevent deletion of a locked part * Add option to prevent build order creation for unlocked part * Bump API version * Hide actions from BOM table if part is locked * Fix for boolean form field * Update <PartParameterTable> * Add unit test for 'BUILDORDER_REQUIRE_LOCKED_PART' setting * Add unit test for part deletion * add bom item test * unit test for part parameter * Update playwright tests * Update docs * Remove defunct setting * Update playwright tests
327 lines
9.3 KiB
TypeScript
327 lines
9.3 KiB
TypeScript
import { Trans, t } from '@lingui/macro';
|
|
import { Stack } from '@mantine/core';
|
|
import {
|
|
IconBellCog,
|
|
IconCategory,
|
|
IconClipboardCheck,
|
|
IconCurrencyDollar,
|
|
IconFileAnalytics,
|
|
IconFingerprint,
|
|
IconPackages,
|
|
IconQrcode,
|
|
IconServerCog,
|
|
IconShoppingCart,
|
|
IconSitemap,
|
|
IconTag,
|
|
IconTools,
|
|
IconTruckDelivery,
|
|
IconTruckReturn
|
|
} from '@tabler/icons-react';
|
|
import { useMemo } from 'react';
|
|
|
|
import PermissionDenied from '../../../components/errors/PermissionDenied';
|
|
import { PlaceholderPanel } from '../../../components/items/Placeholder';
|
|
import { PanelGroup, PanelType } from '../../../components/nav/PanelGroup';
|
|
import { SettingsHeader } from '../../../components/nav/SettingsHeader';
|
|
import { GlobalSettingList } from '../../../components/settings/SettingList';
|
|
import { useServerApiState } from '../../../states/ApiState';
|
|
import { useUserState } from '../../../states/UserState';
|
|
|
|
/**
|
|
* System settings page
|
|
*/
|
|
export default function SystemSettings() {
|
|
const systemSettingsPanels: PanelType[] = useMemo(() => {
|
|
return [
|
|
{
|
|
name: 'server',
|
|
label: t`Server`,
|
|
icon: <IconServerCog />,
|
|
content: (
|
|
<GlobalSettingList
|
|
keys={[
|
|
'INVENTREE_BASE_URL',
|
|
'INVENTREE_COMPANY_NAME',
|
|
'INVENTREE_INSTANCE',
|
|
'INVENTREE_INSTANCE_TITLE',
|
|
'INVENTREE_RESTRICT_ABOUT',
|
|
'DISPLAY_FULL_NAMES',
|
|
'INVENTREE_UPDATE_CHECK_INTERVAL',
|
|
'INVENTREE_DOWNLOAD_FROM_URL',
|
|
'INVENTREE_DOWNLOAD_IMAGE_MAX_SIZE',
|
|
'INVENTREE_DOWNLOAD_FROM_URL_USER_AGENT',
|
|
'INVENTREE_REQUIRE_CONFIRM',
|
|
'INVENTREE_STRICT_URLS',
|
|
'INVENTREE_TREE_DEPTH',
|
|
'INVENTREE_BACKUP_ENABLE',
|
|
'INVENTREE_BACKUP_DAYS',
|
|
'INVENTREE_DELETE_TASKS_DAYS',
|
|
'INVENTREE_DELETE_ERRORS_DAYS',
|
|
'INVENTREE_DELETE_NOTIFICATIONS_DAYS'
|
|
]}
|
|
/>
|
|
)
|
|
},
|
|
{
|
|
name: 'login',
|
|
label: t`Login`,
|
|
icon: <IconFingerprint />,
|
|
content: (
|
|
<GlobalSettingList
|
|
keys={[
|
|
'LOGIN_ENABLE_PWD_FORGOT',
|
|
'LOGIN_MAIL_REQUIRED',
|
|
'LOGIN_ENFORCE_MFA',
|
|
'LOGIN_ENABLE_REG',
|
|
'LOGIN_SIGNUP_MAIL_TWICE',
|
|
'LOGIN_SIGNUP_PWD_TWICE',
|
|
'SIGNUP_GROUP',
|
|
'LOGIN_SIGNUP_MAIL_RESTRICTION',
|
|
'LOGIN_ENABLE_SSO',
|
|
'LOGIN_ENABLE_SSO_REG',
|
|
'LOGIN_SIGNUP_SSO_AUTO',
|
|
'LOGIN_ENABLE_SSO_GROUP_SYNC',
|
|
'SSO_GROUP_MAP',
|
|
'SSO_GROUP_KEY',
|
|
'SSO_REMOVE_GROUPS'
|
|
]}
|
|
/>
|
|
)
|
|
},
|
|
{
|
|
name: 'barcode',
|
|
label: t`Barcodes`,
|
|
icon: <IconQrcode />,
|
|
content: (
|
|
<GlobalSettingList
|
|
keys={[
|
|
'BARCODE_ENABLE',
|
|
'BARCODE_INPUT_DELAY',
|
|
'BARCODE_WEBCAM_SUPPORT',
|
|
'BARCODE_SHOW_TEXT'
|
|
]}
|
|
/>
|
|
)
|
|
},
|
|
{
|
|
name: 'notifications',
|
|
label: t`Notifications`,
|
|
icon: <IconBellCog />,
|
|
content: <PlaceholderPanel />
|
|
},
|
|
{
|
|
name: 'pricing',
|
|
label: t`Pricing`,
|
|
icon: <IconCurrencyDollar />,
|
|
content: (
|
|
<>
|
|
<GlobalSettingList
|
|
keys={[
|
|
'INVENTREE_DEFAULT_CURRENCY',
|
|
'CURRENCY_CODES',
|
|
'PART_INTERNAL_PRICE',
|
|
'PART_BOM_USE_INTERNAL_PRICE',
|
|
'PRICING_DECIMAL_PLACES_MIN',
|
|
'PRICING_DECIMAL_PLACES',
|
|
'PRICING_UPDATE_DAYS'
|
|
]}
|
|
/>
|
|
<br />
|
|
<GlobalSettingList
|
|
keys={[
|
|
'PRICING_USE_SUPPLIER_PRICING',
|
|
'PRICING_PURCHASE_HISTORY_OVERRIDES_SUPPLIER',
|
|
'PRICING_USE_STOCK_PRICING',
|
|
'PRICING_STOCK_ITEM_AGE_DAYS',
|
|
'PRICING_USE_VARIANT_PRICING',
|
|
'PRICING_ACTIVE_VARIANTS'
|
|
]}
|
|
/>
|
|
<br />
|
|
<GlobalSettingList
|
|
keys={['CURRENCY_UPDATE_PLUGIN', 'CURRENCY_UPDATE_INTERVAL']}
|
|
/>
|
|
</>
|
|
)
|
|
},
|
|
{
|
|
name: 'labels',
|
|
label: t`Labels`,
|
|
icon: <IconTag />,
|
|
content: <GlobalSettingList keys={['LABEL_ENABLE', 'LABEL_DPI']} />
|
|
},
|
|
{
|
|
name: 'reporting',
|
|
label: t`Reporting`,
|
|
icon: <IconFileAnalytics />,
|
|
content: (
|
|
<GlobalSettingList
|
|
keys={[
|
|
'REPORT_ENABLE',
|
|
'REPORT_DEFAULT_PAGE_SIZE',
|
|
'REPORT_DEBUG_MODE',
|
|
'REPORT_LOG_ERRORS',
|
|
'REPORT_ENABLE_TEST_REPORT',
|
|
'REPORT_ATTACH_TEST_REPORT'
|
|
]}
|
|
/>
|
|
)
|
|
},
|
|
{
|
|
name: 'categories',
|
|
label: t`Part Categories`,
|
|
icon: <IconSitemap />,
|
|
content: <PlaceholderPanel />
|
|
},
|
|
{
|
|
name: 'parts',
|
|
label: t`Parts`,
|
|
icon: <IconCategory />,
|
|
content: (
|
|
<GlobalSettingList
|
|
keys={[
|
|
'PART_ENABLE_REVISION',
|
|
'PART_IPN_REGEX',
|
|
'PART_ALLOW_DUPLICATE_IPN',
|
|
'PART_ALLOW_EDIT_IPN',
|
|
'PART_ALLOW_DELETE_FROM_ASSEMBLY',
|
|
'PART_NAME_FORMAT',
|
|
'PART_SHOW_RELATED',
|
|
'PART_CREATE_INITIAL',
|
|
'PART_CREATE_SUPPLIER', // TODO: Break here
|
|
'PART_TEMPLATE',
|
|
'PART_ASSEMBLY',
|
|
'PART_COMPONENT',
|
|
'PART_TRACKABLE',
|
|
'PART_PURCHASEABLE',
|
|
'PART_SALABLE',
|
|
'PART_VIRTUAL', // TODO: Break here
|
|
'PART_COPY_BOM',
|
|
'PART_COPY_PARAMETERS',
|
|
'PART_COPY_TESTS',
|
|
'PART_CATEGORY_PARAMETERS',
|
|
'PART_CATEGORY_DEFAULT_ICON' // TODO: Move to part category settings page
|
|
]}
|
|
/>
|
|
)
|
|
},
|
|
{
|
|
name: 'stock',
|
|
label: t`Stock`,
|
|
icon: <IconPackages />,
|
|
content: (
|
|
<GlobalSettingList
|
|
keys={[
|
|
'SERIAL_NUMBER_GLOBALLY_UNIQUE',
|
|
'SERIAL_NUMBER_AUTOFILL',
|
|
'STOCK_DELETE_DEPLETED_DEFAULT',
|
|
'STOCK_BATCH_CODE_TEMPLATE',
|
|
'STOCK_ENABLE_EXPIRY',
|
|
'STOCK_STALE_DAYS',
|
|
'STOCK_ALLOW_EXPIRED_SALE',
|
|
'STOCK_ALLOW_EXPIRED_BUILD',
|
|
'STOCK_OWNERSHIP_CONTROL',
|
|
'STOCK_LOCATION_DEFAULT_ICON',
|
|
'STOCK_SHOW_INSTALLED_ITEMS',
|
|
'STOCK_ENFORCE_BOM_INSTALLATION',
|
|
'STOCK_ALLOW_OUT_OF_STOCK_TRANSFER',
|
|
'TEST_STATION_DATA'
|
|
]}
|
|
/>
|
|
)
|
|
},
|
|
{
|
|
name: 'stocktake',
|
|
label: t`Stocktake`,
|
|
icon: <IconClipboardCheck />,
|
|
content: <PlaceholderPanel />
|
|
},
|
|
{
|
|
name: 'buildorders',
|
|
label: t`Build Orders`,
|
|
icon: <IconTools />,
|
|
content: (
|
|
<GlobalSettingList
|
|
keys={[
|
|
'BUILDORDER_REFERENCE_PATTERN',
|
|
'BUILDORDER_REQUIRE_RESPONSIBLE',
|
|
'BUILDORDER_REQUIRE_ACTIVE_PART',
|
|
'BUILDORDER_REQUIRE_LOCKED_PART',
|
|
'BUILDORDER_REQUIRE_VALID_BOM',
|
|
'PREVENT_BUILD_COMPLETION_HAVING_INCOMPLETED_TESTS'
|
|
]}
|
|
/>
|
|
)
|
|
},
|
|
{
|
|
name: 'purchaseorders',
|
|
label: t`Purchase Orders`,
|
|
icon: <IconShoppingCart />,
|
|
content: (
|
|
<GlobalSettingList
|
|
keys={[
|
|
'PURCHASEORDER_REFERENCE_PATTERN',
|
|
'PURCHASEORDER_REQUIRE_RESPONSIBLE',
|
|
'PURCHASEORDER_EDIT_COMPLETED_ORDERS',
|
|
'PURCHASEORDER_AUTO_COMPLETE'
|
|
]}
|
|
/>
|
|
)
|
|
},
|
|
{
|
|
name: 'salesorders',
|
|
label: t`Sales Orders`,
|
|
icon: <IconTruckDelivery />,
|
|
content: (
|
|
<GlobalSettingList
|
|
keys={[
|
|
'SALESORDER_REFERENCE_PATTERN',
|
|
'SALESORDER_REQUIRE_RESPONSIBLE',
|
|
'SALESORDER_DEFAULT_SHIPMENT',
|
|
'SALESORDER_EDIT_COMPLETED_ORDERS',
|
|
'SALESORDER_SHIP_COMPLETE'
|
|
]}
|
|
/>
|
|
)
|
|
},
|
|
{
|
|
name: 'returnorders',
|
|
label: t`Return Orders`,
|
|
icon: <IconTruckReturn />,
|
|
content: (
|
|
<GlobalSettingList
|
|
keys={[
|
|
'RETURNORDER_ENABLED',
|
|
'RETURNORDER_REFERENCE_PATTERN',
|
|
'RETURNORDER_REQUIRE_RESPONSIBLE',
|
|
'RETURNORDER_EDIT_COMPLETED_ORDERS'
|
|
]}
|
|
/>
|
|
)
|
|
}
|
|
];
|
|
}, []);
|
|
|
|
const user = useUserState();
|
|
|
|
const [server] = useServerApiState((state) => [state.server]);
|
|
|
|
return (
|
|
<>
|
|
{user.isStaff() ? (
|
|
<Stack gap="xs">
|
|
<SettingsHeader
|
|
title={t`System Settings`}
|
|
subtitle={server.instance || ''}
|
|
switch_link="/settings/user"
|
|
switch_text={<Trans>Switch to User Setting</Trans>}
|
|
/>
|
|
<PanelGroup pageKey="system-settings" panels={systemSettingsPanels} />
|
|
</Stack>
|
|
) : (
|
|
<PermissionDenied />
|
|
)}
|
|
</>
|
|
);
|
|
}
|