@fui-org/fui-cli 1.3.2 → 2.0.0

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.
Files changed (111) hide show
  1. package/README.md +19 -3
  2. package/dist/fui-bmg5pnmq.js +379 -0
  3. package/dist/fui.js +1 -1
  4. package/package.json +3 -6
  5. package/skills/fui/SKILL.md +9 -41
  6. package/skills/fui-skill/SKILL.md +95 -225
  7. package/skills/fui-skill/assets/projectdefaultstyle-3.0.css +555 -0
  8. package/skills/fui-skill/assets/projectdefaultstyle.css +207 -235
  9. package/skills/fui-skill/references/INDEX.md +105 -137
  10. package/skills/fui-skill/references/advanced-techniques.md +76 -68
  11. package/skills/fui-skill/references/coding-standards.md +56 -56
  12. package/skills/fui-skill/references/component-design.md +166 -173
  13. package/skills/fui-skill/references/component-quickref.md +61 -60
  14. package/skills/fui-skill/references/component-table.md +128 -117
  15. package/skills/fui-skill/references/components-dialog.md +55 -56
  16. package/skills/fui-skill/references/components-display.md +24 -30
  17. package/skills/fui-skill/references/components-echart.md +186 -261
  18. package/skills/fui-skill/references/components-input.md +72 -96
  19. package/skills/fui-skill/references/controls-patterns.md +196 -342
  20. package/skills/fui-skill/references/controls-styling-vocabulary.md +130 -97
  21. package/skills/fui-skill/references/db-table-design.md +24 -28
  22. package/skills/fui-skill/references/db-workflow.md +191 -390
  23. package/skills/fui-skill/references/default-function.md +169 -128
  24. package/skills/fui-skill/references/design-modes.md +35 -63
  25. package/skills/fui-skill/references/echart-templates.md +204 -196
  26. package/skills/fui-skill/references/fastproject.md +62 -60
  27. package/skills/fui-skill/references/fsheet.md +109 -124
  28. package/skills/fui-skill/references/fullstack-workflow.md +90 -128
  29. package/skills/fui-skill/references/module-data-patterns.md +31 -40
  30. package/skills/fui-skill/references/module-json-anatomy.md +47 -52
  31. package/skills/fui-skill/references/module-structure.md +80 -196
  32. package/skills/fui-skill/references/new-session.md +49 -51
  33. package/skills/fui-skill/references/pdfmake.md +17 -17
  34. package/skills/fui-skill/references/permission-system.md +89 -108
  35. package/skills/fui-skill/references/platform-architecture.md +128 -153
  36. package/skills/fui-skill/references/project-config.md +102 -134
  37. package/skills/fui-skill/references/project-provisioning.md +139 -244
  38. package/skills/fui-skill/references/script-map.md +208 -242
  39. package/skills/fui-skill/references/sql-clr-functions.md +98 -97
  40. package/skills/fui-skill/references/system-design.md +63 -88
  41. package/skills/fui-skill/references/tapi-file-api.md +46 -52
  42. package/skills/fui-skill/references/tapi-permission-patterns.md +51 -53
  43. package/skills/fui-skill/references/tapi-reference.md +132 -207
  44. package/skills/fui-skill/references/tools-registry.md +84 -460
  45. package/skills/fui-skill/references/ui-crosswindow-patterns.md +79 -75
  46. package/skills/fui-skill/references/ui-dialog-patterns.md +98 -72
  47. package/skills/fui-skill/references/ui-layout-patterns.md +26 -26
  48. package/skills/fui-skill/references/ui-patterns.md +71 -83
  49. package/skills/fui-skill/references/ui-screenshot-review.md +63 -62
  50. package/skills/fui-skill/references/ui-table-cell-patterns.md +61 -59
  51. package/skills/fui-skill/references/ui-templates.md +16 -23
  52. package/skills/fui-skill/references/verification.md +236 -246
  53. package/skills/fui-skill/references/watcher-patterns.md +30 -63
  54. package/skills/fui-skill/references/websocket-realtime.md +83 -66
  55. package/skills/fui-skill/scripts/component-3.0.js +298 -131
  56. package/skills/fui-skill/scripts/component.js +277 -271
  57. package/skills/fui-skill/scripts/componentTable-3.0.js +182 -53
  58. package/skills/fui-skill/scripts/componentTable.js +171 -49
  59. package/skills/fui-skill/scripts/defaultfunction-3.0.js +88 -3
  60. package/skills/fui-skill/scripts/defaultfunction.js +88 -3
  61. package/skills/fui-skill/scripts/fsheet.js +38 -0
  62. package/dist/fui-y8an39cn.js +0 -420
  63. package/skills/fui-skill/README.md +0 -112
  64. package/skills/fui-skill/metadata.json +0 -75
  65. package/skills/fui-skill-cli/SKILL.md +0 -139
  66. package/skills/fui-skill-cli/references/INDEX.md +0 -110
  67. package/skills/fui-skill-cli/references/advanced-techniques.md +0 -168
  68. package/skills/fui-skill-cli/references/coding-standards.md +0 -112
  69. package/skills/fui-skill-cli/references/component-design.md +0 -448
  70. package/skills/fui-skill-cli/references/component-quickref.md +0 -78
  71. package/skills/fui-skill-cli/references/component-table.md +0 -248
  72. package/skills/fui-skill-cli/references/components-dialog.md +0 -191
  73. package/skills/fui-skill-cli/references/components-display.md +0 -141
  74. package/skills/fui-skill-cli/references/components-echart.md +0 -316
  75. package/skills/fui-skill-cli/references/components-input.md +0 -335
  76. package/skills/fui-skill-cli/references/controls-patterns.md +0 -701
  77. package/skills/fui-skill-cli/references/controls-styling-vocabulary.md +0 -137
  78. package/skills/fui-skill-cli/references/db-table-design.md +0 -73
  79. package/skills/fui-skill-cli/references/db-workflow.md +0 -288
  80. package/skills/fui-skill-cli/references/default-function.md +0 -425
  81. package/skills/fui-skill-cli/references/design-modes.md +0 -57
  82. package/skills/fui-skill-cli/references/echart-templates.md +0 -489
  83. package/skills/fui-skill-cli/references/fastproject.md +0 -99
  84. package/skills/fui-skill-cli/references/fsheet.md +0 -203
  85. package/skills/fui-skill-cli/references/fullstack-workflow.md +0 -313
  86. package/skills/fui-skill-cli/references/module-data-patterns.md +0 -117
  87. package/skills/fui-skill-cli/references/module-json-anatomy.md +0 -132
  88. package/skills/fui-skill-cli/references/module-structure.md +0 -141
  89. package/skills/fui-skill-cli/references/new-session.md +0 -85
  90. package/skills/fui-skill-cli/references/pdfmake.md +0 -60
  91. package/skills/fui-skill-cli/references/permission-system.md +0 -150
  92. package/skills/fui-skill-cli/references/platform-architecture.md +0 -269
  93. package/skills/fui-skill-cli/references/project-config.md +0 -303
  94. package/skills/fui-skill-cli/references/project-provisioning.md +0 -278
  95. package/skills/fui-skill-cli/references/script-map.md +0 -262
  96. package/skills/fui-skill-cli/references/sql-clr-functions.md +0 -225
  97. package/skills/fui-skill-cli/references/system-design.md +0 -89
  98. package/skills/fui-skill-cli/references/tapi-file-api.md +0 -185
  99. package/skills/fui-skill-cli/references/tapi-permission-patterns.md +0 -156
  100. package/skills/fui-skill-cli/references/tapi-reference.md +0 -474
  101. package/skills/fui-skill-cli/references/tools-registry.md +0 -84
  102. package/skills/fui-skill-cli/references/ui-crosswindow-patterns.md +0 -321
  103. package/skills/fui-skill-cli/references/ui-dialog-patterns.md +0 -255
  104. package/skills/fui-skill-cli/references/ui-layout-patterns.md +0 -176
  105. package/skills/fui-skill-cli/references/ui-patterns.md +0 -303
  106. package/skills/fui-skill-cli/references/ui-screenshot-review.md +0 -95
  107. package/skills/fui-skill-cli/references/ui-table-cell-patterns.md +0 -318
  108. package/skills/fui-skill-cli/references/ui-templates.md +0 -22
  109. package/skills/fui-skill-cli/references/verification.md +0 -236
  110. package/skills/fui-skill-cli/references/watcher-patterns.md +0 -163
  111. package/skills/fui-skill-cli/references/websocket-realtime.md +0 -271
