2
0
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:
Oliver
2026-06-11 15:54:40 +10:00
committed by GitHub
parent 741f0e56c8
commit 39cc399a67
6 changed files with 61 additions and 20 deletions
@@ -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.
+6 -7
View File
@@ -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']
+6 -4
View File
@@ -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 (
<>