mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-01 04:56:45 +00:00
Table date filters (#8299)
* Add date filtering for tables * Update filters for build order table * Update other tables * Typing fix * Fix filter type
This commit is contained in:
parent
7c19e51d80
commit
0c9e986796
@ -11,6 +11,15 @@ export type TableFilterChoice = {
|
|||||||
label: string;
|
label: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available filter types
|
||||||
|
*
|
||||||
|
* boolean: A simple true/false filter
|
||||||
|
* choice: A filter which allows selection from a list of (supplied)
|
||||||
|
* date: A filter which allows selection from a date input
|
||||||
|
*/
|
||||||
|
export type TableFilterType = 'boolean' | 'choice' | 'date';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for the table filter type. Provides a number of options for selecting filter value:
|
* Interface for the table filter type. Provides a number of options for selecting filter value:
|
||||||
*
|
*
|
||||||
@ -22,7 +31,7 @@ export type TableFilter = {
|
|||||||
name: string;
|
name: string;
|
||||||
label: string;
|
label: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
type?: string;
|
type?: TableFilterType;
|
||||||
choices?: TableFilterChoice[];
|
choices?: TableFilterChoice[];
|
||||||
choiceFunction?: () => TableFilterChoice[];
|
choiceFunction?: () => TableFilterChoice[];
|
||||||
defaultValue?: any;
|
defaultValue?: any;
|
||||||
@ -83,9 +92,12 @@ export function StatusFilterOptions(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Define some commonly used filters
|
||||||
|
|
||||||
export function AssignedToMeFilter(): TableFilter {
|
export function AssignedToMeFilter(): TableFilter {
|
||||||
return {
|
return {
|
||||||
name: 'assigned_to_me',
|
name: 'assigned_to_me',
|
||||||
|
type: 'boolean',
|
||||||
label: t`Assigned to me`,
|
label: t`Assigned to me`,
|
||||||
description: t`Show orders assigned to me`
|
description: t`Show orders assigned to me`
|
||||||
};
|
};
|
||||||
@ -95,7 +107,7 @@ export function OutstandingFilter(): TableFilter {
|
|||||||
return {
|
return {
|
||||||
name: 'outstanding',
|
name: 'outstanding',
|
||||||
label: t`Outstanding`,
|
label: t`Outstanding`,
|
||||||
description: t`Show outstanding orders`
|
description: t`Show outstanding items`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +115,33 @@ export function OverdueFilter(): TableFilter {
|
|||||||
return {
|
return {
|
||||||
name: 'overdue',
|
name: 'overdue',
|
||||||
label: t`Overdue`,
|
label: t`Overdue`,
|
||||||
description: t`Show overdue orders`
|
description: t`Show overdue items`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MinDateFilter(): TableFilter {
|
||||||
|
return {
|
||||||
|
name: 'min_date',
|
||||||
|
label: t`Minimum Date`,
|
||||||
|
description: t`Show items after this date`,
|
||||||
|
type: 'date'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MaxDateFilter(): TableFilter {
|
||||||
|
return {
|
||||||
|
name: 'max_date',
|
||||||
|
label: t`Maximum Date`,
|
||||||
|
description: t`Show items before this date`,
|
||||||
|
type: 'date'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function HasProjectCodeFilter(): TableFilter {
|
||||||
|
return {
|
||||||
|
name: 'has_project_code',
|
||||||
|
type: 'boolean',
|
||||||
|
label: t`Has Project Code`,
|
||||||
|
description: t`Show orders with an assigned project code`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
|
import { L } from '@lingui/react/dist/shared/react.e5f95de8';
|
||||||
import {
|
import {
|
||||||
Badge,
|
Badge,
|
||||||
Button,
|
Button,
|
||||||
@ -12,6 +13,8 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Tooltip
|
Tooltip
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
|
import { DateInput, DateValue } from '@mantine/dates';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { StylishText } from '../components/items/StylishText';
|
import { StylishText } from '../components/items/StylishText';
|
||||||
@ -19,6 +22,7 @@ import { TableState } from '../hooks/UseTable';
|
|||||||
import {
|
import {
|
||||||
TableFilter,
|
TableFilter,
|
||||||
TableFilterChoice,
|
TableFilterChoice,
|
||||||
|
TableFilterType,
|
||||||
getTableFilterOptions
|
getTableFilterOptions
|
||||||
} from './Filter';
|
} from './Filter';
|
||||||
|
|
||||||
@ -99,6 +103,14 @@ function FilterAddGroup({
|
|||||||
return getTableFilterOptions(filter);
|
return getTableFilterOptions(filter);
|
||||||
}, [selectedFilter]);
|
}, [selectedFilter]);
|
||||||
|
|
||||||
|
// Determine the "type" of filter (default = boolean)
|
||||||
|
const filterType: TableFilterType = useMemo(() => {
|
||||||
|
return (
|
||||||
|
availableFilters?.find((flt) => flt.name === selectedFilter)?.type ??
|
||||||
|
'boolean'
|
||||||
|
);
|
||||||
|
}, [selectedFilter]);
|
||||||
|
|
||||||
const setSelectedValue = useCallback(
|
const setSelectedValue = useCallback(
|
||||||
(value: string | null) => {
|
(value: string | null) => {
|
||||||
// Find the matching filter
|
// Find the matching filter
|
||||||
@ -126,6 +138,18 @@ function FilterAddGroup({
|
|||||||
[selectedFilter]
|
[selectedFilter]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const setDateValue = useCallback(
|
||||||
|
(value: DateValue) => {
|
||||||
|
if (value) {
|
||||||
|
let date = value.toString();
|
||||||
|
setSelectedValue(dayjs(date).format('YYYY-MM-DD'));
|
||||||
|
} else {
|
||||||
|
setSelectedValue('');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[setSelectedValue]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap="xs">
|
<Stack gap="xs">
|
||||||
<Divider />
|
<Divider />
|
||||||
@ -137,16 +161,23 @@ function FilterAddGroup({
|
|||||||
onChange={(value: string | null) => setSelectedFilter(value)}
|
onChange={(value: string | null) => setSelectedFilter(value)}
|
||||||
maxDropdownHeight={800}
|
maxDropdownHeight={800}
|
||||||
/>
|
/>
|
||||||
{selectedFilter && (
|
{selectedFilter &&
|
||||||
<Select
|
(filterType === 'date' ? (
|
||||||
data={valueOptions}
|
<DateInput
|
||||||
label={t`Value`}
|
label={t`Value`}
|
||||||
searchable={true}
|
placeholder={t`Select date value`}
|
||||||
placeholder={t`Select filter value`}
|
onChange={setDateValue}
|
||||||
onChange={(value: string | null) => setSelectedValue(value)}
|
/>
|
||||||
maxDropdownHeight={800}
|
) : (
|
||||||
/>
|
<Select
|
||||||
)}
|
data={valueOptions}
|
||||||
|
label={t`Value`}
|
||||||
|
searchable={true}
|
||||||
|
placeholder={t`Select filter value`}
|
||||||
|
onChange={(value: string | null) => setSelectedValue(value)}
|
||||||
|
maxDropdownHeight={800}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,15 @@ import {
|
|||||||
StatusColumn,
|
StatusColumn,
|
||||||
TargetDateColumn
|
TargetDateColumn
|
||||||
} from '../ColumnRenderers';
|
} from '../ColumnRenderers';
|
||||||
import { StatusFilterOptions, TableFilter } from '../Filter';
|
import {
|
||||||
|
AssignedToMeFilter,
|
||||||
|
HasProjectCodeFilter,
|
||||||
|
MaxDateFilter,
|
||||||
|
MinDateFilter,
|
||||||
|
OverdueFilter,
|
||||||
|
StatusFilterOptions,
|
||||||
|
TableFilter
|
||||||
|
} from '../Filter';
|
||||||
import { InvenTreeTable } from '../InvenTreeTable';
|
import { InvenTreeTable } from '../InvenTreeTable';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -115,29 +123,17 @@ export function BuildOrderTable({
|
|||||||
description: t`Filter by order status`,
|
description: t`Filter by order status`,
|
||||||
choiceFunction: StatusFilterOptions(ModelType.build)
|
choiceFunction: StatusFilterOptions(ModelType.build)
|
||||||
},
|
},
|
||||||
{
|
OverdueFilter(),
|
||||||
name: 'overdue',
|
AssignedToMeFilter(),
|
||||||
label: t`Overdue`,
|
MinDateFilter(),
|
||||||
type: 'boolean',
|
MaxDateFilter(),
|
||||||
description: t`Show overdue status`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'assigned_to_me',
|
|
||||||
type: 'boolean',
|
|
||||||
label: t`Assigned to me`,
|
|
||||||
description: t`Show orders assigned to me`
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'project_code',
|
name: 'project_code',
|
||||||
label: t`Project Code`,
|
label: t`Project Code`,
|
||||||
description: t`Filter by project code`,
|
description: t`Filter by project code`,
|
||||||
choices: projectCodeFilters.choices
|
choices: projectCodeFilters.choices
|
||||||
},
|
},
|
||||||
{
|
HasProjectCodeFilter(),
|
||||||
name: 'has_project_code',
|
|
||||||
label: t`Has Project Code`,
|
|
||||||
description: t`Filter by whether the purchase order has a project code`
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'issued_by',
|
name: 'issued_by',
|
||||||
label: t`Issued By`,
|
label: t`Issued By`,
|
||||||
|
@ -25,6 +25,9 @@ import {
|
|||||||
} from '../ColumnRenderers';
|
} from '../ColumnRenderers';
|
||||||
import {
|
import {
|
||||||
AssignedToMeFilter,
|
AssignedToMeFilter,
|
||||||
|
HasProjectCodeFilter,
|
||||||
|
MaxDateFilter,
|
||||||
|
MinDateFilter,
|
||||||
OutstandingFilter,
|
OutstandingFilter,
|
||||||
OverdueFilter,
|
OverdueFilter,
|
||||||
StatusFilterOptions,
|
StatusFilterOptions,
|
||||||
@ -59,17 +62,15 @@ export function PurchaseOrderTable({
|
|||||||
OutstandingFilter(),
|
OutstandingFilter(),
|
||||||
OverdueFilter(),
|
OverdueFilter(),
|
||||||
AssignedToMeFilter(),
|
AssignedToMeFilter(),
|
||||||
|
MinDateFilter(),
|
||||||
|
MaxDateFilter(),
|
||||||
{
|
{
|
||||||
name: 'project_code',
|
name: 'project_code',
|
||||||
label: t`Project Code`,
|
label: t`Project Code`,
|
||||||
description: t`Filter by project code`,
|
description: t`Filter by project code`,
|
||||||
choices: projectCodeFilters.choices
|
choices: projectCodeFilters.choices
|
||||||
},
|
},
|
||||||
{
|
HasProjectCodeFilter(),
|
||||||
name: 'has_project_code',
|
|
||||||
label: t`Has Project Code`,
|
|
||||||
description: t`Filter by whether the purchase order has a project code`
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'assigned_to',
|
name: 'assigned_to',
|
||||||
label: t`Responsible`,
|
label: t`Responsible`,
|
||||||
|
@ -25,6 +25,9 @@ import {
|
|||||||
} from '../ColumnRenderers';
|
} from '../ColumnRenderers';
|
||||||
import {
|
import {
|
||||||
AssignedToMeFilter,
|
AssignedToMeFilter,
|
||||||
|
HasProjectCodeFilter,
|
||||||
|
MaxDateFilter,
|
||||||
|
MinDateFilter,
|
||||||
OutstandingFilter,
|
OutstandingFilter,
|
||||||
OverdueFilter,
|
OverdueFilter,
|
||||||
StatusFilterOptions,
|
StatusFilterOptions,
|
||||||
@ -50,17 +53,15 @@ export function ReturnOrderTable({ params }: Readonly<{ params?: any }>) {
|
|||||||
OutstandingFilter(),
|
OutstandingFilter(),
|
||||||
OverdueFilter(),
|
OverdueFilter(),
|
||||||
AssignedToMeFilter(),
|
AssignedToMeFilter(),
|
||||||
|
MinDateFilter(),
|
||||||
|
MaxDateFilter(),
|
||||||
{
|
{
|
||||||
name: 'project_code',
|
name: 'project_code',
|
||||||
label: t`Project Code`,
|
label: t`Project Code`,
|
||||||
description: t`Filter by project code`,
|
description: t`Filter by project code`,
|
||||||
choices: projectCodeFilters.choices
|
choices: projectCodeFilters.choices
|
||||||
},
|
},
|
||||||
{
|
HasProjectCodeFilter(),
|
||||||
name: 'has_project_code',
|
|
||||||
label: t`Has Project Code`,
|
|
||||||
description: t`Filter by whether the purchase order has a project code`
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'assigned_to',
|
name: 'assigned_to',
|
||||||
label: t`Responsible`,
|
label: t`Responsible`,
|
||||||
|
@ -26,6 +26,9 @@ import {
|
|||||||
} from '../ColumnRenderers';
|
} from '../ColumnRenderers';
|
||||||
import {
|
import {
|
||||||
AssignedToMeFilter,
|
AssignedToMeFilter,
|
||||||
|
HasProjectCodeFilter,
|
||||||
|
MaxDateFilter,
|
||||||
|
MinDateFilter,
|
||||||
OutstandingFilter,
|
OutstandingFilter,
|
||||||
OverdueFilter,
|
OverdueFilter,
|
||||||
StatusFilterOptions,
|
StatusFilterOptions,
|
||||||
@ -57,17 +60,15 @@ export function SalesOrderTable({
|
|||||||
OutstandingFilter(),
|
OutstandingFilter(),
|
||||||
OverdueFilter(),
|
OverdueFilter(),
|
||||||
AssignedToMeFilter(),
|
AssignedToMeFilter(),
|
||||||
|
MinDateFilter(),
|
||||||
|
MaxDateFilter(),
|
||||||
{
|
{
|
||||||
name: 'project_code',
|
name: 'project_code',
|
||||||
label: t`Project Code`,
|
label: t`Project Code`,
|
||||||
description: t`Filter by project code`,
|
description: t`Filter by project code`,
|
||||||
choices: projectCodeFilters.choices
|
choices: projectCodeFilters.choices
|
||||||
},
|
},
|
||||||
{
|
HasProjectCodeFilter(),
|
||||||
name: 'has_project_code',
|
|
||||||
label: t`Has Project Code`,
|
|
||||||
description: t`Filter by whether the purchase order has a project code`
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'assigned_to',
|
name: 'assigned_to',
|
||||||
label: t`Responsible`,
|
label: t`Responsible`,
|
||||||
|
@ -355,7 +355,7 @@ export function TemplateTable({
|
|||||||
name: 'enabled',
|
name: 'enabled',
|
||||||
label: t`Enabled`,
|
label: t`Enabled`,
|
||||||
description: t`Filter by enabled status`,
|
description: t`Filter by enabled status`,
|
||||||
type: 'checkbox'
|
type: 'boolean'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'model_type',
|
name: 'model_type',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user