mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
[PUI] Tweaks and refactor for "part details" page (#6405)
* Add getModelInfo helper function - Extract model definition from provided modeltype * Improvements for details.tsx - Use defined URL functions, not strings - Catch potential errors * Fix PartDetail page - Use modeltype definitions - URL fixes
This commit is contained in:
parent
7483fd203d
commit
77fd6b6bb3
@ -3,7 +3,7 @@ import { t } from '@lingui/macro';
|
||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||
import { ModelType } from '../../enums/ModelType';
|
||||
|
||||
interface ModelInformationInterface {
|
||||
export interface ModelInformationInterface {
|
||||
label: string;
|
||||
label_multiple: string;
|
||||
url_overview?: string;
|
||||
@ -12,11 +12,11 @@ interface ModelInformationInterface {
|
||||
cui_detail?: string;
|
||||
}
|
||||
|
||||
type ModelDictory = {
|
||||
export type ModelDict = {
|
||||
[key in keyof typeof ModelType]: ModelInformationInterface;
|
||||
};
|
||||
|
||||
export const ModelInformationDict: ModelDictory = {
|
||||
export const ModelInformationDict: ModelDict = {
|
||||
part: {
|
||||
label: t`Part`,
|
||||
label_multiple: t`Parts`,
|
||||
@ -165,3 +165,12 @@ export const ModelInformationDict: ModelDictory = {
|
||||
api_endpoint: ApiEndpoints.user_list
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Extract model definition given the provided type
|
||||
* @param type - ModelType to extract information from
|
||||
* @returns ModelInformationInterface
|
||||
*/
|
||||
export function getModelInfo(type: ModelType): ModelInformationInterface {
|
||||
return ModelInformationDict[type];
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ import { PartCategoryTree } from '../../components/nav/PartCategoryTree';
|
||||
import { NotesEditor } from '../../components/widgets/MarkdownEditor';
|
||||
import { formatPriceRange } from '../../defaults/formatters';
|
||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||
import { ModelType } from '../../enums/ModelType';
|
||||
import { UserRoles } from '../../enums/Roles';
|
||||
import { partFields } from '../../forms/PartForms';
|
||||
import { useEditApiFormModal } from '../../hooks/UseForm';
|
||||
@ -122,8 +123,7 @@ export default function PartDetail() {
|
||||
type: 'link',
|
||||
name: 'variant_of',
|
||||
label: t`Variant of`,
|
||||
path: ApiEndpoints.part_list,
|
||||
dest: '/part/'
|
||||
model: ModelType.part
|
||||
}
|
||||
]);
|
||||
}
|
||||
@ -226,8 +226,7 @@ export default function PartDetail() {
|
||||
type: 'link',
|
||||
name: 'category',
|
||||
label: t`Category`,
|
||||
path: ApiEndpoints.category_list,
|
||||
dest: '/part/category/'
|
||||
model: ModelType.partcategory
|
||||
}
|
||||
]);
|
||||
}
|
||||
@ -336,7 +335,7 @@ export default function PartDetail() {
|
||||
const { data } = useSuspenseQuery({
|
||||
queryKey: ['stocktake', id],
|
||||
queryFn: async () => {
|
||||
const url = ApiEndpoints.part_stocktake_list;
|
||||
const url = apiUrl(ApiEndpoints.part_stocktake_list);
|
||||
|
||||
return api
|
||||
.get(url, { params: { part: id, ordering: 'date' } })
|
||||
@ -364,7 +363,7 @@ export default function PartDetail() {
|
||||
const { data } = useSuspenseQuery({
|
||||
queryKey: ['stocktake', id],
|
||||
queryFn: async () => {
|
||||
const url = ApiEndpoints.part_stocktake_list;
|
||||
const url = apiUrl(ApiEndpoints.part_stocktake_list);
|
||||
|
||||
return api
|
||||
.get(url, { params: { part: id, ordering: 'date' } })
|
||||
@ -392,8 +391,7 @@ export default function PartDetail() {
|
||||
type: 'link',
|
||||
name: 'default_location',
|
||||
label: t`Default Location`,
|
||||
path: ApiEndpoints.stock_location_list,
|
||||
dest: '/stock/location/'
|
||||
model: ModelType.stocklocation
|
||||
}
|
||||
]);
|
||||
}
|
||||
@ -404,8 +402,7 @@ export default function PartDetail() {
|
||||
type: 'link',
|
||||
name: 'default_supplier',
|
||||
label: t`Default Supplier`,
|
||||
path: ApiEndpoints.supplier_part_list,
|
||||
dest: '/part/'
|
||||
model: ModelType.supplierpart
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
@ -11,12 +11,15 @@ import {
|
||||
Tooltip
|
||||
} from '@mantine/core';
|
||||
import { useSuspenseQuery } from '@tanstack/react-query';
|
||||
import { Suspense } from 'react';
|
||||
import { Suspense, useMemo } from 'react';
|
||||
|
||||
import { api } from '../App';
|
||||
import { ProgressBar } from '../components/items/ProgressBar';
|
||||
import { getModelInfo } from '../components/render/ModelType';
|
||||
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||
import { ModelType } from '../enums/ModelType';
|
||||
import { InvenTreeIcon } from '../functions/icons';
|
||||
import { getDetailUrl } from '../functions/urls';
|
||||
import { apiUrl } from '../states/ApiState';
|
||||
import { useGlobalSettingsState } from '../states/SettingsState';
|
||||
|
||||
@ -53,8 +56,7 @@ type LinkDetailField = {
|
||||
} & (InternalLinkField | ExternalLinkField);
|
||||
|
||||
type InternalLinkField = {
|
||||
path: ApiEndpoints;
|
||||
dest: string;
|
||||
model: ModelType;
|
||||
};
|
||||
|
||||
type ExternalLinkField = {
|
||||
@ -292,9 +294,15 @@ function TableAnchorValue(props: FieldProps) {
|
||||
}
|
||||
|
||||
const { data } = useSuspenseQuery({
|
||||
queryKey: ['detail', props.field_data.path],
|
||||
queryKey: ['detail', props.field_data.model, props.field_value],
|
||||
queryFn: async () => {
|
||||
const url = apiUrl(props.field_data.path, props.field_value);
|
||||
const modelDef = getModelInfo(props.field_data.model);
|
||||
|
||||
if (!modelDef.api_endpoint) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const url = apiUrl(modelDef.api_endpoint, props.field_value);
|
||||
|
||||
return api
|
||||
.get(url)
|
||||
@ -312,14 +320,16 @@ function TableAnchorValue(props: FieldProps) {
|
||||
}
|
||||
});
|
||||
|
||||
const detailUrl = useMemo(() => {
|
||||
return getDetailUrl(props.field_data.model, props.field_value);
|
||||
}, [props.field_data.model, props.field_value]);
|
||||
|
||||
return (
|
||||
<Suspense fallback={<Skeleton width={200} height={20} radius="xl" />}>
|
||||
<Anchor
|
||||
href={
|
||||
'/platform' + data.url ?? props.field_data.dest + props.field_value
|
||||
}
|
||||
target={data.external ? '_blank' : undefined}
|
||||
rel={data.external ? 'noreferrer noopener' : undefined}
|
||||
href={`/platform${detailUrl}`}
|
||||
target={data?.external ? '_blank' : undefined}
|
||||
rel={data?.external ? 'noreferrer noopener' : undefined}
|
||||
>
|
||||
<Text>{data.name ?? 'No name defined'}</Text>
|
||||
</Anchor>
|
||||
|
Loading…
Reference in New Issue
Block a user