@fui-org/fui-cli 2.1.3 → 2.2.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 (219) hide show
  1. package/README.md +27 -7
  2. package/dist/fui-qrb1j9jz.js +397 -0
  3. package/dist/fui.js +1 -1
  4. package/package.json +1 -1
  5. package/skills/fui/SKILL.md +143 -38
  6. package/skills/fui/agents/fui-builder.md +62 -0
  7. package/skills/fui/agents/fui-tester.md +77 -0
  8. package/skills/{fui-skill → fui}/assets/projectdefaultstyle.css +489 -489
  9. package/skills/{fui-skill → fui}/examples/component.vue +162 -162
  10. package/skills/{fui-skill → fui}/references/INDEX.md +5 -4
  11. package/skills/{fui-skill → fui}/references/advanced-techniques.md +170 -168
  12. package/skills/{fui-skill → fui}/references/component-design.md +2 -2
  13. package/skills/{fui-skill → fui}/references/component-quickref.md +78 -78
  14. package/skills/{fui-skill → fui}/references/component-table.md +287 -287
  15. package/skills/{fui-skill → fui}/references/components-dialog.md +191 -191
  16. package/skills/{fui-skill → fui}/references/components-display.md +141 -141
  17. package/skills/{fui-skill → fui}/references/components-echart.md +316 -316
  18. package/skills/{fui-skill → fui}/references/components-input.md +335 -335
  19. package/skills/{fui-skill → fui}/references/controls-patterns.md +2 -2
  20. package/skills/{fui-skill → fui}/references/controls-styling-vocabulary.md +173 -173
  21. package/skills/{fui-skill → fui}/references/db-workflow.md +9 -9
  22. package/skills/{fui-skill → fui}/references/default-function.md +456 -456
  23. package/skills/{fui-skill → fui}/references/design-modes.md +57 -57
  24. package/skills/{fui-skill → fui}/references/echart-templates.md +489 -489
  25. package/skills/{fui-skill → fui}/references/fastproject.md +99 -99
  26. package/skills/{fui-skill → fui}/references/fullstack-workflow.md +314 -313
  27. package/skills/{fui-skill → fui}/references/module-data-patterns.md +117 -117
  28. package/skills/{fui-skill → fui}/references/module-json-anatomy.md +132 -132
  29. package/skills/{fui-skill → fui}/references/module-structure.md +144 -144
  30. package/skills/{fui-skill → fui}/references/new-session.md +1 -2
  31. package/skills/{fui-skill → fui}/references/pdfmake.md +60 -60
  32. package/skills/{fui-skill → fui}/references/permission-system.md +1 -1
  33. package/skills/{fui-skill → fui}/references/platform-architecture.md +269 -269
  34. package/skills/{fui-skill → fui}/references/project-config.md +303 -303
  35. package/skills/{fui-skill → fui}/references/project-provisioning.md +4 -4
  36. package/skills/{fui-skill → fui}/references/script-map.md +262 -262
  37. package/skills/{fui-skill → fui}/references/sql-clr-functions.md +225 -225
  38. package/skills/{fui-skill → fui}/references/system-design.md +2 -2
  39. package/skills/{fui-skill → fui}/references/tapi-permission-patterns.md +156 -156
  40. package/skills/{fui-skill → fui}/references/tapi-reference.md +474 -474
  41. package/skills/fui/references/team-run.md +141 -0
  42. package/skills/fui/references/tools-registry.md +211 -0
  43. package/skills/{fui-skill → fui}/references/ui-crosswindow-patterns.md +321 -321
  44. package/skills/{fui-skill → fui}/references/ui-dialog-patterns.md +255 -255
  45. package/skills/{fui-skill → fui}/references/ui-layout-patterns.md +176 -176
  46. package/skills/{fui-skill → fui}/references/ui-patterns.md +303 -303
  47. package/skills/{fui-skill → fui}/references/ui-screenshot-review.md +95 -95
  48. package/skills/{fui-skill → fui}/references/ui-table-cell-patterns.md +318 -318
  49. package/skills/{fui-skill → fui}/references/verification.md +11 -11
  50. package/skills/{fui-skill → fui}/references/watcher-patterns.md +163 -163
  51. package/skills/{fui-skill → fui}/references/websocket-realtime.md +271 -271
  52. package/skills/{fui-skill → fui}/scripts/component-3.0.js +2715 -2715
  53. package/skills/{fui-skill → fui}/scripts/component.js +3147 -3147
  54. package/skills/{fui-skill → fui}/scripts/componentTable-3.0.js +1038 -1038
  55. package/skills/{fui-skill → fui}/scripts/componentTable.js +891 -891
  56. package/skills/{fui-skill → fui}/scripts/defaultfunction-3.0.js +866 -866
  57. package/skills/{fui-skill → fui}/scripts/defaultfunction.js +1051 -1051
  58. package/skills/{fui-skill → fui}/scripts/fastproject-3.0.js +870 -870
  59. package/skills/{fui-skill → fui}/scripts/fastproject.js +828 -828
  60. package/skills/fui-target/hooks/register.tsx +2 -0
  61. package/skills/fui-target/types/index.d.ts +1 -0
  62. package/dist/fui-hk5frcn2.js +0 -381
  63. package/skills/fui-skill/SKILL.md +0 -139
  64. package/skills/fui-skill/references/tools-registry.md +0 -84
  65. /package/skills/{fui-skill → fui}/assets/projectdefaultstyle-3.0.css +0 -0
  66. /package/skills/{fui-skill → fui}/design-md/airbnb/DESIGN.md +0 -0
  67. /package/skills/{fui-skill → fui}/design-md/airbnb/README.md +0 -0
  68. /package/skills/{fui-skill → fui}/design-md/airtable/DESIGN.md +0 -0
  69. /package/skills/{fui-skill → fui}/design-md/airtable/README.md +0 -0
  70. /package/skills/{fui-skill → fui}/design-md/apple/DESIGN.md +0 -0
  71. /package/skills/{fui-skill → fui}/design-md/apple/README.md +0 -0
  72. /package/skills/{fui-skill → fui}/design-md/asu/DESIGN.md +0 -0
  73. /package/skills/{fui-skill → fui}/design-md/asu/README.md +0 -0
  74. /package/skills/{fui-skill → fui}/design-md/binance/DESIGN.md +0 -0
  75. /package/skills/{fui-skill → fui}/design-md/binance/README.md +0 -0
  76. /package/skills/{fui-skill → fui}/design-md/bmw/DESIGN.md +0 -0
  77. /package/skills/{fui-skill → fui}/design-md/bmw/README.md +0 -0
  78. /package/skills/{fui-skill → fui}/design-md/bmw-m/DESIGN.md +0 -0
  79. /package/skills/{fui-skill → fui}/design-md/bmw-m/README.md +0 -0
  80. /package/skills/{fui-skill → fui}/design-md/bugatti/DESIGN.md +0 -0
  81. /package/skills/{fui-skill → fui}/design-md/bugatti/README.md +0 -0
  82. /package/skills/{fui-skill → fui}/design-md/cal/DESIGN.md +0 -0
  83. /package/skills/{fui-skill → fui}/design-md/cal/README.md +0 -0
  84. /package/skills/{fui-skill → fui}/design-md/claude/DESIGN.md +0 -0
  85. /package/skills/{fui-skill → fui}/design-md/claude/README.md +0 -0
  86. /package/skills/{fui-skill → fui}/design-md/clay/DESIGN.md +0 -0
  87. /package/skills/{fui-skill → fui}/design-md/clay/README.md +0 -0
  88. /package/skills/{fui-skill → fui}/design-md/clickhouse/DESIGN.md +0 -0
  89. /package/skills/{fui-skill → fui}/design-md/clickhouse/README.md +0 -0
  90. /package/skills/{fui-skill → fui}/design-md/cohere/DESIGN.md +0 -0
  91. /package/skills/{fui-skill → fui}/design-md/cohere/README.md +0 -0
  92. /package/skills/{fui-skill → fui}/design-md/coinbase/DESIGN.md +0 -0
  93. /package/skills/{fui-skill → fui}/design-md/coinbase/README.md +0 -0
  94. /package/skills/{fui-skill → fui}/design-md/composio/DESIGN.md +0 -0
  95. /package/skills/{fui-skill → fui}/design-md/composio/README.md +0 -0
  96. /package/skills/{fui-skill → fui}/design-md/cursor/DESIGN.md +0 -0
  97. /package/skills/{fui-skill → fui}/design-md/cursor/README.md +0 -0
  98. /package/skills/{fui-skill → fui}/design-md/elevenlabs/DESIGN.md +0 -0
  99. /package/skills/{fui-skill → fui}/design-md/elevenlabs/README.md +0 -0
  100. /package/skills/{fui-skill → fui}/design-md/expo/DESIGN.md +0 -0
  101. /package/skills/{fui-skill → fui}/design-md/expo/README.md +0 -0
  102. /package/skills/{fui-skill → fui}/design-md/ferrari/DESIGN.md +0 -0
  103. /package/skills/{fui-skill → fui}/design-md/ferrari/README.md +0 -0
  104. /package/skills/{fui-skill → fui}/design-md/figma/DESIGN.md +0 -0
  105. /package/skills/{fui-skill → fui}/design-md/figma/README.md +0 -0
  106. /package/skills/{fui-skill → fui}/design-md/framer/DESIGN.md +0 -0
  107. /package/skills/{fui-skill → fui}/design-md/framer/README.md +0 -0
  108. /package/skills/{fui-skill → fui}/design-md/fui/DESIGN.md +0 -0
  109. /package/skills/{fui-skill → fui}/design-md/hashicorp/DESIGN.md +0 -0
  110. /package/skills/{fui-skill → fui}/design-md/hashicorp/README.md +0 -0
  111. /package/skills/{fui-skill → fui}/design-md/ibm/DESIGN.md +0 -0
  112. /package/skills/{fui-skill → fui}/design-md/ibm/README.md +0 -0
  113. /package/skills/{fui-skill → fui}/design-md/intercom/DESIGN.md +0 -0
  114. /package/skills/{fui-skill → fui}/design-md/intercom/README.md +0 -0
  115. /package/skills/{fui-skill → fui}/design-md/kraken/DESIGN.md +0 -0
  116. /package/skills/{fui-skill → fui}/design-md/kraken/README.md +0 -0
  117. /package/skills/{fui-skill → fui}/design-md/lamborghini/DESIGN.md +0 -0
  118. /package/skills/{fui-skill → fui}/design-md/lamborghini/README.md +0 -0
  119. /package/skills/{fui-skill → fui}/design-md/linear.app/DESIGN.md +0 -0
  120. /package/skills/{fui-skill → fui}/design-md/linear.app/README.md +0 -0
  121. /package/skills/{fui-skill → fui}/design-md/lovable/DESIGN.md +0 -0
  122. /package/skills/{fui-skill → fui}/design-md/lovable/README.md +0 -0
  123. /package/skills/{fui-skill → fui}/design-md/mastercard/DESIGN.md +0 -0
  124. /package/skills/{fui-skill → fui}/design-md/mastercard/README.md +0 -0
  125. /package/skills/{fui-skill → fui}/design-md/meta/DESIGN.md +0 -0
  126. /package/skills/{fui-skill → fui}/design-md/meta/README.md +0 -0
  127. /package/skills/{fui-skill → fui}/design-md/minimax/DESIGN.md +0 -0
  128. /package/skills/{fui-skill → fui}/design-md/minimax/README.md +0 -0
  129. /package/skills/{fui-skill → fui}/design-md/mintlify/DESIGN.md +0 -0
  130. /package/skills/{fui-skill → fui}/design-md/mintlify/README.md +0 -0
  131. /package/skills/{fui-skill → fui}/design-md/miro/DESIGN.md +0 -0
  132. /package/skills/{fui-skill → fui}/design-md/miro/README.md +0 -0
  133. /package/skills/{fui-skill → fui}/design-md/mistral.ai/DESIGN.md +0 -0
  134. /package/skills/{fui-skill → fui}/design-md/mistral.ai/README.md +0 -0
  135. /package/skills/{fui-skill → fui}/design-md/mongodb/DESIGN.md +0 -0
  136. /package/skills/{fui-skill → fui}/design-md/mongodb/README.md +0 -0
  137. /package/skills/{fui-skill → fui}/design-md/nike/DESIGN.md +0 -0
  138. /package/skills/{fui-skill → fui}/design-md/nike/README.md +0 -0
  139. /package/skills/{fui-skill → fui}/design-md/notion/DESIGN.md +0 -0
  140. /package/skills/{fui-skill → fui}/design-md/notion/README.md +0 -0
  141. /package/skills/{fui-skill → fui}/design-md/nvidia/DESIGN.md +0 -0
  142. /package/skills/{fui-skill → fui}/design-md/nvidia/README.md +0 -0
  143. /package/skills/{fui-skill → fui}/design-md/ollama/DESIGN.md +0 -0
  144. /package/skills/{fui-skill → fui}/design-md/ollama/README.md +0 -0
  145. /package/skills/{fui-skill → fui}/design-md/opencode.ai/DESIGN.md +0 -0
  146. /package/skills/{fui-skill → fui}/design-md/opencode.ai/README.md +0 -0
  147. /package/skills/{fui-skill → fui}/design-md/pinterest/DESIGN.md +0 -0
  148. /package/skills/{fui-skill → fui}/design-md/pinterest/README.md +0 -0
  149. /package/skills/{fui-skill → fui}/design-md/playstation/DESIGN.md +0 -0
  150. /package/skills/{fui-skill → fui}/design-md/playstation/README.md +0 -0
  151. /package/skills/{fui-skill → fui}/design-md/posthog/DESIGN.md +0 -0
  152. /package/skills/{fui-skill → fui}/design-md/posthog/README.md +0 -0
  153. /package/skills/{fui-skill → fui}/design-md/raycast/DESIGN.md +0 -0
  154. /package/skills/{fui-skill → fui}/design-md/raycast/README.md +0 -0
  155. /package/skills/{fui-skill → fui}/design-md/renault/DESIGN.md +0 -0
  156. /package/skills/{fui-skill → fui}/design-md/renault/README.md +0 -0
  157. /package/skills/{fui-skill → fui}/design-md/replicate/DESIGN.md +0 -0
  158. /package/skills/{fui-skill → fui}/design-md/replicate/README.md +0 -0
  159. /package/skills/{fui-skill → fui}/design-md/resend/DESIGN.md +0 -0
  160. /package/skills/{fui-skill → fui}/design-md/resend/README.md +0 -0
  161. /package/skills/{fui-skill → fui}/design-md/revolut/DESIGN.md +0 -0
  162. /package/skills/{fui-skill → fui}/design-md/revolut/README.md +0 -0
  163. /package/skills/{fui-skill → fui}/design-md/runwayml/DESIGN.md +0 -0
  164. /package/skills/{fui-skill → fui}/design-md/runwayml/README.md +0 -0
  165. /package/skills/{fui-skill → fui}/design-md/sanity/DESIGN.md +0 -0
  166. /package/skills/{fui-skill → fui}/design-md/sanity/README.md +0 -0
  167. /package/skills/{fui-skill → fui}/design-md/sentry/DESIGN.md +0 -0
  168. /package/skills/{fui-skill → fui}/design-md/sentry/README.md +0 -0
  169. /package/skills/{fui-skill → fui}/design-md/shopify/DESIGN.md +0 -0
  170. /package/skills/{fui-skill → fui}/design-md/shopify/README.md +0 -0
  171. /package/skills/{fui-skill → fui}/design-md/slack/DESIGN.md +0 -0
  172. /package/skills/{fui-skill → fui}/design-md/spacex/DESIGN.md +0 -0
  173. /package/skills/{fui-skill → fui}/design-md/spacex/README.md +0 -0
  174. /package/skills/{fui-skill → fui}/design-md/spotify/DESIGN.md +0 -0
  175. /package/skills/{fui-skill → fui}/design-md/spotify/README.md +0 -0
  176. /package/skills/{fui-skill → fui}/design-md/starbucks/DESIGN.md +0 -0
  177. /package/skills/{fui-skill → fui}/design-md/starbucks/README.md +0 -0
  178. /package/skills/{fui-skill → fui}/design-md/stripe/DESIGN.md +0 -0
  179. /package/skills/{fui-skill → fui}/design-md/stripe/README.md +0 -0
  180. /package/skills/{fui-skill → fui}/design-md/supabase/DESIGN.md +0 -0
  181. /package/skills/{fui-skill → fui}/design-md/supabase/README.md +0 -0
  182. /package/skills/{fui-skill → fui}/design-md/superhuman/DESIGN.md +0 -0
  183. /package/skills/{fui-skill → fui}/design-md/superhuman/README.md +0 -0
  184. /package/skills/{fui-skill → fui}/design-md/tesla/DESIGN.md +0 -0
  185. /package/skills/{fui-skill → fui}/design-md/tesla/README.md +0 -0
  186. /package/skills/{fui-skill → fui}/design-md/theverge/DESIGN.md +0 -0
  187. /package/skills/{fui-skill → fui}/design-md/theverge/README.md +0 -0
  188. /package/skills/{fui-skill → fui}/design-md/together.ai/DESIGN.md +0 -0
  189. /package/skills/{fui-skill → fui}/design-md/together.ai/README.md +0 -0
  190. /package/skills/{fui-skill → fui}/design-md/uber/DESIGN.md +0 -0
  191. /package/skills/{fui-skill → fui}/design-md/uber/README.md +0 -0
  192. /package/skills/{fui-skill → fui}/design-md/vercel/DESIGN.md +0 -0
  193. /package/skills/{fui-skill → fui}/design-md/vercel/README.md +0 -0
  194. /package/skills/{fui-skill → fui}/design-md/vodafone/DESIGN.md +0 -0
  195. /package/skills/{fui-skill → fui}/design-md/vodafone/README.md +0 -0
  196. /package/skills/{fui-skill → fui}/design-md/voltagent/DESIGN.md +0 -0
  197. /package/skills/{fui-skill → fui}/design-md/voltagent/README.md +0 -0
  198. /package/skills/{fui-skill → fui}/design-md/warp/DESIGN.md +0 -0
  199. /package/skills/{fui-skill → fui}/design-md/warp/README.md +0 -0
  200. /package/skills/{fui-skill → fui}/design-md/webflow/DESIGN.md +0 -0
  201. /package/skills/{fui-skill → fui}/design-md/webflow/README.md +0 -0
  202. /package/skills/{fui-skill → fui}/design-md/wired/DESIGN.md +0 -0
  203. /package/skills/{fui-skill → fui}/design-md/wired/README.md +0 -0
  204. /package/skills/{fui-skill → fui}/design-md/wise/DESIGN.md +0 -0
  205. /package/skills/{fui-skill → fui}/design-md/wise/README.md +0 -0
  206. /package/skills/{fui-skill → fui}/design-md/x.ai/DESIGN.md +0 -0
  207. /package/skills/{fui-skill → fui}/design-md/x.ai/README.md +0 -0
  208. /package/skills/{fui-skill → fui}/design-md/zapier/DESIGN.md +0 -0
  209. /package/skills/{fui-skill → fui}/design-md/zapier/README.md +0 -0
  210. /package/skills/{fui-skill → fui}/examples/f-table-patterns.json +0 -0
  211. /package/skills/{fui-skill → fui}/examples/module-patterns.json +0 -0
  212. /package/skills/{fui-skill → fui}/examples/project-patterns.json +0 -0
  213. /package/skills/{fui-skill → fui}/references/coding-standards.md +0 -0
  214. /package/skills/{fui-skill → fui}/references/db-table-design.md +0 -0
  215. /package/skills/{fui-skill → fui}/references/fsheet.md +0 -0
  216. /package/skills/{fui-skill → fui}/references/tapi-file-api.md +0 -0
  217. /package/skills/{fui-skill → fui}/references/ui-templates.md +0 -0
  218. /package/skills/{fui-skill → fui}/scripts/fechart.js +0 -0
  219. /package/skills/{fui-skill → fui}/scripts/fsheet.js +0 -0