@@ -1,77 +1,78 @@
1
1
  # FUI Component Quick Reference
2
2
 
3
- > File này sở hữu: **danh mục component FUI, bảng component cần import JS/CSS, quy trình thêm/bỏ import**. Chi tiết từng component xem file reference tương ứng ở cột phải.
3
+ > Owns: **FUI component catalog, components needing JS/CSS imports, add/remove import workflow**. Per-component details: file in the right column.
4
4
 
5
- Tra cứu nhanh toàn bộ component có sẵn trong FUI runtime. Ưu tiên dùng `f-*` trước — chỉ dùng `v-*` khi không có FUI equivalent.
5
+ Prefer `f-*`; use `v-*` only when no FUI equivalent exists.
6
6
 
7
- | Component | Dùng khi nào | Reference |
8
- |---|---|---|
9
- | `f-table` | **Hiển thị dữ liệu dạng datatable** — cả CRUD qua dialog form lẫn chỉ xem (readonly = không khai `:update-api`); auto-build headers khi không truyền `:headers`; hàng tổng qua `sum-format` | [component-table.md](component-table.md) |
10
- | `f-dialog` | Modal dialog với form, watch, button | [components-dialog.md](components-dialog.md) |
11
- | `f-window` | Dialog mở URL trong iframe | [components-dialog.md](components-dialog.md) |
12
- | `f-button` | Nút bấm có action, hotkey, form validation | [components-input.md](components-input.md) |
13
- | `f-date` | Input ngày có date picker + typed mask | [components-input.md](components-input.md) |
14
- | `f-time` | Input giờ có time picker + typed mask | [components-input.md](components-input.md) |
15
- | `f-time-counter` | Đếm ngược / đồng hồ | [components-input.md](components-input.md) |
16
- | `f-search` | Autocomplete tìm kiếm qua API | [components-input.md](components-input.md) |
17
- | `f-menu` | Dropdown button menu có icon/action/link | [components-input.md](components-input.md) |
18
- | `f-radiobox` | Radio group từ array items | [components-input.md](components-input.md) |
19
- | `f-file-upload` | Upload file (Plupload, progress dialog) | [components-input.md](components-input.md) |
20
- | `f-image-update` | Upload + crop ảnh | [components-input.md](components-input.md) |
21
- | `f-excel-reader` | Đọc file Excel/CSV → JSON (chọn sheet, bỏ N dòng đầu, tự đặt tên cột) | [components-input.md](components-input.md) |
22
- | `f-qrcode` | Render mã QR | [components-input.md](components-input.md) |
23
- | `f-qrcode-reader` | Đọc QR bằng camera | [components-input.md](components-input.md) |
24
- | `f-editor` | Rich text editor (CKEditor 5) | [components-dialog.md](components-dialog.md) |
25
- | `f-editor-dialog` | Rich text editor trong modal | [components-dialog.md](components-dialog.md) |
26
- | `f-echart` | **Biểu đồ** — ECharts V5: bar, line, pie, scatter, gauge, radar, heatmap, sankey, tree, map, graph... | [components-echart.md](components-echart.md) · [echart-templates.md](echart-templates.md) |
27
- | `f-sheet` | **Nhập liệu trực tiếp trên bảng kiểu Excel** — sửa ô tại chỗ, dán từ Excel, không qua dialog (dựa trên AG Grid) — **cần import** | [fsheet.md](fsheet.md) |
28
- | `f-pdfmake` | Render PDF trong iframe | [components-display.md](components-display.md) · [pdfmake.md](pdfmake.md) |
29
- | `f-label` | Chip/badge hiển thị tag, trạng thái | [components-display.md](components-display.md) |
30
- | `f-box` | Hiển thị/chỉnh sửa key-value rows | [components-display.md](components-display.md) |
31
- | `f-header` | Tiêu đề lớn (display-1, primary color) | [components-display.md](components-display.md) |
32
- | `f-title` | Tiêu đề nhỏ (title, primary color) | [components-display.md](components-display.md) |
33
- | `f-slider` | Carousel ảnh | [components-display.md](components-display.md) |
34
- | `fp-profile` | Khối thông tin/hồ sơ user | [components-display.md](components-display.md) |
7
+ | Component | Use for | Reference |
8
+ | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
9
+ | `f-table` | **Any datatable** — CRUD via dialog form or view-only (readonly = omit `:update-api`); auto-builds headers when `:headers` omitted; totals row via `sum-format` | [component-table.md](component-table.md) |
10
+ | `f-dialog` | Modal with form, watch, buttons | [components-dialog.md](components-dialog.md) |
11
+ | `f-window` | Dialog opening a URL in an iframe | [components-dialog.md](components-dialog.md) |
12
+ | `f-button` | Button with action, hotkey, form validation | [components-input.md](components-input.md) |
13
+ | `f-date` | Date input with picker + typed mask | [components-input.md](components-input.md) |
14
+ | `f-time` | Time input with picker + typed mask | [components-input.md](components-input.md) |
15
+ | `f-time-counter` | Countdown / clock | [components-input.md](components-input.md) |
16
+ | `f-search` | API-backed autocomplete | [components-input.md](components-input.md) |
17
+ | `f-menu` | Dropdown button menu with icon/action/link | [components-input.md](components-input.md) |
18
+ | `f-radiobox` | Radio group from items array | [components-input.md](components-input.md) |
19
+ | `f-file-upload` | File upload (Plupload, progress dialog) | [components-input.md](components-input.md) |
20
+ | `f-image-update` | Image upload + crop | [components-input.md](components-input.md) |
21
+ | `f-excel-reader` | Excel/CSV → JSON (pick sheet, skip first N rows, name columns) | [components-input.md](components-input.md) |
22
+ | `f-qrcode` | Render QR code | [components-input.md](components-input.md) |
23
+ | `f-qrcode-reader` | Read QR via camera | [components-input.md](components-input.md) |
24
+ | `f-editor` | Rich text editor (CKEditor 5) | [components-dialog.md](components-dialog.md) |
25
+ | `f-editor-dialog` | Rich text editor in a modal | [components-dialog.md](components-dialog.md) |
26
+ | `f-echart` | **Charts** — ECharts V5: bar, line, pie, scatter, gauge, radar, heatmap, sankey, tree, map, graph... | [components-echart.md](components-echart.md) · [echart-templates.md](echart-templates.md) |
27
+ | `f-sheet` | **Excel-like in-grid editing** — edit cells in place, paste from Excel, no dialog (AG Grid) — **needs import** | [fsheet.md](fsheet.md) |
28
+ | `f-pdfmake` | Render PDF in iframe | [components-display.md](components-display.md) · [pdfmake.md](pdfmake.md) |
29
+ | `f-label` | Chip/badge for tags, status | [components-display.md](components-display.md) |
30
+ | `f-box` | Display/edit key-value rows | [components-display.md](components-display.md) |
31
+ | `f-header` | Large heading (display-1, primary color) | [components-display.md](components-display.md) |
32
+ | `f-title` | Small heading (title, primary color) | [components-display.md](components-display.md) |
33
+ | `f-slider` | Image carousel | [components-display.md](components-display.md) |
34
+ | `fp-profile` | User info/profile block | [components-display.md](components-display.md) |
35
35
 
