@fui-org/fui-cli 1.3.1 → 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 +7 -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-x7kph78r.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,14 +1,12 @@
1
1
  # FUI Layout Patterns — page-container, master-detail, switch, dynamic label
2
2
 
3
- > File này sở hữu: **pattern layout trang: page-container sticky, master-detail 2 cột, v-switch, date init, dynamic label**.
3
+ > Owns: **page layout patterns: sticky page-container, 2-column master-detail, v-switch, date init, dynamic label**.
4
4
 
5
- Các pattern layout và điều khiển bổ trợ. Rút ra từ project **security-manager**.
6
-
7
- > Xem thêm: [ui-patterns.md](ui-patterns.md), [ui-table-cell-patterns.md](ui-table-cell-patterns.md), [module-structure.md](module-structure.md).
5
+ Layout and helper-control patterns, drawn from project **security-manager**. See also: [ui-patterns.md](ui-patterns.md), [ui-table-cell-patterns.md](ui-table-cell-patterns.md), [module-structure.md](module-structure.md).
8
6
 
9
7
  ---
10
8
 
11
- ## 1. Khởi tạo Date với moment()
9
+ ## 1. Date init with moment()
12
10
 
13
11
  ```json
14
12
  "data": [
@@ -19,13 +17,13 @@ Các pattern layout và điều khiển bổ trợ. Rút ra từ project **secur
19
17
  ]
20
18
  ```
21
19
 
22
- > Giá trị là JS expression string — FUI sẽ eval nó khi khởi tạo. `moment()` có sẵn trong FUI runtime.
20
+ > The value is a JS expression string, eval'd at init. `moment()` is available in the FUI runtime.
23
21
 
24
22
  ---
25
23
 
26
- ## 2. page-container + page-navigation Layout
24
+ ## 2. page-container + page-navigation
27
25
 
28
- Dùng khi cần filter bar cố định phía trên, nội dung bên dưới scroll.
26
+ Use for a fixed filter bar on top with scrolling content below.
29
27
 
30
28
  ```json
31
29
  {
@@ -38,29 +36,32 @@ Dùng khi cần filter bar cố định phía trên, nội dung bên dưới scr
38
36
  { "el": "f-date", "attr": { "v-model": "DenNgay", "label": "Tới ngày", "date-add": 0 }, "w": "2" },
39
37
  {
40
38
  "el": "f-button",
41
- "attr": { "color": "primary", "icon-text": "mdi-filter", "label": "Tìm", ":action": { "CALL": "getLogData" } },
39
+ "attr": {
40
+ "color": "primary",
41
+ "icon-text": "mdi-filter",
42
+ "label": "Tìm",
43
+ ":action": { "CALL": "getLogData" }
44
+ },
42
45
  "w": 3
43
46
  }
44
47
  ]
45
48
  },
46
49
  {
47
50
  "prop": "",
48
- "cols": [
49
- { "el": "f-table", "attr": { "label": "Log viewer", ":items": "LogData" } }
50
- ]
51
+ "cols": [{ "el": "f-table", "attr": { "label": "Log viewer", ":items": "LogData" } }]
51
52
  }
52
53
  ]
53
54
  }
54
55
  ```
55
56
 
56
- - `page-container` + `page-navigation` → filter bar sticky top
57
- - `f-table` không khai `:update-api` → readonly view; không truyền `:headers` → tự build header từ data
57
+ - `page-container` + `page-navigation` → sticky top filter bar
58
+ - `f-table` without `:update-api` → readonly; without `:headers` → headers auto-built from data
58
59
 
59
60
  ---
60
61
 
61
- ## 3. Dynamic Label từ State
62
+ ## 3. Dynamic label from state
62
63
 
63
- Dùng `:label` với expression để hiển thị thông tin context.
64
+ Use `:label` with an expression to show context.
64
65
 
65
66
  ```json
66
67
  {
@@ -82,7 +83,7 @@ Dùng `:label` với expression để hiển thị thông tin context.
82
83
 
83
84
  ---
84
85
 
85
- ## 4. v-switch — Toggle với Label
86
+ ## 4. v-switch — toggle with label
86
87
 
87
88
  ```json
88
89
  {
@@ -102,7 +103,8 @@ Dùng `:label` với expression để hiển thị thông tin context.
102
103
  }
