Skip to content

feat(finance): bulk product routing system, import/export jobs tracking page, and responsive UI polish#52

Merged
ilramdhan merged 9 commits into
mutugading:mainfrom
ilramdhan:fix/seed-master-data-product-cost
Jun 22, 2026
Merged

feat(finance): bulk product routing system, import/export jobs tracking page, and responsive UI polish#52
ilramdhan merged 9 commits into
mutugading:mainfrom
ilramdhan:fix/seed-master-data-product-cost

Conversation

@ilramdhan

Copy link
Copy Markdown
Member

Description

Pull Request ini memperkenalkan fitur Bulk Product Routing Import/Export yang terintegrasi penuh dari backend (RPCs/BFF) hingga frontend (UI/UX). Implementasi ini mencakup pembuatan template dinamis menggunakan ExcelJS, perombakan tombol aksi pada halaman Product Master menjadi dropdown interaktif, serta desain ulang BulkImportDialog dengan validasi data per-sheet.

Selain itu, PR ini menambahkan sebuah halaman khusus Import/Export Jobs (/finance/import-jobs) untuk memantau status pemrosesan asynchronous secara real-time (dengan sistem auto-refresh setiap 5 detik). Terdapat juga berbagai perbaikan bug krusial terkait UI mobile responsiveness, penanganan error pada API, dan penyelesaian isu double-header pada berkas Excel.

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 🎨 UI/UX improvement
  • ♻️ Refactor
  • 📚 Documentation
  • 🔧 Chore (deps, config)

Module/Component Affected

  • Dashboard
  • Finance (Costing / Product Master / Import-Export)
  • HR / IT / CI / EXSIM
  • Components (common/)
  • Components (ui/)
  • Navigation
  • API Routes (BFF)

Changes Made

1. Bulk Product Routing System:

  • Mengenerate ulang proto TypeScript types untuk kapabilitas RPCs bulk product routing.
  • Membuat BFF routes untuk template download, validate, dan eksekusi import/export massal.
  • Mengimplementasikan pembuatan template file Excel menggunakan library ExcelJS langsung di layer BFF.
  • Bug Fix: Memperbaiki logika ExcelJS agar tidak menulis baris header ganda (double-header), dengan mengatur konfigurasi ws.columns terlebih dahulu sebelum memasukkan sample data.

2. Import/Export Jobs Tracking Page:

  • Menambahkan halaman dashboard baru di /finance/import-jobs untuk melihat daftar pekerjaan import/export, lengkap dengan status badges, progress bar, dan tombol download.
  • Mengimplementasikan TanStack Query hook (useImportJobs) dengan polling auto-refresh interval 5 detik.
  • Mengubah success toast dari aksi bulk export menjadi notifikasi asynchronous informatif (berdurasi 8 detik) yang disertai tombol aksi "Lihat Jobs" yang langsung mengarah ke halaman pelacakan.

3. UI/UX Redesign & Responsiveness:

  • Menyederhanakan antarmuka halaman product-master dengan menggabungkan 4 tombol aksi terpisah menjadi 2 tombol dropdown terpadu (Import & Export).
  • Merombak BulkImportDialog untuk menyerupai standar Import Dialog UX: menambahkan kartu unduh template di atas, area drag-and-drop file bersisi putus-putus (dashed), serta tabel hasil validasi per-sheet sebelum mengklik "Start Import".
  • Mobile Responsiveness Fix: Memastikan BulkImportDialog responsif secara penuh di ukuran layar kecil (375px) dengan bermigrasi ke ScrollableDialog, mengatur stacking flex-col pada kartu template, memotong nama file dengan ellipsis, menerapkan table-fixed untuk mencegah horizontal overflow, serta mengganti konflik ScrollArea dengan struktur div mandiri (overflow-auto).

4. Error Handling & Stability:

  • React Warning Fix: Memperbaiki peringatan (warning) React Key pada .map() dengan memindahkan properti key dari TableRow langsung ke elemen React.Fragment.
  • Memperbaiki logika respons BFF agar melempar error (throw) ketika HTTP 200 mengembalikan status isSuccess=false, menggantikan behavior lamanya yang secara senyap (silently) mereturn object validasi kosong, sehingga pesan error dapat dimunculkan dengan tepat ke pengguna (termasuk memblokir munculnya toast "Job #0").

Related Issues

Fixes #
Related to #

Screenshots

Before

After

Testing Performed

Manual Testing

  • Desktop (1440px+)
  • Tablet (768px)
  • Mobile (375px)
  • Light mode
  • Dark mode