36
- ### Component trong ô bảng (`t-*`) — dùng trong `headers` của f-table
36
+ ### Table-cell components (`t-*`) — used in f-table `headers`
37
37
 
38
- `t-html` · `t-label` · `t-num` · `t-time` · `t-boolean` · `t-check` (toggle) · `t-text` · `t-select` · `t-combobox` · `t-menu` (context menu) · `t-link` · `t-button` — chi tiết & ví dụ: [ui-table-cell-patterns.md](ui-table-cell-patterns.md).
38
+ `t-html` · `t-label` · `t-num` · `t-time` · `t-boolean` · `t-check` (toggle) · `t-text` · `t-select` · `t-combobox` · `t-menu` (context menu) · `t-link` · `t-button` — details: [ui-table-cell-patterns.md](ui-table-cell-patterns.md).
39
39
 
40
- > `header-bar` và `f-window` là component nội bộ do runtime tự dựng (menu header, cửa sổ `openWindow`) — không đặt trực tiếp trong `controls`.
40
+ > `header-bar` and `f-window` are internal, runtime-built (header menu, `openWindow` window) — never place them directly in `controls`.
41
41
 
42
- ## Components cần import JS/CSS
42
+ ## Components needing JS/CSS imports
43
43
 
44
- Một số component yêu cầu import thêm thư viện — **phải gọi `file_import_list` để kiểm tra và thêm/xóa import tương ứng khi thêm hoặc bỏ component**.
44
+ **When adding or removing one of these, run `fui import list` and add/remove the matching imports.**
45
45
 
