@fui-org/fui-cli 2.1.4 → 2.2.1
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 +16 -7
- package/dist/fui-xg17j3f9.js +396 -0
- package/dist/fui.js +1 -1
- package/package.json +1 -1
- package/skills/fui/SKILL.md +152 -39
- package/skills/{fui-skill → fui}/assets/projectdefaultstyle.css +489 -489
- package/skills/{fui-skill → fui}/examples/component.vue +162 -162
- package/skills/{fui-skill → fui}/references/INDEX.md +4 -5
- package/skills/{fui-skill → fui}/references/advanced-techniques.md +170 -168
- package/skills/{fui-skill → fui}/references/component-design.md +2 -2
- package/skills/{fui-skill → fui}/references/component-quickref.md +78 -78
- package/skills/{fui-skill → fui}/references/component-table.md +287 -287
- package/skills/{fui-skill → fui}/references/components-dialog.md +191 -191
- package/skills/{fui-skill → fui}/references/components-display.md +141 -141
- package/skills/{fui-skill → fui}/references/components-echart.md +316 -316
- package/skills/{fui-skill → fui}/references/components-input.md +335 -335
- package/skills/{fui-skill → fui}/references/controls-patterns.md +2 -2
- package/skills/{fui-skill → fui}/references/controls-styling-vocabulary.md +173 -173
- package/skills/{fui-skill → fui}/references/db-workflow.md +9 -9
- package/skills/{fui-skill → fui}/references/default-function.md +456 -456
- package/skills/{fui-skill → fui}/references/design-modes.md +57 -57
- package/skills/{fui-skill → fui}/references/echart-templates.md +489 -489
- package/skills/{fui-skill → fui}/references/fastproject.md +99 -99
- package/skills/{fui-skill → fui}/references/fullstack-workflow.md +314 -313
- package/skills/{fui-skill → fui}/references/module-data-patterns.md +117 -117
- package/skills/{fui-skill → fui}/references/module-json-anatomy.md +132 -132
- package/skills/{fui-skill → fui}/references/module-structure.md +144 -144
- package/skills/{fui-skill → fui}/references/new-session.md +3 -20
- package/skills/{fui-skill → fui}/references/pdfmake.md +60 -60
- package/skills/{fui-skill → fui}/references/permission-system.md +1 -1
- package/skills/{fui-skill → fui}/references/platform-architecture.md +269 -269
- package/skills/{fui-skill → fui}/references/project-config.md +303 -303
- package/skills/{fui-skill → fui}/references/project-provisioning.md +4 -4
- package/skills/{fui-skill → fui}/references/script-map.md +262 -262
- package/skills/{fui-skill → fui}/references/sql-clr-functions.md +225 -225
- package/skills/{fui-skill → fui}/references/system-design.md +3 -3
- package/skills/{fui-skill → fui}/references/tapi-permission-patterns.md +156 -156
- package/skills/{fui-skill → fui}/references/tapi-reference.md +474 -474
- package/skills/fui/references/tools-registry.md +214 -0
- package/skills/{fui-skill → fui}/references/ui-crosswindow-patterns.md +321 -321
- package/skills/{fui-skill → fui}/references/ui-dialog-patterns.md +255 -255
- package/skills/{fui-skill → fui}/references/ui-layout-patterns.md +176 -176
- package/skills/{fui-skill → fui}/references/ui-patterns.md +303 -303
- package/skills/{fui-skill → fui}/references/ui-screenshot-review.md +95 -95
- package/skills/{fui-skill → fui}/references/ui-table-cell-patterns.md +318 -318
- package/skills/{fui-skill → fui}/references/verification.md +18 -18
- package/skills/{fui-skill → fui}/references/watcher-patterns.md +163 -163
- package/skills/{fui-skill → fui}/references/websocket-realtime.md +271 -271
- package/skills/{fui-skill → fui}/scripts/component-3.0.js +2715 -2715
- package/skills/{fui-skill → fui}/scripts/component.js +3147 -3147
- package/skills/{fui-skill → fui}/scripts/componentTable-3.0.js +1038 -1038
- package/skills/{fui-skill → fui}/scripts/componentTable.js +891 -891
- package/skills/{fui-skill → fui}/scripts/defaultfunction-3.0.js +866 -866
- package/skills/{fui-skill → fui}/scripts/defaultfunction.js +1051 -1051
- package/skills/{fui-skill → fui}/scripts/fastproject-3.0.js +870 -870
- package/skills/{fui-skill → fui}/scripts/fastproject.js +828 -828
- package/dist/fui-h4z7zhk2.js +0 -381
- package/skills/fui-skill/SKILL.md +0 -139
- package/skills/fui-skill/references/tools-registry.md +0 -84
- /package/skills/{fui-skill → fui}/assets/projectdefaultstyle-3.0.css +0 -0
- /package/skills/{fui-skill → fui}/design-md/airbnb/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airbnb/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airtable/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airtable/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/apple/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/apple/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/asu/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/asu/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/binance/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/binance/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw-m/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw-m/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bugatti/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bugatti/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cal/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cal/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/claude/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/claude/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clay/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clay/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clickhouse/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clickhouse/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cohere/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cohere/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/coinbase/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/coinbase/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/composio/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/composio/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cursor/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cursor/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/elevenlabs/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/elevenlabs/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/expo/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/expo/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ferrari/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ferrari/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/figma/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/figma/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/framer/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/framer/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/fui/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/hashicorp/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/hashicorp/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ibm/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ibm/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/intercom/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/intercom/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/kraken/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/kraken/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lamborghini/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lamborghini/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/linear.app/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/linear.app/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lovable/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lovable/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mastercard/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mastercard/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/meta/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/meta/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/minimax/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/minimax/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mintlify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mintlify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/miro/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/miro/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mistral.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mistral.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mongodb/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mongodb/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nike/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nike/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/notion/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/notion/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nvidia/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nvidia/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ollama/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ollama/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/opencode.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/opencode.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/pinterest/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/pinterest/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/playstation/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/playstation/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/posthog/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/posthog/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/raycast/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/raycast/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/renault/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/renault/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/replicate/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/replicate/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/resend/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/resend/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/revolut/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/revolut/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/runwayml/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/runwayml/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sanity/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sanity/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sentry/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sentry/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/shopify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/shopify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/slack/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spacex/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spacex/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spotify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spotify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/starbucks/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/starbucks/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/stripe/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/stripe/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/supabase/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/supabase/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/superhuman/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/superhuman/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/tesla/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/tesla/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/theverge/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/theverge/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/together.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/together.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/uber/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/uber/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vercel/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vercel/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vodafone/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vodafone/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/voltagent/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/voltagent/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/warp/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/warp/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/webflow/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/webflow/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wired/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wired/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wise/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wise/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/x.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/x.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/zapier/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/zapier/README.md +0 -0
- /package/skills/{fui-skill → fui}/examples/f-table-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/examples/module-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/examples/project-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/references/coding-standards.md +0 -0
- /package/skills/{fui-skill → fui}/references/db-table-design.md +0 -0
- /package/skills/{fui-skill → fui}/references/fsheet.md +0 -0
- /package/skills/{fui-skill → fui}/references/tapi-file-api.md +0 -0
- /package/skills/{fui-skill → fui}/references/ui-templates.md +0 -0
- /package/skills/{fui-skill → fui}/scripts/fechart.js +0 -0
- /package/skills/{fui-skill → fui}/scripts/fsheet.js +0 -0
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
# module.json `data[]` — State declaration & value resolution
|
|
2
|
-
|
|
3
|
-
> Owns: **`data[]` declaration patterns: three element kinds, order state → named action → auto-startup**. Value resolution: [controls-patterns.md](controls-patterns.md) §0; nested key syntax (dot/bracket/`#PARENT`): [controls-patterns.md](controls-patterns.md) §1; cross-window: [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md).
|
|
4
|
-
|
|
5
|
-
FUI processes `data[]` **sequentially top to bottom**; each object assigns/runs based on how its value is written. Examples come from `ex/ex-v3-1SetData` + `ex-v3-2CauTruc` (official FUI demo modules).
|
|
6
|
-
|
|
7
|
-
> Overview of the 4 blocks: [module-json-anatomy.md](module-json-anatomy.md). Engine: [platform-architecture.md](platform-architecture.md) §5.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## 1. Three element kinds in `data[]`
|
|
12
|
-
|
|
13
|
-
```json
|
|
14
|
-
"data": [
|
|
15
|
-
{ "keyword": "", "dsUser": [], "dlOpen": false }, // (a) khởi tạo state
|
|
16
|
-
{ "getUser": { "API": "...", "IN": {...}, "OUT": "dsUser" } }, // (b) named action
|
|
17
|
-
{ "API": "...", "OUT": "dsInit" }, // (c) action tự chạy khi load
|
|
18
|
-
{ "CALL": "getUser" } // (c) auto-startup
|
|
19
|
-
]
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
- (a) no action key → creates reactive var in `vueData`.
|
|
23
|
-
- (b) key is a **function name** → reusable action (invoke via `CALL`).
|
|
24
|
-
- (c) object is itself an action (`API`/`CALL`/`FUN`…) → **runs on page load**, in order.
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## 2. Value resolution — HOW you write it decides the VALUE (common mistake)
|
|
29
|
-
|
|
30
|
-
Full rules (`getVueData`: backtick / `{{ }}` / string with spaces / string without spaces → JS eval) live in [controls-patterns.md §0](controls-patterns.md#0-value-resolution-rules-fundamental) — Tier A, always loaded; not repeated here.
|
|
31
|
-
|
|
32
|
-
> **Consequence for `data[]`:** to assign a **fixed string without spaces** (id, url, code) → **wrap in backticks** (``"`winUser"``) or single quotes (`"'winUser'"`), otherwise FUI treats it as a variable. This is the most common `data`/`IN` bug.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## 3. Keys as nested paths (deep set)
|
|
37
|
-
|
|
38
|
-
The left-hand key is also resolved (dot / bracket / dynamic index / `#PARENT`) — full syntax in [controls-patterns.md §1](controls-patterns.md#1-data-keys-and-assignment) _(Tier A, already loaded)_.
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## 4. Auto-run action: inline `IN`/`OUT`/`API` on load
|
|
43
|
-
|
|
44
|
-
A standalone action object in `data[]` runs on load; no name needed:
|
|
45
|
-
|
|
46
|
-
```json
|
|
47
|
-
{ "API": "https://tapi.example.vn/me/auth/ApplicationList", "OUT": "Mang" },
|
|
48
|
-
{ "IN": { "ABC": "`gdsgdsg", "DEF": "val5", "CBV": 1233 }, "OUT": "DoiTuong" }
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
→ loads the page's initial data (catalogs, dropdowns, table data).
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## 5. Named action + CALLBACK (reusable)
|
|
56
|
-
|
|
57
|
-
```json
|
|
58
|
-
{
|
|
59
|
-
"cmdSETData": [{ "MESS": "Thông báo" }, { "#Win1.GiaTriSetTuCHA": "Giá trị set từ CHA" }],
|
|
60
|
-
"apiChart": {
|
|
61
|
-
"API": "/ts/TS_Report_ForChart/{{ab}}",
|
|
62
|
-
"IN": { "sachID": "apiLoadFBUser", "modeY": 12345 },
|
|
63
|
-
"OUT": "DSDoiQuaTang",
|
|
64
|
-
"CALLBACK": { "AAA": "val2" }
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Invoke with `{ "CALL": "cmdSETData" }` from `controls`, `watch` or another action. `CALLBACK` runs after the API completes (see [ui-patterns.md](ui-patterns.md) §7).
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## 6. `watch` with `v_old` — previous value
|
|
74
|
-
|
|
75
|
-
In `watch`, `v_old.<field>` gives the value **before the change**:
|
|
76
|
-
|
|
77
|
-
```json
|
|
78
|
-
"watch": {
|
|
79
|
-
"val4": {
|
|
80
|
-
"API": "ts/auth/QuanHuyen_Select",
|
|
81
|
-
"IN": { "MaTinhTP": "tinhID" },
|
|
82
|
-
"OUT": "DS_QUAN_HUYEN",
|
|
83
|
-
"CALLBACK": { "BAC": "v_old.abcdeID" }
|
|
84
|
-
},
|
|
85
|
-
"taoID": { "dungthu": "v_old.taoID" }
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
`v_old`, `deep-watch` details: [watcher-patterns.md](watcher-patterns.md).
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## 7. Cross-window exchange inside `data[]`
|
|
94
|
-
|
|
95
|
-
`data[]` can read/write other windows via `#PARENT.*` / `#WinID.*` keys/values — place **before** fetch CALLs:
|
|
96
|
-
|
|
97
|
-
```json
|
|
98
|
-
"data": [
|
|
99
|
-
{
|
|
100
|
-
"LayDuLieuWinCha": "#PARENT.Win1", // đọc data cha
|
|
101
|
-
"#PARENT.abcdef": 1234567890, // ghi xuống cha
|
|
102
|
-
"#Win1": { "CALL": "cmdTHONGBao" } // gọi lệnh ở Win1
|
|
103
|
-
}
|
|
104
|
-
]
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Full: [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md).
|
|
108
|
-
|
|
109
|
-
---
|
|
110
|
-
|
|
111
|
-
## 8. `data[]` checklist
|
|
112
|
-
|
|
113
|
-
1. Initialize **every** state var in the first object (including `[]`, `false`, `null`) so reactivity works.
|
|
114
|
-
2. Named actions in the middle; auto-startup (`CALL`/`API`) **last**.
|
|
115
|
-
3. Fixed space-free strings → **backticks**; never let FUI read them as variables.
|
|
116
|
-
4. `#PARENT.*` / URL vars before fetch CALLs.
|
|
117
|
-
5. No complex logic in `data` — move to `script.js` (functions) or sparing `EXE`.
|
|
1
|
+
# module.json `data[]` — State declaration & value resolution
|
|
2
|
+
|
|
3
|
+
> Owns: **`data[]` declaration patterns: three element kinds, order state → named action → auto-startup**. Value resolution: [controls-patterns.md](controls-patterns.md) §0; nested key syntax (dot/bracket/`#PARENT`): [controls-patterns.md](controls-patterns.md) §1; cross-window: [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md).
|
|
4
|
+
|
|
5
|
+
FUI processes `data[]` **sequentially top to bottom**; each object assigns/runs based on how its value is written. Examples come from `ex/ex-v3-1SetData` + `ex-v3-2CauTruc` (official FUI demo modules).
|
|
6
|
+
|
|
7
|
+
> Overview of the 4 blocks: [module-json-anatomy.md](module-json-anatomy.md). Engine: [platform-architecture.md](platform-architecture.md) §5.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. Three element kinds in `data[]`
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
"data": [
|
|
15
|
+
{ "keyword": "", "dsUser": [], "dlOpen": false }, // (a) khởi tạo state
|
|
16
|
+
{ "getUser": { "API": "...", "IN": {...}, "OUT": "dsUser" } }, // (b) named action
|
|
17
|
+
{ "API": "...", "OUT": "dsInit" }, // (c) action tự chạy khi load
|
|
18
|
+
{ "CALL": "getUser" } // (c) auto-startup
|
|
19
|
+
]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- (a) no action key → creates reactive var in `vueData`.
|
|
23
|
+
- (b) key is a **function name** → reusable action (invoke via `CALL`).
|
|
24
|
+
- (c) object is itself an action (`API`/`CALL`/`FUN`…) → **runs on page load**, in order.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 2. Value resolution — HOW you write it decides the VALUE (common mistake)
|
|
29
|
+
|
|
30
|
+
Full rules (`getVueData`: backtick / `{{ }}` / string with spaces / string without spaces → JS eval) live in [controls-patterns.md §0](controls-patterns.md#0-value-resolution-rules-fundamental) — Tier A, always loaded; not repeated here.
|
|
31
|
+
|
|
32
|
+
> **Consequence for `data[]`:** to assign a **fixed string without spaces** (id, url, code) → **wrap in backticks** (``"`winUser"``) or single quotes (`"'winUser'"`), otherwise FUI treats it as a variable. This is the most common `data`/`IN` bug.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 3. Keys as nested paths (deep set)
|
|
37
|
+
|
|
38
|
+
The left-hand key is also resolved (dot / bracket / dynamic index / `#PARENT`) — full syntax in [controls-patterns.md §1](controls-patterns.md#1-data-keys-and-assignment) _(Tier A, already loaded)_.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 4. Auto-run action: inline `IN`/`OUT`/`API` on load
|
|
43
|
+
|
|
44
|
+
A standalone action object in `data[]` runs on load; no name needed:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{ "API": "https://tapi.example.vn/me/auth/ApplicationList", "OUT": "Mang" },
|
|
48
|
+
{ "IN": { "ABC": "`gdsgdsg", "DEF": "val5", "CBV": 1233 }, "OUT": "DoiTuong" }
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
→ loads the page's initial data (catalogs, dropdowns, table data).
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 5. Named action + CALLBACK (reusable)
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"cmdSETData": [{ "MESS": "Thông báo" }, { "#Win1.GiaTriSetTuCHA": "Giá trị set từ CHA" }],
|
|
60
|
+
"apiChart": {
|
|
61
|
+
"API": "/ts/TS_Report_ForChart/{{ab}}",
|
|
62
|
+
"IN": { "sachID": "apiLoadFBUser", "modeY": 12345 },
|
|
63
|
+
"OUT": "DSDoiQuaTang",
|
|
64
|
+
"CALLBACK": { "AAA": "val2" }
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Invoke with `{ "CALL": "cmdSETData" }` from `controls`, `watch` or another action. `CALLBACK` runs after the API completes (see [ui-patterns.md](ui-patterns.md) §7).
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 6. `watch` with `v_old` — previous value
|
|
74
|
+
|
|
75
|
+
In `watch`, `v_old.<field>` gives the value **before the change**:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
"watch": {
|
|
79
|
+
"val4": {
|
|
80
|
+
"API": "ts/auth/QuanHuyen_Select",
|
|
81
|
+
"IN": { "MaTinhTP": "tinhID" },
|
|
82
|
+
"OUT": "DS_QUAN_HUYEN",
|
|
83
|
+
"CALLBACK": { "BAC": "v_old.abcdeID" }
|
|
84
|
+
},
|
|
85
|
+
"taoID": { "dungthu": "v_old.taoID" }
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`v_old`, `deep-watch` details: [watcher-patterns.md](watcher-patterns.md).
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 7. Cross-window exchange inside `data[]`
|
|
94
|
+
|
|
95
|
+
`data[]` can read/write other windows via `#PARENT.*` / `#WinID.*` keys/values — place **before** fetch CALLs:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
"data": [
|
|
99
|
+
{
|
|
100
|
+
"LayDuLieuWinCha": "#PARENT.Win1", // đọc data cha
|
|
101
|
+
"#PARENT.abcdef": 1234567890, // ghi xuống cha
|
|
102
|
+
"#Win1": { "CALL": "cmdTHONGBao" } // gọi lệnh ở Win1
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Full: [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md).
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 8. `data[]` checklist
|
|
112
|
+
|
|
113
|
+
1. Initialize **every** state var in the first object (including `[]`, `false`, `null`) so reactivity works.
|
|
114
|
+
2. Named actions in the middle; auto-startup (`CALL`/`API`) **last**.
|
|
115
|
+
3. Fixed space-free strings → **backticks**; never let FUI read them as variables.
|
|
116
|
+
4. `#PARENT.*` / URL vars before fetch CALLs.
|
|
117
|
+
5. No complex logic in `data` — move to `script.js` (functions) or sparing `EXE`.
|
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
# module.json Anatomy — data · watch · controls · set
|
|
2
|
-
|
|
3
|
-
> Owns: **the 4 `module.json` blocks (data/watch/controls/set) — roles, interaction, structure checklist**. Action/control syntax: [controls-patterns.md](controls-patterns.md).
|
|
4
|
-
|
|
5
|
-
`module.json` describes one FUI page with exactly **4 top-level blocks**. Runtime internals: [platform-architecture.md](platform-architecture.md). Battle-tested UI patterns (high priority): [ui-patterns.md](ui-patterns.md).
|
|
6
|
-
|
|
7
|
-
```json
|
|
8
|
-
{
|
|
9
|
-
"data": [/* state + action */],
|
|
10
|
-
"watch": {/* observer → action */},
|
|
11
|
-
"controls": [/* layout UI: container > rows > cols */],
|
|
12
|
-
"set": {/* override config trang (tùy chọn) */}
|
|
13
|
-
}
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
Runtime order: `runAction(data)` → `buildModuleUI(controls)` → attach `watch` → merge `set` into page config. All state lives in `vueData`.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## 1. `data` — state init + action definitions
|
|
21
|
-
|
|
22
|
-
An **array**, processed top to bottom on page load. Three element kinds:
|
|
23
|
-
|
|
24
|
-
| Object kind | Recognized by | Effect |
|
|
25
|
-
| ------------ | ------------------------------------------------ | ----------------------------------- |
|
|
26
|
-
| State init | No action key (`API`/`CALL`/`IF`...) | Creates reactive var in `vueData` |
|
|
27
|
-
| Named action | Key = function name, value = action object | Reusable action (invoke via `CALL`) |
|
|
28
|
-
| Auto-startup | Standalone `{ "API": ... }` or `{ "CALL": ... }` | **Runs immediately** on load |
|
|
29
|
-
|
|
30
|
-
```json
|
|
31
|
-
"data": [
|
|
32
|
-
{ "dsUser": [], "sGroup": null, "dlUserInfo": false },
|
|
33
|
-
{
|
|
34
|
-
"getUser": { "API": "SM_Users_SelectByDepGroup", "IN": { "GroupID": "sGroup" }, "OUT": "dsUser" }
|
|
35
|
-
},
|
|
36
|
-
{ "CALL": "getUser" }
|
|
37
|
-
]
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Named actions are callable from `watch`, `controls` or other actions; trailing auto-startup = initial page data.
|
|
41
|
-
|
|
42
|
-
Details: `data[]` declaration + value resolution (string/var/backtick/`{{ }}`/deep key, auto-run, named action, `v_old`) → **[module-data-patterns.md](module-data-patterns.md)**; action engine → [controls-patterns.md](controls-patterns.md); real-world data layout → [ui-patterns.md](ui-patterns.md) §1–2.
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## 2. `watch` — state change → run action
|
|
47
|
-
|
|
48
|
-
An **object** `{ "varName": action }`; action runs when the var changes.
|
|
49
|
-
|
|
50
|
-
```json
|
|
51
|
-
"watch": {
|
|
52
|
-
"sGroup": { "CALL": "getUser" },
|
|
53
|
-
"sDepartment": { "CALL": "getUser" },
|
|
54
|
-
"sModuleID": [ { "CALL": "getSysRight" }, { "CALL": "getFunctionRight" } ]
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
- **Cascading filter**: one watch per filter dropdown → table reloads on change.
|
|
59
|
-
- Multiple actions for one var → use an **array**.
|
|
60
|
-
- **`deep-watch`**: tracks nested changes inside object/array (runtime supports the `deep-watch` key).
|
|
61
|
-
|
|
62
|
-
Details: [watcher-patterns.md](watcher-patterns.md) (v_old, deep-watch, cascading), [ui-patterns.md](ui-patterns.md) §3.
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## 3. `controls` — UI layout (mandatory grid container > rows > cols)
|
|
67
|
-
|
|
68
|
-
An **array** of containers. Runtime builds `container (v-container)` → `rows (v-layout)` → `cols` → each item is a **Control Object**.
|
|
69
|
-
|
|
70
|
-
```json
|
|
71
|
-
"controls": [
|
|
72
|
-
{
|
|
73
|
-
"prop": "fluid grid-list-md",
|
|
74
|
-
"rows": [
|
|
75
|
-
{ "prop": "row", "cols": [ /* Control Objects */ ] }
|
|
76
|
-
]
|
|
77
|
-
}
|
|
78
|
-
]
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Control Object keys:
|
|
82
|
-
|
|
83
|
-
| Key | Role |
|
|
84
|
-
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
85
|
-
| `el` | Tag/component: `div`, `v-*` (Vuetify), `f-*`/`t-*` (FUI), `uc-*` (custom) |
|
|
86
|
-
| `attr` | Attributes/directives (`class`, `style`, `v-model`, `v-on:click`) — **use `v-on:click`, NOT `@click`** |
|
|
87
|
-
| `w` | Column width: `1–12` (grid) or `>= 25` (px, **requires `col: { "class": "shrink" }`**). Never 13–24. Required for every item in `cols` |
|
|
88
|
-
| `col` | Wrapping grid column config (`class`, `style`, `v-if`) |
|
|
89
|
-
| `innerHTML` | Content: string (supports `{{ }}`) or array of nested Control Objects |
|
|
90
|
-
|
|
91
|
-
Mandatory: always start with the grid wrapper; nest via `innerHTML` (array), never `children`; put dialogs in a container with `prop: "hidden-container"`.
|
|
92
|
-
|
|
93
|
-
Details: structure & grid → [controls-patterns.md](controls-patterns.md) §6; **allowed class/prop/style (don't invent styles)** → [controls-styling-vocabulary.md](controls-styling-vocabulary.md); picking components → [component-quickref.md](component-quickref.md); layout/table/dialog patterns → [ui-patterns.md](ui-patterns.md), [ui-table-cell-patterns.md](ui-table-cell-patterns.md), [ui-dialog-patterns.md](ui-dialog-patterns.md), [ui-layout-patterns.md](ui-layout-patterns.md).
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## 4. `set` — per-page config override (optional)
|
|
98
|
-
|
|
99
|
-
An **object** overriding project config for this page. Runtime merges `project.json` then `set` (module wins) — see [platform-architecture.md](platform-architecture.md) §2.1.
|
|
100
|
-
|
|
101
|
-
```json
|
|
102
|
-
"set": {
|
|
103
|
-
"title": "Quản lý sinh viên",
|
|
104
|
-
"menu": false
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Declare only fields differing from the project. Common: `title`, `menu: false` (hide header — sub-window/landing), `menuLeft` (own sidebar), `apiDomain` (different backend for this page). Normal pages **need no `set`**.
|
|
109
|
-
|
|
110
|
-
Full property list: [project-config.md](project-config.md).
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## How the 4 blocks interact
|
|
115
|
-
|
|
116
|
-
```
|
|
117
|
-
URL ?param ──► vueData[param] (inject trước khi data chạy)
|
|
118
|
-
data[] ──► tạo state + action, auto-startup fetch
|
|
119
|
-
controls ──► bind hai chiều vào state (v-model), gọi action (:action / v-on)
|
|
120
|
-
watch ──► state đổi → chạy action → cập nhật state khác → UI re-render
|
|
121
|
-
set ──► quyết định khung trang (title/menu/apiDomain) bao quanh controls
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Typical loop: user acts on `controls` → state changes → `watch` fires → `API` action in `data` → `OUT` updates state → `controls` re-render.
|
|
125
|
-
|
|
126
|
-
## Checklist
|
|
127
|
-
|
|
128
|
-
1. `data[]`: state first → named actions → `{ "CALL": ... }` auto-startup last
|
|
129
|
-
2. `watch`: every filter/dropdown has a watch → reload
|
|
130
|
-
3. `controls`: start with grid wrapper; `w` on every item; dialogs in `hidden-container`; `v-on:click` not `@click`
|
|
131
|
-
4. `set`: only when the page differs from project defaults
|
|
132
|
-
5. Reference state as `vueData.` in controls/attr; valid JSON (no trailing commas)
|
|
1
|
+
# module.json Anatomy — data · watch · controls · set
|
|
2
|
+
|
|
3
|
+
> Owns: **the 4 `module.json` blocks (data/watch/controls/set) — roles, interaction, structure checklist**. Action/control syntax: [controls-patterns.md](controls-patterns.md).
|
|
4
|
+
|
|
5
|
+
`module.json` describes one FUI page with exactly **4 top-level blocks**. Runtime internals: [platform-architecture.md](platform-architecture.md). Battle-tested UI patterns (high priority): [ui-patterns.md](ui-patterns.md).
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"data": [/* state + action */],
|
|
10
|
+
"watch": {/* observer → action */},
|
|
11
|
+
"controls": [/* layout UI: container > rows > cols */],
|
|
12
|
+
"set": {/* override config trang (tùy chọn) */}
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Runtime order: `runAction(data)` → `buildModuleUI(controls)` → attach `watch` → merge `set` into page config. All state lives in `vueData`.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. `data` — state init + action definitions
|
|
21
|
+
|
|
22
|
+
An **array**, processed top to bottom on page load. Three element kinds:
|
|
23
|
+
|
|
24
|
+
| Object kind | Recognized by | Effect |
|
|
25
|
+
| ------------ | ------------------------------------------------ | ----------------------------------- |
|
|
26
|
+
| State init | No action key (`API`/`CALL`/`IF`...) | Creates reactive var in `vueData` |
|
|
27
|
+
| Named action | Key = function name, value = action object | Reusable action (invoke via `CALL`) |
|
|
28
|
+
| Auto-startup | Standalone `{ "API": ... }` or `{ "CALL": ... }` | **Runs immediately** on load |
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
"data": [
|
|
32
|
+
{ "dsUser": [], "sGroup": null, "dlUserInfo": false },
|
|
33
|
+
{
|
|
34
|
+
"getUser": { "API": "SM_Users_SelectByDepGroup", "IN": { "GroupID": "sGroup" }, "OUT": "dsUser" }
|
|
35
|
+
},
|
|
36
|
+
{ "CALL": "getUser" }
|
|
37
|
+
]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Named actions are callable from `watch`, `controls` or other actions; trailing auto-startup = initial page data.
|
|
41
|
+
|
|
42
|
+
Details: `data[]` declaration + value resolution (string/var/backtick/`{{ }}`/deep key, auto-run, named action, `v_old`) → **[module-data-patterns.md](module-data-patterns.md)**; action engine → [controls-patterns.md](controls-patterns.md); real-world data layout → [ui-patterns.md](ui-patterns.md) §1–2.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 2. `watch` — state change → run action
|
|
47
|
+
|
|
48
|
+
An **object** `{ "varName": action }`; action runs when the var changes.
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
"watch": {
|
|
52
|
+
"sGroup": { "CALL": "getUser" },
|
|
53
|
+
"sDepartment": { "CALL": "getUser" },
|
|
54
|
+
"sModuleID": [ { "CALL": "getSysRight" }, { "CALL": "getFunctionRight" } ]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- **Cascading filter**: one watch per filter dropdown → table reloads on change.
|
|
59
|
+
- Multiple actions for one var → use an **array**.
|
|
60
|
+
- **`deep-watch`**: tracks nested changes inside object/array (runtime supports the `deep-watch` key).
|
|
61
|
+
|
|
62
|
+
Details: [watcher-patterns.md](watcher-patterns.md) (v_old, deep-watch, cascading), [ui-patterns.md](ui-patterns.md) §3.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 3. `controls` — UI layout (mandatory grid container > rows > cols)
|
|
67
|
+
|
|
68
|
+
An **array** of containers. Runtime builds `container (v-container)` → `rows (v-layout)` → `cols` → each item is a **Control Object**.
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
"controls": [
|
|
72
|
+
{
|
|
73
|
+
"prop": "fluid grid-list-md",
|
|
74
|
+
"rows": [
|
|
75
|
+
{ "prop": "row", "cols": [ /* Control Objects */ ] }
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Control Object keys:
|
|
82
|
+
|
|
83
|
+
| Key | Role |
|
|
84
|
+
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
85
|
+
| `el` | Tag/component: `div`, `v-*` (Vuetify), `f-*`/`t-*` (FUI), `uc-*` (custom) |
|
|
86
|
+
| `attr` | Attributes/directives (`class`, `style`, `v-model`, `v-on:click`) — **use `v-on:click`, NOT `@click`** |
|
|
87
|
+
| `w` | Column width: `1–12` (grid) or `>= 25` (px, **requires `col: { "class": "shrink" }`**). Never 13–24. Required for every item in `cols` |
|
|
88
|
+
| `col` | Wrapping grid column config (`class`, `style`, `v-if`) |
|
|
89
|
+
| `innerHTML` | Content: string (supports `{{ }}`) or array of nested Control Objects |
|
|
90
|
+
|
|
91
|
+
Mandatory: always start with the grid wrapper; nest via `innerHTML` (array), never `children`; put dialogs in a container with `prop: "hidden-container"`.
|
|
92
|
+
|
|
93
|
+
Details: structure & grid → [controls-patterns.md](controls-patterns.md) §6; **allowed class/prop/style (don't invent styles)** → [controls-styling-vocabulary.md](controls-styling-vocabulary.md); picking components → [component-quickref.md](component-quickref.md); layout/table/dialog patterns → [ui-patterns.md](ui-patterns.md), [ui-table-cell-patterns.md](ui-table-cell-patterns.md), [ui-dialog-patterns.md](ui-dialog-patterns.md), [ui-layout-patterns.md](ui-layout-patterns.md).
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 4. `set` — per-page config override (optional)
|
|
98
|
+
|
|
99
|
+
An **object** overriding project config for this page. Runtime merges `project.json` then `set` (module wins) — see [platform-architecture.md](platform-architecture.md) §2.1.
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
"set": {
|
|
103
|
+
"title": "Quản lý sinh viên",
|
|
104
|
+
"menu": false
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Declare only fields differing from the project. Common: `title`, `menu: false` (hide header — sub-window/landing), `menuLeft` (own sidebar), `apiDomain` (different backend for this page). Normal pages **need no `set`**.
|
|
109
|
+
|
|
110
|
+
Full property list: [project-config.md](project-config.md).
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## How the 4 blocks interact
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
URL ?param ──► vueData[param] (inject trước khi data chạy)
|
|
118
|
+
data[] ──► tạo state + action, auto-startup fetch
|
|
119
|
+
controls ──► bind hai chiều vào state (v-model), gọi action (:action / v-on)
|
|
120
|
+
watch ──► state đổi → chạy action → cập nhật state khác → UI re-render
|
|
121
|
+
set ──► quyết định khung trang (title/menu/apiDomain) bao quanh controls
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Typical loop: user acts on `controls` → state changes → `watch` fires → `API` action in `data` → `OUT` updates state → `controls` re-render.
|
|
125
|
+
|
|
126
|
+
## Checklist
|
|
127
|
+
|
|
128
|
+
1. `data[]`: state first → named actions → `{ "CALL": ... }` auto-startup last
|
|
129
|
+
2. `watch`: every filter/dropdown has a watch → reload
|
|
130
|
+
3. `controls`: start with grid wrapper; `w` on every item; dialogs in `hidden-container`; `v-on:click` not `@click`
|
|
131
|
+
4. `set`: only when the page differs from project defaults
|
|
132
|
+
5. Reference state as `vueData.` in controls/attr; valid JSON (no trailing commas)
|