@fui-org/fui-cli 1.3.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +21 -3
  2. package/dist/fui-cx180e19.js +379 -0
  3. package/dist/fui.js +1 -1
  4. package/package.json +3 -6
  5. package/skills/fui/SKILL.md +9 -41
  6. package/skills/fui-skill/SKILL.md +95 -225
  7. package/skills/fui-skill/assets/projectdefaultstyle-3.0.css +555 -0
  8. package/skills/fui-skill/assets/projectdefaultstyle.css +207 -235
  9. package/skills/fui-skill/references/INDEX.md +105 -137
  10. package/skills/fui-skill/references/advanced-techniques.md +76 -68
  11. package/skills/fui-skill/references/coding-standards.md +56 -56
  12. package/skills/fui-skill/references/component-design.md +166 -173
  13. package/skills/fui-skill/references/component-quickref.md +61 -60
  14. package/skills/fui-skill/references/component-table.md +128 -117
  15. package/skills/fui-skill/references/components-dialog.md +55 -56
  16. package/skills/fui-skill/references/components-display.md +24 -30
  17. package/skills/fui-skill/references/components-echart.md +186 -261
  18. package/skills/fui-skill/references/components-input.md +72 -96
  19. package/skills/fui-skill/references/controls-patterns.md +196 -342
  20. package/skills/fui-skill/references/controls-styling-vocabulary.md +130 -97
  21. package/skills/fui-skill/references/db-table-design.md +24 -28
  22. package/skills/fui-skill/references/db-workflow.md +191 -390
  23. package/skills/fui-skill/references/default-function.md +169 -128
  24. package/skills/fui-skill/references/design-modes.md +35 -63
  25. package/skills/fui-skill/references/echart-templates.md +204 -196
  26. package/skills/fui-skill/references/fastproject.md +62 -60
  27. package/skills/fui-skill/references/fsheet.md +109 -124
  28. package/skills/fui-skill/references/fullstack-workflow.md +90 -128
  29. package/skills/fui-skill/references/module-data-patterns.md +31 -40
  30. package/skills/fui-skill/references/module-json-anatomy.md +47 -52
  31. package/skills/fui-skill/references/module-structure.md +80 -196
  32. package/skills/fui-skill/references/new-session.md +49 -51
  33. package/skills/fui-skill/references/pdfmake.md +17 -17
  34. package/skills/fui-skill/references/permission-system.md +89 -108
  35. package/skills/fui-skill/references/platform-architecture.md +128 -153
  36. package/skills/fui-skill/references/project-config.md +102 -134
  37. package/skills/fui-skill/references/project-provisioning.md +139 -244
  38. package/skills/fui-skill/references/script-map.md +208 -242
  39. package/skills/fui-skill/references/sql-clr-functions.md +98 -97
  40. package/skills/fui-skill/references/system-design.md +63 -88
  41. package/skills/fui-skill/references/tapi-file-api.md +46 -52
  42. package/skills/fui-skill/references/tapi-permission-patterns.md +51 -53
  43. package/skills/fui-skill/references/tapi-reference.md +132 -207
  44. package/skills/fui-skill/references/tools-registry.md +84 -460
  45. package/skills/fui-skill/references/ui-crosswindow-patterns.md +79 -75
  46. package/skills/fui-skill/references/ui-dialog-patterns.md +98 -72
  47. package/skills/fui-skill/references/ui-layout-patterns.md +26 -26
  48. package/skills/fui-skill/references/ui-patterns.md +71 -83
  49. package/skills/fui-skill/references/ui-screenshot-review.md +63 -62
  50. package/skills/fui-skill/references/ui-table-cell-patterns.md +61 -59
  51. package/skills/fui-skill/references/ui-templates.md +16 -23
  52. package/skills/fui-skill/references/verification.md +236 -246
  53. package/skills/fui-skill/references/watcher-patterns.md +30 -63
  54. package/skills/fui-skill/references/websocket-realtime.md +83 -66
  55. package/skills/fui-skill/scripts/component-3.0.js +298 -131
  56. package/skills/fui-skill/scripts/component.js +277 -271
  57. package/skills/fui-skill/scripts/componentTable-3.0.js +182 -53
  58. package/skills/fui-skill/scripts/componentTable.js +171 -49
  59. package/skills/fui-skill/scripts/defaultfunction-3.0.js +88 -3
  60. package/skills/fui-skill/scripts/defaultfunction.js +88 -3
  61. package/skills/fui-skill/scripts/fsheet.js +38 -0
  62. package/skills/fui-target/.claude-plugin/plugin.json +6 -0
  63. package/skills/fui-target/hooks/hooks.json +1 -0
  64. package/skills/fui-target/hooks/register.tsx +71 -0
  65. package/skills/fui-target/types/index.d.ts +7 -0
  66. package/dist/fui-y8an39cn.js +0 -420
  67. package/skills/fui-skill/README.md +0 -112
  68. package/skills/fui-skill/metadata.json +0 -75
  69. package/skills/fui-skill-cli/SKILL.md +0 -139
  70. package/skills/fui-skill-cli/references/INDEX.md +0 -110
  71. package/skills/fui-skill-cli/references/advanced-techniques.md +0 -168
  72. package/skills/fui-skill-cli/references/coding-standards.md +0 -112
  73. package/skills/fui-skill-cli/references/component-design.md +0 -448
  74. package/skills/fui-skill-cli/references/component-quickref.md +0 -78
  75. package/skills/fui-skill-cli/references/component-table.md +0 -248
  76. package/skills/fui-skill-cli/references/components-dialog.md +0 -191
  77. package/skills/fui-skill-cli/references/components-display.md +0 -141
  78. package/skills/fui-skill-cli/references/components-echart.md +0 -316
  79. package/skills/fui-skill-cli/references/components-input.md +0 -335
  80. package/skills/fui-skill-cli/references/controls-patterns.md +0 -701
  81. package/skills/fui-skill-cli/references/controls-styling-vocabulary.md +0 -137
  82. package/skills/fui-skill-cli/references/db-table-design.md +0 -73
  83. package/skills/fui-skill-cli/references/db-workflow.md +0 -288
  84. package/skills/fui-skill-cli/references/default-function.md +0 -425
  85. package/skills/fui-skill-cli/references/design-modes.md +0 -57
  86. package/skills/fui-skill-cli/references/echart-templates.md +0 -489
  87. package/skills/fui-skill-cli/references/fastproject.md +0 -99
  88. package/skills/fui-skill-cli/references/fsheet.md +0 -203
  89. package/skills/fui-skill-cli/references/fullstack-workflow.md +0 -313
  90. package/skills/fui-skill-cli/references/module-data-patterns.md +0 -117
  91. package/skills/fui-skill-cli/references/module-json-anatomy.md +0 -132
  92. package/skills/fui-skill-cli/references/module-structure.md +0 -141
  93. package/skills/fui-skill-cli/references/new-session.md +0 -85
  94. package/skills/fui-skill-cli/references/pdfmake.md +0 -60
  95. package/skills/fui-skill-cli/references/permission-system.md +0 -150
  96. package/skills/fui-skill-cli/references/platform-architecture.md +0 -269
  97. package/skills/fui-skill-cli/references/project-config.md +0 -303
  98. package/skills/fui-skill-cli/references/project-provisioning.md +0 -278
  99. package/skills/fui-skill-cli/references/script-map.md +0 -262
  100. package/skills/fui-skill-cli/references/sql-clr-functions.md +0 -225
  101. package/skills/fui-skill-cli/references/system-design.md +0 -89
  102. package/skills/fui-skill-cli/references/tapi-file-api.md +0 -185
  103. package/skills/fui-skill-cli/references/tapi-permission-patterns.md +0 -156
  104. package/skills/fui-skill-cli/references/tapi-reference.md +0 -474
  105. package/skills/fui-skill-cli/references/tools-registry.md +0 -84
  106. package/skills/fui-skill-cli/references/ui-crosswindow-patterns.md +0 -321
  107. package/skills/fui-skill-cli/references/ui-dialog-patterns.md +0 -255
  108. package/skills/fui-skill-cli/references/ui-layout-patterns.md +0 -176
  109. package/skills/fui-skill-cli/references/ui-patterns.md +0 -303
  110. package/skills/fui-skill-cli/references/ui-screenshot-review.md +0 -95
  111. package/skills/fui-skill-cli/references/ui-table-cell-patterns.md +0 -318
  112. package/skills/fui-skill-cli/references/ui-templates.md +0 -22
  113. package/skills/fui-skill-cli/references/verification.md +0 -236
  114. package/skills/fui-skill-cli/references/watcher-patterns.md +0 -163
  115. package/skills/fui-skill-cli/references/websocket-realtime.md +0 -271
