From 68c3a41f84ed5ad9f9d76f00195c05dc1decb6a4 Mon Sep 17 00:00:00 2001
From: gitbock <gitbock@bock-systems.de>
Date: Sat, 14 Jun 2025 01:04:09 +0200
Subject: [PATCH] feat(frontend): add edit-part function in part table (#9775)

* add edit-part function in part table

* fix code style
using `pre-commit run -a`

---------

Co-authored-by: Matthias Mair <code@mjmair.com>
---
 src/frontend/src/tables/part/PartTable.tsx | 37 ++++++++++++++++++++--
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/src/frontend/src/tables/part/PartTable.tsx b/src/frontend/src/tables/part/PartTable.tsx
index 8349a4849c..7d933770d2 100644
--- a/src/frontend/src/tables/part/PartTable.tsx
+++ b/src/frontend/src/tables/part/PartTable.tsx
@@ -1,13 +1,13 @@
 import { t } from '@lingui/core/macro';
 import { Group, Text } from '@mantine/core';
-import { type ReactNode, useMemo } from 'react';
+import { IconShoppingCart } from '@tabler/icons-react';
+import { type ReactNode, useCallback, useMemo, useState } from 'react';
 
 import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
 import { ModelType } from '@lib/enums/ModelType';
 import { UserRoles } from '@lib/enums/Roles';
 import { apiUrl } from '@lib/functions/Api';
 import type { TableFilter } from '@lib/types/Filters';
-import { IconShoppingCart } from '@tabler/icons-react';
 import { AddItemButton } from '../../components/buttons/AddItemButton';
 import { ActionDropdown } from '../../components/items/ActionDropdown';
 import OrderPartsWizard from '../../components/wizards/OrderPartsWizard';
@@ -16,13 +16,15 @@ import { usePartFields } from '../../forms/PartForms';
 import { InvenTreeIcon } from '../../functions/icons';
 import {
   useBulkEditApiFormModal,
-  useCreateApiFormModal
+  useCreateApiFormModal,
+  useEditApiFormModal
 } from '../../hooks/UseForm';
 import { useTable } from '../../hooks/UseTable';
 import { useUserState } from '../../states/UserState';
 import type { TableColumn } from '../Column';
 import { DescriptionColumn, LinkColumn, PartColumn } from '../ColumnRenderers';
 import { InvenTreeTable, type InvenTreeTableProps } from '../InvenTreeTable';
+import { type RowAction, RowEditAction } from '../RowActions';
 import { TableHoverCard } from '../TableHoverCard';
 
 /**
@@ -345,6 +347,16 @@ export function PartListTable({
     modelType: ModelType.part
   });
 
+  const [selectedPart, setSelectedPart] = useState<number>(-1);
+
+  const editPart = useEditApiFormModal({
+    url: ApiEndpoints.part_list,
+    pk: selectedPart,
+    title: t`Edit Part`,
+    fields: usePartFields({ create: false }),
+    onFormSuccess: table.refreshTable
+  });
+
   const setCategory = useBulkEditApiFormModal({
     url: ApiEndpoints.part_list,
     items: table.selectedIds,
@@ -357,6 +369,23 @@ export function PartListTable({
 
   const orderPartsWizard = OrderPartsWizard({ parts: table.selectedRecords });
 
+  const rowActions = useCallback(
+    (record: any): RowAction[] => {
+      const can_edit = user.hasChangePermission(ModelType.part);
+
+      return [
+        RowEditAction({
+          hidden: !can_edit,
+          onClick: () => {
+            setSelectedPart(record.pk);
+            editPart.open();
+          }
+        })
+      ];
+    },
+    [user, editPart]
+  );
+
   const tableActions = useMemo(() => {
     return [
       <ActionDropdown
@@ -397,6 +426,7 @@ export function PartListTable({
   return (
     <>
       {newPart.modal}
+      {editPart.modal}
       {setCategory.modal}
       {orderPartsWizard.wizard}
       <InvenTreeTable
@@ -409,6 +439,7 @@ export function PartListTable({
           modelType: ModelType.part,
           tableFilters: tableFilters,
           tableActions: tableActions,
+          rowActions: rowActions,
           enableSelection: true,
           enableReports: true,
           enableLabels: true,