46
- | Component | Import bắt buộc |
47
- |---|---|
48
- | `f-pdfmake` | `/include/pdfmake/pdfmake.min.js` · `/include/pdfmake/print.min.js` · `/include/pdfmake/vfs_fonts.js` |
49
- | `f-file-upload` | `/include/plupload-2.3.7/plupload.full.min.js` |
50
- | `f-image-update` | `/include/vue-advanced-cropper/index.umd.js` · `/include/vue-advanced-cropper/style.css` |
51
- | `f-qrcode` | `/include/qrcode/qrcode.min.js` |
52
- | `f-qrcode-reader` | `/include/qrcode/qrcode-reader.min.js` |
53
- | `f-echart` | `/include/chart/echarts.min.js` · `/include/chart/fechart.js` (**theo thứ tự này**) — nền tảng Apache ECharts |
54
- | `f-sheet` | `/include/ag-grid/ag-grid-community.min.js` · `/include/ag-grid/fsheet.js` (**theo thứ tự này**) — nền tảng AG Grid |
55
- | `f-editor` | `/include/ckeditor5/build/ckeditor.js` |
56
- | `f-editor-dialog` | `/include/ckeditor5/build/ckeditor.js` |
46
+ | Component | Required imports |
47
+ | ----------------- | -------------------------------------------------------------------------------------------------------- |
48
+ | `f-pdfmake` | `/include/pdfmake/pdfmake.min.js` · `/include/pdfmake/print.min.js` · `/include/pdfmake/vfs_fonts.js` |
49
+ | `f-file-upload` | `/include/plupload-2.3.7/plupload.full.min.js` |
50
+ | `f-image-update` | `/include/vue-advanced-cropper/index.umd.js` · `/include/vue-advanced-cropper/style.css` |
51
+ | `f-qrcode` | `/include/qrcode/qrcode.min.js` |
52
+ | `f-qrcode-reader` | `/include/qrcode/qrcode-reader.min.js` |
53
+ | `f-echart` | `/include/chart/echarts.min.js` · `/include/chart/fechart.js` (**in this order**) — Apache ECharts |
54
+ | `f-sheet` | `/include/ag-grid/ag-grid-community.min.js` · `/include/ag-grid/fsheet.js` (**in this order**) — AG Grid |
55
+ | `f-editor` | `/include/ckeditor5/build/ckeditor.js` |
56
+ | `f-editor-dialog` | `/include/ckeditor5/build/ckeditor.js` |
57
57
 
58
- > **Bundled sẵn, KHÔNG cần import thêm:** `v-*` (Vuetify) · `f-table` · `f-dialog` · `f-button` ·
58
+ > **Bundled, NO import needed:** `v-*` (Vuetify) · `f-table` · `f-dialog` · `f-button` ·
59
59
  > `f-date` · `f-time` · `f-search` · `f-menu` · `f-radiobox` · `f-box` · `f-label` · `f-header` ·
60
- > `f-title` · `f-slider` · `f-excel-reader` — và mọi component không có tên trong bảng trên.
60
+ > `f-title` · `f-slider` · `f-excel-reader` — and any component not in the table above.
61
61
 
62
- **Quy trình khi thêm component có import:**
63
- 1. `file_import_list` (projectId + moduleId) — kiểm tra import hiện có
64
- 2. Nếu chưa có → `file_import_new` để thêm từng file
65
- 3. Nếu bỏ component → kiểm tra import đó còn dùng ở chỗ nào khác không; nếu không → `file_import_delete`
62
+ **Workflow when adding a component with imports** (see `fui import --help`):
63
+
64
+ 1. `fui import list` (project + module) — check existing imports
65
+ 2. Missing → `fui import new` for each file
66
+ 3. Removing a component → check whether the import is still used elsewhere; if not → `fui import delete`
66
67
 
67
68
  ---
68
69
 
69
- ## Quy tắc chọn nhanh
70
+ ## Quick selection rules
70
71
 
71
- - `f-button` thay `v-btn` khi cần action FUI (CALL, hotkey, form validation)
72
- - `f-date` / `f-time` thay `v-text-field` + manual date parsing
73
- - `f-search` thay `v-autocomplete` khi cần search qua API
74
- - `f-menu` thay `v-menu + v-btn` khi cần dropdown actions
75
- - `f-table` thay `v-data-table` cho MỌI bảng — CRUD lẫn chỉ xem (readonly = không khai `:update-api`)
76
- - `f-echart` cho mọi loại biểu đồ (bar, line, pie, gauge, scatter, radar, sankey, tree, map...)
77
- - Dialog: `ctrl-update` của `f-table` cho CRUD inline; dialog riêng → dựng `v-dialog` thủ công theo anatomy chuẩn (`design_read("fui")` §4 + `ui-dialog-patterns.md`); `f-dialog` chỉ cho form rất nhỏ
72
+ - `f-button` over `v-btn` when you need FUI actions (CALL, hotkey, form validation)
73
+ - `f-date` / `f-time` over `v-text-field` + manual date parsing
74
+ - `f-search` over `v-autocomplete` for API search
75
+ - `f-menu` over `v-menu + v-btn` for dropdown actions
76
+ - `f-table` over `v-data-table` for EVERY table — CRUD and view-only (readonly = omit `:update-api`)
77
+ - `f-echart` for every chart type (bar, line, pie, gauge, scatter, radar, sankey, tree, map...)
78
+ - Dialogs: `f-table` `ctrl-update` for inline CRUD; standalone dialog → hand-build `v-dialog` per the standard anatomy (`fui design read fui` §4 + `ui-dialog-patterns.md`); `f-dialog` only for very small forms
@@ -1,111 +1,106 @@
1
1
  # FUI Table Components (Source-Based)
2
2
 
3
- > File này sở hữu: **`f-table` chuyên sâu: mọi props, auto-header, `sum-format`, readonly table**. Điều khiển trong ô (`t-*`) xem [ui-table-cell-patterns.md](ui-table-cell-patterns.md).
3
+ > Owns: **`f-table` in depth: all props, auto-header, `sum-format`, Excel export (`excel`), readonly table**. In-cell controls (`t-*`): [ui-table-cell-patterns.md](ui-table-cell-patterns.md).
4
4
 
5
- This file is derived from `scripts/componentTable.js` (V2) and `scripts/componentTable-3.0.js` (V3).
6
- Focus: `f-table` and `t-*` renderers.
5
+ Source: `scripts/componentTable.js` (V2), `scripts/componentTable-3.0.js` (V3).
7
6
 
8
- > **Xác định phiên bản trước khi viết headers** — V2 và V3 dùng tên field khác nhau, sai tên thì bảng không render. Xem mục "V2 vs V3 — Sự khác biệt quan trọng" cuối file.
7
+ > **Check the version before writing headers** — V2/V3 field names differ; wrong names = no render. See "V2 vs V3" below.
9
8
 
