diff --git a/docs/docs/extend/plugins/urls.md b/docs/docs/extend/plugins/urls.md index f593c0bd30..b76bb3ac16 100644 --- a/docs/docs/extend/plugins/urls.md +++ b/docs/docs/extend/plugins/urls.md @@ -18,6 +18,7 @@ class MyUrlsPlugin(UrlsMixin, InvenTreePlugin): ] ``` + The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the [url tag](https://docs.djangoproject.com/en/stable/ref/templates/builtins/#url)). !!! info "Note" @@ -117,4 +118,4 @@ Example: onPanelLoad('loans', function() { ... });; -``` \ No newline at end of file +``` diff --git a/src/frontend/src/components/DashboardItemProxy.tsx b/src/frontend/src/components/DashboardItemProxy.tsx index d59ea39fab..d7ffedba9a 100644 --- a/src/frontend/src/components/DashboardItemProxy.tsx +++ b/src/frontend/src/components/DashboardItemProxy.tsx @@ -3,7 +3,8 @@ import { useQuery } from '@tanstack/react-query'; import { useEffect, useState } from 'react'; import { api } from '../App'; -import { ApiPaths, apiUrl } from '../states/ApiState'; +import { ApiPaths } from '../enums/ApiEndpoints'; +import { apiUrl } from '../states/ApiState'; import { StatisticItem } from './items/DashboardItem'; import { ErrorItem } from './items/ErrorItem'; diff --git a/src/frontend/src/components/buttons/ActionButton.tsx b/src/frontend/src/components/buttons/ActionButton.tsx index 9aeb65cb00..b9bfa90898 100644 --- a/src/frontend/src/components/buttons/ActionButton.tsx +++ b/src/frontend/src/components/buttons/ActionButton.tsx @@ -4,6 +4,7 @@ import { ReactNode } from 'react'; import { notYetImplemented } from '../../functions/notifications'; export type ActionButtonProps = { + key?: string; icon?: ReactNode; text?: string; color?: string; @@ -22,12 +23,13 @@ export function ActionButton(props: ActionButtonProps) { return ( !props.hidden && ( } actions={actions} diff --git a/src/frontend/src/components/modals/AboutInvenTreeModal.tsx b/src/frontend/src/components/modals/AboutInvenTreeModal.tsx index 9a7771fb00..b4b8f85cfa 100644 --- a/src/frontend/src/components/modals/AboutInvenTreeModal.tsx +++ b/src/frontend/src/components/modals/AboutInvenTreeModal.tsx @@ -4,7 +4,8 @@ import { ContextModalProps } from '@mantine/modals'; import { useQuery } from '@tanstack/react-query'; import { api } from '../../App'; -import { ApiPaths, apiUrl, useServerApiState } from '../../states/ApiState'; +import { ApiPaths } from '../../enums/ApiEndpoints'; +import { apiUrl, useServerApiState } from '../../states/ApiState'; import { useLocalState } from '../../states/LocalState'; import { useUserState } from '../../states/UserState'; import { CopyButton } from '../items/CopyButton'; diff --git a/src/frontend/src/components/modals/QrCodeModal.tsx b/src/frontend/src/components/modals/QrCodeModal.tsx index a8fb969023..63d9054440 100644 --- a/src/frontend/src/components/modals/QrCodeModal.tsx +++ b/src/frontend/src/components/modals/QrCodeModal.tsx @@ -23,7 +23,8 @@ import { Html5QrcodeResult } from 'html5-qrcode/core'; import { useEffect, useState } from 'react'; import { api } from '../../App'; -import { ApiPaths, apiUrl } from '../../states/ApiState'; +import { ApiPaths } from '../../enums/ApiEndpoints'; +import { apiUrl } from '../../states/ApiState'; export function QrCodeModal({ context, diff --git a/src/frontend/src/components/nav/Header.tsx b/src/frontend/src/components/nav/Header.tsx index c282956a59..eb87b3baca 100644 --- a/src/frontend/src/components/nav/Header.tsx +++ b/src/frontend/src/components/nav/Header.tsx @@ -7,8 +7,9 @@ import { useNavigate, useParams } from 'react-router-dom'; import { api } from '../../App'; import { navTabs as mainNavTabs } from '../../defaults/links'; +import { ApiPaths } from '../../enums/ApiEndpoints'; import { InvenTreeStyle } from '../../globalStyle'; -import { ApiPaths, apiUrl } from '../../states/ApiState'; +import { apiUrl } from '../../states/ApiState'; import { ScanButton } from '../items/ScanButton'; import { MainMenu } from './MainMenu'; import { NavHoverMenu } from './NavHoverMenu'; diff --git a/src/frontend/src/components/nav/NotificationDrawer.tsx b/src/frontend/src/components/nav/NotificationDrawer.tsx index cf7debae66..895cc11eef 100644 --- a/src/frontend/src/components/nav/NotificationDrawer.tsx +++ b/src/frontend/src/components/nav/NotificationDrawer.tsx @@ -14,7 +14,8 @@ import { useQuery } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; import { api } from '../../App'; -import { ApiPaths, apiUrl } from '../../states/ApiState'; +import { ApiPaths } from '../../enums/ApiEndpoints'; +import { apiUrl } from '../../states/ApiState'; import { StylishText } from '../items/StylishText'; /** diff --git a/src/frontend/src/components/nav/PageDetail.tsx b/src/frontend/src/components/nav/PageDetail.tsx index c66c55df02..5f997482f2 100644 --- a/src/frontend/src/components/nav/PageDetail.tsx +++ b/src/frontend/src/components/nav/PageDetail.tsx @@ -58,7 +58,7 @@ export function PageDetail({ {detail} {actions && ( - + {actions} )} diff --git a/src/frontend/src/components/nav/PartCategoryTree.tsx b/src/frontend/src/components/nav/PartCategoryTree.tsx index b541c53892..a376189919 100644 --- a/src/frontend/src/components/nav/PartCategoryTree.tsx +++ b/src/frontend/src/components/nav/PartCategoryTree.tsx @@ -6,7 +6,8 @@ import { useQuery } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; import { api } from '../../App'; -import { ApiPaths, apiUrl } from '../../states/ApiState'; +import { ApiPaths } from '../../enums/ApiEndpoints'; +import { apiUrl } from '../../states/ApiState'; import { StylishText } from '../items/StylishText'; export function PartCategoryTree({ diff --git a/src/frontend/src/components/nav/SearchDrawer.tsx b/src/frontend/src/components/nav/SearchDrawer.tsx index 903ebb6456..16c2757dfe 100644 --- a/src/frontend/src/components/nav/SearchDrawer.tsx +++ b/src/frontend/src/components/nav/SearchDrawer.tsx @@ -26,139 +26,27 @@ import { IconX } from '@tabler/icons-react'; import { useQuery } from '@tanstack/react-query'; -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { api } from '../../App'; -import { ApiPaths, apiUrl } from '../../states/ApiState'; +import { ApiPaths } from '../../enums/ApiEndpoints'; +import { ModelType } from '../../enums/ModelType'; +import { UserRoles } from '../../enums/Roles'; +import { apiUrl } from '../../states/ApiState'; +import { useUserSettingsState } from '../../states/SettingsState'; +import { useUserState } from '../../states/UserState'; import { RenderInstance } from '../render/Instance'; -import { ModelInformationDict, ModelType } from '../render/ModelType'; +import { ModelInformationDict } from '../render/ModelType'; // Define type for handling individual search queries type SearchQuery = { - name: ModelType; + model: ModelType; enabled: boolean; parameters: any; results?: any; }; -// Placeholder function for permissions checks (will be replaced with a proper implementation) -function permissionCheck(permission: string) { - return true; -} - -// Placeholder function for settings checks (will be replaced with a proper implementation) -function settingsCheck(setting: string) { - return true; -} - -/* - * Build a list of search queries based on user permissions - */ -function buildSearchQueries(): SearchQuery[] { - return [ - { - name: ModelType.part, - parameters: {}, - enabled: - permissionCheck('part.view') && - settingsCheck('SEARCH_PREVIEW_SHOW_PARTS') - }, - { - name: ModelType.supplierpart, - parameters: { - part_detail: true, - supplier_detail: true, - manufacturer_detail: true - }, - enabled: - permissionCheck('part.view') && - permissionCheck('purchase_order.view') && - settingsCheck('SEARCH_PREVIEW_SHOW_SUPPLIER_PARTS') - }, - { - name: ModelType.manufacturerpart, - parameters: { - part_detail: true, - supplier_detail: true, - manufacturer_detail: true - }, - enabled: - permissionCheck('part.view') && - permissionCheck('purchase_order.view') && - settingsCheck('SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS') - }, - { - name: ModelType.partcategory, - parameters: {}, - enabled: - permissionCheck('part_category.view') && - settingsCheck('SEARCH_PREVIEW_SHOW_CATEGORIES') - }, - { - name: ModelType.stockitem, - parameters: { - part_detail: true, - location_detail: true - }, - enabled: - permissionCheck('stock.view') && - settingsCheck('SEARCH_PREVIEW_SHOW_STOCK') - }, - { - name: ModelType.stocklocation, - parameters: {}, - enabled: - permissionCheck('stock_location.view') && - settingsCheck('SEARCH_PREVIEW_SHOW_LOCATIONS') - }, - { - name: ModelType.build, - parameters: { - part_detail: true - }, - enabled: - permissionCheck('build.view') && - settingsCheck('SEARCH_PREVIEW_SHOW_BUILD_ORDERS') - }, - { - name: ModelType.company, - parameters: {}, - enabled: - (permissionCheck('sales_order.view') || - permissionCheck('purchase_order.view')) && - settingsCheck('SEARCH_PREVIEW_SHOW_COMPANIES') - }, - { - name: ModelType.purchaseorder, - parameters: { - supplier_detail: true - }, - enabled: - permissionCheck('purchase_order.view') && - settingsCheck(`SEARCH_PREVIEW_SHOW_PURCHASE_ORDERS`) - }, - { - name: ModelType.salesorder, - parameters: { - customer_detail: true - }, - enabled: - permissionCheck('sales_order.view') && - settingsCheck(`SEARCH_PREVIEW_SHOW_SALES_ORDERS`) - }, - { - name: ModelType.returnorder, - parameters: { - customer_detail: true - }, - enabled: - permissionCheck('return_order.view') && - settingsCheck(`SEARCH_PREVIEW_SHOW_RETURN_ORDERS`) - } - ]; -} - /* * Render the results for a single search query */ @@ -175,10 +63,11 @@ function QueryResultGroup({ return null; } - const model = ModelInformationDict[query.name]; + const model = ModelInformationDict[query.model]; + return ( - - + + {model.label_multiple} @@ -193,7 +82,7 @@ function QueryResultGroup({ color="red" variant="transparent" radius="xs" - onClick={() => onRemove(query.name)} + onClick={() => onRemove(query.model)} > @@ -201,11 +90,11 @@ function QueryResultGroup({ {query.results.results.map((result: any) => ( - onResultClick(query.name, result.pk)}> + onResultClick(query.model, result.pk)}> ))} @@ -233,10 +122,116 @@ export function SearchDrawer({ const [searchRegex, setSearchRegex] = useState(false); const [searchWhole, setSearchWhole] = useState(false); + const user = useUserState(); + const userSettings = useUserSettingsState(); + + // Build out search queries based on user permissions and preferences + const searchQueryList: SearchQuery[] = useMemo(() => { + return [ + { + model: ModelType.part, + parameters: {}, + enabled: + user.hasViewRole(UserRoles.part) && + userSettings.isSet('SEARCH_PREVIEW_SHOW_PARTS') + }, + { + model: ModelType.supplierpart, + parameters: { + part_detail: true, + supplier_detail: true, + manufacturer_detail: true + }, + enabled: + user.hasViewRole(UserRoles.part) && + user.hasViewRole(UserRoles.purchase_order) && + userSettings.isSet('SEARCH_PREVIEW_SHOW_SUPPLIER_PARTS') + }, + { + model: ModelType.manufacturerpart, + parameters: { + part_detail: true, + supplier_detail: true, + manufacturer_detail: true + }, + enabled: + user.hasViewRole(UserRoles.part) && + user.hasViewRole(UserRoles.purchase_order) && + userSettings.isSet('SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS') + }, + { + model: ModelType.partcategory, + parameters: {}, + enabled: + user.hasViewRole(UserRoles.part_category) && + userSettings.isSet('SEARCH_PREVIEW_SHOW_CATEGORIES') + }, + { + model: ModelType.stockitem, + parameters: { + part_detail: true, + location_detail: true + }, + enabled: + user.hasViewRole(UserRoles.stock) && + userSettings.isSet('SEARCH_PREVIEW_SHOW_STOCK') + }, + { + model: ModelType.stocklocation, + parameters: {}, + enabled: + user.hasViewRole(UserRoles.stock_location) && + userSettings.isSet('SEARCH_PREVIEW_SHOW_LOCATIONS') + }, + { + model: ModelType.build, + parameters: { + part_detail: true + }, + enabled: + user.hasViewRole(UserRoles.build) && + userSettings.isSet('SEARCH_PREVIEW_SHOW_BUILD_ORDERS') + }, + { + model: ModelType.company, + parameters: {}, + enabled: + (user.hasViewRole(UserRoles.sales_order) || + user.hasViewRole(UserRoles.purchase_order)) && + userSettings.isSet('SEARCH_PREVIEW_SHOW_COMPANIES') + }, + { + model: ModelType.purchaseorder, + parameters: { + supplier_detail: true + }, + enabled: + user.hasViewRole(UserRoles.purchase_order) && + userSettings.isSet(`SEARCH_PREVIEW_SHOW_PURCHASE_ORDERS`) + }, + { + model: ModelType.salesorder, + parameters: { + customer_detail: true + }, + enabled: + user.hasViewRole(UserRoles.sales_order) && + userSettings.isSet(`SEARCH_PREVIEW_SHOW_SALES_ORDERS`) + }, + { + model: ModelType.returnorder, + parameters: { + customer_detail: true + }, + enabled: + user.hasViewRole(UserRoles.return_order) && + userSettings.isSet(`SEARCH_PREVIEW_SHOW_RETURN_ORDERS`) + } + ]; + }, [user, userSettings]); + // Construct a list of search queries based on user permissions - const searchQueries: SearchQuery[] = buildSearchQueries().filter( - (q) => q.enabled - ); + const searchQueries: SearchQuery[] = searchQueryList.filter((q) => q.enabled); // Re-fetch data whenever the search term is updated useEffect(() => { @@ -261,7 +256,7 @@ export function SearchDrawer({ // Add in custom query parameters searchQueries.forEach((query) => { - params[query.name] = query.parameters; + params[query.model] = query.parameters; }); return api @@ -289,11 +284,11 @@ export function SearchDrawer({ useEffect(() => { if (searchQuery.data) { let queries = searchQueries.filter( - (query) => query.name in searchQuery.data + (query) => query.model in searchQuery.data ); for (let key in searchQuery.data) { - let query = queries.find((q) => q.name == key); + let query = queries.find((q) => q.model == key); if (query) { query.results = searchQuery.data[key]; } @@ -310,7 +305,7 @@ export function SearchDrawer({ // Callback to remove a set of results from the list function removeResults(query: ModelType) { - setQueryResults(queryResults.filter((q) => q.name != query)); + setQueryResults(queryResults.filter((q) => q.model != query)); } // Callback when the drawer is closed @@ -332,7 +327,7 @@ export function SearchDrawer({ return ( - - {title} - {shorthand && ({shorthand})} - - - {subtitle} + + + + + {title} + {shorthand} + + {subtitle} + + {switch_text && switch_link && switch_condition && ( - - {switch_text} + )} - + ); } diff --git a/src/frontend/src/components/nav/StockLocationTree.tsx b/src/frontend/src/components/nav/StockLocationTree.tsx index 02917989f5..5f4cd76bcc 100644 --- a/src/frontend/src/components/nav/StockLocationTree.tsx +++ b/src/frontend/src/components/nav/StockLocationTree.tsx @@ -6,7 +6,8 @@ import { useQuery } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; import { api } from '../../App'; -import { ApiPaths, apiUrl } from '../../states/ApiState'; +import { ApiPaths } from '../../enums/ApiEndpoints'; +import { apiUrl } from '../../states/ApiState'; import { StylishText } from '../items/StylishText'; export function StockLocationTree({ diff --git a/src/frontend/src/components/render/Build.tsx b/src/frontend/src/components/render/Build.tsx index 175a07b9cb..d5ee532c78 100644 --- a/src/frontend/src/components/render/Build.tsx +++ b/src/frontend/src/components/render/Build.tsx @@ -1,6 +1,8 @@ import { ReactNode } from 'react'; +import { ModelType } from '../../enums/ModelType'; import { RenderInlineModel } from './Instance'; +import { StatusRenderer } from './StatusRenderer'; /** * Inline rendering of a single BuildOrder instance @@ -10,6 +12,10 @@ export function RenderBuildOrder({ instance }: { instance: any }): ReactNode { ); diff --git a/src/frontend/src/components/render/Instance.tsx b/src/frontend/src/components/render/Instance.tsx index 2ace53f7ac..17efca6512 100644 --- a/src/frontend/src/components/render/Instance.tsx +++ b/src/frontend/src/components/render/Instance.tsx @@ -3,6 +3,7 @@ import { Alert, Space } from '@mantine/core'; import { Group, Text } from '@mantine/core'; import { ReactNode } from 'react'; +import { ModelType } from '../../enums/ModelType'; import { Thumbnail } from '../images/Thumbnail'; import { RenderBuildOrder } from './Build'; import { @@ -13,7 +14,6 @@ import { RenderSupplierPart } from './Company'; import { RenderProjectCode } from './Generic'; -import { ModelType } from './ModelType'; import { RenderPurchaseOrder, RenderReturnOrder, @@ -101,7 +101,7 @@ export function RenderInlineModel({ }: { primary: string; secondary?: string; - suffix?: string; + suffix?: ReactNode; image?: string; labels?: string[]; url?: string; diff --git a/src/frontend/src/components/render/ModelType.tsx b/src/frontend/src/components/render/ModelType.tsx index 1976f95151..77e2414333 100644 --- a/src/frontend/src/components/render/ModelType.tsx +++ b/src/frontend/src/components/render/ModelType.tsx @@ -1,37 +1,18 @@ import { t } from '@lingui/macro'; -export enum ModelType { - part = 'part', - supplierpart = 'supplierpart', - manufacturerpart = 'manufacturerpart', - partcategory = 'partcategory', - partparametertemplate = 'partparametertemplate', - projectcode = 'projectcode', - stockitem = 'stockitem', - stocklocation = 'stocklocation', - stockhistory = 'stockhistory', - build = 'build', - company = 'company', - purchaseorder = 'purchaseorder', - purchaseorderline = 'purchaseorderline', - salesorder = 'salesorder', - salesordershipment = 'salesordershipment', - returnorder = 'returnorder', - address = 'address', - contact = 'contact', - owner = 'owner', - user = 'user' -} +import { ApiPaths } from '../../enums/ApiEndpoints'; +import { ModelType } from '../../enums/ModelType'; -interface ModelInformatonInterface { +interface ModelInformationInterface { label: string; label_multiple: string; url_overview?: string; url_detail?: string; + api_endpoint?: ApiPaths; } type ModelDictory = { - [key in keyof typeof ModelType]: ModelInformatonInterface; + [key in keyof typeof ModelType]: ModelInformationInterface; }; export const ModelInformationDict: ModelDictory = { @@ -39,116 +20,136 @@ export const ModelInformationDict: ModelDictory = { label: t`Part`, label_multiple: t`Parts`, url_overview: '/part', - url_detail: '/part/:pk/' + url_detail: '/part/:pk/', + api_endpoint: ApiPaths.part_list }, partparametertemplate: { label: t`Part Parameter Template`, label_multiple: t`Part Parameter Templates`, url_overview: '/partparametertemplate', - url_detail: '/partparametertemplate/:pk/' + url_detail: '/partparametertemplate/:pk/', + api_endpoint: ApiPaths.part_parameter_template_list }, supplierpart: { label: t`Supplier Part`, label_multiple: t`Supplier Parts`, url_overview: '/supplierpart', - url_detail: '/supplierpart/:pk/' + url_detail: '/supplierpart/:pk/', + api_endpoint: ApiPaths.supplier_part_list }, manufacturerpart: { label: t`Manufacturer Part`, label_multiple: t`Manufacturer Parts`, url_overview: '/manufacturerpart', - url_detail: '/manufacturerpart/:pk/' + url_detail: '/manufacturerpart/:pk/', + api_endpoint: ApiPaths.manufacturer_part_list }, partcategory: { label: t`Part Category`, label_multiple: t`Part Categories`, url_overview: '/partcategory', - url_detail: '/partcategory/:pk/' + url_detail: '/partcategory/:pk/', + api_endpoint: ApiPaths.category_list }, stockitem: { label: t`Stock Item`, label_multiple: t`Stock Items`, url_overview: '/stockitem', - url_detail: '/stockitem/:pk/' + url_detail: '/stockitem/:pk/', + api_endpoint: ApiPaths.stock_item_list }, stocklocation: { label: t`Stock Location`, label_multiple: t`Stock Locations`, url_overview: '/stocklocation', - url_detail: '/stocklocation/:pk/' + url_detail: '/stocklocation/:pk/', + api_endpoint: ApiPaths.stock_location_list }, stockhistory: { label: t`Stock History`, - label_multiple: t`Stock Histories` + label_multiple: t`Stock Histories`, + api_endpoint: ApiPaths.stock_tracking_list }, build: { label: t`Build`, label_multiple: t`Builds`, url_overview: '/build', - url_detail: '/build/:pk/' + url_detail: '/build/:pk/', + api_endpoint: ApiPaths.build_order_list }, company: { label: t`Company`, label_multiple: t`Companies`, url_overview: '/company', - url_detail: '/company/:pk/' + url_detail: '/company/:pk/', + api_endpoint: ApiPaths.company_list }, projectcode: { label: t`Project Code`, label_multiple: t`Project Codes`, url_overview: '/project-code', - url_detail: '/project-code/:pk/' + url_detail: '/project-code/:pk/', + api_endpoint: ApiPaths.project_code_list }, purchaseorder: { label: t`Purchase Order`, label_multiple: t`Purchase Orders`, url_overview: '/purchaseorder', - url_detail: '/purchaseorder/:pk/' + url_detail: '/purchaseorder/:pk/', + api_endpoint: ApiPaths.purchase_order_list }, purchaseorderline: { label: t`Purchase Order Line`, - label_multiple: t`Purchase Order Lines` + label_multiple: t`Purchase Order Lines`, + api_endpoint: ApiPaths.purchase_order_line_list }, salesorder: { label: t`Sales Order`, label_multiple: t`Sales Orders`, url_overview: '/salesorder', - url_detail: '/salesorder/:pk/' + url_detail: '/salesorder/:pk/', + api_endpoint: ApiPaths.sales_order_list }, salesordershipment: { label: t`Sales Order Shipment`, label_multiple: t`Sales Order Shipments`, url_overview: '/salesordershipment', - url_detail: '/salesordershipment/:pk/' + url_detail: '/salesordershipment/:pk/', + api_endpoint: ApiPaths.sales_order_shipment_list }, returnorder: { label: t`Return Order`, label_multiple: t`Return Orders`, url_overview: '/returnorder', - url_detail: '/returnorder/:pk/' + url_detail: '/returnorder/:pk/', + api_endpoint: ApiPaths.return_order_list }, address: { label: t`Address`, label_multiple: t`Addresses`, url_overview: '/address', - url_detail: '/address/:pk/' + url_detail: '/address/:pk/', + api_endpoint: ApiPaths.address_list }, contact: { label: t`Contact`, label_multiple: t`Contacts`, url_overview: '/contact', - url_detail: '/contact/:pk/' + url_detail: '/contact/:pk/', + api_endpoint: ApiPaths.contact_list }, owner: { label: t`Owner`, label_multiple: t`Owners`, url_overview: '/owner', - url_detail: '/owner/:pk/' + url_detail: '/owner/:pk/', + api_endpoint: ApiPaths.owner_list }, user: { label: t`User`, label_multiple: t`Users`, url_overview: '/user', - url_detail: '/user/:pk/' + url_detail: '/user/:pk/', + api_endpoint: ApiPaths.user_list } }; diff --git a/src/frontend/src/components/render/Order.tsx b/src/frontend/src/components/render/Order.tsx index e9d990be5e..df22461b30 100644 --- a/src/frontend/src/components/render/Order.tsx +++ b/src/frontend/src/components/render/Order.tsx @@ -1,7 +1,9 @@ import { t } from '@lingui/macro'; import { ReactNode } from 'react'; +import { ModelType } from '../../enums/ModelType'; import { RenderInlineModel } from './Instance'; +import { StatusRenderer } from './StatusRenderer'; /** * Inline rendering of a single PurchaseOrder instance @@ -18,6 +20,10 @@ export function RenderPurchaseOrder({ ); @@ -33,6 +39,10 @@ export function RenderReturnOrder({ instance }: { instance: any }): ReactNode { ); @@ -50,6 +60,10 @@ export function RenderSalesOrder({ instance }: { instance: any }): ReactNode { ); diff --git a/src/frontend/src/components/renderers/StatusRenderer.tsx b/src/frontend/src/components/render/StatusRenderer.tsx similarity index 97% rename from src/frontend/src/components/renderers/StatusRenderer.tsx rename to src/frontend/src/components/render/StatusRenderer.tsx index bcd1359f8a..73c9a527a2 100644 --- a/src/frontend/src/components/renderers/StatusRenderer.tsx +++ b/src/frontend/src/components/render/StatusRenderer.tsx @@ -1,8 +1,8 @@ import { Badge, Center, MantineSize } from '@mantine/core'; import { colorMap } from '../../defaults/backendMappings'; +import { ModelType } from '../../enums/ModelType'; import { useServerApiState } from '../../states/ApiState'; -import { ModelType } from '../render/ModelType'; interface StatusCodeInterface { key: string; diff --git a/src/frontend/src/components/render/Stock.tsx b/src/frontend/src/components/render/Stock.tsx index 9537480749..7738861e98 100644 --- a/src/frontend/src/components/render/Stock.tsx +++ b/src/frontend/src/components/render/Stock.tsx @@ -1,3 +1,4 @@ +import { t } from '@lingui/macro'; import { ReactNode } from 'react'; import { RenderInlineModel } from './Instance'; @@ -19,10 +20,18 @@ export function RenderStockLocation({ } export function RenderStockItem({ instance }: { instance: any }): ReactNode { + let quantity_string = ''; + + if (instance?.serial !== null && instance?.serial !== undefined) { + quantity_string += t`Serial Number` + `: ${instance.serial}`; + } else if (instance?.quantity) { + quantity_string = t`Quantity` + `: ${instance.quantity}`; + } + return ( ); diff --git a/src/frontend/src/components/renderers/BuildOrderRenderer.tsx b/src/frontend/src/components/renderers/BuildOrderRenderer.tsx deleted file mode 100644 index c683365a66..0000000000 --- a/src/frontend/src/components/renderers/BuildOrderRenderer.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Group } from '@mantine/core'; - -import { ApiPaths } from '../../states/ApiState'; -import { GeneralRenderer } from './GeneralRenderer'; -import { PartRenderer } from './PartRenderer'; - -export const BuildOrderRenderer = ({ pk }: { pk: string }) => { - const DetailRenderer = (data: any) => { - return ( - - {data?.reference} - - - - - ); - }; - return ( - - ); -}; diff --git a/src/frontend/src/components/renderers/GeneralRenderer.tsx b/src/frontend/src/components/renderers/GeneralRenderer.tsx deleted file mode 100644 index d100b14635..0000000000 --- a/src/frontend/src/components/renderers/GeneralRenderer.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { Anchor, Loader } from '@mantine/core'; -import { useQuery } from '@tanstack/react-query'; - -import { api } from '../../App'; -import { ApiPaths, apiUrl } from '../../states/ApiState'; -import { ThumbnailHoverCard } from '../images/Thumbnail'; - -export function GeneralRenderer({ - api_key, - api_ref: ref, - link, - pk, - image = true, - data = undefined, - renderer -}: { - api_key: ApiPaths; - api_ref: string; - link: string; - pk: string; - image?: boolean; - data?: any; - renderer?: (data: any) => JSX.Element; -}) { - // check if data was passed - or fetch it - if (!data) { - const { - data: fetched_data, - isError, - isFetching, - isLoading - } = useQuery({ - queryKey: [ref, pk], - queryFn: () => { - return api - .get(apiUrl(api_key, pk)) - .then((res) => res.data) - .catch(() => { - { - } - }); - } - }); - - // Loading section - if (isError) { - return
Something went wrong...
; - } - if (isFetching || isLoading) { - return ; - } - data = fetched_data; - } - - // Renderers - let content = undefined; - // Specific renderer was passed - if (renderer) content = renderer(data); - - // No image and no content no default renderer - if (image === false && !content) content = data.name; - - // Wrap in link if link was passed - if (content && link) { - content = ( - - {content} - - ); - } - - // Return content if it exists, else default - if (content !== undefined) { - return content; - } - return ( - - ); -} diff --git a/src/frontend/src/components/renderers/PartRenderer.tsx b/src/frontend/src/components/renderers/PartRenderer.tsx deleted file mode 100644 index 2738b5df1a..0000000000 --- a/src/frontend/src/components/renderers/PartRenderer.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { ApiPaths } from '../../states/ApiState'; -import { GeneralRenderer } from './GeneralRenderer'; - -export const PartRenderer = ({ - pk, - data = undefined, - link = true -}: { - pk: string; - data?: any; - link?: boolean; -}) => { - return ( - - ); -}; diff --git a/src/frontend/src/components/renderers/PurchaseOrderRenderer.tsx b/src/frontend/src/components/renderers/PurchaseOrderRenderer.tsx deleted file mode 100644 index d59b6789e1..0000000000 --- a/src/frontend/src/components/renderers/PurchaseOrderRenderer.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Group } from '@mantine/core'; - -import { ApiPaths } from '../../states/ApiState'; -import { GeneralRenderer } from './GeneralRenderer'; - -export const PurchaseOrderRenderer = ({ pk }: { pk: string }) => { - const DetailRenderer = (data: any) => { - const code = data?.project_code_detail?.code; - return ( - -
{data?.reference}
- {code &&
({code})
} - {data?.supplier_reference &&
{data?.supplier_reference}
} -
- ); - }; - return ( - - ); -}; diff --git a/src/frontend/src/components/renderers/SalesOrderRenderer.tsx b/src/frontend/src/components/renderers/SalesOrderRenderer.tsx deleted file mode 100644 index 006b2418da..0000000000 --- a/src/frontend/src/components/renderers/SalesOrderRenderer.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { ApiPaths } from '../../states/ApiState'; -import { GeneralRenderer } from './GeneralRenderer'; - -export const SalesOrderRenderer = ({ pk }: { pk: string }) => { - return ( - { - return data.reference; - }} - /> - ); -}; diff --git a/src/frontend/src/components/renderers/StockItemRenderer.tsx b/src/frontend/src/components/renderers/StockItemRenderer.tsx deleted file mode 100644 index bdd81b66b9..0000000000 --- a/src/frontend/src/components/renderers/StockItemRenderer.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Group } from '@mantine/core'; - -import { ApiPaths } from '../../states/ApiState'; -import { GeneralRenderer } from './GeneralRenderer'; -import { PartRenderer } from './PartRenderer'; - -export const StockItemRenderer = ({ pk }: { pk: string }) => { - const DetailRenderer = (data: any) => { - return ( - - {data?.quantity} - - - - - ); - }; - return ( - - ); -}; diff --git a/src/frontend/src/components/renderers/StockLocationRenderer.tsx b/src/frontend/src/components/renderers/StockLocationRenderer.tsx deleted file mode 100644 index 090d9614cd..0000000000 --- a/src/frontend/src/components/renderers/StockLocationRenderer.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { ApiPaths } from '../../states/ApiState'; -import { GeneralRenderer } from './GeneralRenderer'; - -export const StockLocationRenderer = ({ pk }: { pk: string }) => { - return ( - - ); -}; diff --git a/src/frontend/src/components/renderers/SupplierPartRenderer.tsx b/src/frontend/src/components/renderers/SupplierPartRenderer.tsx deleted file mode 100644 index 57b040a859..0000000000 --- a/src/frontend/src/components/renderers/SupplierPartRenderer.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Group } from '@mantine/core'; - -import { ApiPaths } from '../../states/ApiState'; -import { GeneralRenderer } from './GeneralRenderer'; -import { PartRenderer } from './PartRenderer'; - -export const SupplierPartRenderer = ({ pk }: { pk: string }) => { - const DetailRenderer = (data: any) => { - return ( - - {data?.SKU} - - - - - - - ); - }; - return ( - - ); -}; diff --git a/src/frontend/src/components/renderers/index.tsx b/src/frontend/src/components/renderers/index.tsx deleted file mode 100644 index af42b84c66..0000000000 --- a/src/frontend/src/components/renderers/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { BuildOrderRenderer } from './BuildOrderRenderer'; -import { PartRenderer } from './PartRenderer'; -import { PurchaseOrderRenderer } from './PurchaseOrderRenderer'; -import { SalesOrderRenderer } from './SalesOrderRenderer'; -import { StockItemRenderer } from './StockItemRenderer'; -import { StockLocationRenderer } from './StockLocationRenderer'; -import { SupplierPartRenderer } from './SupplierPartRenderer'; - -export enum RenderTypes { - part = 'part', - stock_item = 'stockitem', - stock_location = 'stocklocation', - supplier_part = 'supplierpart', - purchase_order = 'purchase_order', - sales_order = 'sales_order', - build_order = 'build_order' -} - -// dict of renderers -const renderers = { - [RenderTypes.part]: PartRenderer, - [RenderTypes.stock_item]: StockItemRenderer, - [RenderTypes.stock_location]: StockLocationRenderer, - [RenderTypes.supplier_part]: SupplierPartRenderer, - [RenderTypes.purchase_order]: PurchaseOrderRenderer, - [RenderTypes.sales_order]: SalesOrderRenderer, - [RenderTypes.build_order]: BuildOrderRenderer -}; - -export interface RenderProps { - type: RenderTypes; - pk: string; -} - -export function Render(props: RenderProps) { - const { type, ...rest } = props; - const RendererComponent = renderers[type]; - return ; -} diff --git a/src/frontend/src/components/tables/ColumnRenderers.tsx b/src/frontend/src/components/tables/ColumnRenderers.tsx index e6c845942f..daf81c011c 100644 --- a/src/frontend/src/components/tables/ColumnRenderers.tsx +++ b/src/frontend/src/components/tables/ColumnRenderers.tsx @@ -4,11 +4,11 @@ import { t } from '@lingui/macro'; import { formatCurrency, renderDate } from '../../defaults/formatters'; +import { ModelType } from '../../enums/ModelType'; import { ProgressBar } from '../items/ProgressBar'; import { YesNoButton } from '../items/YesNoButton'; -import { ModelType } from '../render/ModelType'; +import { TableStatusRenderer } from '../render/StatusRenderer'; import { RenderOwner } from '../render/User'; -import { TableStatusRenderer } from '../renderers/StatusRenderer'; import { TableColumn } from './Column'; import { ProjectCodeHoverCard } from './TableHoverCard'; diff --git a/src/frontend/src/components/tables/TableHoverCard.tsx b/src/frontend/src/components/tables/TableHoverCard.tsx index 9975e3eae7..8486845638 100644 --- a/src/frontend/src/components/tables/TableHoverCard.tsx +++ b/src/frontend/src/components/tables/TableHoverCard.tsx @@ -56,7 +56,11 @@ export function ProjectCodeHoverCard({ projectCode }: { projectCode: any }) { {projectCode?.description} + ) + } /> ) : ( '-' diff --git a/src/frontend/src/components/tables/bom/BomTable.tsx b/src/frontend/src/components/tables/bom/BomTable.tsx index 73ac081edf..ac46a504a4 100644 --- a/src/frontend/src/components/tables/bom/BomTable.tsx +++ b/src/frontend/src/components/tables/bom/BomTable.tsx @@ -8,11 +8,13 @@ import { import { ReactNode, useCallback, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; +import { UserRoles } from '../../../enums/Roles'; import { bomItemFields } from '../../../forms/BomForms'; import { openDeleteApiForm, openEditApiForm } from '../../../functions/forms'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; -import { UserRoles, useUserState } from '../../../states/UserState'; +import { apiUrl } from '../../../states/ApiState'; +import { useUserState } from '../../../states/UserState'; import { Thumbnail } from '../../images/Thumbnail'; import { YesNoButton } from '../../items/YesNoButton'; import { TableColumn } from '../Column'; @@ -64,7 +66,9 @@ export function BomTable({ let extra = []; if (record.part != partId) { - extra.push(t`This BOM item is defined for a different parent`); + extra.push( + {t`This BOM item is defined for a different parent`} + ); } return ( diff --git a/src/frontend/src/components/tables/bom/UsedInTable.tsx b/src/frontend/src/components/tables/bom/UsedInTable.tsx index 486c69e704..a16252bd3b 100644 --- a/src/frontend/src/components/tables/bom/UsedInTable.tsx +++ b/src/frontend/src/components/tables/bom/UsedInTable.tsx @@ -2,8 +2,9 @@ import { t } from '@lingui/macro'; import { useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; +import { apiUrl } from '../../../states/ApiState'; import { ThumbnailHoverCard } from '../../images/Thumbnail'; import { TableColumn } from '../Column'; import { TableFilter } from '../Filter'; diff --git a/src/frontend/src/components/tables/build/BuildOrderTable.tsx b/src/frontend/src/components/tables/build/BuildOrderTable.tsx index a1ff687cc7..4afbf112a9 100644 --- a/src/frontend/src/components/tables/build/BuildOrderTable.tsx +++ b/src/frontend/src/components/tables/build/BuildOrderTable.tsx @@ -3,11 +3,12 @@ import { useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { renderDate } from '../../../defaults/formatters'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; +import { ModelType } from '../../../enums/ModelType'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; +import { apiUrl } from '../../../states/ApiState'; import { ThumbnailHoverCard } from '../../images/Thumbnail'; import { ProgressBar } from '../../items/ProgressBar'; -import { ModelType } from '../../render/ModelType'; import { RenderUser } from '../../render/User'; import { TableColumn } from '../Column'; import { diff --git a/src/frontend/src/components/tables/general/AttachmentTable.tsx b/src/frontend/src/components/tables/general/AttachmentTable.tsx index 5519e0870a..6bc125c5cd 100644 --- a/src/frontend/src/components/tables/general/AttachmentTable.tsx +++ b/src/frontend/src/components/tables/general/AttachmentTable.tsx @@ -7,13 +7,14 @@ import { IconExternalLink, IconFileUpload } from '@tabler/icons-react'; import { ReactNode, useEffect, useMemo, useState } from 'react'; import { api } from '../../../App'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; import { addAttachment, deleteAttachment, editAttachment } from '../../../forms/AttachmentForms'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; +import { apiUrl } from '../../../states/ApiState'; import { AttachmentLink } from '../../items/AttachmentLink'; import { TableColumn } from '../Column'; import { InvenTreeTable } from '../InvenTreeTable'; diff --git a/src/frontend/src/components/tables/general/CompanyTable.tsx b/src/frontend/src/components/tables/general/CompanyTable.tsx index 97ec95c5c7..512c586d44 100644 --- a/src/frontend/src/components/tables/general/CompanyTable.tsx +++ b/src/frontend/src/components/tables/general/CompanyTable.tsx @@ -3,8 +3,9 @@ import { Group, Text } from '@mantine/core'; import { useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; +import { apiUrl } from '../../../states/ApiState'; import { Thumbnail } from '../../images/Thumbnail'; import { DescriptionColumn } from '../ColumnRenderers'; import { InvenTreeTable } from '../InvenTreeTable'; diff --git a/src/frontend/src/components/tables/notifications/NotificationsTable.tsx b/src/frontend/src/components/tables/notifications/NotificationsTable.tsx index 16743444dc..b53982c794 100644 --- a/src/frontend/src/components/tables/notifications/NotificationsTable.tsx +++ b/src/frontend/src/components/tables/notifications/NotificationsTable.tsx @@ -1,7 +1,8 @@ import { t } from '@lingui/macro'; import { useMemo } from 'react'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; +import { apiUrl } from '../../../states/ApiState'; import { TableColumn } from '../Column'; import { InvenTreeTable } from '../InvenTreeTable'; import { RowAction } from '../RowActions'; diff --git a/src/frontend/src/components/tables/part/PartCategoryTable.tsx b/src/frontend/src/components/tables/part/PartCategoryTable.tsx index 4688ea498d..fff25e95d0 100644 --- a/src/frontend/src/components/tables/part/PartCategoryTable.tsx +++ b/src/frontend/src/components/tables/part/PartCategoryTable.tsx @@ -2,8 +2,9 @@ import { t } from '@lingui/macro'; import { useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; +import { apiUrl } from '../../../states/ApiState'; import { TableColumn } from '../Column'; import { DescriptionColumn } from '../ColumnRenderers'; import { InvenTreeTable } from '../InvenTreeTable'; diff --git a/src/frontend/src/components/tables/part/PartParameterTable.tsx b/src/frontend/src/components/tables/part/PartParameterTable.tsx index fe7da2b1d0..4040601549 100644 --- a/src/frontend/src/components/tables/part/PartParameterTable.tsx +++ b/src/frontend/src/components/tables/part/PartParameterTable.tsx @@ -2,14 +2,16 @@ import { t } from '@lingui/macro'; import { Group, Text } from '@mantine/core'; import { useCallback, useMemo } from 'react'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; +import { UserRoles } from '../../../enums/Roles'; import { openCreateApiForm, openDeleteApiForm, openEditApiForm } from '../../../functions/forms'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; -import { UserRoles, useUserState } from '../../../states/UserState'; +import { apiUrl } from '../../../states/ApiState'; +import { useUserState } from '../../../states/UserState'; import { AddItemButton } from '../../buttons/AddItemButton'; import { Thumbnail } from '../../images/Thumbnail'; import { YesNoButton } from '../../items/YesNoButton'; @@ -178,7 +180,7 @@ export function PartParameterTable({ partId }: { partId: any }) { // TODO: Hide if user does not have permission to edit parts actions.push( - + ); return actions; diff --git a/src/frontend/src/components/tables/part/PartParameterTemplateTable.tsx b/src/frontend/src/components/tables/part/PartParameterTemplateTable.tsx index 46987253a2..164d754935 100644 --- a/src/frontend/src/components/tables/part/PartParameterTemplateTable.tsx +++ b/src/frontend/src/components/tables/part/PartParameterTemplateTable.tsx @@ -2,6 +2,8 @@ import { t } from '@lingui/macro'; import { Text } from '@mantine/core'; import { useCallback, useMemo } from 'react'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; +import { UserRoles } from '../../../enums/Roles'; import { partParameterTemplateFields } from '../../../forms/PartForms'; import { openCreateApiForm, @@ -9,8 +11,8 @@ import { openEditApiForm } from '../../../functions/forms'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; -import { UserRoles, useUserState } from '../../../states/UserState'; +import { apiUrl } from '../../../states/ApiState'; +import { useUserState } from '../../../states/UserState'; import { AddItemButton } from '../../buttons/AddItemButton'; import { TableColumn } from '../Column'; import { InvenTreeTable } from '../InvenTreeTable'; diff --git a/src/frontend/src/components/tables/part/PartTable.tsx b/src/frontend/src/components/tables/part/PartTable.tsx index fe35844af9..521116e254 100644 --- a/src/frontend/src/components/tables/part/PartTable.tsx +++ b/src/frontend/src/components/tables/part/PartTable.tsx @@ -3,9 +3,10 @@ import { Group, Text } from '@mantine/core'; import { ReactNode, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; import { shortenString } from '../../../functions/tables'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; +import { apiUrl } from '../../../states/ApiState'; import { Thumbnail } from '../../images/Thumbnail'; import { TableColumn } from '../Column'; import { DescriptionColumn, LinkColumn } from '../ColumnRenderers'; @@ -77,23 +78,29 @@ function partTableColumns(): TableColumn[] { if (min_stock > stock) { extra.push( - {t`Minimum stock` + `: ${min_stock}`} + + {t`Minimum stock` + `: ${min_stock}`} + ); color = 'orange'; } if (record.ordering > 0) { - extra.push({t`On Order` + `: ${record.ordering}`}); + extra.push( + {t`On Order` + `: ${record.ordering}`} + ); } if (record.building) { - extra.push({t`Building` + `: ${record.building}`}); + extra.push( + {t`Building` + `: ${record.building}`} + ); } if (record.allocated_to_build_orders > 0) { extra.push( - + {t`Build Order Allocations` + `: ${record.allocated_to_build_orders}`} @@ -102,7 +109,7 @@ function partTableColumns(): TableColumn[] { if (record.allocated_to_sales_orders > 0) { extra.push( - + {t`Sales Order Allocations` + `: ${record.allocated_to_sales_orders}`} @@ -110,7 +117,9 @@ function partTableColumns(): TableColumn[] { } if (available != stock) { - extra.push({t`Available` + `: ${available}`}); + extra.push( + {t`Available` + `: ${available}`} + ); } // TODO: Add extra information on stock "demand" diff --git a/src/frontend/src/components/tables/part/RelatedPartTable.tsx b/src/frontend/src/components/tables/part/RelatedPartTable.tsx index 2b76f1e520..4e099798e0 100644 --- a/src/frontend/src/components/tables/part/RelatedPartTable.tsx +++ b/src/frontend/src/components/tables/part/RelatedPartTable.tsx @@ -4,10 +4,12 @@ import { IconLayersLinked } from '@tabler/icons-react'; import { ReactNode, useCallback, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; +import { UserRoles } from '../../../enums/Roles'; import { openCreateApiForm, openDeleteApiForm } from '../../../functions/forms'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; -import { UserRoles, useUserState } from '../../../states/UserState'; +import { apiUrl } from '../../../states/ApiState'; +import { useUserState } from '../../../states/UserState'; import { Thumbnail } from '../../images/Thumbnail'; import { TableColumn } from '../Column'; import { InvenTreeTable } from '../InvenTreeTable'; diff --git a/src/frontend/src/components/tables/plugin/PluginListTable.tsx b/src/frontend/src/components/tables/plugin/PluginListTable.tsx index e0c352eaa4..48573b819a 100644 --- a/src/frontend/src/components/tables/plugin/PluginListTable.tsx +++ b/src/frontend/src/components/tables/plugin/PluginListTable.tsx @@ -10,8 +10,9 @@ import { import { useCallback, useMemo } from 'react'; import { api } from '../../../App'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; +import { apiUrl } from '../../../states/ApiState'; import { StylishText } from '../../items/StylishText'; import { TableColumn } from '../Column'; import { InvenTreeTable, InvenTreeTableProps } from '../InvenTreeTable'; diff --git a/src/frontend/src/components/tables/purchasing/PurchaseOrderLineItemTable.tsx b/src/frontend/src/components/tables/purchasing/PurchaseOrderLineItemTable.tsx index d758b31b71..e95cc67855 100644 --- a/src/frontend/src/components/tables/purchasing/PurchaseOrderLineItemTable.tsx +++ b/src/frontend/src/components/tables/purchasing/PurchaseOrderLineItemTable.tsx @@ -4,11 +4,13 @@ import { IconSquareArrowRight } from '@tabler/icons-react'; import { useCallback, useMemo } from 'react'; import { ProgressBar } from '../../../components/items/ProgressBar'; +import { ApiPaths } from '../../../enums/ApiEndpoints'; +import { UserRoles } from '../../../enums/Roles'; import { purchaseOrderLineItemFields } from '../../../forms/PurchaseOrderForms'; import { openCreateApiForm, openEditApiForm } from '../../../functions/forms'; import { useTableRefresh } from '../../../hooks/TableRefresh'; -import { ApiPaths, apiUrl } from '../../../states/ApiState'; -import { UserRoles, useUserState } from '../../../states/UserState'; +import { apiUrl } from '../../../states/ApiState'; +import { useUserState } from '../../../states/UserState'; import { ActionButton } from '../../buttons/ActionButton'; import { AddItemButton } from '../../buttons/AddItemButton'; import { Thumbnail } from '../../images/Thumbnail'; @@ -64,7 +66,8 @@ export function PurchaseOrderLineItemTable({ } let fields = purchaseOrderLineItemFields({ - supplierId: supplier + supplierId: supplier, + create: false }); openEditApiForm({ @@ -219,21 +222,29 @@ export function PurchaseOrderLineItemTable({ openCreateApiForm({ url: ApiPaths.purchase_order_line_list, title: t`Add Line Item`, - fields: purchaseOrderLineItemFields({}), + fields: purchaseOrderLineItemFields({ + create: true, + orderId: orderId + }), onFormSuccess: refreshTable, successMessage: t`Line item added` }); - }, []); + }, [orderId]); // Custom table actions const tableActions = useMemo(() => { return [