@@ -1,94 +1,95 @@
1
- # Review giao diện qua ảnh chụp màn hình
1
+ # UI review from screenshots
2
2
 
3
- > File này sở hữu: **cách đọc và đánh giá ảnh chụp giao diện (user gửi hoặc từ `renderUI`)**.
3
+ > Owns: **reading and assessing UI screenshots (user-sent or from `--render`)**.
4
4
 
5
- Áp dụng khi có **ảnh giao diện** để đánh giá, từ một trong hai nguồn:
5
+ Sources: (1) **user screenshot in chat** ("why is it ugly", "make it nicer", or an image + bug description); (2) **`fui module simulate --render`** — `render.png` (inline), `render-full.png`, `render-dialog.jpg`.
6
6
 
7
- 1. **User gửi ảnh chụp màn hình vào chat** — "xem giao diện này", "sao nhìn xấu vậy", "sửa lại cho đẹp", hoặc chỉ gửi ảnh kèm mô tả lỗi.
8
- 2. **Screenshot từ `module_simulate({ renderUI: true })`** — `render.png` (inline), `render-full.png`, `render-dialog.jpg`.
7
+ Act as design QA: scan with the checklist; map every finding to a **concrete code cause** (controls[i] in module.json, class/style, CSS in header.html) + fix. No vague "doesn't look good".
9
8
 
10
- Nguyên tắc cốt lõi: **nhìn ảnh như một designer QA** — quét có hệ thống theo checklist bên dưới, và mỗi phát hiện phải map về **nguyên nhân cụ thể trong code** (controls[i] nào trong module.json, class/style nào, CSS nào trong header.html) kèm fix đề xuất. Đừng chỉ mô tả cảm tính "nhìn chưa đẹp".
11
-
12
- **BẮT BUỘC — phát hiện xong là phải SỬA, không phải chỉ ghi nhận.** Checklist A–D bên dưới không phải danh sách tham khảo: nhìn thấy chữ dính/chồng lấn (khoảng hở quá ít), control lệch hàng/không thẳng, khoảng trắng dư thừa bất thường giữa các control — đây là lỗi thẩm mỹ **phải xử lý trong cùng lượt**, y hệt một lỗi hiển thị cứng. "Đã ghi nhận vào báo cáo" không phải là "đã xong việc". Chỉ dừng lại hỏi user khi bản thân không chắc ý đồ thiết kế (vd không rõ hai khối có nên tách hàng hay không) — còn lại thì tự sửa rồi render lại đối chiếu (bước 4 dưới đây).
9
+ **MANDATORY — FIX findings, don't just report them.** Stuck/overlapping text (too little gap), misaligned controls, abnormal whitespace between controls are bugs **to fix in the same turn**, like hard rendering bugs. "Noted in the report" ≠ done. Ask the user only when design intent is unclear (e.g. should two blocks be on separate rows); otherwise fix and re-render (step 4).
13
10
 
