2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00

[PUI] Refactor "notYetImplemented" (#7913)

* Remove default "not yet implemented" action

- Will force us to manually add "not yet implemented"
- Intended to highlight where we still need to work

* Refactor more components

* Fix for onClick
This commit is contained in:
Oliver 2024-08-19 21:01:05 +10:00 committed by GitHub
parent 4b140aba8d
commit a7d9600c3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
48 changed files with 223 additions and 255 deletions

View File

@ -2,7 +2,6 @@ import { ActionIcon, FloatingPosition, Group, Tooltip } from '@mantine/core';
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import { identifierString } from '../../functions/conversion'; import { identifierString } from '../../functions/conversion';
import { notYetImplemented } from '../../functions/notifications';
export type ActionButtonProps = { export type ActionButtonProps = {
icon?: ReactNode; icon?: ReactNode;
@ -13,7 +12,7 @@ export type ActionButtonProps = {
size?: number | string; size?: number | string;
radius?: number | string; radius?: number | string;
disabled?: boolean; disabled?: boolean;
onClick?: any; onClick: (event?: any) => void;
hidden?: boolean; hidden?: boolean;
tooltipAlignment?: FloatingPosition; tooltipAlignment?: FloatingPosition;
}; };
@ -42,7 +41,9 @@ export function ActionButton(props: ActionButtonProps) {
aria-label={`action-button-${identifierString( aria-label={`action-button-${identifierString(
props.tooltip ?? props.text ?? '' props.tooltip ?? props.text ?? ''
)}`} )}`}
onClick={props.onClick ?? notYetImplemented} onClick={() => {
props.onClick();
}}
variant={props.variant ?? 'transparent'} variant={props.variant ?? 'transparent'}
> >
<Group gap="xs" wrap="nowrap"> <Group gap="xs" wrap="nowrap">

View File

@ -1,7 +1,6 @@
import { Button, Tooltip } from '@mantine/core'; import { Button, Tooltip } from '@mantine/core';
import { InvenTreeIcon, InvenTreeIconType } from '../../functions/icons'; import { InvenTreeIcon, InvenTreeIconType } from '../../functions/icons';
import { notYetImplemented } from '../../functions/notifications';
/** /**
* A "primary action" button for display on a page detail, (for example) * A "primary action" button for display on a page detail, (for example)
@ -19,7 +18,7 @@ export default function PrimaryActionButton({
icon?: InvenTreeIconType; icon?: InvenTreeIconType;
color?: string; color?: string;
hidden?: boolean; hidden?: boolean;
onClick?: () => void; onClick: () => void;
}) { }) {
if (hidden) { if (hidden) {
return null; return null;
@ -32,7 +31,7 @@ export default function PrimaryActionButton({
color={color} color={color}
radius="sm" radius="sm"
p="xs" p="xs"
onClick={onClick ?? notYetImplemented} onClick={onClick}
> >
{title} {title}
</Button> </Button>

View File

@ -22,7 +22,11 @@ import { apiUrl } from '../../states/ApiState';
import { TableColumn } from '../../tables/Column'; import { TableColumn } from '../../tables/Column';
import { TableFilter } from '../../tables/Filter'; import { TableFilter } from '../../tables/Filter';
import { InvenTreeTable } from '../../tables/InvenTreeTable'; import { InvenTreeTable } from '../../tables/InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../../tables/RowActions'; import {
RowAction,
RowDeleteAction,
RowEditAction
} from '../../tables/RowActions';
import { ActionButton } from '../buttons/ActionButton'; import { ActionButton } from '../buttons/ActionButton';
import { YesNoButton } from '../buttons/YesNoButton'; import { YesNoButton } from '../buttons/YesNoButton';
import { ApiFormFieldSet } from '../forms/fields/ApiFormField'; import { ApiFormFieldSet } from '../forms/fields/ApiFormField';
@ -316,7 +320,7 @@ export default function ImporterDataSelector({
}, [session]); }, [session]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
{ {
title: t`Accept`, title: t`Accept`,

View File

@ -20,16 +20,15 @@ import { ReactNode, useMemo } from 'react';
import { ModelType } from '../../enums/ModelType'; import { ModelType } from '../../enums/ModelType';
import { identifierString } from '../../functions/conversion'; import { identifierString } from '../../functions/conversion';
import { InvenTreeIcon } from '../../functions/icons'; import { InvenTreeIcon } from '../../functions/icons';
import { notYetImplemented } from '../../functions/notifications';
import { InvenTreeQRCode } from './QRCode'; import { InvenTreeQRCode } from './QRCode';
export type ActionDropdownItem = { export type ActionDropdownItem = {
icon: ReactNode; icon?: ReactNode;
name: string; name?: string;
tooltip?: string; tooltip?: string;
disabled?: boolean; disabled?: boolean;
hidden?: boolean; hidden?: boolean;
onClick?: () => void; onClick: (event?: any) => void;
indicator?: Omit<IndicatorProps, 'children'>; indicator?: Omit<IndicatorProps, 'children'>;
}; };
@ -97,13 +96,7 @@ export function ActionDropdown({
<Menu.Item <Menu.Item
aria-label={id} aria-label={id}
leftSection={action.icon} leftSection={action.icon}
onClick={() => { onClick={action.onClick}
if (action.onClick != undefined) {
action.onClick();
} else {
notYetImplemented();
}
}}
disabled={action.disabled} disabled={action.disabled}
> >
{action.name} {action.name}
@ -159,131 +152,79 @@ export function ViewBarcodeAction({
} }
// Common action button for linking a custom barcode // Common action button for linking a custom barcode
export function LinkBarcodeAction({ export function LinkBarcodeAction(
hidden = false, props: ActionDropdownItem
onClick ): ActionDropdownItem {
}: {
hidden?: boolean;
onClick?: () => void;
}): ActionDropdownItem {
return { return {
...props,
icon: <IconLink />, icon: <IconLink />,
name: t`Link Barcode`, name: t`Link Barcode`,
tooltip: t`Link custom barcode`, tooltip: t`Link custom barcode`
onClick: onClick,
hidden: hidden
}; };
} }
// Common action button for un-linking a custom barcode // Common action button for un-linking a custom barcode
export function UnlinkBarcodeAction({ export function UnlinkBarcodeAction(
hidden = false, props: ActionDropdownItem
onClick ): ActionDropdownItem {
}: {
hidden?: boolean;
onClick?: () => void;
}): ActionDropdownItem {
return { return {
...props,
icon: <IconUnlink />, icon: <IconUnlink />,
name: t`Unlink Barcode`, name: t`Unlink Barcode`,
tooltip: t`Unlink custom barcode`, tooltip: t`Unlink custom barcode`
onClick: onClick,
hidden: hidden
}; };
} }
// Common action button for editing an item // Common action button for editing an item
export function EditItemAction({ export function EditItemAction(props: ActionDropdownItem): ActionDropdownItem {
hidden = false,
tooltip,
onClick
}: {
hidden?: boolean;
tooltip?: string;
onClick?: () => void;
}): ActionDropdownItem {
return { return {
...props,
icon: <IconEdit color="blue" />, icon: <IconEdit color="blue" />,
name: t`Edit`, name: t`Edit`,
tooltip: tooltip ?? `Edit item`, tooltip: props.tooltip ?? t`Edit item`
onClick: onClick,
hidden: hidden
}; };
} }
// Common action button for deleting an item // Common action button for deleting an item
export function DeleteItemAction({ export function DeleteItemAction(
hidden = false, props: ActionDropdownItem
disabled = false, ): ActionDropdownItem {
tooltip,
onClick
}: {
hidden?: boolean;
disabled?: boolean;
tooltip?: string;
onClick?: () => void;
}): ActionDropdownItem {
return { return {
...props,
icon: <IconTrash color="red" />, icon: <IconTrash color="red" />,
name: t`Delete`, name: t`Delete`,
tooltip: tooltip ?? t`Delete item`, tooltip: props.tooltip ?? t`Delete item`
onClick: onClick,
hidden: hidden,
disabled: disabled
}; };
} }
export function HoldItemAction({ export function HoldItemAction(props: ActionDropdownItem): ActionDropdownItem {
hidden = false,
tooltip,
onClick
}: {
hidden?: boolean;
tooltip?: string;
onClick?: () => void;
}): ActionDropdownItem {
return { return {
...props,
icon: <InvenTreeIcon icon="hold" iconProps={{ color: 'orange' }} />, icon: <InvenTreeIcon icon="hold" iconProps={{ color: 'orange' }} />,
name: t`Hold`, name: t`Hold`,
tooltip: tooltip ?? t`Hold`, tooltip: props.tooltip ?? t`Hold`
onClick: onClick,
hidden: hidden
}; };
} }
export function CancelItemAction({ export function CancelItemAction(
hidden = false, props: ActionDropdownItem
tooltip, ): ActionDropdownItem {
onClick
}: {
hidden?: boolean;
tooltip?: string;
onClick?: () => void;
}): ActionDropdownItem {
return { return {
...props,
icon: <InvenTreeIcon icon="cancel" iconProps={{ color: 'red' }} />, icon: <InvenTreeIcon icon="cancel" iconProps={{ color: 'red' }} />,
name: t`Cancel`, name: t`Cancel`,
tooltip: tooltip ?? t`Cancel`, tooltip: props.tooltip ?? t`Cancel`
onClick: onClick,
hidden: hidden
}; };
} }
// Common action button for duplicating an item // Common action button for duplicating an item
export function DuplicateItemAction({ export function DuplicateItemAction(
hidden = false, props: ActionDropdownItem
tooltip, ): ActionDropdownItem {
onClick
}: {
hidden?: boolean;
tooltip?: string;
onClick?: () => void;
}): ActionDropdownItem {
return { return {
...props,
icon: <IconCopy color="green" />, icon: <IconCopy color="green" />,
name: t`Duplicate`, name: t`Duplicate`,
tooltip: tooltip ?? t`Duplicate item`, tooltip: props.tooltip ?? t`Duplicate item`
onClick: onClick,
hidden: hidden
}; };
} }

View File

@ -43,6 +43,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 { useBuildOrderFields } from '../../forms/BuildForms'; import { useBuildOrderFields } from '../../forms/BuildForms';
import { notYetImplemented } from '../../functions/notifications';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
useEditApiFormModal useEditApiFormModal
@ -477,10 +478,12 @@ export default function BuildDetail() {
pk: build.pk pk: build.pk
}), }),
LinkBarcodeAction({ LinkBarcodeAction({
hidden: build?.barcode_hash hidden: build?.barcode_hash,
onClick: notYetImplemented
}), }),
UnlinkBarcodeAction({ UnlinkBarcodeAction({
hidden: !build?.barcode_hash hidden: !build?.barcode_hash,
onClick: notYetImplemented
}) })
]} ]}
/>, />,

View File

@ -37,7 +37,10 @@ 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 { companyFields } from '../../forms/CompanyForms'; import { companyFields } from '../../forms/CompanyForms';
import { useEditApiFormModal } from '../../hooks/UseForm'; import {
useDeleteApiFormModal,
useEditApiFormModal
} from '../../hooks/UseForm';
import { useInstance } from '../../hooks/UseInstance'; import { useInstance } from '../../hooks/UseInstance';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { AddressTable } from '../../tables/company/AddressTable'; import { AddressTable } from '../../tables/company/AddressTable';
@ -289,6 +292,13 @@ export default function CompanyDetail(props: Readonly<CompanyDetailProps>) {
onFormSuccess: refreshInstance onFormSuccess: refreshInstance
}); });
const deleteCompany = useDeleteApiFormModal({
url: ApiEndpoints.company_list,
pk: company?.pk,
title: t`Delete Company`,
onFormSuccess: refreshInstance
});
const companyActions = useMemo(() => { const companyActions = useMemo(() => {
return [ return [
<AdminButton model={ModelType.company} pk={company.pk} />, <AdminButton model={ModelType.company} pk={company.pk} />,
@ -301,7 +311,8 @@ export default function CompanyDetail(props: Readonly<CompanyDetailProps>) {
onClick: () => editCompany.open() onClick: () => editCompany.open()
}), }),
DeleteItemAction({ DeleteItemAction({
hidden: !user.hasDeleteRole(UserRoles.purchase_order) hidden: !user.hasDeleteRole(UserRoles.purchase_order),
onClick: () => deleteCompany.open()
}) })
]} ]}
/> />
@ -321,6 +332,7 @@ export default function CompanyDetail(props: Readonly<CompanyDetailProps>) {
return ( return (
<> <>
{editCompany.modal} {editCompany.modal}
{deleteCompany.modal}
<InstanceDetail status={requestStatus} loading={instanceQuery.isFetching}> <InstanceDetail status={requestStatus} loading={instanceQuery.isFetching}>
<Stack gap="xs"> <Stack gap="xs">
<PageDetail <PageDetail

View File

@ -34,6 +34,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 { useSupplierPartFields } from '../../forms/CompanyForms'; import { useSupplierPartFields } from '../../forms/CompanyForms';
import { notYetImplemented } from '../../functions/notifications';
import { getDetailUrl } from '../../functions/urls'; import { getDetailUrl } from '../../functions/urls';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
@ -278,12 +279,14 @@ export default function SupplierPartDetail() {
LinkBarcodeAction({ LinkBarcodeAction({
hidden: hidden:
supplierPart.barcode_hash || supplierPart.barcode_hash ||
!user.hasChangeRole(UserRoles.purchase_order) !user.hasChangeRole(UserRoles.purchase_order),
onClick: notYetImplemented
}), }),
UnlinkBarcodeAction({ UnlinkBarcodeAction({
hidden: hidden:
!supplierPart.barcode_hash || !supplierPart.barcode_hash ||
!user.hasChangeRole(UserRoles.purchase_order) !user.hasChangeRole(UserRoles.purchase_order),
onClick: notYetImplemented
}) })
]} ]}
/>, />,

View File

@ -74,6 +74,7 @@ import {
useTransferStockItem useTransferStockItem
} from '../../forms/StockForms'; } from '../../forms/StockForms';
import { InvenTreeIcon } from '../../functions/icons'; import { InvenTreeIcon } from '../../functions/icons';
import { notYetImplemented } from '../../functions/notifications';
import { getDetailUrl } from '../../functions/urls'; import { getDetailUrl } from '../../functions/urls';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
@ -978,10 +979,12 @@ export default function PartDetail() {
pk: part.pk pk: part.pk
}), }),
LinkBarcodeAction({ LinkBarcodeAction({
hidden: part?.barcode_hash || !user.hasChangeRole(UserRoles.part) hidden: part?.barcode_hash || !user.hasChangeRole(UserRoles.part),
onClick: notYetImplemented
}), }),
UnlinkBarcodeAction({ UnlinkBarcodeAction({
hidden: !part?.barcode_hash || !user.hasChangeRole(UserRoles.part) hidden: !part?.barcode_hash || !user.hasChangeRole(UserRoles.part),
onClick: notYetImplemented
}) })
]} ]}
key="action_dropdown" key="action_dropdown"

View File

@ -19,7 +19,11 @@ import { apiUrl } from '../../../states/ApiState';
import { useUserState } from '../../../states/UserState'; import { useUserState } from '../../../states/UserState';
import { TableColumn } from '../../../tables/Column'; import { TableColumn } from '../../../tables/Column';
import { InvenTreeTable } from '../../../tables/InvenTreeTable'; import { InvenTreeTable } from '../../../tables/InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../../../tables/RowActions'; import {
RowAction,
RowDeleteAction,
RowEditAction
} from '../../../tables/RowActions';
import { NoPricingData } from './PricingPanel'; import { NoPricingData } from './PricingPanel';
export default function PriceBreakPanel({ export default function PriceBreakPanel({
@ -113,7 +117,7 @@ export default function PriceBreakPanel({
}, [user]); }, [user]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.part), hidden: !user.hasChangeRole(UserRoles.part),

View File

@ -39,6 +39,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 { notYetImplemented } from '../../functions/notifications';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
useEditApiFormModal useEditApiFormModal
@ -408,10 +409,12 @@ export default function PurchaseOrderDetail() {
pk: order.pk pk: order.pk
}), }),
LinkBarcodeAction({ LinkBarcodeAction({
hidden: order?.barcode_hash hidden: order?.barcode_hash,
onClick: notYetImplemented
}), }),
UnlinkBarcodeAction({ UnlinkBarcodeAction({
hidden: !order?.barcode_hash hidden: !order?.barcode_hash,
onClick: notYetImplemented
}) })
]} ]}
/>, />,

View File

@ -38,6 +38,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 { notYetImplemented } from '../../functions/notifications';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
useEditApiFormModal useEditApiFormModal
@ -409,10 +410,12 @@ export default function ReturnOrderDetail() {
pk: order.pk pk: order.pk
}), }),
LinkBarcodeAction({ LinkBarcodeAction({
hidden: order?.barcode_hash hidden: order?.barcode_hash,
onClick: notYetImplemented
}), }),
UnlinkBarcodeAction({ UnlinkBarcodeAction({
hidden: !order?.barcode_hash hidden: !order?.barcode_hash,
onClick: notYetImplemented
}) })
]} ]}
/>, />,

View File

@ -41,6 +41,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 { notYetImplemented } from '../../functions/notifications';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
useEditApiFormModal useEditApiFormModal
@ -449,10 +450,12 @@ export default function SalesOrderDetail() {
pk: order.pk pk: order.pk
}), }),
LinkBarcodeAction({ LinkBarcodeAction({
hidden: order?.barcode_hash hidden: order?.barcode_hash,
onClick: notYetImplemented
}), }),
UnlinkBarcodeAction({ UnlinkBarcodeAction({
hidden: !order?.barcode_hash hidden: !order?.barcode_hash,
onClick: notYetImplemented
}) })
]} ]}
/>, />,
@ -467,23 +470,23 @@ export default function SalesOrderDetail() {
actions={[ actions={[
EditItemAction({ EditItemAction({
hidden: !canEdit, hidden: !canEdit,
onClick: () => editSalesOrder.open(), onClick: editSalesOrder.open,
tooltip: t`Edit order` tooltip: t`Edit order`
}), }),
DuplicateItemAction({ DuplicateItemAction({
hidden: !user.hasAddRole(UserRoles.sales_order), hidden: !user.hasAddRole(UserRoles.sales_order),
onClick: () => duplicateSalesOrder.open(), onClick: duplicateSalesOrder.open,
tooltip: t`Duplicate order` tooltip: t`Duplicate order`
}), }),
HoldItemAction({ HoldItemAction({
tooltip: t`Hold order`, tooltip: t`Hold order`,
hidden: !canHold, hidden: !canHold,
onClick: () => holdOrder.open() onClick: holdOrder.open
}), }),
CancelItemAction({ CancelItemAction({
tooltip: t`Cancel order`, tooltip: t`Cancel order`,
hidden: !canCancel, hidden: !canCancel,
onClick: () => cancelOrder.open() onClick: cancelOrder.open
}) })
]} ]}
/> />

View File

@ -38,6 +38,7 @@ import {
useTransferStockItem useTransferStockItem
} from '../../forms/StockForms'; } from '../../forms/StockForms';
import { InvenTreeIcon } from '../../functions/icons'; import { InvenTreeIcon } from '../../functions/icons';
import { notYetImplemented } from '../../functions/notifications';
import { getDetailUrl } from '../../functions/urls'; import { getDetailUrl } from '../../functions/urls';
import { import {
useDeleteApiFormModal, useDeleteApiFormModal,
@ -280,6 +281,7 @@ export default function Stock() {
<AdminButton model={ModelType.stocklocation} pk={location.pk} />, <AdminButton model={ModelType.stocklocation} pk={location.pk} />,
<ActionButton <ActionButton
icon={<InvenTreeIcon icon="stocktake" />} icon={<InvenTreeIcon icon="stocktake" />}
onClick={notYetImplemented}
variant="outline" variant="outline"
size="lg" size="lg"
/>, />,
@ -290,17 +292,23 @@ export default function Stock() {
model: ModelType.stocklocation, model: ModelType.stocklocation,
pk: location.pk pk: location.pk
}), }),
LinkBarcodeAction({}), LinkBarcodeAction({
UnlinkBarcodeAction({}), onClick: notYetImplemented
}),
UnlinkBarcodeAction({
onClick: notYetImplemented
}),
{ {
name: 'Scan in stock items', name: 'Scan in stock items',
icon: <InvenTreeIcon icon="stock" />, icon: <InvenTreeIcon icon="stock" />,
tooltip: 'Scan items' tooltip: 'Scan items',
onClick: notYetImplemented
}, },
{ {
name: 'Scan in container', name: 'Scan in container',
icon: <InvenTreeIcon icon="unallocated_stock" />, icon: <InvenTreeIcon icon="unallocated_stock" />,
tooltip: 'Scan container' tooltip: 'Scan container',
onClick: notYetImplemented
} }
]} ]}
/> />

View File

@ -50,6 +50,7 @@ import {
useTransferStockItem useTransferStockItem
} from '../../forms/StockForms'; } from '../../forms/StockForms';
import { InvenTreeIcon } from '../../functions/icons'; import { InvenTreeIcon } from '../../functions/icons';
import { notYetImplemented } from '../../functions/notifications';
import { getDetailUrl } from '../../functions/urls'; import { getDetailUrl } from '../../functions/urls';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
@ -483,11 +484,13 @@ export default function StockDetail() {
}), }),
LinkBarcodeAction({ LinkBarcodeAction({
hidden: hidden:
stockitem?.barcode_hash || !user.hasChangeRole(UserRoles.stock) stockitem?.barcode_hash || !user.hasChangeRole(UserRoles.stock),
onClick: notYetImplemented
}), }),
UnlinkBarcodeAction({ UnlinkBarcodeAction({
hidden: hidden:
!stockitem?.barcode_hash || !user.hasChangeRole(UserRoles.stock) !stockitem?.barcode_hash || !user.hasChangeRole(UserRoles.stock),
onClick: notYetImplemented
}) })
]} ]}
/>, />,

View File

@ -53,7 +53,6 @@ import { TableFilter } from './Filter';
import { FilterSelectDrawer } from './FilterSelectDrawer'; import { FilterSelectDrawer } from './FilterSelectDrawer';
import { RowAction, RowActions } from './RowActions'; import { RowAction, RowActions } from './RowActions';
import { TableSearchInput } from './Search'; import { TableSearchInput } from './Search';
import { UploadAction } from './UploadAction';
const defaultPageSize: number = 25; const defaultPageSize: number = 25;
@ -66,7 +65,6 @@ const defaultPageSize: number = 25;
* @param noRecordsText : string - Text to display when no records are found * @param noRecordsText : string - Text to display when no records are found
* @param enableBulkDelete : boolean - Enable bulk deletion of records * @param enableBulkDelete : boolean - Enable bulk deletion of records
* @param enableDownload : boolean - Enable download actions * @param enableDownload : boolean - Enable download actions
* @param enableUpload : boolean - Enable upload actions
* @param enableFilters : boolean - Enable filter actions * @param enableFilters : boolean - Enable filter actions
* @param enableSelection : boolean - Enable row selection * @param enableSelection : boolean - Enable row selection
* @param enableSearch : boolean - Enable search actions * @param enableSearch : boolean - Enable search actions
@ -92,7 +90,6 @@ export type InvenTreeTableProps<T = any> = {
noRecordsText?: string; noRecordsText?: string;
enableBulkDelete?: boolean; enableBulkDelete?: boolean;
enableDownload?: boolean; enableDownload?: boolean;
enableUpload?: boolean;
enableFilters?: boolean; enableFilters?: boolean;
enableSelection?: boolean; enableSelection?: boolean;
enableSearch?: boolean; enableSearch?: boolean;
@ -125,7 +122,6 @@ const defaultInvenTreeTableProps: InvenTreeTableProps = {
params: {}, params: {},
noRecordsText: t`No records found`, noRecordsText: t`No records found`,
enableDownload: false, enableDownload: false,
enableUpload: false,
enableLabels: false, enableLabels: false,
enableReports: false, enableReports: false,
enableFilters: true, enableFilters: true,
@ -607,7 +603,6 @@ export function InvenTreeTable<T = any>({
<Stack gap="sm"> <Stack gap="sm">
<Group justify="apart" grow wrap="nowrap"> <Group justify="apart" grow wrap="nowrap">
<Group justify="left" key="custom-actions" gap={5} wrap="nowrap"> <Group justify="left" key="custom-actions" gap={5} wrap="nowrap">
{tableProps.enableUpload && <UploadAction key="upload-action" />}
<PrintingActions <PrintingActions
items={tableState.selectedIds} items={tableState.selectedIds}
modelType={tableProps.modelType} modelType={tableProps.modelType}

View File

@ -4,76 +4,45 @@ import { IconCopy, IconDots, IconEdit, IconTrash } from '@tabler/icons-react';
import { ReactNode, useMemo, useState } from 'react'; import { ReactNode, useMemo, useState } from 'react';
import { cancelEvent } from '../functions/events'; import { cancelEvent } from '../functions/events';
import { notYetImplemented } from '../functions/notifications';
// Type definition for a table row action // Type definition for a table row action
export type RowAction = { export type RowAction = {
title: string; title?: string;
tooltip?: string; tooltip?: string;
color?: string; color?: string;
icon: ReactNode; icon?: ReactNode;
onClick?: () => void; onClick: () => void;
hidden?: boolean; hidden?: boolean;
disabled?: boolean; disabled?: boolean;
}; };
// Component for duplicating a row in a table // Component for duplicating a row in a table
export function RowDuplicateAction({ export function RowDuplicateAction(props: RowAction): RowAction {
onClick,
tooltip,
hidden
}: {
onClick?: () => void;
tooltip?: string;
hidden?: boolean;
}): RowAction {
return { return {
...props,
title: t`Duplicate`, title: t`Duplicate`,
color: 'green', color: 'green',
tooltip: tooltip, icon: <IconCopy />
onClick: onClick,
icon: <IconCopy />,
hidden: hidden
}; };
} }
// Component for editing a row in a table // Component for editing a row in a table
export function RowEditAction({ export function RowEditAction(props: RowAction): RowAction {
onClick,
tooltip,
hidden
}: {
onClick?: () => void;
tooltip?: string;
hidden?: boolean;
}): RowAction {
return { return {
...props,
title: t`Edit`, title: t`Edit`,
color: 'blue', color: 'blue',
tooltip: tooltip, icon: <IconEdit />
onClick: onClick,
icon: <IconEdit />,
hidden: hidden
}; };
} }
// Component for deleting a row in a table // Component for deleting a row in a table
export function RowDeleteAction({ export function RowDeleteAction(props: RowAction): RowAction {
onClick,
tooltip,
hidden
}: {
onClick?: () => void;
tooltip?: string;
hidden?: boolean;
}): RowAction {
return { return {
...props,
title: t`Delete`, title: t`Delete`,
color: 'red', color: 'red',
tooltip: tooltip, icon: <IconTrash />
onClick: onClick,
icon: <IconTrash />,
hidden: hidden
}; };
} }
@ -120,13 +89,7 @@ export function RowActions({
onClick={(event) => { onClick={(event) => {
// Prevent clicking on the action from selecting the row itself // Prevent clicking on the action from selecting the row itself
cancelEvent(event); cancelEvent(event);
action.onClick();
if (action.onClick) {
action.onClick();
} else {
notYetImplemented();
}
setOpened(false); setOpened(false);
}} }}
disabled={action.disabled || false} disabled={action.disabled || false}

View File

@ -1,8 +0,0 @@
import { t } from '@lingui/macro';
import { IconUpload } from '@tabler/icons-react';
import { ActionButton } from '../components/buttons/ActionButton';
export function UploadAction({}) {
return <ActionButton icon={<IconUpload />} tooltip={t`Upload Data`} />;
}

View File

@ -23,6 +23,7 @@ import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles'; import { UserRoles } from '../../enums/Roles';
import { bomItemFields } from '../../forms/BomForms'; import { bomItemFields } from '../../forms/BomForms';
import { dataImporterSessionFields } from '../../forms/ImporterForms'; import { dataImporterSessionFields } from '../../forms/ImporterForms';
import { notYetImplemented } from '../../functions/notifications';
import { import {
useApiFormModal, useApiFormModal,
useCreateApiFormModal, useCreateApiFormModal,
@ -41,7 +42,7 @@ import {
} from '../ColumnRenderers'; } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard'; import { TableHoverCard } from '../TableHoverCard';
// Calculate the total stock quantity available for a given BomItem // Calculate the total stock quantity available for a given BomItem
@ -454,7 +455,7 @@ export function BomTable({
}, []); }, []);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
// If this BOM item is defined for a *different* parent, then it cannot be edited // If this BOM item is defined for a *different* parent, then it cannot be edited
if (record.part && record.part != partId) { if (record.part && record.part != partId) {
return [ return [
@ -488,7 +489,8 @@ export function BomTable({
title: t`Edit Substitutes`, title: t`Edit Substitutes`,
color: 'blue', color: 'blue',
hidden: partLocked || !user.hasChangeRole(UserRoles.part), hidden: partLocked || !user.hasChangeRole(UserRoles.part),
icon: <IconSwitch3 /> icon: <IconSwitch3 />,
onClick: notYetImplemented
}, },
RowDeleteAction({ RowDeleteAction({
hidden: partLocked || !user.hasDeleteRole(UserRoles.part), hidden: partLocked || !user.hasDeleteRole(UserRoles.part),

View File

@ -20,7 +20,7 @@ import {
} from '../ColumnRenderers'; } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
/** /**
* Render a table of allocated stock for a build. * Render a table of allocated stock for a build.
@ -155,7 +155,7 @@ export default function BuildAllocatedStockTable({
}); });
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.build), hidden: !user.hasChangeRole(UserRoles.build),

View File

@ -12,6 +12,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 { useBuildOrderFields } from '../../forms/BuildForms'; import { useBuildOrderFields } from '../../forms/BuildForms';
import { notYetImplemented } from '../../functions/notifications';
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';
@ -20,6 +21,7 @@ import { TableColumn } from '../Column';
import { BooleanColumn, PartColumn } from '../ColumnRenderers'; import { BooleanColumn, PartColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard'; import { TableHoverCard } from '../TableHoverCard';
export default function BuildLineTable({ export default function BuildLineTable({
@ -270,7 +272,7 @@ export default function BuildLineTable({
}); });
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
let part = record.part_detail ?? {}; let part = record.part_detail ?? {};
// Consumable items have no appropriate actions // Consumable items have no appropriate actions
@ -295,13 +297,15 @@ export default function BuildLineTable({
icon: <IconArrowRight />, icon: <IconArrowRight />,
title: t`Allocate Stock`, title: t`Allocate Stock`,
hidden: !canAllocate, hidden: !canAllocate,
color: 'green' color: 'green',
onClick: notYetImplemented
}, },
{ {
icon: <IconShoppingCart />, icon: <IconShoppingCart />,
title: t`Order Stock`, title: t`Order Stock`,
hidden: !canOrder, hidden: !canOrder,
color: 'blue' color: 'blue',
onClick: notYetImplemented
}, },
{ {
icon: <IconTool />, icon: <IconTool />,

View File

@ -19,6 +19,7 @@ import { TableColumn } from '../Column';
import { LocationColumn } from '../ColumnRenderers'; import { LocationColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard'; import { TableHoverCard } from '../TableHoverCard';
/** /**
@ -226,7 +227,7 @@ export default function BuildOrderTestTable({
}, []); }, []);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return []; return [];
}, },
[user] [user]

View File

@ -18,6 +18,7 @@ import {
useScrapBuildOutputsForm useScrapBuildOutputsForm
} from '../../forms/BuildForms'; } from '../../forms/BuildForms';
import { InvenTreeIcon } from '../../functions/icons'; import { InvenTreeIcon } from '../../functions/icons';
import { notYetImplemented } from '../../functions/notifications';
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';
@ -245,19 +246,21 @@ export default function BuildOutputTable({ build }: { build: any }) {
}, [user, table.selectedRecords, table.hasSelectedRecords]); }, [user, table.selectedRecords, table.hasSelectedRecords]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
let actions: RowAction[] = [ return [
{ {
title: t`Allocate`, title: t`Allocate`,
tooltip: t`Allocate stock to build output`, tooltip: t`Allocate stock to build output`,
color: 'blue', color: 'blue',
icon: <InvenTreeIcon icon="plus" /> icon: <InvenTreeIcon icon="plus" />,
onClick: notYetImplemented
}, },
{ {
title: t`Deallocate`, title: t`Deallocate`,
tooltip: t`Deallocate stock from build output`, tooltip: t`Deallocate stock from build output`,
color: 'red', color: 'red',
icon: <InvenTreeIcon icon="minus" /> icon: <InvenTreeIcon icon="minus" />,
onClick: notYetImplemented
}, },
{ {
title: t`Complete`, title: t`Complete`,
@ -290,8 +293,6 @@ export default function BuildOutputTable({ build }: { build: any }) {
} }
} }
]; ];
return actions;
}, },
[user, partId] [user, partId]
); );

View File

@ -16,7 +16,7 @@ import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
export function AddressTable({ export function AddressTable({
companyId, companyId,
@ -146,7 +146,7 @@ export function AddressTable({
}); });
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
let can_edit = let can_edit =
user.hasChangeRole(UserRoles.purchase_order) || user.hasChangeRole(UserRoles.purchase_order) ||
user.hasChangeRole(UserRoles.sales_order); user.hasChangeRole(UserRoles.sales_order);

View File

@ -19,7 +19,7 @@ import { useUserState } from '../../states/UserState';
import { BooleanColumn, DescriptionColumn } from '../ColumnRenderers'; import { BooleanColumn, DescriptionColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowEditAction } from '../RowActions'; import { RowAction, RowEditAction } from '../RowActions';
/** /**
* A table which displays a list of company records, * A table which displays a list of company records,
@ -128,7 +128,7 @@ export function CompanyTable({
}, [user]); }, [user]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: hidden:

View File

@ -15,7 +15,7 @@ import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
export function ContactTable({ export function ContactTable({
companyId, companyId,
@ -91,7 +91,7 @@ export function ContactTable({
}); });
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
let can_edit = let can_edit =
user.hasChangeRole(UserRoles.purchase_order) || user.hasChangeRole(UserRoles.purchase_order) ||
user.hasChangeRole(UserRoles.sales_order); user.hasChangeRole(UserRoles.sales_order);

View File

@ -28,7 +28,7 @@ import { useUserState } from '../../states/UserState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
/** /**
* Define set of columns to display for the attachment table * Define set of columns to display for the attachment table
@ -262,7 +262,7 @@ export function AttachmentTable({
// Construct row actions for the attachment table // Construct row actions for the attachment table
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangePermission(model_type), hidden: !user.hasChangePermission(model_type),

View File

@ -18,6 +18,7 @@ import { TableColumn } from '../Column';
import { LinkColumn, NoteColumn } from '../ColumnRenderers'; import { LinkColumn, NoteColumn } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { import {
RowAction,
RowDeleteAction, RowDeleteAction,
RowDuplicateAction, RowDuplicateAction,
RowEditAction RowEditAction
@ -107,7 +108,7 @@ export default function ExtraLineItemTable({
}); });
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(role), hidden: !user.hasChangeRole(role),

View File

@ -20,7 +20,7 @@ import { TableColumn } from '../Column';
import { DescriptionColumn } from '../ColumnRenderers'; import { DescriptionColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowEditAction } from '../RowActions'; import { RowAction, RowEditAction } from '../RowActions';
/** /**
* PartCategoryTable - Displays a table of part categories * PartCategoryTable - Displays a table of part categories
@ -117,7 +117,7 @@ export function PartCategoryTable({ parentId }: { parentId?: any }) {
}, [user]); }, [user]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
let can_edit = user.hasChangeRole(UserRoles.part_category); let can_edit = user.hasChangeRole(UserRoles.part_category);
return [ return [

View File

@ -17,7 +17,7 @@ import { useUserState } from '../../states/UserState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
export default function PartCategoryTemplateTable() { export default function PartCategoryTemplateTable() {
const table = useTable('part-category-parameter-templates'); const table = useTable('part-category-parameter-templates');
@ -104,7 +104,7 @@ export default function PartCategoryTemplateTable() {
}, []); }, []);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.part), hidden: !user.hasChangeRole(UserRoles.part),

View File

@ -20,7 +20,7 @@ import { useUserState } from '../../states/UserState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { DescriptionColumn, PartColumn } from '../ColumnRenderers'; import { DescriptionColumn, PartColumn } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard'; import { TableHoverCard } from '../TableHoverCard';
/** /**
@ -140,7 +140,7 @@ export function PartParameterTable({
// Callback for row actions // Callback for row actions
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
// Actions not allowed for "variant" rows // Actions not allowed for "variant" rows
if (String(partId) != String(record.part)) { if (String(partId) != String(record.part)) {
return []; return [];

View File

@ -17,7 +17,7 @@ import { TableColumn } from '../Column';
import { BooleanColumn, DescriptionColumn } from '../ColumnRenderers'; import { BooleanColumn, DescriptionColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
export default function PartParameterTemplateTable() { export default function PartParameterTemplateTable() {
const table = useTable('part-parameter-templates'); const table = useTable('part-parameter-templates');
@ -114,7 +114,7 @@ export default function PartParameterTemplateTable() {
// Callback for row actions // Callback for row actions
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.part), hidden: !user.hasChangeRole(UserRoles.part),

View File

@ -22,7 +22,7 @@ import { TableColumn } from '../Column';
import { BooleanColumn, DescriptionColumn } from '../ColumnRenderers'; import { BooleanColumn, DescriptionColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard'; import { TableHoverCard } from '../TableHoverCard';
export default function PartTestTemplateTable({ export default function PartTestTemplateTable({
@ -192,7 +192,7 @@ export default function PartTestTemplateTable({
}); });
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
const can_edit = user.hasChangeRole(UserRoles.part); const can_edit = user.hasChangeRole(UserRoles.part);
const can_delete = user.hasDeleteRole(UserRoles.part); const can_delete = user.hasDeleteRole(UserRoles.part);

View File

@ -17,7 +17,7 @@ import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction } from '../RowActions'; import { RowAction, RowDeleteAction } from '../RowActions';
/** /**
* Construct a table listing related parts for a given part * Construct a table listing related parts for a given part
@ -111,7 +111,7 @@ export function RelatedPartTable({ partId }: { partId: number }): ReactNode {
}, [user]); }, [user]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowDeleteAction({ RowDeleteAction({
hidden: !user.hasDeleteRole(UserRoles.part), hidden: !user.hasDeleteRole(UserRoles.part),

View File

@ -351,7 +351,7 @@ export default function PluginListTable() {
// Determine available actions for a given plugin // Determine available actions for a given plugin
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
// TODO: Plugin actions should be updated based on on the users's permissions // TODO: Plugin actions should be updated based on on the users's permissions
let actions: RowAction[] = []; let actions: RowAction[] = [];

View File

@ -15,7 +15,7 @@ import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
export default function ManufacturerPartParameterTable({ export default function ManufacturerPartParameterTable({
params params
@ -80,7 +80,7 @@ export default function ManufacturerPartParameterTable({
}); });
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.purchase_order), hidden: !user.hasChangeRole(UserRoles.purchase_order),

View File

@ -18,7 +18,7 @@ import { useUserState } from '../../states/UserState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { DescriptionColumn, LinkColumn, PartColumn } from '../ColumnRenderers'; import { DescriptionColumn, LinkColumn, PartColumn } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
/* /*
* Construct a table listing manufacturer parts * Construct a table listing manufacturer parts
@ -108,7 +108,7 @@ export function ManufacturerPartTable({ params }: { params: any }): ReactNode {
}, [user]); }, [user]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.purchase_order), hidden: !user.hasChangeRole(UserRoles.purchase_order),

View File

@ -37,6 +37,7 @@ import {
} from '../ColumnRenderers'; } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { import {
RowAction,
RowDeleteAction, RowDeleteAction,
RowDuplicateAction, RowDuplicateAction,
RowEditAction RowEditAction
@ -290,7 +291,7 @@ export function PurchaseOrderLineItemTable({
}, [order, poStatus]); }, [order, poStatus]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
let received = (record?.received ?? 0) >= (record?.quantity ?? 0); let received = (record?.received ?? 0) >= (record?.quantity ?? 0);
return [ return [

View File

@ -26,7 +26,7 @@ import {
} from '../ColumnRenderers'; } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard'; import { TableHoverCard } from '../TableHoverCard';
/* /*
@ -221,7 +221,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
// Row action callback // Row action callback
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.purchase_order), hidden: !user.hasChangeRole(UserRoles.purchase_order),

View File

@ -20,7 +20,7 @@ import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
export function calculateSupplierPartUnitPrice(record: any) { export function calculateSupplierPartUnitPrice(record: any) {
let pack_quantity = record?.part_detail?.pack_quantity_native ?? 1; let pack_quantity = record?.part_detail?.pack_quantity_native ?? 1;
@ -175,7 +175,7 @@ export default function SupplierPriceBreakTable({
}, [user]); }, [user]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.purchase_order), hidden: !user.hasChangeRole(UserRoles.purchase_order),

View File

@ -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 { useReturnOrderLineItemFields } from '../../forms/ReturnOrderForms'; import { useReturnOrderLineItemFields } from '../../forms/ReturnOrderForms';
import { notYetImplemented } from '../../functions/notifications';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
useDeleteApiFormModal, useDeleteApiFormModal,
@ -27,7 +28,7 @@ import {
} from '../ColumnRenderers'; } from '../ColumnRenderers';
import { StatusFilterOptions, TableFilter } from '../Filter'; import { StatusFilterOptions, TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
export default function ReturnOrderLineItemTable({ export default function ReturnOrderLineItemTable({
orderId, orderId,
@ -148,14 +149,15 @@ export default function ReturnOrderLineItemTable({
}, [user, orderId]); }, [user, orderId]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
const received: boolean = !!record?.received_date; const received: boolean = !!record?.received_date;
return [ return [
{ {
hidden: received || !user.hasChangeRole(UserRoles.return_order), hidden: received || !user.hasChangeRole(UserRoles.return_order),
title: t`Receive Item`, title: t`Receive Item`,
icon: <IconSquareArrowRight /> icon: <IconSquareArrowRight />,
onClick: notYetImplemented
}, },
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.return_order), hidden: !user.hasChangeRole(UserRoles.return_order),

View File

@ -15,6 +15,7 @@ import {
} from '../ColumnRenderers'; } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowAction } from '../RowActions';
export default function SalesOrderAllocationTable({ export default function SalesOrderAllocationTable({
partId, partId,
@ -102,7 +103,7 @@ export default function SalesOrderAllocationTable({
}, []); }, []);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return []; return [];
}, },
[user] [user]

View File

@ -15,6 +15,7 @@ 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 { useSalesOrderLineItemFields } from '../../forms/SalesOrderForms'; import { useSalesOrderLineItemFields } from '../../forms/SalesOrderForms';
import { notYetImplemented } from '../../functions/notifications';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
useDeleteApiFormModal, useDeleteApiFormModal,
@ -27,6 +28,7 @@ import { TableColumn } from '../Column';
import { DateColumn, LinkColumn, PartColumn } from '../ColumnRenderers'; import { DateColumn, LinkColumn, PartColumn } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { import {
RowAction,
RowDeleteAction, RowDeleteAction,
RowDuplicateAction, RowDuplicateAction,
RowEditAction RowEditAction
@ -248,7 +250,7 @@ export default function SalesOrderLineItemTable({
}, [user, orderId]); }, [user, orderId]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
const allocated = (record?.allocated ?? 0) > (record?.quantity ?? 0); const allocated = (record?.allocated ?? 0) > (record?.quantity ?? 0);
return [ return [
@ -259,7 +261,8 @@ export default function SalesOrderLineItemTable({
!user.hasChangeRole(UserRoles.sales_order), !user.hasChangeRole(UserRoles.sales_order),
title: t`Allocate stock`, title: t`Allocate stock`,
icon: <IconSquareArrowRight />, icon: <IconSquareArrowRight />,
color: 'green' color: 'green',
onClick: notYetImplemented
}, },
{ {
hidden: hidden:
@ -285,7 +288,8 @@ export default function SalesOrderLineItemTable({
!record?.part_detail?.purchaseable, !record?.part_detail?.purchaseable,
title: t`Order stock`, title: t`Order stock`,
icon: <IconShoppingCart />, icon: <IconShoppingCart />,
color: 'blue' color: 'blue',
onClick: notYetImplemented
}, },
RowEditAction({ RowEditAction({
hidden: !editable || !user.hasChangeRole(UserRoles.sales_order), hidden: !editable || !user.hasChangeRole(UserRoles.sales_order),

View File

@ -6,6 +6,7 @@ import { AddItemButton } from '../../components/buttons/AddItemButton';
import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { UserRoles } from '../../enums/Roles'; import { UserRoles } from '../../enums/Roles';
import { useSalesOrderShipmentFields } from '../../forms/SalesOrderForms'; import { useSalesOrderShipmentFields } from '../../forms/SalesOrderForms';
import { notYetImplemented } from '../../functions/notifications';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
useDeleteApiFormModal, useDeleteApiFormModal,
@ -18,7 +19,7 @@ import { TableColumn } from '../Column';
import { DateColumn, LinkColumn, NoteColumn } from '../ColumnRenderers'; import { DateColumn, LinkColumn, NoteColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
export default function SalesOrderShipmentTable({ export default function SalesOrderShipmentTable({
orderId orderId
@ -97,14 +98,15 @@ export default function SalesOrderShipmentTable({
}, []); }, []);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
const shipped: boolean = !!record.shipment_date; const shipped: boolean = !!record.shipment_date;
return [ return [
{ {
hidden: shipped || !user.hasChangeRole(UserRoles.sales_order), hidden: shipped || !user.hasChangeRole(UserRoles.sales_order),
title: t`Complete Shipment`, title: t`Complete Shipment`,
icon: <IconTruckDelivery /> icon: <IconTruckDelivery />,
onClick: notYetImplemented
}, },
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.sales_order), hidden: !user.hasChangeRole(UserRoles.sales_order),

View File

@ -15,6 +15,7 @@ import { AttachmentLink } from '../../components/items/AttachmentLink';
import { DetailDrawer } from '../../components/nav/DetailDrawer'; import { DetailDrawer } from '../../components/nav/DetailDrawer';
import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType'; import { ModelType } from '../../enums/ModelType';
import { notYetImplemented } from '../../functions/notifications';
import { useFilters } from '../../hooks/UseFilter'; import { useFilters } from '../../hooks/UseFilter';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
@ -187,8 +188,9 @@ export function TemplateTable({
} }
}), }),
RowDuplicateAction({ RowDuplicateAction({
hidden: true hidden: true,
// TODO: Duplicate selected template // TODO: Duplicate selected template
onClick: notYetImplemented
}), }),
RowDeleteAction({ RowDeleteAction({
hidden: !user.hasDeletePermission(templateProps.modelType), hidden: !user.hasDeletePermission(templateProps.modelType),

View File

@ -16,7 +16,7 @@ import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
export default function LocationTypesTable() { export default function LocationTypesTable() {
const table = useTable('location-types'); const table = useTable('location-types');
@ -81,7 +81,7 @@ export default function LocationTypesTable() {
}, []); }, []);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
return [ return [
RowEditAction({ RowEditAction({
hidden: !user.hasChangeRole(UserRoles.stock_location), hidden: !user.hasChangeRole(UserRoles.stock_location),

View File

@ -21,6 +21,7 @@ import {
useTransferStockItem useTransferStockItem
} from '../../forms/StockForms'; } from '../../forms/StockForms';
import { InvenTreeIcon } from '../../functions/icons'; import { InvenTreeIcon } from '../../functions/icons';
import { notYetImplemented } from '../../functions/notifications';
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';
@ -506,7 +507,8 @@ export function StockItemTable({
name: t`Order stock`, name: t`Order stock`,
icon: <InvenTreeIcon icon="buy" />, icon: <InvenTreeIcon icon="buy" />,
tooltip: t`Order new stock`, tooltip: t`Order new stock`,
disabled: !can_add_order || !can_change_order disabled: !can_add_order || !can_change_order,
onClick: notYetImplemented
}, },
{ {
name: t`Assign to customer`, name: t`Assign to customer`,

View File

@ -32,7 +32,12 @@ import { TableColumn } from '../Column';
import { DateColumn, DescriptionColumn, NoteColumn } from '../ColumnRenderers'; import { DateColumn, DescriptionColumn, NoteColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowActions, RowDeleteAction, RowEditAction } from '../RowActions'; import {
RowAction,
RowActions,
RowDeleteAction,
RowEditAction
} from '../RowActions';
export default function StockItemTestResultTable({ export default function StockItemTestResultTable({
partId, partId,
@ -301,7 +306,7 @@ export default function StockItemTestResultTable({
); );
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
if (record.stock_item != undefined && record.stock_item != itemId) { if (record.stock_item != undefined && record.stock_item != itemId) {
// Test results for other stock items cannot be edited // Test results for other stock items cannot be edited
return []; return [];

View File

@ -20,7 +20,7 @@ import { TableColumn } from '../Column';
import { BooleanColumn, DescriptionColumn } from '../ColumnRenderers'; import { BooleanColumn, DescriptionColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { RowEditAction } from '../RowActions'; import { RowAction, RowEditAction } from '../RowActions';
/** /**
* Stock location table * Stock location table
@ -138,7 +138,7 @@ export function StockLocationTable({ parentId }: { parentId?: any }) {
}, [user]); }, [user]);
const rowActions = useCallback( const rowActions = useCallback(
(record: any) => { (record: any): RowAction[] => {
let can_edit = user.hasChangeRole(UserRoles.stock_location); let can_edit = user.hasChangeRole(UserRoles.stock_location);
return [ return [