@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,318 +1,318 @@
1
- # FUI Table Cell Patterns — f-table & in-cell controls
2
-
3
- > Owns: **in-cell `f-table` controls (`t-*`), `ctrl-update`, show-select, chip-group, `t-button` vs `t-menu`**. Table props: [component-table.md](component-table.md).
4
-
5
- Patterns for `f-table` and in-cell controls (`t-check`, `t-button`, `t-select`, `t-menu`, `ctrl-update`, `show-select`, `v-chip-group`), from project **security-manager**.
6
-
7
- > See also: [ui-patterns.md](ui-patterns.md) (data/watch/toolbar), [ui-dialog-patterns.md](ui-dialog-patterns.md), [component-table.md](component-table.md).
8
-
9
- ---
10
-
11
- ## 1. Basic f-table with fixed header
12
-
13
- ```json
14
- {
15
- "el": "f-table",
16
- "attr": {
17
- "label": "User list",
18
- ":items-per-page": 50,
19
- ":height": -16,
20
- ":items": "dsUser",
21
- "item-key": "UserID",
22
- ":hide-default-footer": false,
23
- ":item-class": "item => item.ChuaKichHoat>0 ? 'danger' : ''",
24
- ":headers": [
25
- { "align": "center", "text": "UserID", "value": "UserID" },
26
- { "text": "Username", "value": "UserName" },
27
- { "text": "Fullname", "value": "FullName" }
28
- ]
29
- },
30
- "w": 12
31
- }
32
- ```
33
-
34
- - **Table height RULE (lint D9)**: the module's main data table declares `":height": -16` — f-table **measures its real position** after layout (`getBoundingClientRect().top`), fills to the screen bottom leaving 16px, and enables `fixed-header`. Data scrolls **inside the table** only, header stays put, no nested page scrollbars. Updates on window resize and when `items` changes.
35
-
36
- | `:height` | Behavior |
37
- | ----------- | ----------------------------------------------------------------------------------------------------- |
38
- | _(omitted)_ | Grows with row count — intentional short/lookup tables; wrong for the main table (whole page scrolls) |
39
- | `<= 0` | Fill to bottom leaving `abs(height)` px — **standard for main table** |
40
- | `> 0` | Fixed px — **table inside a dialog** (e.g. `":height": 360`) |
41
-
42
- Same three modes apply to `f-sheet` — see [fsheet.md](fsheet.md) §Height.
43
-
44
- ⚠ Old pattern `":height": "$( window ).height()-285"` is **deprecated** — it forces guessing total toolbar/filter/menu height; wrong guess = short or overflowing. It returns a **positive** number so it still works as fixed px (doesn't break) but loses auto-measure; lint D9 warns so you replace it with `-16`.
45
-
46
- - `:item-class`: conditional row highlight — `"item => item.Active==0 ? 'danger' : ''"`
47
-
48
- ---
49
-
50
- ## 2. t-check — toggle in cell
51
-
52
- In `headers`, renders a checkbox/icon toggle that fires an API on click.
53
-
54
- ```json
55
- {
56
- "text": "Active",
57
- "value": "Enable",
58
- "align": "center",
59
- "el": "t-check",
60
- "attr": {
61
- "on-icon": "mdi-check",
62
- "off-icon": "mdi-lock",
63
- ":action": [
64
- { "API": "/SM_Users_SetActive", "IN": { "UserID": "item.UserID" } },
65
- { "dsUser": [] },
66
- { "CALL": "getUser" }
67
- ]
68
- }
69
- }
70
- ```
71
-
72
- ---
73
-
74
- ## 3. t-button — button in cell
75
-
76
- Button/icon with an action in a cell; supports dynamic icons.
77
-
78
- ```json
79
- {
80
- "text": "Allow",
81
- "value": "Locked",
82
- "align": "center",
83
- "el": "t-button",
84
- "attr": {
85
- "color": "primary",
86
- ":outlined": false,
87
- ":icon-text": "`${ item.Locked==0 ? 'mdi-check-bold':'mdi-lock'}`",
88
- ":action": [
89
- { "API": "/SM_Computer_SetLocked", "IN": { "ComputerID": "item.ComputerID" } },
90
- { "dsComputer": [] },
91
- { "CALL": "getComputer" }
92
- ]
93
- }
94
- }
95
- ```
96
-
97
- ---
98
-
99
- ## 4. t-select — inline dropdown in cell
100
-
101
- Edit a field in the table; fires an API on selection.
102
-
103
- ```json
104
- {
105
- "text": "SystemRight",
106
- "value": "SysRight",
107
- "el": "t-select",
108
- "width": "250px",
109
- "attr": {
110
- "class": "flex-md-grow-0 my-2",
111
- ":items": "vueData.dsSystemRight",
112
- "item-text": "Note",
113
- "item-value": "SysRight",
114
- ":action": [
115
- {
116
- "CONFIRM": "Bạn có chắc cập nhật System Right cho user này không?",
117
- "API": "/SM_UserModule_UpdateSystemRight",
118
- "IN": {
119
- "ModuleID": "sModuleID",
120
- "UserID": "item.UserID",
121
- "SysRight": "item.SysRight"
122
- },
123
- "CALLBACK": { "MESS": "Cập nhật thành công." }
124
- }
125
- ]
126
- }
127
- }
128
- ```
129
-
130
- ---
131
-
132
- ## 5. t-menu — context menu in table (menuChucNang)
133
-
134
- Define menu items in `data[]`, reference via `t-menu` in headers.
135
-
136
- **Step 1 — `menuChucNang` in `data[]`:**
137
-
138
- ```json
139
- {
140
- "menuChucNang": [
141
- {
142
- "color": "primary",
143
- "icon-text": "mdi-account-details",
144
- "text": "Update Info",
145
- "action": [
146
- {
147
- "addNew": 0,
148
- "dongChon": "item",
149
- "sUserID": "item.UserID",
150
- "sUserName": "item.UserName",
151
- "sLastName": "item.LastName",
152
- "sFirstName": "item.FirstName"
153
- },
154
- { "dlUserInfo": true }
155
- ]
156
- },
157
- {
158
- "color": "primary",
159
- "icon-text": "mdi-shield-account-outline",
160
- "text": "User Permission",
161
- "action": [
162
- {
163
- "dongChon": "item",
164
- "sUserID": "item.UserID",
165
- "sFullName": "item.FullName"
166
- },
167
- {
168
- "FUN": "openWindow",
169
- "IN": {
170
- "id": "`WinPer",
171
- "title": "`User Permission",
172
- "url": "`/UserPermission"
173
- }
174
- }
175
- ]
176
- }
177
- ]
178
- }
179
- ```
180
-
181
- **Step 2 — `t-menu` in `headers`:**
182
-
183
- ```json
184
- {
185
- "el": "t-menu",
186
- "width": "120px",
187
- "align": "center",
188
- "text": "Update",
189
- "value": "Update",
190
- "attr": { ":items": "vueData.menuChucNang" }
191
- }
192
- ```
193
-
194
- - `"dongChon": "item"` — stores the current record in `dongChon`
195
- - `"sUserID": "item.UserID"` etc. — copy item fields into state
196
- - `{ "dlXxx": true }` — open the dialog after state is ready
197
-
198
- ---
199
-
200
- ## 6. ctrl-update CRUD
201
-
202
- CRUD directly in the table — no manual dialog.
203
-
204
- ```json
205
- {
206
- "el": "f-table",
207
- "attr": {
208
- ":items": "dsFunctionRight",
209
- "item-key": "FunctionID",
210
- ":headers": [
211
- { "text": "Code", "value": "FunctionCode" },
212
- { "text": "Name", "value": "FunctionName" },
213
- { "text": "Update", "value": "ctrl-update" }
214
- ],
215
- ":update-form": [
216
- {
217
- "el": "v-text-field",
218
- "w": 12,
219
- "attr": { "v-model": "FunctionCode", "label": "Function Code", ":required": true }
220
- },
221
- {
222
- "el": "v-text-field",
223
- "w": 12,
224
- "attr": { "v-model": "FunctionName", "label": "Function Name" }
225
- }
226
- ],
227
- ":update-api": {
228
- "new": {
229
- "API": "/SM_Function_Insert",
230
- "IN": { "ModuleID": "sModuleID", "FunctionCode": "item.FunctionCode", "FunctionName": "item.FunctionName" },
231
- "CALLBACK": { "CALL": "getFunctionRight" }
232
- },
233
- "edit": {
234
- "API": "/SM_Function_Update",
235
- "IN": {
236
- "FunctionID": "item.FunctionID",
237
- "FunctionCode": "item.FunctionCode",
238
- "FunctionName": "item.FunctionName"
239
- },
240
- "CALLBACK": { "CALL": "getFunctionRight" }
241
- },
242
- "delete": {
243
- "CONFIRM": "Bạn có chắc muốn xóa quyền này không?",
244
- "API": "/SM_Function_Delete",
245
- "IN": { "FunctionID": "item.FunctionID" },
246
- "CALLBACK": [{ "MESS": "Xóa thành công" }, { "CALL": "getFunctionRight" }]
247
- }
248
- }
249
- }
250
- }
251
- ```
252
-
253
- Use ctrl-update for simple edit forms (2–5 fields) with no complex layout.
254
-
255
- ---
256
-
257
- ## 7. f-table with show-select (multi-select)
258
-
259
- ```json
260
- {
261
- "el": "f-table",
262
- "attr": {
263
- ":show-select": true,
264
- "v-model": "sUserSelected",
265
- ":items": "dsUsers",
266
- "item-key": "UserID",
267
- ":items-per-page": -1,
268
- ":hide-default-footer": true,
269
- ":update-api": { "default-item": { "xAA": [] } },
270
- ":headers": [...]
271
- }
272
- }
273
- ```
274
-
275
- - `v-model`: array of selected items
276
- - `:update-api.default-item`: injects default fields into each item on load (here `xAA: []` for chip-group)
277
-
278
- ---
279
-
280
- ## 8. v-chip-group in cell
281
-
282
- Tag list in a cell; click opens a dialog.
283
-
284
- ```json
285
- {
286
- "text": "FunctionRight",
287
- "value": "FunctionName",
288
- "el": "v-chip-group",
289
- "attr": {
290
- "v-model": "item.xAA",
291
- "column": true,
292
- "v-if": "item.FunctionName"
293
- },
294
- "innerHTML": [
295
- {
296
- "el": "v-chip",
297
- "attr": {
298
- ":small": true,
299
- "color": "primary",
300
- "outlined": "",
301
- "v-for": "fn in item.FunctionName",
302
- ":key": "fn",
303
- "v-on:click": "vueData.dlFunction = true; CALL(setFunction(item, item.FunctionName));"
304
- },
305
- "innerHTML": "<div>{{fn.FunctionCode}}-{{fn.FunctionName}}</div>"
306
- }
307
- ]
308
- }
309
- ```
310
-
311
- ---
312
-
313
- ## `t-button` vs `t-menu`
314
-
315
- - **`t-button`**: the only action is viewing/loading related data → one direct click
316
- - **`t-menu`**: several actions **or** a state-changing action (Kích hoạt, Chốt điểm, Xóa...)
317
-
318
- > Don't wrap "Xem chi tiết" in `t-menu` — adds a wasted click; use `t-button`. See Master-Detail in [ui-layout-patterns.md](ui-layout-patterns.md).
1
+ # FUI Table Cell Patterns — f-table & in-cell controls
2
+
3
+ > Owns: **in-cell `f-table` controls (`t-*`), `ctrl-update`, show-select, chip-group, `t-button` vs `t-menu`**. Table props: [component-table.md](component-table.md).
4
+
5
+ Patterns for `f-table` and in-cell controls (`t-check`, `t-button`, `t-select`, `t-menu`, `ctrl-update`, `show-select`, `v-chip-group`), from project **security-manager**.
6
+
7
+ > See also: [ui-patterns.md](ui-patterns.md) (data/watch/toolbar), [ui-dialog-patterns.md](ui-dialog-patterns.md), [component-table.md](component-table.md).
8
+
9
+ ---
10
+
11
+ ## 1. Basic f-table with fixed header
12
+
13
+ ```json
14
+ {
15
+ "el": "f-table",
16
+ "attr": {
17
+ "label": "User list",
18
+ ":items-per-page": 50,
19
+ ":height": -16,
20
+ ":items": "dsUser",
21
+ "item-key": "UserID",
22
+ ":hide-default-footer": false,
23
+ ":item-class": "item => item.ChuaKichHoat>0 ? 'danger' : ''",
24
+ ":headers": [
25
+ { "align": "center", "text": "UserID", "value": "UserID" },
26
+ { "text": "Username", "value": "UserName" },
27
+ { "text": "Fullname", "value": "FullName" }
28
+ ]
29
+ },
30
+ "w": 12
31
+ }
32
+ ```
33
+
34
+ - **Table height RULE (lint D9)**: the module's main data table declares `":height": -16` — f-table **measures its real position** after layout (`getBoundingClientRect().top`), fills to the screen bottom leaving 16px, and enables `fixed-header`. Data scrolls **inside the table** only, header stays put, no nested page scrollbars. Updates on window resize and when `items` changes.
35
+
36
+ | `:height` | Behavior |
37
+ | ----------- | ----------------------------------------------------------------------------------------------------- |
38
+ | _(omitted)_ | Grows with row count — intentional short/lookup tables; wrong for the main table (whole page scrolls) |
39
+ | `<= 0` | Fill to bottom leaving `abs(height)` px — **standard for main table** |
40
+ | `> 0` | Fixed px — **table inside a dialog** (e.g. `":height": 360`) |
41
+
42
+ Same three modes apply to `f-sheet` — see [fsheet.md](fsheet.md) §Height.
43
+
44
+ ⚠ Old pattern `":height": "$( window ).height()-285"` is **deprecated** — it forces guessing total toolbar/filter/menu height; wrong guess = short or overflowing. It returns a **positive** number so it still works as fixed px (doesn't break) but loses auto-measure; lint D9 warns so you replace it with `-16`.
45
+
46
+ - `:item-class`: conditional row highlight — `"item => item.Active==0 ? 'danger' : ''"`
47
+
48
+ ---
49
+
50
+ ## 2. t-check — toggle in cell
51
+
52
+ In `headers`, renders a checkbox/icon toggle that fires an API on click.
53
+
54
+ ```json
55
+ {
56
+ "text": "Active",
57
+ "value": "Enable",
58
+ "align": "center",
59
+ "el": "t-check",
60
+ "attr": {
61
+ "on-icon": "mdi-check",
62
+ "off-icon": "mdi-lock",
63
+ ":action": [
64
+ { "API": "/SM_Users_SetActive", "IN": { "UserID": "item.UserID" } },
65
+ { "dsUser": [] },
66
+ { "CALL": "getUser" }
67
+ ]
68
+ }
69
+ }
70
+ ```
71
+
72
+ ---
73
+
74
+ ## 3. t-button — button in cell
75
+
76
+ Button/icon with an action in a cell; supports dynamic icons.
77
+
78
+ ```json
79
+ {
80
+ "text": "Allow",
81
+ "value": "Locked",
82
+ "align": "center",
83
+ "el": "t-button",
84
+ "attr": {
85
+ "color": "primary",
86
+ ":outlined": false,
87
+ ":icon-text": "`${ item.Locked==0 ? 'mdi-check-bold':'mdi-lock'}`",
88
+ ":action": [
89
+ { "API": "/SM_Computer_SetLocked", "IN": { "ComputerID": "item.ComputerID" } },
90
+ { "dsComputer": [] },
91
+ { "CALL": "getComputer" }
92
+ ]
93
+ }
94
+ }
95
+ ```
96
+
97
+ ---
98
+
99
+ ## 4. t-select — inline dropdown in cell
100
+
101
+ Edit a field in the table; fires an API on selection.
102
+
103
+ ```json
104
+ {
105
+ "text": "SystemRight",
106
+ "value": "SysRight",
107
+ "el": "t-select",
108
+ "width": "250px",
109
+ "attr": {
110
+ "class": "flex-md-grow-0 my-2",
111
+ ":items": "vueData.dsSystemRight",
112
+ "item-text": "Note",
113
+ "item-value": "SysRight",
114
+ ":action": [
115
+ {
116
+ "CONFIRM": "Bạn có chắc cập nhật System Right cho user này không?",
117
+ "API": "/SM_UserModule_UpdateSystemRight",
118
+ "IN": {
119
+ "ModuleID": "sModuleID",
120
+ "UserID": "item.UserID",
121
+ "SysRight": "item.SysRight"
122
+ },
123
+ "CALLBACK": { "MESS": "Cập nhật thành công." }
124
+ }
125
+ ]
126
+ }
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ## 5. t-menu — context menu in table (menuChucNang)
133
+
134
+ Define menu items in `data[]`, reference via `t-menu` in headers.
135
+
136
+ **Step 1 — `menuChucNang` in `data[]`:**
137
+
138
+ ```json
139
+ {
140
+ "menuChucNang": [
141
+ {
142
+ "color": "primary",
143
+ "icon-text": "mdi-account-details",
144
+ "text": "Update Info",
145
+ "action": [
146
+ {
147
+ "addNew": 0,
148
+ "dongChon": "item",
149
+ "sUserID": "item.UserID",
150
+ "sUserName": "item.UserName",
151
+ "sLastName": "item.LastName",
152
+ "sFirstName": "item.FirstName"
153
+ },
154
+ { "dlUserInfo": true }
155
+ ]
156
+ },
157
+ {
158
+ "color": "primary",
159
+ "icon-text": "mdi-shield-account-outline",
160
+ "text": "User Permission",
161
+ "action": [
162
+ {
163
+ "dongChon": "item",
164
+ "sUserID": "item.UserID",
165
+ "sFullName": "item.FullName"
166
+ },
167
+ {
168
+ "FUN": "openWindow",
169
+ "IN": {
170
+ "id": "`WinPer",
171
+ "title": "`User Permission",
172
+ "url": "`/UserPermission"
173
+ }
174
+ }
175
+ ]
176
+ }
177
+ ]
178
+ }
179
+ ```
180
+
181
+ **Step 2 — `t-menu` in `headers`:**
182
+
183
+ ```json
184
+ {
185
+ "el": "t-menu",
186
+ "width": "120px",
187
+ "align": "center",
188
+ "text": "Update",
189
+ "value": "Update",
190
+ "attr": { ":items": "vueData.menuChucNang" }
191
+ }
192
+ ```
193
+
194
+ - `"dongChon": "item"` — stores the current record in `dongChon`
195
+ - `"sUserID": "item.UserID"` etc. — copy item fields into state
196
+ - `{ "dlXxx": true }` — open the dialog after state is ready
197
+
198
+ ---
199
+
200
+ ## 6. ctrl-update CRUD
201
+
202
+ CRUD directly in the table — no manual dialog.
203
+
204
+ ```json
205
+ {
206
+ "el": "f-table",
207
+ "attr": {
208
+ ":items": "dsFunctionRight",
209
+ "item-key": "FunctionID",
210
+ ":headers": [
211
+ { "text": "Code", "value": "FunctionCode" },
212
+ { "text": "Name", "value": "FunctionName" },
213
+ { "text": "Update", "value": "ctrl-update" }
214
+ ],
215
+ ":update-form": [
216
+ {
217
+ "el": "v-text-field",
218
+ "w": 12,
219
+ "attr": { "v-model": "FunctionCode", "label": "Function Code", ":required": true }
220
+ },
221
+ {
222
+ "el": "v-text-field",
223
+ "w": 12,
224
+ "attr": { "v-model": "FunctionName", "label": "Function Name" }
225
+ }
226
+ ],
227
+ ":update-api": {
228
+ "new": {
229
+ "API": "/SM_Function_Insert",
230
+ "IN": { "ModuleID": "sModuleID", "FunctionCode": "item.FunctionCode", "FunctionName": "item.FunctionName" },
231
+ "CALLBACK": { "CALL": "getFunctionRight" }
232
+ },
233
+ "edit": {
234
+ "API": "/SM_Function_Update",
235
+ "IN": {
236
+ "FunctionID": "item.FunctionID",
237
+ "FunctionCode": "item.FunctionCode",
238
+ "FunctionName": "item.FunctionName"
239
+ },
240
+ "CALLBACK": { "CALL": "getFunctionRight" }
241
+ },
242
+ "delete": {
243
+ "CONFIRM": "Bạn có chắc muốn xóa quyền này không?",
244
+ "API": "/SM_Function_Delete",
245
+ "IN": { "FunctionID": "item.FunctionID" },
246
+ "CALLBACK": [{ "MESS": "Xóa thành công" }, { "CALL": "getFunctionRight" }]
247
+ }
248
+ }
249
+ }
250
+ }
251
+ ```
252
+
253
+ Use ctrl-update for simple edit forms (2–5 fields) with no complex layout.
254
+
255
+ ---
256
+
257
+ ## 7. f-table with show-select (multi-select)
258
+
259
+ ```json
260
+ {
261
+ "el": "f-table",
262
+ "attr": {
263
+ ":show-select": true,
264
+ "v-model": "sUserSelected",
265
+ ":items": "dsUsers",
266
+ "item-key": "UserID",
267
+ ":items-per-page": -1,
268
+ ":hide-default-footer": true,
269
+ ":update-api": { "default-item": { "xAA": [] } },
270
+ ":headers": [...]
271
+ }
272
+ }
273
+ ```
274
+
275
+ - `v-model`: array of selected items
276
+ - `:update-api.default-item`: injects default fields into each item on load (here `xAA: []` for chip-group)
277
+
278
+ ---
279
+
280
+ ## 8. v-chip-group in cell
281
+
282
+ Tag list in a cell; click opens a dialog.
283
+
284
+ ```json
285
+ {
286
+ "text": "FunctionRight",
287
+ "value": "FunctionName",
288
+ "el": "v-chip-group",
289
+ "attr": {
290
+ "v-model": "item.xAA",
291
+ "column": true,
292
+ "v-if": "item.FunctionName"
293
+ },
294
+ "innerHTML": [
295
+ {
296
+ "el": "v-chip",
297
+ "attr": {
298
+ ":small": true,
299
+ "color": "primary",
300
+ "outlined": "",
301
+ "v-for": "fn in item.FunctionName",
302
+ ":key": "fn",
303
+ "v-on:click": "vueData.dlFunction = true; CALL(setFunction(item, item.FunctionName));"
304
+ },
305
+ "innerHTML": "<div>{{fn.FunctionCode}}-{{fn.FunctionName}}</div>"
306
+ }
307
+ ]
308
+ }
309
+ ```
310
+
311
+ ---
312
+
313
+ ## `t-button` vs `t-menu`
314
+
315
+ - **`t-button`**: the only action is viewing/loading related data → one direct click
316
+ - **`t-menu`**: several actions **or** a state-changing action (Kích hoạt, Chốt điểm, Xóa...)
317
+
318
+ > Don't wrap "Xem chi tiết" in `t-menu` — adds a wasted click; use `t-button`. See Master-Detail in [ui-layout-patterns.md](ui-layout-patterns.md).