@ditojs/admin 0.268.0 → 0.269.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.common.js +819 -686
- package/dist/dito-admin.common.js.map +1 -1
- package/dist/dito-admin.umd.js +819 -686
- package/dist/dito-admin.umd.js.map +1 -1
- package/dist/dito-admin.umd.min.js +2 -2
- package/dist/dito-admin.umd.min.js.map +1 -1
- package/package.json +8 -8
- package/src/DitoAdmin.js +2 -1
- package/src/components/DitoButtons.vue +4 -6
- package/src/components/{DitoComponentContainer.vue → DitoContainer.vue} +4 -8
- package/src/components/DitoForm.vue +0 -1
- package/src/components/DitoLabel.vue +2 -2
- package/src/components/{DitoComponents.vue → DitoPane.vue} +18 -28
- package/src/components/DitoPanel.vue +10 -5
- package/src/components/DitoPanels.vue +4 -2
- package/src/components/DitoSchema.vue +32 -27
- package/src/components/DitoSchemaInlined.vue +1 -1
- package/src/components/index.js +5 -6
- package/src/mixins/DitoMixin.js +7 -2
- package/src/mixins/RouteMixin.js +1 -1
- package/src/mixins/SourceMixin.js +7 -3
- package/src/mixins/TypeMixin.js +13 -12
- package/src/styles/_button.sass +1 -1
- package/src/types/TypeCode.vue +1 -1
- package/src/types/TypeMarkup.vue +1 -1
- package/src/types/TypeMultiselect.vue +1 -1
- package/src/types/TypeSection.vue +1 -1
- package/src/types/TypeTreeList.vue +1 -3
- package/src/utils/schema.js +17 -7
- package/src/components/DitoButtonContainer.vue +0 -22
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/admin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.269.0",
|
|
4
4
|
"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",
|
|
5
5
|
"main": "dist/dito-admin.umd.min.js",
|
|
6
6
|
"repository": "https://github.com/ditojs/dito/tree/master/packages/admin",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@babel/runtime": "^7.15.4",
|
|
37
|
-
"@ditojs/ui": "^0.
|
|
38
|
-
"@ditojs/utils": "^0.
|
|
37
|
+
"@ditojs/ui": "^0.269.0",
|
|
38
|
+
"@ditojs/utils": "^0.269.0",
|
|
39
39
|
"axios": "^0.21.4",
|
|
40
40
|
"codeflask": "^1.4.1",
|
|
41
|
-
"core-js": "^3.
|
|
41
|
+
"core-js": "^3.18.0",
|
|
42
42
|
"filesize": "^8.0.3",
|
|
43
43
|
"filesize-parser": "^1.5.0",
|
|
44
44
|
"hint.css": "^2.6.0",
|
|
@@ -63,14 +63,14 @@
|
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@babel/core": "^7.15.5",
|
|
65
65
|
"@babel/preset-env": "^7.15.6",
|
|
66
|
-
"@ditojs/babel-preset": "^0.
|
|
67
|
-
"@ditojs/build": "^0.
|
|
66
|
+
"@ditojs/babel-preset": "^0.269.0",
|
|
67
|
+
"@ditojs/build": "^0.269.0",
|
|
68
68
|
"@vue/cli-plugin-babel": "^4.5.13",
|
|
69
69
|
"@vue/cli-service": "^4.5.13",
|
|
70
70
|
"autoprefixer": "^9.8.6",
|
|
71
71
|
"babel-loader": "^8.2.2",
|
|
72
72
|
"fibers": "^5.0.0",
|
|
73
|
-
"postcss": "^8.3.
|
|
73
|
+
"postcss": "^8.3.8",
|
|
74
74
|
"postcss-loader": "^4.3.0",
|
|
75
75
|
"pug": "^3.0.2",
|
|
76
76
|
"pug-plain-loader": "^1.1.0",
|
|
@@ -78,5 +78,5 @@
|
|
|
78
78
|
"sass-loader": "^10.2.0",
|
|
79
79
|
"webpack": "^4.46.0"
|
|
80
80
|
},
|
|
81
|
-
"gitHead": "
|
|
81
|
+
"gitHead": "74b214afd5691f27312afbfd034c72de8871eac5"
|
|
82
82
|
}
|
package/src/DitoAdmin.js
CHANGED
|
@@ -182,7 +182,8 @@ export default class DitoAdmin {
|
|
|
182
182
|
$sourceComponent: () => null,
|
|
183
183
|
$resourceComponent: () => null,
|
|
184
184
|
$dialogComponent: () => null,
|
|
185
|
-
$panelComponent: () => null
|
|
185
|
+
$panelComponent: () => null,
|
|
186
|
+
$tabComponent: () => null
|
|
186
187
|
},
|
|
187
188
|
|
|
188
189
|
render: createElement => createElement(DitoRoot, {
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
// NOTE: This is similar to DitoComponents, but uses the DitoButtonContainer
|
|
3
|
-
// sub-class as the component container for different layout:
|
|
4
2
|
.dito-buttons(
|
|
5
3
|
v-if="buttonSchemas || $slots.default"
|
|
6
4
|
/* Pass on $listeners so that dito-edit-buttons can pass events. */
|
|
7
5
|
v-on="$listeners"
|
|
8
6
|
)
|
|
9
|
-
dito-
|
|
7
|
+
dito-container(
|
|
10
8
|
v-for="(buttonSchema, buttonDataPath) in buttonSchemas"
|
|
11
9
|
v-if="shouldRender(buttonSchema)"
|
|
12
10
|
:key="buttonDataPath"
|
|
@@ -19,8 +17,8 @@
|
|
|
19
17
|
:generateLabels="false"
|
|
20
18
|
)
|
|
21
19
|
// Render each node in the default slot through `dito-vnode`, so it can be
|
|
22
|
-
// wrapped in a `.dito-
|
|
23
|
-
.dito-
|
|
20
|
+
// wrapped in a `.dito-container` class.
|
|
21
|
+
.dito-container(
|
|
24
22
|
v-for="node in $slots.default"
|
|
25
23
|
v-if="node.tag"
|
|
26
24
|
)
|
|
@@ -34,7 +32,7 @@ import { appendDataPath } from '@/utils/data'
|
|
|
34
32
|
// @vue/component
|
|
35
33
|
export default DitoComponent.component('dito-buttons', {
|
|
36
34
|
provide: {
|
|
37
|
-
tabComponent: null
|
|
35
|
+
$tabComponent: () => null
|
|
38
36
|
},
|
|
39
37
|
|
|
40
38
|
props: {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
div(
|
|
2
|
+
.dito-container(
|
|
4
3
|
v-show="componentVisible"
|
|
5
4
|
:class="containerClass"
|
|
6
5
|
:style="containerStyle"
|
|
@@ -30,7 +29,7 @@
|
|
|
30
29
|
</template>
|
|
31
30
|
|
|
32
31
|
<style lang="sass">
|
|
33
|
-
.dito-
|
|
32
|
+
.dito-container
|
|
34
33
|
// Needed for better vertical alignment:
|
|
35
34
|
align-self: stretch
|
|
36
35
|
box-sizing: border-box
|
|
@@ -47,7 +46,7 @@
|
|
|
47
46
|
margin: $form-spacing $form-spacing-half 0
|
|
48
47
|
&.dito-single
|
|
49
48
|
height: 100% // So that list buttons can be sticky at the bottom
|
|
50
|
-
// NOTE: This is not nested inside
|
|
49
|
+
// NOTE: This is not nested inside `.dito-container` so that other
|
|
51
50
|
// type components can override `.dito-width-fill` class (filter precedence).
|
|
52
51
|
.dito-component
|
|
53
52
|
&.dito-width-fill
|
|
@@ -68,7 +67,7 @@ import { parseFraction } from '@/utils/math'
|
|
|
68
67
|
import { isString, isNumber } from '@ditojs/utils'
|
|
69
68
|
|
|
70
69
|
// @vue/component
|
|
71
|
-
export default DitoComponent.component('dito-
|
|
70
|
+
export default DitoComponent.component('dito-container', {
|
|
72
71
|
props: {
|
|
73
72
|
schema: { type: Object, required: true },
|
|
74
73
|
dataPath: { type: String, default: '' },
|
|
@@ -156,9 +155,6 @@ export default DitoComponent.component('dito-component-container', {
|
|
|
156
155
|
containerClass() {
|
|
157
156
|
const { class: containerClass } = this.schema
|
|
158
157
|
return {
|
|
159
|
-
// Use the component name as its class, so the extended
|
|
160
|
-
// dito-button-container automatically works too.
|
|
161
|
-
[this.$options.name]: true,
|
|
162
158
|
'dito-single': this.single,
|
|
163
159
|
'dito-omit-padding': shouldOmitPadding(this.schema),
|
|
164
160
|
...(
|
|
@@ -90,8 +90,8 @@
|
|
|
90
90
|
// TODO: Find a better way to control this behavior.
|
|
91
91
|
.dito-schema-compact
|
|
92
92
|
> .dito-schema-content
|
|
93
|
-
> .dito-
|
|
94
|
-
> .dito-
|
|
93
|
+
> .dito-pane
|
|
94
|
+
> .dito-container
|
|
95
95
|
> .dito-label:not(.dito-label-component)
|
|
96
96
|
display: inline-block
|
|
97
97
|
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
.dito-
|
|
2
|
+
.dito-pane(
|
|
3
3
|
v-if="isPopulated && componentSchemas.length > 0"
|
|
4
4
|
v-show="visible"
|
|
5
5
|
)
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
.dito-break(
|
|
16
16
|
v-if="schema.break === 'before'"
|
|
17
17
|
)
|
|
18
|
-
dito-
|
|
18
|
+
dito-container(
|
|
19
19
|
v-if="shouldRender(schema)"
|
|
20
20
|
:key="nestedDataPath"
|
|
21
21
|
:schema="schema"
|
|
@@ -34,30 +34,28 @@
|
|
|
34
34
|
</template>
|
|
35
35
|
|
|
36
36
|
<style lang="sass">
|
|
37
|
-
|
|
38
|
-
// `DitoSchema`
|
|
39
|
-
.dito-components
|
|
37
|
+
.dito-pane
|
|
40
38
|
display: flex
|
|
41
39
|
position: relative
|
|
42
40
|
flex-flow: row wrap
|
|
43
41
|
align-content: flex-start
|
|
44
42
|
align-items: baseline
|
|
45
|
-
// Remove padding added by
|
|
43
|
+
// Remove padding added by `.dito-container`
|
|
46
44
|
margin: (-$form-spacing) (-$form-spacing-half)
|
|
47
45
|
// Add removed horizontal margin again to max-width:
|
|
48
46
|
max-width: $content-width + 2 * $form-spacing-half
|
|
49
|
-
// Use `flex: 0%` for all `.dito-
|
|
47
|
+
// Use `flex: 0%` for all `.dito-pane` except `.dito-pane-main`,
|
|
50
48
|
// so that the `.dito-buttons-main` can be moved all the way to the bottom.
|
|
51
49
|
flex: 0%
|
|
52
50
|
|
|
53
|
-
&.dito-
|
|
51
|
+
&.dito-pane-main
|
|
54
52
|
flex: 100%
|
|
55
53
|
|
|
56
54
|
.dito-schema-header:not(.dito-schema-menu-header) + &
|
|
57
55
|
// Clear top-margin if the components are preceded by a schema header.
|
|
58
56
|
margin-top: 0
|
|
59
57
|
|
|
60
|
-
.dito-
|
|
58
|
+
.dito-container.dito-omit-padding > &
|
|
61
59
|
// Clear margins set above again if parent is omitting padding.
|
|
62
60
|
margin: 0
|
|
63
61
|
max-width: unset
|
|
@@ -73,10 +71,10 @@ import { appendDataPath } from '@/utils/data'
|
|
|
73
71
|
import { getAllPanelSchemas, isNested } from '@/utils/schema'
|
|
74
72
|
|
|
75
73
|
// @vue/component
|
|
76
|
-
export default DitoComponent.component('dito-
|
|
74
|
+
export default DitoComponent.component('dito-pane', {
|
|
77
75
|
provide() {
|
|
78
76
|
return {
|
|
79
|
-
tabComponent: this.tabComponent
|
|
77
|
+
$tabComponent: () => this.tabComponent
|
|
80
78
|
}
|
|
81
79
|
},
|
|
82
80
|
|
|
@@ -95,7 +93,7 @@ export default DitoComponent.component('dito-components', {
|
|
|
95
93
|
|
|
96
94
|
computed: {
|
|
97
95
|
tabComponent() {
|
|
98
|
-
return this.tab ? this :
|
|
96
|
+
return this.tab ? this : this.$tabComponent()
|
|
99
97
|
},
|
|
100
98
|
|
|
101
99
|
componentSchemas() {
|
|
@@ -130,21 +128,13 @@ export default DitoComponent.component('dito-components', {
|
|
|
130
128
|
panelSchemas() {
|
|
131
129
|
// Gather all panel schemas from all component schemas, by finding those
|
|
132
130
|
// that want to provide a panel. See `getAllPanelSchemas()` for details.
|
|
133
|
-
return this.componentSchemas.
|
|
134
|
-
(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
schemas.push({
|
|
141
|
-
...panel,
|
|
142
|
-
tabComponent: this.tabComponent
|
|
143
|
-
})
|
|
144
|
-
}
|
|
145
|
-
return schemas
|
|
146
|
-
},
|
|
147
|
-
[]
|
|
131
|
+
return this.componentSchemas.flatMap(
|
|
132
|
+
({ schema, nestedDataPath: dataPath }) => getAllPanelSchemas(
|
|
133
|
+
schema,
|
|
134
|
+
dataPath,
|
|
135
|
+
this.schemaComponent,
|
|
136
|
+
this.tabComponent
|
|
137
|
+
)
|
|
148
138
|
)
|
|
149
139
|
},
|
|
150
140
|
|
|
@@ -163,7 +153,7 @@ export default DitoComponent.component('dito-components', {
|
|
|
163
153
|
|
|
164
154
|
methods: {
|
|
165
155
|
_register(add) {
|
|
166
|
-
this.schemaComponent.
|
|
156
|
+
this.schemaComponent._registerPane(this, add)
|
|
167
157
|
},
|
|
168
158
|
|
|
169
159
|
focus() {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Only show panels in tabs when the tabs are also visible.
|
|
3
3
|
component.dito-panel(
|
|
4
4
|
:is="panelTag"
|
|
5
|
-
v-show="visible && (!
|
|
5
|
+
v-show="visible && (!panelTabComponent || panelTabComponent.visible)"
|
|
6
6
|
@submit.prevent
|
|
7
7
|
)
|
|
8
8
|
label.dito-panel-title {{ getLabel(schema) }}
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
margin: 0
|
|
57
57
|
label
|
|
58
58
|
font-weight: normal
|
|
59
|
-
.dito-
|
|
59
|
+
.dito-pane
|
|
60
60
|
margin: 0 (-$form-spacing-half)
|
|
61
|
-
.dito-
|
|
61
|
+
.dito-container
|
|
62
62
|
padding: $form-spacing-half
|
|
63
63
|
</style>
|
|
64
64
|
|
|
@@ -75,7 +75,8 @@ export default DitoComponent.component('dito-panel', {
|
|
|
75
75
|
|
|
76
76
|
provide() {
|
|
77
77
|
return {
|
|
78
|
-
$panelComponent: () => this
|
|
78
|
+
$panelComponent: () => this,
|
|
79
|
+
$tabComponent: () => this.panelTabComponent
|
|
79
80
|
}
|
|
80
81
|
},
|
|
81
82
|
|
|
@@ -86,7 +87,7 @@ export default DitoComponent.component('dito-panel', {
|
|
|
86
87
|
meta: { type: Object, required: true },
|
|
87
88
|
store: { type: Object, required: true },
|
|
88
89
|
disabled: { type: Boolean, required: true },
|
|
89
|
-
|
|
90
|
+
panelTabComponent: { type: DitoComponent, default: null }
|
|
90
91
|
},
|
|
91
92
|
|
|
92
93
|
data() {
|
|
@@ -100,6 +101,10 @@ export default DitoComponent.component('dito-panel', {
|
|
|
100
101
|
return this
|
|
101
102
|
},
|
|
102
103
|
|
|
104
|
+
tabComponent() {
|
|
105
|
+
return this.panelTabComponent
|
|
106
|
+
},
|
|
107
|
+
|
|
103
108
|
buttonSchemas() {
|
|
104
109
|
return getButtonSchemas(this.schema.buttons)
|
|
105
110
|
},
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
.dito-panels
|
|
2
|
+
.dito-panels(
|
|
3
|
+
v-if="panels.length > 0"
|
|
4
|
+
)
|
|
3
5
|
dito-panel(
|
|
4
6
|
v-for="{ schema, dataPath, tabComponent } in panels"
|
|
5
7
|
v-if="shouldRender(schema)"
|
|
@@ -10,7 +12,7 @@
|
|
|
10
12
|
:meta="meta"
|
|
11
13
|
:store="getChildStore(schema.name)"
|
|
12
14
|
:disabled="schema.disabled != null ? schema.disabled : disabled"
|
|
13
|
-
:
|
|
15
|
+
:panelTabComponent="tabComponent"
|
|
14
16
|
)
|
|
15
17
|
</template>
|
|
16
18
|
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
:dataPath="dataPath"
|
|
30
30
|
:data="data"
|
|
31
31
|
)
|
|
32
|
-
dito-
|
|
32
|
+
dito-pane.dito-pane-tab(
|
|
33
33
|
v-if="hasTabs"
|
|
34
34
|
v-for="(schema, tab) in tabs"
|
|
35
35
|
ref="tabs"
|
|
@@ -41,15 +41,15 @@
|
|
|
41
41
|
:data="data"
|
|
42
42
|
:meta="meta"
|
|
43
43
|
:store="store"
|
|
44
|
-
:single="!inlined && !
|
|
44
|
+
:single="!inlined && !hasMainPane"
|
|
45
45
|
:disabled="disabled"
|
|
46
46
|
:generateLabels="generateLabels"
|
|
47
47
|
)
|
|
48
48
|
transition-height(
|
|
49
49
|
:enabled="inlined"
|
|
50
50
|
)
|
|
51
|
-
dito-
|
|
52
|
-
v-if="
|
|
51
|
+
dito-pane.dito-pane-main(
|
|
52
|
+
v-if="hasMainPane && opened"
|
|
53
53
|
ref="components"
|
|
54
54
|
:schema="schema"
|
|
55
55
|
:dataPath="dataPath"
|
|
@@ -69,9 +69,8 @@
|
|
|
69
69
|
v-if="!hasLabel"
|
|
70
70
|
name="edit-buttons"
|
|
71
71
|
)
|
|
72
|
-
template(
|
|
72
|
+
template(v-else-if="isPopulated")
|
|
73
73
|
dito-panels(
|
|
74
|
-
v-if="isPopulated && panelSchemas.length > 0"
|
|
75
74
|
:panels="panelSchemas"
|
|
76
75
|
:data="data"
|
|
77
76
|
:meta="meta"
|
|
@@ -103,7 +102,7 @@
|
|
|
103
102
|
> .dito-panels
|
|
104
103
|
padding: $content-padding $content-padding $content-padding 0
|
|
105
104
|
// Display a ruler between tabbed components and towards the .dito-buttons
|
|
106
|
-
.dito-
|
|
105
|
+
.dito-pane-tab + .dito-pane-main
|
|
107
106
|
&::before
|
|
108
107
|
// Use a pseudo element to display a ruler with proper margins
|
|
109
108
|
display: block
|
|
@@ -203,8 +202,8 @@ export default DitoComponent.component('dito-schema', {
|
|
|
203
202
|
? data.call(this, this.context)
|
|
204
203
|
: data
|
|
205
204
|
),
|
|
206
|
-
containersRegistry: {},
|
|
207
205
|
componentsRegistry: {},
|
|
206
|
+
panesRegistry: {},
|
|
208
207
|
panelsRegistry: {}
|
|
209
208
|
}
|
|
210
209
|
},
|
|
@@ -224,8 +223,8 @@ export default DitoComponent.component('dito-schema', {
|
|
|
224
223
|
|
|
225
224
|
panelSchemas() {
|
|
226
225
|
const panels = getPanelSchemas(this.schema.panels, '')
|
|
227
|
-
for (const
|
|
228
|
-
panels.push(...
|
|
226
|
+
for (const pane of this.panes) {
|
|
227
|
+
panels.push(...pane.panelSchemas)
|
|
229
228
|
}
|
|
230
229
|
return panels
|
|
231
230
|
},
|
|
@@ -340,7 +339,7 @@ export default DitoComponent.component('dito-schema', {
|
|
|
340
339
|
return !this.inlined && !!this.tabs
|
|
341
340
|
},
|
|
342
341
|
|
|
343
|
-
|
|
342
|
+
hasMainPane() {
|
|
344
343
|
const { components } = this.schema
|
|
345
344
|
return !!components && Object.keys(components).length > 0
|
|
346
345
|
},
|
|
@@ -351,14 +350,26 @@ export default DitoComponent.component('dito-schema', {
|
|
|
351
350
|
}
|
|
352
351
|
}),
|
|
353
352
|
|
|
354
|
-
|
|
355
|
-
return
|
|
353
|
+
components() {
|
|
354
|
+
return Object.values(this.componentsRegistry)
|
|
355
|
+
},
|
|
356
|
+
|
|
357
|
+
panes() {
|
|
358
|
+
return Object.values(this.panesRegistry)
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
panels() {
|
|
362
|
+
return Object.values(this.panelsRegistry)
|
|
356
363
|
},
|
|
357
364
|
|
|
358
365
|
componentsByDataPath() {
|
|
359
366
|
return this._listEntriesByDataPath(this.componentsRegistry)
|
|
360
367
|
},
|
|
361
368
|
|
|
369
|
+
panesByDataPath() {
|
|
370
|
+
return this._listEntriesByDataPath(this.panesRegistry)
|
|
371
|
+
},
|
|
372
|
+
|
|
362
373
|
panelsByDataPath() {
|
|
363
374
|
return this._listEntriesByDataPath(this.panelsRegistry)
|
|
364
375
|
}
|
|
@@ -421,17 +432,11 @@ export default DitoComponent.component('dito-schema', {
|
|
|
421
432
|
},
|
|
422
433
|
|
|
423
434
|
someComponent(callback) {
|
|
424
|
-
return (
|
|
425
|
-
this.isPopulated &&
|
|
426
|
-
Object.values(this.componentsRegistry).some(callback)
|
|
427
|
-
)
|
|
435
|
+
return this.isPopulated && this.components.some(callback)
|
|
428
436
|
},
|
|
429
437
|
|
|
430
438
|
everyComponent(callback) {
|
|
431
|
-
return (
|
|
432
|
-
this.isPopulated &&
|
|
433
|
-
Object.values(this.componentsRegistry).every(callback)
|
|
434
|
-
)
|
|
439
|
+
return this.isPopulated && this.components.every(callback)
|
|
435
440
|
},
|
|
436
441
|
|
|
437
442
|
onExpand(expand) {
|
|
@@ -456,13 +461,13 @@ export default DitoComponent.component('dito-schema', {
|
|
|
456
461
|
},
|
|
457
462
|
|
|
458
463
|
resetValidation() {
|
|
459
|
-
for (const component of
|
|
464
|
+
for (const component of this.components) {
|
|
460
465
|
component.resetValidation()
|
|
461
466
|
}
|
|
462
467
|
},
|
|
463
468
|
|
|
464
469
|
clearErrors() {
|
|
465
|
-
for (const component of
|
|
470
|
+
for (const component of this.components) {
|
|
466
471
|
component.clearErrors()
|
|
467
472
|
}
|
|
468
473
|
},
|
|
@@ -655,16 +660,16 @@ export default DitoComponent.component('dito-schema', {
|
|
|
655
660
|
this.$schemaParentComponent()?._registerSchemaComponent(this, add)
|
|
656
661
|
},
|
|
657
662
|
|
|
658
|
-
_registerContainer(container, add) {
|
|
659
|
-
this._registerEntry(this.containersRegistry, container, add)
|
|
660
|
-
},
|
|
661
|
-
|
|
662
663
|
_registerComponent(component, add) {
|
|
663
664
|
this._registerEntry(this.componentsRegistry, component, add)
|
|
664
665
|
// Only register with the parent if schema shares data with it.
|
|
665
666
|
this.parentSchemaComponent?._registerComponent(component, add)
|
|
666
667
|
},
|
|
667
668
|
|
|
669
|
+
_registerPane(pane, add) {
|
|
670
|
+
this._registerEntry(this.panesRegistry, pane, add)
|
|
671
|
+
},
|
|
672
|
+
|
|
668
673
|
_registerPanel(panel, add) {
|
|
669
674
|
this._registerEntry(this.panelsRegistry, panel, add)
|
|
670
675
|
},
|
package/src/components/index.js
CHANGED
|
@@ -12,15 +12,14 @@ import './DitoElement'
|
|
|
12
12
|
import './DitoLabel'
|
|
13
13
|
import './DitoSchema'
|
|
14
14
|
import './DitoSchemaInlined'
|
|
15
|
-
import './
|
|
15
|
+
import './DitoPane'
|
|
16
|
+
import './DitoContainer'
|
|
17
|
+
import './DitoTabs'
|
|
18
|
+
import './DitoPanel'
|
|
19
|
+
import './DitoPanels'
|
|
16
20
|
import './DitoButtons'
|
|
17
21
|
import './DitoEditButtons'
|
|
18
|
-
import './DitoComponentContainer'
|
|
19
|
-
import './DitoButtonContainer'
|
|
20
22
|
import './DitoCreateButton'
|
|
21
|
-
import './DitoPanel'
|
|
22
|
-
import './DitoPanels'
|
|
23
|
-
import './DitoTabs'
|
|
24
23
|
import './DitoClipboard'
|
|
25
24
|
import './DitoView'
|
|
26
25
|
import './DitoForm'
|
package/src/mixins/DitoMixin.js
CHANGED
|
@@ -25,7 +25,8 @@ export default {
|
|
|
25
25
|
'$sourceComponent',
|
|
26
26
|
'$resourceComponent',
|
|
27
27
|
'$dialogComponent',
|
|
28
|
-
'$panelComponent'
|
|
28
|
+
'$panelComponent',
|
|
29
|
+
'$tabComponent'
|
|
29
30
|
],
|
|
30
31
|
|
|
31
32
|
provide() {
|
|
@@ -122,6 +123,10 @@ export default {
|
|
|
122
123
|
return this.$panelComponent()
|
|
123
124
|
},
|
|
124
125
|
|
|
126
|
+
tabComponent() {
|
|
127
|
+
return this.$tabComponent()
|
|
128
|
+
},
|
|
129
|
+
|
|
125
130
|
parentSchemaComponent() {
|
|
126
131
|
return this.schemaComponent?.$parent.schemaComponent
|
|
127
132
|
},
|
|
@@ -153,7 +158,7 @@ export default {
|
|
|
153
158
|
// We can't store this in `data`, as this is already the pure data from the
|
|
154
159
|
// API server. That's what the `store` is for: Memory that's available as
|
|
155
160
|
// long as the current editing path is still valid. For type components,
|
|
156
|
-
// this memory is provided by the parent, see RouteMixin and
|
|
161
|
+
// this memory is provided by the parent, see RouteMixin and DitoPane.
|
|
157
162
|
getStore(key) {
|
|
158
163
|
return this.store[key]
|
|
159
164
|
},
|
package/src/mixins/RouteMixin.js
CHANGED
|
@@ -24,7 +24,7 @@ export default {
|
|
|
24
24
|
reload: false,
|
|
25
25
|
// Each route-component defines a store that gets passed on to its
|
|
26
26
|
// child components, so they can store values in them that live beyond
|
|
27
|
-
// their life-cycle. See:
|
|
27
|
+
// their life-cycle. See: DitoPane, SourceMixin
|
|
28
28
|
store: {},
|
|
29
29
|
loadCache: {} // See TypeMixin.load()
|
|
30
30
|
}
|
|
@@ -460,14 +460,18 @@ export default {
|
|
|
460
460
|
async navigateToComponent(dataPath, onComplete) {
|
|
461
461
|
if (this.collapsible) {
|
|
462
462
|
const index = dataPath.startsWith(this.dataPath)
|
|
463
|
-
?
|
|
463
|
+
? this.isListSource
|
|
464
|
+
? parseDataPath(dataPath.slice(this.dataPath.length + 1))[0] ?? null
|
|
465
|
+
: 0
|
|
464
466
|
: null
|
|
465
467
|
if (index !== null && isNumber(+index)) {
|
|
466
468
|
const schemaComponent = this.getSchemaComponent(+index)
|
|
467
469
|
if (schemaComponent) {
|
|
468
470
|
const { opened } = schemaComponent
|
|
469
|
-
|
|
470
|
-
|
|
471
|
+
if (!opened) {
|
|
472
|
+
schemaComponent.opened = true
|
|
473
|
+
await this.$nextTick()
|
|
474
|
+
}
|
|
471
475
|
const components = schemaComponent.getComponentsByDataPath(dataPath)
|
|
472
476
|
if (components.length > 0 && (onComplete?.(components) ?? true)) {
|
|
473
477
|
return true
|
package/src/mixins/TypeMixin.js
CHANGED
|
@@ -9,10 +9,6 @@ import { isString, asArray } from '@ditojs/utils'
|
|
|
9
9
|
export default {
|
|
10
10
|
mixins: [ValidationMixin],
|
|
11
11
|
|
|
12
|
-
inject: [
|
|
13
|
-
'tabComponent'
|
|
14
|
-
],
|
|
15
|
-
|
|
16
12
|
props: {
|
|
17
13
|
schema: { type: Object, required: true },
|
|
18
14
|
// NOTE: While `dataPath` points to the actual `value`, `data` represents
|
|
@@ -259,23 +255,28 @@ export default {
|
|
|
259
255
|
return null
|
|
260
256
|
},
|
|
261
257
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
this.
|
|
265
|
-
|
|
266
|
-
const [focus] = asArray(this.$refs.element)
|
|
267
|
-
if (focus) {
|
|
258
|
+
// @overridable
|
|
259
|
+
focusElement() {
|
|
260
|
+
const [element] = asArray(this.$refs.element)
|
|
261
|
+
if (element) {
|
|
268
262
|
this.$nextTick(() => {
|
|
269
|
-
|
|
263
|
+
element.focus()
|
|
270
264
|
// If the element is disabled, `focus()` will likely not have the
|
|
271
265
|
// desired effect. Use `scrollIntoView()` if available:
|
|
272
266
|
if (this.disabled) {
|
|
273
|
-
(
|
|
267
|
+
(element.$el || element).scrollIntoView?.()
|
|
274
268
|
}
|
|
275
269
|
})
|
|
276
270
|
}
|
|
277
271
|
},
|
|
278
272
|
|
|
273
|
+
focus() {
|
|
274
|
+
// Also focus this component's schema and panel in case it's a tab.
|
|
275
|
+
this.schemaComponent.focus()
|
|
276
|
+
this.tabComponent?.focus()
|
|
277
|
+
this.focusElement()
|
|
278
|
+
},
|
|
279
|
+
|
|
279
280
|
clear() {
|
|
280
281
|
this.value = null
|
|
281
282
|
this.onChange()
|
package/src/styles/_button.sass
CHANGED
package/src/types/TypeCode.vue
CHANGED