@@ -1,176 +1,176 @@
1
- # FUI Layout Patterns — page-container, master-detail, switch, dynamic label
2
-
3
- > Owns: **page layout patterns: sticky page-container, 2-column master-detail, v-switch, date init, dynamic label**.
4
-
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).
6
-
7
- ---
8
-
9
- ## 1. Date init with moment()
10
-
11
- ```json
12
- "data": [
13
- {
14
- "TuNgay": "moment().format('YYYY-MM-DD')",
15
- "DenNgay": "moment().format('YYYY-MM-DD')"
16
- }
17
- ]
18
- ```
19
-
20
- > The value is a JS expression string, eval'd at init. `moment()` is available in the FUI runtime.
21
-
22
- ---
23
-
24
- ## 2. page-container + page-navigation
25
-
26
- Use for a fixed filter bar on top with scrolling content below.
27
-
28
- ```json
29
- {
30
- "prop": "page-container grid-list-md fluid",
31
- "rows": [
32
- {
33
- "prop": "page-navigation",
34
- "cols": [
35
- { "el": "f-date", "attr": { "v-model": "TuNgay", "label": "Từ ngày", "date-add": 0 }, "w": "2" },
36
- { "el": "f-date", "attr": { "v-model": "DenNgay", "label": "Tới ngày", "date-add": 0 }, "w": "2" },
37
- {
38
- "el": "f-button",
39
- "attr": {
40
- "color": "primary",
41
- "icon-text": "mdi-filter",
42
- "label": "Tìm",
43
- ":action": { "CALL": "getLogData" }
44
- },
45
- "w": 3
46
- }
47
- ]
48
- },
49
- {
50
- "prop": "",
51
- "cols": [{ "el": "f-table", "attr": { "label": "Log viewer", ":items": "LogData" } }]
52
- }
53
- ]
54
- }
55
- ```
56
-
57
- - `page-container` + `page-navigation` → sticky top filter bar
58
- - `f-table` without `:update-api` → readonly; without `:headers` → headers auto-built from data
59
-
60
- ---
61
-
62
- ## 3. Dynamic label from state
63
-
64
- Use `:label` with an expression to show context.
65
-
66
- ```json
67
- {
68
- "el": "f-title",
69
- "attr": {
70
- ":label": "sFullName + ` - ` + sDepartment"
71
- }
72
- }
73
- ```
74
-
75
- ```json
76
- {
77
- "el": "f-table",
78
- "attr": {
79
- ":label": "`${fTableTitle==''? 'Computer list' : fTableTitle}`"
80
- }
81
- }
82
- ```
83
-
84
- ---
85
-
86
- ## 4. v-switch — toggle with label
87
-
88
- ```json
89
- {
90
- "el": "v-layout",
91
- "attr": {},
92
- "innerHTML": [
93
- {
94
- "el": "v-switch",
95
- "attr": {
96
- "v-model": "switchResetPassword",
97
- ":required": false,
98
- "label": "Đặt lại mật khẩu"
99
- },
100
- "w": "12"
101
- }
102
- ]
103
- }
104
- ```
105
-
106
- Combine with `v-if` to show/hide extra fields:
107
-
108
- ```json
109
- {
110
- "el": "v-layout",
111
- "attr": { "v-if": "switchResetPassword" },
112
- "innerHTML": [...]
113
- }
114
- ```
115
-
116
- ---
117
-
118
- ## 5. Two-column master-detail
119
-
120
- Left table row pick → watch → load right table. No new window needed.
121
-
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
-
124
- **`data[]` and watch:**
125
-
126
- ```json
127
- "data": [
128
- { "dsParent": [], "dsDetail": [], "selectedId": null },
129
- {
130
- "getParent": { "API": "/SM_Parent_Select", "OUT": "dsParent" },
131
- "getDetail": {
132
- "API": "/SM_Detail_Select",
133
- "IN": { "ParentID": "selectedId" },
134
- "OUT": "dsDetail"
135
- }
136
- },
137
- { "CALL": "getParent" }
138
- ],
139
- "watch": {
140
- "selectedId": { "CALL": "getDetail" }
141
- }
142
- ```
143
-
144
- **`t-button` column in the left table:**
145
-
146
- ```json
147
- {
148
- "text": "Chi tiết",
149
- "value": "ParentID",
150
- "align": "center",
151
- "el": "t-button",
152
- "attr": {
153
- "icon-text": "mdi-eye",
154
- "color": "primary",
155
- ":outlined": true,
156
- ":action": { "selectedId": "item.ParentID" }
157
- }
158
- }
159
- ```
160
-
161
- **2-column layout:**
162
-
163
- ```json
164
- {
165
- "prop": "fluid grid-list-md",
166
- "rows": [
167
- {
168
- "prop": "row wrap",
169
- "cols": [
170
- { "w": 5, "el": "f-table", "attr": { ":items": "dsParent", "item-key": "ParentID", ":headers": [...] } },
171
- { "w": 7, "el": "f-table", "attr": { ":items": "dsDetail", "item-key": "DetailID", ":headers": [...] } }
172
- ]
173
- }
174
- ]
175
- }
176
- ```
1
+ # FUI Layout Patterns — page-container, master-detail, switch, dynamic label
2
+
3
+ > Owns: **page layout patterns: sticky page-container, 2-column master-detail, v-switch, date init, dynamic label**.
4
+
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).
6
+
7
+ ---
8
+
9
+ ## 1. Date init with moment()
10
+
11
+ ```json
12
+ "data": [
13
+ {
14
+ "TuNgay": "moment().format('YYYY-MM-DD')",
15
+ "DenNgay": "moment().format('YYYY-MM-DD')"
16
+ }
17
+ ]
18
+ ```
19
+
20
+ > The value is a JS expression string, eval'd at init. `moment()` is available in the FUI runtime.
21
+
22
+ ---
23
+
24
+ ## 2. page-container + page-navigation
25
+
26
+ Use for a fixed filter bar on top with scrolling content below.
27
+
28
+ ```json
29
+ {
30
+ "prop": "page-container grid-list-md fluid",
31
+ "rows": [
32
+ {
33
+ "prop": "page-navigation",
34
+ "cols": [
35
+ { "el": "f-date", "attr": { "v-model": "TuNgay", "label": "Từ ngày", "date-add": 0 }, "w": "2" },
36
+ { "el": "f-date", "attr": { "v-model": "DenNgay", "label": "Tới ngày", "date-add": 0 }, "w": "2" },
37
+ {
38
+ "el": "f-button",
39
+ "attr": {
40
+ "color": "primary",
41
+ "icon-text": "mdi-filter",
42
+ "label": "Tìm",
43
+ ":action": { "CALL": "getLogData" }
44
+ },
45
+ "w": 3
46
+ }
47
+ ]
48
+ },
49
+ {
50
+ "prop": "",
51
+ "cols": [{ "el": "f-table", "attr": { "label": "Log viewer", ":items": "LogData" } }]
52
+ }
53
+ ]
54
+ }
55
+ ```
56
+
57
+ - `page-container` + `page-navigation` → sticky top filter bar
58
+ - `f-table` without `:update-api` → readonly; without `:headers` → headers auto-built from data
59
+
60
+ ---
61
+
62
+ ## 3. Dynamic label from state
63
+
64
+ Use `:label` with an expression to show context.
65
+
66
+ ```json
67
+ {
68
+ "el": "f-title",
69
+ "attr": {
70
+ ":label": "sFullName + ` - ` + sDepartment"
71
+ }
72
+ }
73
+ ```
74
+
75
+ ```json
76
+ {
77
+ "el": "f-table",
78
+ "attr": {
79
+ ":label": "`${fTableTitle==''? 'Computer list' : fTableTitle}`"
80
+ }
81
+ }
82
+ ```
83
+
84
+ ---
85
+
86
+ ## 4. v-switch — toggle with label
87
+
88
+ ```json
89
+ {
90
+ "el": "v-layout",
91
+ "attr": {},
92
+ "innerHTML": [
93
+ {
94
+ "el": "v-switch",
95
+ "attr": {
96
+ "v-model": "switchResetPassword",
97
+ ":required": false,
98
+ "label": "Đặt lại mật khẩu"
99
+ },
100
+ "w": "12"
101
+ }
102
+ ]
103
+ }
104
+ ```
105
+
106
+ Combine with `v-if` to show/hide extra fields:
107
+
108
+ ```json
109
+ {
110
+ "el": "v-layout",
111
+ "attr": { "v-if": "switchResetPassword" },
112
+ "innerHTML": [...]
113
+ }
114
+ ```
115
+
116
+ ---
117
+
118
+ ## 5. Two-column master-detail
119
+
120
+ Left table row pick → watch → load right table. No new window needed.
121
+
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
+
124
+ **`data[]` and watch:**
125
+
126
+ ```json
127
+ "data": [
128
+ { "dsParent": [], "dsDetail": [], "selectedId": null },
129
+ {
130
+ "getParent": { "API": "/SM_Parent_Select", "OUT": "dsParent" },
131
+ "getDetail": {
132
+ "API": "/SM_Detail_Select",
133
+ "IN": { "ParentID": "selectedId" },
134
+ "OUT": "dsDetail"
135
+ }
136
+ },
137
+ { "CALL": "getParent" }
138
+ ],
139
+ "watch": {
140
+ "selectedId": { "CALL": "getDetail" }
141
+ }
142
+ ```
143
+
144
+ **`t-button` column in the left table:**
145
+
146
+ ```json
147
+ {
148
+ "text": "Chi tiết",
149
+ "value": "ParentID",
150
+ "align": "center",
151
+ "el": "t-button",
152
+ "attr": {
153
+ "icon-text": "mdi-eye",
154
+ "color": "primary",
155
+ ":outlined": true,
156
+ ":action": { "selectedId": "item.ParentID" }
157
+ }
158
+ }
159
+ ```
160
+
161
+ **2-column layout:**
162
+
163
+ ```json
164
+ {
165
+ "prop": "fluid grid-list-md",
166
+ "rows": [
167
+ {
168
+ "prop": "row wrap",
169
+ "cols": [
170
+ { "w": 5, "el": "f-table", "attr": { ":items": "dsParent", "item-key": "ParentID", ":headers": [...] } },
171
+ { "w": 7, "el": "f-table", "attr": { ":items": "dsDetail", "item-key": "DetailID", ":headers": [...] } }
172
+ ]
173
+ }
174
+ ]
175
+ }
176
+ ```