diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py index 461a8f01ce..4b8064a625 100644 --- a/src/backend/InvenTree/InvenTree/api_version.py +++ b/src/backend/InvenTree/InvenTree/api_version.py @@ -1,11 +1,14 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 436 +INVENTREE_API_VERSION = 437 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +v437 -> 2026-01-07 : https://github.com/inventree/InvenTree/pull/11084 + - Add generic parameter support for the StockLocation model + v436 -> 2026-01-06 : https://github.com/inventree/InvenTree/pull/11035 - Removes model-specific metadata endpoints and replaces them with redirects - Adds new generic /api/metadata// endpoint to retrieve metadata for any model diff --git a/src/backend/InvenTree/stock/models.py b/src/backend/InvenTree/stock/models.py index 07fef64c5c..d525bfb6dc 100644 --- a/src/backend/InvenTree/stock/models.py +++ b/src/backend/InvenTree/stock/models.py @@ -120,6 +120,7 @@ class StockLocationReportContext(report.mixins.BaseReportContext): class StockLocation( InvenTree.models.PluginValidationMixin, + InvenTree.models.InvenTreeParameterMixin, InvenTree.models.InvenTreeBarcodeMixin, report.mixins.InvenTreeReportMixin, InvenTree.models.PathStringMixin, diff --git a/src/backend/InvenTree/stock/serializers.py b/src/backend/InvenTree/stock/serializers.py index f8d76e543a..e5314ed6ef 100644 --- a/src/backend/InvenTree/stock/serializers.py +++ b/src/backend/InvenTree/stock/serializers.py @@ -1159,8 +1159,10 @@ class LocationSerializer( 'structural', 'external', 'location_type', + # Optional fields 'location_type_detail', 'tags', + 'parameters', ] read_only_fields = ['barcode_hash', 'icon', 'level', 'pathstring'] @@ -1205,6 +1207,8 @@ class LocationSerializer( filter_name='path_detail', ) + parameters = common.filters.enable_parameters_filter() + # explicitly set this field, so it gets included for AutoSchema icon = serializers.CharField(read_only=True) diff --git a/src/frontend/src/components/panels/ParametersPanel.tsx b/src/frontend/src/components/panels/ParametersPanel.tsx index 03450e2aa8..574909cdc6 100644 --- a/src/frontend/src/components/panels/ParametersPanel.tsx +++ b/src/frontend/src/components/panels/ParametersPanel.tsx @@ -8,16 +8,19 @@ import type { PanelType } from './Panel'; export default function ParametersPanel({ model_type, model_id, + hidden, allowEdit = true }: { model_type: ModelType; model_id: number | undefined; + hidden?: boolean; allowEdit?: boolean; }): PanelType { return { name: 'parameters', label: t`Parameters`, icon: , + hidden: hidden ?? false, content: model_type && model_id ? ( ('table'); + const locationPanels: PanelType[] = useMemo(() => { return [ { @@ -169,12 +180,32 @@ export default function Stock() { icon: , content: detailsPanel }, - { + SegmentedControlPanel({ name: 'sublocations', label: id ? t`Sublocations` : t`Stock Locations`, icon: , - content: - }, + hidden: !user.hasViewPermission(ModelType.stocklocation), + selection: sublocationView, + onChange: setSublocationView, + options: [ + { + value: 'table', + label: t`Table View`, + icon: , + content: + }, + { + value: 'parametric', + label: t`Parametric View`, + icon: , + content: ( + + ) + } + ] + }), { name: 'stock-items', label: t`Stock Items`, @@ -203,9 +234,14 @@ export default function Stock() { }} /> ) - } + }, + ParametersPanel({ + model_type: ModelType.stocklocation, + model_id: location.pk, + hidden: !location.pk + }) ]; - }, [location, id]); + }, [sublocationView, location, id]); const editLocation = useEditApiFormModal({ url: ApiEndpoints.stock_location_list, diff --git a/src/frontend/src/tables/build/BuildOrderParametricTable.tsx b/src/frontend/src/tables/build/BuildOrderParametricTable.tsx index d9f85cb295..67606bf2cb 100644 --- a/src/frontend/src/tables/build/BuildOrderParametricTable.tsx +++ b/src/frontend/src/tables/build/BuildOrderParametricTable.tsx @@ -1,8 +1,13 @@ import { ApiEndpoints, ModelType } from '@lib/index'; import type { TableFilter } from '@lib/types/Filters'; import type { TableColumn } from '@lib/types/Tables'; +import { t } from '@lingui/core/macro'; import { type ReactNode, useMemo } from 'react'; -import { DescriptionColumn, ReferenceColumn } from '../ColumnRenderers'; +import { + DescriptionColumn, + PartColumn, + ReferenceColumn +} from '../ColumnRenderers'; import { OrderStatusFilter, OutstandingFilter } from '../Filter'; import ParametricDataTable from '../general/ParametricDataTable'; @@ -16,6 +21,10 @@ export default function BuildOrderParametricTable({ ReferenceColumn({ switchable: false }), + PartColumn({ + part: 'part_detail', + title: t`Part` + }), DescriptionColumn({ accessor: 'title' }) @@ -33,6 +42,7 @@ export default function BuildOrderParametricTable({ customColumns={customColumns} customFilters={customFilters} queryParams={{ + part_detail: true, ...queryParams }} /> diff --git a/src/frontend/src/tables/stock/StockLocationParametricTable.tsx b/src/frontend/src/tables/stock/StockLocationParametricTable.tsx new file mode 100644 index 0000000000..1c34581921 --- /dev/null +++ b/src/frontend/src/tables/stock/StockLocationParametricTable.tsx @@ -0,0 +1,45 @@ +import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; +import { ModelType } from '@lib/enums/ModelType'; +import type { TableColumn } from '@lib/types/Tables'; +import { Group } from '@mantine/core'; +import { type ReactNode, useMemo } from 'react'; +import { ApiIcon } from '../../components/items/ApiIcon'; +import { DescriptionColumn } from '../ColumnRenderers'; +import ParametricDataTable from '../general/ParametricDataTable'; + +export default function StockLocationParametricTable({ + queryParams +}: { + queryParams?: Record; +}): ReactNode { + const customColumns: TableColumn[] = useMemo(() => { + return [ + { + accessor: 'name', + switchable: false, + render: (record: any) => ( + + {record.icon && } + {record.name} + + ) + }, + DescriptionColumn({}), + { + accessor: 'pathstring', + sortable: true + } + ]; + }, []); + + return ( + + ); +}