@ditojs/admin 2.94.1 → 2.96.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.css +1 -1
- package/dist/dito-admin.es.js +56 -21
- package/dist/dito-admin.umd.js +5 -5
- package/package.json +14 -13
- package/src/components/DitoCreateButton.vue +11 -3
- package/src/components/DitoEditButtons.vue +4 -2
- package/src/components/DitoLabel.vue +2 -0
- package/src/components/DitoSchema.vue +2 -0
- package/src/components/DitoSchemaInlined.vue +9 -5
- package/src/components/DitoTreeItem.vue +12 -3
- package/src/mixins/SourceMixin.js +19 -6
- package/src/styles/_button.scss +6 -3
- package/src/types/DitoTypeList.vue +3 -1
- package/src/utils/ui/dist/dito-ui.es.js +0 -2729
- package/src/utils/ui/dist/dito-ui.umd.js +0 -2744
- package/src/utils/ui/dist/style.css +0 -1139
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/admin",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.96.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/main/packages/admin",
|
|
@@ -24,6 +24,12 @@
|
|
|
24
24
|
"dist/",
|
|
25
25
|
"types/"
|
|
26
26
|
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "vite build",
|
|
29
|
+
"watch": "pnpm run build --mode 'development' --watch",
|
|
30
|
+
"prepare": "pnpm run build",
|
|
31
|
+
"types": "tsc --noEmit types/index.d.ts"
|
|
32
|
+
},
|
|
27
33
|
"engines": {
|
|
28
34
|
"node": ">= 24.0.0"
|
|
29
35
|
},
|
|
@@ -34,8 +40,8 @@
|
|
|
34
40
|
"not ie_mob > 0"
|
|
35
41
|
],
|
|
36
42
|
"dependencies": {
|
|
37
|
-
"@ditojs/ui": "^2.
|
|
38
|
-
"@ditojs/utils": "^2.
|
|
43
|
+
"@ditojs/ui": "^2.96.0",
|
|
44
|
+
"@ditojs/utils": "^2.96.0"
|
|
39
45
|
},
|
|
40
46
|
"peerDependencies": {
|
|
41
47
|
"@kyvg/vue3-notification": "^3.4.2",
|
|
@@ -83,14 +89,9 @@
|
|
|
83
89
|
"vue-upload-component": "^3.1.17"
|
|
84
90
|
},
|
|
85
91
|
"devDependencies": {
|
|
86
|
-
"@ditojs/build": "^2.
|
|
87
|
-
"typescript": "^6.0.
|
|
88
|
-
"vite": "^8.0.
|
|
92
|
+
"@ditojs/build": "^2.96.0",
|
|
93
|
+
"typescript": "^6.0.3",
|
|
94
|
+
"vite": "^8.0.10"
|
|
89
95
|
},
|
|
90
|
-
"gitHead": "
|
|
91
|
-
|
|
92
|
-
"build": "vite build",
|
|
93
|
-
"watch": "pnpm run build --mode 'development' --watch",
|
|
94
|
-
"types": "tsc --noEmit types/index.d.ts"
|
|
95
|
-
}
|
|
96
|
-
}
|
|
96
|
+
"gitHead": "689f4d061088500884114c5ced79d68209717bc5"
|
|
97
|
+
}
|
|
@@ -63,12 +63,20 @@ export default DitoComponent.component('DitoCreateButton', {
|
|
|
63
63
|
path: { type: String, required: true },
|
|
64
64
|
verb: { type: String, required: true },
|
|
65
65
|
text: { type: String, default: null },
|
|
66
|
-
disabled: { type: Boolean, required: true }
|
|
66
|
+
disabled: { type: Boolean, required: true },
|
|
67
|
+
insertIndex: { type: Number, default: null }
|
|
67
68
|
},
|
|
68
69
|
|
|
69
70
|
computed: {
|
|
70
71
|
forms() {
|
|
71
|
-
|
|
72
|
+
// When inserting per-item, `this.schema` is the item's form, not the
|
|
73
|
+
// list schema. Fall back to `sourceSchema` (the parent list's schema via
|
|
74
|
+
// `meta.schema`) so all creatable forms are discoverable in the pulldown.
|
|
75
|
+
const schema =
|
|
76
|
+
this.insertIndex != null
|
|
77
|
+
? this.sourceSchema || this.schema
|
|
78
|
+
: this.schema
|
|
79
|
+
return getFormSchemas(schema, this.context)
|
|
72
80
|
},
|
|
73
81
|
|
|
74
82
|
creatableForms() {
|
|
@@ -107,7 +115,7 @@ export default DitoComponent.component('DitoCreateButton', {
|
|
|
107
115
|
createItem(form, type = null) {
|
|
108
116
|
if (!this.shouldDisableSchema(form)) {
|
|
109
117
|
if (this.isInlined) {
|
|
110
|
-
this.sourceComponent.createItem(form, type)
|
|
118
|
+
this.sourceComponent.createItem(form, type, this.insertIndex)
|
|
111
119
|
} else {
|
|
112
120
|
const { creatable } = this.schema
|
|
113
121
|
const query = {
|
|
@@ -31,8 +31,9 @@ DitoButtons.dito-edit-buttons.dito-buttons--round(
|
|
|
31
31
|
:nested="nested"
|
|
32
32
|
:path="createPath"
|
|
33
33
|
:verb="verbs.create"
|
|
34
|
-
:text="createButtonText"
|
|
34
|
+
:text="insertIndex != null ? null : createButtonText"
|
|
35
35
|
:disabled="isCreatableDisabled"
|
|
36
|
+
:insertIndex="insertIndex"
|
|
36
37
|
)
|
|
37
38
|
button.dito-button(
|
|
38
39
|
v-if="deletable"
|
|
@@ -67,7 +68,8 @@ export default DitoComponent.component('DitoEditButtons', {
|
|
|
67
68
|
creatable: { type: Boolean, default: false },
|
|
68
69
|
deletable: { type: Boolean, default: false },
|
|
69
70
|
editPath: { type: String, default: null },
|
|
70
|
-
createPath: { type: String, default: null }
|
|
71
|
+
createPath: { type: String, default: null },
|
|
72
|
+
insertIndex: { type: Number, default: null }
|
|
71
73
|
},
|
|
72
74
|
|
|
73
75
|
computed: {
|
|
@@ -102,6 +102,8 @@ export default DitoComponent.component('DitoLabel', {
|
|
|
102
102
|
position: relative;
|
|
103
103
|
// Vertically center all items in the label, e.g. chevron, edit-buttons.
|
|
104
104
|
align-items: center;
|
|
105
|
+
// Let nested labels with ellipsis shrink below their content width.
|
|
106
|
+
min-width: 0;
|
|
105
107
|
min-height: $input-height;
|
|
106
108
|
margin-right: $form-spacing-half; // When inlined.
|
|
107
109
|
|
|
@@ -825,6 +825,8 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
825
825
|
.dito-schema-header {
|
|
826
826
|
display: flex;
|
|
827
827
|
justify-content: space-between;
|
|
828
|
+
// Let nested labels with ellipsis shrink below their content width.
|
|
829
|
+
min-width: 0;
|
|
828
830
|
|
|
829
831
|
.dito-header & {
|
|
830
832
|
// When teleported into main header.
|
|
@@ -21,7 +21,7 @@ DitoSchema.dito-schema-inlined(
|
|
|
21
21
|
//- others in `TypeList` as a scope, for better handling of layout.
|
|
22
22
|
template(#edit-buttons)
|
|
23
23
|
DitoEditButtons(
|
|
24
|
-
v-if="deletable || draggable || editable"
|
|
24
|
+
v-if="deletable || draggable || editable || insertIndex != null"
|
|
25
25
|
:schema="schema"
|
|
26
26
|
:dataPath="dataPath"
|
|
27
27
|
:data="data"
|
|
@@ -32,6 +32,9 @@ DitoSchema.dito-schema-inlined(
|
|
|
32
32
|
:draggable="draggable"
|
|
33
33
|
:editable="editable"
|
|
34
34
|
:editPath="editPath"
|
|
35
|
+
:creatable="insertIndex != null"
|
|
36
|
+
:createPath="createPath"
|
|
37
|
+
:insertIndex="insertIndex"
|
|
35
38
|
@delete="$emit('delete')"
|
|
36
39
|
)
|
|
37
40
|
</template>
|
|
@@ -59,6 +62,8 @@ export default DitoComponent.component('DitoSchemaInlined', {
|
|
|
59
62
|
editable: { type: Boolean, default: false },
|
|
60
63
|
deletable: { type: Boolean, default: false },
|
|
61
64
|
editPath: { type: String, default: null },
|
|
65
|
+
createPath: { type: String, default: null },
|
|
66
|
+
insertIndex: { type: Number, default: null },
|
|
62
67
|
labelNode: { type: HTMLElement, default: null },
|
|
63
68
|
accumulatedBasis: { type: Number, default: null }
|
|
64
69
|
},
|
|
@@ -87,10 +92,9 @@ export default DitoComponent.component('DitoSchemaInlined', {
|
|
|
87
92
|
grid-template-columns: 100%;
|
|
88
93
|
|
|
89
94
|
&:not(:hover, .dito-schema--open) {
|
|
90
|
-
> .dito-schema-header
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
95
|
+
> .dito-schema-header
|
|
96
|
+
.dito-button:not(.dito-button--edit, .dito-button--remove) {
|
|
97
|
+
display: none;
|
|
94
98
|
}
|
|
95
99
|
}
|
|
96
100
|
}
|
|
@@ -321,8 +321,14 @@ export default DitoComponent.component('DitoTreeItem', {
|
|
|
321
321
|
--chevron-indent: #{$chevron-indent};
|
|
322
322
|
|
|
323
323
|
overflow: hidden;
|
|
324
|
+
padding: 0 $input-padding-hor;
|
|
325
|
+
margin: 0 (-$input-padding-hor);
|
|
324
326
|
|
|
325
327
|
> .dito-tree-header {
|
|
328
|
+
// Extend header into item padding so active background reaches the edge:
|
|
329
|
+
margin: 0 (-$input-padding-hor);
|
|
330
|
+
padding: 0 $input-padding-hor;
|
|
331
|
+
|
|
326
332
|
> .dito-tree-branch,
|
|
327
333
|
> .dito-tree-leaf {
|
|
328
334
|
// Use `--level` CSS variable to calculated the accumulated indent
|
|
@@ -356,8 +362,13 @@ export default DitoComponent.component('DitoTreeItem', {
|
|
|
356
362
|
display: flex;
|
|
357
363
|
align-items: baseline;
|
|
358
364
|
gap: 0.25em;
|
|
359
|
-
|
|
365
|
+
min-width: 0;
|
|
360
366
|
white-space: nowrap;
|
|
367
|
+
|
|
368
|
+
> :first-child {
|
|
369
|
+
overflow: hidden;
|
|
370
|
+
text-overflow: ellipsis;
|
|
371
|
+
}
|
|
361
372
|
}
|
|
362
373
|
|
|
363
374
|
.dito-tree-info {
|
|
@@ -395,8 +406,6 @@ export default DitoComponent.component('DitoTreeItem', {
|
|
|
395
406
|
&--active {
|
|
396
407
|
> .dito-tree-header {
|
|
397
408
|
background: $color-active;
|
|
398
|
-
padding: 0 $input-padding-hor;
|
|
399
|
-
margin: 0 (-$input-padding-hor);
|
|
400
409
|
|
|
401
410
|
> .dito-tree-branch {
|
|
402
411
|
> .dito-chevron::before {
|
|
@@ -318,7 +318,7 @@ export default {
|
|
|
318
318
|
type: Boolean,
|
|
319
319
|
default: false,
|
|
320
320
|
get(draggable) {
|
|
321
|
-
return this.isListSource &&
|
|
321
|
+
return this.isListSource && draggable
|
|
322
322
|
}
|
|
323
323
|
}),
|
|
324
324
|
|
|
@@ -450,15 +450,17 @@ export default {
|
|
|
450
450
|
}
|
|
451
451
|
},
|
|
452
452
|
|
|
453
|
-
createItem(schema, type) {
|
|
453
|
+
createItem(schema, type, index = null) {
|
|
454
454
|
const item = this.createData(schema, type)
|
|
455
455
|
if (this.isObjectSource) {
|
|
456
456
|
this.objectData = item
|
|
457
|
+
} else if (index != null) {
|
|
458
|
+
this.listData.splice(index, 0, item)
|
|
457
459
|
} else {
|
|
458
460
|
this.listData.push(item)
|
|
459
461
|
}
|
|
460
462
|
if (this.collapsible) {
|
|
461
|
-
this.$nextTick(() => this.openSchemaComponent(-1))
|
|
463
|
+
this.$nextTick(() => this.openSchemaComponent(index ?? -1))
|
|
462
464
|
}
|
|
463
465
|
this.onChange()
|
|
464
466
|
return item
|
|
@@ -531,9 +533,20 @@ export default {
|
|
|
531
533
|
},
|
|
532
534
|
|
|
533
535
|
getSchemaComponent(index) {
|
|
534
|
-
const { schemaComponents } = this
|
|
535
|
-
const
|
|
536
|
-
|
|
536
|
+
const { listData, schemaComponents } = this
|
|
537
|
+
const candidate = schemaComponents.at(index)
|
|
538
|
+
if (listData?.length) {
|
|
539
|
+
// Fast path: registration order usually matches `listData`. Fall back
|
|
540
|
+
// to a search by reference when it doesn't (non-tail inserts, drag
|
|
541
|
+
// reorders), since `schemaComponents` is filled by mount-order pushes.
|
|
542
|
+
const item = listData.at(index)
|
|
543
|
+
return item == null
|
|
544
|
+
? null
|
|
545
|
+
: candidate?.data === item
|
|
546
|
+
? candidate
|
|
547
|
+
: schemaComponents.find(c => c.data === item)
|
|
548
|
+
}
|
|
549
|
+
return candidate
|
|
537
550
|
},
|
|
538
551
|
|
|
539
552
|
openSchemaComponent(index) {
|
package/src/styles/_button.scss
CHANGED
|
@@ -155,9 +155,12 @@
|
|
|
155
155
|
|
|
156
156
|
&--round,
|
|
157
157
|
&--small {
|
|
158
|
-
// For now, nothing for
|
|
159
|
-
// .dito-button--create:empty::before
|
|
160
|
-
|
|
158
|
+
// For now, nothing for create:
|
|
159
|
+
// .dito-button--create:empty::before
|
|
160
|
+
|
|
161
|
+
.dito-button--add:empty::before {
|
|
162
|
+
@extend %icon-add;
|
|
163
|
+
}
|
|
161
164
|
|
|
162
165
|
.dito-button--upload:empty::before {
|
|
163
166
|
@extend %icon-upload;
|
|
@@ -85,9 +85,11 @@
|
|
|
85
85
|
:collapsed="collapsed"
|
|
86
86
|
:collapsible="collapsible"
|
|
87
87
|
:deletable="deletable"
|
|
88
|
-
:draggable="draggable"
|
|
88
|
+
:draggable="draggable && listData.length > 1"
|
|
89
89
|
:editable="editable"
|
|
90
90
|
:editPath="getEditPath(item, index)"
|
|
91
|
+
:createPath="createPath"
|
|
92
|
+
:insertIndex="creatable && draggable ? index : null"
|
|
91
93
|
@delete="deleteItem(item, index)"
|
|
92
94
|
)
|
|
93
95
|
component(
|