103
104
  ```
104
105
 
105
- Dùng với `v-if` để hiện/ẩn field bổ sung:
106
+ Combine with `v-if` to show/hide extra fields:
107
+
106
108
  ```json
107
109
  {
108
110
  "el": "v-layout",
@@ -113,15 +115,13 @@ Dùng với `v-if` để hiện/ẩn field bổ sung:
113
115
 
114
116
  ---
115
117
 
116
- ## 5. Master-Detail 2 Cột
118
+ ## 5. Two-column master-detail
117
119
 
118
- Pattern layout cha-con: bảng trái chọn row → watch → load bảng phải. Không cần mở window mới.
120
+ Left table row pick → watch → load right table. No new window needed.
119
121
 
120
- > Nút mở detail đặt trong ô bảng: chọn `t-button` hay `t-menu` theo quy tắc ở
121
- > [ui-table-cell-patterns.md](ui-table-cell-patterns.md#khi-nào-dùng-t-button-vs-t-menu) — với
122
- > master-detail thì hành động là "xem/load dữ liệu liên quan" nên dùng `t-button`.
122
+ > Detail button in a table cell: choose `t-button` vs `t-menu` per [ui-table-cell-patterns.md](ui-table-cell-patterns.md) — for master-detail the action is "view/load related data", so use `t-button`.
123
123
 
124
- **`data[]` và watch:**
124
+ **`data[]` and watch:**
125
125
 
126
126
  ```json
127
127
  "data": [
@@ -141,7 +141,7 @@ Pattern layout cha-con: bảng trái chọn row → watch → load bảng phải
141
141
  }
142
142
  ```
143
143
 
144
- **Cột `t-button` trong bảng trái:**
144
+ **`t-button` column in the left table:**
145
145
 
146
146
  ```json
147
147
  {
@@ -158,7 +158,7 @@ Pattern layout cha-con: bảng trái chọn row → watch → load bảng phải
158
158
  }
159
159
  ```
160
160
 
161
- **Layout 2 cột:**
161
+ **2-column layout:**
162
162
 
163
163
  ```json
164
164
  {
@@ -1,28 +1,25 @@
1
- # FUI UI Patterns — Real-World Design Reference (Core)
1
+ # FUI UI Patterns — Core
2
2
 
3
- > File này sở hữu: **pattern UI cốt lõi: toolbar/filter, permission gate, checklist thiết kế giao diện**. Bảng/dialog/cross-window/layout đã tách sang các file `ui-*` riêng.
3
+ > Owns: **core UI patterns: toolbar/filter, permission gate, UI design checklist**. Table/dialog/cross-window/layout live in separate `ui-*` files.
4
4
 
5
- Các pattern được rút ra từ project **security-manager** — dùng làm tham chiếu khi thiết kế module mới.
5
+ Patterns taken from project **security-manager** — use as reference for new modules. Load specialised files as needed:
6
6
 
7
- File này chứa **core patterns** (data/watch/toolbar/action). Các nhóm pattern chuyên sâu đã tách ra — load thêm khi cần:
8
-
9
- | Cần làm | File |
10
- |---|---|
11
- | f-table + điều khiển trong ô (t-check/t-button/t-select/t-menu, ctrl-update, chip-group) | [ui-table-cell-patterns.md](ui-table-cell-patterns.md) |
12
- | Dialog/form popup (hidden-container, mở dialog với row, checkbox-list) | [ui-dialog-patterns.md](ui-dialog-patterns.md) |
13
- | Mở sub-window & trao đổi dữ liệu (`openWindow`, `#PARENT`/`#Win`) | [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md) |
14
- | Layout (page-container, master-detail, v-switch, date init, dynamic label) | [ui-layout-patterns.md](ui-layout-patterns.md) |
7
+ | Need | File |
8
+ | -------------------------------------------------------------------------------------- | -------------------------------------------------------- |
9
+ | f-table + in-cell controls (t-check/t-button/t-select/t-menu, ctrl-update, chip-group) | [ui-table-cell-patterns.md](ui-table-cell-patterns.md) |
10
+ | Dialog/popup form (hidden-container, open dialog with row, checkbox-list) | [ui-dialog-patterns.md](ui-dialog-patterns.md) |
11
+ | Sub-window & data exchange (`openWindow`, `#PARENT`/`#Win`) | [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md) |
12
+ | Layout (page-container, master-detail, v-switch, date init, dynamic label) | [ui-layout-patterns.md](ui-layout-patterns.md) |
15
13
 
16
14
  ---
17
15
 
18
- ## 1. Cấu trúc `data[]` trong module.json
16
+ ## 1. `data[]` structure
19
17
 
20
- `data` là mảng khởi tạo state + action. FUI xử lý tuần tự từ trên xuống dưới.
18
+ `data` initialises state + actions, processed top to bottom.
21
19
 
22
- **Quy ước tổ chức:**
23
- - Object **không có key action** (không có API, CALL, IF…) → khởi tạo state
24
- - Object **có key là tên hàm** → định nghĩa named action (tái sử dụng)
25
- - Object dạng `{ "API": ..., "OUT": ... }` hoặc `{ "CALL": ... }` ở cuối → tự chạy khi load xong
20
+ - Object with **no action key** (no API, CALL, IF…) → state init
21
+ - Object whose **key is a function name** → named (reusable) action
22
+ - Trailing `{ "API": ..., "OUT": ... }` or `{ "CALL": ... }` → runs automatically on load
26
23
 
27
24
  ```json
28
25
  "data": [
@@ -46,13 +43,13 @@ File này chứa **core patterns** (data/watch/toolbar/action). Các nhóm patte
46
43
  ]
47
44
  ```
48
45
 
49
- > **Auto-startup**: CALL ở cuối `data[]` sẽ tự chạy khi module load — không cần event handler riêng.
46
+ > **Auto-startup**: trailing CALLs in `data[]` run on module load — no event handler needed.
50
47
 
51
48
  ---
52
49
 
53
- ## 2. Cascading API Init
50
+ ## 2. Cascading API init
54
51
 
55
- Dùng `CALLBACK` để set giá trị từ kết quả API đầu tiên, rồi API tiếp theo tự chạy qua `watch`.
52
+ `CALLBACK` sets a value from the first API result; the next API runs via `watch`.
56
53
 
57
54
  ```json
58
55
  "data": [
@@ -68,13 +65,13 @@ Dùng `CALLBACK` để set giá trị từ kết quả API đầu tiên, rồi A
68
65
  }
69
66
  ```
70
67
 
71
- > `sModuleID` được set từ CALLBACK → watch tự kích hoạt `getFunctionRight`. Không cần gọi thủ công.
68
+ > CALLBACK sets `sModuleID` → watch fires `getFunctionRight`. No manual call.
72
69
 
73
70
  ---
74
71
 
75
- ## 3. Watch — Cascading Filter
72
+ ## 3. Watch — cascading filter
76
73
 
77
- Khi filter thay đổi → tự reload data. Nhiều watch → mảng CALL.
74
+ Filter change → reload. Several actions → array of CALL.
78
75
 
79
76
  ```json
80
77
  "watch": {
@@ -90,11 +87,11 @@ Khi filter thay đổi → tự reload data. Nhiều watch → mảng CALL.
90
87
 
91
88
  ---
92
89
 
93
- ## 4. Toolbar / Filter Row Pattern
90
+ ## 4. Toolbar / filter row
94
91
 
95
- Row chứa filter fields và action buttons, `v-spacer` đẩy nhóm nút về phải.
92
+ Row of filter fields + action buttons; `v-spacer` pushes the button group right.
96
93
 
97
- > **Chuẩn mực bố cục của hàng này: MỌI cột đều `"col": "shrink"`, trừ `v-spacer`.** Cột không `shrink` là cột được chia phần trống — kể cả cột `w` rỗng, kể cả nút. Thiếu `shrink` thì nút phình ra, hở khoảng giữa các nút, và nhóm cuối hàng không sát mép phải dù đã có `v-spacer`. Khuôn chuẩn + số đo trên framework thật: [controls-patterns.md](controls-patterns.md) §Hàng nhiều control (toolbar).
94
+ > **Rule: EVERY column is `"col": "shrink"` except `v-spacer`.** A non-`shrink` column takes a share of free space — including an empty-`w` column and buttons. Missing `shrink` → buttons stretch, gaps appear between buttons, and the trailing group doesn't reach the right edge even with `v-spacer`. Standard template + measurements: [controls-patterns.md](controls-patterns.md) §Toolbar row.
98
95
 
99
96
  ```json
100
97
  {
@@ -148,43 +145,39 @@ Row chứa filter fields và action buttons, `v-spacer` đẩy nhóm nút về p
148
145
  "color": "primary",
149
146
  "label": "Add User",
150
147
  "icon-text": "mdi-account-multiple-plus",
151
- ":action": [
152
- { "addNew": 1, "sUserID": "", "sUserName": "" },
153
- { "dlUserInfo": true }
154
- ]
148
+ ":action": [{ "addNew": 1, "sUserID": "", "sUserName": "" }, { "dlUserInfo": true }]
155
149
  }
156
150
  }
157
151
  ]
