mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-01 04:56:45 +00:00
PUI tweaks (#7144)
* Default progress bars a bit thicker * Implement useFilters hook - Adds "project code" filter for order tables * Add "responsible" filters to backend * Add more filters to tables * Bump API version * Typo fix * Tweak PartTable * Tweaks * remove unused imports
This commit is contained in:
parent
1ef9512f18
commit
a9b932cc32
@ -1,11 +1,14 @@
|
|||||||
"""InvenTree API version information."""
|
"""InvenTree API version information."""
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 192
|
INVENTREE_API_VERSION = 193
|
||||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||||
|
|
||||||
INVENTREE_API_TEXT = """
|
INVENTREE_API_TEXT = """
|
||||||
|
|
||||||
|
v193 - 2024-04-30 : https://github.com/inventree/InvenTree/pull/7144
|
||||||
|
- Adds "assigned_to" filter to PurchaseOrder / SalesOrder / ReturnOrder API endpoints
|
||||||
|
|
||||||
v192 - 2024-04-23 : https://github.com/inventree/InvenTree/pull/7106
|
v192 - 2024-04-23 : https://github.com/inventree/InvenTree/pull/7106
|
||||||
- Adds 'trackable' ordering option to BuildLineLabel API endpoint
|
- Adds 'trackable' ordering option to BuildLineLabel API endpoint
|
||||||
|
|
||||||
|
@ -148,6 +148,10 @@ class OrderFilter(rest_filters.FilterSet):
|
|||||||
return queryset.exclude(project_code=None)
|
return queryset.exclude(project_code=None)
|
||||||
return queryset.filter(project_code=None)
|
return queryset.filter(project_code=None)
|
||||||
|
|
||||||
|
assigned_to = rest_filters.ModelChoiceFilter(
|
||||||
|
queryset=Owner.objects.all(), field_name='responsible'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LineItemFilter(rest_filters.FilterSet):
|
class LineItemFilter(rest_filters.FilterSet):
|
||||||
"""Base class for custom API filters for order line item list(s)."""
|
"""Base class for custom API filters for order line item list(s)."""
|
||||||
|
@ -77,16 +77,18 @@ class AbstractOrderSerializer(serializers.Serializer):
|
|||||||
"""Abstract serializer class which provides fields common to all order types."""
|
"""Abstract serializer class which provides fields common to all order types."""
|
||||||
|
|
||||||
# Number of line items in this order
|
# Number of line items in this order
|
||||||
line_items = serializers.IntegerField(read_only=True)
|
line_items = serializers.IntegerField(read_only=True, label=_('Line Items'))
|
||||||
|
|
||||||
# Number of completed line items (this is an annotated field)
|
# Number of completed line items (this is an annotated field)
|
||||||
completed_lines = serializers.IntegerField(read_only=True)
|
completed_lines = serializers.IntegerField(
|
||||||
|
read_only=True, label=_('Completed Lines')
|
||||||
|
)
|
||||||
|
|
||||||
# Human-readable status text (read-only)
|
# Human-readable status text (read-only)
|
||||||
status_text = serializers.CharField(source='get_status_display', read_only=True)
|
status_text = serializers.CharField(source='get_status_display', read_only=True)
|
||||||
|
|
||||||
# status field cannot be set directly
|
# status field cannot be set directly
|
||||||
status = serializers.IntegerField(read_only=True)
|
status = serializers.IntegerField(read_only=True, label=_('Order Status'))
|
||||||
|
|
||||||
# Reference string is *required*
|
# Reference string is *required*
|
||||||
reference = serializers.CharField(required=True)
|
reference = serializers.CharField(required=True)
|
||||||
@ -114,7 +116,9 @@ class AbstractOrderSerializer(serializers.Serializer):
|
|||||||
|
|
||||||
barcode_hash = serializers.CharField(read_only=True)
|
barcode_hash = serializers.CharField(read_only=True)
|
||||||
|
|
||||||
creation_date = serializers.DateField(required=False, allow_null=True)
|
creation_date = serializers.DateField(
|
||||||
|
required=False, allow_null=True, label=_('Creation Date')
|
||||||
|
)
|
||||||
|
|
||||||
def validate_reference(self, reference):
|
def validate_reference(self, reference):
|
||||||
"""Custom validation for the reference field."""
|
"""Custom validation for the reference field."""
|
||||||
|
@ -6,6 +6,7 @@ export type ProgressBarProps = {
|
|||||||
maximum?: number;
|
maximum?: number;
|
||||||
label?: string;
|
label?: string;
|
||||||
progressLabel?: boolean;
|
progressLabel?: boolean;
|
||||||
|
size?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,8 +32,8 @@ export function ProgressBar(props: ProgressBarProps) {
|
|||||||
<Progress
|
<Progress
|
||||||
value={progress}
|
value={progress}
|
||||||
color={progress < 100 ? 'orange' : progress > 100 ? 'blue' : 'green'}
|
color={progress < 100 ? 'orange' : progress > 100 ? 'blue' : 'green'}
|
||||||
size="sm"
|
size={props.size ?? 'md'}
|
||||||
radius="xs"
|
radius="sm"
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
91
src/frontend/src/hooks/UseFilter.tsx
Normal file
91
src/frontend/src/hooks/UseFilter.tsx
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Custom hook for retrieving a list of items from the API,
|
||||||
|
* and turning them into "filters" for use in the frontend table framework.
|
||||||
|
*/
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
|
import { api } from '../App';
|
||||||
|
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||||
|
import { resolveItem } from '../functions/conversion';
|
||||||
|
import { apiUrl } from '../states/ApiState';
|
||||||
|
import { TableFilterChoice } from '../tables/Filter';
|
||||||
|
|
||||||
|
type UseFilterProps = {
|
||||||
|
url: string;
|
||||||
|
method?: 'GET' | 'POST' | 'OPTIONS';
|
||||||
|
params?: any;
|
||||||
|
accessor?: string;
|
||||||
|
transform: (item: any) => TableFilterChoice;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function useFilters(props: UseFilterProps) {
|
||||||
|
const query = useQuery({
|
||||||
|
enabled: true,
|
||||||
|
queryKey: [props.url, props.method, props.params],
|
||||||
|
queryFn: async () => {
|
||||||
|
return await api
|
||||||
|
.request({
|
||||||
|
url: props.url,
|
||||||
|
method: props.method || 'GET',
|
||||||
|
params: props.params
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
let data = resolveItem(response, props.accessor ?? 'data');
|
||||||
|
|
||||||
|
if (data == null || data == undefined) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
.catch((error) => []);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const choices: TableFilterChoice[] = useMemo(() => {
|
||||||
|
return query.data?.map(props.transform) ?? [];
|
||||||
|
}, [props.transform, query.data]);
|
||||||
|
|
||||||
|
const refresh = useCallback(() => {
|
||||||
|
query.refetch();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {
|
||||||
|
choices,
|
||||||
|
refresh
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide list of project code filters
|
||||||
|
export function useProjectCodeFilters() {
|
||||||
|
return useFilters({
|
||||||
|
url: apiUrl(ApiEndpoints.project_code_list),
|
||||||
|
transform: (item) => ({
|
||||||
|
value: item.pk,
|
||||||
|
label: item.code
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide list of user filters
|
||||||
|
export function useUserFilters() {
|
||||||
|
return useFilters({
|
||||||
|
url: apiUrl(ApiEndpoints.user_list),
|
||||||
|
transform: (item) => ({
|
||||||
|
value: item.pk,
|
||||||
|
label: item.username
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide list of owner filters
|
||||||
|
export function useOwnerFilters() {
|
||||||
|
return useFilters({
|
||||||
|
url: apiUrl(ApiEndpoints.owner_list),
|
||||||
|
transform: (item) => ({
|
||||||
|
value: item.pk,
|
||||||
|
label: item.name
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
@ -10,6 +10,11 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
|||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
import { useBuildOrderFields } from '../../forms/BuildForms';
|
import { useBuildOrderFields } from '../../forms/BuildForms';
|
||||||
|
import {
|
||||||
|
useOwnerFilters,
|
||||||
|
useProjectCodeFilters,
|
||||||
|
useUserFilters
|
||||||
|
} from '../../hooks/UseFilter';
|
||||||
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
||||||
import { useTable } from '../../hooks/UseTable';
|
import { useTable } from '../../hooks/UseTable';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
@ -92,6 +97,10 @@ export function BuildOrderTable({
|
|||||||
}) {
|
}) {
|
||||||
const tableColumns = useMemo(() => buildOrderTableColumns(), []);
|
const tableColumns = useMemo(() => buildOrderTableColumns(), []);
|
||||||
|
|
||||||
|
const projectCodeFilters = useProjectCodeFilters();
|
||||||
|
const userFilters = useUserFilters();
|
||||||
|
const responsibleFilters = useOwnerFilters();
|
||||||
|
|
||||||
const tableFilters: TableFilter[] = useMemo(() => {
|
const tableFilters: TableFilter[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -115,18 +124,36 @@ export function BuildOrderTable({
|
|||||||
type: 'boolean',
|
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`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'project_code',
|
||||||
|
label: t`Project Code`,
|
||||||
|
description: t`Filter by project code`,
|
||||||
|
choices: projectCodeFilters.choices
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'has_project_code',
|
||||||
|
label: t`Has Project Code`,
|
||||||
|
description: t`Filter by whether the purchase order has a project code`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'issued_by',
|
||||||
|
label: t`Issued By`,
|
||||||
|
description: t`Filter by user who issued this order`,
|
||||||
|
choices: userFilters.choices
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'assigned_to',
|
||||||
|
label: t`Responsible`,
|
||||||
|
description: t`Filter by responsible owner`,
|
||||||
|
choices: responsibleFilters.choices
|
||||||
}
|
}
|
||||||
// TODO: 'assigned to' filter
|
|
||||||
// TODO: 'issued by' filter
|
|
||||||
// {
|
|
||||||
// name: 'has_project_code',
|
|
||||||
// title: t`Has Project Code`,
|
|
||||||
// description: t`Show orders with project code`,
|
|
||||||
// }
|
|
||||||
// TODO: 'has project code' filter (see table_filters.js)
|
|
||||||
// TODO: 'project code' filter (see table_filters.js)
|
|
||||||
];
|
];
|
||||||
}, []);
|
}, [
|
||||||
|
projectCodeFilters.choices,
|
||||||
|
userFilters.choices,
|
||||||
|
responsibleFilters.choices
|
||||||
|
]);
|
||||||
|
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
|
@ -116,13 +116,13 @@ export default function BuildOutputTable({
|
|||||||
/>,
|
/>,
|
||||||
<ActionButton
|
<ActionButton
|
||||||
tooltip={t`Scrap selected outputs`}
|
tooltip={t`Scrap selected outputs`}
|
||||||
icon={<InvenTreeIcon icon="cancel" />}
|
icon={<InvenTreeIcon icon="delete" />}
|
||||||
color="red"
|
color="red"
|
||||||
disabled={!table.hasSelectedRecords}
|
disabled={!table.hasSelectedRecords}
|
||||||
/>,
|
/>,
|
||||||
<ActionButton
|
<ActionButton
|
||||||
tooltip={t`Cancel selected outputs`}
|
tooltip={t`Cancel selected outputs`}
|
||||||
icon={<InvenTreeIcon icon="delete" />}
|
icon={<InvenTreeIcon icon="cancel" />}
|
||||||
color="red"
|
color="red"
|
||||||
disabled={!table.hasSelectedRecords}
|
disabled={!table.hasSelectedRecords}
|
||||||
/>
|
/>
|
||||||
@ -153,14 +153,14 @@ export default function BuildOutputTable({
|
|||||||
{
|
{
|
||||||
title: t`Scrap`,
|
title: t`Scrap`,
|
||||||
tooltip: t`Scrap build output`,
|
tooltip: t`Scrap build output`,
|
||||||
color: 'red',
|
icon: <InvenTreeIcon icon="delete" />,
|
||||||
icon: <InvenTreeIcon icon="cancel" />
|
color: 'red'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t`Delete`,
|
title: t`Cancel`,
|
||||||
tooltip: t`Delete build output`,
|
tooltip: t`Cancel build output`,
|
||||||
color: 'red',
|
icon: <InvenTreeIcon icon="cancel" />,
|
||||||
icon: <InvenTreeIcon icon="delete" />
|
color: 'red'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Group, Text } from '@mantine/core';
|
import { Group, Text } from '@mantine/core';
|
||||||
import { ReactNode, useMemo } from 'react';
|
import { ReactNode, useMemo } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
|
|
||||||
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
||||||
import { formatPriceRange } from '../../defaults/formatters';
|
import { formatPriceRange } from '../../defaults/formatters';
|
||||||
@ -9,7 +8,6 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
|||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
import { usePartFields } from '../../forms/PartForms';
|
import { usePartFields } from '../../forms/PartForms';
|
||||||
import { shortenString } from '../../functions/tables';
|
|
||||||
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
||||||
import { useTable } from '../../hooks/UseTable';
|
import { useTable } from '../../hooks/UseTable';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
@ -43,13 +41,7 @@ function partTableColumns(): TableColumn[] {
|
|||||||
{
|
{
|
||||||
accessor: 'category',
|
accessor: 'category',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
|
render: (record: any) => record.category_detail?.pathstring
|
||||||
render: function (record: any) {
|
|
||||||
// TODO: Link to the category detail page
|
|
||||||
return shortenString({
|
|
||||||
str: record.category_detail?.pathstring
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessor: 'total_in_stock',
|
accessor: 'total_in_stock',
|
||||||
|
@ -8,6 +8,7 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
|||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
import { usePurchaseOrderFields } from '../../forms/PurchaseOrderForms';
|
import { usePurchaseOrderFields } from '../../forms/PurchaseOrderForms';
|
||||||
|
import { useOwnerFilters, useProjectCodeFilters } from '../../hooks/UseFilter';
|
||||||
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
||||||
import { useTable } from '../../hooks/UseTable';
|
import { useTable } from '../../hooks/UseTable';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
@ -44,6 +45,9 @@ export function PurchaseOrderTable({
|
|||||||
const table = useTable('purchase-order');
|
const table = useTable('purchase-order');
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
|
const projectCodeFilters = useProjectCodeFilters();
|
||||||
|
const responsibleFilters = useOwnerFilters();
|
||||||
|
|
||||||
const tableFilters: TableFilter[] = useMemo(() => {
|
const tableFilters: TableFilter[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -54,11 +58,26 @@ export function PurchaseOrderTable({
|
|||||||
},
|
},
|
||||||
OutstandingFilter(),
|
OutstandingFilter(),
|
||||||
OverdueFilter(),
|
OverdueFilter(),
|
||||||
AssignedToMeFilter()
|
AssignedToMeFilter(),
|
||||||
// TODO: has_project_code
|
{
|
||||||
// TODO: project_code
|
name: 'project_code',
|
||||||
|
label: t`Project Code`,
|
||||||
|
description: t`Filter by project code`,
|
||||||
|
choices: projectCodeFilters.choices
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'has_project_code',
|
||||||
|
label: t`Has Project Code`,
|
||||||
|
description: t`Filter by whether the purchase order has a project code`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'assigned_to',
|
||||||
|
label: t`Responsible`,
|
||||||
|
description: t`Filter by responsible owner`,
|
||||||
|
choices: responsibleFilters.choices
|
||||||
|
}
|
||||||
];
|
];
|
||||||
}, []);
|
}, [projectCodeFilters.choices, responsibleFilters.choices]);
|
||||||
|
|
||||||
const tableColumns = useMemo(() => {
|
const tableColumns = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
|
@ -8,6 +8,7 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
|||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
import { useReturnOrderFields } from '../../forms/SalesOrderForms';
|
import { useReturnOrderFields } from '../../forms/SalesOrderForms';
|
||||||
|
import { useOwnerFilters, useProjectCodeFilters } from '../../hooks/UseFilter';
|
||||||
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
||||||
import { useTable } from '../../hooks/UseTable';
|
import { useTable } from '../../hooks/UseTable';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
@ -35,6 +36,9 @@ export function ReturnOrderTable({ params }: { params?: any }) {
|
|||||||
const table = useTable('return-orders');
|
const table = useTable('return-orders');
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
|
const projectCodeFilters = useProjectCodeFilters();
|
||||||
|
const responsibleFilters = useOwnerFilters();
|
||||||
|
|
||||||
const tableFilters: TableFilter[] = useMemo(() => {
|
const tableFilters: TableFilter[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -45,9 +49,26 @@ export function ReturnOrderTable({ params }: { params?: any }) {
|
|||||||
},
|
},
|
||||||
OutstandingFilter(),
|
OutstandingFilter(),
|
||||||
OverdueFilter(),
|
OverdueFilter(),
|
||||||
AssignedToMeFilter()
|
AssignedToMeFilter(),
|
||||||
|
{
|
||||||
|
name: 'project_code',
|
||||||
|
label: t`Project Code`,
|
||||||
|
description: t`Filter by project code`,
|
||||||
|
choices: projectCodeFilters.choices
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'has_project_code',
|
||||||
|
label: t`Has Project Code`,
|
||||||
|
description: t`Filter by whether the purchase order has a project code`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'assigned_to',
|
||||||
|
label: t`Responsible`,
|
||||||
|
description: t`Filter by responsible owner`,
|
||||||
|
choices: responsibleFilters.choices
|
||||||
|
}
|
||||||
];
|
];
|
||||||
}, []);
|
}, [projectCodeFilters.choices, responsibleFilters.choices]);
|
||||||
|
|
||||||
const tableColumns = useMemo(() => {
|
const tableColumns = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
|
@ -8,6 +8,7 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
|||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
import { useSalesOrderFields } from '../../forms/SalesOrderForms';
|
import { useSalesOrderFields } from '../../forms/SalesOrderForms';
|
||||||
|
import { useOwnerFilters, useProjectCodeFilters } from '../../hooks/UseFilter';
|
||||||
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
||||||
import { useTable } from '../../hooks/UseTable';
|
import { useTable } from '../../hooks/UseTable';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
@ -41,6 +42,9 @@ export function SalesOrderTable({
|
|||||||
const table = useTable('sales-order');
|
const table = useTable('sales-order');
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
|
const projectCodeFilters = useProjectCodeFilters();
|
||||||
|
const responsibleFilters = useOwnerFilters();
|
||||||
|
|
||||||
const tableFilters: TableFilter[] = useMemo(() => {
|
const tableFilters: TableFilter[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -51,11 +55,26 @@ export function SalesOrderTable({
|
|||||||
},
|
},
|
||||||
OutstandingFilter(),
|
OutstandingFilter(),
|
||||||
OverdueFilter(),
|
OverdueFilter(),
|
||||||
AssignedToMeFilter()
|
AssignedToMeFilter(),
|
||||||
// TODO: has_project_code
|
{
|
||||||
// TODO: project_code
|
name: 'project_code',
|
||||||
|
label: t`Project Code`,
|
||||||
|
description: t`Filter by project code`,
|
||||||
|
choices: projectCodeFilters.choices
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'has_project_code',
|
||||||
|
label: t`Has Project Code`,
|
||||||
|
description: t`Filter by whether the purchase order has a project code`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'assigned_to',
|
||||||
|
label: t`Responsible`,
|
||||||
|
description: t`Filter by responsible owner`,
|
||||||
|
choices: responsibleFilters.choices
|
||||||
|
}
|
||||||
];
|
];
|
||||||
}, []);
|
}, [projectCodeFilters.choices, responsibleFilters.choices]);
|
||||||
|
|
||||||
const salesOrderFields = useSalesOrderFields();
|
const salesOrderFields = useSalesOrderFields();
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { ReactNode, useMemo } from 'react';
|
|||||||
|
|
||||||
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
||||||
import { ActionDropdown } from '../../components/items/ActionDropdown';
|
import { ActionDropdown } from '../../components/items/ActionDropdown';
|
||||||
import { formatCurrency, renderDate } from '../../defaults/formatters';
|
import { formatCurrency } from '../../defaults/formatters';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user