@ditojs/admin 2.2.1 → 2.2.3
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 +1432 -1327
- package/dist/dito-admin.umd.js +4 -4
- package/dist/style.css +1 -1
- package/package.json +5 -5
- package/src/DitoAdmin.js +1 -23
- package/src/components/DitoMenu.vue +16 -4
- package/src/components/DitoPane.vue +2 -1
- package/src/components/DitoPanel.vue +72 -15
- package/src/components/DitoRoot.vue +10 -2
- package/src/components/DitoSchema.vue +6 -2
- package/src/mixins/DataMixin.js +4 -1
- package/src/mixins/DitoMixin.js +4 -5
- package/src/mixins/DomMixin.js +1 -1
- package/src/mixins/NumberMixin.js +7 -1
- package/src/mixins/SourceMixin.js +5 -9
- package/src/mixins/TypeMixin.js +1 -1
- package/src/styles/_button.scss +8 -0
- package/src/types/DitoTypeButton.vue +6 -5
- package/src/types/DitoTypeCode.vue +0 -4
- package/src/types/DitoTypeList.vue +16 -21
- package/src/types/DitoTypeMarkup.vue +1 -1
- package/src/types/DitoTypeNumber.vue +6 -0
- package/src/types/DitoTypePanel.vue +1 -1
- package/src/types/DitoTypeText.vue +6 -0
- package/src/utils/filter.js +72 -30
- package/src/utils/route.js +46 -0
- package/src/utils/schema.js +51 -23
- package/src/verbs.js +3 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/admin",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.3",
|
|
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,7 +33,7 @@
|
|
|
33
33
|
"not ie_mob > 0"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@ditojs/ui": "^2.2.
|
|
36
|
+
"@ditojs/ui": "^2.2.3",
|
|
37
37
|
"@ditojs/utils": "^2.2.0",
|
|
38
38
|
"@kyvg/vue3-notification": "^2.9.0",
|
|
39
39
|
"@lk77/vue3-color": "^3.0.6",
|
|
@@ -73,16 +73,16 @@
|
|
|
73
73
|
"vue-upload-component": "^3.1.8"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@ditojs/build": "^2.2.
|
|
76
|
+
"@ditojs/build": "^2.2.3",
|
|
77
77
|
"@vitejs/plugin-vue": "^4.1.0",
|
|
78
78
|
"@vue/compiler-sfc": "^3.2.47",
|
|
79
79
|
"pug": "^3.0.2",
|
|
80
80
|
"sass": "1.62.0",
|
|
81
81
|
"typescript": "^5.0.4",
|
|
82
|
-
"vite": "^4.
|
|
82
|
+
"vite": "^4.3.1"
|
|
83
83
|
},
|
|
84
84
|
"types": "types",
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "7102747103c7d60e9fffca44ca6ae459bea67cc1",
|
|
86
86
|
"scripts": {
|
|
87
87
|
"build": "vite build",
|
|
88
88
|
"watch": "yarn build --mode 'development' --watch",
|
package/src/DitoAdmin.js
CHANGED
|
@@ -3,8 +3,6 @@ import { createRouter, createWebHistory } from 'vue-router'
|
|
|
3
3
|
import VueNotifications from '@kyvg/vue3-notification'
|
|
4
4
|
import {
|
|
5
5
|
isString,
|
|
6
|
-
isArray,
|
|
7
|
-
asArray,
|
|
8
6
|
isAbsoluteUrl,
|
|
9
7
|
merge,
|
|
10
8
|
hyphenate,
|
|
@@ -17,6 +15,7 @@ import DitoRoot from './components/DitoRoot.vue'
|
|
|
17
15
|
import DitoTypeComponent from './DitoTypeComponent.js'
|
|
18
16
|
import { getResource } from './utils/resource.js'
|
|
19
17
|
import { deprecate } from './utils/deprecate.js'
|
|
18
|
+
import { formatQuery } from './utils/route.js'
|
|
20
19
|
import verbs from './verbs.js'
|
|
21
20
|
|
|
22
21
|
export default class DitoAdmin {
|
|
@@ -297,24 +296,3 @@ function combineUrls(baseUrl, relativeUrl) {
|
|
|
297
296
|
// Use same approach as axios `combineURLs()` to join baseUrl & relativeUrl:
|
|
298
297
|
return `${baseUrl.replace(/\/+$/, '')}/${relativeUrl.replace(/^\/+/, '')}`
|
|
299
298
|
}
|
|
300
|
-
|
|
301
|
-
function formatQuery(query) {
|
|
302
|
-
const entries = query
|
|
303
|
-
? isArray(query)
|
|
304
|
-
? query
|
|
305
|
-
: Object.entries(query)
|
|
306
|
-
: []
|
|
307
|
-
return new URLSearchParams(
|
|
308
|
-
// Expand array values into multiple entries under the same key, so
|
|
309
|
-
// `formatQuery({ foo: [1, 2], bar: 3 })` => 'foo=1&foo=2&bar=3'.
|
|
310
|
-
entries.reduce(
|
|
311
|
-
(entries, [key, value]) => {
|
|
312
|
-
for (const val of asArray(value)) {
|
|
313
|
-
entries.push([key, val])
|
|
314
|
-
}
|
|
315
|
-
return entries
|
|
316
|
-
},
|
|
317
|
-
[]
|
|
318
|
-
)
|
|
319
|
-
).toString()
|
|
320
|
-
}
|
|
@@ -5,18 +5,30 @@ nav.dito-menu.dito-scroll-parent
|
|
|
5
5
|
li(
|
|
6
6
|
v-for="view in views"
|
|
7
7
|
)
|
|
8
|
-
RouterLink
|
|
8
|
+
RouterLink(
|
|
9
9
|
v-if="shouldRender(view)"
|
|
10
|
+
v-slot="{ isActive, href, route }"
|
|
11
|
+
custom
|
|
10
12
|
:to="`/${view.path}`"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
)
|
|
14
|
+
a.dito-link(
|
|
15
|
+
:href="href"
|
|
16
|
+
:class="{ 'dito-active': isActive }"
|
|
17
|
+
@click.prevent="onClickLink(route)"
|
|
18
|
+
) {{ getLabel(view) }}
|
|
13
19
|
</template>
|
|
14
20
|
|
|
15
21
|
<script>
|
|
16
22
|
import DitoComponent from '../DitoComponent.js'
|
|
17
23
|
|
|
18
24
|
// @vue/component
|
|
19
|
-
export default DitoComponent.component('DitoMenu', {
|
|
25
|
+
export default DitoComponent.component('DitoMenu', {
|
|
26
|
+
methods: {
|
|
27
|
+
onClickLink(route) {
|
|
28
|
+
this.$router.push({ ...route, force: true })
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
})
|
|
20
32
|
</script>
|
|
21
33
|
|
|
22
34
|
<style lang="scss">
|
|
@@ -101,6 +101,7 @@ export default DitoComponent.component('DitoPane', {
|
|
|
101
101
|
return this.componentSchemas.flatMap(
|
|
102
102
|
({ schema, nestedDataPath: dataPath }) =>
|
|
103
103
|
getAllPanelEntries(
|
|
104
|
+
this.api,
|
|
104
105
|
schema,
|
|
105
106
|
dataPath,
|
|
106
107
|
this.schemaComponent,
|
|
@@ -118,7 +119,7 @@ export default DitoComponent.component('DitoPane', {
|
|
|
118
119
|
this._register(true)
|
|
119
120
|
},
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
unmounted() {
|
|
122
123
|
this._register(false)
|
|
123
124
|
},
|
|
124
125
|
|
|
@@ -5,8 +5,7 @@ component.dito-panel(
|
|
|
5
5
|
:is="panelTag"
|
|
6
6
|
@submit.prevent
|
|
7
7
|
)
|
|
8
|
-
|
|
9
|
-
DitoSchema.dito-panel-schema(
|
|
8
|
+
DitoSchema.dito-panel__schema(
|
|
10
9
|
:schema="panelSchema"
|
|
11
10
|
:dataPath="panelDataPath"
|
|
12
11
|
:data="panelData"
|
|
@@ -15,6 +14,17 @@ component.dito-panel(
|
|
|
15
14
|
:disabled="disabled"
|
|
16
15
|
:hasOwnData="hasOwnData"
|
|
17
16
|
)
|
|
17
|
+
template(#before)
|
|
18
|
+
h2.dito-panel__header(:class="{ 'dito-panel__header--sticky': sticky }")
|
|
19
|
+
span {{ getLabel(schema) }}
|
|
20
|
+
DitoButtons.dito-buttons-small(
|
|
21
|
+
:buttons="panelButtonSchemas"
|
|
22
|
+
:dataPath="panelDataPath"
|
|
23
|
+
:data="panelData"
|
|
24
|
+
:meta="meta"
|
|
25
|
+
:store="store"
|
|
26
|
+
:disabled="disabled"
|
|
27
|
+
)
|
|
18
28
|
template(#buttons)
|
|
19
29
|
DitoButtons(
|
|
20
30
|
:buttons="buttonSchemas"
|
|
@@ -73,6 +83,10 @@ export default DitoComponent.component('DitoPanel', {
|
|
|
73
83
|
return getButtonSchemas(this.schema.buttons)
|
|
74
84
|
},
|
|
75
85
|
|
|
86
|
+
panelButtonSchemas() {
|
|
87
|
+
return getButtonSchemas(this.schema.panelButtons)
|
|
88
|
+
},
|
|
89
|
+
|
|
76
90
|
target() {
|
|
77
91
|
return this.schema.target || this.dataPath
|
|
78
92
|
},
|
|
@@ -111,6 +125,11 @@ export default DitoComponent.component('DitoPanel', {
|
|
|
111
125
|
visible: getSchemaAccessor('visible', {
|
|
112
126
|
type: Boolean,
|
|
113
127
|
default: true
|
|
128
|
+
}),
|
|
129
|
+
|
|
130
|
+
sticky: getSchemaAccessor('sticky', {
|
|
131
|
+
type: Boolean,
|
|
132
|
+
default: false
|
|
114
133
|
})
|
|
115
134
|
},
|
|
116
135
|
|
|
@@ -126,7 +145,7 @@ export default DitoComponent.component('DitoPanel', {
|
|
|
126
145
|
}
|
|
127
146
|
},
|
|
128
147
|
|
|
129
|
-
|
|
148
|
+
unmounted() {
|
|
130
149
|
this._register(false)
|
|
131
150
|
},
|
|
132
151
|
|
|
@@ -144,19 +163,53 @@ export default DitoComponent.component('DitoPanel', {
|
|
|
144
163
|
@import '../styles/_imports';
|
|
145
164
|
|
|
146
165
|
.dito-panel {
|
|
147
|
-
|
|
166
|
+
padding-bottom: $content-padding;
|
|
148
167
|
|
|
149
|
-
|
|
168
|
+
&__header {
|
|
150
169
|
display: block;
|
|
170
|
+
position: relative;
|
|
151
171
|
box-sizing: border-box;
|
|
152
172
|
padding: $input-padding;
|
|
153
173
|
background: $button-color;
|
|
154
174
|
border: $border-style;
|
|
155
175
|
border-top-left-radius: $border-radius;
|
|
156
176
|
border-top-right-radius: $border-radius;
|
|
177
|
+
|
|
178
|
+
&--sticky {
|
|
179
|
+
$margin: $input-height-factor * $line-height * $font-size-small +
|
|
180
|
+
$form-spacing;
|
|
181
|
+
|
|
182
|
+
position: sticky;
|
|
183
|
+
top: $content-padding;
|
|
184
|
+
margin-bottom: $margin;
|
|
185
|
+
z-index: 1;
|
|
186
|
+
|
|
187
|
+
& + * {
|
|
188
|
+
margin-top: -$margin;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
&::before {
|
|
192
|
+
content: '';
|
|
193
|
+
display: block;
|
|
194
|
+
position: absolute;
|
|
195
|
+
background: $content-color-background;
|
|
196
|
+
left: 0;
|
|
197
|
+
right: 0;
|
|
198
|
+
height: $content-padding;
|
|
199
|
+
top: -$content-padding;
|
|
200
|
+
margin: -$border-width;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.dito-buttons {
|
|
205
|
+
position: absolute;
|
|
206
|
+
right: $input-padding-ver;
|
|
207
|
+
top: 50%;
|
|
208
|
+
transform: translateY(-50%);
|
|
209
|
+
}
|
|
157
210
|
}
|
|
158
211
|
|
|
159
|
-
|
|
212
|
+
&__schema {
|
|
160
213
|
font-size: $font-size-small;
|
|
161
214
|
background: $content-color-background;
|
|
162
215
|
border: $border-style;
|
|
@@ -167,16 +220,24 @@ export default DitoComponent.component('DitoPanel', {
|
|
|
167
220
|
> .dito-schema-content {
|
|
168
221
|
padding: $form-spacing-half $form-spacing;
|
|
169
222
|
|
|
223
|
+
.dito-container {
|
|
224
|
+
padding: $form-spacing-half;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.dito-object {
|
|
228
|
+
border: 0;
|
|
229
|
+
padding: 0;
|
|
230
|
+
}
|
|
231
|
+
|
|
170
232
|
> .dito-buttons {
|
|
171
233
|
--button-margin: #{$form-spacing};
|
|
172
234
|
|
|
173
235
|
padding: $form-spacing-half 0;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
236
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
237
|
+
.dito-container {
|
|
238
|
+
padding: 0;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
180
241
|
}
|
|
181
242
|
|
|
182
243
|
.dito-label {
|
|
@@ -190,10 +251,6 @@ export default DitoComponent.component('DitoPanel', {
|
|
|
190
251
|
.dito-pane {
|
|
191
252
|
margin: 0 (-$form-spacing-half);
|
|
192
253
|
}
|
|
193
|
-
|
|
194
|
-
.dito-container {
|
|
195
|
-
padding: $form-spacing-half;
|
|
196
|
-
}
|
|
197
254
|
}
|
|
198
255
|
}
|
|
199
256
|
</style>
|
|
@@ -212,8 +212,16 @@ export default DitoComponent.component('DitoRoot', {
|
|
|
212
212
|
...additionalComponents
|
|
213
213
|
},
|
|
214
214
|
buttons: {
|
|
215
|
-
cancel: {
|
|
216
|
-
|
|
215
|
+
cancel: {
|
|
216
|
+
type: 'button',
|
|
217
|
+
text: 'Cancel'
|
|
218
|
+
// NOTE: The click event is added in DitoDialog.buttonSchemas()
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
login: {
|
|
222
|
+
type: 'submit',
|
|
223
|
+
text: 'Login'
|
|
224
|
+
}
|
|
217
225
|
}
|
|
218
226
|
})
|
|
219
227
|
if (loginData) {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
2
|
+
slot(name="before")
|
|
3
|
+
.dito-schema(
|
|
4
|
+
v-bind="$attrs"
|
|
5
|
+
)
|
|
3
6
|
.dito-schema-content
|
|
4
7
|
.dito-schema-header(
|
|
5
8
|
v-if="hasLabel || hasTabs || clipboard"
|
|
@@ -81,6 +84,7 @@
|
|
|
81
84
|
:store="store"
|
|
82
85
|
:disabled="disabled"
|
|
83
86
|
)
|
|
87
|
+
slot(name="after")
|
|
84
88
|
</template>
|
|
85
89
|
|
|
86
90
|
<script>
|
|
@@ -334,7 +338,7 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
334
338
|
this.emitEvent('initialize') // Not `'create'`, since that's for data.
|
|
335
339
|
},
|
|
336
340
|
|
|
337
|
-
|
|
341
|
+
unmounted() {
|
|
338
342
|
this.emitEvent('destroy')
|
|
339
343
|
this._register(false)
|
|
340
344
|
},
|
package/src/mixins/DataMixin.js
CHANGED
|
@@ -98,13 +98,16 @@ export default {
|
|
|
98
98
|
},
|
|
99
99
|
|
|
100
100
|
async resolveData(load, loadingOptions = {}) {
|
|
101
|
-
|
|
101
|
+
// Use a timeout to allow already resolved promises to return data without
|
|
102
|
+
// showing a loading indicator.
|
|
103
|
+
const timer = setTimeout(() => this.setLoading(true, loadingOptions), 0)
|
|
102
104
|
let data = null
|
|
103
105
|
try {
|
|
104
106
|
data = await (isFunction(load) ? load() : load)
|
|
105
107
|
} catch (error) {
|
|
106
108
|
this.addError(error.message || error)
|
|
107
109
|
}
|
|
110
|
+
clearTimeout(timer)
|
|
108
111
|
this.setLoading(false, loadingOptions)
|
|
109
112
|
return data
|
|
110
113
|
}
|
package/src/mixins/DitoMixin.js
CHANGED
|
@@ -176,6 +176,8 @@ export default {
|
|
|
176
176
|
},
|
|
177
177
|
|
|
178
178
|
methods: {
|
|
179
|
+
labelize,
|
|
180
|
+
|
|
179
181
|
// The state of components is only available during the life-cycle of a
|
|
180
182
|
// component. Some information we need available longer than that, e.g.
|
|
181
183
|
// `query` & `total` on TypeList, so that when the user navigates back from
|
|
@@ -245,13 +247,10 @@ export default {
|
|
|
245
247
|
: labelize(name) || ''
|
|
246
248
|
},
|
|
247
249
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
getButtonAttributes(name, button) {
|
|
251
|
-
const verb = this.verbs[name] || name
|
|
250
|
+
getButtonAttributes(verb) {
|
|
252
251
|
return {
|
|
253
252
|
class: `dito-button-${verb}`,
|
|
254
|
-
title:
|
|
253
|
+
title: labelize(verb)
|
|
255
254
|
}
|
|
256
255
|
},
|
|
257
256
|
|
package/src/mixins/DomMixin.js
CHANGED
|
@@ -25,7 +25,13 @@ export default {
|
|
|
25
25
|
},
|
|
26
26
|
|
|
27
27
|
stepValue() {
|
|
28
|
-
|
|
28
|
+
// Don't show steps if the input is also clearable, since the step buttons
|
|
29
|
+
// would collide with the clear button.
|
|
30
|
+
return this.clearable
|
|
31
|
+
? null
|
|
32
|
+
: this.step == null && !this.isInteger
|
|
33
|
+
? 'any'
|
|
34
|
+
: this.step
|
|
29
35
|
},
|
|
30
36
|
|
|
31
37
|
decimals: getSchemaAccessor('decimals', {
|
|
@@ -3,6 +3,7 @@ import ResourceMixin from './ResourceMixin.js'
|
|
|
3
3
|
import SchemaParentMixin from '../mixins/SchemaParentMixin.js'
|
|
4
4
|
import { getSchemaAccessor, getStoreAccessor } from '../utils/accessor.js'
|
|
5
5
|
import { getMemberResource } from '../utils/resource.js'
|
|
6
|
+
import { replaceRoute } from '../utils/route.js'
|
|
6
7
|
import {
|
|
7
8
|
processRouteSchema,
|
|
8
9
|
processForms,
|
|
@@ -43,8 +44,7 @@ export default {
|
|
|
43
44
|
data() {
|
|
44
45
|
return {
|
|
45
46
|
wrappedPrimitives: null,
|
|
46
|
-
unwrappingPrimitives: false
|
|
47
|
-
ignoreRouteChange: false
|
|
47
|
+
unwrappingPrimitives: false
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
|
|
@@ -177,9 +177,9 @@ export default {
|
|
|
177
177
|
...query
|
|
178
178
|
}
|
|
179
179
|
if (!equals(query, this.$route.query)) {
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
180
|
+
// Change the route query parameters, but don't trigger a route
|
|
181
|
+
// change, as that would cause the list to reload.
|
|
182
|
+
replaceRoute({ query })
|
|
183
183
|
}
|
|
184
184
|
return query // Let getStoreAccessor() do the actual setting
|
|
185
185
|
}
|
|
@@ -314,10 +314,6 @@ export default {
|
|
|
314
314
|
|
|
315
315
|
watch: {
|
|
316
316
|
$route(to, from) {
|
|
317
|
-
if (this.ignoreRouteChange) {
|
|
318
|
-
this.ignoreRouteChange = false
|
|
319
|
-
return
|
|
320
|
-
}
|
|
321
317
|
if (from.path === to.path && from.hash === to.hash) {
|
|
322
318
|
// Paths and hashes remain the same, so only queries have changed.
|
|
323
319
|
// Update filter and reload data without clearing.
|
package/src/mixins/TypeMixin.js
CHANGED
package/src/styles/_button.scss
CHANGED
|
@@ -63,6 +63,10 @@
|
|
|
63
63
|
content: 'Edit';
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
.dito-button-clear:empty::before {
|
|
67
|
+
content: 'Clear';
|
|
68
|
+
}
|
|
69
|
+
|
|
66
70
|
.dito-button-save:empty::before {
|
|
67
71
|
content: 'Save';
|
|
68
72
|
}
|
|
@@ -159,6 +163,10 @@
|
|
|
159
163
|
@extend %icon-edit;
|
|
160
164
|
}
|
|
161
165
|
|
|
166
|
+
.dito-button-clear:empty::before {
|
|
167
|
+
@extend %icon-clear;
|
|
168
|
+
}
|
|
169
|
+
|
|
162
170
|
.dito-button-drag:empty::before {
|
|
163
171
|
@extend %icon-drag;
|
|
164
172
|
}
|
|
@@ -3,7 +3,7 @@ button.dito-button(
|
|
|
3
3
|
:id="dataPath"
|
|
4
4
|
ref="element"
|
|
5
5
|
:type="type"
|
|
6
|
-
:title="
|
|
6
|
+
:title="title"
|
|
7
7
|
:class="buttonClass"
|
|
8
8
|
v-bind="attributes"
|
|
9
9
|
) {{ text }}
|
|
@@ -34,12 +34,13 @@ export default DitoTypeComponent.register(
|
|
|
34
34
|
},
|
|
35
35
|
|
|
36
36
|
text: getSchemaAccessor('text', {
|
|
37
|
-
type: String
|
|
38
|
-
get(text) {
|
|
39
|
-
return text || labelize(this.verb)
|
|
40
|
-
}
|
|
37
|
+
type: String
|
|
41
38
|
}),
|
|
42
39
|
|
|
40
|
+
title() {
|
|
41
|
+
return this.text || labelize(this.verb)
|
|
42
|
+
},
|
|
43
|
+
|
|
43
44
|
closeForm: getSchemaAccessor('closeForm', {
|
|
44
45
|
type: Boolean,
|
|
45
46
|
default: false
|
|
@@ -110,10 +110,6 @@ export default DitoTypeComponent.register('code', {
|
|
|
110
110
|
// for proper line-height calculation.
|
|
111
111
|
padding: $input-padding;
|
|
112
112
|
|
|
113
|
-
&.dito-width-fill {
|
|
114
|
-
width: auto;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
113
|
.codeflask {
|
|
118
114
|
background: none;
|
|
119
115
|
// Ignore the parent padding defined above which is only needed to set
|
|
@@ -156,12 +156,11 @@ import DitoContext from '../DitoContext.js'
|
|
|
156
156
|
import SourceMixin from '../mixins/SourceMixin.js'
|
|
157
157
|
import SortableMixin from '../mixins/SortableMixin.js'
|
|
158
158
|
import {
|
|
159
|
-
getNamedSchemas,
|
|
160
159
|
getViewEditPath,
|
|
161
160
|
resolveSchemaComponent,
|
|
162
161
|
resolveSchemaComponents
|
|
163
162
|
} from '../utils/schema.js'
|
|
164
|
-
import {
|
|
163
|
+
import { createFiltersPanel } from '../utils/filter.js'
|
|
165
164
|
import { appendDataPath } from '../utils/data.js'
|
|
166
165
|
import { pickBy, equals, hyphenate } from '@ditojs/utils'
|
|
167
166
|
|
|
@@ -175,7 +174,7 @@ export default DitoTypeComponent.register('list', {
|
|
|
175
174
|
return type
|
|
176
175
|
},
|
|
177
176
|
|
|
178
|
-
getPanelSchema(schema, dataPath, schemaComponent) {
|
|
177
|
+
getPanelSchema(api, schema, dataPath, schemaComponent) {
|
|
179
178
|
const { filters } = schema
|
|
180
179
|
// See if this list component wants to display a filter panel, and if so,
|
|
181
180
|
// create the panel schema for it through `getFiltersPanel()`.
|
|
@@ -189,27 +188,23 @@ export default DitoTypeComponent.register('list', {
|
|
|
189
188
|
component => component.type === 'list'
|
|
190
189
|
)
|
|
191
190
|
|
|
192
|
-
return
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
if (component) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (!equals(filter(query), filter(component.query))) {
|
|
206
|
-
component.query = query
|
|
207
|
-
component.loadData(false)
|
|
208
|
-
}
|
|
191
|
+
return createFiltersPanel(api, filters, dataPath, {
|
|
192
|
+
// Create a simple proxy to get / set the query, see getFiltersPanel()
|
|
193
|
+
get query() {
|
|
194
|
+
return getListComponent()?.query
|
|
195
|
+
},
|
|
196
|
+
set query(query) {
|
|
197
|
+
const component = getListComponent()
|
|
198
|
+
if (component) {
|
|
199
|
+
// Filter out undefined values for comparing with equals()
|
|
200
|
+
const filter = obj => pickBy(obj, value => value !== undefined)
|
|
201
|
+
if (!equals(filter(query), filter(component.query))) {
|
|
202
|
+
component.query = query
|
|
203
|
+
component.loadData(false)
|
|
209
204
|
}
|
|
210
205
|
}
|
|
211
206
|
}
|
|
212
|
-
)
|
|
207
|
+
})
|
|
213
208
|
}
|
|
214
209
|
},
|
|
215
210
|
|
|
@@ -9,7 +9,7 @@ export default DitoTypeComponent.register('panel', {
|
|
|
9
9
|
alignBottom: false,
|
|
10
10
|
omitPadding: true,
|
|
11
11
|
|
|
12
|
-
getPanelSchema(schema) {
|
|
12
|
+
getPanelSchema(api, schema) {
|
|
13
13
|
// For a TypePanel, the component schema is also the panel schema, but
|
|
14
14
|
// remove the added name, so it doesn't get appended twice to data-path.
|
|
15
15
|
const { name, ...panel } = schema
|