@fui-org/fui-cli 2.1.4 → 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.
- package/README.md +27 -7
- package/dist/fui-qrb1j9jz.js +397 -0
- package/dist/fui.js +1 -1
- package/package.json +1 -1
- package/skills/fui/SKILL.md +143 -38
- package/skills/fui/agents/fui-builder.md +62 -0
- package/skills/fui/agents/fui-tester.md +77 -0
- package/skills/{fui-skill → fui}/assets/projectdefaultstyle.css +489 -489
- package/skills/{fui-skill → fui}/examples/component.vue +162 -162
- package/skills/{fui-skill → fui}/references/INDEX.md +5 -4
- package/skills/{fui-skill → fui}/references/advanced-techniques.md +170 -168
- package/skills/{fui-skill → fui}/references/component-design.md +2 -2
- package/skills/{fui-skill → fui}/references/component-quickref.md +78 -78
- package/skills/{fui-skill → fui}/references/component-table.md +287 -287
- package/skills/{fui-skill → fui}/references/components-dialog.md +191 -191
- package/skills/{fui-skill → fui}/references/components-display.md +141 -141
- package/skills/{fui-skill → fui}/references/components-echart.md +316 -316
- package/skills/{fui-skill → fui}/references/components-input.md +335 -335
- package/skills/{fui-skill → fui}/references/controls-patterns.md +2 -2
- package/skills/{fui-skill → fui}/references/controls-styling-vocabulary.md +173 -173
- package/skills/{fui-skill → fui}/references/db-workflow.md +9 -9
- package/skills/{fui-skill → fui}/references/default-function.md +456 -456
- package/skills/{fui-skill → fui}/references/design-modes.md +57 -57
- package/skills/{fui-skill → fui}/references/echart-templates.md +489 -489
- package/skills/{fui-skill → fui}/references/fastproject.md +99 -99
- package/skills/{fui-skill → fui}/references/fullstack-workflow.md +314 -313
- package/skills/{fui-skill → fui}/references/module-data-patterns.md +117 -117
- package/skills/{fui-skill → fui}/references/module-json-anatomy.md +132 -132
- package/skills/{fui-skill → fui}/references/module-structure.md +144 -144
- package/skills/{fui-skill → fui}/references/new-session.md +1 -2
- package/skills/{fui-skill → fui}/references/pdfmake.md +60 -60
- package/skills/{fui-skill → fui}/references/permission-system.md +1 -1
- package/skills/{fui-skill → fui}/references/platform-architecture.md +269 -269
- package/skills/{fui-skill → fui}/references/project-config.md +303 -303
- package/skills/{fui-skill → fui}/references/project-provisioning.md +4 -4
- package/skills/{fui-skill → fui}/references/script-map.md +262 -262
- package/skills/{fui-skill → fui}/references/sql-clr-functions.md +225 -225
- package/skills/{fui-skill → fui}/references/system-design.md +2 -2
- package/skills/{fui-skill → fui}/references/tapi-permission-patterns.md +156 -156
- package/skills/{fui-skill → fui}/references/tapi-reference.md +474 -474
- package/skills/fui/references/team-run.md +141 -0
- package/skills/fui/references/tools-registry.md +211 -0
- package/skills/{fui-skill → fui}/references/ui-crosswindow-patterns.md +321 -321
- package/skills/{fui-skill → fui}/references/ui-dialog-patterns.md +255 -255
- package/skills/{fui-skill → fui}/references/ui-layout-patterns.md +176 -176
- package/skills/{fui-skill → fui}/references/ui-patterns.md +303 -303
- package/skills/{fui-skill → fui}/references/ui-screenshot-review.md +95 -95
- package/skills/{fui-skill → fui}/references/ui-table-cell-patterns.md +318 -318
- package/skills/{fui-skill → fui}/references/verification.md +11 -11
- package/skills/{fui-skill → fui}/references/watcher-patterns.md +163 -163
- package/skills/{fui-skill → fui}/references/websocket-realtime.md +271 -271
- package/skills/{fui-skill → fui}/scripts/component-3.0.js +2715 -2715
- package/skills/{fui-skill → fui}/scripts/component.js +3147 -3147
- package/skills/{fui-skill → fui}/scripts/componentTable-3.0.js +1038 -1038
- package/skills/{fui-skill → fui}/scripts/componentTable.js +891 -891
- package/skills/{fui-skill → fui}/scripts/defaultfunction-3.0.js +866 -866
- package/skills/{fui-skill → fui}/scripts/defaultfunction.js +1051 -1051
- package/skills/{fui-skill → fui}/scripts/fastproject-3.0.js +870 -870
- package/skills/{fui-skill → fui}/scripts/fastproject.js +828 -828
- package/dist/fui-h4z7zhk2.js +0 -381
- package/skills/fui-skill/SKILL.md +0 -139
- package/skills/fui-skill/references/tools-registry.md +0 -84
- /package/skills/{fui-skill → fui}/assets/projectdefaultstyle-3.0.css +0 -0
- /package/skills/{fui-skill → fui}/design-md/airbnb/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airbnb/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airtable/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airtable/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/apple/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/apple/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/asu/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/asu/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/binance/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/binance/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw-m/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw-m/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bugatti/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bugatti/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cal/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cal/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/claude/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/claude/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clay/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clay/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clickhouse/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clickhouse/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cohere/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cohere/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/coinbase/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/coinbase/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/composio/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/composio/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cursor/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cursor/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/elevenlabs/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/elevenlabs/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/expo/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/expo/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ferrari/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ferrari/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/figma/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/figma/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/framer/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/framer/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/fui/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/hashicorp/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/hashicorp/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ibm/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ibm/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/intercom/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/intercom/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/kraken/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/kraken/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lamborghini/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lamborghini/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/linear.app/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/linear.app/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lovable/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lovable/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mastercard/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mastercard/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/meta/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/meta/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/minimax/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/minimax/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mintlify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mintlify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/miro/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/miro/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mistral.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mistral.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mongodb/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mongodb/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nike/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nike/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/notion/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/notion/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nvidia/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nvidia/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ollama/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ollama/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/opencode.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/opencode.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/pinterest/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/pinterest/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/playstation/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/playstation/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/posthog/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/posthog/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/raycast/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/raycast/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/renault/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/renault/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/replicate/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/replicate/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/resend/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/resend/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/revolut/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/revolut/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/runwayml/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/runwayml/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sanity/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sanity/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sentry/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sentry/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/shopify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/shopify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/slack/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spacex/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spacex/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spotify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spotify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/starbucks/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/starbucks/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/stripe/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/stripe/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/supabase/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/supabase/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/superhuman/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/superhuman/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/tesla/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/tesla/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/theverge/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/theverge/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/together.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/together.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/uber/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/uber/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vercel/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vercel/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vodafone/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vodafone/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/voltagent/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/voltagent/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/warp/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/warp/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/webflow/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/webflow/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wired/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wired/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wise/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wise/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/x.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/x.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/zapier/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/zapier/README.md +0 -0
- /package/skills/{fui-skill → fui}/examples/f-table-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/examples/module-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/examples/project-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/references/coding-standards.md +0 -0
- /package/skills/{fui-skill → fui}/references/db-table-design.md +0 -0
- /package/skills/{fui-skill → fui}/references/fsheet.md +0 -0
- /package/skills/{fui-skill → fui}/references/tapi-file-api.md +0 -0
- /package/skills/{fui-skill → fui}/references/ui-templates.md +0 -0
- /package/skills/{fui-skill → fui}/scripts/fechart.js +0 -0
- /package/skills/{fui-skill → fui}/scripts/fsheet.js +0 -0
|
@@ -1,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).
|