158
152
  }
159
153
  ```
160
154
 
161
- **Quy tắc:**
162
- - Filter fields: `w` là px (`>= 25`) + `col: "shrink"`. Cặp `attr: { class: "flex-md-grow-0", style: "width:Xpx" }` ở ví dụ trên là **thừa** — `w` + `shrink` đã cho đúng bề rộng đó (đo được: `w:150` + `shrink` → đúng 150px ở cả V2 lẫn V3); giữ lại trong ví dụ vì đây là module production chép nguyên, viết mới thì bỏ đi
163
- - Nút tìm: ngay sau fields, cũng `col: "shrink"` (nút **không** shrink sẽ bị kéo dãn ra)
164
- - **Luôn là `class: "shrink"` / `"col": "shrink"`, không phải `shrink: true`** — dạng thuộc tính trần chỉ ăn ở V2, ở V3 nó trơ và cột giãn full
165
- - `v-spacer`: cột **duy nhất** không `shrink` — nó phải giãn được thì mới đẩy được nhóm sau sang phải
166
- - Nút Add/Delete admin: sau spacer, thêm `v-if` permission — `col: { "v-if": "…", "class": "shrink" }` (object khi cần thêm key, vẫn giữ `shrink`)
167
- - Không có `v-spacer` mà muốn canh phải cả hàng: `"prop": "row justify-end"`
155
+ - Filter fields: `w` in px (`>= 25`) + `col: "shrink"`. The `attr: { class: "flex-md-grow-0", style: "width:Xpx" }` pair above is **redundant** — `w` + `shrink` already gives that width (measured: `w:150` + `shrink` → exactly 150px on V2 and V3). It stays only because the example is copied from production; omit it in new code.
156
+ - Search button right after the fields, also `col: "shrink"` (a non-shrink button stretches).
157
+ - **Always `class: "shrink"` / `"col": "shrink"`, never `shrink: true`** — the bare attribute works only on V2; on V3 it's inert and the column goes full width.
158
+ - `v-spacer` is the **only** non-`shrink` column — it must grow to push the following group right.
159
+ - Admin Add/Delete buttons: after the spacer, permission `v-if` — `col: { "v-if": "…", "class": "shrink" }` (object form when extra keys are needed; keep `shrink`).
160
+ - Right-align the whole row without `v-spacer`: `"prop": "row justify-end"`.
168
161
 
169
162
  ---
170
163
 
171
- ## 5. Permission Gating
164
+ ## 5. Permission gating
172
165
 
173
- Ẩn/hiện phần tử theo `SystemRight` của user.
166
+ Show/hide by the user's `SystemRight`.
174
167
 
175
168
  ```json
