@ditojs/admin 2.35.0 → 2.36.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/dist/dito-admin.es.js +1970 -1939
- package/dist/dito-admin.umd.js +5 -5
- package/package.json +31 -31
- package/src/DitoContext.js +39 -16
- package/src/components/DitoButtons.vue +5 -0
- package/src/components/DitoContainer.vue +5 -3
- package/src/components/DitoCreateButton.vue +3 -1
- package/src/components/DitoEditButtons.vue +5 -0
- package/src/components/DitoPane.vue +8 -0
- package/src/components/DitoPanel.vue +7 -1
- package/src/components/DitoPanels.vue +10 -0
- package/src/components/DitoRoot.vue +1 -1
- package/src/components/DitoSchema.vue +9 -29
- package/src/components/DitoTableCell.vue +3 -0
- package/src/mixins/ContextMixin.js +68 -0
- package/src/mixins/TypeMixin.js +3 -86
- package/src/mixins/ValueMixin.js +32 -0
- package/src/types/DitoTypeComputed.vue +3 -3
- package/src/types/DitoTypeList.vue +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/admin",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.36.1",
|
|
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",
|
|
@@ -39,34 +39,34 @@
|
|
|
39
39
|
"not ie_mob > 0"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@ditojs/ui": "^2.
|
|
43
|
-
"@ditojs/utils": "^2.
|
|
42
|
+
"@ditojs/ui": "^2.36.1",
|
|
43
|
+
"@ditojs/utils": "^2.36.0",
|
|
44
44
|
"@kyvg/vue3-notification": "^3.4.0",
|
|
45
45
|
"@lk77/vue3-color": "^3.0.6",
|
|
46
|
-
"@tiptap/core": "^2.
|
|
47
|
-
"@tiptap/extension-blockquote": "^2.
|
|
48
|
-
"@tiptap/extension-bold": "^2.
|
|
49
|
-
"@tiptap/extension-bullet-list": "^2.
|
|
50
|
-
"@tiptap/extension-code": "^2.
|
|
51
|
-
"@tiptap/extension-code-block": "^2.
|
|
52
|
-
"@tiptap/extension-document": "^2.
|
|
53
|
-
"@tiptap/extension-hard-break": "^2.
|
|
54
|
-
"@tiptap/extension-heading": "^2.
|
|
55
|
-
"@tiptap/extension-history": "^2.
|
|
56
|
-
"@tiptap/extension-horizontal-rule": "^2.
|
|
57
|
-
"@tiptap/extension-italic": "^2.
|
|
58
|
-
"@tiptap/extension-link": "^2.
|
|
59
|
-
"@tiptap/extension-list-item": "^2.
|
|
60
|
-
"@tiptap/extension-ordered-list": "^2.
|
|
61
|
-
"@tiptap/extension-paragraph": "^2.
|
|
62
|
-
"@tiptap/extension-strike": "^2.
|
|
63
|
-
"@tiptap/extension-subscript": "^2.
|
|
64
|
-
"@tiptap/extension-superscript": "^2.
|
|
65
|
-
"@tiptap/extension-text": "^2.
|
|
66
|
-
"@tiptap/extension-text-style": "^2.
|
|
67
|
-
"@tiptap/extension-underline": "^2.
|
|
68
|
-
"@tiptap/pm": "^2.
|
|
69
|
-
"@tiptap/vue-3": "^2.
|
|
46
|
+
"@tiptap/core": "^2.9.1",
|
|
47
|
+
"@tiptap/extension-blockquote": "^2.9.1",
|
|
48
|
+
"@tiptap/extension-bold": "^2.9.1",
|
|
49
|
+
"@tiptap/extension-bullet-list": "^2.9.1",
|
|
50
|
+
"@tiptap/extension-code": "^2.9.1",
|
|
51
|
+
"@tiptap/extension-code-block": "^2.9.1",
|
|
52
|
+
"@tiptap/extension-document": "^2.9.1",
|
|
53
|
+
"@tiptap/extension-hard-break": "^2.9.1",
|
|
54
|
+
"@tiptap/extension-heading": "^2.9.1",
|
|
55
|
+
"@tiptap/extension-history": "^2.9.1",
|
|
56
|
+
"@tiptap/extension-horizontal-rule": "^2.9.1",
|
|
57
|
+
"@tiptap/extension-italic": "^2.9.1",
|
|
58
|
+
"@tiptap/extension-link": "^2.9.1",
|
|
59
|
+
"@tiptap/extension-list-item": "^2.9.1",
|
|
60
|
+
"@tiptap/extension-ordered-list": "^2.9.1",
|
|
61
|
+
"@tiptap/extension-paragraph": "^2.9.1",
|
|
62
|
+
"@tiptap/extension-strike": "^2.9.1",
|
|
63
|
+
"@tiptap/extension-subscript": "^2.9.1",
|
|
64
|
+
"@tiptap/extension-superscript": "^2.9.1",
|
|
65
|
+
"@tiptap/extension-text": "^2.9.1",
|
|
66
|
+
"@tiptap/extension-text-style": "^2.9.1",
|
|
67
|
+
"@tiptap/extension-underline": "^2.9.1",
|
|
68
|
+
"@tiptap/pm": "^2.9.1",
|
|
69
|
+
"@tiptap/vue-3": "^2.9.1",
|
|
70
70
|
"@vueuse/integrations": "^11.1.0",
|
|
71
71
|
"codeflask": "^1.4.1",
|
|
72
72
|
"filesize": "^10.1.6",
|
|
@@ -77,16 +77,16 @@
|
|
|
77
77
|
"tinycolor2": "^1.6.0",
|
|
78
78
|
"tippy.js": "^6.3.7",
|
|
79
79
|
"type-fest": "^4.26.1",
|
|
80
|
-
"vue": "^3.5.
|
|
80
|
+
"vue": "^3.5.12",
|
|
81
81
|
"vue-multiselect": "^3.1.0",
|
|
82
82
|
"vue-router": "^4.4.5",
|
|
83
83
|
"vue-upload-component": "^3.1.17"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
|
-
"@ditojs/build": "^2.
|
|
86
|
+
"@ditojs/build": "^2.36.1",
|
|
87
87
|
"typescript": "^5.6.3",
|
|
88
|
-
"vite": "^5.4.
|
|
88
|
+
"vite": "^5.4.10"
|
|
89
89
|
},
|
|
90
90
|
"types": "types",
|
|
91
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "70fd2abe897c2a4fd5d51cdaa06493c059f05d46"
|
|
92
92
|
}
|
package/src/DitoContext.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toRaw } from 'vue'
|
|
2
|
-
import { isFunction } from '@ditojs/utils'
|
|
2
|
+
import { getValueAtDataPath, isFunction } from '@ditojs/utils'
|
|
3
3
|
import {
|
|
4
4
|
getItemDataPath,
|
|
5
5
|
getParentItemDataPath,
|
|
@@ -11,24 +11,37 @@ import {
|
|
|
11
11
|
|
|
12
12
|
const { hasOwnProperty } = Object.prototype
|
|
13
13
|
|
|
14
|
-
// `DitoContext` instances are a thin wrapper around
|
|
15
|
-
// which themselves actually inherit from the linked
|
|
16
|
-
// that they only need to provide the values that
|
|
17
|
-
// in the underlying component. In order to not expose
|
|
18
|
-
// component, the wrapper is introduced
|
|
14
|
+
// See also `ContextMixin`: `DitoContext` instances are a thin wrapper around
|
|
15
|
+
// raw `context` objects, which themselves actually inherit from the linked
|
|
16
|
+
// `component` instance, so that they only need to provide the values that
|
|
17
|
+
// should be different than in the underlying component. In order to not expose
|
|
18
|
+
// all fields from the component, the wrapper is introduced.
|
|
19
|
+
|
|
19
20
|
// Use WeakMap for the raw `context` objects, so we don't have to pollute the
|
|
20
21
|
// actual `DitoContext` instance with it.
|
|
21
22
|
const contexts = new WeakMap()
|
|
22
23
|
|
|
23
|
-
function
|
|
24
|
-
|
|
24
|
+
function toObject(context) {
|
|
25
|
+
const rawStart = toRaw(context)
|
|
26
|
+
let raw = rawStart
|
|
25
27
|
let object = null
|
|
26
28
|
// In case `DitoContext.extend()` was used, we need to find the actual context
|
|
27
29
|
// object from the object's the inheritance chain:
|
|
28
|
-
|
|
30
|
+
do {
|
|
29
31
|
object = contexts.get(raw)
|
|
32
|
+
if (object) break
|
|
30
33
|
raw = Object.getPrototypeOf(raw)
|
|
34
|
+
} while (raw)
|
|
35
|
+
if (object && raw !== rawStart) {
|
|
36
|
+
// Assign the passed context with the original object as well, so we don't
|
|
37
|
+
// have to search for it again:
|
|
38
|
+
contexts.set(raw, object)
|
|
31
39
|
}
|
|
40
|
+
return object
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function get(context, key, defaultValue) {
|
|
44
|
+
const object = toObject(context)
|
|
32
45
|
const value = key in object ? object[key] : undefined
|
|
33
46
|
// If `object` explicitly sets the key to `undefined`, return it.
|
|
34
47
|
return value !== undefined || hasOwnProperty.call(object, key)
|
|
@@ -39,7 +52,7 @@ function get(context, key, defaultValue) {
|
|
|
39
52
|
}
|
|
40
53
|
|
|
41
54
|
function set(context, key, value) {
|
|
42
|
-
|
|
55
|
+
toObject(context)[key] = value
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
export default class DitoContext {
|
|
@@ -85,7 +98,16 @@ export default class DitoContext {
|
|
|
85
98
|
}
|
|
86
99
|
|
|
87
100
|
get value() {
|
|
88
|
-
return get(
|
|
101
|
+
return get(
|
|
102
|
+
this,
|
|
103
|
+
'value',
|
|
104
|
+
() =>
|
|
105
|
+
// If the value is not defined on the underlying object, it's not a type
|
|
106
|
+
// component. If it is nested, we can still get the value from the root.
|
|
107
|
+
this.nested
|
|
108
|
+
? getValueAtDataPath(this.rootItem, this.dataPath)
|
|
109
|
+
: undefined
|
|
110
|
+
)
|
|
89
111
|
}
|
|
90
112
|
|
|
91
113
|
get dataPath() {
|
|
@@ -118,10 +140,12 @@ export default class DitoContext {
|
|
|
118
140
|
|
|
119
141
|
// NOTE: While internally, we speak of `data`, in the API surface the
|
|
120
142
|
// term `item` is used for the data that relates to editing objects:
|
|
121
|
-
// If `data` isn't provided, we can determine it from rootData & dataPath:
|
|
122
143
|
get item() {
|
|
123
|
-
return get(
|
|
124
|
-
|
|
144
|
+
return get(
|
|
145
|
+
this,
|
|
146
|
+
'data',
|
|
147
|
+
// If `data` isn't provided, we can determine it from rootData & dataPath:
|
|
148
|
+
() => getItem(this.rootItem, this.dataPath, this.nested) || null
|
|
125
149
|
)
|
|
126
150
|
}
|
|
127
151
|
|
|
@@ -133,8 +157,7 @@ export default class DitoContext {
|
|
|
133
157
|
// processing with `rootData` and `dataPath`.
|
|
134
158
|
get parentItem() {
|
|
135
159
|
const item = (
|
|
136
|
-
getParentItem(this.rootItem, this.dataPath, this.nested) ||
|
|
137
|
-
null
|
|
160
|
+
getParentItem(this.rootItem, this.dataPath, this.nested) || null
|
|
138
161
|
)
|
|
139
162
|
return item !== this.item ? item : null
|
|
140
163
|
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
:dataPath="buttonDataPath"
|
|
13
13
|
:data="data"
|
|
14
14
|
:meta="meta"
|
|
15
|
+
:nested="nested"
|
|
15
16
|
:store="getChildStore(buttonSchema.name)"
|
|
16
17
|
:disabled="disabled"
|
|
17
18
|
)
|
|
@@ -28,11 +29,14 @@
|
|
|
28
29
|
|
|
29
30
|
<script>
|
|
30
31
|
import DitoComponent from '../DitoComponent.js'
|
|
32
|
+
import ContextMixin from '../mixins/ContextMixin.js'
|
|
31
33
|
import { appendDataPath } from '../utils/data.js'
|
|
32
34
|
import { hasSlotContent, hasVNodeContent } from '@ditojs/ui/src'
|
|
33
35
|
|
|
34
36
|
// @vue/component
|
|
35
37
|
export default DitoComponent.component('DitoButtons', {
|
|
38
|
+
mixins: [ContextMixin],
|
|
39
|
+
|
|
36
40
|
provide: {
|
|
37
41
|
$tabComponent: () => null
|
|
38
42
|
},
|
|
@@ -43,6 +47,7 @@ export default DitoComponent.component('DitoButtons', {
|
|
|
43
47
|
data: { type: [Object, Array], default: null },
|
|
44
48
|
meta: { type: Object, default: () => ({}) },
|
|
45
49
|
store: { type: Object, default: () => ({}) },
|
|
50
|
+
nested: { type: Boolean, default: true },
|
|
46
51
|
disabled: { type: Boolean, default: false }
|
|
47
52
|
},
|
|
48
53
|
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
<script>
|
|
47
47
|
import { isString, isNumber } from '@ditojs/utils'
|
|
48
48
|
import DitoComponent from '../DitoComponent.js'
|
|
49
|
-
import
|
|
49
|
+
import ValueMixin from '../mixins/ValueMixin.js'
|
|
50
|
+
import ContextMixin from '../mixins/ContextMixin.js'
|
|
50
51
|
import { getSchemaAccessor } from '../utils/accessor.js'
|
|
51
52
|
import {
|
|
52
53
|
getAllPanelEntries,
|
|
@@ -58,6 +59,7 @@ import { parseFraction } from '../utils/math.js'
|
|
|
58
59
|
|
|
59
60
|
// @vue/component
|
|
60
61
|
export default DitoComponent.component('DitoContainer', {
|
|
62
|
+
mixins: [ValueMixin, ContextMixin],
|
|
61
63
|
props: {
|
|
62
64
|
schema: { type: Object, required: true },
|
|
63
65
|
dataPath: { type: String, default: '' },
|
|
@@ -79,8 +81,8 @@ export default DitoComponent.component('DitoContainer', {
|
|
|
79
81
|
},
|
|
80
82
|
|
|
81
83
|
computed: {
|
|
82
|
-
|
|
83
|
-
return
|
|
84
|
+
name() {
|
|
85
|
+
return this.schema.name
|
|
84
86
|
},
|
|
85
87
|
|
|
86
88
|
type() {
|
|
@@ -30,12 +30,13 @@
|
|
|
30
30
|
|
|
31
31
|
<script>
|
|
32
32
|
import DitoComponent from '../DitoComponent.js'
|
|
33
|
+
import ContextMixin from '../mixins/ContextMixin.js'
|
|
33
34
|
import PulldownMixin from '../mixins/PulldownMixin.js'
|
|
34
35
|
import { getFormSchemas, isInlined } from '../utils/schema.js'
|
|
35
36
|
|
|
36
37
|
// @vue/component
|
|
37
38
|
export default DitoComponent.component('DitoCreateButton', {
|
|
38
|
-
mixins: [PulldownMixin],
|
|
39
|
+
mixins: [ContextMixin, PulldownMixin],
|
|
39
40
|
|
|
40
41
|
props: {
|
|
41
42
|
schema: { type: Object, required: true },
|
|
@@ -52,6 +53,7 @@ export default DitoComponent.component('DitoCreateButton', {
|
|
|
52
53
|
data: { type: [Object, Array], default: null },
|
|
53
54
|
meta: { type: Object, required: true },
|
|
54
55
|
store: { type: Object, required: true },
|
|
56
|
+
nested: { type: Boolean, default: false },
|
|
55
57
|
path: { type: String, required: true },
|
|
56
58
|
verb: { type: String, required: true },
|
|
57
59
|
text: { type: String, default: null },
|
|
@@ -6,6 +6,7 @@ DitoButtons.dito-edit-buttons.dito-buttons-round(
|
|
|
6
6
|
:data="data"
|
|
7
7
|
:meta="meta"
|
|
8
8
|
:store="store"
|
|
9
|
+
:nested="nested"
|
|
9
10
|
@click.stop
|
|
10
11
|
)
|
|
11
12
|
//- Firefox doesn't like <button> here, so use <a> instead:
|
|
@@ -27,6 +28,7 @@ DitoButtons.dito-edit-buttons.dito-buttons-round(
|
|
|
27
28
|
:data="data"
|
|
28
29
|
:meta="meta"
|
|
29
30
|
:store="store"
|
|
31
|
+
:nested="nested"
|
|
30
32
|
:path="createPath"
|
|
31
33
|
:verb="verbs.create"
|
|
32
34
|
:text="createButtonText"
|
|
@@ -43,10 +45,12 @@ DitoButtons.dito-edit-buttons.dito-buttons-round(
|
|
|
43
45
|
|
|
44
46
|
<script>
|
|
45
47
|
import DitoComponent from '../DitoComponent.js'
|
|
48
|
+
import ContextMixin from '../mixins/ContextMixin.js'
|
|
46
49
|
import { capitalize } from '@ditojs/utils'
|
|
47
50
|
|
|
48
51
|
// @vue/component
|
|
49
52
|
export default DitoComponent.component('DitoEditButtons', {
|
|
53
|
+
mixins: [ContextMixin],
|
|
50
54
|
emits: ['delete'],
|
|
51
55
|
|
|
52
56
|
props: {
|
|
@@ -56,6 +60,7 @@ export default DitoComponent.component('DitoEditButtons', {
|
|
|
56
60
|
data: { type: [Object, Array], default: null },
|
|
57
61
|
meta: { type: Object, required: true },
|
|
58
62
|
store: { type: Object, required: true },
|
|
63
|
+
nested: { type: Boolean, default: false },
|
|
59
64
|
disabled: { type: Boolean, required: true },
|
|
60
65
|
draggable: { type: Boolean, default: false },
|
|
61
66
|
editable: { type: Boolean, default: false },
|
|
@@ -43,11 +43,14 @@
|
|
|
43
43
|
|
|
44
44
|
<script>
|
|
45
45
|
import DitoComponent from '../DitoComponent.js'
|
|
46
|
+
import ContextMixin from '../mixins/ContextMixin.js'
|
|
46
47
|
import { appendDataPath } from '../utils/data.js'
|
|
47
48
|
import { isNested } from '../utils/schema.js'
|
|
48
49
|
|
|
49
50
|
// @vue/component
|
|
50
51
|
export default DitoComponent.component('DitoPane', {
|
|
52
|
+
mixins: [ContextMixin],
|
|
53
|
+
|
|
51
54
|
provide() {
|
|
52
55
|
return {
|
|
53
56
|
$tabComponent: () => this.tabComponent
|
|
@@ -75,6 +78,11 @@ export default DitoComponent.component('DitoPane', {
|
|
|
75
78
|
},
|
|
76
79
|
|
|
77
80
|
computed: {
|
|
81
|
+
nested() {
|
|
82
|
+
// For `ContextMixin`:
|
|
83
|
+
return false
|
|
84
|
+
},
|
|
85
|
+
|
|
78
86
|
classes() {
|
|
79
87
|
return {
|
|
80
88
|
'dito-pane--single': this.isSingleComponent,
|
|
@@ -43,13 +43,14 @@ component.dito-panel(
|
|
|
43
43
|
<script>
|
|
44
44
|
import { isFunction } from '@ditojs/utils'
|
|
45
45
|
import DitoComponent from '../DitoComponent.js'
|
|
46
|
+
import ContextMixin from '../mixins/ContextMixin.js'
|
|
46
47
|
import ValidatorMixin from '../mixins/ValidatorMixin.js'
|
|
47
48
|
import { getButtonSchemas } from '../utils/schema.js'
|
|
48
49
|
import { getSchemaAccessor } from '../utils/accessor.js'
|
|
49
50
|
|
|
50
51
|
// @vue/component
|
|
51
52
|
export default DitoComponent.component('DitoPanel', {
|
|
52
|
-
mixins: [ValidatorMixin],
|
|
53
|
+
mixins: [ContextMixin, ValidatorMixin],
|
|
53
54
|
|
|
54
55
|
provide() {
|
|
55
56
|
return {
|
|
@@ -75,6 +76,11 @@ export default DitoComponent.component('DitoPanel', {
|
|
|
75
76
|
},
|
|
76
77
|
|
|
77
78
|
computed: {
|
|
79
|
+
nested() {
|
|
80
|
+
// For `ContextMixin`:
|
|
81
|
+
return true
|
|
82
|
+
},
|
|
83
|
+
|
|
78
84
|
panelComponent() {
|
|
79
85
|
return this
|
|
80
86
|
},
|
|
@@ -20,9 +20,12 @@
|
|
|
20
20
|
|
|
21
21
|
<script>
|
|
22
22
|
import DitoComponent from '../DitoComponent.js'
|
|
23
|
+
import ContextMixin from '../mixins/ContextMixin.js'
|
|
23
24
|
|
|
24
25
|
// @vue/component
|
|
25
26
|
export default DitoComponent.component('DitoPanels', {
|
|
27
|
+
mixins: [ContextMixin],
|
|
28
|
+
|
|
26
29
|
props: {
|
|
27
30
|
panels: { type: Array, default: null },
|
|
28
31
|
data: { type: Object, required: true },
|
|
@@ -31,6 +34,13 @@ export default DitoComponent.component('DitoPanels', {
|
|
|
31
34
|
disabled: { type: Boolean, required: true }
|
|
32
35
|
},
|
|
33
36
|
|
|
37
|
+
computed: {
|
|
38
|
+
nested() {
|
|
39
|
+
// For `ContextMixin`:
|
|
40
|
+
return false
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
|
|
34
44
|
methods: {
|
|
35
45
|
getPanelKey(dataPath, tabComponent) {
|
|
36
46
|
// Allow separate tabs to use panels of the same name, by
|
|
@@ -115,8 +115,9 @@ import {
|
|
|
115
115
|
} from '@ditojs/utils'
|
|
116
116
|
import { TransitionHeight } from '@ditojs/ui/src'
|
|
117
117
|
import DitoComponent from '../DitoComponent.js'
|
|
118
|
+
import ContextMixin from '../mixins/ContextMixin.js'
|
|
118
119
|
import ItemMixin from '../mixins/ItemMixin.js'
|
|
119
|
-
import { appendDataPath
|
|
120
|
+
import { appendDataPath } from '../utils/data.js'
|
|
120
121
|
import {
|
|
121
122
|
getNamedSchemas,
|
|
122
123
|
getPanelEntries,
|
|
@@ -129,7 +130,7 @@ import { getSchemaAccessor, getStoreAccessor } from '../utils/accessor.js'
|
|
|
129
130
|
|
|
130
131
|
// @vue/component
|
|
131
132
|
export default DitoComponent.component('DitoSchema', {
|
|
132
|
-
mixins: [ItemMixin],
|
|
133
|
+
mixins: [ContextMixin, ItemMixin],
|
|
133
134
|
components: { TransitionHeight },
|
|
134
135
|
inheritAttrs: false,
|
|
135
136
|
|
|
@@ -184,6 +185,11 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
184
185
|
},
|
|
185
186
|
|
|
186
187
|
computed: {
|
|
188
|
+
nested() {
|
|
189
|
+
// For `ContextMixin`:
|
|
190
|
+
return false
|
|
191
|
+
},
|
|
192
|
+
|
|
187
193
|
schemaComponent() {
|
|
188
194
|
// Override DitoMixin's schemaComponent() which uses the injected value.
|
|
189
195
|
return this
|
|
@@ -236,11 +242,7 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
236
242
|
: this.labelNode
|
|
237
243
|
},
|
|
238
244
|
|
|
239
|
-
|
|
240
|
-
const data = getParentItem(this.rootData, this.dataPath, false)
|
|
241
|
-
return data !== this.data ? data : null
|
|
242
|
-
},
|
|
243
|
-
|
|
245
|
+
// @override
|
|
244
246
|
processedData() {
|
|
245
247
|
// TODO: Fix side-effects
|
|
246
248
|
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
|
@@ -259,28 +261,6 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
259
261
|
}
|
|
260
262
|
},
|
|
261
263
|
|
|
262
|
-
// The following computed properties are similar to `DitoContext`
|
|
263
|
-
// properties, so that we can access these on `this` as well:
|
|
264
|
-
// NOTE: While internally, we speak of `data`, in the API surface the
|
|
265
|
-
// term `item` is used for the data that relates to editing objects.
|
|
266
|
-
// NOTE: This should always return the same as:
|
|
267
|
-
// return getItem(this.rootData, this.dataPath, false)
|
|
268
|
-
item() {
|
|
269
|
-
return this.data
|
|
270
|
-
},
|
|
271
|
-
|
|
272
|
-
parentItem() {
|
|
273
|
-
return this.parentData
|
|
274
|
-
},
|
|
275
|
-
|
|
276
|
-
rootItem() {
|
|
277
|
-
return this.rootData
|
|
278
|
-
},
|
|
279
|
-
|
|
280
|
-
processedItem() {
|
|
281
|
-
return this.processedData
|
|
282
|
-
},
|
|
283
|
-
|
|
284
264
|
clipboardItem() {
|
|
285
265
|
return this.clipboardData
|
|
286
266
|
},
|
|
@@ -24,11 +24,14 @@ td(
|
|
|
24
24
|
<script>
|
|
25
25
|
import DitoComponent from '../DitoComponent.js'
|
|
26
26
|
import DitoContext from '../DitoContext.js'
|
|
27
|
+
import ContextMixin from '../mixins/ContextMixin.js'
|
|
27
28
|
import { appendDataPath } from '../utils/data.js'
|
|
28
29
|
import { escapeHtml } from '@ditojs/utils'
|
|
29
30
|
|
|
30
31
|
// @vue/component
|
|
31
32
|
export default DitoComponent.component('DitoTableCell', {
|
|
33
|
+
mixins: [ContextMixin],
|
|
34
|
+
|
|
32
35
|
props: {
|
|
33
36
|
cell: { type: Object, required: true },
|
|
34
37
|
schema: { type: Object, required: true },
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import DitoContext from '../DitoContext.js'
|
|
2
|
+
import { getItem, getParentItem } from '../utils/data.js'
|
|
3
|
+
|
|
4
|
+
// @vue/component
|
|
5
|
+
export default {
|
|
6
|
+
computed: {
|
|
7
|
+
context() {
|
|
8
|
+
return new DitoContext(this, { nested: this.nested })
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
// The following computed properties are similar to `DitoContext`
|
|
12
|
+
// properties, so that we can access these on `this` as well:
|
|
13
|
+
// NOTE: While internally, we speak of `data`, in the API surface the
|
|
14
|
+
// term `item` is used for the data that relates to editing objects.
|
|
15
|
+
// NOTE: This should always return the same as:
|
|
16
|
+
// return getItem(this.rootData, this.dataPath, false)
|
|
17
|
+
parentData() {
|
|
18
|
+
const data = getParentItem(this.rootData, this.dataPath, this.nested)
|
|
19
|
+
return data !== this.data ? data : null
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
// @overridable
|
|
23
|
+
processedData() {
|
|
24
|
+
return getProcessedParentData(this, this.dataPath, this.nested)
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
processedRootData() {
|
|
28
|
+
return getProcessedParentData(this, '', false)
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
item() {
|
|
32
|
+
return this.data
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
parentItem() {
|
|
36
|
+
return this.parentData
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
rootItem() {
|
|
40
|
+
return this.rootData
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
processedItem() {
|
|
44
|
+
return this.processedData
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
processedRootItem() {
|
|
48
|
+
return this.processedRootData
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getProcessedParentData(component, dataPath, nested = false) {
|
|
54
|
+
// We can only get the processed data through the schemaComponent, but
|
|
55
|
+
// that's not necessarily the item represented by this component.
|
|
56
|
+
// Solution: Find the relative path and the processed sub-item from there:
|
|
57
|
+
let { schemaComponent } = component
|
|
58
|
+
// Find the schema component that contains the desired data-path:
|
|
59
|
+
while (schemaComponent.dataPath.length > dataPath.length) {
|
|
60
|
+
schemaComponent = schemaComponent.parentSchemaComponent
|
|
61
|
+
}
|
|
62
|
+
return getItem(
|
|
63
|
+
schemaComponent.processedData,
|
|
64
|
+
// Get the dataPath relative to the schemaComponent's data:
|
|
65
|
+
dataPath.slice(schemaComponent.dataPath.length),
|
|
66
|
+
nested
|
|
67
|
+
)
|
|
68
|
+
}
|
package/src/mixins/TypeMixin.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ValueMixin from './ValueMixin.js'
|
|
2
|
+
import ContextMixin from './ContextMixin.js'
|
|
2
3
|
import ValidationMixin from './ValidationMixin.js'
|
|
3
4
|
import { getSchemaAccessor } from '../utils/accessor.js'
|
|
4
|
-
import { computeValue } from '../utils/schema.js'
|
|
5
|
-
import { getItem, getParentItem } from '../utils/data.js'
|
|
6
5
|
import { asArray, camelize } from '@ditojs/utils'
|
|
7
6
|
|
|
8
7
|
// @vue/component
|
|
9
8
|
export default {
|
|
10
|
-
mixins: [ValidationMixin],
|
|
9
|
+
mixins: [ValueMixin, ContextMixin, ValidationMixin],
|
|
11
10
|
|
|
12
11
|
props: {
|
|
13
12
|
schema: { type: Object, required: true },
|
|
@@ -41,71 +40,6 @@ export default {
|
|
|
41
40
|
return this.schema.type
|
|
42
41
|
},
|
|
43
42
|
|
|
44
|
-
context() {
|
|
45
|
-
return new DitoContext(this, { nested: this.nested })
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
value: {
|
|
49
|
-
get() {
|
|
50
|
-
const value = computeValue(
|
|
51
|
-
this.schema,
|
|
52
|
-
this.data,
|
|
53
|
-
this.name,
|
|
54
|
-
this.dataPath,
|
|
55
|
-
{ component: this }
|
|
56
|
-
)
|
|
57
|
-
const { format } = this.schema
|
|
58
|
-
return format
|
|
59
|
-
? format(new DitoContext(this, { value }))
|
|
60
|
-
: value
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
set(value) {
|
|
64
|
-
const { parse } = this.schema
|
|
65
|
-
if (parse) {
|
|
66
|
-
value = parse(new DitoContext(this, { value }))
|
|
67
|
-
}
|
|
68
|
-
this.parsedValue = value
|
|
69
|
-
// eslint-disable-next-line vue/no-mutating-props
|
|
70
|
-
this.data[this.name] = value
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
parentData() {
|
|
75
|
-
const data = getParentItem(this.rootData, this.dataPath, this.nested)
|
|
76
|
-
return data !== this.data ? data : null
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
processedData() {
|
|
80
|
-
return getProcessedParentData(this, this.dataPath, this.nested)
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
processedRootData() {
|
|
84
|
-
return getProcessedParentData(this, '', false)
|
|
85
|
-
},
|
|
86
|
-
|
|
87
|
-
// The following computed properties are similar to `DitoContext`
|
|
88
|
-
// properties, so that we can access these on `this` as well:
|
|
89
|
-
item() {
|
|
90
|
-
return this.data
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
parentItem() {
|
|
94
|
-
return this.parentData
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
rootItem() {
|
|
98
|
-
return this.rootData
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
processedItem() {
|
|
102
|
-
return this.processedData
|
|
103
|
-
},
|
|
104
|
-
|
|
105
|
-
processedRootItem() {
|
|
106
|
-
return this.processedRootData
|
|
107
|
-
},
|
|
108
|
-
|
|
109
43
|
labelNode() {
|
|
110
44
|
const node = this.isMounted ? this.$el.previousElementSibling : null
|
|
111
45
|
return node?.matches('.dito-label') ? node : null
|
|
@@ -326,20 +260,3 @@ export default {
|
|
|
326
260
|
}
|
|
327
261
|
}
|
|
328
262
|
}
|
|
329
|
-
|
|
330
|
-
function getProcessedParentData(component, dataPath, nested = false) {
|
|
331
|
-
// We can only get the processed data through the schemaComponent, but
|
|
332
|
-
// that's not necessarily the item represented by this component.
|
|
333
|
-
// Solution: Find the relative path and the processed sub-item from there:
|
|
334
|
-
let { schemaComponent } = component
|
|
335
|
-
// Find the schema component that contains the desired data-path:
|
|
336
|
-
while (schemaComponent.dataPath.length > dataPath.length) {
|
|
337
|
-
schemaComponent = schemaComponent.parentSchemaComponent
|
|
338
|
-
}
|
|
339
|
-
return getItem(
|
|
340
|
-
schemaComponent.processedData,
|
|
341
|
-
// Get the dataPath relative to the schemaComponent's data:
|
|
342
|
-
dataPath.slice(schemaComponent.dataPath.length),
|
|
343
|
-
nested
|
|
344
|
-
)
|
|
345
|
-
}
|