@ditojs/admin 2.26.0 → 2.26.2
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 +1244 -1208
- package/dist/dito-admin.umd.js +5 -5
- package/package.json +29 -29
- package/src/DitoContext.js +6 -0
- package/src/components/DitoForm.vue +10 -16
- package/src/components/DitoFormInner.vue +26 -0
- package/src/components/index.js +1 -0
- package/src/mixins/DitoMixin.js +24 -18
- package/src/mixins/EmitterMixin.js +2 -0
- package/src/utils/schema.js +26 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/admin",
|
|
3
|
-
"version": "2.26.
|
|
3
|
+
"version": "2.26.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Dito.js Admin is a schema based admin interface for Dito.js Server, featuring auto-generated views and forms and built with Vue.js",
|
|
6
6
|
"repository": "https://github.com/ditojs/dito/tree/master/packages/admin",
|
|
@@ -33,31 +33,31 @@
|
|
|
33
33
|
"not ie_mob > 0"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@ditojs/ui": "^2.26.
|
|
37
|
-
"@ditojs/utils": "^2.26.
|
|
36
|
+
"@ditojs/ui": "^2.26.1",
|
|
37
|
+
"@ditojs/utils": "^2.26.1",
|
|
38
38
|
"@kyvg/vue3-notification": "^3.2.1",
|
|
39
39
|
"@lk77/vue3-color": "^3.0.6",
|
|
40
|
-
"@tiptap/core": "^2.
|
|
41
|
-
"@tiptap/extension-blockquote": "^2.
|
|
42
|
-
"@tiptap/extension-bold": "^2.
|
|
43
|
-
"@tiptap/extension-bullet-list": "^2.
|
|
44
|
-
"@tiptap/extension-code": "^2.
|
|
45
|
-
"@tiptap/extension-code-block": "^2.
|
|
46
|
-
"@tiptap/extension-document": "^2.
|
|
47
|
-
"@tiptap/extension-hard-break": "^2.
|
|
48
|
-
"@tiptap/extension-heading": "^2.
|
|
49
|
-
"@tiptap/extension-history": "^2.
|
|
50
|
-
"@tiptap/extension-horizontal-rule": "^2.
|
|
51
|
-
"@tiptap/extension-italic": "^2.
|
|
52
|
-
"@tiptap/extension-link": "^2.
|
|
53
|
-
"@tiptap/extension-list-item": "^2.
|
|
54
|
-
"@tiptap/extension-ordered-list": "^2.
|
|
55
|
-
"@tiptap/extension-paragraph": "^2.
|
|
56
|
-
"@tiptap/extension-strike": "^2.
|
|
57
|
-
"@tiptap/extension-text": "^2.
|
|
58
|
-
"@tiptap/extension-underline": "^2.
|
|
59
|
-
"@tiptap/pm": "^2.
|
|
60
|
-
"@tiptap/vue-3": "^2.
|
|
40
|
+
"@tiptap/core": "^2.3.0",
|
|
41
|
+
"@tiptap/extension-blockquote": "^2.3.0",
|
|
42
|
+
"@tiptap/extension-bold": "^2.3.0",
|
|
43
|
+
"@tiptap/extension-bullet-list": "^2.3.0",
|
|
44
|
+
"@tiptap/extension-code": "^2.3.0",
|
|
45
|
+
"@tiptap/extension-code-block": "^2.3.0",
|
|
46
|
+
"@tiptap/extension-document": "^2.3.0",
|
|
47
|
+
"@tiptap/extension-hard-break": "^2.3.0",
|
|
48
|
+
"@tiptap/extension-heading": "^2.3.0",
|
|
49
|
+
"@tiptap/extension-history": "^2.3.0",
|
|
50
|
+
"@tiptap/extension-horizontal-rule": "^2.3.0",
|
|
51
|
+
"@tiptap/extension-italic": "^2.3.0",
|
|
52
|
+
"@tiptap/extension-link": "^2.3.0",
|
|
53
|
+
"@tiptap/extension-list-item": "^2.3.0",
|
|
54
|
+
"@tiptap/extension-ordered-list": "^2.3.0",
|
|
55
|
+
"@tiptap/extension-paragraph": "^2.3.0",
|
|
56
|
+
"@tiptap/extension-strike": "^2.3.0",
|
|
57
|
+
"@tiptap/extension-text": "^2.3.0",
|
|
58
|
+
"@tiptap/extension-underline": "^2.3.0",
|
|
59
|
+
"@tiptap/pm": "^2.3.0",
|
|
60
|
+
"@tiptap/vue-3": "^2.3.0",
|
|
61
61
|
"@vueuse/integrations": "^10.9.0",
|
|
62
62
|
"codeflask": "^1.4.1",
|
|
63
63
|
"filesize": "^10.1.1",
|
|
@@ -69,21 +69,21 @@
|
|
|
69
69
|
"tippy.js": "^6.3.7",
|
|
70
70
|
"type-fest": "^4.15.0",
|
|
71
71
|
"vue": "3.4.10",
|
|
72
|
-
"vue-multiselect": "^3.0.0
|
|
72
|
+
"vue-multiselect": "^3.0.0",
|
|
73
73
|
"vue-router": "^4.3.0",
|
|
74
74
|
"vue-upload-component": "^3.1.15"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
-
"@ditojs/build": "^2.26.
|
|
77
|
+
"@ditojs/build": "^2.26.1",
|
|
78
78
|
"@vitejs/plugin-vue": "^5.0.4",
|
|
79
79
|
"@vue/compiler-sfc": "3.4.21",
|
|
80
80
|
"pug": "^3.0.2",
|
|
81
|
-
"sass": "1.
|
|
82
|
-
"typescript": "^5.4.
|
|
81
|
+
"sass": "1.75.0",
|
|
82
|
+
"typescript": "^5.4.5",
|
|
83
83
|
"vite": "^5.2.8"
|
|
84
84
|
},
|
|
85
85
|
"types": "types",
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "7fd7a0b9a8727e1a27a8e78e7381f58c95017499",
|
|
87
87
|
"scripts": {
|
|
88
88
|
"build": "vite build",
|
|
89
89
|
"watch": "yarn build --mode 'development' --watch",
|
package/src/DitoContext.js
CHANGED
|
@@ -61,6 +61,12 @@ export default class DitoContext {
|
|
|
61
61
|
: new DitoContext(component, context)
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
extend(object) {
|
|
65
|
+
// Create a copy of this context that inherits from the real one, but
|
|
66
|
+
// overrides some properties with the ones from the passed `object`.
|
|
67
|
+
return Object.setPrototypeOf(object, this)
|
|
68
|
+
}
|
|
69
|
+
|
|
64
70
|
// `nested` is `true` when the data-path points a value inside an item, and
|
|
65
71
|
// `false` when it points to the item itself.
|
|
66
72
|
get nested() {
|
|
@@ -3,20 +3,18 @@
|
|
|
3
3
|
:class="{ 'dito-form-nested': isNestedRoute }"
|
|
4
4
|
:data-resource="sourceSchema.path"
|
|
5
5
|
)
|
|
6
|
-
//-
|
|
7
|
-
//-
|
|
8
|
-
//- editing. Only render a router-view here if this isn't the last data route
|
|
9
|
-
//- and not a nested form route, which will appear elsewhere in its own view.
|
|
6
|
+
//- Only render a router-view here if this isn't the last data route and not a
|
|
7
|
+
//- nested form route, which will appear elsewhere in its own view.
|
|
10
8
|
RouterView(
|
|
11
|
-
v-if="!
|
|
9
|
+
v-if="!isLastUnnestedRoute && !isNestedRoute"
|
|
12
10
|
v-show="!isActive"
|
|
13
11
|
)
|
|
14
|
-
//-
|
|
15
|
-
|
|
12
|
+
//- NOTE: Nested form components are kept alive by using `v-show` instead of
|
|
13
|
+
//- `v-if` here, so event handling and other things still work with nested
|
|
14
|
+
//- editing.
|
|
15
|
+
DitoFormInner(
|
|
16
16
|
v-show="isActive"
|
|
17
|
-
:
|
|
18
|
-
:class="{ 'dito-scroll-parent': isRootForm }"
|
|
19
|
-
@submit.prevent
|
|
17
|
+
:nested="isNestedRoute"
|
|
20
18
|
)
|
|
21
19
|
//- Prevent implicit submission of the form, for example when typing enter
|
|
22
20
|
//- in an input field.
|
|
@@ -34,12 +32,12 @@
|
|
|
34
32
|
:store="store"
|
|
35
33
|
:padding="isNestedRoute ? 'nested' : 'root'"
|
|
36
34
|
:disabled="isLoading"
|
|
37
|
-
:scrollable="
|
|
35
|
+
:scrollable="!isNestedRoute"
|
|
38
36
|
generateLabels
|
|
39
37
|
)
|
|
40
38
|
template(#buttons)
|
|
41
39
|
DitoButtons.dito-buttons-round.dito-buttons-large.dito-buttons-main(
|
|
42
|
-
:class="{ 'dito-buttons-sticky':
|
|
40
|
+
:class="{ 'dito-buttons-sticky': !isNestedRoute }"
|
|
43
41
|
:buttons="buttonSchemas"
|
|
44
42
|
:dataPath="dataPath"
|
|
45
43
|
:data="data"
|
|
@@ -127,10 +125,6 @@ export default DitoComponent.component('DitoForm', {
|
|
|
127
125
|
)
|
|
128
126
|
},
|
|
129
127
|
|
|
130
|
-
isRootForm() {
|
|
131
|
-
return this.dataPath === '' && !this.isNestedRoute
|
|
132
|
-
},
|
|
133
|
-
|
|
134
128
|
isActive() {
|
|
135
129
|
return this.isLastRoute || this.isLastUnnestedRoute
|
|
136
130
|
},
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<template lang="pug">
|
|
2
|
+
//- Use a <div> for nested forms, as we shouldn't nest actual <form> tags.
|
|
3
|
+
div(
|
|
4
|
+
v-if="nested"
|
|
5
|
+
)
|
|
6
|
+
slot
|
|
7
|
+
form.dito-scroll-parent(
|
|
8
|
+
v-else
|
|
9
|
+
@submit.prevent
|
|
10
|
+
)
|
|
11
|
+
slot
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
import DitoComponent from '../DitoComponent.js'
|
|
16
|
+
|
|
17
|
+
// @vue/component
|
|
18
|
+
export default DitoComponent.component('DitoFormInner', {
|
|
19
|
+
props: {
|
|
20
|
+
nested: {
|
|
21
|
+
type: Boolean,
|
|
22
|
+
default: false
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
</script>
|
package/src/components/index.js
CHANGED
|
@@ -27,6 +27,7 @@ export { default as DitoCreateButton } from './DitoCreateButton.vue'
|
|
|
27
27
|
export { default as DitoClipboard } from './DitoClipboard.vue'
|
|
28
28
|
export { default as DitoView } from './DitoView.vue'
|
|
29
29
|
export { default as DitoForm } from './DitoForm.vue'
|
|
30
|
+
export { default as DitoFormInner } from './DitoFormInner.vue'
|
|
30
31
|
export { default as DitoFormNested } from './DitoFormNested.vue'
|
|
31
32
|
export { default as DitoErrors } from './DitoErrors.vue'
|
|
32
33
|
export { default as DitoScopes } from './DitoScopes.vue'
|
package/src/mixins/DitoMixin.js
CHANGED
|
@@ -534,30 +534,36 @@ export default {
|
|
|
534
534
|
}
|
|
535
535
|
},
|
|
536
536
|
|
|
537
|
-
|
|
537
|
+
emitEvent(event, {
|
|
538
538
|
context = null,
|
|
539
539
|
parent = null
|
|
540
540
|
} = {}) {
|
|
541
541
|
const hasListeners = this.hasListeners(event)
|
|
542
542
|
const parentHasListeners = parent?.hasListeners(event)
|
|
543
543
|
if (hasListeners || parentHasListeners) {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
const
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
544
|
+
const emitEvent = target =>
|
|
545
|
+
target.emit(event, (context = DitoContext.get(this, context)))
|
|
546
|
+
|
|
547
|
+
const handleParentListeners = result =>
|
|
548
|
+
// Don't bubble to parent if handled event returned `false`
|
|
549
|
+
parentHasListeners && result !== false
|
|
550
|
+
? emitEvent(parent).then(() => result)
|
|
551
|
+
: result
|
|
552
|
+
|
|
553
|
+
const handleListeners = () =>
|
|
554
|
+
hasListeners
|
|
555
|
+
? emitEvent(this).then(handleParentListeners)
|
|
556
|
+
: handleParentListeners(undefined)
|
|
557
|
+
|
|
558
|
+
return ['load', 'change'].includes(event)
|
|
559
|
+
? // The effects of some events need time to propagate through Vue.
|
|
560
|
+
// Use $nextTick() to make sure our handlers see these changes.
|
|
561
|
+
// For example, `processedItem` is only correct after components
|
|
562
|
+
// that are newly rendered due to data changes have registered.
|
|
563
|
+
// NOTE: The result of `handleListeners()` makes it through the
|
|
564
|
+
// `$nextTick()` call and will be returned as expected.
|
|
565
|
+
this.$nextTick(handleListeners)
|
|
566
|
+
: handleListeners()
|
|
561
567
|
}
|
|
562
568
|
},
|
|
563
569
|
|
package/src/utils/schema.js
CHANGED
|
@@ -122,7 +122,12 @@ export function getSchemaIdentifier(schema) {
|
|
|
122
122
|
return JSON.stringify(schema)
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
const resolvedSchemas = new WeakMap()
|
|
126
|
+
export async function resolveSchema(value, unwrapModule = false) {
|
|
127
|
+
if (resolvedSchemas.has(value)) {
|
|
128
|
+
return resolvedSchemas.get(value)
|
|
129
|
+
}
|
|
130
|
+
let schema = value
|
|
126
131
|
if (isFunction(schema)) {
|
|
127
132
|
schema = schema()
|
|
128
133
|
}
|
|
@@ -147,6 +152,7 @@ export async function resolveSchema(schema, unwrapModule = false) {
|
|
|
147
152
|
}
|
|
148
153
|
}
|
|
149
154
|
}
|
|
155
|
+
resolvedSchemas.set(value, schema)
|
|
150
156
|
return schema
|
|
151
157
|
}
|
|
152
158
|
|
|
@@ -236,29 +242,34 @@ export async function resolveSchemaComponents(schemas) {
|
|
|
236
242
|
await mapConcurrently(Object.values(schemas || {}), resolveSchemaComponent)
|
|
237
243
|
}
|
|
238
244
|
|
|
245
|
+
const processedSchemas = new WeakSet()
|
|
239
246
|
export async function processSchemaComponents(
|
|
240
247
|
api,
|
|
241
248
|
schema,
|
|
242
249
|
routes = null,
|
|
243
250
|
level = 0
|
|
244
251
|
) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
if (schema && !processedSchemas.has(schema)) {
|
|
253
|
+
processedSchemas.add(schema)
|
|
254
|
+
|
|
255
|
+
const promises = []
|
|
256
|
+
const process = (component, name, relativeLevel) => {
|
|
257
|
+
promises.push(
|
|
258
|
+
processSchemaComponent(
|
|
259
|
+
api,
|
|
260
|
+
component,
|
|
261
|
+
name,
|
|
262
|
+
routes,
|
|
263
|
+
level + relativeLevel
|
|
264
|
+
)
|
|
254
265
|
)
|
|
255
|
-
|
|
256
|
-
}
|
|
266
|
+
}
|
|
257
267
|
|
|
258
|
-
|
|
259
|
-
|
|
268
|
+
iterateNestedSchemaComponents(schema, process)
|
|
269
|
+
iterateSchemaComponents(getPanelSchemas(schema), process)
|
|
260
270
|
|
|
261
|
-
|
|
271
|
+
await Promise.all(promises)
|
|
272
|
+
}
|
|
262
273
|
}
|
|
263
274
|
|
|
264
275
|
export async function processSchemaComponent(
|