176
169
  "col": { "v-if": "vueData.user.SystemRight>1" }
177
170
  "col": { "v-if": "vueData.user.SystemRight==9" }
178
171
  ```
179
172
 
180
- - `>1` — visible với mọi user có quyền (không phải level thấp nhất)
181
- - `==9` — chỉ admin cao nhất mới thấy
173
+ - `>1` — any user with rights (not the lowest level)
174
+ - `==9` — top admin only
182
175
 
183
176
  ---
184
177
 
185
- ## 6. IF/THEN/ELSE — Conditional Action
178
+ ## 6. IF/THEN/ELSE
186
179
 
187
- Rẽ nhánh logic trong action hoặc CALLBACK.
180
+ Branching inside an action or CALLBACK.
188
181
 
189
182
  ```json
190
183
  {
@@ -198,10 +191,10 @@ Rẽ nhánh logic trong action hoặc CALLBACK.
198
191
  }
199
192
  ```
200
193
 
201
- - Condition: JavaScript expression dùng vueData fields trực tiếp (không cần `vueData.`)
202
- - Dùng nested IF/ELSE cho switch-case nhiều nhánh
194
+ - Condition: JS expression using vueData fields directly (no `vueData.` prefix).
195
+ - Nest IF/ELSE for multi-branch switch.
203
196
 
204
- **Ứng dụng thực tế:** Module có nhiều chế độ xem (`TypeLoad`) — sau khi update, refresh đúng danh sách đang hiển thị.
197
+ Real use: module with several view modes (`TypeLoad`) — after an update, refresh the list currently shown.
205
198
 
206
199
  ```json