14
11
  ---
15
12
 
16
- ## Quy trình
13
+ ## Workflow
17
14
 
18
- 1. **Xác định bối cảnh** trước khi phán:
19
- - App-mode (CRUD/quản lý — chuẩn thẩm mỹ `design_read("fui")`) hay Web-mode (landing — theo brand DESIGN.md đã chọn)?
20
- - Desktop hay mobile? (ảnh hẹp/dọc → đánh giá theo chuẩn responsive)
21
- - Có module.json tương ứng trong workspace không? (có → đối chiếu ảnh ↔ controls để chỉ đúng vị trí sửa; không → nhận xét trên ảnh + xin module.json nếu cần sửa)
22
- 2. **Quét ảnh theo checklist A→D** (dưới) — ghi nhận từng phát hiện.
23
- 3. **Báo cáo dạng bảng**: `Phát hiện | Mức độ (lỗi/cần sửa/gợi ý) | Vị trí trên ảnh | Nguyên nhân khả dĩ | Fix đề xuất`.
24
- 4. **Tự sửa → render lại đối chiếu** (bắt buộc cho mọi phát hiện ở mục A/B, không chỉ lỗi cứng): nếu có workspace + Playwright, sửa module.json rồi `module_simulate({ renderUI: true })` (cùng viewport/device với ảnh gốc nếu đoán được) và so sánh screenshot mới với ảnh user gửi — lặp cho tới khi sạch. `renderUI` tự phát hiện text dính/chồng lấn (đối chiếu bounding-rect, xem mục A) và in vào DOM AUDIT kèm dòng "PHẢI sửa, không được bỏ qua" — thấy dòng đó thì sửa ngay trong lượt này, đừng để nguyên rồi báo cáo lại cho user quyết.
15
+ 1. **Establish context** first:
16
+ - App-mode (CRUD/admin — aesthetic standard `fui design read fui`) or Web-mode (landing — chosen brand DESIGN.md)?
17
+ - Desktop or mobile? (narrow/portrait image → judge by responsive standards)
18
+ - module.json in workspace? Yes → cross-check image ↔ controls to pinpoint the fix; no → comment on the image, ask for module.json if a fix is needed
19
+ 2. **Scan with checklist A→D**, record each finding.
20
+ 3. **Report as a table**: `Finding | Severity (bug/should fix/suggestion) | Location in image | Likely cause | Proposed fix`.
21
+ 4. **Fix → re-render → compare** (required for every A/B finding): with workspace + Playwright, edit module.json, run `fui module simulate --render` (same viewport/device as the original if guessable), compare with the user's image; repeat until clean. `--render` auto-detects stuck/overlapping text (bounding rects, see A) and prints it in DOM AUDIT with "PHẢI sửa, không được bỏ qua" — fix it this turn; don't hand it to the user.
25
22
 
26
- Ảnh mờ/cắt/không đủ thông tin → hỏi user chụp lại vùng cụ thể, đừng đoán bừa.
23
+ Blurry/cropped/insufficient image → ask the user to recapture the specific area; don't guess.
27
24
 
28
25
  ---
29
26
 
30
- ## Checklist quét ảnh
27
+ ## Scan checklist
31
28
 
32
- ### A. Lỗi hiển thị cứng (bug — phải sửa)
29
+ ### A. Hard rendering bugs (must fix)
33
30
 
34
- - Vùng trống bất thường: component không render (app rỗng, card trống, chart trắng/0-size)
35
- - Text lỗi lộ ra ngoài: `undefined`, `NaN`, `[object Object]`, message exception, key thay vì value
36
- - Tràn ngang: thanh cuộn ngang xuất hiện, phần tử bị cắt mép phải
37
- - Chữ/phần tử đè lên nhau, hoặc dính sát nhau tới mức đọc như liền một chữ (khoảng hở quá ít); label bị cắt cụt không chủ ý (truncate `...` ở chỗ không nên). `renderUI` dò được phần lớn ca này tự động (đối chiếu bounding-rect của các phần tử mang text, dòng `⚠ text dính/chồng lấn` trong DOM AUDIT) — nhưng đó chỉ là lưới an toàn, mắt vẫn phải tự quét thêm vì heuristic bỏ sót các ca không phải text thuần (icon chồng nút, ảnh chồng card...)
38
- - Ảnh vỡ (khung ảnh trống/icon broken), icon thiếu (ô vuông tofu — thường do font mdi chưa load hoặc sai tên icon)
39
- - Loading spinner đứng mãi (v_Loading không về false — thường API treo/lỗi init)
31
+ - Abnormal empty area: component didn't render (empty app, blank card, white/0-size chart)
32
+ - Leaked error text: `undefined`, `NaN`, `[object Object]`, exception messages, keys instead of values
33
+ - Horizontal overflow: horizontal scrollbar, elements clipped at the right edge
34
+ - Overlapping text/elements, or so close they read as one word; unintended truncation (`...`). `--render` catches most (line `⚠ text dính/chồng lấn` in DOM AUDIT) — only a safety net; still scan by eye, the heuristic misses non-text cases (icon over button, image over card...)
35
+ - Broken image (empty frame/broken icon), missing icon (tofu square — usually mdi font not loaded or wrong icon name)
36
+ - Spinner forever (v_Loading never returns to false — usually a hung API/init error)
40
37
 