10
- > `f-table` đảm nhận cả hai vai trò: bảng CRUD và bảng chỉ xem (readonly). Bảng chỉ xem = `f-table` không khai báo `:update-api` (hoặc thêm `:disabled-update true`); có thể bỏ luôn `:headers` để bảng tự dựng header từ dữ liệu (xem Auto Headers bên dưới).
9
+ > `f-table` does CRUD and readonly. Readonly = no `:update-api` (or `:disabled-update true`); omit `:headers` to auto-build.
11
10
 
12
11
  ## Prefix Reminder
13
12
 
14
- - `f-table`: FUI component.
15
- - `t-*`: FUI cell renderers for table columns.
16
- - `v-data-table`: Vuetify internal implementation, but CRUD and table action flow comes from FUI wrappers.
13
+ `f-table` = FUI component · `t-*` = FUI cell renderers · `v-data-table` = Vuetify internals (CRUD/action flow comes from FUI wrappers).
17
14
 
18
15
  ## f-table
19
16
 
20
17
  ### Props (exact from source)
21
18
 
22
- `value`, `headers`, `updateForm`, `updateFormAttr`, `updateApi`, `items`, `label`, `excel`, `showSearch`, `sumFormat`, `disabledHover`, `returnObject`, `itemKey`, `itemsPerPage`, `disabledUpdate`, `hideDefaultFooter`, `template`, `headercomponent`, `height`, `fixedHeader`, `fixedCols`
19
+ `value`, `headers`, `updateForm`, `updateFormAttr`, `updateApi`, `items`, `label`, `excel`, `showSearch`, `sumFormat`, `disabledHover`, `returnObject`, `itemKey`, `itemsPerPage`, `disabledUpdate`, `hideDefaultFooter`, `template`, `headercomponent`, `height`, `fixedHeader`, `fixedCols`
23
20
 
24
21
  ### Real Behavior
25
22
 
26
- 1. If a header item has `el`, table creates custom slot renderer automatically.
27
- 2. If `updateApi.new` or `updateApi['new-action']` exists, add button appears.
23
+ 1. Header item with `el` → custom slot renderer created automatically.
24
+ 2. `updateApi.new` or `updateApi['new-action']` present → add button appears.
28
25
  3. CRUD action slots rely on header `value: "ctrl-update"`.
29
- 4. Editing dialog is `f-dialog` with `updateForm`.
30
- 5. Selection result emit:
31
- - if `returnObject=false`: emit array of `itemKey`
32
- - if `returnObject=true`: emit selected row objects
33
- 6. Emits row events from slots: `click:row`, `mouseover:row`, `mouseleave:row`.
34
- 7. **Auto headers**: nếu KHÔNG truyền `:headers`, table tự build header từ `items` (xem mục Auto Headers).
35
- 8. **Sum row / sum line**: prop `sum-format` nhận string HOẶC object — hai cách render khác nhau (xem mục sum-format).
36
-
37
- ### Cố định cột bên trái (`fixed-cols`)
38
-
39
- Khai `fixed-cols="N"` để giữ N cột đầu tiên khi cuộn ngang. Tính năng có ở cả FUI V2 và V3; bỏ prop, đặt `0`, hoặc truyền giá trị không hợp lệ thì bảng hoạt động như cũ.
40
-
41
- ```json
42
- {
43
- "el": "f-table",
44
- "w": 12,
45
- "attr": {
46
- ":items": "dsNhanVien",
47
- "fixed-cols": "2",
48
- ":headers": [
49
- { "text": "Mã", "value": "Ma", "width": "100px" },
50
- { "text": "Họ tên", "value": "HoTen", "width": "220px" },
51
- { "text": "Phòng ban", "value": "PhongBan", "width": "180px" }
52
- ]
53
- }
54
- }
55
- ```
56
-
57
- - Nên khai `width` cho từng cột được cố định; nếu bỏ trống, `f-table` dùng `150px`.
58
- - `width` dạng số được hiểu là pixel; chuỗi CSS như `"120px"` vẫn được giữ nguyên.
59
- - `fixed-cols` đếm theo thứ tự cột render thực tế. Nếu bật cột chọn dòng/group của Vuetify thì các cột hệ thống đó cũng nằm trong phép đếm.
60
- - CSS được scope theo từng instance `f-table`, nên nhiều bảng có số cột cố định khác nhau có thể cùng xuất hiện trên một trang.
61
-
62
- ### Auto Headers (khi không truyền `:headers`)
63
-
64
- Khi bỏ hẳn prop `:headers`, `f-table` tự build header từ row đầu tiên của `items` (qua `buildHeader`):
65
-
66
- - Mỗi key của row → một cột `{ text: key, value: key, divider: true }`; key có giá trị số → tự gắn `el: "t-num"` (format số bên phải).
67
- - Nếu có `:update-api` với `edit`/`delete` và không `disabled-update` → tự thêm cột `ctrl-update` cuối bảng.
68
- - Headers được rebuild mỗi khi `items` đổi shape (watch trên `items`) — an toàn khi data load async.
69
-
70
- **Khi nào dùng:** bảng hiển thị nhanh, cột đúng bằng field trả về từ API (SP đã alias tên cột đẹp bằng tiếng Việt). **Khi nào KHÔNG dùng (phải khai `:headers` tường minh):** cần label khác tên field, cần ẩn bớt cột, cần `t-*` renderer tùy biến (t-time, t-check, t-link...), cần width/align cụ thể, hoặc data có field kỹ thuật (ID nội bộ, flag) không nên hiển thị.
26
+ 4. Edit dialog is `f-dialog` with `updateForm`.
27
+ 5. Selection emit: `returnObject=false` → array of `itemKey`; `returnObject=true` → selected row objects.
28
+ 6. Row events from slots: `click:row`, `mouseover:row`, `mouseleave:row`.
29
+ 7. **Auto headers**: no `:headers` → built from `items` (see Auto Headers).
30
+ 8. **Sum row / sum line**: `sum-format` takes a string OR object — rendered differently (see sum-format).
31
+ 9. **Excel button**: `excel` = `true` exports the raw data, `"UI"` exports exactly what the table shows (see Excel export).
32
+
33
+ ### Fixed left columns (`fixed-cols`)
34
+
35
+ `fixed-cols="N"` keeps the first N columns during horizontal scroll. V2 and V3. Omitted, `0`, or invalid → normal behavior.
71
36
 