207
200
  "data": [
@@ -211,11 +204,11 @@ Rẽ nhánh logic trong action hoặc CALLBACK.
211
204
 
212
205
  ---
213
206
 
214
- ## 7. CALLBACK Chaining
207
+ ## 7. CALLBACK chaining
215
208
 
216
- CALLBACK là array → thực thi tuần tự.
209
+ Array CALLBACK → runs in order.
217
210
 
218
- > **Nhiều lệnh thì BẮT BUỘC là mảng, mỗi lệnh một `{}` riêng.** Gộp `CALL` + `MESS` + `EXE` vào chung một object thì chỉ **một** lệnh chạy (ưu tiên `API` → `CALL` → `EXE` → `FUN` → `IF` → `MESS` → `MESSBOX`, mỗi nhánh `return` ngay), phần còn lại rơi im lặng — không error, không `[Vue warn]`. Luật đầy đủ + lý do trong runtime: [controls-patterns.md](controls-patterns.md) §QUY TẮC NỀN.
211
+ > **Several commands MUST be an array, one `{}` per command.** Merging `CALL` + `MESS` + `EXE` into one object runs only **one** (priority `API` → `CALL` → `EXE` → `FUN` → `IF` → `MESS` → `MESSBOX`, each branch `return`s immediately); the rest are dropped silently — no error, no `[Vue warn]`. Full rule + runtime reason: [controls-patterns.md](controls-patterns.md) §CORE RULE.
219
212
 
220
213
  ```json
221
214
  "CALLBACK": [
@@ -233,13 +226,13 @@ CALLBACK là array → thực thi tuần tự.
233
226
  ]
234
227
  ```
235
228
 
236
- **Thứ tự thông dụng:** reload data → reset state → hiển thị message.
229
+ Usual order: reload data → reset state → show message.
237
230
 
238
231
  ---
239
232
 
240
- ## 8. set — Cấu hình Module Level
233
+ ## 8. `set` — module-level config
241
234
 
242
- `set` ở root module.json — cấu hình behavior của toàn module.
235
+ `set` at module.json root configures the whole module.
243
236
 
244
237
  ```json
245
238
  "set": {
@@ -247,17 +240,15 @@ CALLBACK là array → thực thi tuần tự.
247
240
  }
248
241
  ```
249
242
 
250
- - `menu: false` — ẩn menu navigation (dùng cho sub-window, log viewer)
243
+ - `menu: false` — hide navigation menu (sub-windows, log viewers).
251
244
 
252
- > Module mở qua `openWindow`: khai báo `"set": { "menu": false }` trong module.json của module con —
253
- > **không** truyền `?menu=0` trong URL. Pattern đầy đủ (kể cả cách set động từ `data[]`):
254
- > [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md).
245
+ > Module opened via `openWindow`: declare `"set": { "menu": false }` in the child module's module.json — **don't** pass `?menu=0` in the URL. Full pattern (incl. setting it dynamically from `data[]`): [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md).
255
246
 
256
247
  ---
257
248
 
258
- ## 9. CALLBACK với JavaScript Expression
249
+ ## 9. CALLBACK with JS expression
259
250
 
260
- Dùng `{{ expression }}` trong CALLBACK để chạy code phức tạp sau API.
251
+ `{{ expression }}` in CALLBACK runs complex code after the API.
261
252
 
262
253
  ```json
263
254
  "CALLBACK": "{{ _.forEach(dsUsers, (x)=> x.FunctionName = JSON.parse(x.FunctionName)) }}"
@@ -267,49 +258,46 @@ Dùng `{{ expression }}` trong CALLBACK để chạy code phức tạp sau API.
267
258
  "CALLBACK": "{{ _.forEach(dsUserFunction, (x)=> x.FunctionName = JSON.parse(x.FunctionName)), _.forEach(dsUserFunction, (x)=> x.UserSysItem = JSON.parse(x.UserSysItem)) }}"
268
259
  ```
269
260
 
270
- > Dùng khi API trả về JSON string cần parse thành object/array trước khi render.
261
+ > Use when the API returns a JSON string that must be parsed to object/array before render.
271
262
 
272
263
  ---
273
264
 
274
- ## 10. script.js — Helper Functions
265
+ ## 10. script.js — helpers
275
266
 
276
- `script.js` chứa helper functions gọi từ `v-on:click` hoặc action.
267
+ `script.js` holds helpers called from `v-on:click` or actions. They access `vueData` directly; use for logic plain action JSON can't express.
277
268
 
278
269
  ```javascript
279
270
  // script.js
280
271
  function setFunction(user, fc) {
281
- vueData.sFunctionSelected = [];
282
- vueData.sUserSelected = [];
283
- vueData.sUserSelected.push(user);
284
- if (!fc) return;
285
- vueData.dsFunctionRight.map((item) => {
286
- if (fc.some(fci => fci.FunctionID == item.FunctionID)) {
287
- vueData.sFunctionSelected.push(item.FunctionID.toString());
288
- }
289
- });
272
+ vueData.sFunctionSelected = [];
273
+ vueData.sUserSelected = [];
274
+ vueData.sUserSelected.push(user);
275
+ if (!fc) return;
276
+ vueData.dsFunctionRight.map((item) => {
277
+ if (fc.some((fci) => fci.FunctionID == item.FunctionID)) {
278
+ vueData.sFunctionSelected.push(item.FunctionID.toString());
279
+ }
280
+ });
290
281
  }
291
282
  ```
292
283
 
293
- Gọi từ `v-on:click` trong header:
284
+ Called from `v-on:click` in a header:
285
+
294
286
  ```json
295
287
  "v-on:click": "vueData.dlFunction = true; CALL(setFunction(item, item.FunctionName));"
296
288
  ```
297
289
 
298
- > Functions trong `script.js` có thể access `vueData` trực tiếp. Dùng để xử lý logic phức tạp không thể làm bằng action JSON thuần.
299
-
300
290
  ---
301
291
 
302
- ## Checklist Thiết Kế UI
292
+ ## UI design checklist
303
293
 
304
- > Checklist cấu trúc `module.json` (thứ tự `data[]`, grid wrapper, `w`, `v-on:`, `set`, JSON hợp lệ)
305
- > nằm ở [module-json-anatomy.md](module-json-anatomy.md#checklist-khi-viết-modulejson) — dưới đây chỉ
306
- > là phần riêng của thiết kế giao diện.
294
+ > `module.json` structure checklist (`data[]` order, grid wrapper, `w`, `v-on:`, `set`, valid JSON) is in [module-json-anatomy.md](module-json-anatomy.md). Below is UI-specific only.
307
295
 
308
296
  1. **Toolbar row**: shrink filters + v-spacer + permission-gated buttons
309
- 2. **f-table**: fixed-header, item-class cho row highlight, item-key đúng — xem [ui-table-cell-patterns.md](ui-table-cell-patterns.md)
310
- 3. **Dialogs**: luôn trong hidden-container, v-card[padding:0] + v-toolbar[dense flat] — xem [ui-dialog-patterns.md](ui-dialog-patterns.md)
311
- 4. **menuChucNang**: định nghĩa trong data[], ref bằng t-menu trong headers — xem [ui-table-cell-patterns.md](ui-table-cell-patterns.md)
312
- 5. **ctrl-update**: cho CRUD đơn giản, dialog thủ công cho form phức tạp
297
+ 2. **f-table**: fixed-header, item-class for row highlight, correct item-key — [ui-table-cell-patterns.md](ui-table-cell-patterns.md)
298
+ 3. **Dialogs**: always in hidden-container, v-card[padding:0] + v-toolbar[dense flat] — [ui-dialog-patterns.md](ui-dialog-patterns.md)
299
+ 4. **menuChucNang**: define in data[], reference via t-menu in headers — [ui-table-cell-patterns.md](ui-table-cell-patterns.md)
300
+ 5. **ctrl-update**: simple CRUD; manual dialog for complex forms
313
301
  6. **CALLBACK**: chaining array — reload → reset state → MESS
314
- 7. **#PARENT**: set ngay đầu data[] trước các CALL startup — xem [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md)
315
- 8. **Permission**: `v-if: "vueData.user.SystemRight>1"` cho admin-only sections
302
+ 7. **#PARENT**: set at the top of data[] before startup CALLs — [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md)
303
+ 8. **Permission**: `v-if: "vueData.user.SystemRight>1"` for admin-only sections