diff --git a/src/frontend/src/components/nav/SearchDrawer.tsx b/src/frontend/src/components/nav/SearchDrawer.tsx index f21cf55a52..0e5266901e 100644 --- a/src/frontend/src/components/nav/SearchDrawer.tsx +++ b/src/frontend/src/components/nav/SearchDrawer.tsx @@ -39,7 +39,7 @@ import { useUserSettingsState } from '../../states/SettingsState'; import { useUserState } from '../../states/UserState'; import { Boundary } from '../Boundary'; import { RenderInstance } from '../render/Instance'; -import { ModelInformationDict } from '../render/ModelType'; +import { ModelInformationDict, getModelInfo } from '../render/ModelType'; // Define type for handling individual search queries type SearchQuery = { @@ -65,7 +65,7 @@ function QueryResultGroup({ return null; } - const model = ModelInformationDict[query.model]; + const model = getModelInfo(query.model); return ( diff --git a/src/frontend/src/components/render/Company.tsx b/src/frontend/src/components/render/Company.tsx index 524d140851..9b472bac2f 100644 --- a/src/frontend/src/components/render/Company.tsx +++ b/src/frontend/src/components/render/Company.tsx @@ -1,3 +1,4 @@ +import { Text } from '@mantine/core'; import { ReactNode } from 'react'; import { ModelType } from '../../enums/ModelType'; @@ -70,7 +71,9 @@ export function RenderSupplierPart( primary={supplier?.name} secondary={instance.SKU} image={part?.thumbnail ?? part?.image} - suffix={part.full_name} + suffix={ + part.full_name ? {part.full_name} : undefined + } url={ props.link ? getDetailUrl(ModelType.supplierpart, instance.pk) @@ -95,7 +98,9 @@ export function RenderManufacturerPart( {...props} primary={manufacturer.name} secondary={instance.MPN} - suffix={part.full_name} + suffix={ + part.full_name ? {part.full_name} : undefined + } image={manufacturer?.thumnbnail ?? manufacturer.image} url={ props.link diff --git a/src/frontend/src/components/render/ModelType.tsx b/src/frontend/src/components/render/ModelType.tsx index 20b5fa1bb7..2df251d1f6 100644 --- a/src/frontend/src/components/render/ModelType.tsx +++ b/src/frontend/src/components/render/ModelType.tsx @@ -4,8 +4,6 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { ModelType } from '../../enums/ModelType'; export interface ModelInformationInterface { - label: string; - label_multiple: string; url_overview?: string; url_detail?: string; api_endpoint: ApiEndpoints; @@ -13,14 +11,19 @@ export interface ModelInformationInterface { admin_url?: string; } +// Interface which includes dynamically translated labels +export interface ModelInformationInterfaceWithLabel + extends ModelInformationInterface { + label: string; + label_multiple: string; +} + export type ModelDict = { [key in keyof typeof ModelType]: ModelInformationInterface; }; export const ModelInformationDict: ModelDict = { part: { - label: t`Part`, - label_multiple: t`Parts`, url_overview: '/part', url_detail: '/part/:pk/', cui_detail: '/part/:pk/', @@ -28,22 +31,16 @@ export const ModelInformationDict: ModelDict = { admin_url: '/part/part/' }, partparametertemplate: { - label: t`Part Parameter Template`, - label_multiple: t`Part Parameter Templates`, url_overview: '/partparametertemplate', url_detail: '/partparametertemplate/:pk/', api_endpoint: ApiEndpoints.part_parameter_template_list }, parttesttemplate: { - label: t`Part Test Template`, - label_multiple: t`Part Test Templates`, url_overview: '/parttesttemplate', url_detail: '/parttesttemplate/:pk/', api_endpoint: ApiEndpoints.part_test_template_list }, supplierpart: { - label: t`Supplier Part`, - label_multiple: t`Supplier Parts`, url_overview: '/supplierpart', url_detail: '/purchasing/supplier-part/:pk/', cui_detail: '/supplier-part/:pk/', @@ -51,8 +48,6 @@ export const ModelInformationDict: ModelDict = { admin_url: '/company/supplierpart/' }, manufacturerpart: { - label: t`Manufacturer Part`, - label_multiple: t`Manufacturer Parts`, url_overview: '/manufacturerpart', url_detail: '/purchasing/manufacturer-part/:pk/', cui_detail: '/manufacturer-part/:pk/', @@ -60,8 +55,6 @@ export const ModelInformationDict: ModelDict = { admin_url: '/company/manufacturerpart/' }, partcategory: { - label: t`Part Category`, - label_multiple: t`Part Categories`, url_overview: '/part/category', url_detail: '/part/category/:pk/', cui_detail: '/part/category/:pk/', @@ -69,8 +62,6 @@ export const ModelInformationDict: ModelDict = { admin_url: '/part/partcategory/' }, stockitem: { - label: t`Stock Item`, - label_multiple: t`Stock Items`, url_overview: '/stock/item', url_detail: '/stock/item/:pk/', cui_detail: '/stock/item/:pk/', @@ -78,8 +69,6 @@ export const ModelInformationDict: ModelDict = { admin_url: '/stock/stockitem/' }, stocklocation: { - label: t`Stock Location`, - label_multiple: t`Stock Locations`, url_overview: '/stock/location', url_detail: '/stock/location/:pk/', cui_detail: '/stock/location/:pk/', @@ -87,18 +76,12 @@ export const ModelInformationDict: ModelDict = { admin_url: '/stock/stocklocation/' }, stocklocationtype: { - label: t`Stock Location Type`, - label_multiple: t`Stock Location Types`, api_endpoint: ApiEndpoints.stock_location_type_list }, stockhistory: { - label: t`Stock History`, - label_multiple: t`Stock Histories`, api_endpoint: ApiEndpoints.stock_tracking_list }, build: { - label: t`Build`, - label_multiple: t`Builds`, url_overview: '/build', url_detail: '/build/:pk/', cui_detail: '/build/:pk/', @@ -106,21 +89,15 @@ export const ModelInformationDict: ModelDict = { admin_url: '/build/build/' }, buildline: { - label: t`Build Line`, - label_multiple: t`Build Lines`, url_overview: '/build/line', url_detail: '/build/line/:pk/', cui_detail: '/build/line/:pk/', api_endpoint: ApiEndpoints.build_line_list }, builditem: { - label: t`Build Item`, - label_multiple: t`Build Items`, api_endpoint: ApiEndpoints.build_item_list }, company: { - label: t`Company`, - label_multiple: t`Companies`, url_overview: '/company', url_detail: '/company/:pk/', cui_detail: '/company/:pk/', @@ -128,15 +105,11 @@ export const ModelInformationDict: ModelDict = { admin_url: '/company/company/' }, projectcode: { - label: t`Project Code`, - label_multiple: t`Project Codes`, url_overview: '/project-code', url_detail: '/project-code/:pk/', api_endpoint: ApiEndpoints.project_code_list }, purchaseorder: { - label: t`Purchase Order`, - label_multiple: t`Purchase Orders`, url_overview: '/purchasing/purchase-order', url_detail: '/purchasing/purchase-order/:pk/', cui_detail: '/order/purchase-order/:pk/', @@ -144,13 +117,9 @@ export const ModelInformationDict: ModelDict = { admin_url: '/order/purchaseorder/' }, purchaseorderlineitem: { - label: t`Purchase Order Line`, - label_multiple: t`Purchase Order Lines`, api_endpoint: ApiEndpoints.purchase_order_line_list }, salesorder: { - label: t`Sales Order`, - label_multiple: t`Sales Orders`, url_overview: '/sales/sales-order', url_detail: '/sales/sales-order/:pk/', cui_detail: '/order/sales-order/:pk/', @@ -158,15 +127,11 @@ export const ModelInformationDict: ModelDict = { admin_url: '/order/salesorder/' }, salesordershipment: { - label: t`Sales Order Shipment`, - label_multiple: t`Sales Order Shipments`, url_overview: '/salesordershipment', url_detail: '/salesordershipment/:pk/', api_endpoint: ApiEndpoints.sales_order_shipment_list }, returnorder: { - label: t`Return Order`, - label_multiple: t`Return Orders`, url_overview: '/sales/return-order', url_detail: '/sales/return-order/:pk/', cui_detail: '/order/return-order/:pk/', @@ -174,86 +139,216 @@ export const ModelInformationDict: ModelDict = { admin_url: '/order/returnorder/' }, returnorderlineitem: { - label: t`Return Order Line Item`, - label_multiple: t`Return Order Line Items`, api_endpoint: ApiEndpoints.return_order_line_list }, address: { - label: t`Address`, - label_multiple: t`Addresses`, url_overview: '/address', url_detail: '/address/:pk/', api_endpoint: ApiEndpoints.address_list }, contact: { - label: t`Contact`, - label_multiple: t`Contacts`, url_overview: '/contact', url_detail: '/contact/:pk/', api_endpoint: ApiEndpoints.contact_list }, owner: { - label: t`Owner`, - label_multiple: t`Owners`, url_overview: '/owner', url_detail: '/owner/:pk/', api_endpoint: ApiEndpoints.owner_list }, user: { - label: t`User`, - label_multiple: t`Users`, url_overview: '/user', url_detail: '/user/:pk/', api_endpoint: ApiEndpoints.user_list }, group: { - label: t`Group`, - label_multiple: t`Groups`, url_overview: '/user/group', url_detail: '/user/group-:pk', api_endpoint: ApiEndpoints.group_list, admin_url: '/auth/group/' }, importsession: { - label: t`Import Session`, - label_multiple: t`Import Sessions`, url_overview: '/import', url_detail: '/import/:pk/', api_endpoint: ApiEndpoints.import_session_list }, labeltemplate: { - label: t`Label Template`, - label_multiple: t`Label Templates`, url_overview: '/labeltemplate', url_detail: '/labeltemplate/:pk/', api_endpoint: ApiEndpoints.label_list }, reporttemplate: { - label: t`Report Template`, - label_multiple: t`Report Templates`, url_overview: '/reporttemplate', url_detail: '/reporttemplate/:pk/', api_endpoint: ApiEndpoints.report_list }, pluginconfig: { - label: t`Plugin Configuration`, - label_multiple: t`Plugin Configurations`, url_overview: '/pluginconfig', url_detail: '/pluginconfig/:pk/', api_endpoint: ApiEndpoints.plugin_list }, contenttype: { - label: t`Content Type`, - label_multiple: t`Content Types`, api_endpoint: ApiEndpoints.content_type_list } }; +/* + * Return the translated singular label for a particular model type. + * Note: This *must* be called dynamically, as the translation is not static. + */ +export function getModelLabel(type: ModelType): string { + switch (type) { + case ModelType.part: + return t`Part`; + case ModelType.partparametertemplate: + return t`Part Parameter Template`; + case ModelType.parttesttemplate: + return t`Part Test Template`; + case ModelType.supplierpart: + return t`Supplier Part`; + case ModelType.manufacturerpart: + return t`Manufacturer Part`; + case ModelType.partcategory: + return t`Part Category`; + case ModelType.stockitem: + return t`Stock Item`; + case ModelType.stocklocation: + return t`Stock Location`; + case ModelType.stocklocationtype: + return t`Stock Location Type`; + case ModelType.stockhistory: + return t`Stock History`; + case ModelType.build: + return t`Build Order`; + case ModelType.buildline: + return t`Build Line`; + case ModelType.builditem: + return t`Build Item`; + case ModelType.company: + return t`Company`; + case ModelType.projectcode: + return t`Project Code`; + case ModelType.purchaseorder: + return t`Purchase Order`; + case ModelType.purchaseorderlineitem: + return t`Purchase Order Line Item`; + case ModelType.salesorder: + return t`Sales Order`; + case ModelType.salesordershipment: + return t`Sales Order Shipment`; + case ModelType.returnorder: + return t`Return Order`; + case ModelType.returnorderlineitem: + return t`Return Order Line Item`; + case ModelType.address: + return t`Address`; + case ModelType.contact: + return t`Contact`; + case ModelType.owner: + return t`Owner`; + case ModelType.user: + return t`User`; + case ModelType.group: + return t`Group`; + case ModelType.importsession: + return t`Import Session`; + case ModelType.labeltemplate: + return t`Label Template`; + case ModelType.reporttemplate: + return t`Report Template`; + case ModelType.pluginconfig: + return t`Plugin Configuration`; + case ModelType.contenttype: + return t`Content Type`; + default: + return t`Unknown Model`; + } +} + +/* + * Return the translated plural label for a particular model type. + * Note: This *must* be called dynamically, as the translation is not static. + */ +export function getModelLabelMultiple(type: ModelType): string { + switch (type) { + case ModelType.part: + return t`Parts`; + case ModelType.partparametertemplate: + return t`Part Parameter Templates`; + case ModelType.parttesttemplate: + return t`Part Test Templates`; + case ModelType.supplierpart: + return t`Supplier Parts`; + case ModelType.manufacturerpart: + return t`Manufacturer Parts`; + case ModelType.partcategory: + return t`Part Categories`; + case ModelType.stockitem: + return t`Stock Items`; + case ModelType.stocklocation: + return t`Stock Locations`; + case ModelType.stocklocationtype: + return t`Stock Location Types`; + case ModelType.stockhistory: + return t`Stock Histories`; + case ModelType.build: + return t`Build Orders`; + case ModelType.buildline: + return t`Build Lines`; + case ModelType.builditem: + return t`Build Items`; + case ModelType.company: + return t`Companies`; + case ModelType.projectcode: + return t`Project Codes`; + case ModelType.purchaseorder: + return t`Purchase Orders`; + case ModelType.purchaseorderlineitem: + return t`Purchase Order Line Items`; + case ModelType.salesorder: + return t`Sales Orders`; + case ModelType.salesordershipment: + return t`Sales Order Shipments`; + case ModelType.returnorder: + return t`Return Orders`; + case ModelType.returnorderlineitem: + return t`Return Order Line Items`; + case ModelType.address: + return t`Addresses`; + case ModelType.contact: + return t`Contacts`; + case ModelType.owner: + return t`Owners`; + case ModelType.user: + return t`Users`; + case ModelType.group: + return t`Groups`; + case ModelType.importsession: + return t`Import Sessions`; + case ModelType.labeltemplate: + return t`Label Templates`; + case ModelType.reporttemplate: + return t`Report Templates`; + case ModelType.pluginconfig: + return t`Plugin Configurations`; + case ModelType.contenttype: + return t`Content Types`; + default: + return t`Unknown Models`; + } +} + /* * Extract model definition given the provided type * @param type - ModelType to extract information from - * @returns ModelInformationInterface + * @returns ModelInformationInterfaceWithLabel */ -export function getModelInfo(type: ModelType): ModelInformationInterface { - return ModelInformationDict[type]; +export function getModelInfo( + type: ModelType +): ModelInformationInterfaceWithLabel { + return { + ...ModelInformationDict[type], + label: getModelLabel(type), + label_multiple: getModelLabelMultiple(type) + }; } diff --git a/src/frontend/src/components/render/Stock.tsx b/src/frontend/src/components/render/Stock.tsx index d42c52f58b..6d0854f05c 100644 --- a/src/frontend/src/components/render/Stock.tsx +++ b/src/frontend/src/components/render/Stock.tsx @@ -1,4 +1,5 @@ import { t } from '@lingui/macro'; +import { Text } from '@mantine/core'; import { ReactNode } from 'react'; import { ModelType } from '../../enums/ModelType'; @@ -66,7 +67,7 @@ export function RenderStockItem( {quantity_string}} image={instance.part_detail?.thumbnail || instance.part_detail?.image} url={ props.link ? getDetailUrl(ModelType.stockitem, instance.pk) : undefined