feat: implement finance parameter management module with CRUD, import/export, and UI components#12
Conversation
…/export, and UI components
There was a problem hiding this comment.
Pull request overview
Implements an end-to-end Finance “Parameter” master-data module, adding gRPC-backed REST endpoints and a full dashboard UI for managing parameters (CRUD + import/export + filtering/pagination).
Changes:
- Added proto-generated Parameter types plus a UI-friendly re-export layer with labels/options.
- Added finance parameter gRPC client wiring and Next.js API routes for CRUD + export/import/template.
- Added dashboard page and reusable UI components (table, filters, pagination, dialogs) plus React Query hooks.
Reviewed changes
Copilot reviewed 19 out of 20 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/types/generated/finance/v1/parameter.ts | Adds generated proto TypeScript definitions for finance parameters and service definition. |
| src/types/finance/parameter.ts | Re-exports generated types and adds UI helpers (labels/options, form defaults, filter param types). |
| src/lib/grpc/index.ts | Exposes the new getParameterClient from the gRPC client registry. |
| src/lib/grpc/clients.ts | Registers a singleton gRPC client for ParameterService. |
| src/hooks/finance/use-parameter.ts | Adds CRUD hooks via createCrudHooks plus export/import/template download mutations. |
| src/components/finance/parameter/parameter-table.tsx | Parameter list DataTable with row actions and enum label mapping. |
| src/components/finance/parameter/parameter-pagination.tsx | Pagination wrapper around shared DataTablePagination. |
| src/components/finance/parameter/parameter-import-dialog.tsx | Import dialog UX (template download, file selection, duplicate handling, result display). |
| src/components/finance/parameter/parameter-form-dialog.tsx | Create/edit dialog with zod validation + mutations. |
| src/components/finance/parameter/parameter-filters.tsx | Search + filter + sort controls wired to URL state. |
| src/components/finance/parameter/parameter-delete-dialog.tsx | Confirmation dialog for deleting a parameter. |
| src/components/finance/parameter/index.ts | Barrel export for parameter feature components. |
| src/app/api/v1/finance/parameters/template/route.ts | API route to download import template via gRPC (base64 JSON payload). |
| src/app/api/v1/finance/parameters/route.ts | API routes for list + create (gRPC-backed). |
| src/app/api/v1/finance/parameters/import/route.ts | API route to import parameters (JSON byte-array → Uint8Array for gRPC). |
| src/app/api/v1/finance/parameters/export/route.ts | API route to export parameters (gRPC bytes → base64 JSON). |
| src/app/api/v1/finance/parameters/[paramId]/route.ts | API routes for get/update/delete by ID (gRPC-backed). |
| src/app/(dashboard)/finance/master/parameter/parameter-page-client.tsx | Client page implementing the management UI wired to hooks + dialogs. |
| src/app/(dashboard)/finance/master/parameter/page.tsx | Registers the new dashboard route and page metadata. |
| src/app/(dashboard)/finance/master/parameter/loading.tsx | Adds a loading skeleton for the new page segment. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| uomId: values.uomId || undefined, | ||
| defaultValue: values.defaultValue || undefined, | ||
| minValue: values.minValue || undefined, | ||
| maxValue: values.maxValue || undefined, | ||
| isActive: values.isActive, |
There was a problem hiding this comment.
In update mode, converting empty strings to undefined (e.g., uomId: values.uomId || undefined) prevents users from clearing previously-set values. The proto comment indicates empty string should clear the UOM, so the UI should send an empty string when the field is cleared (and only use undefined when you truly want to omit the field / leave it unchanged).
| dataType: z.nativeEnum(DataType).refine( | ||
| (val) => val !== DataType.DATA_TYPE_UNSPECIFIED, | ||
| "Data type is required" |
There was a problem hiding this comment.
z.nativeEnum(DataType) will accept DataType.UNRECOGNIZED (-1). With the current refine only excluding DATA_TYPE_UNSPECIFIED, an unknown enum value coming from the backend could be submitted back to the API. Consider refining to only allow the known selectable values (e.g., NUMBER/TEXT/BOOLEAN) and explicitly exclude UNRECOGNIZED.
| dataType: z.nativeEnum(DataType).refine( | |
| (val) => val !== DataType.DATA_TYPE_UNSPECIFIED, | |
| "Data type is required" | |
| dataType: z.union( | |
| [ | |
| z.literal(DataType.NUMBER), | |
| z.literal(DataType.TEXT), | |
| z.literal(DataType.BOOLEAN), | |
| ], | |
| { | |
| errorMap: () => ({ message: "Data type is required" }), | |
| } |
| "Data type is required" | ||
| ), | ||
| paramCategory: z.nativeEnum(ParamCategory).refine( | ||
| (val) => val !== ParamCategory.PARAM_CATEGORY_UNSPECIFIED, |
There was a problem hiding this comment.
Same issue as dataType: this schema allows ParamCategory.UNRECOGNIZED (-1) because the refine only excludes PARAM_CATEGORY_UNSPECIFIED. Consider restricting to the known valid categories and excluding UNRECOGNIZED to avoid submitting invalid enum values.
| (val) => val !== ParamCategory.PARAM_CATEGORY_UNSPECIFIED, | |
| (val) => PARAM_CATEGORY_FORM_OPTIONS.some((option) => option.value === val), |
| <> | ||
| <Upload className="mb-2 h-8 w-8 text-muted-foreground" /> | ||
| <p className="text-sm text-muted-foreground"> | ||
| Click to select or drag and drop an Excel file |
There was a problem hiding this comment.
The UI text says users can “drag and drop” an Excel file, but the component only supports click-to-select (no onDrop / onDragOver handling). Either implement drag-and-drop handlers or adjust the copy to avoid misleading users.
| Click to select or drag and drop an Excel file | |
| Click to select an Excel file |
| import { generateMetadata as genMeta } from "@/config/site" | ||
| import ParameterPageClient from "./parameter-page-client" | ||
|
|
||
| export const metadata = genMeta("Parameter") | ||
|
|
There was a problem hiding this comment.
This page is routed under /finance/master/parameter, but the existing navigation/breadcrumb mapping points to /finance/master/parameters (e.g. src/config/navigation.ts:111,209) and the finance dashboard links there as well (src/app/(dashboard)/finance/dashboard/page.tsx:86,123). As-is, the new UI may be unreachable from the app navigation. Consider aligning the route (rename folder to parameters or update navigation/links and remove the old stub page).
…r form Uses useUOMs() hook to fetch active UOMs for a user-friendly dropdown instead of requiring manual UUID entry. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Description
This pull request introduces a complete implementation of the Finance Parameter management feature, including both frontend UI and backend API routes. The changes add CRUD operations, import/export functionality, and table filtering/pagination for finance parameters, as well as loading and error handling states. The backend routes are integrated with gRPC services for all parameter operations.
Type of Change
Module/Component Affected
Changes Made
The most important changes are:
Backend API Routes for Finance Parameters:
src/app/api/v1/finance/parameters/route.ts,src/app/api/v1/finance/parameters/[paramId]/route.ts). (src/app/api/v1/finance/parameters/route.tsR1-R79, src/app/api/v1/finance/parameters/[paramId]/route.tsR1-R93)src/app/api/v1/finance/parameters/export/route.ts,src/app/api/v1/finance/parameters/import/route.ts,src/app/api/v1/finance/parameters/template/route.ts). [1] [2] [3]Frontend Pages and Components:
src/app/(dashboard)/finance/master/parameter/page.tsx,src/app/(dashboard)/finance/master/parameter/parameter-page-client.tsx). [1] [2]src/app/(dashboard)/finance/master/parameter/loading.tsx).Component Exports and Dialogs:
src/components/finance/parameter/index.ts,src/components/finance/parameter/parameter-delete-dialog.tsx). [1] [2]These changes collectively provide a robust, user-friendly finance parameter management module with full CRUD and import/export capabilities.
Build Verification
npm run lintpassesnpx tsc --noEmitpassesnpm run buildsucceedsAccessibility
Performance
Pre-merge Checklist