mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-05 06:48:48 +00:00
Type model information in SearchDrawer (#5597)
* moved search query to strongly typed model reference * move title and link to reusable typed section * typed ApiFormFieldType.model too * renamed symbol * switched to lookup
This commit is contained in:
parent
e76fa11e63
commit
608ca75763
@ -14,6 +14,7 @@ import { IconX } from '@tabler/icons-react';
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
import { ModelType } from '../../render/ModelType';
|
||||||
import { ApiFormProps } from '../ApiForm';
|
import { ApiFormProps } from '../ApiForm';
|
||||||
import { ChoiceField } from './ChoiceField';
|
import { ChoiceField } from './ChoiceField';
|
||||||
import { RelatedModelField } from './RelatedModelField';
|
import { RelatedModelField } from './RelatedModelField';
|
||||||
@ -63,7 +64,7 @@ export type ApiFormFieldType = {
|
|||||||
fieldType?: string;
|
fieldType?: string;
|
||||||
api_url?: string;
|
api_url?: string;
|
||||||
read_only?: boolean;
|
read_only?: boolean;
|
||||||
model?: string;
|
model?: ModelType;
|
||||||
filters?: any;
|
filters?: any;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
choices?: any[];
|
choices?: any[];
|
||||||
|
@ -160,7 +160,7 @@ export function RelatedModelField({
|
|||||||
// TODO: If a custom render function is provided, use that
|
// TODO: If a custom render function is provided, use that
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RenderInstance instance={data} model={definition.model ?? 'undefined'} />
|
<RenderInstance instance={data} model={definition.model ?? undefined} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,11 +31,11 @@ import { useNavigate } from 'react-router-dom';
|
|||||||
|
|
||||||
import { api } from '../../App';
|
import { api } from '../../App';
|
||||||
import { RenderInstance } from '../render/Instance';
|
import { RenderInstance } from '../render/Instance';
|
||||||
|
import { ModelInformationDict, ModelType } from '../render/ModelType';
|
||||||
|
|
||||||
// Define type for handling individual search queries
|
// Define type for handling individual search queries
|
||||||
type SearchQuery = {
|
type SearchQuery = {
|
||||||
name: string;
|
name: ModelType;
|
||||||
title: string;
|
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
parameters: any;
|
parameters: any;
|
||||||
results?: any;
|
results?: any;
|
||||||
@ -57,16 +57,14 @@ function settingsCheck(setting: string) {
|
|||||||
function buildSearchQueries(): SearchQuery[] {
|
function buildSearchQueries(): SearchQuery[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
name: 'part',
|
name: ModelType.part,
|
||||||
title: t`Parts`,
|
|
||||||
parameters: {},
|
parameters: {},
|
||||||
enabled:
|
enabled:
|
||||||
permissionCheck('part.view') &&
|
permissionCheck('part.view') &&
|
||||||
settingsCheck('SEARCH_PREVIEW_SHOW_PARTS')
|
settingsCheck('SEARCH_PREVIEW_SHOW_PARTS')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'supplierpart',
|
name: ModelType.supplierpart,
|
||||||
title: t`Supplier Parts`,
|
|
||||||
parameters: {
|
parameters: {
|
||||||
part_detail: true,
|
part_detail: true,
|
||||||
supplier_detail: true,
|
supplier_detail: true,
|
||||||
@ -78,8 +76,7 @@ function buildSearchQueries(): SearchQuery[] {
|
|||||||
settingsCheck('SEARCH_PREVIEW_SHOW_SUPPLIER_PARTS')
|
settingsCheck('SEARCH_PREVIEW_SHOW_SUPPLIER_PARTS')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'manufacturerpart',
|
name: ModelType.manufacturerpart,
|
||||||
title: t`Manufacturer Parts`,
|
|
||||||
parameters: {
|
parameters: {
|
||||||
part_detail: true,
|
part_detail: true,
|
||||||
supplier_detail: true,
|
supplier_detail: true,
|
||||||
@ -91,16 +88,14 @@ function buildSearchQueries(): SearchQuery[] {
|
|||||||
settingsCheck('SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS')
|
settingsCheck('SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'partcategory',
|
name: ModelType.partcategory,
|
||||||
title: t`Part Categories`,
|
|
||||||
parameters: {},
|
parameters: {},
|
||||||
enabled:
|
enabled:
|
||||||
permissionCheck('part_category.view') &&
|
permissionCheck('part_category.view') &&
|
||||||
settingsCheck('SEARCH_PREVIEW_SHOW_CATEGORIES')
|
settingsCheck('SEARCH_PREVIEW_SHOW_CATEGORIES')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'stockitem',
|
name: ModelType.stockitem,
|
||||||
title: t`Stock Items`,
|
|
||||||
parameters: {
|
parameters: {
|
||||||
part_detail: true,
|
part_detail: true,
|
||||||
location_detail: true
|
location_detail: true
|
||||||
@ -110,16 +105,14 @@ function buildSearchQueries(): SearchQuery[] {
|
|||||||
settingsCheck('SEARCH_PREVIEW_SHOW_STOCK')
|
settingsCheck('SEARCH_PREVIEW_SHOW_STOCK')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'stocklocation',
|
name: ModelType.stocklocation,
|
||||||
title: t`Stock Locations`,
|
|
||||||
parameters: {},
|
parameters: {},
|
||||||
enabled:
|
enabled:
|
||||||
permissionCheck('stock_location.view') &&
|
permissionCheck('stock_location.view') &&
|
||||||
settingsCheck('SEARCH_PREVIEW_SHOW_LOCATIONS')
|
settingsCheck('SEARCH_PREVIEW_SHOW_LOCATIONS')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'build',
|
name: ModelType.build,
|
||||||
title: t`Build Orders`,
|
|
||||||
parameters: {
|
parameters: {
|
||||||
part_detail: true
|
part_detail: true
|
||||||
},
|
},
|
||||||
@ -128,8 +121,7 @@ function buildSearchQueries(): SearchQuery[] {
|
|||||||
settingsCheck('SEARCH_PREVIEW_SHOW_BUILD_ORDERS')
|
settingsCheck('SEARCH_PREVIEW_SHOW_BUILD_ORDERS')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'company',
|
name: ModelType.company,
|
||||||
title: t`Companies`,
|
|
||||||
parameters: {},
|
parameters: {},
|
||||||
enabled:
|
enabled:
|
||||||
(permissionCheck('sales_order.view') ||
|
(permissionCheck('sales_order.view') ||
|
||||||
@ -137,8 +129,7 @@ function buildSearchQueries(): SearchQuery[] {
|
|||||||
settingsCheck('SEARCH_PREVIEW_SHOW_COMPANIES')
|
settingsCheck('SEARCH_PREVIEW_SHOW_COMPANIES')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'purchaseorder',
|
name: ModelType.purchaseorder,
|
||||||
title: t`Purchase Orders`,
|
|
||||||
parameters: {
|
parameters: {
|
||||||
supplier_detail: true
|
supplier_detail: true
|
||||||
},
|
},
|
||||||
@ -147,8 +138,7 @@ function buildSearchQueries(): SearchQuery[] {
|
|||||||
settingsCheck(`SEARCH_PREVIEW_SHOW_PURCHASE_ORDERS`)
|
settingsCheck(`SEARCH_PREVIEW_SHOW_PURCHASE_ORDERS`)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'salesorder',
|
name: ModelType.salesorder,
|
||||||
title: t`Sales Orders`,
|
|
||||||
parameters: {
|
parameters: {
|
||||||
customer_detail: true
|
customer_detail: true
|
||||||
},
|
},
|
||||||
@ -157,8 +147,7 @@ function buildSearchQueries(): SearchQuery[] {
|
|||||||
settingsCheck(`SEARCH_PREVIEW_SHOW_SALES_ORDERS`)
|
settingsCheck(`SEARCH_PREVIEW_SHOW_SALES_ORDERS`)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'returnorder',
|
name: ModelType.returnorder,
|
||||||
title: t`Return Orders`,
|
|
||||||
parameters: {
|
parameters: {
|
||||||
customer_detail: true
|
customer_detail: true
|
||||||
},
|
},
|
||||||
@ -178,19 +167,20 @@ function QueryResultGroup({
|
|||||||
onResultClick
|
onResultClick
|
||||||
}: {
|
}: {
|
||||||
query: SearchQuery;
|
query: SearchQuery;
|
||||||
onRemove: (query: string) => void;
|
onRemove: (query: ModelType) => void;
|
||||||
onResultClick: (query: string, pk: number) => void;
|
onResultClick: (query: ModelType, pk: number) => void;
|
||||||
}) {
|
}) {
|
||||||
if (query.results.count == 0) {
|
if (query.results.count == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const model = ModelInformationDict[query.name];
|
||||||
return (
|
return (
|
||||||
<Paper shadow="sm" radius="xs" p="md">
|
<Paper shadow="sm" radius="xs" p="md">
|
||||||
<Stack key={query.name}>
|
<Stack key={query.name}>
|
||||||
<Group position="apart" noWrap={true}>
|
<Group position="apart" noWrap={true}>
|
||||||
<Group position="left" spacing={5} noWrap={true}>
|
<Group position="left" spacing={5} noWrap={true}>
|
||||||
<Text size="lg">{query.title}</Text>
|
<Text size="lg">{model.label_multiple}</Text>
|
||||||
<Text size="sm" italic>
|
<Text size="sm" italic>
|
||||||
{' '}
|
{' '}
|
||||||
- {query.results.count} <Trans>results</Trans>
|
- {query.results.count} <Trans>results</Trans>
|
||||||
@ -320,7 +310,7 @@ export function SearchDrawer({
|
|||||||
}, [searchQuery.data]);
|
}, [searchQuery.data]);
|
||||||
|
|
||||||
// Callback to remove a set of results from the list
|
// Callback to remove a set of results from the list
|
||||||
function removeResults(query: string) {
|
function removeResults(query: ModelType) {
|
||||||
setQueryResults(queryResults.filter((q) => q.name != query));
|
setQueryResults(queryResults.filter((q) => q.name != query));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,9 +323,11 @@ export function SearchDrawer({
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// Callback when one of the search results is clicked
|
// Callback when one of the search results is clicked
|
||||||
function onResultClick(query: string, pk: number) {
|
function onResultClick(query: ModelType, pk: number) {
|
||||||
closeDrawer();
|
closeDrawer();
|
||||||
navigate(`/${query}/${pk}/`);
|
navigate(
|
||||||
|
ModelInformationDict[query].url_detail.replace(':pk', pk.toString())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -5,16 +5,12 @@ import { RenderInlineModel } from './Instance';
|
|||||||
/**
|
/**
|
||||||
* Inline rendering of a single BuildOrder instance
|
* Inline rendering of a single BuildOrder instance
|
||||||
*/
|
*/
|
||||||
export function RenderBuildOrder({
|
export function RenderBuildOrder({ instance }: { instance: any }): ReactNode {
|
||||||
buildorder
|
|
||||||
}: {
|
|
||||||
buildorder: any;
|
|
||||||
}): ReactNode {
|
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={buildorder.reference}
|
primary={instance.reference}
|
||||||
secondary={buildorder.title}
|
secondary={instance.title}
|
||||||
image={buildorder.part_detail?.thumbnail || buildorder.part_detail?.image}
|
image={instance.part_detail?.thumbnail || instance.part_detail?.image}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,23 +5,23 @@ import { RenderInlineModel } from './Instance';
|
|||||||
/**
|
/**
|
||||||
* Inline rendering of a single Address instance
|
* Inline rendering of a single Address instance
|
||||||
*/
|
*/
|
||||||
export function RenderAddress({ address }: { address: any }): ReactNode {
|
export function RenderAddress({ instance }: { instance: any }): ReactNode {
|
||||||
let text = [
|
let text = [
|
||||||
address.title,
|
instance.title,
|
||||||
address.country,
|
instance.country,
|
||||||
address.postal_code,
|
instance.postal_code,
|
||||||
address.postal_city,
|
instance.postal_city,
|
||||||
address.province,
|
instance.province,
|
||||||
address.line1,
|
instance.line1,
|
||||||
address.line2
|
instance.line2
|
||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={address.description}
|
primary={instance.description}
|
||||||
secondary={address.address}
|
secondary={instance.address}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -29,14 +29,14 @@ export function RenderAddress({ address }: { address: any }): ReactNode {
|
|||||||
/**
|
/**
|
||||||
* Inline rendering of a single Company instance
|
* Inline rendering of a single Company instance
|
||||||
*/
|
*/
|
||||||
export function RenderCompany({ company }: { company: any }): ReactNode {
|
export function RenderCompany({ instance }: { instance: any }): ReactNode {
|
||||||
// TODO: Handle URL
|
// TODO: Handle URL
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
image={company.thumnbnail || company.image}
|
image={instance.thumnbnail || instance.image}
|
||||||
primary={company.name}
|
primary={instance.name}
|
||||||
secondary={company.description}
|
secondary={instance.description}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -44,25 +44,37 @@ export function RenderCompany({ company }: { company: any }): ReactNode {
|
|||||||
/**
|
/**
|
||||||
* Inline rendering of a single Contact instance
|
* Inline rendering of a single Contact instance
|
||||||
*/
|
*/
|
||||||
export function RenderContact({ contact }: { contact: any }): ReactNode {
|
export function RenderContact({ instance }: { instance: any }): ReactNode {
|
||||||
return <RenderInlineModel primary={contact.name} />;
|
return <RenderInlineModel primary={instance.name} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inline rendering of a single SupplierPart instance
|
* Inline rendering of a single SupplierPart instance
|
||||||
*/
|
*/
|
||||||
export function RenderSupplierPart({
|
export function RenderSupplierPart({ instance }: { instance: any }): ReactNode {
|
||||||
supplierpart
|
|
||||||
}: {
|
|
||||||
supplierpart: any;
|
|
||||||
}): ReactNode {
|
|
||||||
// TODO: Handle image
|
// TODO: Handle image
|
||||||
// TODO: handle URL
|
// TODO: handle URL
|
||||||
|
|
||||||
let supplier = supplierpart.supplier_detail ?? {};
|
let supplier = instance.supplier_detail ?? {};
|
||||||
let part = supplierpart.part_detail ?? {};
|
let part = instance.part_detail ?? {};
|
||||||
|
|
||||||
let text = supplierpart.SKU;
|
let text = instance.SKU;
|
||||||
|
|
||||||
|
if (supplier.name) {
|
||||||
|
text = `${supplier.name} | ${text}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <RenderInlineModel primary={text} secondary={part.full_name} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inline rendering of a single ManufacturerPart instance
|
||||||
|
*/
|
||||||
|
export function ManufacturerPart({ instance }: { instance: any }): ReactNode {
|
||||||
|
let supplier = instance.supplier_detail ?? {};
|
||||||
|
let part = instance.part_detail ?? {};
|
||||||
|
|
||||||
|
let text = instance.SKU;
|
||||||
|
|
||||||
if (supplier.name) {
|
if (supplier.name) {
|
||||||
text = `${supplier.name} | ${text}`;
|
text = `${supplier.name} | ${text}`;
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
RenderContact,
|
RenderContact,
|
||||||
RenderSupplierPart
|
RenderSupplierPart
|
||||||
} from './Company';
|
} from './Company';
|
||||||
|
import { ModelType } from './ModelType';
|
||||||
import {
|
import {
|
||||||
RenderPurchaseOrder,
|
RenderPurchaseOrder,
|
||||||
RenderReturnOrder,
|
RenderReturnOrder,
|
||||||
@ -21,6 +22,35 @@ import { RenderPart, RenderPartCategory } from './Part';
|
|||||||
import { RenderStockItem, RenderStockLocation } from './Stock';
|
import { RenderStockItem, RenderStockLocation } from './Stock';
|
||||||
import { RenderOwner, RenderUser } from './User';
|
import { RenderOwner, RenderUser } from './User';
|
||||||
|
|
||||||
|
type EnumDictionary<T extends string | symbol | number, U> = {
|
||||||
|
[K in T]: U;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup table for rendering a model instance
|
||||||
|
*/
|
||||||
|
const RendererLookup: EnumDictionary<
|
||||||
|
ModelType,
|
||||||
|
(props: { instance: any }) => ReactNode
|
||||||
|
> = {
|
||||||
|
[ModelType.address]: RenderAddress,
|
||||||
|
[ModelType.build]: RenderBuildOrder,
|
||||||
|
[ModelType.company]: RenderCompany,
|
||||||
|
[ModelType.contact]: RenderContact,
|
||||||
|
[ModelType.owner]: RenderOwner,
|
||||||
|
[ModelType.part]: RenderPart,
|
||||||
|
[ModelType.partcategory]: RenderPartCategory,
|
||||||
|
[ModelType.purchaseorder]: RenderPurchaseOrder,
|
||||||
|
[ModelType.returnorder]: RenderReturnOrder,
|
||||||
|
[ModelType.salesorder]: RenderSalesOrder,
|
||||||
|
[ModelType.salesordershipment]: RenderSalesOrderShipment,
|
||||||
|
[ModelType.stocklocation]: RenderStockLocation,
|
||||||
|
[ModelType.stockitem]: RenderStockItem,
|
||||||
|
[ModelType.supplierpart]: RenderSupplierPart,
|
||||||
|
[ModelType.user]: RenderUser,
|
||||||
|
[ModelType.manufacturerpart]: RenderPart
|
||||||
|
};
|
||||||
|
|
||||||
// import { ApiFormFieldType } from "../forms/fields/ApiFormField";
|
// import { ApiFormFieldType } from "../forms/fields/ApiFormField";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,48 +60,12 @@ export function RenderInstance({
|
|||||||
model,
|
model,
|
||||||
instance
|
instance
|
||||||
}: {
|
}: {
|
||||||
model: string;
|
model: ModelType | undefined;
|
||||||
instance: any;
|
instance: any;
|
||||||
}): ReactNode {
|
}): ReactNode {
|
||||||
switch (model) {
|
if (model === undefined) return <UnknownRenderer model={model} />;
|
||||||
case 'address':
|
const RenderComponent = RendererLookup[model];
|
||||||
return <RenderAddress address={instance} />;
|
return <RenderComponent instance={instance} />;
|
||||||
case 'build':
|
|
||||||
return <RenderBuildOrder buildorder={instance} />;
|
|
||||||
case 'company':
|
|
||||||
return <RenderCompany company={instance} />;
|
|
||||||
case 'contact':
|
|
||||||
return <RenderContact contact={instance} />;
|
|
||||||
case 'owner':
|
|
||||||
return <RenderOwner owner={instance} />;
|
|
||||||
case 'part':
|
|
||||||
return <RenderPart part={instance} />;
|
|
||||||
case 'partcategory':
|
|
||||||
return <RenderPartCategory category={instance} />;
|
|
||||||
case 'purchaseorder':
|
|
||||||
return <RenderPurchaseOrder order={instance} />;
|
|
||||||
case 'returnorder':
|
|
||||||
return <RenderReturnOrder order={instance} />;
|
|
||||||
case 'salesoder':
|
|
||||||
return <RenderSalesOrder order={instance} />;
|
|
||||||
case 'salesordershipment':
|
|
||||||
return <RenderSalesOrderShipment shipment={instance} />;
|
|
||||||
case 'stocklocation':
|
|
||||||
return <RenderStockLocation location={instance} />;
|
|
||||||
case 'stockitem':
|
|
||||||
return <RenderStockItem item={instance} />;
|
|
||||||
case 'supplierpart':
|
|
||||||
return <RenderSupplierPart supplierpart={instance} />;
|
|
||||||
case 'user':
|
|
||||||
return <RenderUser user={instance} />;
|
|
||||||
default:
|
|
||||||
// Unknown model
|
|
||||||
return (
|
|
||||||
<Alert color="red" title={t`Unknown model: ${model}`}>
|
|
||||||
<></>
|
|
||||||
</Alert>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,3 +95,15 @@ export function RenderInlineModel({
|
|||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function UnknownRenderer({
|
||||||
|
model
|
||||||
|
}: {
|
||||||
|
model: ModelType | undefined;
|
||||||
|
}): ReactNode {
|
||||||
|
return (
|
||||||
|
<Alert color="red" title={t`Unknown model: ${model}`}>
|
||||||
|
<></>
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
130
src/frontend/src/components/render/ModelType.tsx
Normal file
130
src/frontend/src/components/render/ModelType.tsx
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import { t } from '@lingui/macro';
|
||||||
|
|
||||||
|
export enum ModelType {
|
||||||
|
part = 'part',
|
||||||
|
supplierpart = 'supplierpart',
|
||||||
|
manufacturerpart = 'manufacturerpart',
|
||||||
|
partcategory = 'partcategory',
|
||||||
|
stockitem = 'stockitem',
|
||||||
|
stocklocation = 'stocklocation',
|
||||||
|
build = 'build',
|
||||||
|
company = 'company',
|
||||||
|
purchaseorder = 'purchaseorder',
|
||||||
|
salesorder = 'salesorder',
|
||||||
|
salesordershipment = 'salesordershipment',
|
||||||
|
returnorder = 'returnorder',
|
||||||
|
address = 'address',
|
||||||
|
contact = 'contact',
|
||||||
|
owner = 'owner',
|
||||||
|
user = 'user'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ModelInformatonInterface {
|
||||||
|
label: string;
|
||||||
|
label_multiple: string;
|
||||||
|
url_overview: string;
|
||||||
|
url_detail: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModelDictory = {
|
||||||
|
[key in keyof typeof ModelType]: ModelInformatonInterface;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ModelInformationDict: ModelDictory = {
|
||||||
|
part: {
|
||||||
|
label: t`Part`,
|
||||||
|
label_multiple: t`Parts`,
|
||||||
|
url_overview: '/part',
|
||||||
|
url_detail: '/part/:pk/'
|
||||||
|
},
|
||||||
|
supplierpart: {
|
||||||
|
label: t`Supplier Part`,
|
||||||
|
label_multiple: t`Supplier Parts`,
|
||||||
|
url_overview: '/supplierpart',
|
||||||
|
url_detail: '/supplierpart/:pk/'
|
||||||
|
},
|
||||||
|
manufacturerpart: {
|
||||||
|
label: t`Manufacturer Part`,
|
||||||
|
label_multiple: t`Manufacturer Parts`,
|
||||||
|
url_overview: '/manufacturerpart',
|
||||||
|
url_detail: '/manufacturerpart/:pk/'
|
||||||
|
},
|
||||||
|
partcategory: {
|
||||||
|
label: t`Part Category`,
|
||||||
|
label_multiple: t`Part Categories`,
|
||||||
|
url_overview: '/partcategory',
|
||||||
|
url_detail: '/partcategory/:pk/'
|
||||||
|
},
|
||||||
|
stockitem: {
|
||||||
|
label: t`Stock Item`,
|
||||||
|
label_multiple: t`Stock Items`,
|
||||||
|
url_overview: '/stockitem',
|
||||||
|
url_detail: '/stockitem/:pk/'
|
||||||
|
},
|
||||||
|
stocklocation: {
|
||||||
|
label: t`Stock Location`,
|
||||||
|
label_multiple: t`Stock Locations`,
|
||||||
|
url_overview: '/stocklocation',
|
||||||
|
url_detail: '/stocklocation/:pk/'
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
label: t`Build`,
|
||||||
|
label_multiple: t`Builds`,
|
||||||
|
url_overview: '/build',
|
||||||
|
url_detail: '/build/:pk/'
|
||||||
|
},
|
||||||
|
company: {
|
||||||
|
label: t`Company`,
|
||||||
|
label_multiple: t`Companies`,
|
||||||
|
url_overview: '/company',
|
||||||
|
url_detail: '/company/:pk/'
|
||||||
|
},
|
||||||
|
purchaseorder: {
|
||||||
|
label: t`Purchase Order`,
|
||||||
|
label_multiple: t`Purchase Orders`,
|
||||||
|
url_overview: '/purchaseorder',
|
||||||
|
url_detail: '/purchaseorder/:pk/'
|
||||||
|
},
|
||||||
|
salesorder: {
|
||||||
|
label: t`Sales Order`,
|
||||||
|
label_multiple: t`Sales Orders`,
|
||||||
|
url_overview: '/salesorder',
|
||||||
|
url_detail: '/salesorder/:pk/'
|
||||||
|
},
|
||||||
|
salesordershipment: {
|
||||||
|
label: t`Sales Order Shipment`,
|
||||||
|
label_multiple: t`Sales Order Shipments`,
|
||||||
|
url_overview: '/salesordershipment',
|
||||||
|
url_detail: '/salesordershipment/:pk/'
|
||||||
|
},
|
||||||
|
returnorder: {
|
||||||
|
label: t`Return Order`,
|
||||||
|
label_multiple: t`Return Orders`,
|
||||||
|
url_overview: '/returnorder',
|
||||||
|
url_detail: '/returnorder/:pk/'
|
||||||
|
},
|
||||||
|
address: {
|
||||||
|
label: t`Address`,
|
||||||
|
label_multiple: t`Addresses`,
|
||||||
|
url_overview: '/address',
|
||||||
|
url_detail: '/address/:pk/'
|
||||||
|
},
|
||||||
|
contact: {
|
||||||
|
label: t`Contact`,
|
||||||
|
label_multiple: t`Contacts`,
|
||||||
|
url_overview: '/contact',
|
||||||
|
url_detail: '/contact/:pk/'
|
||||||
|
},
|
||||||
|
owner: {
|
||||||
|
label: t`Owner`,
|
||||||
|
label_multiple: t`Owners`,
|
||||||
|
url_overview: '/owner',
|
||||||
|
url_detail: '/owner/:pk/'
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
label: t`User`,
|
||||||
|
label_multiple: t`Users`,
|
||||||
|
url_overview: '/user',
|
||||||
|
url_detail: '/user/:pk/'
|
||||||
|
}
|
||||||
|
};
|
@ -6,14 +6,18 @@ import { RenderInlineModel } from './Instance';
|
|||||||
/**
|
/**
|
||||||
* Inline rendering of a single PurchaseOrder instance
|
* Inline rendering of a single PurchaseOrder instance
|
||||||
*/
|
*/
|
||||||
export function RenderPurchaseOrder({ order }: { order: any }): ReactNode {
|
export function RenderPurchaseOrder({
|
||||||
let supplier = order.supplier_detail || {};
|
instance
|
||||||
|
}: {
|
||||||
|
instance: any;
|
||||||
|
}): ReactNode {
|
||||||
|
let supplier = instance.supplier_detail || {};
|
||||||
|
|
||||||
// TODO: Handle URL
|
// TODO: Handle URL
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={order.reference}
|
primary={instance.reference}
|
||||||
secondary={order.description}
|
secondary={instance.description}
|
||||||
image={supplier.thumnbnail || supplier.image}
|
image={supplier.thumnbnail || supplier.image}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -22,13 +26,13 @@ export function RenderPurchaseOrder({ order }: { order: any }): ReactNode {
|
|||||||
/**
|
/**
|
||||||
* Inline rendering of a single ReturnOrder instance
|
* Inline rendering of a single ReturnOrder instance
|
||||||
*/
|
*/
|
||||||
export function RenderReturnOrder({ order }: { order: any }): ReactNode {
|
export function RenderReturnOrder({ instance }: { instance: any }): ReactNode {
|
||||||
let customer = order.customer_detail || {};
|
let customer = instance.customer_detail || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={order.reference}
|
primary={instance.reference}
|
||||||
secondary={order.description}
|
secondary={instance.description}
|
||||||
image={customer.thumnbnail || customer.image}
|
image={customer.thumnbnail || customer.image}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -37,15 +41,15 @@ export function RenderReturnOrder({ order }: { order: any }): ReactNode {
|
|||||||
/**
|
/**
|
||||||
* Inline rendering of a single SalesOrder instance
|
* Inline rendering of a single SalesOrder instance
|
||||||
*/
|
*/
|
||||||
export function RenderSalesOrder({ order }: { order: any }): ReactNode {
|
export function RenderSalesOrder({ instance }: { instance: any }): ReactNode {
|
||||||
let customer = order.customer_detail || {};
|
let customer = instance.customer_detail || {};
|
||||||
|
|
||||||
// TODO: Handle URL
|
// TODO: Handle URL
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={order.reference}
|
primary={instance.reference}
|
||||||
secondary={order.description}
|
secondary={instance.description}
|
||||||
image={customer.thumnbnail || customer.image}
|
image={customer.thumnbnail || customer.image}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -55,16 +59,16 @@ export function RenderSalesOrder({ order }: { order: any }): ReactNode {
|
|||||||
* Inline rendering of a single SalesOrderAllocation instance
|
* Inline rendering of a single SalesOrderAllocation instance
|
||||||
*/
|
*/
|
||||||
export function RenderSalesOrderShipment({
|
export function RenderSalesOrderShipment({
|
||||||
shipment
|
instance
|
||||||
}: {
|
}: {
|
||||||
shipment: any;
|
instance: any;
|
||||||
}): ReactNode {
|
}): ReactNode {
|
||||||
let order = shipment.sales_order_detail || {};
|
let order = instance.sales_order_detail || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={order.reference}
|
primary={order.reference}
|
||||||
secondary={t`Shipment` + ` ${shipment.description}`}
|
secondary={t`Shipment` + ` ${instance.description}`}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,12 @@ import { RenderInlineModel } from './Instance';
|
|||||||
/**
|
/**
|
||||||
* Inline rendering of a single Part instance
|
* Inline rendering of a single Part instance
|
||||||
*/
|
*/
|
||||||
export function RenderPart({ part }: { part: any }): ReactNode {
|
export function RenderPart({ instance }: { instance: any }): ReactNode {
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={part.name}
|
primary={instance.name}
|
||||||
secondary={part.description}
|
secondary={instance.description}
|
||||||
image={part.thumnbnail || part.image}
|
image={instance.thumnbnail || instance.image}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -18,15 +18,15 @@ export function RenderPart({ part }: { part: any }): ReactNode {
|
|||||||
/**
|
/**
|
||||||
* Inline rendering of a PartCategory instance
|
* Inline rendering of a PartCategory instance
|
||||||
*/
|
*/
|
||||||
export function RenderPartCategory({ category }: { category: any }): ReactNode {
|
export function RenderPartCategory({ instance }: { instance: any }): ReactNode {
|
||||||
// TODO: Handle URL
|
// TODO: Handle URL
|
||||||
|
|
||||||
let lvl = '-'.repeat(category.level || 0);
|
let lvl = '-'.repeat(instance.level || 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={`${lvl} ${category.name}`}
|
primary={`${lvl} ${instance.name}`}
|
||||||
secondary={category.description}
|
secondary={instance.description}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -6,24 +6,24 @@ import { RenderInlineModel } from './Instance';
|
|||||||
* Inline rendering of a single StockLocation instance
|
* Inline rendering of a single StockLocation instance
|
||||||
*/
|
*/
|
||||||
export function RenderStockLocation({
|
export function RenderStockLocation({
|
||||||
location
|
instance
|
||||||
}: {
|
}: {
|
||||||
location: any;
|
instance: any;
|
||||||
}): ReactNode {
|
}): ReactNode {
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={location.name}
|
primary={instance.name}
|
||||||
secondary={location.description}
|
secondary={instance.description}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RenderStockItem({ item }: { item: any }): ReactNode {
|
export function RenderStockItem({ instance }: { instance: any }): ReactNode {
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={item.part_detail?.full_name}
|
primary={instance.part_detail?.full_name}
|
||||||
secondary={item.quantity}
|
secondary={instance.quantity}
|
||||||
image={item.part_detail?.thumbnail || item.part_detail?.image}
|
image={instance.part_detail?.thumbnail || instance.part_detail?.image}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,17 @@ import { ReactNode } from 'react';
|
|||||||
|
|
||||||
import { RenderInlineModel } from './Instance';
|
import { RenderInlineModel } from './Instance';
|
||||||
|
|
||||||
export function RenderOwner({ owner }: { owner: any }): ReactNode {
|
export function RenderOwner({ instance }: { instance: any }): ReactNode {
|
||||||
// TODO: Icon based on user / group status?
|
// TODO: Icon based on user / group status?
|
||||||
|
|
||||||
return <RenderInlineModel primary={owner.name} />;
|
return <RenderInlineModel primary={instance.name} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RenderUser({ user }: { user: any }): ReactNode {
|
export function RenderUser({ instance }: { instance: any }): ReactNode {
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={user.username}
|
primary={instance.username}
|
||||||
secondary={`${user.first_name} ${user.last_name}`}
|
secondary={`${instance.first_name} ${instance.last_name}`}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user