Browser Testing

  • Chrome
  • Firefox
  • Safari
  • Edge

Build Verification

  • npm run lint passes
  • npx tsc --noEmit passes
  • npm run build succeeds

Accessibility

  • Keyboard navigation works
  • Screen reader compatible
  • Proper ARIA labels
  • Color contrast adequate

Performance

  • No unnecessary re-renders
  • Images optimized
  • Heavy components lazy loaded

Pre-merge Checklist

  • I have read and followed RULES.md
  • I have read and followed CONTRIBUTING.md
  • Loading states implemented (if data fetching)
  • Error handling present (API error throwing)
  • Component props typed properly
  • Uses semantic color classes
  • Responsive design tested
  • Dark mode compatible
  • Screenshots included (for UI changes)

Reviewer Notes

  • ExcelJS Implementation: Proses pembuatan dan modifikasi berkas .xlsx dilakukan melalui layer BFF (Route Handlers) menggunakan ExcelJS. Pastikan untuk me-review secara saksama komit terkait ws.columns agar tata urutan (order) header dengan isi data tidak mengalami tabrakan/penimpaan overwrite.
  • Mobile Scroll Overflow: Untuk komponen BulkImportDialog, kami membuang penggunaan <ScrollArea> bawaan UI (yang sering kali menimbulkan bug scroll container ganda saat dipadukan dengan tabel). Sebagai gantinya, digunakan elemen standar max-h-64 overflow-auto serta table-fixed. Pendekatan ini terbukti lebih stabil di tampilan mobile.
  • API Response Pattern: BFF validate route telah diperbarui. Saat ini, system akan secara proaktif me-reject dan throw error jika respons bernilai isSuccess=false, meskipun status HTTP mengembalikan nilai 200 (OK).

ilramdhan and others added 9 commits June 22, 2026 14:17
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nd page integration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rtDialog

- Import React to use React.Fragment with key prop on .map() (line 193)
- Moved key from TableRow to Fragment to fix React key warning
- Add isValid validation check to "Start Import" button (line 280)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ly returning empty result

When the BFF returns a successful HTTP 200 but base.isSuccess=false,
validateBulkProductRoutingFile now throws so the caller can surface the error
to the user rather than silently returning { isValid: false, sheets: [] }.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ign bulk import dialog

- Replace 4 separate action buttons on product-master page with 2 dropdown buttons (Import / Export), each with product-only and bulk+routing variants
- Redesign BulkImportDialog to match ImportDialog UX: template download card at top, dashed file picker, validate → per-sheet results table → Start Import flow
- Add downloadBulkProductRoutingTemplate() to cost-import-api.ts (triggers browser download via fetch)
- Add BFF stub GET /api/v1/finance/costing/template/bulk_product_routing returning 501 until backend RPC is implemented

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…le-header

- cost-import-api.ts: throw error when base.isSuccess is false so
  "Job #0" never surfaces as a success toast
- product-master-page-client.tsx: replace generic success toast with
  descriptive async message + "Lihat Jobs" action button linking to
  /finance/import-jobs (duration 8s)
- bulk_product_routing template route: set ws.columns first (ExcelJS
  writes header row via ws.columns), then add only the sample data row
  — previously ws.addRow(headers) + ws.columns = [{header}] caused a
  double header row or overwrite

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New dashboard page with job list, status badges, progress bar, and download button
- BFF GET /api/v1/finance/costing/import-jobs list route
- listImportJobs API function and useImportJobs hook with 5s auto-refresh
- Extended ImportEntity type to include bulk_product_routing variants
- Bulk export toast Lihat Jobs link now resolves to this page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace DialogContent/Header/Footer with ScrollableDialog equivalents
- Template card stacks vertically on mobile (flex-col sm:flex-row)
- File name truncates with ellipsis (truncate min-w-0)
- Validation table uses table-fixed to eliminate horizontal overflow
- Error rows use break-all + pl-4 so full message is visible at 375px
- Replace ScrollArea+overflow-x-auto (conflicting scroll containers) with
  a single div.max-h-64.overflow-auto wrapping the table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ilramdhan ilramdhan added this to the Costing Release Milestone milestone Jun 22, 2026
@ilramdhan ilramdhan self-assigned this Jun 22, 2026
@ilramdhan ilramdhan added documentation Improvements or additions to documentation enhancement New feature or request feat labels Jun 22, 2026
@ilramdhan ilramdhan added the fix label Jun 22, 2026
@ilramdhan ilramdhan merged commit 3d447c8 into mutugading:main Jun 22, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request feat fix

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant