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);