@gemafajarramadhan/dynamic-ui 1.1.28 → 1.1.29
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 -0
- package/dist/dynamic-ui.css +2 -2
- package/dist/dynamic-ui.es.js +37400 -37457
- package/dist/dynamic-ui.umd.js +1719 -1719
- package/package.json +1 -1
- 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)
|
|
@@ -379,6 +386,269 @@ Kemudian gunakan di page atau component manapun:
|
|
|
379
386
|
|
|
380
387
|
---
|
|
381
388
|
|
|
389
|
+
## DCodeDataTable – Tabel Dinamis
|
|
390
|
+
|
|
391
|
+
`DCodeDataTable` adalah komponen tabel dinamis yang mendukung **pagination server-side**, **sorting**, **filtering**, **action buttons**, dan **badge kondisional** — seluruhnya dikonfigurasi via JSON schema.
|
|
392
|
+
|
|
393
|
+
Komponen ini dirancang sebagai **micro-frontend**: consumer bertanggung jawab penuh atas HTTP client, auth token, dan sistem permission.
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
### Props Utama
|
|
398
|
+
|
|
399
|
+
| Prop | Tipe | Default | Deskripsi |
|
|
400
|
+
|------|------|---------|-----------|
|
|
401
|
+
| `table-config` | `Object` | — | Config JSON (kolom, filter, action, pagination) |
|
|
402
|
+
| `fetch-handler` | `(params) => Promise<any>` | — | **[MFE]** Consumer kontrol penuh fetch. Component tidak hit endpoint sama sekali. |
|
|
403
|
+
| `http-client` | `({ url, method, data }) => Promise<any>` | — | **[MFE]** Axios instance consumer untuk action tombol row/header (DELETE, PATCH, dll.) |
|
|
404
|
+
| `action-access-checker` | `(path, action) => boolean` | `() => true` | **[MFE]** Fungsi RBAC dari consumer. Default: semua action allow. |
|
|
405
|
+
| `ignore-permissions` | `boolean` | `false` | Matikan filter permission sepenuhnya |
|
|
406
|
+
| `data` | `any[]` | `[]` | Data statis (tanpa API); pakai jika consumer sudah fetch di luar |
|
|
407
|
+
| `loading` | `boolean` | `false` | Loading state untuk mode data statis |
|
|
408
|
+
| `columns` | `TableColumn[]` | `[]` | Kolom manual (tanpa table-config) |
|
|
409
|
+
| `per-page` | `number` | `10` | Jumlah baris per halaman awal |
|
|
410
|
+
| `show-pagination` | `boolean` | `true` | Tampilkan pagination |
|
|
411
|
+
| `has-actions` | `boolean` | `false` | Tampilkan kolom aksi (untuk mode kolom manual) |
|
|
412
|
+
| `api-url` | `string` | — | URL endpoint langsung (tanpa table-config) |
|
|
413
|
+
| `api-method` | `string` | `'POST'` | HTTP method untuk apiUrl |
|
|
414
|
+
| `api-params` | `object` | `{}` | Parameter tetap yang selalu disertakan di setiap request |
|
|
415
|
+
|
|
416
|
+
### Events
|
|
417
|
+
|
|
418
|
+
| Event | Payload | Deskripsi |
|
|
419
|
+
|-------|---------|-----------|
|
|
420
|
+
| `@action` | `{ action, row, selection? }` | Dipanggil saat tombol action diklik |
|
|
421
|
+
| `@update:selection` | `any[]` | Dipanggil saat checkbox selection berubah |
|
|
422
|
+
| `@update:page` | `number` | Dipanggil saat halaman berganti |
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
### Pola 1 — `fetchHandler` ⭐ Disarankan untuk MFE
|
|
427
|
+
|
|
428
|
+
Consumer kontrol penuh HTTP. Component tidak hit endpoint sama sekali — cocok untuk menghindari error 401.
|
|
429
|
+
|
|
430
|
+
```vue
|
|
431
|
+
<template>
|
|
432
|
+
<DCodeDataTable
|
|
433
|
+
:table-config="tableConfig"
|
|
434
|
+
:fetch-handler="fetchUsers"
|
|
435
|
+
:http-client="httpClient"
|
|
436
|
+
:action-access-checker="checkPermission"
|
|
437
|
+
@action="handleAction"
|
|
438
|
+
/>
|
|
439
|
+
</template>
|
|
440
|
+
|
|
441
|
+
<script setup lang="ts">
|
|
442
|
+
import { DCodeDataTable } from '@gemafajarramadhan/dynamic-ui'
|
|
443
|
+
import axios from '@/lib/axios' // axios instance consumer — interceptor token sudah terpasang
|
|
444
|
+
|
|
445
|
+
// 1. fetchHandler: dipanggil tiap page/filter/sort/search change
|
|
446
|
+
// params: { page, perPage, keyword?, ...filters }
|
|
447
|
+
const fetchUsers = async (params: Record<string, any>) => {
|
|
448
|
+
const { data } = await axios.post('/api/users/list', params)
|
|
449
|
+
return data
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// 2. httpClient: untuk call dari tombol action row (delete, toggle, dll.)
|
|
453
|
+
const httpClient = async ({ url, method, data }: any) => {
|
|
454
|
+
const res = await axios({ url, method, data })
|
|
455
|
+
return res.data
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// 3. Permission checker dari sistem RBAC consumer
|
|
459
|
+
const checkPermission = (path: string, action: string): boolean => {
|
|
460
|
+
return useAuthStore().can(`${path}:${action}`)
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// 4. Handle action event dari tabel
|
|
464
|
+
const handleAction = ({ action, row, selection }: any) => {
|
|
465
|
+
if (action === 'edit') router.push(`/users/${row.id}/edit`)
|
|
466
|
+
if (action === 'delete') deleteUser(row.id)
|
|
467
|
+
if (action === 'export') exportSelected(selection)
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// 5. Konfigurasi tabel via JSON schema
|
|
471
|
+
const tableConfig = {
|
|
472
|
+
headers: [
|
|
473
|
+
{ key: 'no', labelID: 'No', labelEN: 'No', align: 'CENTER' },
|
|
474
|
+
{ key: 'name', labelID: 'Nama', labelEN: 'Name', align: 'LEFT' },
|
|
475
|
+
{ key: 'email', labelID: 'Email', labelEN: 'Email', align: 'LEFT' },
|
|
476
|
+
{
|
|
477
|
+
key: 'status',
|
|
478
|
+
labelID: 'Status', labelEN: 'Status',
|
|
479
|
+
custom: {
|
|
480
|
+
type: 'BADGE',
|
|
481
|
+
conditionBadge: [
|
|
482
|
+
{ value: 'active', labelID: 'Aktif', labelEN: 'Active', color: 'success' },
|
|
483
|
+
{ value: 'inactive', labelID: 'Nonaktif', labelEN: 'Inactive', color: 'danger' },
|
|
484
|
+
],
|
|
485
|
+
},
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
key: 'action',
|
|
489
|
+
labelID: 'Aksi', labelEN: 'Actions',
|
|
490
|
+
custom: {
|
|
491
|
+
type: 'ACTION',
|
|
492
|
+
actionCustom: [
|
|
493
|
+
{
|
|
494
|
+
permission: 'EDIT',
|
|
495
|
+
propsActionCustom: {
|
|
496
|
+
labelID: 'Edit', labelEN: 'Edit',
|
|
497
|
+
icon: 'SquarePen', actionType: 'edit', bgColor: 'primary',
|
|
498
|
+
},
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
permission: 'DELETE',
|
|
502
|
+
requireConfirm: true,
|
|
503
|
+
propCustomMessage: {
|
|
504
|
+
titleID: 'Hapus Data', titleEN: 'Delete',
|
|
505
|
+
messageID: 'Yakin ingin menghapus?', messageEN: 'Are you sure?',
|
|
506
|
+
},
|
|
507
|
+
propsActionCustom: {
|
|
508
|
+
labelID: 'Hapus', labelEN: 'Delete',
|
|
509
|
+
icon: 'Trash2', actionType: 'delete', bgColor: 'red',
|
|
510
|
+
},
|
|
511
|
+
},
|
|
512
|
+
],
|
|
513
|
+
},
|
|
514
|
+
},
|
|
515
|
+
],
|
|
516
|
+
filters: [
|
|
517
|
+
{
|
|
518
|
+
seq: 1, model: 'name', labelID: 'Nama', labelEN: 'Name', type: 'TEXT',
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
seq: 2, model: 'status', labelID: 'Status', labelEN: 'Status', type: 'SELECT',
|
|
522
|
+
propsFilters: {
|
|
523
|
+
items: [
|
|
524
|
+
{ value: 'active', label: 'Active' },
|
|
525
|
+
{ value: 'inactive', label: 'Inactive' },
|
|
526
|
+
],
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
],
|
|
530
|
+
actionGlobal: [
|
|
531
|
+
{
|
|
532
|
+
permission: 'CREATE',
|
|
533
|
+
propsActionGlobal: {
|
|
534
|
+
labelID: 'Tambah', labelEN: 'Add New',
|
|
535
|
+
icon: 'Plus', variant: 'default',
|
|
536
|
+
route: '/users/create',
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
],
|
|
540
|
+
pagination: true,
|
|
541
|
+
}
|
|
542
|
+
</script>
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
---
|
|
546
|
+
|
|
547
|
+
### Pola 2 — Static Data (consumer fetch di luar)
|
|
548
|
+
|
|
549
|
+
Pakai ketika consumer sudah fetch data sendiri dan ingin sekadar menampilkan tabel.
|
|
550
|
+
|
|
551
|
+
```vue
|
|
552
|
+
<template>
|
|
553
|
+
<DCodeDataTable
|
|
554
|
+
:columns="columns"
|
|
555
|
+
:data="users"
|
|
556
|
+
:loading="isLoading"
|
|
557
|
+
has-actions
|
|
558
|
+
ignore-permissions
|
|
559
|
+
@action="handleAction"
|
|
560
|
+
/>
|
|
561
|
+
</template>
|
|
562
|
+
|
|
563
|
+
<script setup lang="ts">
|
|
564
|
+
import { ref, onMounted } from 'vue'
|
|
565
|
+
import axios from '@/lib/axios'
|
|
566
|
+
|
|
567
|
+
const users = ref([])
|
|
568
|
+
const isLoading = ref(false)
|
|
569
|
+
|
|
570
|
+
onMounted(async () => {
|
|
571
|
+
isLoading.value = true
|
|
572
|
+
const { data } = await axios.get('/api/users')
|
|
573
|
+
users.value = data.data
|
|
574
|
+
isLoading.value = false
|
|
575
|
+
})
|
|
576
|
+
|
|
577
|
+
const columns = [
|
|
578
|
+
{ key: 'no', label: 'No', align: 'center' },
|
|
579
|
+
{ key: 'name', label: 'Nama', align: 'left' },
|
|
580
|
+
{ key: 'email', label: 'Email', align: 'left' },
|
|
581
|
+
]
|
|
582
|
+
</script>
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
### Pola 3 — Realtime Socket (consumer kelola socket)
|
|
588
|
+
|
|
589
|
+
Consumer connect ke WebSocket sendiri, push data ke tabel melalui `:data`.
|
|
590
|
+
|
|
591
|
+
```vue
|
|
592
|
+
<template>
|
|
593
|
+
<DCodeDataTable :columns="columns" :data="realtimeData" ignore-permissions />
|
|
594
|
+
</template>
|
|
595
|
+
|
|
596
|
+
<script setup lang="ts">
|
|
597
|
+
import { ref, onMounted, onUnmounted } from 'vue'
|
|
598
|
+
import { io } from 'socket.io-client'
|
|
599
|
+
|
|
600
|
+
const realtimeData = ref([])
|
|
601
|
+
let socket: any = null
|
|
602
|
+
|
|
603
|
+
onMounted(() => {
|
|
604
|
+
socket = io('wss://your-server.com', {
|
|
605
|
+
auth: { token: localStorage.getItem('token') }
|
|
606
|
+
})
|
|
607
|
+
socket.emit('dashboard:list', { page: 1, perPage: 10 })
|
|
608
|
+
socket.on('dashboard:result', (res: any) => {
|
|
609
|
+
realtimeData.value = res.data ?? res
|
|
610
|
+
})
|
|
611
|
+
})
|
|
612
|
+
|
|
613
|
+
onUnmounted(() => socket?.disconnect())
|
|
614
|
+
</script>
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
---
|
|
618
|
+
|
|
619
|
+
### Format Response yang Didukung
|
|
620
|
+
|
|
621
|
+
Component secara otomatis mendeteksi berbagai format response API:
|
|
622
|
+
|
|
623
|
+
```json
|
|
624
|
+
{ "data": [], "totalData": 100 } ✅ (disarankan)
|
|
625
|
+
{ "data": [], "maxPage": 10 } ✅
|
|
626
|
+
{ "items": [], "total": 100 } ✅
|
|
627
|
+
{ "list": [], "total": 100 } ✅
|
|
628
|
+
{ "rows": [], "count": 100 } ✅
|
|
629
|
+
{ "result": [], "total": 100 } ✅
|
|
630
|
+
[] ✅ (array langsung)
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
635
|
+
### Expose Methods (via `ref`)
|
|
636
|
+
|
|
637
|
+
```typescript
|
|
638
|
+
const tableRef = ref()
|
|
639
|
+
|
|
640
|
+
tableRef.value.fetchData() // Refresh data (panggil ulang fetchHandler)
|
|
641
|
+
tableRef.value.handleRefresh() // Reset filter & refresh
|
|
642
|
+
tableRef.value.resetFilters() // Reset nilai filter saja (tanpa fetch)
|
|
643
|
+
console.log(tableRef.value.filters) // Reactive nilai filter saat ini
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
```vue
|
|
647
|
+
<DCodeDataTable ref="tableRef" :fetch-handler="fetchUsers" ... />
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
---
|
|
651
|
+
|
|
382
652
|
## DCodeAutoComplete – Komponen dengan API
|
|
383
653
|
|
|
384
654
|
`DCodeAutoComplete` adalah komponen autocomplete yang bisa **langsung fetch data dari API** menggunakan konfigurasi yang sudah di-set di host project.
|