41
- ### B. Bố cục, căn chỉnh, khoảng cách
38
+ ### B. Layout, alignment, spacing
42
39
 
43
- - **Thẳng hàng**: field cùng row thẳng baseline, cùng chiều cao (`dense`/`outlined` đồng bộ); các card/khối cùng hàng cùng chiều cao
44
- - **Căn trái/phải đúng ngữ nghĩa**: text căn trái; **số/tiền tệ trong bảng căn phải** (`t-num`); tiêu đề cột khớp hướng căn của data
45
- - **Vị trí nút chuẩn**: nút hành động chính của trang ở toolbar bên phải; trong dialog nút chính (Lưu/Đồng ý) nằm **phải** của `v-card-actions` (có `v-spacer` đẩy); không có nút "Đóng" thừa (D7)
46
- - **Hàng toolbar — nút phình / hở khoảng đều nhau**: triệu chứng đặc trưng của cột thiếu `shrink`. Nút rộng hơn hẳn chữ bên trong, các nút cách nhau những khoảng **bằng nhau**, và nhóm nút cuối **không sát mép phải** dù đã có `v-spacer` ⇒ các cột đó vẫn `flex-grow: 1` nên được chia phần trống y như spacer. Chuẩn: **mọi cột `"col": "shrink"`, trừ đúng `v-spacer`** — kể cả cột `w` rỗng ([controls-patterns.md](controls-patterns.md) §Hàng nhiều control). `module_validate` bắt được ca này trước khi phải nhìn ảnh
47
- - **Khoảng cách nhất quán**: padding/margin theo nhịp Vuetify (bội 4px — pa-2/ma-2...); không có khoảng hở to bất thường giữa các khối, không có khối dính sát mép màn hình
48
- - **Bảng data**: cuộn CHỈ trong bảng (bảng chính khai `":height": -16`), trang không có 2 thanh cuộn dọc lồng nhau, header bảng không trôi mất khi cuộn (D9)
49
- - **Cân đối grid**: các cột trong row có tỷ lệ hợp lý (Σw ≤ 12), không có cột bị bóp quá hẹp làm nội dung xuống dòng xấu
40
+ - **Alignment**: fields in a row share baseline and height (consistent `dense`/`outlined`); cards/blocks in a row share height
41
+ - **Semantic alignment**: text left; **numbers/currency in tables right** (`t-num`); column header matches data alignment
42
+ - **Button placement**: page primary action in the toolbar on the right; in a dialog the primary button (Lưu/Đồng ý) sits **right** in `v-card-actions` (pushed by `v-spacer`); no redundant "Đóng" button (D7)
43
+ - **Toolbar row — bloated buttons / equal gaps** = columns missing `shrink`: buttons much wider than their text, **equal** gaps, trailing group **not flush right** despite `v-spacer` ⇒ columns still `flex-grow: 1`, sharing free space like the spacer. Standard: **every column `"col": "shrink"` except `v-spacer`** — including empty-`w` columns ([controls-patterns.md](controls-patterns.md) §Toolbar row). `fui module validate` catches this before any screenshot
44
+ - **Consistent spacing**: Vuetify rhythm (multiples of 4px — pa-2/ma-2...); no abnormally large gaps between blocks, no blocks touching the screen edge
45
+ - **Data tables**: scroll ONLY inside the table (main table declares `":height": -16`), no two nested vertical page scrollbars, table header stays visible on scroll (D9)
46
+ - **Grid balance**: sensible column ratios in a row (Σw ≤ 12), no column squeezed so narrow content wraps badly
50
47
 
51
- ### C. Màu sắc & phân cấp thị giác (App-mode đối chiếu `design_read("fui")`)
48
+ ### C. Color & visual hierarchy (App-mode vs `fui design read fui`)
52
49
 
53
- - Đối chiếu bộ quy tắc D1–D9 của validator: toolbar dialog **cùng màu nền** thân (không color/dark); nút xóa màu **warning cam** (không đỏ/error); width dialog thuộc bộ 400/550/600/650/800
54
- - Một màn hình chỉ 1–2 màu nhấn; không tô màu tùy hứng vào card/nút phụ
55
- - Contrast đủ đọc (chữ xám nhạt trên nền trắng, chữ trên nền màu — nghi ngờ thì báo)
56
- - Trạng thái (chip/badge) dùng màu ngữ nghĩa nhất quán: success/warning/error cùng nghĩa ở mọi nơi
50
+ - Validator rules D1–D9: dialog toolbar **same background** as body (no color/dark); delete button **warning orange** (not red/error); dialog width in 400/550/600/650/800
51
+ - 1–2 accent colors per screen; no arbitrary color on cards/secondary buttons
52
+ - Readable contrast (light grey on white, text on colored backgrounds — report if doubtful)
53
+ - Status (chip/badge) semantic colors consistent: success/warning/error mean the same everywhere
57
54
 
58
- ### D. Mật độ & responsive
55
+ ### D. Density & responsive
59
56
 
