fix(finance): comprehensive product master UX overhaul, sortable tables, and detail drawer#63
Merged
ilramdhan merged 23 commits intoJul 8, 2026
Conversation
Replace ad-hoc initials logic scattered across comments, nav-user, and profile-header with a single UserAvatar component that renders the user's actual profile photo (AvatarImage) when available and falls back to deterministic-color initials (hash mod 6 palette) when not. Supersedes the former UserInitials helper (removed). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…l dialog; hide Use Existing Costing Replace two separate single-step dialogs (VerifyClassification and Feasibility) with a single ClassificationAndFeasibilityDialog that submits both steps in sequence, shows partial-failure state when classification succeeds but feasibility fails, and retries only the failed step. Also hides the Use Existing Costing button in the UNDER_REVIEW action block — the transition existed but had no useful completion path for the user at that stage. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…entity pre-claim Add FillTaskIdentity component that displays the product name (not just code) and the assigned filler/approver's name before they have claimed the task. Rendered in FillTrackingCompact and FillTaskRow so users can identify which product each fill task belongs to without memorizing product codes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lReviewDrawer Add is_approval_visible toggle and approval_display_order number input to the Parameter Master form dialog so operators can configure which parameters appear in the CPR approval drawer. FillApprovalReviewDrawer replaces the one-click Approve button with a drawer that shows the filtered (isApprovalVisible=true), ordered parameter values for every product at the fill level before the approver confirms. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… guard useUnlinkRoute.onSuccess was missing the ["finance","cost-route"] invalidation added to useLinkExistingRoute, leaving the route's linked- request list stale after an unlink. Add the missing key. Also disables the Unlink button with a tooltip when the linked route is in LOCKED status, reflecting the new backend 409 guard. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update UserAvatar section to document the new colorHash prop behavior and note the removal of the former UserInitials component. Fix stale test references to removed components. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
routing-panel: disable Unlink button and show lock tooltip when route is in LOCKED status, preventing accidental detach of routes with active cost results. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When the reviewer selects NOT_FEASIBLE, hide the classification section
entirely and submit directly to the feasibility RPC without first calling
the classification RPC. Eliminates the confusing question "which
classification?" for a product that is not feasible.
Changes:
- handleSubmit: early-return to submitFeasibility() when isInfeasible
- canSubmit: short-circuit canSubmitClassification with isInfeasible
- classification section + separator: wrapped in {!isInfeasible && ...}
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ead of count Replace the ambiguous "N level(s)" count with "Level N, M" showing the actual route level numbers each product sits at. Also display the product name below the product code so users can identify products without memorizing codes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each of these drawers had both a SheetClose/X icon button and a "← Back to request" button doing the exact same thing. Remove the X button — "Back to request" is more informative and less ambiguous. FillTrackingDrawer had only an X and no Back button; replaced with a proper "← Back" button for consistency. Two-level drawers (param-detail, override-params, param-edit-log) are intentionally left unchanged — their X/Back correctly closes only the inner drawer while keeping the outer one open. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Apply the same displayGroup / displayOrder grouping used in the cost breakdown modal to FillParamProductSection and FillApprovalReviewDrawer. Params are now grouped under labelled section headers (text-xs uppercase) sorted by the group's minimum displayOrder; ungrouped params render last with no header. Makes param layout consistent across fill entry, approval review, and cost results breakdown views. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cancel and Close both terminate a request to CLOSED status. The difference (Cancel forces substatus=cancelled; Close lets the user pick won/lost/cancelled/on_hold) was not visible to users, creating three overlapping buttons. Remove Cancel entirely. Users who want to close with substatus=cancelled use the Close dialog and select that option. Reject remains separate (terminates to REJECTED — recoverable via Revise — not CLOSED). Also updates the action-bar test to assert Cancel is absent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…w dialog Feasibility is the primary decision — show it first. Classification only appears (below a separator) when FEASIBLE is selected, which already matches the skip-classification-when-NOT_FEASIBLE behavior added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…code Each product badge in the fill tracking card now shows the product name in a truncated muted line below the code, matching the product summary card behavior. productName is optional so cards without name data render unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
param-detail-drawer (drawer 1), override-params-drawer (drawer 2), and param-edit-log-drawer (drawer 2) each had both a SheetClose/X icon and a Back button doing the same thing. Remove the X button; keep Back only. Two-level behavior is preserved: Back on drawer 2 calls onClose which unmounts only the inner drawer, leaving the outer one open. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…awer - ParamValueEntry type gains displayGroup + displayOrder with normalizer - ParamGroupedList component renders params grouped under section headers (divider line + bold uppercase label) ordered by min displayOrder per group - Ungrouped params (empty display_group) fall to bottom - Generated TS types updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ixes List page: - Split page.tsx into server component + routes-page-client.tsx (client) - Add loading.tsx skeleton - useUrlState for all filter/sort/pagination params (URL-synced) - SortableHeader on product, status, version columns - ColumnVisibilityMenu in filter bar - DataTablePagination replacing prev/next buttons - TableRow onClick → router.push (whole row is clickable) - KpiGrid with 4 KpiCards matching product-master layout Detail page: - Add loading.tsx skeleton - Fix locked banner: remove absolute positioning → inline amber card with Lock icon - Replace emoji Fork button (🔱) with GitFork Lucide icon - Replace raw <Badge> status with <StatusBadge type="route"> - Hide notes textarea behind <details> to declutter header - Replace window.confirm with <ConfirmDialog variant="destructive"> - LinkedRequestsPopover → responsive Sheet drawer (side="right") React Flow dark mode: - StageNode: add dark:bg-emerald-950/40 dark:border-emerald-700 variants - RmNode: add dark:bg-purple-950/40 / dark:bg-amber-950/40 dark variants - text-foreground on node text to prevent invisible text in dark mode Bug fixes: - deleteRm: was directly mutating seq.rms then shallow-spreading seqs → now uses .map() for fully immutable update (fixes delete 1 → deletes all) - deleteStage: was directly mutating base.seqs via assignment → now uses .filter() returning new array (fully immutable) - handleStageClick/handleEdgeClick: added seqId===0/rmId===0 guard → shows toast "Save first" instead of opening panel on unsaved nodes Cards view: - RM chips show typed color border (green=PRODUCT, purple=GROUP, amber=ITEM) - routeRmName shown (group name already populated by RmGroupCombobox onChange) - ratio displayed on second line of each chip for readability Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…, rm drag, dark mode, modals List page: level/rm count columns, sort fix (head_id/version), KPI/filter polish. Detail page: client-uuid keying for stages/RMs (fixes new-node-edit + multi-delete on unsaved elements), RM drag position persists, RM label shows group name, dark mode support in react-flow nodes, add-stage/add-RM dialogs restyled. Renamed linked-requests-popover.tsx -> linked-requests-sheet.tsx (Popover -> Sheet). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…d of onClick Replace TableRow onClick + router.push with an absolutely-positioned Link covering the product_code cell, so the row stays keyboard/middle-click/ new-tab friendly. Actions cell raised to z-10 to stay clickable above it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… doc audit Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tend) Combines two batches whose frontend edits landed interleaved in the working tree (product-requests-ux-batch, product-request-workflow-revamp): product-requests-ux-batch: - request-table.tsx: sortable columns, "Pending" badge for pending classification. - product-requests-page-client.tsx: sort state wired to SortableHeader. - request-form-dialog.tsx: form restructure (D1-D5 field changes). product-request-workflow-revamp: - RoutingResolver component + useResolveRouting() hook replace the deleted create-routing-wizard.tsx / pick-existing-route-dialog.tsx (link-existing / create-from-product / create-master-then-route, all inline). RoutingPanel and the review dialog's routing phase both consume it. - transition-dialogs.tsx: ClassificationAndFeasibilityDialog gains a routing phase between classified/deciding, gated on resolvedHeadId. - useSubmitAndDecide hook + BFF route for the merged Submit+StartReview action. - cost-product-request-import-dialog.tsx + BFF export/import/template routes for bulk request handling (xlsx, UOM-pattern), wired into a dropdown next to "New request". - PaperTubeName: fixed Paper/Plastic enum display, falls back to legacy cost_paper_tube_type lookup for historical rows. - FillTrackingDrawer: product info extracted into FillTrackingDrawerRow + badges. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…de merge Propagate the P3 helper rewrite (submitAndDecide, submitViaApi/startReviewViaApi API-bypass pair, useExistingCostingViaApi, findAnyProductSysId) through every remaining test that still referenced deleted helpers or pre-merge UI text. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Drop the standalone description field from the create/edit form; product description now comes solely from the spec section, removing duplicate free-text inputs. - Merge the description and attachments blocks into the product specification card in the detail panel, and always render the spec card (previously hidden when spec was absent) so description and attachments have a consistent home. - Move shade code/name helper text to a shared FormDescription instead of duplicating it per field.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Pull Request ini menghadirkan perombakan UX (User Experience) secara masif pada halaman Product Master. Pembaruan ini mencakup implementasi tabel yang dapat diurutkan secara server-side menggunakan komponen
SortableHeaderbaru, kontrol visibilitas kolom yang tersimpan (persisted), filter multi-select, serta navigasi baris yang dapat diklik (clickable rows).Selain itu, PR ini memperkenalkan Product Detail Drawer, sebuah laci interaktif (interactive drawer) dengan sticky header/footer dan lazy loading per-seksi, yang menggantikan kebutuhan navigasi ke halaman terpisah untuk melihat detail. Seluruh pola UI baru ini—termasuk standardisasi tinggi elemen kontrol (
h-9), responsivitas icon-only di layar kecil, dan ritme tata letak (layout rhythm)—telah dikodifikasikan ke dalam dokumen design system (DESIGN.md,LAYOUT.md,RULES.md,CLAUDE.md).Type of Change
Module/Component Affected
Changes Made
1. Advanced Data Table & Filters:
fa-sort, area klik penuh, dan dukungan aksesibilitas (aria-sort& navigasi keyboard).ColumnVisibilityMenudan hookuseColumnVisibilityuntuk menampilkan/menyembunyikan kolom secara dinamis (kode produk diatur agar tidak dapat disembunyikan).ProductTypeMultiComboboxyang memungkinkan filter multi-select dan secara otomatis menyinkronkan data ke URL dalam format CSV.2. Product Detail Drawer:
ProductDetailDraweryang responsif.3. UI Polish & Bug Fixes:
h-9, ukuran tombol yang seragam,KpiGriddengan lebar penuh (full-width span) untuk elemen ganjil terakhir, table edge padding, serta floor responsivitas layar di batas 375px.sm(mobile).sortBydansortOrderke dalam defaultsuseUrlState(sebelumnya nilai ini hilang secara silent saat state berubah).4. Design System Documentation:
DESIGN.mddanLAYOUT.mddengan konvensi UI terbaru (flat list page variant, h-9 parity, multi-select combobox, aturan row-click).RULES.mddanCLAUDE.md(Mistake 12: missing URL defaults, Mistake 13: stale typography), serta dokumentasi penggunaanSortableHeader.Related Issues
Fixes #
Related to #
Screenshots
Before
After
Testing Performed
Manual Testing
Browser Testing
Build Verification
npm run lintpassesnpx tsc --noEmitpassesnpm run buildsucceedsAccessibility
aria-sortimplemented)Performance
Pre-merge Checklist
Reviewer Notes
useUrlStateFix): Harap perhatikan perbaikan pada hook state parameter. Kealpaan memasukkan variabel ke dalam objekdefaultValuespadauseUrlStateakan menyebabkan status URL terhapus otomatis saat ada interaksi lain. Aturan ini telah dibakukan di dokumenRULES.md.h-9untuk memastikan konsistensi dan estetika setara di seluruh dashboard.