72
37
  ```json
73
- { "el": "f-table", "w": "12", "attr": { "label": "Kết quả", ":items": "dsKetQua", "show-search": true } }
38
+ {
39
+ "el": "f-table",
40
+ "w": 12,
41
+ "attr": {
42
+ ":items": "dsNhanVien",
43
+ "fixed-cols": "2",
44
+ ":headers": [
45
+ { "text": "Mã", "value": "Ma", "width": "100px" },
46
+ { "text": "Họ tên", "value": "HoTen", "width": "220px" },
47
+ { "text": "Phòng ban", "value": "PhongBan", "width": "180px" }
48
+ ]
49
+ }
50
+ }
74
51
  ```
75
52
 
76
- ### sum-format — Tổng cột (2 dạng)
53
+ - Set `width` on each fixed column; missing → `150px`.
54
+ - Numeric `width` = pixels; CSS strings like `"120px"` kept as-is.
55
+ - `fixed-cols` counts actual rendered columns; Vuetify select/group columns, if enabled, are counted.
56
+ - CSS is scoped per `f-table` instance, so several tables with different fixed counts can share a page.
77
57
 
78
- Prop `sum-format` có 2 dạng, render hoàn toàn khác nhau:
58
+ ### Auto Headers (no `:headers`)
79
59
 
80
- **Dạng 1 — string template → MỘT dòng text tổng dưới bảng** (trong `v-card-actions`, KHÔNG nằm trong `v-data-table`, không thẳng cột):
60
+ With `:headers` omitted, `f-table` builds headers from the first row of `items` (via `buildHeader`):
61
+
62
+ - Each key → column `{ text: key, value: key, divider: true }`; numeric values → `el: "t-num"` (right-aligned number format).
63
+ - `:update-api` with `edit`/`delete` and no `disabled-update` → `ctrl-update` column appended.
64
+ - Rebuilt whenever `items` changes shape (watch on `items`) — safe with async loads.
65
+
66
+ **Use when** columns = API fields exactly (SP aliases nice Vietnamese names). **Declare `:headers` when** labels differ from fields, columns hidden, custom `t-*` (t-time, t-check, t-link...), specific width/align, or technical fields (internal IDs, flags) must not show.
67
+
68
+ ```json
69
+ { "el": "f-table", "w": "12", "attr": { "label": "Kết quả", ":items": "dsKetQua", "show-search": true } }
70
+ ```
71
+
72
+ ### sum-format — column totals (2 forms)
73
+
74
+ **Form 1 — string template → ONE total text line below the table** (in `v-card-actions`, NOT inside `v-data-table`, not column-aligned):
81
75
 
82
76
  ```json
83
77
  "sum-format": "Tổng đăng ký: [[DangKy]] | Nhập học: [[NhapHoc]]"
84
78
  ```
85
79
 
86
- - `[[FieldName]]` được thay bằng `_.sumBy(items, 'FieldName')` format cố định `'0,0'` (numeral).
87
- - Kết quả là 1 dòng text duy nhất, căn phải, phía dưới bảng (có `v-divider` ngăn cách).
88
- - Dùng khi: chỉ cần 1 dòng tóm tắt tổng, hoặc tổng của nhiều cột gộp chung 1 câu.
89
- - Là string tĩnh → khai báo attr KHÔNG có `:` prefix.
80
+ - `[[FieldName]]` → `_.sumBy(items, 'FieldName')`, fixed format `'0,0'` (numeral).
81
+ - Single right-aligned text line below the table (separated by `v-divider`).
82
+ - For one summary line / several totals in one sentence.
83
+ - Static string → attr WITHOUT `:` prefix.
90
84
 
91
- **Dạng 2 — object → HÀNG TỔNG thật sự trong bảng** (slot `body.append` của `v-data-table`, thẳng theo từng cột):
85
+ **Form 2 — object → REAL total row inside the table** (`v-data-table` slot `body.append`, aligned per column):
92
86
 
93
87
  ```json
94
88
  ":sum-format": { "DangKy": "0,0", "NhapHoc": "0,0", "HocPhi": "0,0.0" }
95
89
  ```
96
90
 
97
- - Key = `value` của cột trong headers; value = numeral format string riêng cho cột đó (`"0,0"`, `"0,0.0"`, `"0.0%"`, ...).
98
- - Render một `<tr>` cuối thân bảng: ô của cột có key trong object hiển thị `_.sumBy(items, key)` theo format tương ứng; các cột khác để trống. Tất cả ô căn phải, `font-weight-medium`.
99
- - Hàng tổng nằm TRONG bảng nên thẳng hàng với cột, cuộn cùng thân bảng.
100
- - Là object → khai báo attr CÓ `:` prefix.
91
+ - Key = column `value` in headers; value = numeral format for that column (`"0,0"`, `"0,0.0"`, `"0.0%"`, ...).
92
+ - Renders a final `<tr>`: cells whose column key is in the object show `_.sumBy(items, key)` in that format; others empty. All cells right-aligned, `font-weight-medium`.
93
+ - Aligned with columns, scrolls with the body.
94
+ - Object → attr WITH `:` prefix.
101
95
 
102
- **Chọn dạng nào:** user cần "hàng tổng dưới mỗi cột / dòng tổng trong bảng / tổng thẳng cột" → dạng object. User cần "dòng chữ tổng kết chung" → dạng string. **KHÔNG tự dựng hàng tổng thủ công** (không push row "Tổng" vào items, không tự viết template body.append) — dùng `sum-format`.
96
+ **Choosing:** "total row under each column / total row in table / column-aligned totals" → object. "General summary text line" → string. **NEVER build a total row manually** (no pushing a "Tổng" row into items, no hand-written body.append template) — use `sum-format`.
103
97
 
