mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-15 11:35:41 +00:00
[UI] Adjustable column width (#9744)
* Add prop to column def * Enable resizable columns * Enable cell wrapping if required * Tweak CompanyTable * Remove old setting * Tweak for PartTable
This commit is contained in:
@ -25,7 +25,6 @@ The *Display Settings* screen shows general display configuration options:
|
|||||||
{{ usersetting("PART_SHOW_QUANTITY_IN_FORMS") }}
|
{{ usersetting("PART_SHOW_QUANTITY_IN_FORMS") }}
|
||||||
{{ usersetting("DISPLAY_SCHEDULE_TAB") }}
|
{{ usersetting("DISPLAY_SCHEDULE_TAB") }}
|
||||||
{{ usersetting("DISPLAY_STOCKTAKE_TAB") }}
|
{{ usersetting("DISPLAY_STOCKTAKE_TAB") }}
|
||||||
{{ usersetting("TABLE_STRING_MAX_LENGTH") }}
|
|
||||||
{{ usersetting("ENABLE_LAST_BREADCRUMB") }}
|
{{ usersetting("ENABLE_LAST_BREADCRUMB") }}
|
||||||
|
|
||||||
### Search Settings
|
### Search Settings
|
||||||
|
@ -225,12 +225,6 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = {
|
|||||||
'default': True,
|
'default': True,
|
||||||
'validator': bool,
|
'validator': bool,
|
||||||
},
|
},
|
||||||
'TABLE_STRING_MAX_LENGTH': {
|
|
||||||
'name': _('Table String Length'),
|
|
||||||
'description': _('Maximum length limit for strings displayed in table views'),
|
|
||||||
'validator': [int, MinValueValidator(0)],
|
|
||||||
'default': 100,
|
|
||||||
},
|
|
||||||
'ENABLE_LAST_BREADCRUMB': {
|
'ENABLE_LAST_BREADCRUMB': {
|
||||||
'name': _('Show Last Breadcrumb'),
|
'name': _('Show Last Breadcrumb'),
|
||||||
'description': _('Show the current page in breadcrumbs'),
|
'description': _('Show the current page in breadcrumbs'),
|
||||||
|
@ -56,7 +56,6 @@ export default function UserSettings() {
|
|||||||
'PART_SHOW_QUANTITY_IN_FORMS',
|
'PART_SHOW_QUANTITY_IN_FORMS',
|
||||||
'DISPLAY_SCHEDULE_TAB',
|
'DISPLAY_SCHEDULE_TAB',
|
||||||
'DISPLAY_STOCKTAKE_TAB',
|
'DISPLAY_STOCKTAKE_TAB',
|
||||||
'TABLE_STRING_MAX_LENGTH',
|
|
||||||
'ENABLE_LAST_BREADCRUMB'
|
'ENABLE_LAST_BREADCRUMB'
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
@ -16,6 +16,7 @@ import type { ApiFormFieldType } from '@lib/types/Forms';
|
|||||||
* @param filter - A custom filter function
|
* @param filter - A custom filter function
|
||||||
* @param filtering - Whether the column is filterable
|
* @param filtering - Whether the column is filterable
|
||||||
* @param width - The width of the column
|
* @param width - The width of the column
|
||||||
|
* @param resizable - Whether the column is resizable (defaults to true)
|
||||||
* @param noWrap - Whether the column should wrap
|
* @param noWrap - Whether the column should wrap
|
||||||
* @param ellipsis - Whether the column should be ellipsized
|
* @param ellipsis - Whether the column should be ellipsized
|
||||||
* @param textAlign - The text alignment of the column
|
* @param textAlign - The text alignment of the column
|
||||||
@ -36,6 +37,7 @@ export type TableColumnProps<T = any> = {
|
|||||||
filter?: any;
|
filter?: any;
|
||||||
filtering?: boolean;
|
filtering?: boolean;
|
||||||
width?: number;
|
width?: number;
|
||||||
|
resizable?: boolean;
|
||||||
noWrap?: boolean;
|
noWrap?: boolean;
|
||||||
ellipsis?: boolean;
|
ellipsis?: boolean;
|
||||||
textAlign?: 'left' | 'center' | 'right';
|
textAlign?: 'left' | 'center' | 'right';
|
||||||
|
@ -9,7 +9,8 @@ import {
|
|||||||
DataTable,
|
DataTable,
|
||||||
type DataTableCellClickHandler,
|
type DataTableCellClickHandler,
|
||||||
type DataTableRowExpansionProps,
|
type DataTableRowExpansionProps,
|
||||||
type DataTableSortStatus
|
type DataTableSortStatus,
|
||||||
|
useDataTableColumns
|
||||||
} from 'mantine-datatable';
|
} from 'mantine-datatable';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
@ -147,6 +148,19 @@ export function InvenTreeTable<T extends Record<string, any>>({
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { showContextMenu } = useContextMenu();
|
const { showContextMenu } = useContextMenu();
|
||||||
|
|
||||||
|
// Key used for caching table data
|
||||||
|
const cacheKey = useMemo(() => {
|
||||||
|
const key: string = `table-${tableState.tableKey}`;
|
||||||
|
|
||||||
|
// Remove anything after (and including) "mantine"
|
||||||
|
const mantineIndex = key.indexOf('-mantine');
|
||||||
|
if (mantineIndex >= 0) {
|
||||||
|
return key.substring(0, mantineIndex);
|
||||||
|
} else {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}, [tableState.tableKey]);
|
||||||
|
|
||||||
// Construct table filters - note that we can introspect filter labels from column names
|
// Construct table filters - note that we can introspect filter labels from column names
|
||||||
const filters: TableFilter[] = useMemo(() => {
|
const filters: TableFilter[] = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
@ -164,7 +178,7 @@ export function InvenTreeTable<T extends Record<string, any>>({
|
|||||||
// Request OPTIONS data from the API, before we load the table
|
// Request OPTIONS data from the API, before we load the table
|
||||||
const tableOptionQuery = useQuery({
|
const tableOptionQuery = useQuery({
|
||||||
enabled: !!url && !tableData,
|
enabled: !!url && !tableData,
|
||||||
queryKey: ['options', url, tableState.tableKey, props.enableColumnCaching],
|
queryKey: ['options', url, cacheKey, props.enableColumnCaching],
|
||||||
retry: 3,
|
retry: 3,
|
||||||
refetchOnMount: true,
|
refetchOnMount: true,
|
||||||
gcTime: 5000,
|
gcTime: 5000,
|
||||||
@ -202,8 +216,6 @@ export function InvenTreeTable<T extends Record<string, any>>({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const cacheKey = tableState.tableKey.replaceAll('-', '');
|
|
||||||
|
|
||||||
setFieldNames(names);
|
setFieldNames(names);
|
||||||
setTableColumnNames(cacheKey)(names);
|
setTableColumnNames(cacheKey)(names);
|
||||||
}
|
}
|
||||||
@ -230,8 +242,6 @@ export function InvenTreeTable<T extends Record<string, any>>({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cacheKey = tableState.tableKey.replaceAll('-', '');
|
|
||||||
|
|
||||||
// First check the local cache
|
// First check the local cache
|
||||||
const cachedNames = getTableColumnNames(cacheKey);
|
const cachedNames = getTableColumnNames(cacheKey);
|
||||||
|
|
||||||
@ -242,7 +252,7 @@ export function InvenTreeTable<T extends Record<string, any>>({
|
|||||||
}
|
}
|
||||||
|
|
||||||
tableOptionQuery.refetch();
|
tableOptionQuery.refetch();
|
||||||
}, [url, props.params, props.enableColumnCaching]);
|
}, [cacheKey, url, props.params, props.enableColumnCaching]);
|
||||||
|
|
||||||
// Build table properties based on provided props (and default props)
|
// Build table properties based on provided props (and default props)
|
||||||
const tableProps: InvenTreeTableProps<T> = useMemo(() => {
|
const tableProps: InvenTreeTableProps<T> = useMemo(() => {
|
||||||
@ -295,7 +305,7 @@ export function InvenTreeTable<T extends Record<string, any>>({
|
|||||||
return {
|
return {
|
||||||
...col,
|
...col,
|
||||||
hidden: hidden,
|
hidden: hidden,
|
||||||
noWrap: true,
|
resizable: col.resizable ?? true,
|
||||||
title: col.title ?? fieldNames[col.accessor] ?? `${col.accessor}`
|
title: col.title ?? fieldNames[col.accessor] ?? `${col.accessor}`
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -306,6 +316,7 @@ export function InvenTreeTable<T extends Record<string, any>>({
|
|||||||
accessor: '--actions--',
|
accessor: '--actions--',
|
||||||
title: ' ',
|
title: ' ',
|
||||||
hidden: false,
|
hidden: false,
|
||||||
|
resizable: false,
|
||||||
switchable: false,
|
switchable: false,
|
||||||
width: 50,
|
width: 50,
|
||||||
render: (record: any, index?: number | undefined) => (
|
render: (record: any, index?: number | undefined) => (
|
||||||
@ -342,6 +353,12 @@ export function InvenTreeTable<T extends Record<string, any>>({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final state of the table columns
|
||||||
|
const tableColumns = useDataTableColumns({
|
||||||
|
key: cacheKey,
|
||||||
|
columns: dataColumns
|
||||||
|
});
|
||||||
|
|
||||||
// Reset the pagination state when the search term changes
|
// Reset the pagination state when the search term changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
tableState.setPage(1);
|
tableState.setPage(1);
|
||||||
@ -759,20 +776,15 @@ export function InvenTreeTable<T extends Record<string, any>>({
|
|||||||
enableSelection ? onSelectedRecordsChange : undefined
|
enableSelection ? onSelectedRecordsChange : undefined
|
||||||
}
|
}
|
||||||
rowExpansion={rowExpansion}
|
rowExpansion={rowExpansion}
|
||||||
// rowStyle={rowStyleCallback}
|
|
||||||
fetching={isFetching}
|
fetching={isFetching}
|
||||||
noRecordsText={missingRecordsText}
|
noRecordsText={missingRecordsText}
|
||||||
records={tableState.records}
|
records={tableState.records}
|
||||||
columns={dataColumns}
|
storeColumnsKey={cacheKey}
|
||||||
|
columns={tableColumns.effectiveColumns}
|
||||||
onCellClick={supportsCellClick ? handleCellClick : undefined}
|
onCellClick={supportsCellClick ? handleCellClick : undefined}
|
||||||
noHeader={tableProps.noHeader ?? false}
|
noHeader={tableProps.noHeader ?? false}
|
||||||
defaultColumnProps={{
|
defaultColumnProps={{
|
||||||
noWrap: true,
|
textAlign: 'left'
|
||||||
textAlign: 'left',
|
|
||||||
cellsStyle: () => (theme) => ({
|
|
||||||
// TODO @SchrodingersGat : Need a better way of handling "wide" cells,
|
|
||||||
overflow: 'hidden'
|
|
||||||
})
|
|
||||||
}}
|
}}
|
||||||
onCellContextMenu={
|
onCellContextMenu={
|
||||||
supportsContextMenu ? handleCellContextMenu : undefined
|
supportsContextMenu ? handleCellContextMenu : undefined
|
||||||
|
@ -43,6 +43,7 @@ export function CompanyTable({
|
|||||||
{
|
{
|
||||||
accessor: 'name',
|
accessor: 'name',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
|
switchable: false,
|
||||||
render: (record: any) => {
|
render: (record: any) => {
|
||||||
return (
|
return (
|
||||||
<Group gap='xs' wrap='nowrap'>
|
<Group gap='xs' wrap='nowrap'>
|
||||||
|
@ -35,6 +35,7 @@ function partTableColumns(): TableColumn[] {
|
|||||||
title: t`Part`,
|
title: t`Part`,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
noWrap: true,
|
noWrap: true,
|
||||||
|
switchable: false,
|
||||||
render: (record: any) => PartColumn({ part: record })
|
render: (record: any) => PartColumn({ part: record })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user