60
- - Mức `dense`/gọn đồng bộ toàn màn (không chỗ dày chỗ thưa)
61
- - Ảnh mobile: cột tự xuống dòng đúng, nút không tràn/không quá bé để bấm, font đọc được, bảng có phương án mobile (`mobile-breakpoint`)
62
- - `viewport-fit=cover` (mặc định của FUI): nội dung sát mép trên/dưới ở màn có notch → cần safe-area padding
57
+ - Consistent `dense`/compact level across the screen (no dense-here, sparse-there)
58
+ - Mobile image: columns wrap correctly, buttons don't overflow and aren't too small to tap, readable font, tables have a mobile plan (`mobile-breakpoint`)
59
+ - `viewport-fit=cover` (FUI default): content at top/bottom edges on notched screens → needs safe-area padding
63
60
 
64
61
  ---
65
62
 
66
- ## Map triệu chứng → nguyên nhân thường gặp
63
+ ## Symptom → common cause
67
64
 
68
- | Triệu chứng trên ảnh | Nguyên nhân hay gặp | Fix |
69
- |---|---|---|
70
- | Trang có thanh cuộn dọc, bảng dài vô tận | f-table/f-sheet không khai `:height` → tự giãn theo số dòng | Thêm `":height": -16` (tự đo `rect.top`, fill tới đáy) |
71
- | Bảng hụt/tràn một khoảng cố định | `:height` cũ tính tay `"$( window ).height()-N"` không khớp toolbar thật | Thay bằng `":height": -16` |
72
- | Field trong form so le chiều cao | Trộn field có/không `dense`, có/không `hide-details` | Đồng bộ `outlined dense hide-details` cả form |
73
- | Số trong bảng căn trái | Cột thiếu `el: "t-num"` / align | Xem `component-table.md` |
74
- | Chart trắng | Container 0-height lúc chart init | Cho container `:height` cụ thể; renderUI audit "canvas 0-size" xác nhận |
75
- | Icon ô vuông | Sai tên `mdi-*` hoặc font chưa load | Kiểm tra tên icon; import materialdesignicons |
76
- | Dialog tràn màn hình / bé tẹo | width không thuộc bộ chuẩn | Bộ width 400/550/600/650/800 (D3) |
77
- | Nút chính lệch trái trong dialog | Thiếu `v-spacer` trong v-card-actions | Thêm v-spacer trước nút chính |
78
- | Khối dính mép màn hình | Thiếu page-container / pa-* | Xem `ui-layout-patterns.md` |
65
+ | Symptom | Common cause | Fix |
66
+ | ----------------------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
67
+ | Page has vertical scroll, endless table | f-table/f-sheet without `:height` → grows with row count | Add `":height": -16` (measures `rect.top`, fills to bottom) |
68
+ | Table short/overflowing by a fixed amount | Old hand-computed `:height` `"$( window ).height()-N"` doesn't match the real toolbar | Replace with `":height": -16` |
69
+ | Form fields of uneven height | Mixed with/without `dense`, `hide-details` | Use `outlined dense hide-details` across the form |
70
+ | Numbers left-aligned in table | Column missing `el: "t-num"` / align | See `component-table.md` |
71
+ | Blank chart | Container 0-height at chart init | Give the container a concrete `:height`; `--render` audit "canvas 0-size" confirms |
72
+ | Square icon | Wrong `mdi-*` name or font not loaded | Check icon name; import materialdesignicons |
73
+ | Dialog overflowing / tiny | Non-standard width | Widths 400/550/600/650/800 (D3) |
74
+ | Primary button left in dialog | Missing `v-spacer` in v-card-actions | Add v-spacer before the primary button |
75
+ | Block touching screen edge | Missing page-container / pa-* | See `ui-layout-patterns.md` |
79
76
 
80
77
  ---
81
78
 
82
- ## Meta viewport mặc định của FUI (ảnh hưởng UI)
79
+ ## FUI default meta viewport (affects UI)
83
80
 
84
- Trang FUI mặc định đã có sẵn trong `<head>` (KHÔNG lặp lại trong header.html):
81
+ FUI pages already include in `<head>` (do NOT repeat in header.html):
85
82
 
86
83
  ```html
87
- <meta charset="UTF-8"/>
88
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"/>
84
+ <meta charset="UTF-8" />
85
+ <meta
86
+ name="viewport"
87
+ content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"
88
+ />
89
89
  ```
90
90
 
91
- Hệ quả khi đánh giá/thiết kế:
92
- - `user-scalable=no, maximum-scale=1` — user **không pinch-zoom được** → font/nút phải đủ lớn ngay từ đầu trên mobile, không trông chờ zoom.
93
- - `width=device-width, initial-scale=1` — layout theo đúng CSS pixel của thiết bị; breakpoint Vuetify hoạt động chuẩn.
94
- - `viewport-fit=cover` — trang tràn vào vùng notch/home-indicator trên iOS → nội dung sát mép trên/dưới cần `env(safe-area-inset-*)` padding khi làm fullscreen/HTMLOnly.
91
+ Consequences:
92
+
93
+ - `user-scalable=no, maximum-scale=1` — **no pinch-zoom** → fonts/buttons must be large enough on mobile from the start.
94
+ - `width=device-width, initial-scale=1` — layout in true device CSS pixels; Vuetify breakpoints work normally.
95
+ - `viewport-fit=cover` — page extends into iOS notch/home-indicator → content at top/bottom edges needs `env(safe-area-inset-*)` padding for fullscreen/HTMLOnly.
@@ -1,14 +1,14 @@
1
1
  # FUI Table Cell Patterns — f-table & in-cell controls
2
2
 
3
- > File này sở hữu: **điều khiển trong ô `f-table` (`t-*`), `ctrl-update`, show-select, chip-group, chọn `t-button` vs `t-menu`**. Props bảng xem [component-table.md](component-table.md).
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
4
 
