mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 19:46:46 +00:00
[PUI] Table filters (#7519)
* Fix for table filter functions - New mantine version requires string values * Add playwright test for tables
This commit is contained in:
parent
a9223970bd
commit
c1b2cbef5e
@ -44,7 +44,15 @@ export function useFilters(props: UseFilterProps) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const choices: TableFilterChoice[] = useMemo(() => {
|
const choices: TableFilterChoice[] = useMemo(() => {
|
||||||
return query.data?.map(props.transform) ?? [];
|
let opts = query.data?.map(props.transform) ?? [];
|
||||||
|
|
||||||
|
// Ensure stringiness
|
||||||
|
return opts.map((opt: any) => {
|
||||||
|
return {
|
||||||
|
value: opt.value.toString(),
|
||||||
|
label: opt?.label?.toString() ?? opt.value.toString()
|
||||||
|
};
|
||||||
|
});
|
||||||
}, [props.transform, query.data]);
|
}, [props.transform, query.data]);
|
||||||
|
|
||||||
const refresh = useCallback(() => {
|
const refresh = useCallback(() => {
|
||||||
|
@ -12,7 +12,7 @@ export function TableColumnSelect({
|
|||||||
return (
|
return (
|
||||||
<Menu shadow="xs" closeOnItemClick={false}>
|
<Menu shadow="xs" closeOnItemClick={false}>
|
||||||
<Menu.Target>
|
<Menu.Target>
|
||||||
<ActionIcon variant="transparent">
|
<ActionIcon variant="transparent" aria-label="table-select-columns">
|
||||||
<Tooltip label={t`Select Columns`}>
|
<Tooltip label={t`Select Columns`}>
|
||||||
<IconAdjustments />
|
<IconAdjustments />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -72,8 +72,8 @@ export function StatusFilterOptions(
|
|||||||
return Object.keys(codes).map((key) => {
|
return Object.keys(codes).map((key) => {
|
||||||
const entry = codes[key];
|
const entry = codes[key];
|
||||||
return {
|
return {
|
||||||
value: entry.key,
|
value: entry.key.toString(),
|
||||||
label: entry.label ?? entry.key
|
label: entry.label?.toString() ?? entry.key.toString()
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -57,12 +57,6 @@ function FilterItem({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FilterProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
||||||
name: string;
|
|
||||||
label: string;
|
|
||||||
description?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function FilterAddGroup({
|
function FilterAddGroup({
|
||||||
tableState,
|
tableState,
|
||||||
availableFilters
|
availableFilters
|
||||||
@ -182,6 +176,9 @@ export function FilterSelectDrawer({
|
|||||||
withCloseButton={true}
|
withCloseButton={true}
|
||||||
opened={opened}
|
opened={opened}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
|
closeButtonProps={{
|
||||||
|
'aria-label': 'filter-drawer-close'
|
||||||
|
}}
|
||||||
title={<StylishText size="lg">{t`Table Filters`}</StylishText>}
|
title={<StylishText size="lg">{t`Table Filters`}</StylishText>}
|
||||||
>
|
>
|
||||||
<Stack gap="xs">
|
<Stack gap="xs">
|
||||||
|
@ -626,7 +626,7 @@ export function InvenTreeTable<T = any>({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{tableProps.enableRefresh && (
|
{tableProps.enableRefresh && (
|
||||||
<ActionIcon variant="transparent">
|
<ActionIcon variant="transparent" aria-label="table-refresh">
|
||||||
<Tooltip label={t`Refresh data`}>
|
<Tooltip label={t`Refresh data`}>
|
||||||
<IconRefresh onClick={() => refetch()} />
|
<IconRefresh onClick={() => refetch()} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -644,7 +644,10 @@ export function InvenTreeTable<T = any>({
|
|||||||
label={tableState.activeFilters?.length ?? 0}
|
label={tableState.activeFilters?.length ?? 0}
|
||||||
disabled={tableState.activeFilters?.length == 0}
|
disabled={tableState.activeFilters?.length == 0}
|
||||||
>
|
>
|
||||||
<ActionIcon variant="transparent">
|
<ActionIcon
|
||||||
|
variant="transparent"
|
||||||
|
aria-label="table-select-filters"
|
||||||
|
>
|
||||||
<Tooltip label={t`Table filters`}>
|
<Tooltip label={t`Table filters`}>
|
||||||
<IconFilter
|
<IconFilter
|
||||||
onClick={() => setFiltersVisible(!filtersVisible)}
|
onClick={() => setFiltersVisible(!filtersVisible)}
|
||||||
|
67
src/frontend/tests/pui_tables.spec.ts
Normal file
67
src/frontend/tests/pui_tables.spec.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import { test } from './baseFixtures.js';
|
||||||
|
import { baseUrl } from './defaults.js';
|
||||||
|
import { doQuickLogin } from './login.js';
|
||||||
|
|
||||||
|
// Helper function to set the value of a specific table filter
|
||||||
|
const setFilter = async (page, name: string, value: string) => {
|
||||||
|
await page.getByLabel('table-select-filters').click();
|
||||||
|
await page.getByRole('button', { name: 'Add Filter' }).click();
|
||||||
|
await page.getByPlaceholder('Select filter').click();
|
||||||
|
await page.getByRole('option', { name: name, exact: true }).click();
|
||||||
|
await page.getByPlaceholder('Select filter value').click();
|
||||||
|
await page.getByRole('option', { name: value, exact: true }).click();
|
||||||
|
await page.getByLabel('filter-drawer-close').click();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function to clear table filters
|
||||||
|
const clearFilters = async (page) => {
|
||||||
|
await page.getByLabel('table-select-filters').click();
|
||||||
|
await page.getByRole('button', { name: 'Clear Filters' }).click();
|
||||||
|
await page.getByLabel('filter-drawer-close').click();
|
||||||
|
};
|
||||||
|
|
||||||
|
test('PUI - Tables - Filters', async ({ page }) => {
|
||||||
|
await doQuickLogin(page);
|
||||||
|
|
||||||
|
// Head to the "build order list" page
|
||||||
|
await page.goto(`${baseUrl}/build/`);
|
||||||
|
|
||||||
|
await setFilter(page, 'Status', 'Complete');
|
||||||
|
await setFilter(page, 'Responsible', 'allaccess');
|
||||||
|
await setFilter(page, 'Project Code', 'PRJ-NIM');
|
||||||
|
|
||||||
|
await clearFilters(page);
|
||||||
|
|
||||||
|
// Head to the "part list" page
|
||||||
|
await page.goto(`${baseUrl}/part/category/index/parts/`);
|
||||||
|
|
||||||
|
await setFilter(page, 'Assembly', 'Yes');
|
||||||
|
|
||||||
|
await clearFilters(page);
|
||||||
|
|
||||||
|
// Head to the "purchase order list" page
|
||||||
|
await page.goto(`${baseUrl}/purchasing/index/purchaseorders/`);
|
||||||
|
|
||||||
|
await setFilter(page, 'Status', 'Complete');
|
||||||
|
await setFilter(page, 'Responsible', 'readers');
|
||||||
|
await setFilter(page, 'Assigned to me', 'No');
|
||||||
|
await setFilter(page, 'Project Code', 'PRO-ZEN');
|
||||||
|
|
||||||
|
await clearFilters(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('PUI - Tables - Columns', async ({ page }) => {
|
||||||
|
await doQuickLogin(page);
|
||||||
|
|
||||||
|
// Go to the "stock list" page
|
||||||
|
await page.goto(`${baseUrl}/stock/location/index/stock-items`);
|
||||||
|
|
||||||
|
// Open column selector
|
||||||
|
await page.getByLabel('table-select-columns').click();
|
||||||
|
|
||||||
|
// De-select some items
|
||||||
|
await page.getByRole('menuitem', { name: 'Description' }).click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Stocktake' }).click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(2500);
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user