104
- Ví dụ đầy đủ dạng object:
98
+ Full object example:
105
99
 
106
100
  ```json
107
101
  {
108
- "el": "f-table", "w": "12",
102
+ "el": "f-table",
103
+ "w": "12",
109
104
  "attr": {
110
105
  "label": "Thống kê tuyển sinh",
111
106
  ":items": "dsThongKe",
@@ -119,15 +114,38 @@ Ví dụ đầy đủ dạng object:
119
114
  }
120
115
  ```
121
116
 
117
+ ### Excel export — prop `excel` (2 modes)
118
+
119
+ Excel button on the table toolbar, in both V2 and V3. **V2**: no `excel` → no button. **V3**: the prop defaults to `true`, so the button always shows; hide it with `":excel": false`.
120
+
121
+ | Value | Rows | Columns & headers | Cell values |
122
+ | -------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
123
+ | `true` _(default, old behavior)_ | **All** `items`, original order — ignores search and sorting | Every field of the **first row**, header = raw field name (`HoTen`), including IDs/technical fields not shown | Raw, dates as ISO strings |
124
+ | `"UI"` | Only rows **matching the search box**, in the **current sort order** (including `group-by`), **all pages** | Only columns declared in `headers`, same order, header = `title`/`text` (HTML stripped) | **Raw, unformatted data** — as `true` |
125
+
126
+ ```json
127
+ { "el": "f-table", "w": 12, "attr": { "label": "Danh sách", ":items": "dsHang", "excel": "UI", ":headers": [ ... ] } }
128
+ ```
129
+
130
+ - `"UI"` is a static string → **no** `:` prefix. Case-insensitive (`"ui"` works). Any other value (`true`, `"true"`, …) is the raw mode.
131
+ - **In short:** `"UI"` takes **rows and columns as displayed**, while **cell values stay raw**. User wants "export what I see / filtered / sorted" → `"UI"`. Need every field dumped (IDs, hidden fields) → `true`.
132
+
133
+ **`"UI"` details:**
134
+
135
+ - **Filtering** reuses the table's own `customSearch`, so the result matches the rows on screen. **Sorting** follows the current `v-data-table` sort state (caught via `update:options`). If the user has not clicked a column, the `sort-by`/`sort-desc` (V2) or `sort-by` (V3) from attr apply. Strings compare with `Intl.Collator`, so accented Vietnamese sorts correctly.
136
+ - **Pagination does not matter**: the file always holds every page of the filtered set. Collapsed groups (`group-by`) are exported too.
137
+ - **Dropped columns**: `ctrl-update`, system columns (`data-table-select`/`-group`/`-expand`), headers without `key`/`value`. Group headers (`children`, V3) are flattened to `Parent / Child`.
138
+ - **Column field from `v-model`**: a header with `attr["v-model"]: "item.X"` exports field `X`, even when the column `key` is another name. Filtering and sorting still use `key`/`value`, as `v-data-table` does.
139
+ - **Cell value = raw data, NOT formatted**: numbers export as plain numbers (no numFmt, zeros not hidden even with `t-num` `hidezero`), dates as the raw API string (`2026-08-15T00:00:00`, not dd/mm/yyyy), `t-html` as the raw HTML string, `t-select`/`t-check` as the raw code/value, not the label. `format` of `t-num`/`t-time` is **not** applied to the file.
140
+ - **No total row**: `sum-format` only displays on the table; the file has no total line.
141
+ - Need a pre-formatted file (numFmt, real dates, a `SUM` total row) → call `jsonToExcel` with `columns` yourself; see [default-function.md](default-function.md).
142
+ - Only the file presentation is adjusted: header row bold and frozen. Column width comes from the header's px `width` (÷7), else estimated from content. File/sheet name = `label` with HTML stripped (sheet cut to 31 characters), `tableFP` when there is no label.
143
+ - No matching rows → "Không có dòng nào đang hiển thị để xuất Excel", no empty file.
144
+ - **Selected** rows (show-select) do not matter: `"UI"` exports every displayed row, not only the selected ones.
145
+
122
146
  ### updateApi Keys Used By Source
123
147
 
124
- - `new`
125
- - `edit`
126
- - `delete`
127
- - `default-item`
128
- - `new-action`
129
- - `edit-action`
130
- - `data-out`
148
+ `new`, `edit`, `delete`, `default-item`, `new-action`, `edit-action`, `data-out`
131
149
 
132
150
  ### Minimal CRUD Example
133
151
 
@@ -177,7 +195,7 @@ Ví dụ đầy đủ dạng object:
177
195
 
178
196
  ## Readonly Table
179
197
 
180
- Bảng chỉ xem = `f-table` không có `:update-api` (không hiện nút thêm/sửa/xóa) — bỏ `:headers` nếu muốn auto-build:
198
+ `f-table` without `:update-api` (no add/edit/delete buttons); omit `:headers` to auto-build:
181
199
 
182
200
  ```json
183
201
  {
@@ -196,51 +214,35 @@ Bảng chỉ xem = `f-table` không có `:update-api` (không hiện nút thêm/
196
214
 
197
215
  ## t-* Cell Renderers
198
216
 
199
- Use in `headers` by setting `el`.
200
-
201
- Example header:
217
+ Set `el` in `headers`:
202
218
 
203
219
  ```json
204
220
  { "text": "Ngay tao", "value": "CreatedAt", "el": "t-time", "attr": { "format": "DD/MM/YYYY HH:mm" } }
