@vc-shell/create-vc-app 1.1.98-rc.5 → 1.1.99-alpha.1
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 +552 -26
- package/dist/cli/argv.d.ts +4 -0
- package/dist/cli/argv.d.ts.map +1 -0
- package/dist/cli/constants.d.ts +4 -0
- package/dist/cli/constants.d.ts.map +1 -0
- package/dist/cli/errors.d.ts +12 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/help.d.ts +3 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/run.d.ts +2 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/runtime.d.ts +7 -0
- package/dist/cli/runtime.d.ts.map +1 -0
- package/dist/cli/types.d.ts +30 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/utils.d.ts +4 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/validation.d.ts +5 -0
- package/dist/cli/validation.d.ts.map +1 -0
- package/dist/commands/generate-blade.d.ts +16 -0
- package/dist/commands/generate-blade.d.ts.map +1 -0
- package/dist/index.js +1900 -530
- package/dist/templates/base/_package.json +5 -5
- package/dist/templates/base/ai-guides/.cursorrules-vc-shell +529 -0
- package/dist/templates/base/ai-guides/README.md +360 -0
- package/dist/templates/base/ai-guides/guides/AI_GUIDE.md +195 -0
- package/dist/templates/base/ai-guides/guides/blade-patterns.md +384 -0
- package/dist/templates/base/ai-guides/guides/complete-workflow.md +781 -0
- package/dist/templates/base/ai-guides/guides/composables-reference.md +338 -0
- package/dist/templates/base/ai-guides/guides/troubleshooting.md +529 -0
- package/dist/templates/base/ai-guides/guides/ui-components-reference.md +903 -0
- package/dist/templates/base/ai-guides/prompts/adapt-existing-module.md +1026 -0
- package/dist/templates/base/ai-guides/prompts/advanced-scenarios.md +852 -0
- package/dist/templates/base/ai-guides/prompts/api-client-generation.md +877 -0
- package/dist/templates/base/ai-guides/prompts/cli-usage.md +640 -0
- package/dist/templates/base/ai-guides/prompts/quick-start-scenarios.md +773 -0
- package/dist/templates/base/ai-guides/prompts/simple-modifications.md +987 -0
- package/dist/templates/base/src/main.ts +0 -4
- package/dist/templates/blades/details/blade.vue +175 -0
- package/dist/templates/blades/grid/blade.vue +340 -0
- package/dist/templates/composables/details-composable.ts +101 -0
- package/dist/templates/composables/grid-composable.ts +244 -0
- package/dist/templates/module/components/index.ts +2 -0
- package/dist/templates/module/components/widgets/index.ts +2 -0
- package/dist/templates/module/composables/index.ts +3 -0
- package/dist/templates/module/index.ts +13 -0
- package/dist/templates/module/locales/en.json +65 -0
- package/dist/templates/module/locales/index.ts +4 -0
- package/dist/templates/module/pages/index.ts +3 -0
- package/dist/templates/widgets/widget.vue +113 -0
- package/dist/utils/form-builder.d.ts +69 -0
- package/dist/utils/form-builder.d.ts.map +1 -0
- package/dist/utils/format.d.ts +24 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/naming.d.ts +44 -0
- package/dist/utils/naming.d.ts.map +1 -0
- package/dist/utils/register-module.d.ts +21 -0
- package/dist/utils/register-module.d.ts.map +1 -0
- package/dist/workflows/create-app.d.ts +14 -0
- package/dist/workflows/create-app.d.ts.map +1 -0
- package/package.json +12 -7
- package/dist/templates/mocks/sample-data/constants.ts +0 -89
- package/dist/templates/mocks/sample-data/index.ts +0 -2
- package/dist/templates/mocks/sample-data/methods.ts +0 -65
- package/dist/templates/modules/classic-module/composables/index.ts +0 -2
- package/dist/templates/modules/classic-module/composables/use{{ModuleNamePascalCase}}Details/index.ts +0 -24
- package/dist/templates/modules/classic-module/composables/use{{ModuleNamePascalCase}}List/index.ts +0 -47
- package/dist/templates/modules/classic-module/index.ts +0 -8
- package/dist/templates/modules/classic-module/locales/en.json +0 -37
- package/dist/templates/modules/classic-module/locales/index.ts +0 -2
- package/dist/templates/modules/classic-module/pages/details.vue +0 -87
- package/dist/templates/modules/classic-module/pages/index.ts +0 -2
- package/dist/templates/modules/classic-module/pages/list.vue +0 -257
- package/dist/templates/sample/classic-module/composables/index.ts +0 -2
- package/dist/templates/sample/classic-module/composables/useDetails/index.ts +0 -54
- package/dist/templates/sample/classic-module/composables/useList/index.ts +0 -62
- package/dist/templates/sample/classic-module/index.ts +0 -8
- package/dist/templates/sample/classic-module/locales/en.json +0 -67
- package/dist/templates/sample/classic-module/locales/index.ts +0 -2
- package/dist/templates/sample/classic-module/pages/details.vue +0 -238
- package/dist/templates/sample/classic-module/pages/index.ts +0 -2
- package/dist/templates/sample/classic-module/pages/list.vue +0 -300
- package/dist/templates/sample/overrides/main.ts +0 -52
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"@types/node": "^20.10.5",
|
|
24
24
|
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
|
25
25
|
"@typescript-eslint/parser": "^7.4.0",
|
|
26
|
-
"@vc-shell/api-client-generator": "^1.1.
|
|
27
|
-
"@vc-shell/release-config": "^1.1.
|
|
28
|
-
"@vc-shell/ts-config": "^1.1.
|
|
26
|
+
"@vc-shell/api-client-generator": "^1.1.99-alpha.1",
|
|
27
|
+
"@vc-shell/release-config": "^1.1.99-alpha.1",
|
|
28
|
+
"@vc-shell/ts-config": "^1.1.99-alpha.1",
|
|
29
29
|
"@vitejs/plugin-vue": "^5.2.3",
|
|
30
30
|
"@vue/eslint-config-prettier": "^9.0.0",
|
|
31
31
|
"@vue/eslint-config-typescript": "^13.0.0",
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
"vue-tsc": "^2.2.10"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@vc-shell/config-generator": "^1.1.
|
|
57
|
-
"@vc-shell/framework": "^1.1.
|
|
56
|
+
"@vc-shell/config-generator": "^1.1.99-alpha.1",
|
|
57
|
+
"@vc-shell/framework": "^1.1.99-alpha.1",
|
|
58
58
|
"@vueuse/core": "^10.7.1",
|
|
59
59
|
"@vueuse/integrations": "^10.7.1",
|
|
60
60
|
"cross-spawn": "^7.0.3",
|
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
# VC-Shell Framework AI Guidance
|
|
2
|
+
|
|
3
|
+
You are an expert in the VC-Shell framework. This file contains complete framework knowledge to help you build applications efficiently.
|
|
4
|
+
|
|
5
|
+
## Framework Overview
|
|
6
|
+
|
|
7
|
+
VC-Shell is a Vue 3 + TypeScript framework for building enterprise applications with:
|
|
8
|
+
- Blade-based navigation system
|
|
9
|
+
- Modular architecture
|
|
10
|
+
- Built-in UI components
|
|
11
|
+
- API client generation
|
|
12
|
+
- Form validation with VeeValidate
|
|
13
|
+
- Internationalization support
|
|
14
|
+
|
|
15
|
+
## Blade System
|
|
16
|
+
|
|
17
|
+
### Core Concepts
|
|
18
|
+
- Blades are horizontal modal-like containers that stack
|
|
19
|
+
- Two main types: List blades (with tables) and Details blades (with forms)
|
|
20
|
+
- Navigation handled via useBladeNavigation composable
|
|
21
|
+
|
|
22
|
+
### Required Blade Props (4 total)
|
|
23
|
+
```typescript
|
|
24
|
+
interface BladeProps {
|
|
25
|
+
expanded?: boolean; // Expansion state
|
|
26
|
+
closable?: boolean; // Can be closed
|
|
27
|
+
param?: string; // Entity ID
|
|
28
|
+
options?: unknown; // Additional data
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Blade Events
|
|
33
|
+
- `parent:call` - Communication with parent blade
|
|
34
|
+
- `close:blade` - Close current blade
|
|
35
|
+
- `collapse:blade` - Collapse blade
|
|
36
|
+
- `expand:blade` - Expand blade
|
|
37
|
+
|
|
38
|
+
### Blade Toolbar
|
|
39
|
+
```typescript
|
|
40
|
+
interface IBladeToolbar {
|
|
41
|
+
id: string;
|
|
42
|
+
title: string;
|
|
43
|
+
icon?: string;
|
|
44
|
+
onClick: () => void;
|
|
45
|
+
disabled?: boolean;
|
|
46
|
+
loading?: boolean;
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Module Structure
|
|
51
|
+
|
|
52
|
+
Standard module layout:
|
|
53
|
+
```
|
|
54
|
+
src/modules/[name]/
|
|
55
|
+
├── pages/
|
|
56
|
+
│ ├── list.vue // List blade with VcTable
|
|
57
|
+
│ ├── details.vue // Details blade with VcForm
|
|
58
|
+
│ └── index.ts // Export pages
|
|
59
|
+
├── composables/
|
|
60
|
+
│ ├── use[Name]List/
|
|
61
|
+
│ │ └── index.ts // List logic with useAsync
|
|
62
|
+
│ ├── use[Name]Details/
|
|
63
|
+
│ │ └── index.ts // Details logic with useModificationTracker
|
|
64
|
+
│ └── index.ts // Export composables
|
|
65
|
+
├── locales/
|
|
66
|
+
│ ├── en.json // Translations
|
|
67
|
+
│ └── index.ts // Export locales
|
|
68
|
+
├── components/ // Optional module-specific components
|
|
69
|
+
└── index.ts // Module registration with createAppModule
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Core Composables
|
|
73
|
+
|
|
74
|
+
### useAsync
|
|
75
|
+
Handles async operations with loading states and error handling:
|
|
76
|
+
```typescript
|
|
77
|
+
const { action, loading, error } = useAsync(async () => {
|
|
78
|
+
return await apiCall();
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### useBladeNavigation
|
|
83
|
+
Manages blade navigation:
|
|
84
|
+
```typescript
|
|
85
|
+
const { openBlade, closeBlade } = useBladeNavigation();
|
|
86
|
+
|
|
87
|
+
// Open blade
|
|
88
|
+
openBlade({
|
|
89
|
+
blade: DetailsComponent,
|
|
90
|
+
param: id,
|
|
91
|
+
options: { data }
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Close current blade
|
|
95
|
+
closeBlade();
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### useModificationTracker
|
|
99
|
+
Tracks form changes for dirty state:
|
|
100
|
+
```typescript
|
|
101
|
+
const item = ref({ /* form data */ });
|
|
102
|
+
const { isModified, currentValue, pristineValue, resetModificationState } = useModificationTracker(item);
|
|
103
|
+
|
|
104
|
+
// Use currentValue for data operations
|
|
105
|
+
currentValue.value = await loadItem(id);
|
|
106
|
+
await saveItem(currentValue.value);
|
|
107
|
+
resetModificationState(); // After successful save
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### useApiClient
|
|
111
|
+
Provides API client with authentication:
|
|
112
|
+
```typescript
|
|
113
|
+
const { getApiClient } = useApiClient(GeneratedClient);
|
|
114
|
+
const client = getApiClient();
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### useMenuService
|
|
118
|
+
Registers menu items:
|
|
119
|
+
```typescript
|
|
120
|
+
useMenuService().addMenuItem({
|
|
121
|
+
id: 'my-module',
|
|
122
|
+
title: 'My Module',
|
|
123
|
+
url: '/my-module',
|
|
124
|
+
icon: 'my-icon',
|
|
125
|
+
priority: 100
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### usePermissions
|
|
130
|
+
Handles access control:
|
|
131
|
+
```typescript
|
|
132
|
+
const { checkPermission } = usePermissions();
|
|
133
|
+
const canEdit = checkPermission('my-module:edit');
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## API Integration
|
|
137
|
+
|
|
138
|
+
### Setup Process
|
|
139
|
+
1. Scaffolded apps already have `generate-api-client` script
|
|
140
|
+
2. Add to `.env.local`: `APP_PLATFORM_URL=https://platform-url/`
|
|
141
|
+
3. Run: `yarn generate-api-client`
|
|
142
|
+
4. Use: `const { getApiClient } = useApiClient(Client)`
|
|
143
|
+
|
|
144
|
+
### Module Integration
|
|
145
|
+
```typescript
|
|
146
|
+
// In src/main.ts
|
|
147
|
+
import MyModule from './modules/my-module';
|
|
148
|
+
app.use(MyModule, { router });
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Form Validation Pattern
|
|
152
|
+
|
|
153
|
+
Correct VeeValidate integration:
|
|
154
|
+
```vue
|
|
155
|
+
<Field name="fieldName" v-slot="{ errors, errorMessage, handleChange }" :rules="{ required: true }">
|
|
156
|
+
<VcInput
|
|
157
|
+
:model-value="data.fieldName"
|
|
158
|
+
:error-message="errorMessage"
|
|
159
|
+
:error="!!errors.length"
|
|
160
|
+
@update:model-value="(v) => { data.fieldName = v; handleChange(v); }"
|
|
161
|
+
/>
|
|
162
|
+
</Field>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## UI Components Reference
|
|
166
|
+
|
|
167
|
+
### ATOMS (20 components)
|
|
168
|
+
|
|
169
|
+
**VcBadge** - Notification badge
|
|
170
|
+
- Props: content, active, disabled, clickable, size (s|m), isDot, variant (primary|success|warning|danger|info|secondary), customPosition, top, right
|
|
171
|
+
- Emits: click
|
|
172
|
+
- Slots: default
|
|
173
|
+
|
|
174
|
+
**VcButton** - Action button
|
|
175
|
+
- Props: icon, iconClass, iconSize, variant (primary|secondary), disabled, size (xs|sm|base), selected, text
|
|
176
|
+
- Emits: click
|
|
177
|
+
- Slots: default
|
|
178
|
+
|
|
179
|
+
**VcCard** - Container card
|
|
180
|
+
- Props: header, icon, isCollapsable, isCollapsed, fill, variant (default|success|danger)
|
|
181
|
+
- Emits: header:click, state:collapsed
|
|
182
|
+
- Slots: default, actions, header
|
|
183
|
+
|
|
184
|
+
**VcCol** - Column layout
|
|
185
|
+
- Props: size (number)
|
|
186
|
+
- Slots: default
|
|
187
|
+
|
|
188
|
+
**VcContainer** - Scrollable container
|
|
189
|
+
- Props: shadow, noPadding, usePtr
|
|
190
|
+
- Emits: scroll:ptr, scroll
|
|
191
|
+
- Methods: scrollTop()
|
|
192
|
+
|
|
193
|
+
**VcHint** - Helper text
|
|
194
|
+
- Slots: default
|
|
195
|
+
|
|
196
|
+
**VcIcon** - Universal icon
|
|
197
|
+
- Props: icon, size (xs|s|m|l|xl|xxl|xxxl), variant (warning|danger|success), customSize, useContainer
|
|
198
|
+
- Supports: material-, bi-, lucide-, fas fa-, svg:
|
|
199
|
+
|
|
200
|
+
**VcImage** - Image display
|
|
201
|
+
- Props: src, alt, size, aspectRatio, bordered, rounded
|
|
202
|
+
|
|
203
|
+
**VcLabel** - Text label
|
|
204
|
+
- Props: text, required
|
|
205
|
+
- Slots: default
|
|
206
|
+
|
|
207
|
+
**VcLink** - Hyperlink
|
|
208
|
+
- Props: to, href, target
|
|
209
|
+
- Slots: default
|
|
210
|
+
|
|
211
|
+
**VcLoading** - Loading indicator
|
|
212
|
+
- Props: active
|
|
213
|
+
|
|
214
|
+
**VcProgress** - Progress bar
|
|
215
|
+
- Props: value (0-100), variant
|
|
216
|
+
|
|
217
|
+
**VcRow** - Row layout
|
|
218
|
+
- Slots: default
|
|
219
|
+
|
|
220
|
+
**VcSkeleton** - Loading skeleton
|
|
221
|
+
- Props: variant (text|circle|rect), width, height, count
|
|
222
|
+
|
|
223
|
+
**VcStatus** - Status indicator
|
|
224
|
+
- Props: variant, outline, extend
|
|
225
|
+
- Slots: default
|
|
226
|
+
|
|
227
|
+
**VcStatusIcon** - Status icon
|
|
228
|
+
- Props: variant
|
|
229
|
+
|
|
230
|
+
**VcTooltip** - Tooltip
|
|
231
|
+
- Props: text, placement, width, maxWidth
|
|
232
|
+
- Slots: default
|
|
233
|
+
|
|
234
|
+
**VcVideo** - Video player
|
|
235
|
+
- Props: src, poster, controls, autoplay, loop, muted
|
|
236
|
+
|
|
237
|
+
**VcWidget** - Dashboard widget
|
|
238
|
+
- Props: title, icon, value, loading
|
|
239
|
+
- Emits: click
|
|
240
|
+
|
|
241
|
+
**VcBanner** - Banner message
|
|
242
|
+
- Props: variant, icon, iconSize, iconVariant
|
|
243
|
+
- Slots: title, default, trigger
|
|
244
|
+
|
|
245
|
+
### MOLECULES (18 components)
|
|
246
|
+
|
|
247
|
+
**VcBreadcrumbs** - Navigation breadcrumbs
|
|
248
|
+
- Props: items (array of {id, title, icon?})
|
|
249
|
+
- Emits: item:click
|
|
250
|
+
|
|
251
|
+
**VcCheckbox** - Checkbox input
|
|
252
|
+
- Props: modelValue, label, disabled, errorMessage, hint
|
|
253
|
+
- Emits: update:modelValue
|
|
254
|
+
|
|
255
|
+
**VcEditor** - Rich text editor (TipTap)
|
|
256
|
+
- Props: modelValue, placeholder, editable, customToolbar
|
|
257
|
+
- Emits: update:modelValue
|
|
258
|
+
|
|
259
|
+
**VcField** - Form field wrapper
|
|
260
|
+
- Props: label, required, errorMessage, hint, tooltip
|
|
261
|
+
- Slots: default
|
|
262
|
+
|
|
263
|
+
**VcFileUpload** - File upload
|
|
264
|
+
- Props: accept, multiple, disabled, maxSize, errorMessage
|
|
265
|
+
- Emits: upload
|
|
266
|
+
|
|
267
|
+
**VcForm** - Form container (VeeValidate)
|
|
268
|
+
- Emits: submit
|
|
269
|
+
- Slots: default
|
|
270
|
+
|
|
271
|
+
**VcInput** - Text input
|
|
272
|
+
- Props: modelValue, label, placeholder, type, disabled, required, clearable, errorMessage, tooltip, maxlength, prefix, suffix
|
|
273
|
+
- Emits: update:modelValue, blur, focus, clear
|
|
274
|
+
|
|
275
|
+
**VcInputCurrency** - Currency input
|
|
276
|
+
- Props: modelValue, label, currency, locale, disabled, required, errorMessage
|
|
277
|
+
- Emits: update:modelValue
|
|
278
|
+
|
|
279
|
+
**VcInputDropdown** - Input with dropdown
|
|
280
|
+
- Props: modelValue, option, options, label, placeholder, disabled
|
|
281
|
+
- Emits: update:modelValue, update:option
|
|
282
|
+
|
|
283
|
+
**VcMultivalue** - Multi-value input
|
|
284
|
+
- Props: modelValue, placeholder, disabled, dictionary
|
|
285
|
+
- Emits: update:modelValue
|
|
286
|
+
|
|
287
|
+
**VcPagination** - Pagination
|
|
288
|
+
- Props: pages, currentPage, maxVisiblePages
|
|
289
|
+
- Emits: itemClick
|
|
290
|
+
|
|
291
|
+
**VcRadioButton** - Radio button
|
|
292
|
+
- Props: modelValue, value, label, name, disabled
|
|
293
|
+
- Emits: update:modelValue
|
|
294
|
+
|
|
295
|
+
**VcRating** - Star rating
|
|
296
|
+
- Props: modelValue, max, readonly, size
|
|
297
|
+
- Emits: update:modelValue
|
|
298
|
+
|
|
299
|
+
**VcSelect** - Dropdown select (async search)
|
|
300
|
+
- Props: modelValue, options, label, placeholder, multiple, searchable, clearable, disabled, loading, errorMessage, optionValue, optionLabel, searchMethod, tooltip
|
|
301
|
+
- Emits: update:modelValue, search, open, close
|
|
302
|
+
|
|
303
|
+
**VcSlider** - Range slider
|
|
304
|
+
- Props: modelValue, min, max, step, disabled
|
|
305
|
+
- Emits: update:modelValue
|
|
306
|
+
|
|
307
|
+
**VcSwitch** - Toggle switch
|
|
308
|
+
- Props: modelValue, label, disabled
|
|
309
|
+
- Emits: update:modelValue
|
|
310
|
+
|
|
311
|
+
**VcTextarea** - Multi-line text
|
|
312
|
+
- Props: modelValue, label, placeholder, rows, maxlength, disabled, required, errorMessage
|
|
313
|
+
- Emits: update:modelValue
|
|
314
|
+
|
|
315
|
+
**VcToast** - Toast notification
|
|
316
|
+
- Props: variant, text, timeout, closable
|
|
317
|
+
- Use via: notification() API
|
|
318
|
+
|
|
319
|
+
### ORGANISMS (7 components)
|
|
320
|
+
|
|
321
|
+
**VcApp** - Application shell
|
|
322
|
+
- Props: disableMenu, disableAppSwitcher, version, avatar, name, role, appsList, isEmbedded
|
|
323
|
+
- Emits: menuItemClick, switchApp
|
|
324
|
+
- Slots: navmenu, userDropdown, appSwitcher, toolbar, default
|
|
325
|
+
|
|
326
|
+
**VcBlade** - Blade container
|
|
327
|
+
- Props: title, toolbarItems (IBladeToolbar[]), expanded, closable, width, modified
|
|
328
|
+
- Emits: parent:call, close:blade, collapse:blade, expand:blade
|
|
329
|
+
- Slots: default, toolbar, actions
|
|
330
|
+
|
|
331
|
+
**VcDynamicProperty** - Dynamic properties
|
|
332
|
+
- Props: properties, modelValue, disabled
|
|
333
|
+
- Emits: update:modelValue
|
|
334
|
+
|
|
335
|
+
**VcGallery** - Image gallery
|
|
336
|
+
- Props: images, activeIndex
|
|
337
|
+
- Emits: update:activeIndex, close
|
|
338
|
+
|
|
339
|
+
**VcLoginForm** - Login form
|
|
340
|
+
- Props: logo, title
|
|
341
|
+
- Emits: submit
|
|
342
|
+
|
|
343
|
+
**VcPopup** - Modal popup
|
|
344
|
+
- Props: modelValue, title, variant, width, maxWidth, closable
|
|
345
|
+
- Emits: update:modelValue, close
|
|
346
|
+
- Slots: default, actions, title
|
|
347
|
+
|
|
348
|
+
**VcTable** - Data table
|
|
349
|
+
- Props: items, columns (ITableColumns[]), loading, selectedItemId, totalCount, pages, currentPage, enableItemActions, itemActionBuilder, multiselect, stateKey
|
|
350
|
+
- Emits: itemClick, selectionChanged, headerClick, pageChanged, reorder
|
|
351
|
+
- Slots: header, filters, mobile-item, item_[field], header_[field], notfound, empty, footer
|
|
352
|
+
- Columns: { id, title, field, type, sortable, width, alwaysVisible }
|
|
353
|
+
|
|
354
|
+
## Common Patterns
|
|
355
|
+
|
|
356
|
+
### List Blade Pattern
|
|
357
|
+
```vue
|
|
358
|
+
<template>
|
|
359
|
+
<VcBlade :expanded="true" :closable="true" :param="undefined" :options="undefined">
|
|
360
|
+
<VcTable
|
|
361
|
+
:items="items"
|
|
362
|
+
:columns="columns"
|
|
363
|
+
:loading="loading"
|
|
364
|
+
@item-click="handleItemClick"
|
|
365
|
+
/>
|
|
366
|
+
</VcBlade>
|
|
367
|
+
</template>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Details Blade Pattern
|
|
371
|
+
```vue
|
|
372
|
+
<template>
|
|
373
|
+
<VcBlade :expanded="true" :closable="true" :param="id" :options="undefined">
|
|
374
|
+
<VcForm @submit="handleSubmit">
|
|
375
|
+
<Field name="name" v-slot="{ errors, errorMessage, handleChange }" :rules="{ required: true }">
|
|
376
|
+
<VcInput
|
|
377
|
+
:model-value="data.name"
|
|
378
|
+
:error-message="errorMessage"
|
|
379
|
+
@update:model-value="(v) => { data.name = v; handleChange(v); }"
|
|
380
|
+
/>
|
|
381
|
+
</Field>
|
|
382
|
+
</VcForm>
|
|
383
|
+
</VcBlade>
|
|
384
|
+
</template>
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## CLI Commands Reference
|
|
388
|
+
|
|
389
|
+
### Application Creation
|
|
390
|
+
```bash
|
|
391
|
+
# Interactive mode
|
|
392
|
+
npx create-vc-app my-app
|
|
393
|
+
|
|
394
|
+
# Non-interactive mode
|
|
395
|
+
npx create-vc-app my-app --package-name "my-app" --base-path "/apps/my-app/" --skip-module-gen
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Module Generation
|
|
399
|
+
```bash
|
|
400
|
+
# Interactive mode
|
|
401
|
+
npx create-vc-app blade
|
|
402
|
+
|
|
403
|
+
# Generate module with grid blade
|
|
404
|
+
npx create-vc-app blade --module products --type grid --name products --is-workspace
|
|
405
|
+
|
|
406
|
+
# Generate details blade with form fields
|
|
407
|
+
npx create-vc-app blade --module products --type details --name product-details --form-fields '[...]'
|
|
408
|
+
|
|
409
|
+
# Generate widget
|
|
410
|
+
npx create-vc-app blade --widget
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Development Commands
|
|
414
|
+
- `yarn serve` - Start development server
|
|
415
|
+
- `yarn build` - Build for production
|
|
416
|
+
- `yarn generate-api-client` - Generate API client from OpenAPI
|
|
417
|
+
- `yarn lint` - Run ESLint
|
|
418
|
+
- `yarn type-check` - Run TypeScript checks
|
|
419
|
+
- `yarn test` - Run tests
|
|
420
|
+
|
|
421
|
+
## Common Development Patterns
|
|
422
|
+
|
|
423
|
+
### Pattern 1: Generate Module with CLI
|
|
424
|
+
```typescript
|
|
425
|
+
// When user says: "Create a products module"
|
|
426
|
+
// Use CLI in non-interactive mode:
|
|
427
|
+
npx create-vc-app blade --module products --type grid --name products --is-workspace
|
|
428
|
+
npx create-vc-app blade --module products --type details --name product-details
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Pattern 2: Connect to Custom API
|
|
432
|
+
```typescript
|
|
433
|
+
// Create API client
|
|
434
|
+
// src/api_client/custom-api.ts
|
|
435
|
+
const API_URL = import.meta.env.VITE_API_URL;
|
|
436
|
+
|
|
437
|
+
export const api = {
|
|
438
|
+
async getProducts(params) {
|
|
439
|
+
const response = await fetch(`${API_URL}/products`, {
|
|
440
|
+
headers: { 'Authorization': `Bearer ${token}` }
|
|
441
|
+
});
|
|
442
|
+
return response.json();
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
// Use in composable
|
|
447
|
+
import { api } from '../../../api_client/custom-api';
|
|
448
|
+
const { data } = await api.getProducts({ page, limit });
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Pattern 3: Dynamic Form Fields
|
|
452
|
+
```typescript
|
|
453
|
+
// Control field visibility with computed
|
|
454
|
+
const showAdvancedFields = computed(() => item.value.type === 'advanced');
|
|
455
|
+
|
|
456
|
+
// In template
|
|
457
|
+
<template v-if="showAdvancedFields">
|
|
458
|
+
<Field name="advancedOption">...</Field>
|
|
459
|
+
</template>
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### Pattern 4: Master-Detail Relationship
|
|
463
|
+
```typescript
|
|
464
|
+
// Order items array
|
|
465
|
+
const items = ref<OrderItem[]>([]);
|
|
466
|
+
|
|
467
|
+
// Calculated total
|
|
468
|
+
const total = computed(() =>
|
|
469
|
+
items.value.reduce((sum, item) => sum + item.quantity * item.price, 0)
|
|
470
|
+
);
|
|
471
|
+
|
|
472
|
+
// Add/remove items
|
|
473
|
+
const addItem = (product) => items.value.push({ ...product, quantity: 1 });
|
|
474
|
+
const removeItem = (index) => items.value.splice(index, 1);
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Pattern 5: File Upload
|
|
478
|
+
```typescript
|
|
479
|
+
const handleUpload = async (files: FileList) => {
|
|
480
|
+
for (const file of Array.from(files)) {
|
|
481
|
+
const formData = new FormData();
|
|
482
|
+
formData.append('file', file);
|
|
483
|
+
|
|
484
|
+
await api.upload(formData, {
|
|
485
|
+
onUploadProgress: (event) => {
|
|
486
|
+
progress.value = (event.loaded / event.total) * 100;
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
## Best Practices
|
|
494
|
+
|
|
495
|
+
1. **Use CLI for generation:** Always use `create-vc-app` CLI to generate modules
|
|
496
|
+
2. **4 Required Blade Props:** Always include expanded, closable, param, options
|
|
497
|
+
3. **VeeValidate for Forms:** Use Field component for validation
|
|
498
|
+
4. **useAsync for API:** Wrap API calls for loading states
|
|
499
|
+
5. **Modification Tracking:** Use useModificationTracker for dirty state
|
|
500
|
+
6. **Module Structure:** Follow standard module layout
|
|
501
|
+
7. **TypeScript:** Use proper interfaces and types
|
|
502
|
+
8. **Error Handling:** Try-catch with user-friendly messages
|
|
503
|
+
9. **Localization:** Use i18n for all text
|
|
504
|
+
10. **Naming:** Vc prefix for components, use prefix for composables
|
|
505
|
+
|
|
506
|
+
## Error Handling
|
|
507
|
+
|
|
508
|
+
```typescript
|
|
509
|
+
const { action: loadData, error } = useAsync(async () => {
|
|
510
|
+
try {
|
|
511
|
+
const response = await api.getData();
|
|
512
|
+
return response.data;
|
|
513
|
+
} catch (err) {
|
|
514
|
+
notification.error('Failed to load data', { timeout: 5000 });
|
|
515
|
+
console.error('API Error:', err);
|
|
516
|
+
throw err;
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
## Performance Tips
|
|
522
|
+
|
|
523
|
+
- Use `computed` for derived values
|
|
524
|
+
- Implement loading states with `useAsync`
|
|
525
|
+
- Lazy load routes: `component: () => import('./page.vue')`
|
|
526
|
+
- Use proper TypeScript types
|
|
527
|
+
- Debounce search inputs
|
|
528
|
+
- Paginate large datasets
|
|
529
|
+
|