mirror of
https://github.com/inventree/InvenTree.git
synced 2026-06-11 19:27:02 +00:00
Improvements for template tables (#12155)
* Enable in-column filtering for model type * Enable sorting by label size * Enable backend ordering * Improve filtering for report template table * Update API version
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 502
|
||||
INVENTREE_API_VERSION = 503
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v503 -> 2026-06-11 : https://github.com/inventree/InvenTree/pull/12155
|
||||
- Adds additional filtering and sorting options to the LabelTemplate API endpoint
|
||||
- Adds additional filtering and sorting options to the ReportTemplate API endpoint
|
||||
|
||||
v502 -> 2026-06-10 : https://github.com/inventree/InvenTree/pull/12142
|
||||
- Prevents users from printing reports or labels against models for which they do not have adequate permissions. This change improves the security of the system by ensuring that users cannot access or print reports or labels for models they do not have permission to view.
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ from django.utils.translation import gettext_lazy as _
|
||||
from django.views.decorators.cache import never_cache
|
||||
|
||||
import django_filters.rest_framework.filters as rest_filters
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from django_filters.rest_framework.filterset import FilterSet
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
from rest_framework.generics import GenericAPIView
|
||||
@@ -21,7 +20,7 @@ import users.permissions
|
||||
from common.models import DataOutput
|
||||
from common.serializers import DataOutputSerializer
|
||||
from InvenTree.api import meta_path
|
||||
from InvenTree.filters import InvenTreeSearchFilter
|
||||
from InvenTree.filters import SEARCH_ORDER_FILTER
|
||||
from InvenTree.mixins import ListCreateAPI, RetrieveUpdateDestroyAPI
|
||||
from plugin import PluginMixinEnum
|
||||
from plugin.builtin.labels.inventree_label import InvenTreeLabelPlugin
|
||||
@@ -81,7 +80,7 @@ class ReportFilter(ReportFilterBase):
|
||||
"""Filter options."""
|
||||
|
||||
model = report.models.ReportTemplate
|
||||
fields = ['landscape']
|
||||
fields = ['landscape', 'merge', 'attach_to_model', 'enabled', 'model_type']
|
||||
|
||||
|
||||
class LabelFilter(ReportFilterBase):
|
||||
@@ -91,7 +90,7 @@ class LabelFilter(ReportFilterBase):
|
||||
"""Filter options."""
|
||||
|
||||
model = report.models.LabelTemplate
|
||||
fields = []
|
||||
fields = ['enabled']
|
||||
|
||||
|
||||
class LabelPrint(GenericAPIView):
|
||||
@@ -246,9 +245,9 @@ class LabelTemplateList(TemplatePermissionMixin, LabelTemplateMixin, ListCreateA
|
||||
"""API endpoint for viewing list of LabelTemplate objects."""
|
||||
|
||||
filterset_class = LabelFilter
|
||||
filter_backends = [DjangoFilterBackend, InvenTreeSearchFilter]
|
||||
filter_backends = SEARCH_ORDER_FILTER
|
||||
search_fields = ['name', 'description']
|
||||
ordering_fields = ['name', 'enabled']
|
||||
ordering_fields = ['name', 'enabled', 'width', 'height']
|
||||
|
||||
|
||||
class LabelTemplateDetail(
|
||||
@@ -341,7 +340,7 @@ class ReportTemplateList(TemplatePermissionMixin, ReportTemplateMixin, ListCreat
|
||||
"""API endpoint for viewing list of ReportTemplate objects."""
|
||||
|
||||
filterset_class = ReportFilter
|
||||
filter_backends = [DjangoFilterBackend, InvenTreeSearchFilter]
|
||||
filter_backends = SEARCH_ORDER_FILTER
|
||||
search_fields = ['name', 'description']
|
||||
ordering_fields = ['name', 'enabled']
|
||||
|
||||
|
||||
@@ -70,6 +70,11 @@ export type TableState = {
|
||||
idAccessor?: string;
|
||||
};
|
||||
|
||||
export type TableColumnFilterType =
|
||||
| string
|
||||
| string[]
|
||||
| (({ close }: { close: () => void }) => ReactNode);
|
||||
|
||||
/**
|
||||
* Table column properties
|
||||
*
|
||||
@@ -109,10 +114,7 @@ export type TableColumnProps<T = any> = {
|
||||
editable?: boolean;
|
||||
definition?: ApiFormFieldType;
|
||||
render?: (record: T, index?: number) => any;
|
||||
filter?:
|
||||
| string
|
||||
| string[]
|
||||
| (({ close }: { close: () => void }) => ReactNode);
|
||||
filter?: TableColumnFilterType;
|
||||
filtering?: boolean;
|
||||
width?: number;
|
||||
minWidth?: string | number;
|
||||
|
||||
@@ -10,8 +10,12 @@ function LabelTemplateTable() {
|
||||
templateEndpoint: ApiEndpoints.label_list,
|
||||
printingEndpoint: ApiEndpoints.label_print,
|
||||
additionalFormFields: {
|
||||
width: {},
|
||||
height: {}
|
||||
width: {
|
||||
sortable: true
|
||||
},
|
||||
height: {
|
||||
sortable: true
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -17,24 +17,44 @@ function ReportTemplateTable() {
|
||||
modelType: ModelType.reporttemplate,
|
||||
templateEndpoint: ApiEndpoints.report_list,
|
||||
printingEndpoint: ApiEndpoints.report_print,
|
||||
additionalFilters: [
|
||||
{
|
||||
name: 'landscape',
|
||||
label: t`Landscape`,
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: 'merge',
|
||||
label: t`Merge`,
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: 'attach_to_model',
|
||||
label: t`Attach to Model`,
|
||||
type: 'boolean'
|
||||
}
|
||||
],
|
||||
additionalFormFields: {
|
||||
page_size: {
|
||||
label: t`Page Size`
|
||||
},
|
||||
landscape: {
|
||||
label: t`Landscape`,
|
||||
filter: 'landscape',
|
||||
modelRenderer: (instance: any) => (
|
||||
<YesNoButton value={instance.landscape} />
|
||||
)
|
||||
},
|
||||
merge: {
|
||||
label: t`Merge`,
|
||||
filter: 'merge',
|
||||
modelRenderer: (instance: any) => (
|
||||
<YesNoButton value={instance.merge} />
|
||||
)
|
||||
},
|
||||
attach_to_model: {
|
||||
label: t`Attach to Model`,
|
||||
filter: 'attach_to_model',
|
||||
modelRenderer: (instance: any) => (
|
||||
<YesNoButton value={instance.attach_to_model} />
|
||||
)
|
||||
|
||||
@@ -18,8 +18,8 @@ import { apiUrl } from '@lib/functions/Api';
|
||||
import { identifierString } from '@lib/functions/Conversion';
|
||||
import useTable from '@lib/hooks/UseTable';
|
||||
import type { TableFilter } from '@lib/types/Filters';
|
||||
import type { ApiFormFieldSet } from '@lib/types/Forms';
|
||||
import type { TableColumn } from '@lib/types/Tables';
|
||||
import type { ApiFormFieldSet, ApiFormFieldType } from '@lib/types/Forms';
|
||||
import type { TableColumn, TableColumnFilterType } from '@lib/types/Tables';
|
||||
import {
|
||||
CodeEditor,
|
||||
PdfPreview,
|
||||
@@ -68,11 +68,21 @@ export type TemplateI = {
|
||||
template: string;
|
||||
};
|
||||
|
||||
// Additional field props to control the column behaviour in the template table
|
||||
interface TemplateFormFieldType extends ApiFormFieldType {
|
||||
sortable?: boolean;
|
||||
switchable?: boolean;
|
||||
filter?: TableColumnFilterType;
|
||||
}
|
||||
|
||||
type TemplateFormFieldSet = Record<string, TemplateFormFieldType>;
|
||||
|
||||
export interface TemplateProps {
|
||||
modelType: ModelType.labeltemplate | ModelType.reporttemplate;
|
||||
templateEndpoint: ApiEndpoints;
|
||||
printingEndpoint: ApiEndpoints;
|
||||
additionalFormFields?: ApiFormFieldSet;
|
||||
additionalFilters?: TableFilter[];
|
||||
additionalFormFields?: TemplateFormFieldSet;
|
||||
}
|
||||
|
||||
export function TemplateDrawer({
|
||||
@@ -233,6 +243,7 @@ export function TemplateTable({
|
||||
},
|
||||
{
|
||||
accessor: 'model_type',
|
||||
filter: 'model_type',
|
||||
sortable: true,
|
||||
switchable: false
|
||||
},
|
||||
@@ -276,10 +287,10 @@ export function TemplateTable({
|
||||
},
|
||||
...Object.entries(additionalFormFields || {}).map(([key, field]) => ({
|
||||
accessor: key,
|
||||
...field,
|
||||
title: field.label,
|
||||
sortable: false,
|
||||
switchable: true,
|
||||
title: field.label,
|
||||
...field,
|
||||
render: field.modelRenderer
|
||||
})),
|
||||
BooleanColumn({ accessor: 'enabled', title: t`Enabled` })
|
||||
@@ -391,6 +402,7 @@ export function TemplateTable({
|
||||
|
||||
const tableFilters: TableFilter[] = useMemo(() => {
|
||||
return [
|
||||
...(templateProps.additionalFilters || []),
|
||||
{
|
||||
name: 'enabled',
|
||||
label: t`Enabled`,
|
||||
@@ -404,7 +416,7 @@ export function TemplateTable({
|
||||
choices: modelTypeFilters.choices
|
||||
}
|
||||
];
|
||||
}, [modelTypeFilters.choices]);
|
||||
}, [templateProps.additionalFilters, modelTypeFilters.choices]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user