Dashboard Dinamis Berbasis Widget
Halaman utama setelah login. Sistem widget catalog: tiap widget = komponen self-contained yang baca dari DashboardData shared. Layout per role disimpan di DB (DashboardLayout) โ admin atur via drag-drop editor di /settings/dashboard. Fallback ke preset hardcoded kalau role belum di-customize. Real-time update via WebSocket tanpa refresh.
hardcoded fallback"] API1 -->|dto| LayoutDB[("DashboardLayout")] Hook --> Grid[DashboardGrid] Page --> Data["DashboardData
fetched once, shared"] Grid --> Reg["registry.ts
20+ widgets"] Reg --> Widget1[KpiRevenue] Reg --> Widget2[ArAging] Reg --> Widget3[TrendChart] Reg --> WidgetN["..."] Widget1 --> Data Widget2 --> Data Widget3 --> Data end subgraph Editor SettingsPage["/settings/dashboard"] --> APIEdit["PUT /dashboard/layouts/:role"] APIEdit --> LayoutDB end style LayoutDB fill:#dbeafe,stroke:#3b82f6 style Reg fill:#fef3c7,stroke:#d97706 style Data fill:#f0fdf4,stroke:#16a34a
Pintar
Pintar
SMSMLGMD๐ Header
headerโ sambutan, tanggal, quick action sesuai rolealert-barโ notifikasi stok habis, PO transit, AR pendingrole-panelโ panel keputusan harian per role- Category: header / alert / action โ selalu full-width
๐ KPI Cards (sm)
kpi-revenue๐ฒ ยทkpi-profit๐ฒ ยทkpi-spkยทkpi-gross๐ฒkpi-customerยทkpi-ar๐ฒ ยทkpi-ap๐ฒ ยทkpi-stock- $ icon = sensitive (default disembunyikan untuk non-finance role)
- Sparkline 6 bulan + delta vs bulan lalu
๐ Charts
chart-trendโ Revenue + Profit 12 bln, target line, forecast EOMspk-pipelineโ donut status SPK + masuk/selesai hari ini- Forecast = MTD / dayOfMonth ร daysInMonth
- Target = avg 6 bln ร 1.10 (heuristik growth 10%)
๐ฐ Finance Widgets
ar-aging๐ฒ โ bucket 0-30 / 31-60 / 61-90 / >90 harisupplier-due๐ฒ โ hutang outstandingsummary-12mo๐ฒ โ tabel revenue/profit per bulan- Highlight risiko: AR > 60 hari โ "prioritas penagihan minggu ini"
๐ List / Tabel
recent-spkโ 8 SPK terbaru dengan status & totalmekanik-performanceโ utilisasi & rating per mekaniktop-jasaโ top 5 layanan + ringkasan kaspo-transitยทlow-stockยทsummary-spk
๐ Size System
- Grid 4-kolom;
sm=1,md=2,lg=3,full=4 - Default size dari widget meta โ admin bisa override per layout
- Layout (header/alert/action) selalu full-width otomatis
- Saved size override di kolom
widgetSizes(JSON)
๐ก๏ธ Admin / Manager
- Semua KPI + finance + chart + list = ~20 widget
- TrendChart, AR Aging, Summary 12 bulan, mekanik performance
- Sensitive widgets ($) terlihat semua
๐๏ธ Service Advisor (SA)
- SPK aktif, customer, AR, stok
- SPK pipeline donut, summary SPK, recent SPK
- Tanpa widget profit / cogs / chart trend
๐ณ Kasir
- Revenue, AR, AP, AR Aging
- Pipeline + summary SPK + supplier due
- Fokus collection & cash position
๐ง Mekanik / Karu / Gudang / Operator
- Mekanik: SPK saya, stok kritis, pipeline
- Karu: SPK + KPI tim + mekanik performance
- Gudang: stok, PO transit, supplier due, AP
- Operator: SPK aktif, customer, summary
๐ฏ Tab Per Role
- 8 role: admin, manager, sa, kasir, mekanik, gudang, operator, karu
- Tab horizontal di top untuk switch antar role
- Loading: fetch dari API โ fallback ke preset jika belum di-customize
๐ Palet Widget (Sticky Left)
- Dikelompokkan per kategori dengan warna khas
- Drag widget atau click untuk tambah
- Widget yang sudah dipilih โ opacity 0.55
- Badge $ untuk sensitive (finance) widget
๐จ List Layout (Right)
- Drag handle โฎโฎ untuk reorder
- Drop-zone biru di antara item saat drag
- Size selector inline: S / M / L / Full
- Badge "custom" muncul jika size override aktif
- ร untuk hapus widget dari layout
๐พ Save / Reset
- Indicator dirty state โ "Ada perubahan belum disimpan"
- Save โ
PUT /api/dashboard/layouts/:role - Reset to Default โ
DELETE /api/dashboard/layouts/:role(kembali ke preset hardcoded) - Status: "Custom layout" (hijau) atau "Default preset" (kuning)
| Method | Path | Permission | Deskripsi |
|---|---|---|---|
GET | /dashboard/layouts | settings.dashboard:view | List semua layout terkonfigurasi (admin/manager) |
GET | /dashboard/layouts/:role | any auth | Get layout role (non-admin hanya boleh role-nya sendiri) |
PUT | /dashboard/layouts/:role | settings.dashboard:edit | Upsert layout role |
DELETE | /dashboard/layouts/:role | settings.dashboard:delete | Reset ke default preset (admin only) |
GET | /dashboard | rbac admin/manager/sa/karu | Aggregate KPI + alerts (legacy endpoint) |
GET | /dashboard/summary | rbac | Today summary (revenue, bay, queue) |
GET | /dashboard/chart/revenue | rbac | Revenue trend 30 hari |
GET | /dashboard/chart/wo-status | rbac | Distribusi status WO |
GET | /dashboard/alerts | rbac | Low stock, expiring STNK, budget |
Tabel: DashboardLayout (role unique, widgetKeys[], widgetSizes JSON, audit fields)
Resource permission baru: settings.dashboard (view/create/edit/delete)
WS Events (real-time): wo:status_changed, wo:created, bay:occupied, bay:free, payment:closed, followup:created
Throttle: hook useSpkRealtime 300ms agar event burst tidak spam re-render
Performance: shared DashboardData dihitung sekali, semua widget tinggal pakai (mengurangi N+1 fetch)