@rozaqi02/reusable-dashboard 1.1.3 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -2
- package/dist/index.cjs +609 -177
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +610 -178
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,13 +16,15 @@ CSS sudah terbundle — tidak perlu konfigurasi Tailwind.
|
|
|
16
16
|
2. [Prasyarat Teknis](#2-prasyarat-teknis)
|
|
17
17
|
3. [Preset yang Tersedia](#3-preset-yang-tersedia)
|
|
18
18
|
4. [Quick Start — Toko Sepatu (Contoh Lengkap)](#4-quick-start--toko-sepatu)
|
|
19
|
+
- [4.5 Cara Cepat dengan 1 File Config](#45-cara-cepat-dengan-createdasboardconfig)
|
|
19
20
|
5. [Quick Start — Cidika Travel](#5-quick-start--cidika-travel)
|
|
20
21
|
6. [Setup Database Supabase](#6-setup-database-supabase)
|
|
21
22
|
7. [Cara Membuat Adapter untuk Domain Bisnis Baru](#7-cara-membuat-adapter-untuk-domain-bisnis-baru)
|
|
22
23
|
8. [Konfigurasi Widget](#8-konfigurasi-widget)
|
|
23
24
|
9. [Label & Internasionalisasi](#9-label--internasionalisasi)
|
|
24
25
|
10. [API Reference Lengkap](#10-api-reference-lengkap)
|
|
25
|
-
11. [
|
|
26
|
+
11. [Setup Wizard — Panduan Konfigurasi Interaktif](#11-setup-wizard--panduan-konfigurasi-interaktif)
|
|
27
|
+
12. [Pengembangan & Kontribusi](#12-pengembangan--kontribusi)
|
|
26
28
|
|
|
27
29
|
---
|
|
28
30
|
|
|
@@ -313,6 +315,100 @@ Buka browser → dashboard tampil dengan data dari Supabase.
|
|
|
313
315
|
|
|
314
316
|
---
|
|
315
317
|
|
|
318
|
+
## 4.5 Cara Cepat dengan `createDashboardConfig`
|
|
319
|
+
|
|
320
|
+
Mulai versi **1.1.3**, modul menyediakan factory function `createDashboardConfig` yang
|
|
321
|
+
mengemas semua konfigurasi (widgetConfig + dataSource + adapter + labels) menjadi
|
|
322
|
+
**1 objek tunggal**. Ini cara yang lebih ringkas dan direkomendasikan untuk domain baru.
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
Sebelum (4 parameter terpisah ke hook): Sesudah (1 objek terpadu):
|
|
326
|
+
|
|
327
|
+
useReusableDashboard({ const cfg = createDashboardConfig({
|
|
328
|
+
config: tokoSepatuWidgetConfig, widgetConfig: tokoSepatuWidgetConfig,
|
|
329
|
+
dataSource: source, →→→ dataSource: source,
|
|
330
|
+
adapter: adaptTokoSepatuData, adapter: adaptTokoSepatuData,
|
|
331
|
+
createEmptyState: createEmpty, createEmptyState: createEmpty,
|
|
332
|
+
languageCode: "id", languageCode: "id",
|
|
333
|
+
dateLocale: "id-ID", dateLocale: "id-ID",
|
|
334
|
+
labels, });
|
|
335
|
+
}); useReusableDashboard({ ...cfg, labels });
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Contoh penggunaan lengkap:**
|
|
339
|
+
|
|
340
|
+
```jsx
|
|
341
|
+
import { supabase } from "../lib/supabaseClient";
|
|
342
|
+
import {
|
|
343
|
+
ReusableDashboardView,
|
|
344
|
+
useReusableDashboard,
|
|
345
|
+
createDashboardConfig, // ← factory baru
|
|
346
|
+
tokoSepatuWidgetConfig,
|
|
347
|
+
createTokoSepatuSupabaseSource,
|
|
348
|
+
adaptTokoSepatuData,
|
|
349
|
+
createEmptyTokoSepatuData,
|
|
350
|
+
} from "@rozaqi02/reusable-dashboard";
|
|
351
|
+
|
|
352
|
+
import { myWidgetConfig } from "./myWidgetConfig";
|
|
353
|
+
import { createMySource } from "./myDataSource";
|
|
354
|
+
import { adaptMyData, createEmptyMyData } from "./myAdapter";
|
|
355
|
+
|
|
356
|
+
// Buat di luar komponen — sekali saja
|
|
357
|
+
const dashboardConfig = createDashboardConfig({
|
|
358
|
+
widgetConfig: myWidgetConfig,
|
|
359
|
+
dataSource: createMySource(supabase),
|
|
360
|
+
adapter: adaptMyData,
|
|
361
|
+
createEmptyState: createEmptyMyData,
|
|
362
|
+
languageCode: "id",
|
|
363
|
+
dateLocale: "id-ID",
|
|
364
|
+
// labels bisa disertakan di sini atau di-override saat render
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
const labels = { title: "Dashboard Saya", /* ... */ };
|
|
368
|
+
|
|
369
|
+
export default function MyDashboard() {
|
|
370
|
+
const state = useReusableDashboard({ ...dashboardConfig, labels });
|
|
371
|
+
|
|
372
|
+
return (
|
|
373
|
+
<ReusableDashboardView
|
|
374
|
+
config={dashboardConfig.config}
|
|
375
|
+
labels={labels}
|
|
376
|
+
loading={state.loading}
|
|
377
|
+
error={state.error}
|
|
378
|
+
filters={state.filters}
|
|
379
|
+
onFilterChange={state.updateFilter}
|
|
380
|
+
onResetFilters={state.resetFilters}
|
|
381
|
+
onRefresh={state.refresh}
|
|
382
|
+
data={state.data}
|
|
383
|
+
dateLocale={dashboardConfig.dateLocale}
|
|
384
|
+
liveUpdateEnabled={state.liveUpdateEnabled}
|
|
385
|
+
supabase={supabase} // aktifkan fitur baca tabel di wizard
|
|
386
|
+
dashboardConfig={dashboardConfig} // aktifkan validasi otomatis
|
|
387
|
+
/>
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**Apa yang terjadi jika config belum lengkap?**
|
|
393
|
+
|
|
394
|
+
`createDashboardConfig` menyimpan info validasi di `dashboardConfig._meta`:
|
|
395
|
+
|
|
396
|
+
```javascript
|
|
397
|
+
dashboardConfig._meta = {
|
|
398
|
+
isValid: true, // false jika ada bagian yang kurang
|
|
399
|
+
missing: [], // ["adapter", "dataSource"] jika belum diisi
|
|
400
|
+
hasDataSource: true,
|
|
401
|
+
hasRealtimeSupport: true, // false jika subscribeLiveUpdate tidak ada
|
|
402
|
+
hasLabels: true,
|
|
403
|
+
widgetCount: { stats: 4, charts: 4, tableColumns: 6 },
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Jika ada bagian yang kurang, `ReusableDashboardView` secara otomatis menampilkan
|
|
408
|
+
**Setup Wizard** (lihat [Bab 11](#11-setup-wizard--panduan-konfigurasi-interaktif)).
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
316
412
|
## 5. Quick Start — Cidika Travel
|
|
317
413
|
|
|
318
414
|
Ganti hanya 4 baris dari contoh Toko Sepatu di atas:
|
|
@@ -1053,6 +1149,20 @@ function Dashboard() {
|
|
|
1053
1149
|
| `cidikaWidgetConfig` | Object | Config dashboard Cidika Travel |
|
|
1054
1150
|
| `tokoSepatuWidgetConfig` | Object | Config dashboard Toko Sepatu |
|
|
1055
1151
|
| `dummyUmkmWidgetConfig` | Object | Config dashboard UMKM generik |
|
|
1152
|
+
| `createDashboardConfig(options)` | Function | Factory: kemas semua config jadi 1 objek (v1.1.3+) |
|
|
1153
|
+
| `validateDashboardConfig(cfg)` | Function | Validasi config, kembalikan `{ valid, issues }` (v1.1.3+) |
|
|
1154
|
+
|
|
1155
|
+
**`createDashboardConfig(options)` — parameter:**
|
|
1156
|
+
|
|
1157
|
+
| Parameter | Tipe | Wajib | Keterangan |
|
|
1158
|
+
|-----------|------|-------|------------|
|
|
1159
|
+
| `widgetConfig` | Object | ✅ | Konfigurasi widget deklaratif |
|
|
1160
|
+
| `dataSource` | Object | ✅ | Hasil `createXxxSupabaseSource(supabase)` |
|
|
1161
|
+
| `adapter` | Function | ✅ | Fungsi `adaptXxxData` |
|
|
1162
|
+
| `createEmptyState` | Function | ✅ | Fungsi `createEmptyXxxData` |
|
|
1163
|
+
| `labels` | Object | — | Objek label UI (bisa di-override saat render) |
|
|
1164
|
+
| `languageCode` | string | — | Default `"id"` |
|
|
1165
|
+
| `dateLocale` | string | — | Default `"id-ID"` |
|
|
1056
1166
|
|
|
1057
1167
|
### Data Source
|
|
1058
1168
|
|
|
@@ -1103,6 +1213,7 @@ state.range // { fromISO, toISO, daysWindow }
|
|
|
1103
1213
|
| Komponen | Deskripsi |
|
|
1104
1214
|
|----------|-----------|
|
|
1105
1215
|
| `ReusableDashboardView` | Halaman dashboard lengkap — gunakan ini untuk integrasi cepat |
|
|
1216
|
+
| `SetupWizard` | Pop-up wizard panduan konfigurasi interaktif (v1.1.3+) |
|
|
1106
1217
|
| `StatCard` | Kartu metrik dengan warna aksen |
|
|
1107
1218
|
| `ChartCard` | Kartu grafik (area/pie/bar) |
|
|
1108
1219
|
| `DataTable` | Tabel dengan search, sort, pagination |
|
|
@@ -1119,6 +1230,24 @@ state.range // { fromISO, toISO, daysWindow }
|
|
|
1119
1230
|
| `SidebarNavigation` | Navigasi sidebar |
|
|
1120
1231
|
| `TopbarHeader` | Header atas |
|
|
1121
1232
|
|
|
1233
|
+
**Props `ReusableDashboardView` (lengkap):**
|
|
1234
|
+
|
|
1235
|
+
| Prop | Tipe | Wajib | Keterangan |
|
|
1236
|
+
|------|------|-------|------------|
|
|
1237
|
+
| `config` | Object | ✅ | Widget configuration |
|
|
1238
|
+
| `labels` | Object | ✅ | Objek label UI |
|
|
1239
|
+
| `loading` | boolean | — | Status loading data |
|
|
1240
|
+
| `error` | string | — | Pesan error |
|
|
1241
|
+
| `filters` | Object | — | State filter aktif |
|
|
1242
|
+
| `onFilterChange` | Function | ✅ | `(field, value) => void` |
|
|
1243
|
+
| `onResetFilters` | Function | ✅ | `() => void` |
|
|
1244
|
+
| `onRefresh` | Function | ✅ | `() => void` |
|
|
1245
|
+
| `data` | Object | — | Data `{ stats, charts, table }` |
|
|
1246
|
+
| `dateLocale` | string | — | Default `"id-ID"` |
|
|
1247
|
+
| `liveUpdateEnabled` | boolean | — | Badge "Live" aktif |
|
|
1248
|
+
| `supabase` | Object | — | Supabase client — aktifkan fitur baca tabel di wizard (v1.1.3+) |
|
|
1249
|
+
| `dashboardConfig` | Object | — | Hasil `createDashboardConfig()` — aktifkan validasi otomatis (v1.1.3+) |
|
|
1250
|
+
|
|
1122
1251
|
### Utility
|
|
1123
1252
|
|
|
1124
1253
|
| Function | Deskripsi |
|
|
@@ -1136,7 +1265,91 @@ state.range // { fromISO, toISO, daysWindow }
|
|
|
1136
1265
|
|
|
1137
1266
|
---
|
|
1138
1267
|
|
|
1139
|
-
## 11.
|
|
1268
|
+
## 11. Setup Wizard — Panduan Konfigurasi Interaktif
|
|
1269
|
+
|
|
1270
|
+
Mulai versi **1.1.3**, modul menyertakan **Setup Wizard**: pop-up panduan interaktif yang
|
|
1271
|
+
muncul **otomatis** saat `ReusableDashboardView` mendeteksi konfigurasi belum lengkap.
|
|
1272
|
+
|
|
1273
|
+
Ini menjawab kebutuhan: *"developer baru yang belum pernah pakai modul ini tahu harus
|
|
1274
|
+
mulai dari mana tanpa harus baca README dari awal."*
|
|
1275
|
+
|
|
1276
|
+
### Cara kerja
|
|
1277
|
+
|
|
1278
|
+
Wizard aktif ketika salah satu kondisi terpenuhi:
|
|
1279
|
+
- Prop `dashboardConfig` (dari `createDashboardConfig`) punya `_meta.isValid === false`
|
|
1280
|
+
- Prop `config`, `labels`, atau `labels.formatStatusLabel` tidak ditemukan
|
|
1281
|
+
|
|
1282
|
+
Wizard **tidak** muncul jika semua konfigurasi sudah valid.
|
|
1283
|
+
|
|
1284
|
+
### Fitur wizard
|
|
1285
|
+
|
|
1286
|
+
**Step 0 — Overview:**
|
|
1287
|
+
- Checklist masalah yang ditemukan (mis. `"adapter belum diisi"`)
|
|
1288
|
+
- Diagram alur konfigurasi: Data Source → Adapter → Widget Config
|
|
1289
|
+
|
|
1290
|
+
**Step 1 — Data Source:**
|
|
1291
|
+
- Contoh kode `fetchDashboardSnapshot` yang siap di-copy
|
|
1292
|
+
- Tombol **"Baca tabel Supabase langsung"** — membaca daftar tabel dari project
|
|
1293
|
+
Supabase kamu secara realtime via `information_schema.tables`
|
|
1294
|
+
|
|
1295
|
+
**Step 2 — Adapter:**
|
|
1296
|
+
- Contoh kode `adaptMyData` dengan `buildDayBuckets` + `toNumber`
|
|
1297
|
+
- Penjelasan bahwa key `stats` harus cocok dengan `valueKey` di widget config
|
|
1298
|
+
|
|
1299
|
+
**Step 3 — Widget Config & Rangkaian Akhir:**
|
|
1300
|
+
- Contoh kode lengkap dengan `createDashboardConfig` dari langkah 1–3
|
|
1301
|
+
|
|
1302
|
+
### Cara mengaktifkan fitur baca tabel Supabase
|
|
1303
|
+
|
|
1304
|
+
Tambahkan prop `supabase` ke `ReusableDashboardView`:
|
|
1305
|
+
|
|
1306
|
+
```jsx
|
|
1307
|
+
<ReusableDashboardView
|
|
1308
|
+
config={dashboardConfig.config}
|
|
1309
|
+
labels={labels}
|
|
1310
|
+
// ... props lain
|
|
1311
|
+
supabase={supabase} // ← aktifkan fitur baca tabel
|
|
1312
|
+
dashboardConfig={dashboardConfig} // ← aktifkan validasi otomatis
|
|
1313
|
+
/>
|
|
1314
|
+
```
|
|
1315
|
+
|
|
1316
|
+
Saat wizard terbuka di Step 1, pengguna bisa klik tombol untuk melihat
|
|
1317
|
+
daftar tabel yang tersedia di project Supabase mereka:
|
|
1318
|
+
|
|
1319
|
+
```
|
|
1320
|
+
Tabel ditemukan (4):
|
|
1321
|
+
bookings packages package_locales page_sections
|
|
1322
|
+
```
|
|
1323
|
+
|
|
1324
|
+
> Fitur ini membutuhkan RLS Supabase mengizinkan `SELECT` pada
|
|
1325
|
+
> `information_schema.tables` untuk role `anon`, atau fallback ke RPC `get_tables`.
|
|
1326
|
+
> Jika tidak bisa diakses, wizard tetap berfungsi — hanya tombol baca tabel yang
|
|
1327
|
+
> menampilkan pesan error.
|
|
1328
|
+
|
|
1329
|
+
### Menggunakan wizard tanpa `createDashboardConfig`
|
|
1330
|
+
|
|
1331
|
+
Wizard juga bisa dipakai standalone (misalnya saat testing atau demo):
|
|
1332
|
+
|
|
1333
|
+
```jsx
|
|
1334
|
+
import { SetupWizard } from "@rozaqi02/reusable-dashboard";
|
|
1335
|
+
|
|
1336
|
+
// Tampilkan wizard dengan isu kustom
|
|
1337
|
+
<SetupWizard
|
|
1338
|
+
issues={["Widget config belum diisi", "Data source tidak ditemukan"]}
|
|
1339
|
+
supabase={supabase}
|
|
1340
|
+
onDismiss={() => console.log("wizard ditutup")}
|
|
1341
|
+
/>
|
|
1342
|
+
```
|
|
1343
|
+
|
|
1344
|
+
### Menutup wizard
|
|
1345
|
+
|
|
1346
|
+
Klik tombol **"Lanjutkan tanpa wizard"** atau **"Tutup & lanjutkan ✓"** di Step 3.
|
|
1347
|
+
Wizard tidak muncul lagi selama sesi berlangsung (state `wizardDismissed` disimpan
|
|
1348
|
+
di level komponen).
|
|
1349
|
+
|
|
1350
|
+
---
|
|
1351
|
+
|
|
1352
|
+
## 12. Pengembangan & Kontribusi
|
|
1140
1353
|
|
|
1141
1354
|
```bash
|
|
1142
1355
|
# Clone repository
|