205
221
  ```
206
222
 
207
- ### Supported `t-*` components
208
-
209
- - `t-html`
210
- - `t-label`
211
- - `t-num`
212
- - `t-time`
213
- - `t-boolean`
214
- - `t-check`
215
- - `t-text`
216
- - `t-select`
217
- - `t-combobox`
218
- - `t-menu`
219
- - `t-link`
220
- - `t-button`
223
+ Supported: `t-html`, `t-label`, `t-num`, `t-time`, `t-boolean`, `t-check`, `t-text`, `t-select`, `t-combobox`, `t-menu`, `t-link`, `t-button`
221
224
 
222
225
  ### Notes
223
226
 
224
227
  1. Editable renderers (`t-check`, `t-text`, `t-select`, `t-combobox`, `t-menu`, `t-button`) use `tableActionEvent`.
225
- 2. For dialog opening in row actions, use `target: "dialog"` plus `wid`, `url`, `title`, `onclose`.
226
- 3. Apply literal-string rule only in Action `IN` mapping.
227
- Static component props without `:` are plain strings by default.
228
+ 2. Opening a dialog from a row action: `target: "dialog"` plus `wid`, `url`, `title`, `onclose`.
229
+ 3. Literal-string rule applies only in Action `IN` mapping. Static props without `:` are plain strings by default.
228
230
 
229
231
  ---
230
232
 
231
- ## V2 vs V3 — Sự khác biệt quan trọng (nguồn: `componentTable.js` vs `componentTable-3.0.js`)
233
+ ## V2 vs V3 (source: `componentTable.js` vs `componentTable-3.0.js`)
232
234
 
233
- Phiên bản framework được xác định từ `_projectInfo.json` hoặc `_moduleInfo.json` — tra trước khi viết headers.
235
+ Framework version comes from `_projectInfo.json` or `_moduleInfo.json` — check before writing headers.
234
236
 
235
237
  ### Header field names
236
238
 
237
- **Đây là điểm dễ nhầm nhất.** Hai trường `text`/`value` của V2 đổi tên thành `title`/`key` ở V3:
239
+ **Most common mistake.** V2 `text`/`value` are renamed `title`/`key` in V3:
238
240
 
239
- | Trường | V2 (`componentTable.js`) | V3 (`componentTable-3.0.js`) |
240
- |---|---|---|
241
- | Nhãn cột | `"text": "Tên cột"` | `"title": "Tên cột"` |
242
- | Field data | `"value": "TenField"` | `"key": "TenField"` |
243
- | Cột ctrl | `"value": "ctrl-update"` | `"key": "ctrl-update"` |
241
+ | Field | V2 (`componentTable.js`) | V3 (`componentTable-3.0.js`) |
242
+ | ------------ | ------------------------ | ---------------------------- |
243
+ | Column label | `"text": "Tên cột"` | `"title": "Tên cột"` |
244
+ | Data field | `"value": "TenField"` | `"key": "TenField"` |
245
+ | Ctrl column | `"value": "ctrl-update"` | `"key": "ctrl-update"` |
244
246
 
245
247
  ```json
246
248
  // V2 ✅
@@ -252,25 +254,34 @@ Phiên bản framework được xác định từ `_projectInfo.json` hoặc `_m
252
254
  { "title": "Tác vụ", "key": "ctrl-update", "align": "center" }
253
255
  ```
254
256
 
255
- > Dùng `text`/`value` trên project V3 → cột render nhưng **tiêu đề biến mất và sort không hoạt động** (Vuetify 3 đọc `title`/`key`, bỏ qua `text`/`value`). Không có lỗi JS nào báo — chỉ nhìn thấy qua ảnh render.
257
+ > `text`/`value` on V3 → columns render but **headers vanish, sort breaks** (Vuetify 3 ignores them). No JS error — only visible in a rendered screenshot.
258
+
259
+ ### `t-*` columns in V3 must declare `v-model`
260
+
261
+ V2 adds `v-model="item['{value}']"` to every column with `el` by itself. **V3 does not**: a `t-num`/`t-time`/`t-label`… column without `attr["v-model"]` gets an empty value. `t-num` then gets 0, which `hidezero` hides, so **the whole column is blank with no error anywhere** (measured on the real V3 framework). Headers the table builds itself (no `:headers`) already have `v-model`.
262
+
263
+ ```json
264
+ // V3 ✅
265
+ { "title": "Số lượng", "key": "SoLuong", "el": "t-num", "attr": { "v-model": "item.SoLuong" } }
266
+ ```
256
267
 
257
- ### Props bổ sung ở V3
268
+ ### Extra V3 props
258
269
 
259
- | Prop | Mặc định V3 | Ghi chú |
260
- |---|---|---|
261
- | `density` | `'compact'` | Mật độ dòng — `'compact'`/`'comfortable'`/`'default'` |
262
- | `disable-sort` | `false` | Tắt sort toàn bảng |
263
- | `slots` | `null` | Custom slot động (object `{ name, html }`) |
264
- | `group-template` | `null` | Template cho nhóm gộp (`groupBy`) |
265
- | `height` | `null` | Giống V2: null/bỏ trống = tự giãn; ≤0 = fill đáy; >0 = px cố định |
270
+ | Prop | V3 default | Note |
271
+ | ---------------- | ----------- | ------------------------------------------------------------------------ |
272
+ | `density` | `'compact'` | Row density — `'compact'`/`'comfortable'`/`'default'` |
273
+ | `disable-sort` | `false` | Disable sorting for the whole table |
274
+ | `slots` | `null` | Dynamic custom slots (object `{ name, html }`) |
275
+ | `group-template` | `null` | Template for groups (`groupBy`) |
276
+ | `height` | `null` | Same as V2: null/omitted = auto-grow; ≤0 = fill to bottom; >0 = fixed px |
266
277
 
267
- ### sum-format object dạng V3
278
+ ### sum-format object in V3
268
279
 
269
- Ở V3, key của `sum-format` object phải khớp `key` của header (không phải `value`):
280
+ In V3 the `sum-format` object keys must match header `key` (not `value`):
270
281
 
271
282
  ```json
272
283
  // V3 ✅ — key = "DangKy" khớp với header { "key": "DangKy" }
273
284
  ":sum-format": { "DangKy": "0,0", "NhapHoc": "0,0" }
274
285
  ```
275
286
 
276
- Logic giống V2 hoàn toàn — chỉ khác ở chỗ V3 đọc `col.key` thay vì `col.value` nên tên field phải nhất quán.
287
+ Otherwise identical to V2.