5
- Các pattern cho `f-table` và điều khiển ngay trong ô bảng (`t-check`, `t-button`, `t-select`, `t-menu`, `ctrl-update`, `show-select`, `v-chip-group`). Rút ra từ project **security-manager**.
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
6
 
7
- > Xem thêm: [ui-patterns.md](ui-patterns.md) (data/watch/toolbar), [ui-dialog-patterns.md](ui-dialog-patterns.md), [component-table.md](component-table.md).
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
8
 
9
9
  ---
10
10
 
11
- ## 1. f-table Cơ Bản với Fixed Header
11
+ ## 1. Basic f-table with fixed header
12
12
 
13
13
  ```json
14
14
  {
@@ -23,33 +23,33 @@ Các pattern cho `f-table` và điều khiển ngay trong ô bảng (`t-check`,
23
23
  ":item-class": "item => item.ChuaKichHoat>0 ? 'danger' : ''",
24
24
  ":headers": [
25
25
  { "align": "center", "text": "UserID", "value": "UserID" },
26
- { "text": "Username", "value": "UserName" },
27
- { "text": "Fullname", "value": "FullName" }
26
+ { "text": "Username", "value": "UserName" },
27
+ { "text": "Fullname", "value": "FullName" }
28
28
  ]
29
29
  },
30
30
  "w": 12
31
31
  }
32
32
  ```
33
33
 
34
- **Kỹ thuật:**
35
- - **QUY TẮC chiều cao bảng (lint D9)**: bảng data chính của module khai `":height": -16` — f-table tự **đo vị trí thật** của bảng sau khi layout (`getBoundingClientRect().top`) rồi fill tới đáy màn hình chừa 16px, và tự bật `fixed-header`. Cuộn data chỉ cuộn **trong bảng**, header không trôi, trang không có 2 thanh cuộn lồng nhau. Tự cập nhật khi resize cửa sổ và khi `items` đổi.
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.
36
35
 
37
- | `:height` | Hành vi |
38
- |---|---|
39
- | *(bỏ trống)* | Tự giãn theo số dòng — bảng ngắn/lookup chủ ý; bảng chính thì sai (cả trang sẽ cuộn) |
40
- | `<= 0` | Fill tới đáy, chừa `abs(height)` px — **chuẩn cho bảng chính** |
41
- | `> 0` | px cố định — **bảng trong dialog** (vd `":height": 360`) |
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`) |
42
41
 
43
- Cùng ba chế độ này áp cho `f-sheet` — xem [fsheet.md](fsheet.md) §Chiều cao.
42
+ Same three modes apply to `f-sheet` — see [fsheet.md](fsheet.md) §Height.
44
43
 
45
- ⚠ Pattern cũ `":height": "$( window ).height()-285"` **không dùng nữa** — nó bắt bạn tự đoán tổng chiều cao toolbar/filter/menu, sai là hụt hoặc tràn. Biểu thức trả số **dương** nên vẫn chạy như px cố định (không vỡ), nhưng mất khả năng tự đo; lint D9 cảnh báo để bạn thay bằng `-16`.
46
- - `:item-class`: highlight row theo điều kiện — `"item => item.Active==0 ? 'danger' : ''"`
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
47
 
48
48
  ---
49
49
 
50
- ## 2. t-check — Toggle trong Table Cell
50
+ ## 2. t-check — toggle in cell
51
51
 
52
- Dùng trong `headers` để render checkbox/icon toggle, kích hoạt API khi click.
52
+ In `headers`, renders a checkbox/icon toggle that fires an API on click.
53
53
 
54
54
  ```json
55
55
  {
@@ -71,9 +71,9 @@ Dùng trong `headers` để render checkbox/icon toggle, kích hoạt API khi cl
71
71
 
72
72
  ---
73
73
 
74
- ## 3. t-button — Button trong Table Cell
74
+ ## 3. t-button — button in cell
75
75
 
76
- Dùng khi cần button/icon với action trong cell. Hỗ trợ icon động.
76
+ Button/icon with an action in a cell; supports dynamic icons.
77
77
 
78
78
  ```json
79
79
  {
@@ -96,9 +96,9 @@ Dùng khi cần button/icon với action trong cell. Hỗ trợ icon động.
96
96
 
97
97
  ---
98
98
 
99
- ## 4. t-select — Dropdown Inline trong Table Cell
99
+ ## 4. t-select — inline dropdown in cell
100
100
 
101
- Dùng để edit field ngay trong bảng, trigger API khi chọn.
101
+ Edit a field in the table; fires an API on selection.
102
102
 
103
103
  ```json
104
104
  {
@@ -129,11 +129,11 @@ Dùng để edit field ngay trong bảng, trigger API khi chọn.
129
129
 
130
130
  ---
131
131
 
132
- ## 5. t-menu — Context Menu trong Table (menuChucNang Pattern)
132
+ ## 5. t-menu — context menu in table (menuChucNang)
133
133
 
134
- Định nghĩa menu items trong `data[]`, ref qua `t-menu` trong headers.
134
+ Define menu items in `data[]`, reference via `t-menu` in headers.
135
135
 
136
- **Bước 1 — Định nghĩa `menuChucNang` trong `data[]`:**
136
+ **Step 1 — `menuChucNang` in `data[]`:**
137
137
 
138
138
  ```json
139
139
  {
@@ -146,9 +146,9 @@ Dùng để edit field ngay trong bảng, trigger API khi chọn.
146
146
  {
147
147
  "addNew": 0,
148
148
  "dongChon": "item",
149
- "sUserID": "item.UserID",
150
- "sUserName": "item.UserName",
151
- "sLastName": "item.LastName",
149
+ "sUserID": "item.UserID",
150
+ "sUserName": "item.UserName",
151
+ "sLastName": "item.LastName",
152
152
  "sFirstName": "item.FirstName"
153
153
  },
154
154
  { "dlUserInfo": true }
@@ -160,16 +160,16 @@ Dùng để edit field ngay trong bảng, trigger API khi chọn.
160
160
  "text": "User Permission",
161
161
  "action": [
162
162
  {
163
- "dongChon": "item",
164
- "sUserID": "item.UserID",
165
- "sFullName": "item.FullName"
163
+ "dongChon": "item",
164
+ "sUserID": "item.UserID",
165
+ "sFullName": "item.FullName"
166
166
  },
167
167
  {
168
168
  "FUN": "openWindow",
169
169
  "IN": {
170
- "id": "`WinPer",
170
+ "id": "`WinPer",
171
171
  "title": "`User Permission",
172
- "url": "`/UserPermission"
172
+ "url": "`/UserPermission"
173
173
  }
174
174
  }
