@ditojs/admin 2.26.2 → 2.27.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 +1628 -1570
- package/dist/dito-admin.umd.js +5 -5
- package/package.json +5 -5
- package/src/DitoAdmin.js +1 -3
- package/src/components/DitoForm.vue +17 -12
- package/src/components/DitoSchema.vue +25 -15
- package/src/components/DitoView.vue +1 -1
- package/src/mixins/DataMixin.js +10 -3
- package/src/mixins/DitoMixin.js +22 -10
- package/src/mixins/OptionsMixin.js +1 -1
- package/src/mixins/ResourceMixin.js +19 -9
- package/src/mixins/SourceMixin.js +29 -15
- package/src/mixins/TextMixin.js +3 -2
- package/src/types/DitoTypeComponent.vue +1 -1
- package/src/types/DitoTypeDate.vue +1 -1
- package/src/types/DitoTypeSection.vue +1 -1
- package/src/types/DitoTypeText.vue +1 -1
- package/src/types/DitoTypeUpload.vue +1 -1
- package/src/utils/resource.js +4 -1
- package/src/utils/schema.js +54 -45
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/admin",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.27.0",
|
|
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,8 +33,8 @@
|
|
|
33
33
|
"not ie_mob > 0"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@ditojs/ui": "^2.
|
|
37
|
-
"@ditojs/utils": "^2.
|
|
36
|
+
"@ditojs/ui": "^2.27.0",
|
|
37
|
+
"@ditojs/utils": "^2.27.0",
|
|
38
38
|
"@kyvg/vue3-notification": "^3.2.1",
|
|
39
39
|
"@lk77/vue3-color": "^3.0.6",
|
|
40
40
|
"@tiptap/core": "^2.3.0",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"vue-upload-component": "^3.1.15"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
-
"@ditojs/build": "^2.
|
|
77
|
+
"@ditojs/build": "^2.27.0",
|
|
78
78
|
"@vitejs/plugin-vue": "^5.0.4",
|
|
79
79
|
"@vue/compiler-sfc": "3.4.21",
|
|
80
80
|
"pug": "^3.0.2",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"vite": "^5.2.8"
|
|
84
84
|
},
|
|
85
85
|
"types": "types",
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "e80d56a1887faa60f61f4c642502687d50ead333",
|
|
87
87
|
"scripts": {
|
|
88
88
|
"build": "vite build",
|
|
89
89
|
"watch": "yarn build --mode 'development' --watch",
|
package/src/DitoAdmin.js
CHANGED
|
@@ -124,9 +124,7 @@ export default class DitoAdmin {
|
|
|
124
124
|
},
|
|
125
125
|
|
|
126
126
|
member(resource) {
|
|
127
|
-
|
|
128
|
-
// to avoid excessive nesting of (sub-)collection routes.
|
|
129
|
-
return `${resource.path}/${resource.id}`
|
|
127
|
+
return `${this.default(resource)}/${resource.id}`
|
|
130
128
|
},
|
|
131
129
|
|
|
132
130
|
upload(resource) {
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
//- nested form route, which will appear elsewhere in its own view.
|
|
8
8
|
RouterView(
|
|
9
9
|
v-if="!isLastUnnestedRoute && !isNestedRoute"
|
|
10
|
-
v-show="!
|
|
10
|
+
v-show="!isActiveRoute"
|
|
11
11
|
)
|
|
12
12
|
//- NOTE: Nested form components are kept alive by using `v-show` instead of
|
|
13
13
|
//- `v-if` here, so event handling and other things still work with nested
|
|
14
14
|
//- editing.
|
|
15
15
|
DitoFormInner(
|
|
16
|
-
v-show="
|
|
16
|
+
v-show="isActiveRoute"
|
|
17
17
|
:nested="isNestedRoute"
|
|
18
18
|
)
|
|
19
19
|
//- Prevent implicit submission of the form, for example when typing enter
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
:meta="meta"
|
|
32
32
|
:store="store"
|
|
33
33
|
:padding="isNestedRoute ? 'nested' : 'root'"
|
|
34
|
+
:active="isActiveRoute"
|
|
34
35
|
:disabled="isLoading"
|
|
35
36
|
:scrollable="!isNestedRoute"
|
|
36
37
|
generateLabels
|
|
@@ -125,7 +126,7 @@ export default DitoComponent.component('DitoForm', {
|
|
|
125
126
|
)
|
|
126
127
|
},
|
|
127
128
|
|
|
128
|
-
|
|
129
|
+
isActiveRoute() {
|
|
129
130
|
return this.isLastRoute || this.isLastUnnestedRoute
|
|
130
131
|
},
|
|
131
132
|
|
|
@@ -168,11 +169,6 @@ export default DitoComponent.component('DitoForm', {
|
|
|
168
169
|
return this.isCreating ? 'post' : 'patch'
|
|
169
170
|
},
|
|
170
171
|
|
|
171
|
-
resource() {
|
|
172
|
-
const resource = this.getResource()
|
|
173
|
-
return getMemberResource(this.itemId, resource) || resource
|
|
174
|
-
},
|
|
175
|
-
|
|
176
172
|
breadcrumbPrefix() {
|
|
177
173
|
return capitalize(this.isCreating ? this.verbs.create : this.verbs.edit)
|
|
178
174
|
},
|
|
@@ -325,6 +321,12 @@ export default DitoComponent.component('DitoForm', {
|
|
|
325
321
|
)
|
|
326
322
|
},
|
|
327
323
|
|
|
324
|
+
// @override ResourceMixin.getResource()
|
|
325
|
+
getResource(defaults) {
|
|
326
|
+
const resource = ResourceMixin.methods.getResource.call(this, defaults)
|
|
327
|
+
return getMemberResource(this.itemId, resource) || resource
|
|
328
|
+
},
|
|
329
|
+
|
|
328
330
|
// @override ResourceMixin.setupData()
|
|
329
331
|
setupData() {
|
|
330
332
|
if (this.isCreating) {
|
|
@@ -337,7 +339,8 @@ export default DitoComponent.component('DitoForm', {
|
|
|
337
339
|
setSourceData(data) {
|
|
338
340
|
if (this.sourceData && this.sourceKey !== null) {
|
|
339
341
|
const { mainSchemaComponent } = this
|
|
340
|
-
this.sourceData[this.sourceKey] =
|
|
342
|
+
this.sourceData[this.sourceKey] =
|
|
343
|
+
mainSchemaComponent.filterData(data).localData
|
|
341
344
|
mainSchemaComponent.onChange()
|
|
342
345
|
return true
|
|
343
346
|
}
|
|
@@ -400,11 +403,13 @@ export default DitoComponent.component('DitoForm', {
|
|
|
400
403
|
const getVerb = present => this.verbs[this.getSubmitVerb(present)]
|
|
401
404
|
|
|
402
405
|
// Allow buttons to override both method and resource path to submit to:
|
|
406
|
+
let { method } = this
|
|
407
|
+
let resource = this.getResource({ method })
|
|
403
408
|
const buttonResource = getResource(button.schema.resource, {
|
|
404
|
-
parent:
|
|
409
|
+
parent: resource
|
|
405
410
|
})
|
|
406
|
-
|
|
407
|
-
|
|
411
|
+
resource = buttonResource || resource
|
|
412
|
+
method = resource?.method || method
|
|
408
413
|
const data = this.getPayloadData(button, method)
|
|
409
414
|
let success
|
|
410
415
|
if (!buttonResource && this.isTransient) {
|
|
@@ -9,6 +9,7 @@ slot(name="before")
|
|
|
9
9
|
to=".dito-sidebar__teleport"
|
|
10
10
|
)
|
|
11
11
|
DitoPanels(
|
|
12
|
+
v-if="active"
|
|
12
13
|
:panels="panelEntries"
|
|
13
14
|
:data="data"
|
|
14
15
|
:meta="meta"
|
|
@@ -20,7 +21,9 @@ slot(name="before")
|
|
|
20
21
|
:to="headerTeleport"
|
|
21
22
|
:disabled="!headerTeleport"
|
|
22
23
|
)
|
|
23
|
-
.dito-schema-header
|
|
24
|
+
.dito-schema-header(
|
|
25
|
+
v-if="active"
|
|
26
|
+
)
|
|
24
27
|
DitoLabel(
|
|
25
28
|
v-if="hasLabel"
|
|
26
29
|
:label="label"
|
|
@@ -119,7 +122,8 @@ import {
|
|
|
119
122
|
getPanelEntries,
|
|
120
123
|
setDefaultValues,
|
|
121
124
|
processData,
|
|
122
|
-
isEmptySchema
|
|
125
|
+
isEmptySchema,
|
|
126
|
+
isNested
|
|
123
127
|
} from '../utils/schema.js'
|
|
124
128
|
import { getSchemaAccessor, getStoreAccessor } from '../utils/accessor.js'
|
|
125
129
|
|
|
@@ -147,6 +151,7 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
147
151
|
store: { type: Object, default: () => ({}) },
|
|
148
152
|
label: { type: [String, Object], default: null },
|
|
149
153
|
padding: { type: String, default: null },
|
|
154
|
+
active: { type: Boolean, default: true },
|
|
150
155
|
inlined: { type: Boolean, default: false },
|
|
151
156
|
disabled: { type: Boolean, default: false },
|
|
152
157
|
collapsed: { type: Boolean, default: false },
|
|
@@ -223,7 +228,7 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
223
228
|
},
|
|
224
229
|
|
|
225
230
|
headerTeleport() {
|
|
226
|
-
return this.
|
|
231
|
+
return this.isTopLevelSchema
|
|
227
232
|
? '.dito-header__teleport'
|
|
228
233
|
: this.labelNode
|
|
229
234
|
},
|
|
@@ -283,9 +288,8 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
283
288
|
)
|
|
284
289
|
},
|
|
285
290
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
return this.dataPath === '' && !this.inlined
|
|
291
|
+
isNested() {
|
|
292
|
+
return isNested(this.schema)
|
|
289
293
|
},
|
|
290
294
|
|
|
291
295
|
isDirty() {
|
|
@@ -320,8 +324,12 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
320
324
|
return !!this.tabs
|
|
321
325
|
},
|
|
322
326
|
|
|
323
|
-
|
|
324
|
-
return this.
|
|
327
|
+
isTopLevelSchema() {
|
|
328
|
+
return !this.isNested && !this.inlined
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
hasTopLevelTabs() {
|
|
332
|
+
return this.hasTabs && this.isTopLevelSchema
|
|
325
333
|
},
|
|
326
334
|
|
|
327
335
|
hasMainPane() {
|
|
@@ -385,7 +393,7 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
385
393
|
// Remember the current path to know if tab changes should still be
|
|
386
394
|
// handled, but remove the trailing `/create` or `/:id` from it so that
|
|
387
395
|
// tabs informs that stay open after creation still work.
|
|
388
|
-
if (this.
|
|
396
|
+
if (this.hasTopLevelTabs) {
|
|
389
397
|
this.selectedTab = routeTab
|
|
390
398
|
}
|
|
391
399
|
}
|
|
@@ -399,7 +407,7 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
399
407
|
content.scrollTop = this.scrollPositions[newTab] ?? 0
|
|
400
408
|
})
|
|
401
409
|
}
|
|
402
|
-
if (this.
|
|
410
|
+
if (this.hasTopLevelTabs) {
|
|
403
411
|
const tab = this.shouldRenderSchema(this.tabs[newTab])
|
|
404
412
|
? newTab
|
|
405
413
|
: this.defaultTab
|
|
@@ -687,20 +695,22 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
687
695
|
},
|
|
688
696
|
|
|
689
697
|
filterData(data) {
|
|
690
|
-
// Filters out arrays and objects that are
|
|
691
|
-
// themselves, as those are already
|
|
698
|
+
// Filters out arrays and objects that are backed by data resources
|
|
699
|
+
// themselves, as those are already taken care of through their own API
|
|
692
700
|
// resource end-points and shouldn't be set.
|
|
693
|
-
const
|
|
701
|
+
const localData = {}
|
|
702
|
+
const foreignData = {}
|
|
694
703
|
for (const [name, value] of Object.entries(data)) {
|
|
695
704
|
if (isArray(value) || isObject(value)) {
|
|
696
705
|
const components = this.getComponentsByName(name)
|
|
697
706
|
if (components.some(component => component.providesData)) {
|
|
707
|
+
foreignData[name] = value
|
|
698
708
|
continue
|
|
699
709
|
}
|
|
700
710
|
}
|
|
701
|
-
|
|
711
|
+
localData[name] = value
|
|
702
712
|
}
|
|
703
|
-
return
|
|
713
|
+
return { localData, foreignData }
|
|
704
714
|
},
|
|
705
715
|
|
|
706
716
|
processData({ target = 'clipboard', schemaOnly = true } = {}) {
|
package/src/mixins/DataMixin.js
CHANGED
|
@@ -109,15 +109,22 @@ export default {
|
|
|
109
109
|
async resolveData(load, loadingOptions = {}) {
|
|
110
110
|
// Use a timeout to allow already resolved promises to return data without
|
|
111
111
|
// showing a loading indicator.
|
|
112
|
-
|
|
112
|
+
let clearLoading = false
|
|
113
|
+
const timer = setTimeout(() => {
|
|
114
|
+
this.setLoading(true, loadingOptions)
|
|
115
|
+
clearLoading = true
|
|
116
|
+
}, 0)
|
|
113
117
|
let data = null
|
|
114
118
|
try {
|
|
115
119
|
data = await (isFunction(load) ? load() : load)
|
|
116
120
|
} catch (error) {
|
|
117
121
|
this.addError(error.message || error)
|
|
118
122
|
}
|
|
119
|
-
|
|
120
|
-
|
|
123
|
+
if (clearLoading) {
|
|
124
|
+
this.setLoading(false, loadingOptions)
|
|
125
|
+
} else {
|
|
126
|
+
clearTimeout(timer)
|
|
127
|
+
}
|
|
121
128
|
return data
|
|
122
129
|
}
|
|
123
130
|
}
|
package/src/mixins/DitoMixin.js
CHANGED
|
@@ -155,15 +155,19 @@ export default {
|
|
|
155
155
|
},
|
|
156
156
|
|
|
157
157
|
parentSchemaComponent() {
|
|
158
|
-
return this
|
|
158
|
+
return getParentComponent(this, 'schemaComponent')
|
|
159
159
|
},
|
|
160
160
|
|
|
161
161
|
parentRouteComponent() {
|
|
162
|
-
return this
|
|
162
|
+
return getParentComponent(this, 'routeComponent')
|
|
163
163
|
},
|
|
164
164
|
|
|
165
165
|
parentFormComponent() {
|
|
166
|
-
return this
|
|
166
|
+
return getParentComponent(this, 'formComponent')
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
parentResourceComponent() {
|
|
170
|
+
return getParentComponent(this, 'resourceComponent')
|
|
167
171
|
},
|
|
168
172
|
|
|
169
173
|
// Returns the data of the first route component in the chain of parents
|
|
@@ -307,13 +311,12 @@ export default {
|
|
|
307
311
|
},
|
|
308
312
|
|
|
309
313
|
getResourcePath(resource) {
|
|
310
|
-
resource = getResource(resource
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
return this.api.resources.any(getResource(resource))
|
|
314
|
+
resource = getResource(resource, {
|
|
315
|
+
// Resources without a parent inherit the one from `dataComponent`
|
|
316
|
+
// automatically.
|
|
317
|
+
parent: this.dataComponent?.resource ?? null
|
|
318
|
+
})
|
|
319
|
+
return this.api.resources.any(resource)
|
|
317
320
|
},
|
|
318
321
|
|
|
319
322
|
getResourceUrl(resource) {
|
|
@@ -574,3 +577,12 @@ export default {
|
|
|
574
577
|
}
|
|
575
578
|
|
|
576
579
|
let nextUid = 0
|
|
580
|
+
|
|
581
|
+
function getParentComponent(component, key) {
|
|
582
|
+
const current = component[key]
|
|
583
|
+
let parent = component.parentComponent
|
|
584
|
+
while (parent && parent[key] === current) {
|
|
585
|
+
parent = parent.parentComponent
|
|
586
|
+
}
|
|
587
|
+
return parent?.[key] ?? null
|
|
588
|
+
}
|
|
@@ -260,7 +260,7 @@ export default {
|
|
|
260
260
|
}
|
|
261
261
|
},
|
|
262
262
|
|
|
263
|
-
processValue(schema, value, dataPath, graph) {
|
|
263
|
+
processValue({ schema, value, dataPath }, graph) {
|
|
264
264
|
if (schema.relate) {
|
|
265
265
|
// For internally relating data (`schema.options.dataPath`), we need to
|
|
266
266
|
// process both the options (for '#ref') and the value ('#id').
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ItemMixin from './ItemMixin.js'
|
|
2
2
|
import LoadingMixin from './LoadingMixin.js'
|
|
3
3
|
import { setDefaultValues } from '../utils/schema.js'
|
|
4
|
-
import { isObject, isString, labelize } from '@ditojs/utils'
|
|
4
|
+
import { assignDeeply, isObject, isString, labelize } from '@ditojs/utils'
|
|
5
5
|
import { getResource } from '../utils/resource.js'
|
|
6
6
|
import DitoContext from '../DitoContext.js'
|
|
7
7
|
|
|
@@ -31,8 +31,6 @@ export default {
|
|
|
31
31
|
},
|
|
32
32
|
|
|
33
33
|
resource() {
|
|
34
|
-
// Returns the resource object representing the resource for the
|
|
35
|
-
// associated source schema.
|
|
36
34
|
return this.getResource()
|
|
37
35
|
},
|
|
38
36
|
|
|
@@ -126,12 +124,13 @@ export default {
|
|
|
126
124
|
},
|
|
127
125
|
|
|
128
126
|
methods: {
|
|
129
|
-
getResource() {
|
|
130
|
-
//
|
|
131
|
-
//
|
|
127
|
+
getResource(defaults = { method: 'get' }) {
|
|
128
|
+
// Returns the resource object representing the resource for the
|
|
129
|
+
// associated source schema.
|
|
132
130
|
return getResource(this.sourceSchema?.resource, {
|
|
133
131
|
type: 'collection',
|
|
134
|
-
parent: this.
|
|
132
|
+
parent: this.parentResourceComponent?.resource ?? null,
|
|
133
|
+
...defaults
|
|
135
134
|
})
|
|
136
135
|
},
|
|
137
136
|
|
|
@@ -230,7 +229,7 @@ export default {
|
|
|
230
229
|
async handleRequest(
|
|
231
230
|
{
|
|
232
231
|
method,
|
|
233
|
-
resource = this.
|
|
232
|
+
resource = this.getResource({ method }),
|
|
234
233
|
query,
|
|
235
234
|
data
|
|
236
235
|
},
|
|
@@ -244,6 +243,7 @@ export default {
|
|
|
244
243
|
const controller = new AbortController()
|
|
245
244
|
this.abortController = controller
|
|
246
245
|
const { signal } = controller
|
|
246
|
+
method = resource.method || method
|
|
247
247
|
const request = { method, resource, query, data, signal }
|
|
248
248
|
this.setLoading(true, loadingOptions)
|
|
249
249
|
try {
|
|
@@ -340,7 +340,17 @@ export default {
|
|
|
340
340
|
// Update the underlying data before calling `notify()` or
|
|
341
341
|
// `this.itemLabel`, so id is set after creating new items.
|
|
342
342
|
if (setData && data) {
|
|
343
|
-
|
|
343
|
+
// Preserve the foreign data entries when updating the data.
|
|
344
|
+
const { foreignData } = this.mainSchemaComponent.filterData(
|
|
345
|
+
this.data
|
|
346
|
+
)
|
|
347
|
+
// Tell the parent route to reload its data, so that it can
|
|
348
|
+
// update its foreign data entries.
|
|
349
|
+
const parentMeta = this.parentRouteComponent?.routeRecord?.meta
|
|
350
|
+
if (parentMeta) {
|
|
351
|
+
parentMeta.reload = true
|
|
352
|
+
}
|
|
353
|
+
this.setData(assignDeeply({}, foreignData, data))
|
|
344
354
|
}
|
|
345
355
|
onSuccess?.()
|
|
346
356
|
await this.emitButtonEvent(button, 'success', {
|
|
@@ -33,9 +33,9 @@ import { raw } from '@ditojs/ui'
|
|
|
33
33
|
export default {
|
|
34
34
|
mixins: [ItemMixin, ResourceMixin, SchemaParentMixin],
|
|
35
35
|
|
|
36
|
-
defaultValue(schema)
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
defaultValue: context => (isListSource(context.schema) ? [] : null),
|
|
37
|
+
// Exclude all sources that have their own resource handling the data.
|
|
38
|
+
excludeValue: context => !!context.schema.resource,
|
|
39
39
|
|
|
40
40
|
provide() {
|
|
41
41
|
return {
|
|
@@ -321,15 +321,25 @@ export default {
|
|
|
321
321
|
// https://github.com/vuejs/vue-router/issues/3393#issuecomment-1158470149
|
|
322
322
|
flush: 'post',
|
|
323
323
|
handler(to, from) {
|
|
324
|
-
if (
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
324
|
+
if (this.providesData) {
|
|
325
|
+
if (
|
|
326
|
+
from.path === to.path &&
|
|
327
|
+
from.hash === to.hash
|
|
328
|
+
) {
|
|
329
|
+
// Paths and hashes remain the same, so only queries have changed.
|
|
330
|
+
// Update filter and reload data without clearing.
|
|
331
|
+
this.query = to.query
|
|
332
|
+
this.loadData(false)
|
|
333
|
+
} else if (
|
|
334
|
+
this.meta.reload &&
|
|
335
|
+
from.path !== to.path &&
|
|
336
|
+
from.path.startsWith(to.path)
|
|
337
|
+
) {
|
|
338
|
+
// Reload the source when navigating back to a parent-route after
|
|
339
|
+
// changing data in a child-route.
|
|
340
|
+
this.meta.reload = false
|
|
341
|
+
this.loadData(false)
|
|
342
|
+
}
|
|
333
343
|
}
|
|
334
344
|
}
|
|
335
345
|
},
|
|
@@ -464,9 +474,13 @@ export default {
|
|
|
464
474
|
notify()
|
|
465
475
|
} else {
|
|
466
476
|
const itemId = this.getItemId(this.schema, item, index)
|
|
467
|
-
const
|
|
477
|
+
const method = 'delete'
|
|
478
|
+
const resource = getMemberResource(
|
|
479
|
+
itemId,
|
|
480
|
+
this.getResource({ method })
|
|
481
|
+
)
|
|
468
482
|
if (resource) {
|
|
469
|
-
this.handleRequest({ method
|
|
483
|
+
this.handleRequest({ method, resource }, err => {
|
|
470
484
|
if (!err) {
|
|
471
485
|
this.removeItem(item, index)
|
|
472
486
|
notify()
|
|
@@ -666,7 +680,7 @@ export default {
|
|
|
666
680
|
}
|
|
667
681
|
},
|
|
668
682
|
|
|
669
|
-
processValue(schema, value, dataPath, graph) {
|
|
683
|
+
processValue({ schema, value, dataPath }, graph) {
|
|
670
684
|
graph.addSource(dataPath, schema)
|
|
671
685
|
return value
|
|
672
686
|
}
|
package/src/mixins/TextMixin.js
CHANGED
|
@@ -11,14 +11,15 @@ export default {
|
|
|
11
11
|
})
|
|
12
12
|
},
|
|
13
13
|
|
|
14
|
-
processValue(
|
|
14
|
+
processValue(context) {
|
|
15
|
+
let { schema, value } = context
|
|
15
16
|
if (schema.trim && value != null && isString(value)) {
|
|
16
17
|
// Text fields don't necessarily have a `String` value when `format()`
|
|
17
18
|
// without `parse()` is used.
|
|
18
19
|
value = value.trim()
|
|
19
20
|
}
|
|
20
21
|
if (value === '') {
|
|
21
|
-
value = getDefaultValue(schema)
|
|
22
|
+
value = getDefaultValue(schema, context)
|
|
22
23
|
}
|
|
23
24
|
return value
|
|
24
25
|
}
|
|
@@ -22,7 +22,7 @@ export default DitoTypeComponent.register('component', {
|
|
|
22
22
|
// Override the standard `defaultValue: null` to not set any data for custom
|
|
23
23
|
// components, unless they provide a default value.
|
|
24
24
|
defaultValue: () => undefined, // Callback to override `defaultValue: null`
|
|
25
|
-
ignoreMissingValue: schema => !('default' in schema),
|
|
25
|
+
ignoreMissingValue: ({ schema }) => !('default' in schema),
|
|
26
26
|
|
|
27
27
|
async processSchema(api, schema) {
|
|
28
28
|
await resolveSchemaComponent(schema)
|
|
@@ -23,7 +23,7 @@ import { getItemFormSchema, processSchemaComponents } from '../utils/schema.js'
|
|
|
23
23
|
// @vue/component
|
|
24
24
|
export default DitoTypeComponent.register('section', {
|
|
25
25
|
defaultValue: () => undefined, // Callback to override `defaultValue: null`
|
|
26
|
-
ignoreMissingValue: schema => !schema.nested && !('default' in schema),
|
|
26
|
+
ignoreMissingValue: ({ schema }) => !schema.nested && !('default' in schema),
|
|
27
27
|
defaultNested: false,
|
|
28
28
|
generateLabel: false,
|
|
29
29
|
|
|
@@ -38,7 +38,7 @@ export default DitoTypeComponent.register(
|
|
|
38
38
|
components: { InputField },
|
|
39
39
|
nativeField: true,
|
|
40
40
|
textField: true,
|
|
41
|
-
ignoreMissingValue: schema => schema.type === 'password',
|
|
41
|
+
ignoreMissingValue: ({ schema }) => schema.type === 'password',
|
|
42
42
|
|
|
43
43
|
computed: {
|
|
44
44
|
inputType() {
|
|
@@ -452,7 +452,7 @@ export default DitoTypeComponent.register('upload', {
|
|
|
452
452
|
}
|
|
453
453
|
},
|
|
454
454
|
|
|
455
|
-
processValue(schema, value) {
|
|
455
|
+
processValue({ schema, value }) {
|
|
456
456
|
// Filter out all newly added files that weren't actually uploaded.
|
|
457
457
|
const files = asFiles(value)
|
|
458
458
|
.map(({ upload, ...file }) => (!upload || upload.success ? file : null))
|
package/src/utils/resource.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isObject, isString, pickBy } from '@ditojs/utils'
|
|
1
|
+
import { isFunction, isObject, isString, pickBy } from '@ditojs/utils'
|
|
2
2
|
|
|
3
3
|
export function hasResource(schema) {
|
|
4
4
|
return !!getResource(schema.resource)
|
|
@@ -6,6 +6,9 @@ export function hasResource(schema) {
|
|
|
6
6
|
|
|
7
7
|
export function getResource(resource, defaults = {}) {
|
|
8
8
|
const { parent, ...defs } = defaults
|
|
9
|
+
if (isFunction(resource)) {
|
|
10
|
+
resource = resource(defaults)
|
|
11
|
+
}
|
|
9
12
|
resource = isObject(resource)
|
|
10
13
|
? { ...defs, ...resource }
|
|
11
14
|
: isString(resource)
|