@fui-org/fui-cli 0.1.1 → 0.3.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 +18 -3
- package/dist/fui.js +160 -43
- package/package.json +4 -2
- package/skills/fui/SKILL.md +131 -66
- package/skills/fui-skill/README.md +112 -0
- package/skills/fui-skill/SKILL.md +269 -0
- package/skills/fui-skill/assets/projectdefaultstyle.css +518 -0
- package/skills/fui-skill/design-md/airbnb/DESIGN.md +545 -0
- package/skills/fui-skill/design-md/airbnb/README.md +5 -0
- package/skills/fui-skill/design-md/airtable/DESIGN.md +554 -0
- package/skills/fui-skill/design-md/airtable/README.md +5 -0
- package/skills/fui-skill/design-md/apple/DESIGN.md +562 -0
- package/skills/fui-skill/design-md/apple/README.md +5 -0
- package/skills/fui-skill/design-md/asu/DESIGN.md +179 -0
- package/skills/fui-skill/design-md/asu/README.md +107 -0
- package/skills/fui-skill/design-md/binance/DESIGN.md +634 -0
- package/skills/fui-skill/design-md/binance/README.md +5 -0
- package/skills/fui-skill/design-md/bmw/DESIGN.md +544 -0
- package/skills/fui-skill/design-md/bmw/README.md +5 -0
- package/skills/fui-skill/design-md/bmw-m/DESIGN.md +503 -0
- package/skills/fui-skill/design-md/bmw-m/README.md +5 -0
- package/skills/fui-skill/design-md/bugatti/DESIGN.md +454 -0
- package/skills/fui-skill/design-md/bugatti/README.md +5 -0
- package/skills/fui-skill/design-md/cal/DESIGN.md +542 -0
- package/skills/fui-skill/design-md/cal/README.md +5 -0
- package/skills/fui-skill/design-md/claude/DESIGN.md +589 -0
- package/skills/fui-skill/design-md/claude/README.md +5 -0
- package/skills/fui-skill/design-md/clay/DESIGN.md +541 -0
- package/skills/fui-skill/design-md/clay/README.md +5 -0
- package/skills/fui-skill/design-md/clickhouse/DESIGN.md +544 -0
- package/skills/fui-skill/design-md/clickhouse/README.md +5 -0
- package/skills/fui-skill/design-md/cohere/DESIGN.md +451 -0
- package/skills/fui-skill/design-md/cohere/README.md +5 -0
- package/skills/fui-skill/design-md/coinbase/DESIGN.md +570 -0
- package/skills/fui-skill/design-md/coinbase/README.md +5 -0
- package/skills/fui-skill/design-md/composio/DESIGN.md +506 -0
- package/skills/fui-skill/design-md/composio/README.md +5 -0
- package/skills/fui-skill/design-md/cursor/DESIGN.md +537 -0
- package/skills/fui-skill/design-md/cursor/README.md +5 -0
- package/skills/fui-skill/design-md/elevenlabs/DESIGN.md +504 -0
- package/skills/fui-skill/design-md/elevenlabs/README.md +5 -0
- package/skills/fui-skill/design-md/expo/DESIGN.md +526 -0
- package/skills/fui-skill/design-md/expo/README.md +5 -0
- package/skills/fui-skill/design-md/ferrari/DESIGN.md +531 -0
- package/skills/fui-skill/design-md/ferrari/README.md +5 -0
- package/skills/fui-skill/design-md/figma/DESIGN.md +578 -0
- package/skills/fui-skill/design-md/figma/README.md +5 -0
- package/skills/fui-skill/design-md/framer/DESIGN.md +544 -0
- package/skills/fui-skill/design-md/framer/README.md +5 -0
- package/skills/fui-skill/design-md/fui/DESIGN.md +532 -0
- package/skills/fui-skill/design-md/hashicorp/DESIGN.md +575 -0
- package/skills/fui-skill/design-md/hashicorp/README.md +5 -0
- package/skills/fui-skill/design-md/ibm/DESIGN.md +550 -0
- package/skills/fui-skill/design-md/ibm/README.md +5 -0
- package/skills/fui-skill/design-md/intercom/DESIGN.md +546 -0
- package/skills/fui-skill/design-md/intercom/README.md +5 -0
- package/skills/fui-skill/design-md/kraken/DESIGN.md +125 -0
- package/skills/fui-skill/design-md/kraken/README.md +5 -0
- package/skills/fui-skill/design-md/lamborghini/DESIGN.md +288 -0
- package/skills/fui-skill/design-md/lamborghini/README.md +5 -0
- package/skills/fui-skill/design-md/linear.app/DESIGN.md +548 -0
- package/skills/fui-skill/design-md/linear.app/README.md +5 -0
- package/skills/fui-skill/design-md/lovable/DESIGN.md +298 -0
- package/skills/fui-skill/design-md/lovable/README.md +5 -0
- package/skills/fui-skill/design-md/mastercard/DESIGN.md +365 -0
- package/skills/fui-skill/design-md/mastercard/README.md +5 -0
- package/skills/fui-skill/design-md/meta/DESIGN.md +683 -0
- package/skills/fui-skill/design-md/meta/README.md +5 -0
- package/skills/fui-skill/design-md/minimax/DESIGN.md +746 -0
- package/skills/fui-skill/design-md/minimax/README.md +5 -0
- package/skills/fui-skill/design-md/mintlify/DESIGN.md +852 -0
- package/skills/fui-skill/design-md/mintlify/README.md +5 -0
- package/skills/fui-skill/design-md/miro/DESIGN.md +825 -0
- package/skills/fui-skill/design-md/miro/README.md +5 -0
- package/skills/fui-skill/design-md/mistral.ai/DESIGN.md +773 -0
- package/skills/fui-skill/design-md/mistral.ai/README.md +5 -0
- package/skills/fui-skill/design-md/mongodb/DESIGN.md +767 -0
- package/skills/fui-skill/design-md/mongodb/README.md +5 -0
- package/skills/fui-skill/design-md/nike/DESIGN.md +575 -0
- package/skills/fui-skill/design-md/nike/README.md +5 -0
- package/skills/fui-skill/design-md/notion/DESIGN.md +821 -0
- package/skills/fui-skill/design-md/notion/README.md +5 -0
- package/skills/fui-skill/design-md/nvidia/DESIGN.md +640 -0
- package/skills/fui-skill/design-md/nvidia/README.md +5 -0
- package/skills/fui-skill/design-md/ollama/DESIGN.md +539 -0
- package/skills/fui-skill/design-md/ollama/README.md +5 -0
- package/skills/fui-skill/design-md/opencode.ai/DESIGN.md +521 -0
- package/skills/fui-skill/design-md/opencode.ai/README.md +5 -0
- package/skills/fui-skill/design-md/pinterest/DESIGN.md +597 -0
- package/skills/fui-skill/design-md/pinterest/README.md +5 -0
- package/skills/fui-skill/design-md/playstation/DESIGN.md +661 -0
- package/skills/fui-skill/design-md/playstation/README.md +5 -0
- package/skills/fui-skill/design-md/posthog/DESIGN.md +690 -0
- package/skills/fui-skill/design-md/posthog/README.md +5 -0
- package/skills/fui-skill/design-md/raycast/DESIGN.md +669 -0
- package/skills/fui-skill/design-md/raycast/README.md +5 -0
- package/skills/fui-skill/design-md/renault/DESIGN.md +589 -0
- package/skills/fui-skill/design-md/renault/README.md +5 -0
- package/skills/fui-skill/design-md/replicate/DESIGN.md +616 -0
- package/skills/fui-skill/design-md/replicate/README.md +5 -0
- package/skills/fui-skill/design-md/resend/DESIGN.md +585 -0
- package/skills/fui-skill/design-md/resend/README.md +5 -0
- package/skills/fui-skill/design-md/revolut/DESIGN.md +636 -0
- package/skills/fui-skill/design-md/revolut/README.md +5 -0
- package/skills/fui-skill/design-md/runwayml/DESIGN.md +244 -0
- package/skills/fui-skill/design-md/runwayml/README.md +5 -0
- package/skills/fui-skill/design-md/sanity/DESIGN.md +357 -0
- package/skills/fui-skill/design-md/sanity/README.md +5 -0
- package/skills/fui-skill/design-md/sentry/DESIGN.md +551 -0
- package/skills/fui-skill/design-md/sentry/README.md +5 -0
- package/skills/fui-skill/design-md/shopify/DESIGN.md +516 -0
- package/skills/fui-skill/design-md/shopify/README.md +5 -0
- package/skills/fui-skill/design-md/slack/DESIGN.md +482 -0
- package/skills/fui-skill/design-md/spacex/DESIGN.md +363 -0
- package/skills/fui-skill/design-md/spacex/README.md +5 -0
- package/skills/fui-skill/design-md/spotify/DESIGN.md +246 -0
- package/skills/fui-skill/design-md/spotify/README.md +5 -0
- package/skills/fui-skill/design-md/starbucks/DESIGN.md +580 -0
- package/skills/fui-skill/design-md/starbucks/README.md +5 -0
- package/skills/fui-skill/design-md/stripe/DESIGN.md +487 -0
- package/skills/fui-skill/design-md/stripe/README.md +5 -0
- package/skills/fui-skill/design-md/supabase/DESIGN.md +462 -0
- package/skills/fui-skill/design-md/supabase/README.md +5 -0
- package/skills/fui-skill/design-md/superhuman/DESIGN.md +448 -0
- package/skills/fui-skill/design-md/superhuman/README.md +5 -0
- package/skills/fui-skill/design-md/tesla/DESIGN.md +286 -0
- package/skills/fui-skill/design-md/tesla/README.md +5 -0
- package/skills/fui-skill/design-md/theverge/DESIGN.md +339 -0
- package/skills/fui-skill/design-md/theverge/README.md +5 -0
- package/skills/fui-skill/design-md/together.ai/DESIGN.md +633 -0
- package/skills/fui-skill/design-md/together.ai/README.md +5 -0
- package/skills/fui-skill/design-md/uber/DESIGN.md +636 -0
- package/skills/fui-skill/design-md/uber/README.md +5 -0
- package/skills/fui-skill/design-md/vercel/DESIGN.md +736 -0
- package/skills/fui-skill/design-md/vercel/README.md +5 -0
- package/skills/fui-skill/design-md/vodafone/DESIGN.md +538 -0
- package/skills/fui-skill/design-md/vodafone/README.md +5 -0
- package/skills/fui-skill/design-md/voltagent/DESIGN.md +521 -0
- package/skills/fui-skill/design-md/voltagent/README.md +5 -0
- package/skills/fui-skill/design-md/warp/DESIGN.md +526 -0
- package/skills/fui-skill/design-md/warp/README.md +5 -0
- package/skills/fui-skill/design-md/webflow/DESIGN.md +588 -0
- package/skills/fui-skill/design-md/webflow/README.md +5 -0
- package/skills/fui-skill/design-md/wired/DESIGN.md +497 -0
- package/skills/fui-skill/design-md/wired/README.md +5 -0
- package/skills/fui-skill/design-md/wise/DESIGN.md +544 -0
- package/skills/fui-skill/design-md/wise/README.md +5 -0
- package/skills/fui-skill/design-md/x.ai/DESIGN.md +465 -0
- package/skills/fui-skill/design-md/x.ai/README.md +5 -0
- package/skills/fui-skill/design-md/zapier/DESIGN.md +537 -0
- package/skills/fui-skill/design-md/zapier/README.md +5 -0
- package/skills/fui-skill/examples/component.vue +162 -0
- package/skills/fui-skill/examples/f-table-patterns.json +331 -0
- package/skills/fui-skill/examples/module-patterns.json +973 -0
- package/skills/fui-skill/examples/project-patterns.json +222 -0
- package/skills/fui-skill/metadata.json +75 -0
- package/skills/fui-skill/references/INDEX.md +144 -0
- package/skills/fui-skill/references/advanced-techniques.md +160 -0
- package/skills/fui-skill/references/coding-standards.md +112 -0
- package/skills/fui-skill/references/component-design.md +455 -0
- package/skills/fui-skill/references/component-quickref.md +77 -0
- package/skills/fui-skill/references/component-table.md +276 -0
- package/skills/fui-skill/references/components-dialog.md +192 -0
- package/skills/fui-skill/references/components-display.md +147 -0
- package/skills/fui-skill/references/components-echart.md +391 -0
- package/skills/fui-skill/references/components-input.md +359 -0
- package/skills/fui-skill/references/controls-patterns.md +847 -0
- package/skills/fui-skill/references/controls-styling-vocabulary.md +140 -0
- package/skills/fui-skill/references/db-table-design.md +77 -0
- package/skills/fui-skill/references/db-workflow.md +504 -0
- package/skills/fui-skill/references/default-function.md +415 -0
- package/skills/fui-skill/references/design-modes.md +85 -0
- package/skills/fui-skill/references/echart-templates.md +481 -0
- package/skills/fui-skill/references/fastproject.md +97 -0
- package/skills/fui-skill/references/fsheet.md +218 -0
- package/skills/fui-skill/references/fullstack-workflow.md +351 -0
- package/skills/fui-skill/references/module-data-patterns.md +126 -0
- package/skills/fui-skill/references/module-json-anatomy.md +137 -0
- package/skills/fui-skill/references/module-structure.md +260 -0
- package/skills/fui-skill/references/new-session.md +108 -0
- package/skills/fui-skill/references/pdfmake.md +60 -0
- package/skills/fui-skill/references/permission-system.md +169 -0
- package/skills/fui-skill/references/platform-architecture.md +294 -0
- package/skills/fui-skill/references/project-config.md +335 -0
- package/skills/fui-skill/references/project-provisioning.md +383 -0
- package/skills/fui-skill/references/script-map.md +296 -0
- package/skills/fui-skill/references/sql-clr-functions.md +224 -0
- package/skills/fui-skill/references/system-design.md +116 -0
- package/skills/fui-skill/references/tapi-file-api.md +191 -0
- package/skills/fui-skill/references/tapi-permission-patterns.md +158 -0
- package/skills/fui-skill/references/tapi-reference.md +549 -0
- package/skills/fui-skill/references/tools-registry.md +460 -0
- package/skills/fui-skill/references/ui-crosswindow-patterns.md +317 -0
- package/skills/fui-skill/references/ui-dialog-patterns.md +229 -0
- package/skills/fui-skill/references/ui-layout-patterns.md +176 -0
- package/skills/fui-skill/references/ui-patterns.md +315 -0
- package/skills/fui-skill/references/ui-screenshot-review.md +94 -0
- package/skills/fui-skill/references/ui-table-cell-patterns.md +316 -0
- package/skills/fui-skill/references/ui-templates.md +29 -0
- package/skills/fui-skill/references/verification.md +246 -0
- package/skills/fui-skill/references/watcher-patterns.md +196 -0
- package/skills/fui-skill/references/websocket-realtime.md +254 -0
- package/skills/fui-skill/scripts/component-3.0.js +2549 -0
- package/skills/fui-skill/scripts/component.js +3142 -0
- package/skills/fui-skill/scripts/componentTable-3.0.js +909 -0
- package/skills/fui-skill/scripts/componentTable.js +769 -0
- package/skills/fui-skill/scripts/defaultfunction-3.0.js +781 -0
- package/skills/fui-skill/scripts/defaultfunction.js +966 -0
- package/skills/fui-skill/scripts/fastproject-3.0.js +870 -0
- package/skills/fui-skill/scripts/fastproject.js +828 -0
- package/skills/fui-skill/scripts/fechart.js +890 -0
- package/skills/fui-skill/scripts/fsheet.js +1330 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
# FUI Input & Interaction Components
|
|
2
|
+
|
|
3
|
+
> File này sở hữu: **component nhập liệu: `f-date`, `f-time`, `f-search`, `f-radiobox`, `f-button`, `f-menu`, upload**.
|
|
4
|
+
|
|
5
|
+
Components dùng để nhận input hoặc tương tác với người dùng. Xem prefix/binding rules tại [components-display.md](components-display.md).
|
|
6
|
+
|
|
7
|
+
## f-radiobox
|
|
8
|
+
|
|
9
|
+
- Props (source): `label`, `items`, `itemValue`, `itemText`
|
|
10
|
+
- Emit: `input` on change
|
|
11
|
+
- Example:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"el": "f-radiobox",
|
|
16
|
+
"w": "6",
|
|
17
|
+
"attr": {
|
|
18
|
+
"label": "Loai",
|
|
19
|
+
"v-model": "formData.loai",
|
|
20
|
+
":items": "loaiOptions",
|
|
21
|
+
"item-value": "value",
|
|
22
|
+
"item-text": "text"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## f-menu
|
|
28
|
+
|
|
29
|
+
- Props (source): `items`, `label`, `iconText`, `menuAttr`
|
|
30
|
+
- Behavior: dropdown button với danh sách menu items
|
|
31
|
+
- Nếu `label` rỗng hoặc undefined → hiển thị icon-only button
|
|
32
|
+
- `items` format: mảng `{ text, visible, color, "icon-text", action, href, target }`
|
|
33
|
+
- `action`: FUI action object — chạy qua `runAction`
|
|
34
|
+
- `href` + `target`: điều hướng như thẻ `<a>`
|
|
35
|
+
- `visible`: ẩn/hiện item (default `true`)
|
|
36
|
+
- Example:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"el": "f-menu",
|
|
41
|
+
"w": "3",
|
|
42
|
+
"attr": {
|
|
43
|
+
"label": "Tac vu",
|
|
44
|
+
"icon-text": "mdi-dots-vertical",
|
|
45
|
+
":items": [
|
|
46
|
+
{ "text": "Xem chi tiết", "icon-text": "mdi-eye", "action": { "CALL": "vueData.viewDetail" } },
|
|
47
|
+
{ "text": "Xuất Excel", "icon-text": "mdi-file-excel", "action": { "CALL": "vueData.exportExcel" } },
|
|
48
|
+
{ "text": "Trang chủ", "icon-text": "mdi-home", "href": "/", "target": "_blank" }
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## f-search
|
|
55
|
+
|
|
56
|
+
- Props (source): `api`, `apiData`, `items`
|
|
57
|
+
- Emit: `input` when selection changes
|
|
58
|
+
- Behavior: debounced API search (500ms), bỏ qua keyword < 2 ký tự
|
|
59
|
+
- Example:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"el": "f-search",
|
|
64
|
+
"w": "6",
|
|
65
|
+
"attr": {
|
|
66
|
+
"v-model": "filter.userID",
|
|
67
|
+
"api": "/api/user/search",
|
|
68
|
+
":api-data": { "Keyword": "TEXT", "GroupID": "vueData.groupID" },
|
|
69
|
+
"item-text": "UserName",
|
|
70
|
+
"item-value": "UserID"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## f-button
|
|
76
|
+
|
|
77
|
+
- Props (source): `label`, `checkvalid`, `ctrlhotkey`, `iconText`, `action`, `includeData`
|
|
78
|
+
- Behavior:
|
|
79
|
+
- debounced click (500ms, leading)
|
|
80
|
+
- validates form khi `checkvalid=true`
|
|
81
|
+
- nếu `$attrs.target == 'dialog'`, mở window theo attrs (`wid`, `title`, `url`, `onclose`)
|
|
82
|
+
- Example:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"el": "f-button",
|
|
87
|
+
"w": "3",
|
|
88
|
+
"attr": {
|
|
89
|
+
"label": "Luu",
|
|
90
|
+
"color": "primary",
|
|
91
|
+
":action": { "CALL": "handleSubmit" }
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## f-date
|
|
97
|
+
|
|
98
|
+
- Props (source): `value`, `label`, `dateAdd`, `required`
|
|
99
|
+
- Emit: `input` with normalized date (hoặc `null`)
|
|
100
|
+
- Behavior:
|
|
101
|
+
- hỗ trợ typed mask và picker
|
|
102
|
+
- chấp nhận nhiều định dạng input khi khởi tạo
|
|
103
|
+
- `dateAdd` tự set ngày tương đối so với hôm nay
|
|
104
|
+
- Example:
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"el": "f-date",
|
|
109
|
+
"w": "6",
|
|
110
|
+
"attr": {
|
|
111
|
+
"v-model": "filter.fromDate",
|
|
112
|
+
"label": "Tu ngay",
|
|
113
|
+
":required": false,
|
|
114
|
+
":date-add": -7
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## f-time
|
|
120
|
+
|
|
121
|
+
- Props (source): `value`, `label`, `timeAdd`, `required`
|
|
122
|
+
- Emit: `input` with `HH:mm` (hoặc `null`)
|
|
123
|
+
- Behavior: typed mask + time picker
|
|
124
|
+
- Example:
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"el": "f-time",
|
|
129
|
+
"w": "6",
|
|
130
|
+
"attr": {
|
|
131
|
+
"v-model": "formData.startTime",
|
|
132
|
+
"label": "Gio bat dau",
|
|
133
|
+
":required": false,
|
|
134
|
+
":time-add": 30
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## f-time-counter
|
|
140
|
+
|
|
141
|
+
- Props (source): `value`, `type`, `labelFormat`, `format`
|
|
142
|
+
- `value`: số giây (Number) hoặc datetime string (`"yyyy-MM-dd HH:mm:ss"`)
|
|
143
|
+
- `type`:
|
|
144
|
+
- `0` — đếm ngược, hiển thị ngày/giờ/phút/giây đầy đủ
|
|
145
|
+
- `1` — đếm ngược, chỉ hiển thị tổng số giây còn lại
|
|
146
|
+
- `2` — đồng hồ thời gian thực (hiển thị giờ hiện tại)
|
|
147
|
+
- `format`: `{ label, day, hour, minute, second }` — nhãn đơn vị
|
|
148
|
+
- Emit:
|
|
149
|
+
- `input` (số giây còn lại) khi đếm từ seconds (value là Number)
|
|
150
|
+
- `time-end` khi timer về 0
|
|
151
|
+
- Example:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"el": "f-time-counter",
|
|
156
|
+
"w": "4",
|
|
157
|
+
"attr": {
|
|
158
|
+
":value": 300,
|
|
159
|
+
":type": 0,
|
|
160
|
+
":format": { "label": "Còn lại: ", "day": " ngày", "hour": " giờ", "minute": " phút", "second": " giây" }
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## f-qrcode
|
|
166
|
+
|
|
167
|
+
- Props (source): `value`, `logo`, `color`, `size`
|
|
168
|
+
- Behavior: render QR image từ value
|
|
169
|
+
- Example:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"el": "f-qrcode",
|
|
174
|
+
"w": "4",
|
|
175
|
+
"attr": {
|
|
176
|
+
"v-model": "formData.qrText",
|
|
177
|
+
":size": 200,
|
|
178
|
+
"color": "#1e90ff"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## f-qrcode-reader
|
|
184
|
+
|
|
185
|
+
- Props (source): `value`, `label`, `width`
|
|
186
|
+
- Emit: `input` (đóng dialog), `update` (decoded content)
|
|
187
|
+
- Example:
|
|
188
|
+
|
|
189
|
+
```json
|
|
190
|
+
{
|
|
191
|
+
"el": "f-qrcode-reader",
|
|
192
|
+
"w": "12",
|
|
193
|
+
"attr": {
|
|
194
|
+
"v-model": "scanDialog",
|
|
195
|
+
"label": "Doc ma QR",
|
|
196
|
+
"v-on:update": "CALL(vueData.handleScanResult, { item: $event })"
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## f-image-update
|
|
202
|
+
|
|
203
|
+
- Props (source): `value`, `label`, `title`, `apiUpload`, `iconText`, `imageType`, `size`, `quality`, `dialogWidth`, `dialogHeight`, `imageBoxAttr`, `imageAttr`, `buttonAttr`, `croperAttr`
|
|
204
|
+
- Emit: `update` sau khi upload thành công (`{ returnData, imageData }`)
|
|
205
|
+
- Example:
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"el": "f-image-update",
|
|
210
|
+
"w": "4",
|
|
211
|
+
"attr": {
|
|
212
|
+
"v-model": "formData.avatar",
|
|
213
|
+
"label": "Anh dai dien",
|
|
214
|
+
"api-upload": "/api/upload/avatar",
|
|
215
|
+
":dialog-width": 600,
|
|
216
|
+
":dialog-height": 420
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## f-file-upload
|
|
222
|
+
|
|
223
|
+
- Props (source): `label`, `url`, `autoclose`, `iconText`, `filters`, `resize`, `onclose`
|
|
224
|
+
- Emit: `input` on upload complete
|
|
225
|
+
- Behavior:
|
|
226
|
+
- dùng Plupload
|
|
227
|
+
- tự upload khi chọn file
|
|
228
|
+
- chạy `onclose` action khi dialog đóng
|
|
229
|
+
- Example:
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"el": "f-file-upload",
|
|
234
|
+
"w": "4",
|
|
235
|
+
"attr": {
|
|
236
|
+
"label": "Tai tep",
|
|
237
|
+
"url": "/api/upload/file",
|
|
238
|
+
":filters": {
|
|
239
|
+
"max_file_size": "20mb",
|
|
240
|
+
"mime_types": [{ "title": "PDF", "extensions": "pdf" }]
|
|
241
|
+
},
|
|
242
|
+
":onclose": { "CALL": "handleUploadClosed" }
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## f-excel-reader
|
|
248
|
+
|
|
249
|
+
Nút upload đọc file Excel/CSV → đẩy dữ liệu đã parse vào `v-model` (mảng object, hoặc mảng lồng mảng tuỳ `:header`). Thư viện XLSX lazy-load khi người dùng chọn file lần đầu, **không cần khai import** trong module.json.
|
|
250
|
+
|
|
251
|
+
**Đầu ra:**
|
|
252
|
+
- `v-model` — mảng dữ liệu đã parse
|
|
253
|
+
- `load` — object metadata: `{ rows, rowCount, headers, sheetName, sheetNames, fileName }`
|
|
254
|
+
- `error` — `{ message, fileName }` khi file quá lớn, đọc thất bại, hoặc XLSX load timeout
|
|
255
|
+
- `action-error` — `{ message, fileName }` khi action callback ném lỗi (dữ liệu Excel vẫn hợp lệ)
|
|
256
|
+
|
|
257
|
+
**Props — Hiển thị:**
|
|
258
|
+
|
|
259
|
+
| Prop | Default | Mô tả |
|
|
260
|
+
|---|---|---|
|
|
261
|
+
| `label` | `'Load Excel'` | Nhãn nút |
|
|
262
|
+
| `icon-text` | `'mdi-grid'` | Icon Vuetify MDI; `null`/`''` để ẩn icon |
|
|
263
|
+
| `accept` | `.xlsx,.xlsb,.xlsm,.xls,.csv,.txt,.ods,.dbf,.prn,.html,.htm` | Loại file chấp nhận |
|
|
264
|
+
|
|
265
|
+
**Props — Đọc dữ liệu:**
|
|
266
|
+
|
|
267
|
+
| Prop | Default | Mô tả |
|
|
268
|
+
|---|---|---|
|
|
269
|
+
| `:header` | `null` | Quyết định key của mỗi object trong mảng kết quả (xem bảng bên dưới) |
|
|
270
|
+
| `:raw` | `false` | `false` = parse số và ngày; `true` = giữ nguyên raw string |
|
|
271
|
+
| `date-format` | `'dd/mm/yyyy'` | Format ngày khi `:raw="false"` |
|
|
272
|
+
| `:defval` | `''` | Giá trị thay thế cho ô trống |
|
|
273
|
+
| `:sheet` | `0` | Sheet cần đọc — số (index 0-based) hoặc tên sheet (string) |
|
|
274
|
+
| `:skip-rows` | `0` | Bỏ qua N dòng đầu trước khi đọc header/data |
|
|
275
|
+
|
|
276
|
+
**Giá trị của `:header`:**
|
|
277
|
+
|
|
278
|
+
| Giá trị | Kết quả |
|
|
279
|
+
|---|---|
|
|
280
|
+
| `null` _(mặc định)_ | Dùng dòng đầu tiên của sheet làm tên key: `[{MSSV:"1234", HoTen:"An"}]` |
|
|
281
|
+
| `1` | Trả mảng lồng mảng, không có key: `[["MSSV","HoTen"],["1234","An"]]` |
|
|
282
|
+
| `"A"` | Dùng chữ cái cột Excel làm key: `[{A:"MSSV", B:"HoTen"}]` |
|
|
283
|
+
| `["ma","ten"]` | Tự đặt tên key theo thứ tự cột (không dùng dòng header trong file) |
|
|
284
|
+
|
|
285
|
+
⚠️ **Bẫy `:sheet` — sai tên thì KHÔNG báo lỗi.** Hai kiểu giá trị hỏng khác hẳn nhau:
|
|
286
|
+
|
|
287
|
+
- `:sheet` là **tên** không tồn tại → **im lặng đọc sheet đầu tiên**. Vẫn ra dữ liệu, chỉ là dữ liệu của sheet khác — gõ sai tên sheet không có dấu hiệu nào.
|
|
288
|
+
- `:sheet` là **số** vượt quá số sheet → ném lỗi `Không tìm thấy sheet: N` qua event `error`.
|
|
289
|
+
|
|
290
|
+
Dùng tên sheet thì đối chiếu `sheetName` trong event `load` với tên mình mong đợi.
|
|
291
|
+
|
|
292
|
+
**Props — Giới hạn & timeout:**
|
|
293
|
+
|
|
294
|
+
| Prop | Default | Mô tả |
|
|
295
|
+
|---|---|---|
|
|
296
|
+
| `:max-size` | `20` | Giới hạn kích thước file, **đơn vị MB** (tên prop không mang chữ "MB"); `0` = bỏ giới hạn |
|
|
297
|
+
| `:load-timeout` | `15000` | Timeout nạp thư viện XLSX (ms) |
|
|
298
|
+
|
|
299
|
+
Giá trị `:max-size` không parse được thành số thì **quay về 20 MB**, không phải bỏ giới hạn — muốn bỏ giới hạn phải truyền đúng số `0`.
|
|
300
|
+
|
|
301
|
+
**Prop — Callback:**
|
|
302
|
+
|
|
303
|
+
| Prop | Mô tả |
|
|
304
|
+
|---|---|
|
|
305
|
+
| `:action` | Action object chạy sau khi parse xong và `v-model` đã nhận dữ liệu — thường dùng `{ "CALL": "tenAction" }` |
|
|
306
|
+
|
|
307
|
+
**Ranh giới lỗi — đọc Excel và chạy action là hai giai đoạn tách hẳn:**
|
|
308
|
+
|
|
309
|
+
- `action` chỉ chạy sau khi `v-model` đã nhận dữ liệu mới (qua `$nextTick`), nên trong action cứ đọc thẳng `vueData.excelRows`.
|
|
310
|
+
- Một khi Excel đã đọc xong, **không lỗi nào còn biến thành event `error` được nữa** — lỗi của action đi ra `action-error`, và dữ liệu đã parse vẫn nguyên vẹn, không rollback. Nghĩa là nhận được `error` ⇒ chắc chắn hỏng ở khâu đọc file; nhận được `action-error` ⇒ file đọc tốt, hỏng ở xử lý phía sau.
|
|
311
|
+
- Bấm nút lần nữa khi đang parse thì bị bỏ qua; nếu chọn file mới trước khi file cũ parse xong thì kết quả của lượt cũ bị vứt, không ghi đè lượt mới.
|
|
312
|
+
|
|
313
|
+
**Ví dụ cơ bản — header từ dòng đầu (mặc định):**
|
|
314
|
+
|
|
315
|
+
```json
|
|
316
|
+
{
|
|
317
|
+
"el": "f-excel-reader",
|
|
318
|
+
"w": "4",
|
|
319
|
+
"attr": {
|
|
320
|
+
"label": "Nhập từ Excel",
|
|
321
|
+
"icon-text": "mdi-microsoft-excel",
|
|
322
|
+
":action": { "CALL": "cmdImportExcel" },
|
|
323
|
+
"v-model": "excelRows"
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Ví dụ — đọc sheet theo tên, bỏ 2 dòng đầu, giữ raw string:**
|
|
329
|
+
|
|
330
|
+
```json
|
|
331
|
+
{
|
|
332
|
+
"el": "f-excel-reader",
|
|
333
|
+
"w": "4",
|
|
334
|
+
"attr": {
|
|
335
|
+
"label": "Nhập DanhSach",
|
|
336
|
+
":sheet": "DanhSach",
|
|
337
|
+
":skip-rows": 2,
|
|
338
|
+
":raw": true,
|
|
339
|
+
":action": { "CALL": "cmdImportExcel" },
|
|
340
|
+
"v-model": "excelRows"
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Ví dụ — tự đặt tên cột, giới hạn 5 MB:**
|
|
346
|
+
|
|
347
|
+
```json
|
|
348
|
+
{
|
|
349
|
+
"el": "f-excel-reader",
|
|
350
|
+
"w": "4",
|
|
351
|
+
"attr": {
|
|
352
|
+
"label": "Nhập Excel",
|
|
353
|
+
":header": ["mssv", "hoTen", "diemTB"],
|
|
354
|
+
":max-size": 5,
|
|
355
|
+
":action": { "CALL": "cmdImportExcel" },
|
|
356
|
+
"v-model": "excelRows"
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
```
|