2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-07 06:00:57 +00:00

Enhance "path" columns (#9918)

* Enhance "path" columns

- Show "short" version
- Hovercard for full "pathstring"

* Remove old code

* adjust unit tests
This commit is contained in:
Oliver
2025-07-01 21:31:25 +10:00
committed by GitHub
parent 0f407f7dbb
commit 2ee00c80f5
6 changed files with 67 additions and 36 deletions

View File

@ -21,7 +21,7 @@ import { formatCurrency, formatDate } from '../defaults/formatters';
import { resolveItem } from '../functions/conversion';
import { useGlobalSettingsState } from '../states/SettingsStates';
import type { TableColumn, TableColumnProps } from './Column';
import { ProjectCodeHoverCard } from './TableHoverCard';
import { ProjectCodeHoverCard, TableHoverCard } from './TableHoverCard';
// Render a Part instance within a table
export function PartColumn({
@ -81,28 +81,57 @@ export function CompanyColumn({
);
}
export function LocationColumn(props: TableColumnProps): TableColumn {
/**
* Return a column which displays a tree path for a given record.
*/
export function PathColumn(props: TableColumnProps): TableColumn {
return {
...props,
accessor: props.accessor ?? 'path',
render: (record: any) => {
const instance = resolveItem(record, props.accessor ?? '');
if (!instance || !instance.name) {
return '-';
}
const name = instance.name ?? '';
const pathstring = instance.pathstring || name;
if (name == pathstring) {
return <Text>{name}</Text>;
}
return (
<TableHoverCard
value={<Text>{instance.name}</Text>}
icon='sitemap'
title={props.title}
extra={[<Text>{instance.pathstring}</Text>]}
/>
);
}
};
}
export function LocationColumn(props: TableColumnProps): TableColumn {
return PathColumn({
accessor: 'location',
title: t`Location`,
sortable: true,
ordering: 'location',
render: (record: any) => {
const location = resolveItem(record, props.accessor ?? '');
if (!location) {
return (
<Text
size='sm'
style={{ fontStyle: 'italic' }}
>{t`No location set`}</Text>
);
...props
});
}
return <Text size='sm'>{location.pathstring}</Text>;
},
export function CategoryColumn(props: TableColumnProps): TableColumn {
return PathColumn({
accessor: 'category',
title: t`Category`,
sortable: true,
ordering: 'category',
...props
};
});
}
export function BooleanColumn(props: TableColumn): TableColumn {

View File

@ -1,6 +1,5 @@
import { t } from '@lingui/core/macro';
import { Divider, Group, HoverCard, Stack, Text } from '@mantine/core';
import { IconInfoCircle } from '@tabler/icons-react';
import { type ReactNode, useMemo } from 'react';
import type { InvenTreeIconType } from '@lib/types/Icons';
@ -61,7 +60,10 @@ export function TableHoverCard({
<HoverCard.Dropdown>
<Stack gap='xs'>
<Group gap='xs' justify='left'>
<IconInfoCircle size='16' color='blue' />
<InvenTreeIcon
icon={icon ?? 'info'}
iconProps={{ size: 16, color: iconColor ?? 'blue' }}
/>
<Text fw='bold'>{title}</Text>
</Group>
<Divider />

View File

@ -22,7 +22,12 @@ import {
import { useTable } from '../../hooks/UseTable';
import { useUserState } from '../../states/UserState';
import type { TableColumn } from '../Column';
import { DescriptionColumn, LinkColumn, PartColumn } from '../ColumnRenderers';
import {
CategoryColumn,
DescriptionColumn,
LinkColumn,
PartColumn
} from '../ColumnRenderers';
import { InvenTreeTable, type InvenTreeTableProps } from '../InvenTreeTable';
import { type RowAction, RowEditAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard';
@ -53,11 +58,9 @@ function partTableColumns(): TableColumn[] {
sortable: true
},
DescriptionColumn({}),
{
accessor: 'category',
sortable: true,
render: (record: any) => record.category_detail?.pathstring
},
CategoryColumn({
accessor: 'category_detail'
}),
{
accessor: 'default_location',
sortable: true,

View File

@ -32,8 +32,8 @@ import type { TableColumn } from '../Column';
import {
DateColumn,
DescriptionColumn,
LocationColumn,
PartColumn,
PathColumn,
StatusColumn
} from '../ColumnRenderers';
import { StatusFilterOptions } from '../Filter';
@ -222,9 +222,10 @@ function stockItemTableColumns({
accessor: 'batch',
sortable: true
},
LocationColumn({
hidden: !showLocation,
accessor: 'location_detail'
PathColumn({
accessor: 'location_detail',
title: t`Location`,
hidden: !showLocation
}),
{
accessor: 'purchase_order',

View File

@ -80,7 +80,7 @@ test('Build Order - Basic Tests', async ({ browser }) => {
await page.getByText('Quantity: 25').waitFor();
await page.getByText('Continuity Checks').waitFor();
await page
.getByRole('row', { name: 'Quantity: 16 No location set' })
.getByRole('row', { name: 'Quantity: 16' })
.getByRole('button')
.hover();
await page.getByText('Add Test Result').waitFor();
@ -241,9 +241,7 @@ test('Build Order - Allocation', async ({ browser }) => {
// Expand this row
await cell.click();
await page.getByRole('cell', { name: '2022-4-27', exact: true }).waitFor();
await page
.getByRole('cell', { name: 'Electronics Lab/Reel Storage', exact: true })
.waitFor();
await page.getByRole('cell', { name: 'Reel Storage', exact: true }).waitFor();
// Navigate to the "Incomplete Outputs" tab
await loadTab(page, 'Incomplete Outputs');

View File

@ -225,9 +225,7 @@ test('Parts - Allocations', async ({ browser }) => {
// Expand allocations against BO0001
await build_order_cell.click();
await page.getByRole('cell', { name: '# 3', exact: true }).waitFor();
await page
.getByRole('cell', { name: 'Factory/Office Block/Room 101', exact: true })
.waitFor();
await page.getByRole('cell', { name: 'Room 101', exact: true }).waitFor();
await build_order_cell.click();
// Check row options for BO0001