@ditojs/admin 2.3.1 → 2.4.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/dist/dito-admin.es.js +2098 -1961
- package/dist/dito-admin.umd.js +4 -4
- package/dist/style.css +1 -1
- package/package.json +5 -5
- package/src/components/DitoContainer.vue +7 -1
- package/src/components/DitoDialog.vue +1 -0
- package/src/components/DitoHeader.vue +6 -5
- package/src/components/DitoMenu.vue +177 -0
- package/src/components/DitoRoot.vue +112 -5
- package/src/components/DitoSchema.vue +7 -6
- package/src/components/DitoSidebar.vue +11 -49
- package/src/components/DitoTableHead.vue +1 -0
- package/src/components/index.js +1 -0
- package/src/mixins/TypeMixin.js +9 -11
- package/src/styles/_button.scss +4 -4
- package/src/styles/_scroll.scss +0 -1
- package/src/styles/_settings.scss +20 -10
- package/src/types/DitoTypeButton.vue +0 -1
- package/src/types/DitoTypeCheckbox.vue +0 -1
- package/src/types/DitoTypeComputed.vue +0 -1
- package/src/types/DitoTypeMarkup.vue +1 -1
- package/src/types/DitoTypeNumber.vue +0 -1
- package/src/types/DitoTypeProgress.vue +0 -1
- package/src/types/DitoTypeSwitch.vue +0 -1
- package/src/types/DitoTypeText.vue +0 -1
- package/src/types/DitoTypeTextarea.vue +0 -1
- package/src/types/DitoTypeUpload.vue +21 -12
- package/src/utils/schema.js +42 -16
|
@@ -43,21 +43,31 @@ $content-color-background: $color-lightest;
|
|
|
43
43
|
$form-spacing: $input-padding-hor;
|
|
44
44
|
$form-spacing-half: calc($form-spacing / 2);
|
|
45
45
|
|
|
46
|
-
//
|
|
47
|
-
$
|
|
48
|
-
$
|
|
49
|
-
$
|
|
50
|
-
$
|
|
51
|
-
$
|
|
52
|
-
$
|
|
53
|
-
$
|
|
46
|
+
// Header
|
|
47
|
+
$header-font-size: 14px;
|
|
48
|
+
$header-line-height: 1;
|
|
49
|
+
$header-z-index: 1000;
|
|
50
|
+
$header-padding-ver: $header-font-size;
|
|
51
|
+
$header-padding-hor: $content-padding;
|
|
52
|
+
$header-padding: $header-padding-ver $header-padding-hor;
|
|
53
|
+
$header-height: $header-font-size + 2 * $header-padding-ver;
|
|
54
54
|
|
|
55
55
|
// Tabs
|
|
56
56
|
$tab-margin: 6px;
|
|
57
57
|
$tab-padding-hor: 12px;
|
|
58
|
-
$tab-padding-ver: calc(($
|
|
58
|
+
$tab-padding-ver: calc(($header-padding-ver * 2 - $tab-margin) / 2);
|
|
59
59
|
$tab-radius: 4px;
|
|
60
|
-
|
|
60
|
+
|
|
61
|
+
// Menu
|
|
62
|
+
$menu-font-size: $header-font-size;
|
|
63
|
+
$menu-line-height: $header-line-height;
|
|
64
|
+
$menu-spacing: 4px;
|
|
65
|
+
$menu-padding-ver: $header-padding-ver - $menu-spacing;
|
|
66
|
+
$menu-padding-hor: $header-padding-hor - $menu-spacing;
|
|
67
|
+
$menu-padding: $menu-padding-ver $menu-padding-hor;
|
|
68
|
+
|
|
69
|
+
// Drag & Drop
|
|
70
|
+
$drag-overlay-z-index: 2000;
|
|
61
71
|
|
|
62
72
|
// Patterns
|
|
63
73
|
$pattern-transparency-size: ($font-size - $border-width) * $input-height-factor;
|
|
@@ -73,13 +73,8 @@
|
|
|
73
73
|
v-if="isUploadActive"
|
|
74
74
|
type="button"
|
|
75
75
|
@click.prevent="upload.active = false"
|
|
76
|
-
) Cancel
|
|
77
|
-
|
|
78
|
-
v-else-if="isUploadReady"
|
|
79
|
-
type="button"
|
|
80
|
-
@click.prevent="upload.active = true"
|
|
81
|
-
) Upload All
|
|
82
|
-
VueUpload.dito-button.dito-button-add-upload(
|
|
76
|
+
) Cancel
|
|
77
|
+
VueUpload.dito-button(
|
|
83
78
|
ref="upload"
|
|
84
79
|
v-model="uploads"
|
|
85
80
|
:inputId="dataPath"
|
|
@@ -90,10 +85,13 @@
|
|
|
90
85
|
:accept="accept"
|
|
91
86
|
:multiple="multiple"
|
|
92
87
|
:size="maxSize"
|
|
93
|
-
title="Upload Files"
|
|
88
|
+
:title="multiple ? 'Upload Files' : 'Upload File'"
|
|
89
|
+
:drop="$el?.closest('.dito-container')"
|
|
90
|
+
:dropDirectory="true"
|
|
94
91
|
@input-filter="inputFilter"
|
|
95
92
|
@input-file="inputFile"
|
|
96
93
|
)
|
|
94
|
+
.dito-button-upload
|
|
97
95
|
</template>
|
|
98
96
|
|
|
99
97
|
<script>
|
|
@@ -169,7 +167,7 @@ export default DitoTypeComponent.register('upload', {
|
|
|
169
167
|
|
|
170
168
|
isUploadReady() {
|
|
171
169
|
return (
|
|
172
|
-
this.uploads.length &&
|
|
170
|
+
this.uploads.length > 0 &&
|
|
173
171
|
!(this.upload.active || this.upload.uploaded)
|
|
174
172
|
)
|
|
175
173
|
},
|
|
@@ -180,7 +178,7 @@ export default DitoTypeComponent.register('upload', {
|
|
|
180
178
|
|
|
181
179
|
uploadProgress() {
|
|
182
180
|
return (
|
|
183
|
-
this.uploads.reduce((total, file) =>
|
|
181
|
+
this.uploads.reduce((total, file) => +file.progress + total, 0) /
|
|
184
182
|
this.uploads.length
|
|
185
183
|
)
|
|
186
184
|
},
|
|
@@ -193,6 +191,17 @@ export default DitoTypeComponent.register('upload', {
|
|
|
193
191
|
}
|
|
194
192
|
},
|
|
195
193
|
|
|
194
|
+
watch: {
|
|
195
|
+
isUploadReady(ready) {
|
|
196
|
+
if (ready) {
|
|
197
|
+
// Auto-upload.
|
|
198
|
+
this.$nextTick(() => {
|
|
199
|
+
this.upload.active = true
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
|
|
196
205
|
methods: {
|
|
197
206
|
formatFileSize,
|
|
198
207
|
|
|
@@ -293,6 +302,7 @@ export default DitoTypeComponent.register('upload', {
|
|
|
293
302
|
this.removeFile(newFile)
|
|
294
303
|
}
|
|
295
304
|
} else if (error) {
|
|
305
|
+
this.removeFile(newFile)
|
|
296
306
|
const text = (
|
|
297
307
|
{
|
|
298
308
|
abort: 'Upload aborted',
|
|
@@ -310,7 +320,6 @@ export default DitoTypeComponent.register('upload', {
|
|
|
310
320
|
title: 'File Upload Error',
|
|
311
321
|
text
|
|
312
322
|
})
|
|
313
|
-
this.removeFile(newFile)
|
|
314
323
|
}
|
|
315
324
|
}
|
|
316
325
|
},
|
|
@@ -347,7 +356,7 @@ function asFiles(value) {
|
|
|
347
356
|
}
|
|
348
357
|
}
|
|
349
358
|
|
|
350
|
-
.dito-button-
|
|
359
|
+
.dito-button-upload {
|
|
351
360
|
padding: 0;
|
|
352
361
|
|
|
353
362
|
> * {
|
package/src/utils/schema.js
CHANGED
|
@@ -113,6 +113,10 @@ export function isPanel(schema) {
|
|
|
113
113
|
return isSchema(schema) && schema.type === 'panel'
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
export function isMenu(schema) {
|
|
117
|
+
return isSchema(schema) && schema.type === 'menu'
|
|
118
|
+
}
|
|
119
|
+
|
|
116
120
|
export function getSchemaIdentifier(schema) {
|
|
117
121
|
return JSON.stringify(schema)
|
|
118
122
|
}
|
|
@@ -176,6 +180,19 @@ export async function resolveSchemas(
|
|
|
176
180
|
return schemas
|
|
177
181
|
}
|
|
178
182
|
|
|
183
|
+
export async function resolveViews(unresolvedViews) {
|
|
184
|
+
return resolveSchemas(unresolvedViews, async (schema, unwrapModule) => {
|
|
185
|
+
schema = await resolveSchema(schema, unwrapModule)
|
|
186
|
+
if (!schema.name && isMenu(schema)) {
|
|
187
|
+
// Generate a name for sub-menus from their label if it's missing.
|
|
188
|
+
// NOTE: This is never actually referenced from anywhere, but they need
|
|
189
|
+
// a name by which they're stored in the parent object.
|
|
190
|
+
schema.name = camelize(schema.label)
|
|
191
|
+
}
|
|
192
|
+
return schema
|
|
193
|
+
})
|
|
194
|
+
}
|
|
195
|
+
|
|
179
196
|
export async function resolveSchemaComponent(schema) {
|
|
180
197
|
// Resolves async schema components and adds DitoMixin and TypeMixin to them.
|
|
181
198
|
let { component } = schema
|
|
@@ -250,22 +267,31 @@ export async function processSchemaComponent(
|
|
|
250
267
|
}
|
|
251
268
|
|
|
252
269
|
export async function processView(component, api, schema, name) {
|
|
253
|
-
if (!isView(schema)) {
|
|
254
|
-
throw new Error(`Invalid view schema: '${getSchemaIdentifier(schema)}'`)
|
|
255
|
-
}
|
|
256
|
-
processRouteSchema(api, schema, name)
|
|
257
270
|
processSchemaDefaults(api, schema)
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
271
|
+
if (isView(schema)) {
|
|
272
|
+
processRouteSchema(api, schema, name)
|
|
273
|
+
await processNestedSchemas(api, schema)
|
|
274
|
+
const children = []
|
|
275
|
+
await processSchemaComponents(api, schema, children, 0)
|
|
276
|
+
return {
|
|
277
|
+
path: `/${schema.path}`,
|
|
278
|
+
children,
|
|
279
|
+
component,
|
|
280
|
+
meta: {
|
|
281
|
+
api,
|
|
282
|
+
schema
|
|
283
|
+
}
|
|
268
284
|
}
|
|
285
|
+
} else if (isMenu(schema)) {
|
|
286
|
+
schema.items = await resolveSchemas(schema.items)
|
|
287
|
+
return Promise.all(
|
|
288
|
+
Object.entries(schema.items).map(async ([name, item]) =>
|
|
289
|
+
processView(component, api, item, name)
|
|
290
|
+
)
|
|
291
|
+
)
|
|
292
|
+
//
|
|
293
|
+
} else {
|
|
294
|
+
throw new Error(`Invalid view schema: '${getSchemaIdentifier(schema)}'`)
|
|
269
295
|
}
|
|
270
296
|
}
|
|
271
297
|
|
|
@@ -303,8 +329,8 @@ export function processNestedSchemaDefaults(api, schema) {
|
|
|
303
329
|
|
|
304
330
|
export function processRouteSchema(api, schema, name) {
|
|
305
331
|
// Used for view and source schemas, see SourceMixin.
|
|
306
|
-
schema.name
|
|
307
|
-
schema.path
|
|
332
|
+
schema.name ??= name
|
|
333
|
+
schema.path ??= api.normalizePath(name)
|
|
308
334
|
}
|
|
309
335
|
|
|
310
336
|
export async function processForms(api, schema, level) {
|