175
175
  ]
@@ -178,7 +178,7 @@ Dùng để edit field ngay trong bảng, trigger API khi chọn.
178
178
  }
179
179
  ```
180
180
 
181
- **Bước 2 — Dùng `t-menu` trong `headers`:**
181
+ **Step 2 — `t-menu` in `headers`:**
182
182
 
183
183
  ```json
184
184
  {
@@ -191,16 +191,15 @@ Dùng để edit field ngay trong bảng, trigger API khi chọn.
191
191
  }
192
192
  ```
193
193
 
194
- **Pattern xử lý:**
195
- - `"dongChon": "item"` — lưu bản ghi hiện tại vào `dongChon`
196
- - Các field khác `"sUserID": "item.UserID"` — copy field từ item vào state
197
- - `{ "dlXxx": true }` — mở dialog sau khi state đã sẵn sàng
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
198
197
 
199
198
  ---
200
199
 
201
- ## 6. ctrl-update CRUD Pattern
200
+ ## 6. ctrl-update CRUD
202
201
 
203
- CRUD trực tiếp trong bảng — không cần viết dialog thủ công.
202
+ CRUD directly in the table — no manual dialog.
204
203
 
205
204
  ```json
206
205
  {
@@ -209,17 +208,19 @@ CRUD trực tiếp trong bảng — không cần viết dialog thủ công.
209
208
  ":items": "dsFunctionRight",
210
209
  "item-key": "FunctionID",
211
210
  ":headers": [
212
- { "text": "Code", "value": "FunctionCode" },
213
- { "text": "Name", "value": "FunctionName" },
211
+ { "text": "Code", "value": "FunctionCode" },
212
+ { "text": "Name", "value": "FunctionName" },
214
213
  { "text": "Update", "value": "ctrl-update" }
215
214
  ],
216
215
  ":update-form": [
217
216
  {
218
- "el": "v-text-field", "w": 12,
217
+ "el": "v-text-field",
218
+ "w": 12,
219
219
  "attr": { "v-model": "FunctionCode", "label": "Function Code", ":required": true }
220
220
  },
221
221
  {
222
- "el": "v-text-field", "w": 12,
222
+ "el": "v-text-field",
223
+ "w": 12,
223
224
  "attr": { "v-model": "FunctionName", "label": "Function Name" }
224
225
  }
225
226
  ],
@@ -231,28 +232,29 @@ CRUD trực tiếp trong bảng — không cần viết dialog thủ công.
231
232
  },
232
233
  "edit": {
233
234
  "API": "/SM_Function_Update",
234
- "IN": { "FunctionID": "item.FunctionID", "FunctionCode": "item.FunctionCode", "FunctionName": "item.FunctionName" },
235
+ "IN": {
236
+ "FunctionID": "item.FunctionID",
237
+ "FunctionCode": "item.FunctionCode",
238
+ "FunctionName": "item.FunctionName"
239
+ },
235
240
  "CALLBACK": { "CALL": "getFunctionRight" }
236
241
  },
237
242
  "delete": {
238
243
  "CONFIRM": "Bạn có chắc muốn xóa quyền này không?",
239
244
  "API": "/SM_Function_Delete",
240
245
  "IN": { "FunctionID": "item.FunctionID" },
241
- "CALLBACK": [
242
- { "MESS": "Xóa thành công" },
243
- { "CALL": "getFunctionRight" }
244
- ]
246
+ "CALLBACK": [{ "MESS": "Xóa thành công" }, { "CALL": "getFunctionRight" }]
245
247
  }
246
248
  }
247
249
  }
248
250
  }
249
251
  ```
250
252
 
251
- **Khi nào dùng ctrl-update:** Khi form edit đơn giản (2-5 fields) và không cần layout phức tạp.
253
+ Use ctrl-update for simple edit forms (2–5 fields) with no complex layout.
252
254
 
253
255
  ---
254
256
 
255
- ## 7. f-table với show-select (Multi-select)
257
+ ## 7. f-table with show-select (multi-select)
256
258
 
257
259
  ```json
258
260
  {
@@ -270,14 +272,14 @@ CRUD trực tiếp trong bảng — không cần viết dialog thủ công.
270
272
  }
271
273
  ```
272
274
 
273
- - `v-model`: nhận array các item được chọn
274
- - `:update-api.default-item`: inject default field vào mỗi item khi load (ở đây `xAA: []` cho chip-group)
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)
275
277
 
276
278
  ---
277
279
 
278
- ## 8. v-chip-group trong Table Cell
280
+ ## 8. v-chip-group in cell
279
281
 
280
- Hiển thị danh sách tags trong cell, click để mở dialog.
282
+ Tag list in a cell; click opens a dialog.
281
283
 
282
284
  ```json
