@gemafajarramadhan/dynamic-ui 1.1.28 → 1.1.30
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 +270 -26
- package/dist/dynamic-ui.css +2 -2
- package/dist/dynamic-ui.es.js +86236 -28785
- package/dist/dynamic-ui.umd.js +10291 -1726
- package/dist/index.d.ts +0 -11
- package/package.json +1 -1
- package/src/index.d.ts +0 -11
- package/dist/webcomponents/dynamic-ui.css +0 -9
- package/dist/webcomponents/dynamic-ui.es.js +0 -53137
- package/dist/webcomponents/dynamic-ui.umd.js +0 -8549
- package/dist/webcomponents/vite.svg +0 -1
package/README.md
CHANGED
|
@@ -19,6 +19,13 @@ Library **Vue 3** component yang bisa digunakan di berbagai framework (Vue, Reac
|
|
|
19
19
|
- [Penggunaan di Vue 3 (Import Per Komponen)](#penggunaan-di-vue-3-import-per-komponen)
|
|
20
20
|
- [Penggunaan di Vue 3 (Global Plugin)](#penggunaan-di-vue-3-global-plugin)
|
|
21
21
|
- [Penggunaan di Nuxt 3](#penggunaan-di-nuxt-3-vue-components)
|
|
22
|
+
- [DCodeDataTable – Tabel Dinamis](#dcodedatatable--tabel-dinamis)
|
|
23
|
+
- [Props Utama](#props-utama)
|
|
24
|
+
- [Pola 1 — fetchHandler (MFE)](#pola-1--fetchhandler--disarankan-untuk-mfe)
|
|
25
|
+
- [Pola 2 — Static Data](#pola-2--static-data-consumer-fetch-di-luar)
|
|
26
|
+
- [Pola 3 — Realtime Socket](#pola-3--realtime-socket-consumer-kelola-socket)
|
|
27
|
+
- [Format Response](#format-response-yang-didukung)
|
|
28
|
+
- [Expose Methods](#expose-methods-via-ref)
|
|
22
29
|
- [DCodeAutoComplete – Komponen dengan API](#dcodeautocomplete--komponen-dengan-api)
|
|
23
30
|
- [Web Components (Framework Agnostic)](#web-components-framework-agnostic)
|
|
24
31
|
- [API Referensi Web Components](#api-referensi-web-components)
|
|
@@ -248,7 +255,6 @@ Selain Web Components, library ini juga menyediakan **27 komponen Vue** yang bis
|
|
|
248
255
|
| `DCodeAutoComplete` | Input autocomplete dengan pencarian dan fetch API otomatis |
|
|
249
256
|
| `DCodeMultiSelect` | Dropdown multi-pilihan |
|
|
250
257
|
| `DCodeDatePicker` | Date picker kalender |
|
|
251
|
-
| `DCodeDateRangePicker` | Date range picker |
|
|
252
258
|
| `DCodeCurrencyField` | Input nilai mata uang |
|
|
253
259
|
| `DCodeOtpInput` | Input OTP digit-per-digit |
|
|
254
260
|
| `DCodeFileField` | Input file dengan preview |
|
|
@@ -379,6 +385,269 @@ Kemudian gunakan di page atau component manapun:
|
|
|
379
385
|
|
|
380
386
|
---
|
|
381
387
|
|
|
388
|
+
## DCodeDataTable – Tabel Dinamis
|
|
389
|
+
|
|
390
|
+
`DCodeDataTable` adalah komponen tabel dinamis yang mendukung **pagination server-side**, **sorting**, **filtering**, **action buttons**, dan **badge kondisional** — seluruhnya dikonfigurasi via JSON schema.
|
|
391
|
+
|
|
392
|
+
Komponen ini dirancang sebagai **micro-frontend**: consumer bertanggung jawab penuh atas HTTP client, auth token, dan sistem permission.
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
### Props Utama
|
|
397
|
+
|
|
398
|
+
| Prop | Tipe | Default | Deskripsi |
|
|
399
|
+
|------|------|---------|-----------|
|
|
400
|
+
| `table-config` | `Object` | — | Config JSON (kolom, filter, action, pagination) |
|
|
401
|
+
| `fetch-handler` | `(params) => Promise<any>` | — | **[MFE]** Consumer kontrol penuh fetch. Component tidak hit endpoint sama sekali. |
|
|
402
|
+
| `http-client` | `({ url, method, data }) => Promise<any>` | — | **[MFE]** Axios instance consumer untuk action tombol row/header (DELETE, PATCH, dll.) |
|
|
403
|
+
| `action-access-checker` | `(path, action) => boolean` | `() => true` | **[MFE]** Fungsi RBAC dari consumer. Default: semua action allow. |
|
|
404
|
+
| `ignore-permissions` | `boolean` | `false` | Matikan filter permission sepenuhnya |
|
|
405
|
+
| `data` | `any[]` | `[]` | Data statis (tanpa API); pakai jika consumer sudah fetch di luar |
|
|
406
|
+
| `loading` | `boolean` | `false` | Loading state untuk mode data statis |
|
|
407
|
+
| `columns` | `TableColumn[]` | `[]` | Kolom manual (tanpa table-config) |
|
|
408
|
+
| `per-page` | `number` | `10` | Jumlah baris per halaman awal |
|
|
409
|
+
| `show-pagination` | `boolean` | `true` | Tampilkan pagination |
|
|
410
|
+
| `has-actions` | `boolean` | `false` | Tampilkan kolom aksi (untuk mode kolom manual) |
|
|
411
|
+
| `api-url` | `string` | — | URL endpoint langsung (tanpa table-config) |
|
|
412
|
+
| `api-method` | `string` | `'POST'` | HTTP method untuk apiUrl |
|
|
413
|
+
| `api-params` | `object` | `{}` | Parameter tetap yang selalu disertakan di setiap request |
|
|
414
|
+
|
|
415
|
+
### Events
|
|
416
|
+
|
|
417
|
+
| Event | Payload | Deskripsi |
|
|
418
|
+
|-------|---------|-----------|
|
|
419
|
+
| `@action` | `{ action, row, selection? }` | Dipanggil saat tombol action diklik |
|
|
420
|
+
| `@update:selection` | `any[]` | Dipanggil saat checkbox selection berubah |
|
|
421
|
+
| `@update:page` | `number` | Dipanggil saat halaman berganti |
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
### Pola 1 — `fetchHandler` ⭐ Disarankan untuk MFE
|
|
426
|
+
|
|
427
|
+
Consumer kontrol penuh HTTP. Component tidak hit endpoint sama sekali — cocok untuk menghindari error 401.
|
|
428
|
+
|
|
429
|
+
```vue
|
|
430
|
+
<template>
|
|
431
|
+
<DCodeDataTable
|
|
432
|
+
:table-config="tableConfig"
|
|
433
|
+
:fetch-handler="fetchUsers"
|
|
434
|
+
:http-client="httpClient"
|
|
435
|
+
:action-access-checker="checkPermission"
|
|
436
|
+
@action="handleAction"
|
|
437
|
+
/>
|
|
438
|
+
</template>
|
|
439
|
+
|
|
440
|
+
<script setup lang="ts">
|
|
441
|
+
import { DCodeDataTable } from '@gemafajarramadhan/dynamic-ui'
|
|
442
|
+
import axios from '@/lib/axios' // axios instance consumer — interceptor token sudah terpasang
|
|
443
|
+
|
|
444
|
+
// 1. fetchHandler: dipanggil tiap page/filter/sort/search change
|
|
445
|
+
// params: { page, perPage, keyword?, ...filters }
|
|
446
|
+
const fetchUsers = async (params: Record<string, any>) => {
|
|
447
|
+
const { data } = await axios.post('/api/users/list', params)
|
|
448
|
+
return data
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// 2. httpClient: untuk call dari tombol action row (delete, toggle, dll.)
|
|
452
|
+
const httpClient = async ({ url, method, data }: any) => {
|
|
453
|
+
const res = await axios({ url, method, data })
|
|
454
|
+
return res.data
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// 3. Permission checker dari sistem RBAC consumer
|
|
458
|
+
const checkPermission = (path: string, action: string): boolean => {
|
|
459
|
+
return useAuthStore().can(`${path}:${action}`)
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// 4. Handle action event dari tabel
|
|
463
|
+
const handleAction = ({ action, row, selection }: any) => {
|
|
464
|
+
if (action === 'edit') router.push(`/users/${row.id}/edit`)
|
|
465
|
+
if (action === 'delete') deleteUser(row.id)
|
|
466
|
+
if (action === 'export') exportSelected(selection)
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// 5. Konfigurasi tabel via JSON schema
|
|
470
|
+
const tableConfig = {
|
|
471
|
+
headers: [
|
|
472
|
+
{ key: 'no', labelID: 'No', labelEN: 'No', align: 'CENTER' },
|
|
473
|
+
{ key: 'name', labelID: 'Nama', labelEN: 'Name', align: 'LEFT' },
|
|
474
|
+
{ key: 'email', labelID: 'Email', labelEN: 'Email', align: 'LEFT' },
|
|
475
|
+
{
|
|
476
|
+
key: 'status',
|
|
477
|
+
labelID: 'Status', labelEN: 'Status',
|
|
478
|
+
custom: {
|
|
479
|
+
type: 'BADGE',
|
|
480
|
+
conditionBadge: [
|
|
481
|
+
{ value: 'active', labelID: 'Aktif', labelEN: 'Active', color: 'success' },
|
|
482
|
+
{ value: 'inactive', labelID: 'Nonaktif', labelEN: 'Inactive', color: 'danger' },
|
|
483
|
+
],
|
|
484
|
+
},
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
key: 'action',
|
|
488
|
+
labelID: 'Aksi', labelEN: 'Actions',
|
|
489
|
+
custom: {
|
|
490
|
+
type: 'ACTION',
|
|
491
|
+
actionCustom: [
|
|
492
|
+
{
|
|
493
|
+
permission: 'EDIT',
|
|
494
|
+
propsActionCustom: {
|
|
495
|
+
labelID: 'Edit', labelEN: 'Edit',
|
|
496
|
+
icon: 'SquarePen', actionType: 'edit', bgColor: 'primary',
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
permission: 'DELETE',
|
|
501
|
+
requireConfirm: true,
|
|
502
|
+
propCustomMessage: {
|
|
503
|
+
titleID: 'Hapus Data', titleEN: 'Delete',
|
|
504
|
+
messageID: 'Yakin ingin menghapus?', messageEN: 'Are you sure?',
|
|
505
|
+
},
|
|
506
|
+
propsActionCustom: {
|
|
507
|
+
labelID: 'Hapus', labelEN: 'Delete',
|
|
508
|
+
icon: 'Trash2', actionType: 'delete', bgColor: 'red',
|
|
509
|
+
},
|
|
510
|
+
},
|
|
511
|
+
],
|
|
512
|
+
},
|
|
513
|
+
},
|
|
514
|
+
],
|
|
515
|
+
filters: [
|
|
516
|
+
{
|
|
517
|
+
seq: 1, model: 'name', labelID: 'Nama', labelEN: 'Name', type: 'TEXT',
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
seq: 2, model: 'status', labelID: 'Status', labelEN: 'Status', type: 'SELECT',
|
|
521
|
+
propsFilters: {
|
|
522
|
+
items: [
|
|
523
|
+
{ value: 'active', label: 'Active' },
|
|
524
|
+
{ value: 'inactive', label: 'Inactive' },
|
|
525
|
+
],
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
],
|
|
529
|
+
actionGlobal: [
|
|
530
|
+
{
|
|
531
|
+
permission: 'CREATE',
|
|
532
|
+
propsActionGlobal: {
|
|
533
|
+
labelID: 'Tambah', labelEN: 'Add New',
|
|
534
|
+
icon: 'Plus', variant: 'default',
|
|
535
|
+
route: '/users/create',
|
|
536
|
+
},
|
|
537
|
+
},
|
|
538
|
+
],
|
|
539
|
+
pagination: true,
|
|
540
|
+
}
|
|
541
|
+
</script>
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
### Pola 2 — Static Data (consumer fetch di luar)
|
|
547
|
+
|
|
548
|
+
Pakai ketika consumer sudah fetch data sendiri dan ingin sekadar menampilkan tabel.
|
|
549
|
+
|
|
550
|
+
```vue
|
|
551
|
+
<template>
|
|
552
|
+
<DCodeDataTable
|
|
553
|
+
:columns="columns"
|
|
554
|
+
:data="users"
|
|
555
|
+
:loading="isLoading"
|
|
556
|
+
has-actions
|
|
557
|
+
ignore-permissions
|
|
558
|
+
@action="handleAction"
|
|
559
|
+
/>
|
|
560
|
+
</template>
|
|
561
|
+
|
|
562
|
+
<script setup lang="ts">
|
|
563
|
+
import { ref, onMounted } from 'vue'
|
|
564
|
+
import axios from '@/lib/axios'
|
|
565
|
+
|
|
566
|
+
const users = ref([])
|
|
567
|
+
const isLoading = ref(false)
|
|
568
|
+
|
|
569
|
+
onMounted(async () => {
|
|
570
|
+
isLoading.value = true
|
|
571
|
+
const { data } = await axios.get('/api/users')
|
|
572
|
+
users.value = data.data
|
|
573
|
+
isLoading.value = false
|
|
574
|
+
})
|
|
575
|
+
|
|
576
|
+
const columns = [
|
|
577
|
+
{ key: 'no', label: 'No', align: 'center' },
|
|
578
|
+
{ key: 'name', label: 'Nama', align: 'left' },
|
|
579
|
+
{ key: 'email', label: 'Email', align: 'left' },
|
|
580
|
+
]
|
|
581
|
+
</script>
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
---
|
|
585
|
+
|
|
586
|
+
### Pola 3 — Realtime Socket (consumer kelola socket)
|
|
587
|
+
|
|
588
|
+
Consumer connect ke WebSocket sendiri, push data ke tabel melalui `:data`.
|
|
589
|
+
|
|
590
|
+
```vue
|
|
591
|
+
<template>
|
|
592
|
+
<DCodeDataTable :columns="columns" :data="realtimeData" ignore-permissions />
|
|
593
|
+
</template>
|
|
594
|
+
|
|
595
|
+
<script setup lang="ts">
|
|
596
|
+
import { ref, onMounted, onUnmounted } from 'vue'
|
|
597
|
+
import { io } from 'socket.io-client'
|
|
598
|
+
|
|
599
|
+
const realtimeData = ref([])
|
|
600
|
+
let socket: any = null
|
|
601
|
+
|
|
602
|
+
onMounted(() => {
|
|
603
|
+
socket = io('wss://your-server.com', {
|
|
604
|
+
auth: { token: localStorage.getItem('token') }
|
|
605
|
+
})
|
|
606
|
+
socket.emit('dashboard:list', { page: 1, perPage: 10 })
|
|
607
|
+
socket.on('dashboard:result', (res: any) => {
|
|
608
|
+
realtimeData.value = res.data ?? res
|
|
609
|
+
})
|
|
610
|
+
})
|
|
611
|
+
|
|
612
|
+
onUnmounted(() => socket?.disconnect())
|
|
613
|
+
</script>
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
---
|
|
617
|
+
|
|
618
|
+
### Format Response yang Didukung
|
|
619
|
+
|
|
620
|
+
Component secara otomatis mendeteksi berbagai format response API:
|
|
621
|
+
|
|
622
|
+
```json
|
|
623
|
+
{ "data": [], "totalData": 100 } ✅ (disarankan)
|
|
624
|
+
{ "data": [], "maxPage": 10 } ✅
|
|
625
|
+
{ "items": [], "total": 100 } ✅
|
|
626
|
+
{ "list": [], "total": 100 } ✅
|
|
627
|
+
{ "rows": [], "count": 100 } ✅
|
|
628
|
+
{ "result": [], "total": 100 } ✅
|
|
629
|
+
[] ✅ (array langsung)
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
---
|
|
633
|
+
|
|
634
|
+
### Expose Methods (via `ref`)
|
|
635
|
+
|
|
636
|
+
```typescript
|
|
637
|
+
const tableRef = ref()
|
|
638
|
+
|
|
639
|
+
tableRef.value.fetchData() // Refresh data (panggil ulang fetchHandler)
|
|
640
|
+
tableRef.value.handleRefresh() // Reset filter & refresh
|
|
641
|
+
tableRef.value.resetFilters() // Reset nilai filter saja (tanpa fetch)
|
|
642
|
+
console.log(tableRef.value.filters) // Reactive nilai filter saat ini
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
```vue
|
|
646
|
+
<DCodeDataTable ref="tableRef" :fetch-handler="fetchUsers" ... />
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
---
|
|
650
|
+
|
|
382
651
|
## DCodeAutoComplete – Komponen dengan API
|
|
383
652
|
|
|
384
653
|
`DCodeAutoComplete` adalah komponen autocomplete yang bisa **langsung fetch data dari API** menggunakan konfigurasi yang sudah di-set di host project.
|
|
@@ -1669,31 +1938,6 @@ Date picker atau date range picker dengan berbagai format.
|
|
|
1669
1938
|
|
|
1670
1939
|
---
|
|
1671
1940
|
|
|
1672
|
-
### `DCodeDateRangePicker`
|
|
1673
|
-
|
|
1674
|
-
Date range picker sederhana berbasis popover input.
|
|
1675
|
-
|
|
1676
|
-
| Prop | Tipe | Default | Deskripsi |
|
|
1677
|
-
|------|------|---------|-----------|
|
|
1678
|
-
| `modelValue` | `{ start, end }\|null` | — | Range tanggal (v-model) |
|
|
1679
|
-
| `placeholder` | `string` | `'YYYY-MM-DD - YYYY-MM-DD'` | Placeholder |
|
|
1680
|
-
| `disabled` | `boolean` | `false` | Nonaktifkan |
|
|
1681
|
-
| `clearable` | `boolean` | `true` | Tombol clear |
|
|
1682
|
-
| `returnType` | `'date'\|'iso'\|'yyyy-mm-dd'` | `'yyyy-mm-dd'` | Format return |
|
|
1683
|
-
| `requireBoth` | `boolean` | `false` | Wajib isi keduanya |
|
|
1684
|
-
|
|
1685
|
-
```vue
|
|
1686
|
-
<template>
|
|
1687
|
-
<DCodeDateRangePicker
|
|
1688
|
-
v-model="form.periode"
|
|
1689
|
-
placeholder="Pilih periode..."
|
|
1690
|
-
return-type="yyyy-mm-dd"
|
|
1691
|
-
/>
|
|
1692
|
-
</template>
|
|
1693
|
-
```
|
|
1694
|
-
|
|
1695
|
-
---
|
|
1696
|
-
|
|
1697
1941
|
### `DCodeCurrencyField`
|
|
1698
1942
|
|
|
1699
1943
|
Input angka dengan format mata uang otomatis.
|