From 8f0ec252a2ae7ad031d169b30702142ca1862686 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 3 Jul 2026 08:00:40 +0000 Subject: [PATCH] Report asset management --- .../Index/Settings/AdminCenter/Index.tsx | 13 +- .../src/tables/settings/AssetTable.tsx | 124 ++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 src/frontend/src/tables/settings/AssetTable.tsx diff --git a/src/frontend/src/pages/Index/Settings/AdminCenter/Index.tsx b/src/frontend/src/pages/Index/Settings/AdminCenter/Index.tsx index 881a6bdeba..454225c5b5 100644 --- a/src/frontend/src/pages/Index/Settings/AdminCenter/Index.tsx +++ b/src/frontend/src/pages/Index/Settings/AdminCenter/Index.tsx @@ -16,6 +16,7 @@ import { IconListDetails, IconMail, IconPackages, + IconPhoto, IconPlugConnected, IconQrcode, IconReport, @@ -107,6 +108,10 @@ const SnippetTable = Loadable( lazy(() => import('../../../../tables/settings/SnippetTable')) ); +const AssetTable = Loadable( + lazy(() => import('../../../../tables/settings/AssetTable')) +); + export default function AdminCenter() { const user = useUserState(); @@ -231,6 +236,12 @@ export default function AdminCenter() { icon: , content: }, + { + name: 'assets', + label: t`Report Assets`, + icon: , + content: + }, { name: 'location-types', label: t`Location Types`, @@ -283,7 +294,7 @@ export default function AdminCenter() { { id: 'reporting', label: t`Reporting`, - panelIDs: ['labels', 'reports', 'snippets'] + panelIDs: ['labels', 'reports', 'snippets', 'assets'] }, { id: 'plm', diff --git a/src/frontend/src/tables/settings/AssetTable.tsx b/src/frontend/src/tables/settings/AssetTable.tsx new file mode 100644 index 0000000000..a04ac10af0 --- /dev/null +++ b/src/frontend/src/tables/settings/AssetTable.tsx @@ -0,0 +1,124 @@ +import { AddItemButton } from '@lib/components/AddItemButton'; +import { type RowAction, RowDeleteAction } from '@lib/components/RowActions'; +import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; +import { apiUrl } from '@lib/functions/Api'; +import useTable from '@lib/hooks/UseTable'; +import type { ApiFormFieldSet } from '@lib/types/Forms'; +import type { TableColumn } from '@lib/types/Tables'; +import { t } from '@lingui/core/macro'; +import { Alert, Text } from '@mantine/core'; +import { IconInfoCircle } from '@tabler/icons-react'; +import { type ReactNode, useCallback, useMemo, useState } from 'react'; +import { AttachmentLink } from '../../components/items/AttachmentLink'; +import { + useCreateApiFormModal, + useDeleteApiFormModal +} from '../../hooks/UseForm'; +import { useUserState } from '../../states/UserState'; +import { DescriptionColumn } from '../ColumnRenderers'; +import { InvenTreeTable } from '../InvenTreeTable'; + +export type AssetI = { + pk: number; + asset: string; + description: string; +}; + +export default function AssetTable() { + const table = useTable('report-asset'); + const user = useUserState(); + + const columns: TableColumn[] = useMemo(() => { + return [ + { + accessor: 'asset', + title: t`Asset`, + sortable: false, + switchable: false, + render: (record: AssetI) => { + if (!record.asset) { + return '-'; + } + + return ; + }, + noContext: true + }, + DescriptionColumn({ + accessor: 'description', + sortable: false, + switchable: false + }) + ]; + }, []); + + const [selectedAsset, setSelectedAsset] = useState(-1); + + const rowActions = useCallback( + (record: AssetI): RowAction[] => { + return [ + RowDeleteAction({ + hidden: !user.isStaff(), + onClick: () => { + setSelectedAsset(record.pk); + deleteAsset.open(); + } + }) + ]; + }, + [user] + ); + + const newAssetFields: ApiFormFieldSet = useMemo(() => { + return { + asset: {}, + description: {} + }; + }, []); + + const deleteAsset = useDeleteApiFormModal({ + url: ApiEndpoints.report_asset, + pk: selectedAsset, + title: t`Delete Asset`, + table: table + }); + + const newAsset = useCreateApiFormModal({ + url: ApiEndpoints.report_asset, + title: t`Add Asset`, + fields: newAssetFields, + table: table + }); + + const tableActions: ReactNode[] = useMemo(() => { + return [ + newAsset.open()} + tooltip={t`Add asset`} + hidden={!user.isStaff()} + /> + ]; + }, [user]); + + return ( + <> + {newAsset.modal} + {deleteAsset.modal} + } title={t`Assets`}> + {t`Assets are files (such as images) which can be used when rendering reports and labels.`} + + + + ); +}