mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
[PUI] Small updates (#6320)
* Ensure .ts files are generated - "yarn run compile" before "yarn run dev" - ensures that .ts locale files are all generated * Implement "Add Part Category" button * Create new stock location * Rename customActionGroups to tableActions * Rename customFilters to tableFilters * Edit category from table * Edit stock location from table * Add some placeholder buttons * More placeholders
This commit is contained in:
parent
ab921ccb31
commit
d502d93380
@ -20,8 +20,10 @@ export type ActionButtonProps = {
|
||||
* Construct a simple action button with consistent styling
|
||||
*/
|
||||
export function ActionButton(props: ActionButtonProps) {
|
||||
const hidden = props.hidden ?? false;
|
||||
|
||||
return (
|
||||
!props.hidden && (
|
||||
!hidden && (
|
||||
<Tooltip
|
||||
key={`tooltip-${props.key}`}
|
||||
disabled={!props.tooltip && !props.text}
|
||||
|
@ -234,7 +234,6 @@ export function SearchDrawer({
|
||||
|
||||
// Re-fetch data whenever the search term is updated
|
||||
useEffect(() => {
|
||||
// TODO: Implement search functionality
|
||||
searchQuery.refetch();
|
||||
}, [searchText]);
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { RenderInlineModel } from './Instance';
|
||||
@ -6,10 +7,13 @@ import { RenderInlineModel } from './Instance';
|
||||
* Inline rendering of a single Part instance
|
||||
*/
|
||||
export function RenderPart({ instance }: { instance: any }): ReactNode {
|
||||
const stock = t`Stock` + `: ${instance.in_stock}`;
|
||||
|
||||
return (
|
||||
<RenderInlineModel
|
||||
primary={instance.name}
|
||||
secondary={instance.description}
|
||||
suffix={stock}
|
||||
image={instance.thumnbnail || instance.image}
|
||||
/>
|
||||
);
|
||||
|
@ -46,8 +46,8 @@ const defaultPageSize: number = 25;
|
||||
* @param enableRefresh : boolean - Enable refresh actions
|
||||
* @param pageSize : number - Number of records per page
|
||||
* @param barcodeActions : any[] - List of barcode actions
|
||||
* @param customFilters : TableFilter[] - List of custom filters
|
||||
* @param customActionGroups : any[] - List of custom action groups
|
||||
* @param tableFilters : TableFilter[] - List of custom filters
|
||||
* @param tableActions : any[] - List of custom action groups
|
||||
* @param printingActions : any[] - List of printing actions
|
||||
* @param dataFormatter : (data: any) => any - Callback function to reformat data returned by server (if not in default format)
|
||||
* @param rowActions : (record: any) => RowAction[] - Callback function to generate row actions
|
||||
@ -66,8 +66,8 @@ export type InvenTreeTableProps<T = any> = {
|
||||
enableRefresh?: boolean;
|
||||
pageSize?: number;
|
||||
barcodeActions?: any[];
|
||||
customFilters?: TableFilter[];
|
||||
customActionGroups?: React.ReactNode[];
|
||||
tableFilters?: TableFilter[];
|
||||
tableActions?: React.ReactNode[];
|
||||
printingActions?: any[];
|
||||
idAccessor?: string;
|
||||
dataFormatter?: (data: T) => any;
|
||||
@ -91,8 +91,8 @@ const defaultInvenTreeTableProps: InvenTreeTableProps = {
|
||||
defaultSortColumn: '',
|
||||
printingActions: [],
|
||||
barcodeActions: [],
|
||||
customFilters: [],
|
||||
customActionGroups: [],
|
||||
tableFilters: [],
|
||||
tableActions: [],
|
||||
idAccessor: 'pk',
|
||||
onRowClick: (record: any, index: number, event: any) => {}
|
||||
};
|
||||
@ -425,9 +425,9 @@ export function InvenTreeTable<T = any>({
|
||||
return (
|
||||
<>
|
||||
{tableProps.enableFilters &&
|
||||
(tableProps.customFilters?.length ?? 0) > 0 && (
|
||||
(tableProps.tableFilters?.length ?? 0) > 0 && (
|
||||
<FilterSelectDrawer
|
||||
availableFilters={tableProps.customFilters ?? []}
|
||||
availableFilters={tableProps.tableFilters ?? []}
|
||||
tableState={tableState}
|
||||
opened={filtersVisible}
|
||||
onClose={() => setFiltersVisible(false)}
|
||||
@ -436,7 +436,7 @@ export function InvenTreeTable<T = any>({
|
||||
<Stack spacing="sm">
|
||||
<Group position="apart">
|
||||
<Group position="left" key="custom-actions" spacing={5}>
|
||||
{tableProps.customActionGroups?.map((group, idx) => (
|
||||
{tableProps.tableActions?.map((group, idx) => (
|
||||
<Fragment key={idx}>{group}</Fragment>
|
||||
))}
|
||||
{(tableProps.barcodeActions?.length ?? 0 > 0) && (
|
||||
@ -490,7 +490,7 @@ export function InvenTreeTable<T = any>({
|
||||
/>
|
||||
)}
|
||||
{tableProps.enableFilters &&
|
||||
(tableProps.customFilters?.length ?? 0 > 0) && (
|
||||
(tableProps.tableFilters?.length ?? 0 > 0) && (
|
||||
<Indicator
|
||||
size="xs"
|
||||
label={tableState.activeFilters.length}
|
||||
|
@ -363,7 +363,7 @@ export function BomTable({
|
||||
part_detail: true,
|
||||
sub_part_detail: true
|
||||
},
|
||||
customFilters: tableFilters,
|
||||
tableFilters: tableFilters,
|
||||
onRowClick: (row) => navigate(`/part/${row.sub_part}`),
|
||||
rowActions: rowActions
|
||||
}}
|
||||
|
@ -116,7 +116,7 @@ export function UsedInTable({
|
||||
part_detail: true,
|
||||
sub_part_detail: true
|
||||
},
|
||||
customFilters: tableFilters,
|
||||
tableFilters: tableFilters,
|
||||
onRowClick: (row) => navigate(`/part/${row.part}`)
|
||||
}}
|
||||
/>
|
||||
|
@ -155,7 +155,7 @@ export function BuildOrderTable({ params = {} }: { params?: any }) {
|
||||
...params,
|
||||
part_detail: true
|
||||
},
|
||||
customFilters: tableFilters,
|
||||
tableFilters: tableFilters,
|
||||
onRowClick: (row) => navigate(`/build/${row.pk}`)
|
||||
}}
|
||||
/>
|
||||
|
@ -185,7 +185,7 @@ export function AddressTable({
|
||||
columns={columns}
|
||||
props={{
|
||||
rowActions: rowActions,
|
||||
customActionGroups: tableActions,
|
||||
tableActions: tableActions,
|
||||
params: {
|
||||
...params,
|
||||
company: companyId
|
||||
|
@ -133,7 +133,7 @@ export function ContactTable({
|
||||
columns={columns}
|
||||
props={{
|
||||
rowActions: rowActions,
|
||||
customActionGroups: tableActions,
|
||||
tableActions: tableActions,
|
||||
params: {
|
||||
...params,
|
||||
company: companyId
|
||||
|
@ -178,7 +178,7 @@ export function AttachmentTable({
|
||||
});
|
||||
}
|
||||
|
||||
const customActionGroups: ReactNode[] = useMemo(() => {
|
||||
const tableActions: ReactNode[] = useMemo(() => {
|
||||
let actions = [];
|
||||
|
||||
if (allowEdit) {
|
||||
@ -235,7 +235,7 @@ export function AttachmentTable({
|
||||
props={{
|
||||
noRecordsText: t`No attachments found`,
|
||||
enableSelection: true,
|
||||
customActionGroups: customActionGroups,
|
||||
tableActions: tableActions,
|
||||
rowActions: allowEdit && allowDelete ? rowActions : undefined,
|
||||
params: {
|
||||
[model]: pk
|
||||
|
@ -1,23 +1,30 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { useMemo } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { ApiPaths } from '../../../enums/ApiEndpoints';
|
||||
import { UserRoles } from '../../../enums/Roles';
|
||||
import { partCategoryFields } from '../../../forms/PartForms';
|
||||
import { openCreateApiForm, openEditApiForm } from '../../../functions/forms';
|
||||
import { useTable } from '../../../hooks/UseTable';
|
||||
import { apiUrl } from '../../../states/ApiState';
|
||||
import { useUserState } from '../../../states/UserState';
|
||||
import { AddItemButton } from '../../buttons/AddItemButton';
|
||||
import { YesNoButton } from '../../items/YesNoButton';
|
||||
import { TableColumn } from '../Column';
|
||||
import { DescriptionColumn } from '../ColumnRenderers';
|
||||
import { TableFilter } from '../Filter';
|
||||
import { InvenTreeTable } from '../InvenTreeTable';
|
||||
import { RowEditAction } from '../RowActions';
|
||||
|
||||
/**
|
||||
* PartCategoryTable - Displays a table of part categories
|
||||
*/
|
||||
export function PartCategoryTable({ params = {} }: { params?: any }) {
|
||||
export function PartCategoryTable({ parentId }: { parentId?: any }) {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const table = useTable('partcategory');
|
||||
const user = useUserState();
|
||||
|
||||
const tableColumns: TableColumn[] = useMemo(() => {
|
||||
return [
|
||||
@ -64,6 +71,62 @@ export function PartCategoryTable({ params = {} }: { params?: any }) {
|
||||
];
|
||||
}, []);
|
||||
|
||||
const addCategory = useCallback(() => {
|
||||
let fields = partCategoryFields({});
|
||||
|
||||
if (parentId) {
|
||||
fields['parent'].value = parentId;
|
||||
}
|
||||
|
||||
openCreateApiForm({
|
||||
url: apiUrl(ApiPaths.category_list),
|
||||
title: t`Add Part Category`,
|
||||
fields: fields,
|
||||
onFormSuccess(data: any) {
|
||||
if (data.pk) {
|
||||
navigate(`/part/category/${data.pk}`);
|
||||
} else {
|
||||
table.refreshTable();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [parentId]);
|
||||
|
||||
const tableActions = useMemo(() => {
|
||||
let can_add = user.hasAddRole(UserRoles.part_category);
|
||||
|
||||
return [
|
||||
<AddItemButton
|
||||
tooltip={t`Add Part Category`}
|
||||
onClick={addCategory}
|
||||
disabled={!can_add}
|
||||
/>
|
||||
];
|
||||
}, [user]);
|
||||
|
||||
const rowActions = useCallback(
|
||||
(record: any) => {
|
||||
let can_edit = user.hasChangeRole(UserRoles.part_category);
|
||||
|
||||
return [
|
||||
RowEditAction({
|
||||
hidden: !can_edit,
|
||||
onClick: () => {
|
||||
openEditApiForm({
|
||||
url: ApiPaths.category_list,
|
||||
pk: record.pk,
|
||||
title: t`Edit Part Category`,
|
||||
fields: partCategoryFields({}),
|
||||
successMessage: t`Part category updated`,
|
||||
onFormSuccess: table.refreshTable
|
||||
});
|
||||
}
|
||||
})
|
||||
];
|
||||
},
|
||||
[user]
|
||||
);
|
||||
|
||||
return (
|
||||
<InvenTreeTable
|
||||
url={apiUrl(ApiPaths.category_list)}
|
||||
@ -71,11 +134,12 @@ export function PartCategoryTable({ params = {} }: { params?: any }) {
|
||||
columns={tableColumns}
|
||||
props={{
|
||||
enableDownload: true,
|
||||
enableSelection: true,
|
||||
params: {
|
||||
...params
|
||||
parent: parentId ?? 'null'
|
||||
},
|
||||
customFilters: tableFilters,
|
||||
tableFilters: tableFilters,
|
||||
tableActions: tableActions,
|
||||
rowActions: rowActions,
|
||||
onRowClick: (record, index, event) => {
|
||||
navigate(`/part/category/${record.pk}`);
|
||||
}
|
||||
|
@ -180,8 +180,8 @@ export function PartParameterTable({ partId }: { partId: any }) {
|
||||
columns={tableColumns}
|
||||
props={{
|
||||
rowActions: rowActions,
|
||||
customActionGroups: tableActions,
|
||||
customFilters: [
|
||||
tableActions: tableActions,
|
||||
tableFilters: [
|
||||
{
|
||||
name: 'include_variants',
|
||||
label: t`Include Variants`,
|
||||
|
@ -131,8 +131,8 @@ export default function PartParameterTemplateTable() {
|
||||
columns={tableColumns}
|
||||
props={{
|
||||
rowActions: rowActions,
|
||||
customFilters: tableFilters,
|
||||
customActionGroups: tableActions
|
||||
tableFilters: tableFilters,
|
||||
tableActions: tableActions
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -275,7 +275,7 @@ export function PartListTable({ props }: { props: InvenTreeTableProps }) {
|
||||
props={{
|
||||
...props,
|
||||
enableDownload: true,
|
||||
customFilters: tableFilters,
|
||||
tableFilters: tableFilters,
|
||||
params: {
|
||||
...props.params,
|
||||
category_detail: true
|
||||
|
@ -140,8 +140,8 @@ export default function PartTestTemplateTable({ partId }: { partId: number }) {
|
||||
params: {
|
||||
part: partId
|
||||
},
|
||||
customFilters: tableFilters,
|
||||
customActionGroups: tableActions,
|
||||
tableFilters: tableFilters,
|
||||
tableActions: tableActions,
|
||||
rowActions: rowActions
|
||||
}}
|
||||
/>
|
||||
|
@ -37,7 +37,7 @@ export function PartVariantTable({ partId }: { partId: string }) {
|
||||
<PartListTable
|
||||
props={{
|
||||
enableDownload: false,
|
||||
customFilters: tableFilters,
|
||||
tableFilters: tableFilters,
|
||||
params: {
|
||||
ancestor: partId
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ export function RelatedPartTable({ partId }: { partId: number }): ReactNode {
|
||||
category_detail: true
|
||||
},
|
||||
rowActions: rowActions,
|
||||
customActionGroups: customActions
|
||||
tableActions: customActions
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -493,8 +493,8 @@ export function PluginListTable({ props }: { props: InvenTreeTableProps }) {
|
||||
},
|
||||
rowActions: rowActions,
|
||||
onRowClick: (plugin) => navigate(`${plugin.pk}/`),
|
||||
customActionGroups: tableActions,
|
||||
customFilters: [
|
||||
tableActions: tableActions,
|
||||
tableFilters: [
|
||||
{
|
||||
name: 'active',
|
||||
label: t`Active`,
|
||||
|
@ -5,9 +5,11 @@ import { ApiPaths } from '../../../enums/ApiEndpoints';
|
||||
import { UserRoles } from '../../../enums/Roles';
|
||||
import { useManufacturerPartFields } from '../../../forms/CompanyForms';
|
||||
import { openDeleteApiForm, openEditApiForm } from '../../../functions/forms';
|
||||
import { notYetImplemented } from '../../../functions/notifications';
|
||||
import { useTable } from '../../../hooks/UseTable';
|
||||
import { apiUrl } from '../../../states/ApiState';
|
||||
import { useUserState } from '../../../states/UserState';
|
||||
import { AddItemButton } from '../../buttons/AddItemButton';
|
||||
import { Thumbnail } from '../../images/Thumbnail';
|
||||
import { TableColumn } from '../Column';
|
||||
import { DescriptionColumn, LinkColumn, PartColumn } from '../ColumnRenderers';
|
||||
@ -57,9 +59,22 @@ export function ManufacturerPartTable({ params }: { params: any }): ReactNode {
|
||||
];
|
||||
}, [params]);
|
||||
|
||||
const addManufacturerPart = useCallback(() => {
|
||||
notYetImplemented();
|
||||
}, []);
|
||||
|
||||
const tableActions = useMemo(() => {
|
||||
// TODO: Custom actions
|
||||
return [];
|
||||
let can_add =
|
||||
user.hasAddRole(UserRoles.purchase_order) &&
|
||||
user.hasAddRole(UserRoles.part);
|
||||
|
||||
return [
|
||||
<AddItemButton
|
||||
tooltip={t`Add Manufacturer Part`}
|
||||
onClick={addManufacturerPart}
|
||||
hidden={!can_add}
|
||||
/>
|
||||
];
|
||||
}, [user]);
|
||||
|
||||
const editManufacturerPartFields = useManufacturerPartFields();
|
||||
@ -112,7 +127,7 @@ export function ManufacturerPartTable({ params }: { params: any }): ReactNode {
|
||||
manufacturer_detail: true
|
||||
},
|
||||
rowActions: rowActions,
|
||||
customActionGroups: tableActions
|
||||
tableActions: tableActions
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -260,7 +260,7 @@ export function PurchaseOrderLineItemTable({
|
||||
part_detail: true
|
||||
},
|
||||
rowActions: rowActions,
|
||||
customActionGroups: tableActions
|
||||
tableActions: tableActions
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -1,11 +1,15 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { useMemo } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { ApiPaths } from '../../../enums/ApiEndpoints';
|
||||
import { ModelType } from '../../../enums/ModelType';
|
||||
import { UserRoles } from '../../../enums/Roles';
|
||||
import { notYetImplemented } from '../../../functions/notifications';
|
||||
import { useTable } from '../../../hooks/UseTable';
|
||||
import { apiUrl } from '../../../states/ApiState';
|
||||
import { useUserState } from '../../../states/UserState';
|
||||
import { AddItemButton } from '../../buttons/AddItemButton';
|
||||
import { Thumbnail } from '../../images/Thumbnail';
|
||||
import {
|
||||
CreationDateColumn,
|
||||
@ -33,6 +37,7 @@ export function PurchaseOrderTable({ params }: { params?: any }) {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const table = useTable('purchase-order');
|
||||
const user = useUserState();
|
||||
|
||||
const tableFilters: TableFilter[] = useMemo(() => {
|
||||
return [
|
||||
@ -94,6 +99,20 @@ export function PurchaseOrderTable({ params }: { params?: any }) {
|
||||
];
|
||||
}, []);
|
||||
|
||||
const addPurchaseOrder = useCallback(() => {
|
||||
notYetImplemented();
|
||||
}, []);
|
||||
|
||||
const tableActions = useMemo(() => {
|
||||
return [
|
||||
<AddItemButton
|
||||
tooltip={t`Add Purchase Order`}
|
||||
onClick={addPurchaseOrder}
|
||||
hidden={!user.hasAddRole(UserRoles.purchase_order)}
|
||||
/>
|
||||
];
|
||||
}, [user]);
|
||||
|
||||
return (
|
||||
<InvenTreeTable
|
||||
url={apiUrl(ApiPaths.purchase_order_list)}
|
||||
@ -104,7 +123,8 @@ export function PurchaseOrderTable({ params }: { params?: any }) {
|
||||
...params,
|
||||
supplier_detail: true
|
||||
},
|
||||
customFilters: tableFilters,
|
||||
tableFilters: tableFilters,
|
||||
tableActions: tableActions,
|
||||
onRowClick: (row: any) => {
|
||||
if (row.pk) {
|
||||
navigate(`/purchasing/purchase-order/${row.pk}`);
|
||||
|
@ -229,7 +229,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
|
||||
manufacturer_detail: true
|
||||
},
|
||||
rowActions: rowActions,
|
||||
customActionGroups: tableActions
|
||||
tableActions: tableActions
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
@ -1,11 +1,15 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { useMemo } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { ApiPaths } from '../../../enums/ApiEndpoints';
|
||||
import { ModelType } from '../../../enums/ModelType';
|
||||
import { UserRoles } from '../../../enums/Roles';
|
||||
import { notYetImplemented } from '../../../functions/notifications';
|
||||
import { useTable } from '../../../hooks/UseTable';
|
||||
import { apiUrl } from '../../../states/ApiState';
|
||||
import { useUserState } from '../../../states/UserState';
|
||||
import { AddItemButton } from '../../buttons/AddItemButton';
|
||||
import { Thumbnail } from '../../images/Thumbnail';
|
||||
import {
|
||||
CreationDateColumn,
|
||||
@ -27,6 +31,7 @@ import { InvenTreeTable } from '../InvenTreeTable';
|
||||
|
||||
export function ReturnOrderTable({ params }: { params?: any }) {
|
||||
const table = useTable('return-orders');
|
||||
const user = useUserState();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
@ -90,6 +95,20 @@ export function ReturnOrderTable({ params }: { params?: any }) {
|
||||
];
|
||||
}, []);
|
||||
|
||||
const addReturnOrder = useCallback(() => {
|
||||
notYetImplemented();
|
||||
}, []);
|
||||
|
||||
const tableActions = useMemo(() => {
|
||||
return [
|
||||
<AddItemButton
|
||||
tooltip={t`Add Return Order`}
|
||||
onClick={addReturnOrder}
|
||||
hidden={!user.hasAddRole(UserRoles.sales_order)}
|
||||
/>
|
||||
];
|
||||
}, [user]);
|
||||
|
||||
return (
|
||||
<InvenTreeTable
|
||||
url={apiUrl(ApiPaths.return_order_list)}
|
||||
@ -100,7 +119,8 @@ export function ReturnOrderTable({ params }: { params?: any }) {
|
||||
...params,
|
||||
customer_detail: true
|
||||
},
|
||||
customFilters: tableFilters,
|
||||
tableFilters: tableFilters,
|
||||
tableActions: tableActions,
|
||||
onRowClick: (row: any) => {
|
||||
if (row.pk) {
|
||||
navigate(`/sales/return-order/${row.pk}/`);
|
||||
|
@ -1,11 +1,15 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { useMemo } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { ApiPaths } from '../../../enums/ApiEndpoints';
|
||||
import { ModelType } from '../../../enums/ModelType';
|
||||
import { UserRoles } from '../../../enums/Roles';
|
||||
import { notYetImplemented } from '../../../functions/notifications';
|
||||
import { useTable } from '../../../hooks/UseTable';
|
||||
import { apiUrl } from '../../../states/ApiState';
|
||||
import { useUserState } from '../../../states/UserState';
|
||||
import { AddItemButton } from '../../buttons/AddItemButton';
|
||||
import { Thumbnail } from '../../images/Thumbnail';
|
||||
import {
|
||||
CreationDateColumn,
|
||||
@ -28,6 +32,7 @@ import { InvenTreeTable } from '../InvenTreeTable';
|
||||
|
||||
export function SalesOrderTable({ params }: { params?: any }) {
|
||||
const table = useTable('sales-order');
|
||||
const user = useUserState();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
@ -91,6 +96,20 @@ export function SalesOrderTable({ params }: { params?: any }) {
|
||||
];
|
||||
}, []);
|
||||
|
||||
const addSalesOrder = useCallback(() => {
|
||||
notYetImplemented();
|
||||
}, []);
|
||||
|
||||
const tableActions = useMemo(() => {
|
||||
return [
|
||||
<AddItemButton
|
||||
tooltip={t`Add Sales Order`}
|
||||
onClick={addSalesOrder}
|
||||
hidden={!user.hasAddRole(UserRoles.sales_order)}
|
||||
/>
|
||||
];
|
||||
}, [user]);
|
||||
|
||||
return (
|
||||
<InvenTreeTable
|
||||
url={apiUrl(ApiPaths.sales_order_list)}
|
||||
@ -101,7 +120,8 @@ export function SalesOrderTable({ params }: { params?: any }) {
|
||||
...params,
|
||||
customer_detail: true
|
||||
},
|
||||
customFilters: tableFilters,
|
||||
tableFilters: tableFilters,
|
||||
tableActions: tableActions,
|
||||
onRowClick: (row: any) => {
|
||||
if (row.pk) {
|
||||
navigate(`/sales/sales-order/${row.pk}/`);
|
||||
|
@ -66,7 +66,7 @@ export function CurrencyTable() {
|
||||
tableState={table}
|
||||
columns={columns}
|
||||
props={{
|
||||
customActionGroups: tableActions,
|
||||
tableActions: tableActions,
|
||||
dataFormatter: (data) => {
|
||||
let rates = data?.exchange_rates ?? {};
|
||||
|
||||
|
@ -117,7 +117,7 @@ export default function CustomUnitsTable() {
|
||||
columns={columns}
|
||||
props={{
|
||||
rowActions: rowActions,
|
||||
customActionGroups: tableActions
|
||||
tableActions: tableActions
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -166,7 +166,7 @@ export function GroupTable() {
|
||||
columns={columns}
|
||||
props={{
|
||||
rowActions: rowActions,
|
||||
customActionGroups: tableActions,
|
||||
tableActions: tableActions,
|
||||
onRowClick: (record) => openDetailDrawer(record.pk)
|
||||
}}
|
||||
/>
|
||||
|
@ -106,7 +106,7 @@ export default function ProjectCodeTable() {
|
||||
columns={columns}
|
||||
props={{
|
||||
rowActions: rowActions,
|
||||
customActionGroups: tableActions
|
||||
tableActions: tableActions
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -261,7 +261,7 @@ export function UserTable() {
|
||||
columns={columns}
|
||||
props={{
|
||||
rowActions: rowActions,
|
||||
customActionGroups: tableActions,
|
||||
tableActions: tableActions,
|
||||
onRowClick: (record) => openDetailDrawer(record.pk)
|
||||
}}
|
||||
/>
|
||||
|
@ -344,7 +344,7 @@ export function StockItemTable({ params = {} }: { params?: any }) {
|
||||
props={{
|
||||
enableDownload: true,
|
||||
enableSelection: true,
|
||||
customFilters: tableFilters,
|
||||
tableFilters: tableFilters,
|
||||
onRowClick: (record) => navigate(`/stock/item/${record.pk}`),
|
||||
params: {
|
||||
...params,
|
||||
|
@ -1,21 +1,28 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { useMemo } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { ApiPaths } from '../../../enums/ApiEndpoints';
|
||||
import { UserRoles } from '../../../enums/Roles';
|
||||
import { stockLocationFields } from '../../../forms/StockForms';
|
||||
import { openCreateApiForm, openEditApiForm } from '../../../functions/forms';
|
||||
import { useTable } from '../../../hooks/UseTable';
|
||||
import { apiUrl } from '../../../states/ApiState';
|
||||
import { useUserState } from '../../../states/UserState';
|
||||
import { AddItemButton } from '../../buttons/AddItemButton';
|
||||
import { YesNoButton } from '../../items/YesNoButton';
|
||||
import { TableColumn } from '../Column';
|
||||
import { DescriptionColumn } from '../ColumnRenderers';
|
||||
import { TableFilter } from '../Filter';
|
||||
import { InvenTreeTable } from '../InvenTreeTable';
|
||||
import { RowEditAction } from '../RowActions';
|
||||
|
||||
/**
|
||||
* Stock location table
|
||||
*/
|
||||
export function StockLocationTable({ params = {} }: { params?: any }) {
|
||||
export function StockLocationTable({ parentId }: { parentId?: any }) {
|
||||
const table = useTable('stocklocation');
|
||||
const user = useUserState();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
@ -85,7 +92,63 @@ export function StockLocationTable({ params = {} }: { params?: any }) {
|
||||
render: (record: any) => record.location_type_detail?.name
|
||||
}
|
||||
];
|
||||
}, [params]);
|
||||
}, []);
|
||||
|
||||
const addLocation = useCallback(() => {
|
||||
let fields = stockLocationFields({});
|
||||
|
||||
if (parentId) {
|
||||
fields['parent'].value = parentId;
|
||||
}
|
||||
|
||||
openCreateApiForm({
|
||||
url: apiUrl(ApiPaths.stock_location_list),
|
||||
title: t`Add Stock Location`,
|
||||
fields: fields,
|
||||
onFormSuccess(data: any) {
|
||||
if (data.pk) {
|
||||
navigate(`/stock/location/${data.pk}`);
|
||||
} else {
|
||||
table.refreshTable();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [parentId]);
|
||||
|
||||
const tableActions = useMemo(() => {
|
||||
let can_add = user.hasAddRole(UserRoles.stock_location);
|
||||
|
||||
return [
|
||||
<AddItemButton
|
||||
tooltip={t`Add Stock Location`}
|
||||
onClick={addLocation}
|
||||
disabled={!can_add}
|
||||
/>
|
||||
];
|
||||
}, [user]);
|
||||
|
||||
const rowActions = useCallback(
|
||||
(record: any) => {
|
||||
let can_edit = user.hasChangeRole(UserRoles.stock_location);
|
||||
|
||||
return [
|
||||
RowEditAction({
|
||||
hidden: !can_edit,
|
||||
onClick: () => {
|
||||
openEditApiForm({
|
||||
url: ApiPaths.stock_location_list,
|
||||
pk: record.pk,
|
||||
title: t`Edit Stock Location`,
|
||||
fields: stockLocationFields({}),
|
||||
successMessage: t`Stock location updated`,
|
||||
onFormSuccess: table.refreshTable
|
||||
});
|
||||
}
|
||||
})
|
||||
];
|
||||
},
|
||||
[user]
|
||||
);
|
||||
|
||||
return (
|
||||
<InvenTreeTable
|
||||
@ -94,8 +157,12 @@ export function StockLocationTable({ params = {} }: { params?: any }) {
|
||||
columns={tableColumns}
|
||||
props={{
|
||||
enableDownload: true,
|
||||
params: params,
|
||||
customFilters: tableFilters,
|
||||
params: {
|
||||
parent: parentId ?? 'null'
|
||||
},
|
||||
tableFilters: tableFilters,
|
||||
tableActions: tableActions,
|
||||
rowActions: rowActions,
|
||||
onRowClick: (record) => {
|
||||
navigate(`/stock/location/${record.pk}`);
|
||||
}
|
||||
|
@ -133,3 +133,19 @@ export function useEditStockItem({
|
||||
onFormSuccess: callback
|
||||
});
|
||||
}
|
||||
|
||||
export function stockLocationFields({}: {}): ApiFormFieldSet {
|
||||
let fields: ApiFormFieldSet = {
|
||||
parent: {
|
||||
description: t`Parent stock location`,
|
||||
required: false
|
||||
},
|
||||
name: {},
|
||||
description: {},
|
||||
structural: {},
|
||||
external: {},
|
||||
location_type: {}
|
||||
};
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
@ -64,13 +64,7 @@ export default function CategoryDetail({}: {}) {
|
||||
name: 'subcategories',
|
||||
label: t`Part Categories`,
|
||||
icon: <IconSitemap />,
|
||||
content: (
|
||||
<PartCategoryTable
|
||||
params={{
|
||||
parent: id
|
||||
}}
|
||||
/>
|
||||
)
|
||||
content: <PartCategoryTable parentId={id} />
|
||||
},
|
||||
{
|
||||
name: 'parameters',
|
||||
|
@ -53,13 +53,7 @@ export default function Stock() {
|
||||
name: 'sublocations',
|
||||
label: t`Stock Locations`,
|
||||
icon: <IconSitemap />,
|
||||
content: (
|
||||
<StockLocationTable
|
||||
params={{
|
||||
parent: id
|
||||
}}
|
||||
/>
|
||||
)
|
||||
content: <StockLocationTable parentId={id} />
|
||||
}
|
||||
];
|
||||
}, [location, id]);
|
||||
|
Loading…
Reference in New Issue
Block a user