mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 11:36:44 +00:00
Refactor table columns (#5519)
- Improve show/hide - Refactor "actions" colum
This commit is contained in:
parent
528fa349b0
commit
14a6330114
@ -15,6 +15,7 @@ import { DownloadAction } from './DownloadAction';
|
|||||||
import { TableFilter } from './Filter';
|
import { TableFilter } from './Filter';
|
||||||
import { FilterGroup } from './FilterGroup';
|
import { FilterGroup } from './FilterGroup';
|
||||||
import { FilterSelectModal } from './FilterSelectModal';
|
import { FilterSelectModal } from './FilterSelectModal';
|
||||||
|
import { RowAction, RowActions } from './RowActions';
|
||||||
import { TableSearchInput } from './Search';
|
import { TableSearchInput } from './Search';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -96,7 +97,8 @@ export function InvenTreeTable({
|
|||||||
printingActions = [],
|
printingActions = [],
|
||||||
barcodeActions = [],
|
barcodeActions = [],
|
||||||
customActionGroups = [],
|
customActionGroups = [],
|
||||||
customFilters = []
|
customFilters = [],
|
||||||
|
rowActions
|
||||||
}: {
|
}: {
|
||||||
url: string;
|
url: string;
|
||||||
params: any;
|
params: any;
|
||||||
@ -115,12 +117,15 @@ export function InvenTreeTable({
|
|||||||
barcodeActions?: any[];
|
barcodeActions?: any[];
|
||||||
customActionGroups?: any[];
|
customActionGroups?: any[];
|
||||||
customFilters?: TableFilter[];
|
customFilters?: TableFilter[];
|
||||||
|
rowActions?: (record: any) => RowAction[];
|
||||||
}) {
|
}) {
|
||||||
// Data columns
|
// Data columns
|
||||||
const [dataColumns, setDataColumns] = useState<any[]>(columns);
|
const [dataColumns, setDataColumns] = useState<any[]>(columns);
|
||||||
|
|
||||||
// Check if any columns are switchable (can be hidden)
|
// Check if any columns are switchable (can be hidden)
|
||||||
const hasSwitchableColumns = columns.some((col: any) => col.switchable);
|
const hasSwitchableColumns = columns.some(
|
||||||
|
(col: TableColumn) => col.switchable
|
||||||
|
);
|
||||||
|
|
||||||
// Manage state for switchable columns (initially load from local storage)
|
// Manage state for switchable columns (initially load from local storage)
|
||||||
let [hiddenColumns, setHiddenColumns] = useState(() =>
|
let [hiddenColumns, setHiddenColumns] = useState(() =>
|
||||||
@ -129,15 +134,34 @@ export function InvenTreeTable({
|
|||||||
|
|
||||||
// Update column visibility when hiddenColumns change
|
// Update column visibility when hiddenColumns change
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDataColumns(
|
let cols = dataColumns.map((col) => {
|
||||||
dataColumns.map((col) => {
|
let hidden: boolean = col.hidden;
|
||||||
return {
|
|
||||||
...col,
|
if (col.switchable) {
|
||||||
hidden: hiddenColumns.includes(col.accessor)
|
hidden = hiddenColumns.includes(col.accessor);
|
||||||
};
|
}
|
||||||
})
|
|
||||||
);
|
return {
|
||||||
}, [hiddenColumns]);
|
...col,
|
||||||
|
hidden: hidden
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// If row actions are available, add a column for them
|
||||||
|
if (rowActions) {
|
||||||
|
cols.push({
|
||||||
|
accessor: 'actions',
|
||||||
|
title: '',
|
||||||
|
hidden: false,
|
||||||
|
switchable: false,
|
||||||
|
render: function (record: any) {
|
||||||
|
return <RowActions actions={rowActions(record)} />;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setDataColumns(cols);
|
||||||
|
}, [columns, hiddenColumns, rowActions]);
|
||||||
|
|
||||||
// Callback when column visibility is toggled
|
// Callback when column visibility is toggled
|
||||||
function toggleColumn(columnName: string) {
|
function toggleColumn(columnName: string) {
|
||||||
|
@ -24,25 +24,27 @@ export function RowActions({
|
|||||||
actions: RowAction[];
|
actions: RowAction[];
|
||||||
}): ReactNode {
|
}): ReactNode {
|
||||||
return (
|
return (
|
||||||
<Menu>
|
actions.length > 0 && (
|
||||||
<Menu.Target>
|
<Menu>
|
||||||
<ActionIcon variant="subtle" color="gray">
|
<Menu.Target>
|
||||||
<IconDots />
|
<ActionIcon variant="subtle" color="gray">
|
||||||
</ActionIcon>
|
<IconDots />
|
||||||
</Menu.Target>
|
</ActionIcon>
|
||||||
<Menu.Dropdown>
|
</Menu.Target>
|
||||||
<Menu.Label>{title || t`Actions`}</Menu.Label>
|
<Menu.Dropdown>
|
||||||
{actions.map((action, idx) => (
|
<Menu.Label>{title || t`Actions`}</Menu.Label>
|
||||||
<Menu.Item
|
{actions.map((action, idx) => (
|
||||||
key={idx}
|
<Menu.Item
|
||||||
onClick={action.onClick}
|
key={idx}
|
||||||
icon={action.icon}
|
onClick={action.onClick}
|
||||||
title={action.tooltip || action.title}
|
icon={action.icon}
|
||||||
>
|
title={action.tooltip || action.title}
|
||||||
{action.title}
|
>
|
||||||
</Menu.Item>
|
{action.title}
|
||||||
))}
|
</Menu.Item>
|
||||||
</Menu.Dropdown>
|
))}
|
||||||
</Menu>
|
</Menu.Dropdown>
|
||||||
|
</Menu>
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import { ThumbnailHoverCard } from '../../items/Thumbnail';
|
|||||||
import { TableColumn } from '../Column';
|
import { TableColumn } from '../Column';
|
||||||
import { TableFilter } from '../Filter';
|
import { TableFilter } from '../Filter';
|
||||||
import { InvenTreeTable } from '../InvenTreeTable';
|
import { InvenTreeTable } from '../InvenTreeTable';
|
||||||
import { RowActions } from '../RowActions';
|
import { RowAction } from '../RowActions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a list of columns for the part table
|
* Construct a list of columns for the part table
|
||||||
@ -82,38 +82,6 @@ function partTableColumns(): TableColumn[] {
|
|||||||
accessor: 'link',
|
accessor: 'link',
|
||||||
title: t`Link`,
|
title: t`Link`,
|
||||||
switchable: true
|
switchable: true
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: 'actions',
|
|
||||||
title: '',
|
|
||||||
switchable: false,
|
|
||||||
render: function (record: any) {
|
|
||||||
return (
|
|
||||||
<RowActions
|
|
||||||
title={`Part Actions`}
|
|
||||||
actions={[
|
|
||||||
{
|
|
||||||
title: t`Edit`,
|
|
||||||
icon: <IconEdit color="blue" />,
|
|
||||||
onClick: () =>
|
|
||||||
editPart({
|
|
||||||
part_id: record.pk,
|
|
||||||
callback: () => {
|
|
||||||
// TODO: Reload the table, somehow?
|
|
||||||
// TODO: Insert / update a single row in the table?
|
|
||||||
// TODO: We need to have a hook back into the table
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t`Delete`,
|
|
||||||
onClick: notYetImplemented,
|
|
||||||
icon: <IconTrash color="red" />
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -229,6 +197,32 @@ export function PartListTable({ params = {} }: { params?: any }) {
|
|||||||
// Add required query parameters
|
// Add required query parameters
|
||||||
tableParams.category_detail = true;
|
tableParams.category_detail = true;
|
||||||
|
|
||||||
|
function partTableRowActions(record: any): RowAction[] {
|
||||||
|
let actions: RowAction[] = [];
|
||||||
|
|
||||||
|
actions.push({
|
||||||
|
title: t`Edit`,
|
||||||
|
onClick: () => {
|
||||||
|
editPart({
|
||||||
|
part_id: record.pk,
|
||||||
|
callback: () => {
|
||||||
|
// TODO: Reload the table, somehow?
|
||||||
|
notYetImplemented();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (record.IPN) {
|
||||||
|
actions.push({
|
||||||
|
title: t`View IPN`,
|
||||||
|
onClick: () => {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InvenTreeTable
|
<InvenTreeTable
|
||||||
url="part/"
|
url="part/"
|
||||||
@ -241,6 +235,7 @@ export function PartListTable({ params = {} }: { params?: any }) {
|
|||||||
params={tableParams}
|
params={tableParams}
|
||||||
columns={tableColumns}
|
columns={tableColumns}
|
||||||
customFilters={tableFilters}
|
customFilters={tableFilters}
|
||||||
|
rowActions={partTableRowActions}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import { ActionButton } from '../../items/ActionButton';
|
|||||||
import { ThumbnailHoverCard } from '../../items/Thumbnail';
|
import { ThumbnailHoverCard } from '../../items/Thumbnail';
|
||||||
import { TableColumn } from '../Column';
|
import { TableColumn } from '../Column';
|
||||||
import { TableFilter } from '../Filter';
|
import { TableFilter } from '../Filter';
|
||||||
import { RowActions } from '../RowActions';
|
import { RowAction } from '../RowActions';
|
||||||
import { InvenTreeTable } from './../InvenTreeTable';
|
import { InvenTreeTable } from './../InvenTreeTable';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,7 +66,7 @@ function stockItemTableColumns(): TableColumn[] {
|
|||||||
// TODO: Custom renderer for location
|
// TODO: Custom renderer for location
|
||||||
return record.location;
|
return record.location;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
// TODO: stocktake column
|
// TODO: stocktake column
|
||||||
// TODO: expiry date
|
// TODO: expiry date
|
||||||
// TODO: last updated
|
// TODO: last updated
|
||||||
@ -76,31 +76,6 @@ function stockItemTableColumns(): TableColumn[] {
|
|||||||
// TODO: stock value
|
// TODO: stock value
|
||||||
// TODO: packaging
|
// TODO: packaging
|
||||||
// TODO: notes
|
// TODO: notes
|
||||||
{
|
|
||||||
accessor: 'actions',
|
|
||||||
title: '',
|
|
||||||
sortable: false,
|
|
||||||
switchable: false,
|
|
||||||
render: function (record: any) {
|
|
||||||
return (
|
|
||||||
<RowActions
|
|
||||||
title={t`Stock Actions`}
|
|
||||||
actions={[
|
|
||||||
{
|
|
||||||
title: t`Edit`,
|
|
||||||
icon: <IconEdit color="blue" />,
|
|
||||||
onClick: notYetImplemented
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t`Delete`,
|
|
||||||
icon: <IconTrash color="red" />,
|
|
||||||
onClick: notYetImplemented
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +117,19 @@ export function StockItemTable({ params = {} }: { params?: any }) {
|
|||||||
let tableColumns = useMemo(() => stockItemTableColumns(), []);
|
let tableColumns = useMemo(() => stockItemTableColumns(), []);
|
||||||
let tableFilters = useMemo(() => stockItemTableFilters(), []);
|
let tableFilters = useMemo(() => stockItemTableFilters(), []);
|
||||||
|
|
||||||
|
function stockItemRowActions(record: any): RowAction[] {
|
||||||
|
let actions: RowAction[] = [];
|
||||||
|
|
||||||
|
actions.push({
|
||||||
|
title: t`Edit`,
|
||||||
|
onClick: () => {
|
||||||
|
notYetImplemented();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InvenTreeTable
|
<InvenTreeTable
|
||||||
url="stock/"
|
url="stock/"
|
||||||
@ -151,6 +139,7 @@ export function StockItemTable({ params = {} }: { params?: any }) {
|
|||||||
params={tableParams}
|
params={tableParams}
|
||||||
columns={tableColumns}
|
columns={tableColumns}
|
||||||
customFilters={tableFilters}
|
customFilters={tableFilters}
|
||||||
|
rowActions={stockItemRowActions}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user