diff --git a/src/frontend/src/pages/part/CategoryDetail.tsx b/src/frontend/src/pages/part/CategoryDetail.tsx
index a7921e1011..734401cd76 100644
--- a/src/frontend/src/pages/part/CategoryDetail.tsx
+++ b/src/frontend/src/pages/part/CategoryDetail.tsx
@@ -2,6 +2,7 @@ import { t } from '@lingui/macro';
import { LoadingOverlay, Skeleton, Stack, Text } from '@mantine/core';
import {
IconCategory,
+ IconDots,
IconInfoCircle,
IconListDetails,
IconSitemap
@@ -11,12 +12,20 @@ import { useParams } from 'react-router-dom';
import { DetailsField, DetailsTable } from '../../components/details/Details';
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
+import {
+ ActionDropdown,
+ EditItemAction
+} from '../../components/items/ActionDropdown';
import { PageDetail } from '../../components/nav/PageDetail';
import { PanelGroup, PanelType } from '../../components/nav/PanelGroup';
import { PartCategoryTree } from '../../components/nav/PartCategoryTree';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
+import { UserRoles } from '../../enums/Roles';
+import { partCategoryFields } from '../../forms/PartForms';
+import { useEditApiFormModal } from '../../hooks/UseForm';
import { useInstance } from '../../hooks/UseInstance';
+import { useUserState } from '../../states/UserState';
import ParametricPartTable from '../../tables/part/ParametricPartTable';
import { PartCategoryTable } from '../../tables/part/PartCategoryTable';
import { PartListTable } from '../../tables/part/PartTable';
@@ -33,6 +42,8 @@ export default function CategoryDetail({}: {}) {
[_id]
);
+ const user = useUserState();
+
const [treeOpen, setTreeOpen] = useState(false);
const {
@@ -119,6 +130,31 @@ export default function CategoryDetail({}: {}) {
);
}, [category, instanceQuery]);
+ const editCategory = useEditApiFormModal({
+ url: ApiEndpoints.category_list,
+ pk: id,
+ title: t`Edit Part Category`,
+ fields: partCategoryFields({}),
+ onFormSuccess: refreshInstance
+ });
+
+ const categoryActions = useMemo(() => {
+ return [
+ }
+ actions={[
+ EditItemAction({
+ hidden: !id || !user.hasChangeRole(UserRoles.part_category),
+ tooltip: t`Edit Part Category`,
+ onClick: () => editCategory.open()
+ })
+ ]}
+ />
+ ];
+ }, [id, user]);
+
const categoryPanels: PanelType[] = useMemo(
() => [
{
@@ -170,24 +206,28 @@ export default function CategoryDetail({}: {}) {
);
return (
-
-
- {
- setTreeOpen(false);
- }}
- selectedCategory={category?.pk}
- />
- {category.name ?? 'Top level'}}
- breadcrumbs={breadcrumbs}
- breadcrumbAction={() => {
- setTreeOpen(true);
- }}
- />
-
-
+ <>
+ {editCategory.modal}
+
+
+ {
+ setTreeOpen(false);
+ }}
+ selectedCategory={category?.pk}
+ />
+ {category.name ?? 'Top level'}}
+ breadcrumbs={breadcrumbs}
+ breadcrumbAction={() => {
+ setTreeOpen(true);
+ }}
+ actions={categoryActions}
+ />
+
+
+ >
);
}
diff --git a/src/frontend/src/pages/stock/LocationDetail.tsx b/src/frontend/src/pages/stock/LocationDetail.tsx
index 3214ed8183..e9b6d99a2a 100644
--- a/src/frontend/src/pages/stock/LocationDetail.tsx
+++ b/src/frontend/src/pages/stock/LocationDetail.tsx
@@ -1,17 +1,30 @@
import { t } from '@lingui/macro';
import { LoadingOverlay, Skeleton, Stack, Text } from '@mantine/core';
-import { IconInfoCircle, IconPackages, IconSitemap } from '@tabler/icons-react';
+import {
+ IconDots,
+ IconInfoCircle,
+ IconPackages,
+ IconSitemap
+} from '@tabler/icons-react';
import { useMemo, useState } from 'react';
import { useParams } from 'react-router-dom';
import { DetailsField, DetailsTable } from '../../components/details/Details';
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
+import {
+ ActionDropdown,
+ EditItemAction
+} from '../../components/items/ActionDropdown';
import { PageDetail } from '../../components/nav/PageDetail';
import { PanelGroup, PanelType } from '../../components/nav/PanelGroup';
import { StockLocationTree } from '../../components/nav/StockLocationTree';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
+import { UserRoles } from '../../enums/Roles';
+import { stockLocationFields } from '../../forms/StockForms';
+import { useEditApiFormModal } from '../../hooks/UseForm';
import { useInstance } from '../../hooks/UseInstance';
+import { useUserState } from '../../states/UserState';
import { StockItemTable } from '../../tables/stock/StockItemTable';
import { StockLocationTable } from '../../tables/stock/StockLocationTable';
@@ -23,6 +36,8 @@ export default function Stock() {
[_id]
);
+ const user = useUserState();
+
const [treeOpen, setTreeOpen] = useState(false);
const {
@@ -143,6 +158,31 @@ export default function Stock() {
];
}, [location, id]);
+ const editLocation = useEditApiFormModal({
+ url: ApiEndpoints.stock_location_list,
+ pk: id,
+ title: t`Edit Stock Location`,
+ fields: stockLocationFields({}),
+ onFormSuccess: refreshInstance
+ });
+
+ const locationActions = useMemo(() => {
+ return [
+ }
+ actions={[
+ EditItemAction({
+ hidden: !id || !user.hasChangeRole(UserRoles.stock_location),
+ tooltip: t`Edit Stock Location`,
+ onClick: () => editLocation.open()
+ })
+ ]}
+ />
+ ];
+ }, [id, user]);
+
const breadcrumbs = useMemo(
() => [
{ name: t`Stock`, url: '/stock' },
@@ -156,6 +196,7 @@ export default function Stock() {
return (
<>
+ {editLocation.modal}
{location.name ?? 'Top level'}}
+ actions={locationActions}
breadcrumbs={breadcrumbs}
breadcrumbAction={() => {
setTreeOpen(true);