@fui-org/fui-cli 1.3.2 → 2.1.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.
- package/README.md +21 -3
- package/dist/fui-cx180e19.js +379 -0
- package/dist/fui.js +1 -1
- package/package.json +3 -6
- package/skills/fui/SKILL.md +9 -41
- package/skills/fui-skill/SKILL.md +95 -225
- package/skills/fui-skill/assets/projectdefaultstyle-3.0.css +555 -0
- package/skills/fui-skill/assets/projectdefaultstyle.css +207 -235
- package/skills/fui-skill/references/INDEX.md +105 -137
- package/skills/fui-skill/references/advanced-techniques.md +76 -68
- package/skills/fui-skill/references/coding-standards.md +56 -56
- package/skills/fui-skill/references/component-design.md +166 -173
- package/skills/fui-skill/references/component-quickref.md +61 -60
- package/skills/fui-skill/references/component-table.md +128 -117
- package/skills/fui-skill/references/components-dialog.md +55 -56
- package/skills/fui-skill/references/components-display.md +24 -30
- package/skills/fui-skill/references/components-echart.md +186 -261
- package/skills/fui-skill/references/components-input.md +72 -96
- package/skills/fui-skill/references/controls-patterns.md +196 -342
- package/skills/fui-skill/references/controls-styling-vocabulary.md +130 -97
- package/skills/fui-skill/references/db-table-design.md +24 -28
- package/skills/fui-skill/references/db-workflow.md +191 -390
- package/skills/fui-skill/references/default-function.md +169 -128
- package/skills/fui-skill/references/design-modes.md +35 -63
- package/skills/fui-skill/references/echart-templates.md +204 -196
- package/skills/fui-skill/references/fastproject.md +62 -60
- package/skills/fui-skill/references/fsheet.md +109 -124
- package/skills/fui-skill/references/fullstack-workflow.md +90 -128
- package/skills/fui-skill/references/module-data-patterns.md +31 -40
- package/skills/fui-skill/references/module-json-anatomy.md +47 -52
- package/skills/fui-skill/references/module-structure.md +80 -196
- package/skills/fui-skill/references/new-session.md +49 -51
- package/skills/fui-skill/references/pdfmake.md +17 -17
- package/skills/fui-skill/references/permission-system.md +89 -108
- package/skills/fui-skill/references/platform-architecture.md +128 -153
- package/skills/fui-skill/references/project-config.md +102 -134
- package/skills/fui-skill/references/project-provisioning.md +139 -244
- package/skills/fui-skill/references/script-map.md +208 -242
- package/skills/fui-skill/references/sql-clr-functions.md +98 -97
- package/skills/fui-skill/references/system-design.md +63 -88
- package/skills/fui-skill/references/tapi-file-api.md +46 -52
- package/skills/fui-skill/references/tapi-permission-patterns.md +51 -53
- package/skills/fui-skill/references/tapi-reference.md +132 -207
- package/skills/fui-skill/references/tools-registry.md +84 -460
- package/skills/fui-skill/references/ui-crosswindow-patterns.md +79 -75
- package/skills/fui-skill/references/ui-dialog-patterns.md +98 -72
- package/skills/fui-skill/references/ui-layout-patterns.md +26 -26
- package/skills/fui-skill/references/ui-patterns.md +71 -83
- package/skills/fui-skill/references/ui-screenshot-review.md +63 -62
- package/skills/fui-skill/references/ui-table-cell-patterns.md +61 -59
- package/skills/fui-skill/references/ui-templates.md +16 -23
- package/skills/fui-skill/references/verification.md +236 -246
- package/skills/fui-skill/references/watcher-patterns.md +30 -63
- package/skills/fui-skill/references/websocket-realtime.md +83 -66
- package/skills/fui-skill/scripts/component-3.0.js +298 -131
- package/skills/fui-skill/scripts/component.js +277 -271
- package/skills/fui-skill/scripts/componentTable-3.0.js +182 -53
- package/skills/fui-skill/scripts/componentTable.js +171 -49
- package/skills/fui-skill/scripts/defaultfunction-3.0.js +88 -3
- package/skills/fui-skill/scripts/defaultfunction.js +88 -3
- package/skills/fui-skill/scripts/fsheet.js +38 -0
- package/skills/fui-target/.claude-plugin/plugin.json +6 -0
- package/skills/fui-target/hooks/hooks.json +1 -0
- package/skills/fui-target/hooks/register.tsx +71 -0
- package/skills/fui-target/types/index.d.ts +7 -0
- package/dist/fui-y8an39cn.js +0 -420
- package/skills/fui-skill/README.md +0 -112
- package/skills/fui-skill/metadata.json +0 -75
- package/skills/fui-skill-cli/SKILL.md +0 -139
- package/skills/fui-skill-cli/references/INDEX.md +0 -110
- package/skills/fui-skill-cli/references/advanced-techniques.md +0 -168
- package/skills/fui-skill-cli/references/coding-standards.md +0 -112
- package/skills/fui-skill-cli/references/component-design.md +0 -448
- package/skills/fui-skill-cli/references/component-quickref.md +0 -78
- package/skills/fui-skill-cli/references/component-table.md +0 -248
- package/skills/fui-skill-cli/references/components-dialog.md +0 -191
- package/skills/fui-skill-cli/references/components-display.md +0 -141
- package/skills/fui-skill-cli/references/components-echart.md +0 -316
- package/skills/fui-skill-cli/references/components-input.md +0 -335
- package/skills/fui-skill-cli/references/controls-patterns.md +0 -701
- package/skills/fui-skill-cli/references/controls-styling-vocabulary.md +0 -137
- package/skills/fui-skill-cli/references/db-table-design.md +0 -73
- package/skills/fui-skill-cli/references/db-workflow.md +0 -288
- package/skills/fui-skill-cli/references/default-function.md +0 -425
- package/skills/fui-skill-cli/references/design-modes.md +0 -57
- package/skills/fui-skill-cli/references/echart-templates.md +0 -489
- package/skills/fui-skill-cli/references/fastproject.md +0 -99
- package/skills/fui-skill-cli/references/fsheet.md +0 -203
- package/skills/fui-skill-cli/references/fullstack-workflow.md +0 -313
- package/skills/fui-skill-cli/references/module-data-patterns.md +0 -117
- package/skills/fui-skill-cli/references/module-json-anatomy.md +0 -132
- package/skills/fui-skill-cli/references/module-structure.md +0 -141
- package/skills/fui-skill-cli/references/new-session.md +0 -85
- package/skills/fui-skill-cli/references/pdfmake.md +0 -60
- package/skills/fui-skill-cli/references/permission-system.md +0 -150
- package/skills/fui-skill-cli/references/platform-architecture.md +0 -269
- package/skills/fui-skill-cli/references/project-config.md +0 -303
- package/skills/fui-skill-cli/references/project-provisioning.md +0 -278
- package/skills/fui-skill-cli/references/script-map.md +0 -262
- package/skills/fui-skill-cli/references/sql-clr-functions.md +0 -225
- package/skills/fui-skill-cli/references/system-design.md +0 -89
- package/skills/fui-skill-cli/references/tapi-file-api.md +0 -185
- package/skills/fui-skill-cli/references/tapi-permission-patterns.md +0 -156
- package/skills/fui-skill-cli/references/tapi-reference.md +0 -474
- package/skills/fui-skill-cli/references/tools-registry.md +0 -84
- package/skills/fui-skill-cli/references/ui-crosswindow-patterns.md +0 -321
- package/skills/fui-skill-cli/references/ui-dialog-patterns.md +0 -255
- package/skills/fui-skill-cli/references/ui-layout-patterns.md +0 -176
- package/skills/fui-skill-cli/references/ui-patterns.md +0 -303
- package/skills/fui-skill-cli/references/ui-screenshot-review.md +0 -95
- package/skills/fui-skill-cli/references/ui-table-cell-patterns.md +0 -318
- package/skills/fui-skill-cli/references/ui-templates.md +0 -22
- package/skills/fui-skill-cli/references/verification.md +0 -236
- package/skills/fui-skill-cli/references/watcher-patterns.md +0 -163
- package/skills/fui-skill-cli/references/websocket-realtime.md +0 -271
|
@@ -1,144 +1,112 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
> File này sở hữu: **bảng định tuyến tình huống / component / từ khóa → file reference cần load**. Không chứa nội dung kỹ thuật — mọi quy tắc đều nằm ở file đích. *(Tier A — luôn nạp cùng `skill_get`.)*
|
|
4
|
-
|
|
5
|
-
**Bản đồ tra cứu: tình huống / component / từ khóa → file cần load.** Đây là file luôn được nạp cùng `skill_get`. Trước khi xử lý bất kỳ việc gì, tra bảng dưới để biết cần `skill_reference_get({ refs: [...] })` file nào — **đừng dựa vào trí nhớ, hãy load đúng file**.
|
|
6
|
-
|
|
7
|
-
> Cách dùng: `skill_reference_get({ refs: ["references/<tên-file>.md"] })`. Có thể load nhiều file một lần.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Luôn có sẵn (Tier A — đã nạp cùng skill_get)
|
|
12
|
-
|
|
13
|
-
| File | Nội dung |
|
|
14
|
-
|---|---|
|
|
15
|
-
| `controls-patterns.md` | Action engine (**§QUY TẮC NỀN: một `{}` = một lệnh; nhiều lệnh tuần tự = mảng `[{…},{…}]`**), value resolution, key notation, layout grid — **nền tảng** |
|
|
16
|
-
| `module-structure.md` | Cấu trúc file module/project, layout rules |
|
|
17
|
-
| `INDEX.md` | (file này) — bản đồ router |
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Hiểu nền tảng / cấu tạo FUI (đọc sớm)
|
|
22
|
-
|
|
23
|
-
| Tình huống | Load file |
|
|
24
|
-
|---|---|
|
|
25
|
-
| Cấu tạo FUI, phân cấp Project→Module (import/component/set trộn thế nào), runtime, vueData/v_Set | `platform-architecture.md` |
|
|
26
|
-
| 4 thành phần module.json (data/watch/controls/set) — vai trò, cấu hình, tương tác | `module-json-anatomy.md` |
|
|
27
|
-
| **`HTMLOnly: true`** — server KHÔNG nhúng sẵn thư viện nào (Vue/Vuetify/jQuery/lodash/MDI/`projectdefaultstyle.css` đều vắng); cần gì phải tự khai trong chính module, và `script-map.md` KHÔNG áp dụng | `module-structure.md` §HTMLOnly=true: KHÔNG có thư viện nào được nhúng sẵn (Tier A, đã nạp sẵn) |
|
|
28
|
-
|
|
29
|
-
## Thiết kế UI / chọn component
|
|
30
|
-
|
|
31
|
-
| Tình huống | Load file |
|
|
32
|
-
|---|---|
|
|
33
|
-
| **Layout controls — class/prop/style ĐƯỢC DÙNG (đừng tự thêm style)** | `controls-styling-vocabulary.md` |
|
|
34
|
-
| Bắt đầu thiết kế UI, chọn component nào | `component-quickref.md` |
|
|
35
|
-
| Khai báo `data[]` — ba loại phần tử, thứ tự state → named action → auto-startup | `module-data-patterns.md` (value resolution + key lồng nhau: `controls-patterns.md` §0/§1, Tier A) |
|
|
36
|
-
| Pattern UI thực tế (data/watch/toolbar/filter/permission) | `ui-patterns.md` |
|
|
37
|
-
| **Hàng nhiều control / canh phải nhóm nút** — chuẩn `shrink` cho mọi cột trừ `v-spacer`; `w` px | `controls-patterns.md` (Tier A, đã nạp sẵn) |
|
|
38
|
-
| **f-table** — **hiển thị dữ liệu dạng datatable** (list/CRUD qua form dialog, cả readonly lẫn có `:update-api`) + điều khiển trong ô: t-check/t-button/t-select/t-menu, ctrl-update, show-select, chip-group | `ui-table-cell-patterns.md` |
|
|
39
|
-
| Bảng dữ liệu chuyên sâu (mọi props, header types, auto-headers khi bỏ `:headers`, **tổng cột `sum-format`** — object=hàng tổng trong bảng / string=dòng text dưới bảng, readonly table) | `component-table.md` |
|
|
40
|
-
| **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) — component có sẵn (nền tảng AG Grid), KHÔNG tự viết bảng nhập liệu bằng `uc-*.vue`; import, props, columns, wiring API | `fsheet.md` |
|
|
41
|
-
| Dialog / form popup (hidden-container, mở dialog với row, checkbox-list) | `ui-dialog-patterns.md` |
|
|
42
|
-
| Mở sub-window & trao đổi dữ liệu (`openWindow`, `#PARENT`/`#Win`) | `ui-crosswindow-patterns.md` |
|
|
43
|
-
| Layout: page-container, master-detail, v-switch, date init, dynamic label | `ui-layout-patterns.md` |
|
|
44
|
-
| Input controls (f-date, f-time, f-search, f-radiobox, text-field...) | `components-input.md` |
|
|
45
|
-
| Display components (f-label, f-title, f-box, f-header, chip, badge...) | `components-display.md` |
|
|
46
|
-
| Dialog components (f-dialog, v-dialog chi tiết) | `components-dialog.md` |
|
|
47
|
-
| Custom Vue component (`uc-*.vue`) — scope, props/events, **ưu tiên class Vuetify có sẵn (cấm _injectStyle)**, dialog chuẩn hoá, tận dụng ajaxCALL/confirm/showMessage | `component-design.md` |
|
|
48
|
-
| **Kiểm chứng `uc-*.vue` trong không gian riêng** (`component_preview`) + luật push component cấp project trước khi render module | `component-design.md` |
|
|
49
|
-
| **Tra component project-scope đã có** trước khi tạo mới — quy ước `{projectId}/COMPONENTS.md` + vòng tích luỹ | `component-design.md` §1a |
|
|
50
|
-
| Template/ví dụ tham chiếu nhanh | `ui-templates.md` + `examples/` |
|
|
51
|
-
| **User gửi ảnh chụp màn hình giao diện** vào chat, hoặc đọc screenshot từ `renderUI` — đánh giá lỗi hiển thị, màu sắc, padding/margin, căn chỉnh, vị trí nút | `ui-screenshot-review.md` |
|
|
52
|
-
|
|
53
|
-
## Biểu đồ / báo cáo / dashboard
|
|
54
|
-
|
|
55
|
-
| Tình huống | Load file |
|
|
56
|
-
|---|---|
|
|
57
|
-
| Dùng f-echart (nền tảng Apache ECharts) — import, props, config, theme, DataView, `grid` padding, `boundaryGap`, lỗi | `components-echart.md` |
|
|
58
|
-
| Chọn/vẽ loại chart cụ thể + pattern module.json | `echart-templates.md` |
|
|
59
|
-
| Xuất PDF (f-pdfmake) | `pdfmake.md` |
|
|
60
|
-
|
|
61
|
-
## API / Stored Procedure / tAPI
|
|
62
|
-
|
|
63
|
-
| Tình huống | Load file |
|
|
64
|
-
|---|---|
|
|
65
|
-
| Đặt tên SP, params, URL, response format, error, wiring | `tapi-reference.md` |
|
|
66
|
-
| **API trả 200 nhưng dữ liệu rỗng/sai**, hoặc sắp đổi/xoá tham số của một SP đã có module gọi — ghép tham số tAPI khoan dung (thiếu → `NULL`, thừa → bỏ qua, **không bao giờ báo lỗi**) | `tapi-reference.md` §2 |
|
|
67
|
-
| **Đọc HTTP header trong SP** (`User-Agent`, `Cookie`, `X-Forwarded-For`, IP client, thiết bị/trình duyệt) — họ `@sys_header_*`, mỗi dấu `-` đổi thành `_` | `tapi-reference.md` §2 |
|
|
68
|
-
| Kiểm tra quyền trong SP (5 pattern, `@sys_SystemRight`, `getSystemRight`) | `tapi-permission-patterns.md` |
|
|
69
|
-
| Upload/download/xem file qua SP (`spAPIFILE_`, `fileContent`, `tblFileData`) | `tapi-file-api.md` |
|
|
70
|
-
| Hàm SQL CLR: httpCall, sendMail, ImageResize, FileReader, RegexMatch... | `sql-clr-functions.md` |
|
|
71
|
-
|
|
72
|
-
## Phân quyền người dùng
|
|
73
|
-
|
|
74
|
-
| Tình huống | Load file |
|
|
75
|
-
|---|---|
|
|
76
|
-
| Khái niệm `SystemRight` (cấp bậc) vs `FunctionRight` (quyền theo chức năng), `v-if`/menu `right`, và 8 tool quản lý định nghĩa quyền (`right_system_list/new/update/delete`, `right_function_list/new/update/delete`) | `permission-system.md` |
|
|
77
|
-
| **Sắp gác một control/menu/SP bằng mã quyền** — mã đó có tồn tại thật không, tạo thế nào | `permission-system.md` (§"mã quyền phải TỒN TẠI trước khi đem gác") |
|
|
78
|
-
| Kiểm tra quyền trong thân SP (5 pattern SQL) | `tapi-permission-patterns.md` |
|
|
1
|
+
# FUI Reference Router (INDEX)
|
|
79
2
|
|
|
80
|
-
|
|
3
|
+
Routing only; rules live in target files. Printed by `fui skill get` with SKILL.md. Before any task, find the row and load the file — never rely on memory.
|
|
81
4
|
|
|
82
|
-
|
|
83
|
-
|---|---|
|
|
84
|
-
| **Database CHƯA tồn tại** — tạo DB SQL Server mới, hai loại tài khoản SQL, đăng ký alias tAPI vào `acc` | `project-provisioning.md` |
|
|
85
|
-
| **Sắp chạy `CREATE DATABASE` / `CREATE LOGIN`** — kiểm quyền cấp máy chủ trước (`sysadmin`, hoặc `CREATE ANY DATABASE` + `ALTER ANY LOGIN`); thiếu quyền thì từ chối chứ đừng chạy thử | `project-provisioning.md` §Bước 0 |
|
|
86
|
-
| Kết nối DB, dbToken, schema, workflow SP | `db-workflow.md` |
|
|
87
|
-
| **Project gọi nhiều database** (module.json có `"API": "/{alias}/…"` với nhiều alias khác nhau) — mỗi alias một `db_connect`, tham số `db` chọn kết nối, tool trả MENU khi nhập nhằng | `db-workflow.md` (§1, §4) |
|
|
88
|
-
| **SSO xuyên domain** — userToken cùng domain cha dùng được ngay, không cần hỏi lại hay xác minh | `db-workflow.md` §6a |
|
|
89
|
-
| **Linked Server** — SP qua ranh giới linked server, quy ước đặt tên `spIO_IN_` / `spIO_OUT_` | `db-workflow.md` §8a |
|
|
90
|
-
| Quy tắc thiết kế bảng (đặt tên, PK/FK, cột audit) | `db-table-design.md` |
|
|
91
|
-
|
|
92
|
-
## Quy trình / thiết kế hệ thống
|
|
93
|
-
|
|
94
|
-
| Tình huống | Load file |
|
|
95
|
-
|---|---|
|
|
96
|
-
| **"Tạo dự án mới" / "tạo DB + project FUI mới"** — dựng hạ tầng từ số 0: CREATE DATABASE, tài khoản ứng dụng vs dev, alias `acc`, `project_new`, cấp quyền quản trị. Làm TRƯỚC `system-design.md` | `project-provisioning.md` |
|
|
97
|
-
| **Cấp/thu hồi quyền SỬA PROJECT trong IDE FUI** cho một lập trình viên (`UserRight`, 5 tool `project_user_*`) — khác hẳn quyền người dùng cuối ở `permission-system.md` | `project-provisioning.md` (§Bước 6) |
|
|
98
|
-
| **Thiết kế cả app nhiều module từ mô tả** (phân rã, schema-first, menu, quyền) | `system-design.md` |
|
|
99
|
-
| Tạo một module fullstack (UI + API) — quy trình 6 bước UI-first | `fullstack-workflow.md` |
|
|
100
|
-
| Cấu hình project.json: menu, điều hướng, phân quyền, domain | `project-config.md` |
|
|
101
|
-
|
|
102
|
-
## Scripting / kỹ thuật nâng cao
|
|
103
|
-
|
|
104
|
-
| Tình huống | Load file |
|
|
105
|
-
|---|---|
|
|
106
|
-
| **Cần chạy nhiều lệnh có thứ tự** (reset state → reload → báo toast) trong `CALLBACK`/`:action`/`watch`/`THEN` | `controls-patterns.md` §QUY TẮC NỀN (Tier A, đã nạp sẵn) |
|
|
107
|
-
| Watcher patterns (v_old, deep-watch, cascading) | `watcher-patterns.md` |
|
|
108
|
-
| Kỹ thuật nâng cao (EXE, MAP, expression phức tạp) | `advanced-techniques.md` |
|
|
109
|
-
| **Trang trắng / app rỗng dù 0 JS error, 0 Vue warn**, hoặc cần đặt logic phức tạp vào `:attr` `:option` `:config` | `advanced-techniques.md` §1 + chạy `module_validate` |
|
|
110
|
-
| **`… is not defined` lúc render**, hoặc một `EXE`/`FUN` "chạy xong mà không làm gì" | `advanced-techniques.md` §2 (hàm phải có thật trong `script.js` — nhớ `module_publish_script`). ⚠️ `module_validate` KHÔNG bắt được ca này, phải `module_simulate({renderUI:true})` |
|
|
111
|
-
| Hàm tiện ích FUI có sẵn (openWindow, ajaxCALL, jsonToExcel, groupBy...) | `default-function.md` |
|
|
112
|
-
| **Thư viện đã bundled sẵn** (jQuery, lodash, moment, numeral, toast, jquery-confirm) — biết trước khi định thêm CDN. ⚠️ Chỉ đúng với `HTMLOnly=false` | `script-map.md` §0 |
|
|
113
|
-
| Bản đồ script FUI (defaultfunction.js, component.js...) | `script-map.md` |
|
|
114
|
-
| FUI project bootstrapper (fastproject) | `fastproject.md` |
|
|
115
|
-
| Coding standards | `coding-standards.md` |
|
|
116
|
-
| Real-time / SignalR (webSocketJoinGroup, webSocket_Send) | `websocket-realtime.md` |
|
|
117
|
-
|
|
118
|
-
## Vận hành / publish / deploy
|
|
119
|
-
|
|
120
|
-
| Tình huống | Load file |
|
|
121
|
-
|---|---|
|
|
122
|
-
| **"new session" / "phiên mới" / "cửa sổ mới"** — mở thêm một phiên Claude Code CLI ở cửa sổ terminal riêng (lấy workspace root động, KHÔNG hard-code đường dẫn) | `new-session.md` |
|
|
123
|
-
| Mức độ an toàn của từng MCP tool (R/M, Safe/Confirm/Destructive), strict mode, `db_sp_verify`, error log | `tools-registry.md` |
|
|
124
|
-
| Checklist definition-of-done trước khi publish (kèm bước `module_validate` + `module_outline` + `module_simulate` + `db_sp_verify` tĩnh) | `verification.md` |
|
|
125
|
-
| **UI hỏng mà chưa biết vì sao — chọn tầng kiểm chứng nào cho rẻ nhất** (ma trận triệu chứng → tầng; đọc TRƯỚC khi chạy `renderUI`, và đọc lại khi đã render ≥2 lượt mà chưa khá hơn) | `verification.md` §Chọn tầng kiểm chứng |
|
|
126
|
-
|
|
127
|
-
---
|
|
5
|
+
Load: `fui skill ref references/a.md references/b.md` (several at once OK).
|
|
128
6
|
|
|
129
|
-
##
|
|
7
|
+
## Tier A (load first via `fui skill ref`)
|
|
8
|
+
|
|
9
|
+
- `controls-patterns.md` — foundation: action engine (§CORE RULE: one `{}` = one command; sequential commands = array `[{…},{…}]`), value resolution, key notation, layout grid
|
|
10
|
+
- `module-structure.md` — module/project files, layout rules
|
|
11
|
+
- `INDEX.md` — this router
|
|
12
|
+
|
|
13
|
+
## Foundations (read early)
|
|
14
|
+
|
|
15
|
+
- FUI anatomy, Project→Module hierarchy (import/component/set merge), runtime, vueData/v_Set → `platform-architecture.md`
|
|
16
|
+
- module.json's 4 parts (data/watch/controls/set) → `module-json-anatomy.md`
|
|
17
|
+
- `HTMLOnly: true`: server embeds NO library (Vue/Vuetify/jQuery/lodash/MDI/`projectdefaultstyle.css` absent); declare all in the module; `script-map.md` does NOT apply → `module-structure.md` §HTMLOnly=true: KHÔNG có thư viện nào được nhúng sẵn
|
|
18
|
+
|
|
19
|
+
## UI / components
|
|
20
|
+
|
|
21
|
+
- Allowed control class/prop/style (never invent styles) → `controls-styling-vocabulary.md`
|
|
22
|
+
- Area with its own scrollbar / user wants a restyled scrollbar → built-in class `fpScrollbar`, NEVER hand-write `::-webkit-scrollbar`; put it only on the element that actually scrolls, NOT nested → `controls-styling-vocabulary.md` §Scrollbar
|
|
23
|
+
- Start UI, pick component → `component-quickref.md`
|
|
24
|
+
- `data[]`: three element kinds, order state → named action → auto-startup → `module-data-patterns.md` (value resolution, nested keys: `controls-patterns.md` §0/§1)
|
|
25
|
+
- Real patterns (data/watch/toolbar/filter/permission) → `ui-patterns.md`
|
|
26
|
+
- Multi-control row / right-aligned buttons: `shrink` on every column except `v-spacer`; `w` in px → `controls-patterns.md`
|
|
27
|
+
- f-table: datatable display (list/CRUD via form dialog, readonly or `:update-api`) + cell controls t-check/t-button/t-select/t-menu, ctrl-update, show-select, chip-group → `ui-table-cell-patterns.md`
|
|
28
|
+
- Table deep-dive: all props, header types, auto-headers without `:headers`, `sum-format` (object = total row in table / string = text line below), readonly, **Excel export button `excel`** (`true` = raw data / `"UI"` = rows and columns as displayed: filtered, sorted, header names and column count, but values stay raw and unformatted) → `component-table.md`
|
|
29
|
+
- f-sheet: Excel-style in-place entry (paste from Excel, no dialog), built-in (AG Grid); NEVER hand-build an entry grid in `uc-*.vue`; import, props, columns, API wiring → `fsheet.md`
|
|
30
|
+
- Popup form (hidden-container, open with row, checkbox-list) → `ui-dialog-patterns.md`
|
|
31
|
+
- Sub-window data exchange (`openWindow`, `#PARENT`/`#Win`) → `ui-crosswindow-patterns.md`
|
|
32
|
+
- page-container, master-detail, v-switch, date init, dynamic label → `ui-layout-patterns.md`
|
|
33
|
+
- Inputs (f-date, f-time, f-search, f-radiobox, text-field…) → `components-input.md`
|
|
34
|
+
- Display (f-label, f-title, f-box, f-header, chip, badge…) → `components-display.md`
|
|
35
|
+
- f-dialog, v-dialog → `components-dialog.md`
|
|
36
|
+
- `uc-*.vue`: scope, props/events, built-in Vuetify classes (no `_injectStyle`), standard dialog, reuse ajaxCALL/confirm/showMessage → `component-design.md`
|
|
37
|
+
- Isolated `uc-*.vue` check (`fui component preview`); push project-level components before rendering the module → `component-design.md`
|
|
38
|
+
- Check existing project-scope components before creating: `{projectId}/COMPONENTS.md` + accumulation loop → `component-design.md` §1a
|
|
39
|
+
- Templates → `ui-templates.md` + `examples/`
|
|
40
|
+
- UI screenshot (from user or `--render`): display bugs, colors, padding/margin, alignment, button placement → `ui-screenshot-review.md`
|
|
41
|
+
|
|
42
|
+
## Charts / reports
|
|
130
43
|
|
|
131
|
-
|
|
44
|
+
- f-echart (Apache ECharts): import, props, config, theme, DataView, `grid` padding, `boundaryGap`, errors → `components-echart.md`
|
|
45
|
+
- Specific chart type + module.json pattern → `echart-templates.md`
|
|
46
|
+
- PDF (f-pdfmake) → `pdfmake.md`
|
|
132
47
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
48
|
+
## API / SP / tAPI
|
|
49
|
+
|
|
50
|
+
- SP naming, params, URL, response, errors, wiring → `tapi-reference.md`
|
|
51
|
+
- 200 but empty/wrong data, or changing/removing params of an SP a module calls: lenient binding (missing → `NULL`, extra → ignored, never errors) → `tapi-reference.md` §2
|
|
52
|
+
- HTTP headers in SP (`User-Agent`, `Cookie`, `X-Forwarded-For`, client IP, device/browser): `@sys_header_*`, each `-` → `_` → `tapi-reference.md` §2
|
|
53
|
+
- SP permission checks (5 patterns, `@sys_SystemRight`, `getSystemRight`) → `tapi-permission-patterns.md`
|
|
54
|
+
- File upload/download/view (`spAPIFILE_`, `fileContent`, `tblFileData`) → `tapi-file-api.md`
|
|
55
|
+
- SQL CLR: httpCall, sendMail, ImageResize, FileReader, RegexMatch… → `sql-clr-functions.md`
|
|
56
|
+
|
|
57
|
+
## User permissions
|
|
58
|
+
|
|
59
|
+
- `SystemRight` (level) vs `FunctionRight` (per function), `v-if`/menu `right`, `fui right system|function list/new/update/delete` (8 commands) → `permission-system.md`
|
|
60
|
+
- Guarding control/menu/SP with a right code — it must exist; how to create → `permission-system.md` (§"mã quyền phải TỒN TẠI trước khi đem gác")
|
|
61
|
+
- SQL permission checks in SP body → `tapi-permission-patterns.md`
|
|
62
|
+
|
|
63
|
+
## Database
|
|
64
|
+
|
|
65
|
+
- DB doesn't exist: new SQL Server DB, two SQL account types, tAPI alias in `acc` → `project-provisioning.md`
|
|
66
|
+
- Before `CREATE DATABASE` / `CREATE LOGIN`: check server rights (`sysadmin`, or `CREATE ANY DATABASE` + `ALTER ANY LOGIN`); if missing, refuse, no trial run → `project-provisioning.md` §Step 0
|
|
67
|
+
- Connection, dbToken, schema, SP workflow → `db-workflow.md`
|
|
68
|
+
- Multiple DBs / an alias repeated across zones: `connectionName` names a readable folder, `apiName` is stored separately, `--db` picks the connection → `db-workflow.md` (§1, §4)
|
|
69
|
+
- Cross-domain SSO: userToken of same parent domain works as-is; don't re-ask/verify → `db-workflow.md` §6a
|
|
70
|
+
- Linked Server SPs, naming `spIO_IN_` / `spIO_OUT_` → `db-workflow.md` §8a
|
|
71
|
+
- Table design (naming, PK/FK, audit columns) → `db-table-design.md`
|
|
72
|
+
|
|
73
|
+
## Process / system design
|
|
74
|
+
|
|
75
|
+
- New project / new DB + FUI project from zero: CREATE DATABASE, app vs dev accounts, `acc` alias, `fui project new`, admin grant; do BEFORE `system-design.md` → `project-provisioning.md`
|
|
76
|
+
- Grant/revoke IDE project-edit rights for a developer (`UserRight`, `fui user search/list/add/set/remove`); not end-user rights (`permission-system.md`) → `project-provisioning.md` (§Step 6)
|
|
77
|
+
- Multi-module app from a description (decomposition, schema-first, menu, rights) → `system-design.md`
|
|
78
|
+
- One fullstack module, 6-step UI-first → `fullstack-workflow.md`
|
|
79
|
+
- project.json: menu, navigation, permissions, domain → `project-config.md`
|
|
80
|
+
|
|
81
|
+
## Scripting / advanced
|
|
82
|
+
|
|
83
|
+
- Ordered commands (reset → reload → toast) in `CALLBACK`/`:action`/`watch`/`THEN` → `controls-patterns.md` §CORE RULE
|
|
84
|
+
- v_old, deep-watch, cascading → `watcher-patterns.md`
|
|
85
|
+
- EXE, MAP, complex expressions → `advanced-techniques.md`
|
|
86
|
+
- Blank page with 0 JS errors and 0 Vue warns, or complex logic in `:attr` `:option` `:config` → `advanced-techniques.md` §1 + `fui module validate`
|
|
87
|
+
- `… is not defined` at render, or `EXE`/`FUN` doing nothing → `advanced-techniques.md` §2 (function must exist in `script.js`; `fui module publish script`). ⚠️ `fui module validate` misses this; use `fui module simulate --render`
|
|
88
|
+
- Built-in utilities (openWindow, ajaxCALL, jsonToExcel, groupBy…) → `default-function.md`
|
|
89
|
+
- Bundled libs (jQuery, lodash, moment, numeral, toast, jquery-confirm) — check before adding a CDN; ⚠️ `HTMLOnly=false` only → `script-map.md` §0
|
|
90
|
+
- Script map (defaultfunction.js, component.js…) → `script-map.md`
|
|
91
|
+
- fastproject bootstrapper → `fastproject.md`
|
|
92
|
+
- Coding standards → `coding-standards.md`
|
|
93
|
+
- SignalR (webSocketJoinGroup, webSocket_Send) → `websocket-realtime.md`
|
|
94
|
+
|
|
95
|
+
## Operations / publish
|
|
96
|
+
|
|
97
|
+
- "new session" / "phiên mới" / "cửa sổ mới": open another Claude Code CLI in its own terminal window (workspace root resolved dynamically, NEVER hard-coded) → `new-session.md`
|
|
98
|
+
- Hand work / instructions to another running Claude session (coordinating several sessions, a multi-AI workflow, parallelizing work per module) — `ListAgents`/`SendMessage` → `new-session.md` §6
|
|
99
|
+
- Per-command safety (R/M, Safe/Confirm/Destructive), strict mode, `fui sp verify`, error log → `tools-registry.md`
|
|
100
|
+
- Pre-publish definition-of-done (`fui module validate` + `fui module outline` + `fui module simulate` + static `fui sp verify`) → `verification.md`
|
|
101
|
+
- UI broken, cause unknown — cheapest verification layer (symptom → layer; read BEFORE `--render`, reread after ≥2 renders without progress) → `verification.md` §Chọn tầng kiểm chứng
|
|
102
|
+
|
|
103
|
+
## Design system
|
|
137
104
|
|
|
138
|
-
|
|
139
|
-
|---|---|
|
|
140
|
-
| Chọn App-mode hay Web-mode, giới hạn `border-radius`, vòng tích luỹ `{projectId}/DESIGN.md` | `design-modes.md` |
|
|
141
|
-
| Anatomy dialog/form/bảng màu chuẩn App-mode | tool `design_read("fui")` (không qua `skill_reference_get`) |
|
|
105
|
+
Pick the mode BEFORE writing controls. Owner: `design-modes.md`.
|
|
142
106
|
|
|
143
|
-
-
|
|
144
|
-
-
|
|
107
|
+
- App-mode (default): CRUD, forms, lists, internal dashboards. Source: ONLY `fui design read fui` + `controls-styling-vocabulary.md`; NO brand DESIGN.md, NO custom styles.
|
|
108
|
+
- Web-mode: landing/intro/public pages (usually `HTMLOnly: true`). Source: `fui design list` → `fui design read <brand>` by tone/industry; free CSS in header.html.
|
|
109
|
+
- Mode choice, `border-radius` limits, `{projectId}/DESIGN.md` loop → `design-modes.md`
|
|
110
|
+
- App-mode dialog/form/palette anatomy → `fui design read fui` (not `fui skill ref`)
|
|
111
|
+
- `{projectId}/DESIGN.md`, if present, overrides same-topic rules of the active mode; check before designing.
|
|
112
|
+
- User UI feedback → record rule in `{projectId}/DESIGN.md` (`design-modes.md` §3).
|
|
@@ -1,57 +1,60 @@
|
|
|
1
1
|
# Advanced FUI Techniques
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
This document captures advanced patterns and techniques for FUI development, extracted from real-world implementations.
|
|
3
|
+
> Owns: **advanced techniques: `EXE`, `MAP`, complex expressions, pure-expression rule for `:attr`, rule that functions called in `EXE`/`FUN` must really exist**. Basic action engine: [controls-patterns.md](controls-patterns.md).
|
|
6
4
|
|
|
7
5
|
---
|
|
8
6
|
|
|
9
|
-
## 1. `:attr`
|
|
7
|
+
## 1. `:attr` takes a PURE EXPRESSION — never statements
|
|
10
8
|
|
|
11
|
-
**
|
|
9
|
+
**Hard rule.** Every binding value in `module.json` — `:option`, `:config`, `:items`, `:headers`, `:style`, every `v-bind:*` — goes **straight to Vue's template compiler**, which accepts **one expression**. Never include:
|
|
12
10
|
|
|
13
|
-
- `function(){ ... }`
|
|
11
|
+
- `function(){ ... }` or IIFE `(function(){...})()`
|
|
14
12
|
- `return`
|
|
15
13
|
- `var` / `let` / `const`
|
|
16
|
-
-
|
|
14
|
+
- `;` joining statements
|
|
15
|
+
|
|
16
|
+
### Why it is worse than it looks
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
A statement in `:attr` breaks template compilation and Vue **swallows the error**: **blank page, 0 JS errors, 0 `[Vue warn]`**, no stack trace — found only after many `fui module simulate --render` rounds. That is why `fui module validate` reports it as an **error**, not a warning.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
> Unlike `data[]` / `IN` / `{{ }}`, which go through FUI's `getVueData()` (see [controls-patterns.md](controls-patterns.md) §0 Value Resolution) with their own rules, `:attr` does **not**.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
### Allowed in `:attr`
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
| Form | Example |
|
|
25
|
+
| ---------------------------------- | ------------------------------------------------------- |
|
|
26
|
+
| Object / array literal | `":config": "{ height: 300, legend: { show: true } }"` |
|
|
27
|
+
| Ternary | `":color": "ok ? 'primary' : 'warning'"` |
|
|
28
|
+
| Arrow `.map` / `.filter` chains | `":items": "ds.filter(x => x.Active).map(x => x.Name)"` |
|
|
29
|
+
| Property access / vueData variable | `":option": "optThe"` |
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|---|---|
|
|
28
|
-
| Object / array literal | `":config": "{ height: 300, legend: { show: true } }"` |
|
|
29
|
-
| Ternary | `":color": "ok ? 'primary' : 'warning'"` |
|
|
30
|
-
| Chuỗi arrow `.map` / `.filter` | `":items": "ds.filter(x => x.Active).map(x => x.Name)"` |
|
|
31
|
-
| Truy cập thuộc tính / biến vueData | `":option": "optThe"` |
|
|
31
|
+
### Complex logic → `script.js` + `EXE`
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
Multi-step transforms, temp variables, loops, complex conditions → **not in `:attr`**:
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
1. Write a plain function in `script.js`: `function tenHam(){ ... }`
|
|
36
|
+
2. It **assigns directly to `vueData.xxx`** (does not `return` a value for JSON)
|
|
37
|
+
3. Call it via `EXE` — usually in the data-loading action's `CALLBACK`: `"EXE": "tenHam()"`
|
|
38
|
+
4. `:attr` in `module.json` only points at the variable: `":option": "optThe"`
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
2. Hàm **gán thẳng vào `vueData.xxx`** (không `return` giá trị cho JSON đọc)
|
|
39
|
-
3. Gọi hàm qua `EXE` — thường trong `CALLBACK` của action nạp dữ liệu: `"EXE": "tenHam()"`
|
|
40
|
-
4. `:attr` trong `module.json` chỉ trỏ tới biến đó: `":option": "optThe"`
|
|
40
|
+
❌ **Wrong** — IIFE in `:attr`:
|
|
41
41
|
|
|
42
|
-
❌ **Sai** — IIFE trong `:attr`:
|
|
43
42
|
```json
|
|
44
43
|
":option": "(function(){ var src = vueData.ds.filter(r => r.id===1); return { series:[{data: src}] }; })();"
|
|
45
44
|
```
|
|
46
45
|
|
|
47
|
-
✅
|
|
46
|
+
✅ **Right**:
|
|
47
|
+
|
|
48
48
|
```javascript
|
|
49
49
|
// script.js
|
|
50
50
|
function buildChart() {
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
var src = vueData.ds.filter(function (r) {
|
|
52
|
+
return r.id === 1;
|
|
53
|
+
});
|
|
54
|
+
vueData.optThe = { series: [{ data: src }] };
|
|
53
55
|
}
|
|
54
56
|
```
|
|
57
|
+
|
|
55
58
|
```json
|
|
56
59
|
// module.json — action nạp dữ liệu
|
|
57
60
|
"CALLBACK": { "EXE": "buildChart()" },
|
|
@@ -59,102 +62,107 @@ function buildChart() {
|
|
|
59
62
|
":option": "optThe"
|
|
60
63
|
```
|
|
61
64
|
|
|
62
|
-
`:option`
|
|
65
|
+
Declare `:option`'s variable as `{}` in `data[]` so the first render doesn't break; `buildChart()` assigns the real value after the API returns.
|
|
63
66
|
|
|
64
|
-
###
|
|
67
|
+
### Diagnosing a blank page with "0 JS error, 0 Vue warn"
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
Not a runtime error — suspect **`:attr` template compilation** first, not `script.js` or the action engine.
|
|
67
70
|
|
|
68
|
-
|
|
71
|
+
Isolate: replace a suspect expression with a simple static value (`":option": "{}"` or remove the attr) and re-render. **Page comes back ⇒ that expression is the culprit.** Repeat per suspect `:attr` until one remains.
|
|
69
72
|
|
|
70
|
-
|
|
73
|
+
Running `fui module validate` before rendering catches most of these as errors.
|
|
71
74
|
|
|
72
75
|
---
|
|
73
76
|
|
|
74
|
-
## 2.
|
|
77
|
+
## 2. Functions called in `EXE` / `FUN` must REALLY EXIST
|
|
75
78
|
|
|
76
|
-
**
|
|
79
|
+
**Hard rule.** `"EXE": "buildChart()"` and `"FUN": "buildChart"` work only if `buildChart` is a **real global function** at runtime — declared in `{moduleDir}/script.js`, in an imported `.js` file, or a platform built-in ([default-function.md](default-function.md), [script-map.md](script-map.md)).
|
|
77
80
|
|
|
78
|
-
|
|
81
|
+
This is the flip side of §1: moving logic to `script.js` and calling via `EXE` **often loses its second half**. `module.json` is edited, `EXE` written, `fui module publish json` run — but nobody writes `script.js` or runs `fui module publish script`.
|
|
79
82
|
|
|
80
|
-
###
|
|
83
|
+
### Why nothing tells you
|
|
81
84
|
|
|
82
|
-
|
|
85
|
+
Two commands, two failure modes, **neither shows the function name prominently**:
|
|
83
86
|
|
|
84
|
-
|
|
|
85
|
-
|
|
86
|
-
| `EXE`
|
|
87
|
-
| `FUN`
|
|
87
|
+
| Command | Mechanism | Symptom when missing |
|
|
88
|
+
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
89
|
+
| `EXE` | Runs through `templateCompiled(\`<% … %>\`)`— lodash`_.template`. A comma-operator bug at `fastproject-3.0.js:490` means **the data object is never passed**, so bare identifiers resolve to **global** | `ReferenceError: buildChart is not defined` — shows only in `fui module simulate --render`, as just **"1 JS error"** in a long report |
|
|
90
|
+
| `FUN` | `runFunction()` looks up `window[obj.FUN]`; if absent, `console.log("Func:", …, "not found")` and **continues** | **Completely silent.** No error, no `[Vue warn]`, the action "finishes" and does nothing |
|
|
88
91
|
|
|
89
|
-
|
|
92
|
+
Measured cost: one module burned **36 consecutive `--render` runs over 5 days** on this bug class (`buildKPI8Columns is not defined`).
|
|
90
93
|
|
|
91
|
-
###
|
|
94
|
+
### The only layer that catches it: **`fui module simulate --render`**
|
|
92
95
|
|
|
93
|
-
`
|
|
96
|
+
`fui module validate` does **NOT** check this: it does not read `script.js`. (A static rule once did, and was removed — to avoid false positives it had to know **every** platform global, a list never complete; each missing name blocked publishing a working module.) `fui module simulate` in vm mode doesn't catch it either — it doesn't load `script.js` into the sandbox, so it reports ReferenceError for **every** module using `script.js` functions, even correct ones.
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
So verify with **`--render`**: the real browser throws `ReferenceError: buildChart is not defined`, and **every JS error now makes the result an error (`isError`)** — not only init errors; errors from button clicks count too. The message is in the `═══ CHẨN ĐOÁN ═══` block at the **top** of the report, line `[MODULE]`.
|
|
96
99
|
|
|
97
|
-
⚠️
|
|
100
|
+
⚠️ **`--render` does not catch the `FUN` case** — `runFunction` just `console.log`s and continues, throwing nothing. For `FUN`, **check function names against `script.js` yourself**; the only symptom is "action finishes, nothing happens".
|
|
98
101
|
|
|
99
|
-
###
|
|
102
|
+
### Fix
|
|
100
103
|
|
|
101
|
-
1.
|
|
102
|
-
2. **`
|
|
103
|
-
3.
|
|
104
|
+
1. Write the function in `script.js`: `function buildChart(){ … vueData.optThe = …; }`
|
|
105
|
+
2. **`fui module publish script`** — the most-forgotten step. `fui module publish json` does **not** push `script.js`.
|
|
106
|
+
3. Typo → fix the name; never add an empty function to silence the error.
|
|
104
107
|
|
|
105
108
|
---
|
|
106
109
|
|
|
107
110
|
## 3. Advanced Logic & Scripting
|
|
108
111
|
|
|
109
|
-
|
|
112
|
+
JSON logic is limited; use `script.js` for complex operations.
|
|
113
|
+
|
|
114
|
+
### Computed properties workaround
|
|
110
115
|
|
|
111
|
-
|
|
112
|
-
FUI `module.json` does not natively support computed properties.
|
|
113
|
-
**Solution:** Define calculation functions in `script.js` and call them directly in `module.json`.
|
|
116
|
+
`module.json` has no native computed properties. Define calculation functions in `script.js` and call them from `module.json`.
|
|
114
117
|
|
|
115
118
|
**script.js**:
|
|
119
|
+
|
|
116
120
|
```javascript
|
|
117
121
|
function getTongTien() {
|
|
118
|
-
|
|
122
|
+
return vueData.items.reduce((sum, item) => sum + (item.amount || 0), 0);
|
|
119
123
|
}
|
|
120
124
|
```
|
|
121
125
|
|
|
122
126
|
**module.json**:
|
|
127
|
+
|
|
123
128
|
```json
|
|
124
129
|
{
|
|
125
130
|
"innerHTML": "Total: {{getTongTien().toLocaleString()}} VNĐ"
|
|
126
131
|
}
|
|
127
132
|
```
|
|
128
133
|
|
|
129
|
-
### Complex
|
|
130
|
-
|
|
134
|
+
### Complex validation
|
|
135
|
+
|
|
136
|
+
Don't write long logic strings in JSON; move validation to `script.js`.
|
|
131
137
|
|
|
132
138
|
**script.js**:
|
|
139
|
+
|
|
133
140
|
```javascript
|
|
134
141
|
function validateStep1() {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
142
|
+
const d = vueData;
|
|
143
|
+
if (!d.name || !d.email) {
|
|
144
|
+
alert("Missing required fields!");
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
return true;
|
|
141
148
|
}
|
|
142
149
|
|
|
143
150
|
function nextStep() {
|
|
144
|
-
|
|
145
|
-
|
|
151
|
+
if (vueData.step === 1 && !validateStep1()) return;
|
|
152
|
+
vueData.step++;
|
|
146
153
|
}
|
|
147
154
|
```
|
|
148
155
|
|
|
149
156
|
**module.json**:
|
|
157
|
+
|
|
150
158
|
```json
|
|
151
159
|
"v-on:click": "nextStep()"
|
|
152
160
|
```
|
|
153
161
|
|
|
154
|
-
### Action
|
|
155
|
-
|
|
162
|
+
### Action binding
|
|
163
|
+
|
|
164
|
+
For simple UI logic you may bind JS functions to events directly instead of the `CALL` action protocol.
|
|
156
165
|
|
|
157
166
|
```json
|
|
158
167
|
"v-on:click": "prevBuoc()"
|
|
159
168
|
```
|
|
160
|
-
|