283
285
  {
@@ -308,9 +310,9 @@ Hiển thị danh sách tags trong cell, click để mở dialog.
308
310
 
309
311
  ---
310
312
 
311
- ## Khi nào dùng `t-button` vs `t-menu`
313
+ ## `t-button` vs `t-menu`
312
314
 
313
- - **`t-button`**: hành động duy nhất là xem/load dữ liệu liên quan → 1 click trực tiếp
314
- - **`t-menu`**: có nhiều hành động **hoặc** hành động thay đổi trạng thái (Kích hoạt, Chốt điểm, Xóa...)
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...)
315
317
 
316
- > Không bọc "Xem chi tiết" trong `t-menu` — thêm 1 click thừa. Dùng `t-button` thay. Xem thêm Master-Detail trong [ui-layout-patterns.md](ui-layout-patterns.md).
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,29 +1,22 @@
1
- # UI Templates — thư mục `examples/`
1
+ # UI Templates — `examples/`
2
2
 
3
- > File này sở hữu: **mô tả 4 file mẫu trong `examples/` và cách dùng lại chúng**. Quy tắc viết
4
- > `controls`/action xem [controls-patterns.md](controls-patterns.md); pattern f-table chi tiết xem
5
- > [component-table.md](component-table.md).
3
+ > Owns: **the 4 sample files in `examples/` and how to reuse them**. `controls`/action rules: [controls-patterns.md](controls-patterns.md); detailed f-table patterns: [component-table.md](component-table.md).
6
4
 
7
- `examples/` chứa **file tham chiếu thật** — không phải template rỗng để copy nguyên khối. Đọc để lấy
8
- đúng cú pháp/pattern cho tình huống đang làm, rồi viết lại theo nghiệp vụ thực tế.
5
+ `examples/` holds **real reference files**, not blank templates to copy whole. Read them for correct syntax/patterns, then rewrite for the actual business case.
9
6
 
10
- ## Các file có sẵn
7
+ ## Files
11
8
 
12
- | File | Dùng khi |
13
- |---|---|
14
- | `component.vue` | Custom Vue component mẫu (`uc-*`) — cấu trúc chuẩn `<template>` + `<script>`, không `name:`, không `components:{}`, không `<style>` |
15
- | `module-patterns.json` | **Tham chiếu module hoàn chỉnh** — data/watch/controls kết hợp: menuChucNang, TypeLoad, addNew flag dialog, nested IF/THEN/ELSE, bulk action, openWindow+button+ctrlhotkey, `_.find`, pushRouter, f-menu inline, row-prop-object |
16
- | `f-table-patterns.json` | **Tham chiếu f-table chuyên sâu** — tất cả props, mọi loại header (`t-check`/`t-select`/`t-button`/`t-link`/`t-menu`/`v-chip-group`/`v-icon`/divider), `ctrl-update` đầy đủ, f-table trong dialog, default-item-only |
17
- | `project-patterns.json` | **Tham chiếu `project.json`** — cấu trúc đầy đủ project config: menuLeft/menu/menuStyle/menuComponent/domainSetting, `right` theo SystemRight+FunctionRight, quan hệ với `set` của module.json (override title/menu/apiDomain theo từng trang) |
9
+ | File | Use when |
10
+ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
+ | `component.vue` | Sample custom Vue component (`uc-*`) — standard `<template>` + `<script>`, no `name:`, no `components:{}`, no `<style>` |
12
+ | `module-patterns.json` | **Full module reference** — data/watch/controls combined: menuChucNang, TypeLoad, addNew flag dialog, nested IF/THEN/ELSE, bulk action, openWindow+button+ctrlhotkey, `_.find`, pushRouter, inline f-menu, row-prop-object |
13
+ | `f-table-patterns.json` | **In-depth f-table reference** — all props, every header type (`t-check`/`t-select`/`t-button`/`t-link`/`t-menu`/`v-chip-group`/`v-icon`/divider), full `ctrl-update`, f-table in a dialog, default-item-only |
14
+ | `project-patterns.json` | **`project.json` reference** — full project config: menuLeft/menu/menuStyle/menuComponent/domainSetting, `right` by SystemRight+FunctionRight, relation to module.json `set` (per-page override of title/menu/apiDomain) |
18
15
 
19
- ## Cách dùng
16
+ ## How to use
20
17
 
21
- 1. Xác định tình huống → mở file tham chiếu tương ứng ở trên.
22
- 2. Lấy **đúng đoạn pattern cần dùng** (một action, một header, một khối dialog) — không copy cả file.
23
- 3. Thay API bằng endpoint thật, đổi tên field/label theo nghiệp vụ.
24
- 4. Ghép vào `data` / `controls` / `watch` sẵn có của module.
25
- 5. Chạy `module_validate` rồi `module_outline` trước khi publish.
26
-
27
- **Không có filesystem access (SSE/remote)?** Đọc file mẫu qua `skill_reference_get`, sửa nội dung,
28
- rồi stage bằng `module_stage_json` / `component_stage` trước khi gọi tool publish
29
- (xem [tools-registry.md](tools-registry.md)).
18
+ 1. Identify the case → open the matching file above.
19
+ 2. Take **only the pattern needed** (one action, one header, one dialog block) — never the whole file.
20
+ 3. Replace APIs with real endpoints; rename fields/labels for the business case.
21
+ 4. Merge into the module's existing `data` / `controls` / `watch`.
22
+ 5. Run `fui module validate` then `fui module outline` before publishing.