@ditojs/admin 2.2.13 → 2.2.14
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 +1072 -1042
- package/dist/dito-admin.umd.js +4 -4
- package/dist/style.css +1 -1
- package/package.json +4 -3
- package/src/components/DitoContainer.vue +17 -9
- package/src/components/DitoLabel.vue +41 -34
- package/src/components/DitoRoot.vue +4 -0
- package/src/mixins/TypeMixin.js +3 -16
- package/src/styles/_info.scss +32 -0
- package/src/styles/style.scss +1 -0
- package/src/types/DitoTypeButton.vue +41 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/admin",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.14",
|
|
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.14",
|
|
37
37
|
"@ditojs/utils": "^2.2.0",
|
|
38
38
|
"@kyvg/vue3-notification": "^2.9.0",
|
|
39
39
|
"@lk77/vue3-color": "^3.0.6",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"nanoid": "^4.0.2",
|
|
67
67
|
"sortablejs": "^1.15.0",
|
|
68
68
|
"tinycolor2": "^1.6.0",
|
|
69
|
+
"tippy.js": "^6.3.7",
|
|
69
70
|
"type-fest": "^3.8.0",
|
|
70
71
|
"vue": "^3.2.47",
|
|
71
72
|
"vue-multiselect": "^3.0.0-beta.1",
|
|
@@ -82,7 +83,7 @@
|
|
|
82
83
|
"vite": "^4.3.1"
|
|
83
84
|
},
|
|
84
85
|
"types": "types",
|
|
85
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "71b48376ab32cc6ef6cd77bc565501ac264683d7",
|
|
86
87
|
"scripts": {
|
|
87
88
|
"build": "vite build",
|
|
88
89
|
"watch": "yarn build --mode 'development' --watch",
|
|
@@ -6,21 +6,24 @@
|
|
|
6
6
|
)
|
|
7
7
|
DitoLabel(
|
|
8
8
|
v-if="hasLabel"
|
|
9
|
+
:class="componentClass"
|
|
9
10
|
:label="label"
|
|
10
11
|
:dataPath="labelDataPath"
|
|
11
|
-
:
|
|
12
|
+
:info="info"
|
|
12
13
|
)
|
|
13
14
|
component.dito-component(
|
|
14
15
|
:is="typeComponent"
|
|
16
|
+
:class="componentClass"
|
|
15
17
|
:schema="schema"
|
|
16
18
|
:dataPath="dataPath"
|
|
17
19
|
:data="data"
|
|
18
20
|
:meta="meta"
|
|
19
21
|
:store="store"
|
|
22
|
+
:width="width"
|
|
23
|
+
:label="label"
|
|
20
24
|
:single="single"
|
|
21
25
|
:nested="nested"
|
|
22
26
|
:disabled="componentDisabled"
|
|
23
|
-
:class="componentClass"
|
|
24
27
|
@errors="onErrors"
|
|
25
28
|
)
|
|
26
29
|
DitoErrors(:errors="errors")
|
|
@@ -84,7 +87,12 @@ export default DitoComponent.component('DitoContainer', {
|
|
|
84
87
|
return this.nested ? this.dataPath : null
|
|
85
88
|
},
|
|
86
89
|
|
|
87
|
-
|
|
90
|
+
info: getSchemaAccessor('info', {
|
|
91
|
+
type: String,
|
|
92
|
+
default: null
|
|
93
|
+
}),
|
|
94
|
+
|
|
95
|
+
width: getSchemaAccessor('width', {
|
|
88
96
|
type: [String, Number],
|
|
89
97
|
default() {
|
|
90
98
|
return this.typeComponent?.defaultWidth
|
|
@@ -99,7 +107,7 @@ export default DitoComponent.component('DitoContainer', {
|
|
|
99
107
|
}
|
|
100
108
|
}),
|
|
101
109
|
|
|
102
|
-
|
|
110
|
+
widthOperator: getSchemaAccessor('width', {
|
|
103
111
|
type: String,
|
|
104
112
|
get(width) {
|
|
105
113
|
return isString(width)
|
|
@@ -143,7 +151,7 @@ export default DitoComponent.component('DitoContainer', {
|
|
|
143
151
|
},
|
|
144
152
|
|
|
145
153
|
componentBasis() {
|
|
146
|
-
const width = this.
|
|
154
|
+
const width = this.width
|
|
147
155
|
// 'auto' = no fitting:
|
|
148
156
|
const basis = [null, 'auto', 'fill'].includes(width)
|
|
149
157
|
? 'auto'
|
|
@@ -158,11 +166,11 @@ export default DitoComponent.component('DitoContainer', {
|
|
|
158
166
|
containerStyle() {
|
|
159
167
|
// Interpret '>50%' as '50%, flex-grow: 1`
|
|
160
168
|
const grow = (
|
|
161
|
-
this.
|
|
162
|
-
this.
|
|
169
|
+
this.widthOperator === '>' ||
|
|
170
|
+
this.width === 'fill'
|
|
163
171
|
)
|
|
164
172
|
// Interpret '<50%' as '50%, flex-shrink: 1`
|
|
165
|
-
const shrink = this.
|
|
173
|
+
const shrink = this.widthOperator === '<'
|
|
166
174
|
return {
|
|
167
175
|
flex: `${grow ? 1 : 0} ${shrink ? 1 : 0} ${this.componentBasis}`
|
|
168
176
|
}
|
|
@@ -174,7 +182,7 @@ export default DitoComponent.component('DitoContainer', {
|
|
|
174
182
|
// TODO: BEM?
|
|
175
183
|
'dito-single': this.single,
|
|
176
184
|
'dito-disabled': this.componentDisabled,
|
|
177
|
-
'dito-width-fill': !basisIsAuto || this.
|
|
185
|
+
'dito-width-fill': !basisIsAuto || this.width === 'fill',
|
|
178
186
|
'dito-has-errors': !!this.errors
|
|
179
187
|
}
|
|
180
188
|
}
|
|
@@ -9,22 +9,28 @@ component.dito-label(
|
|
|
9
9
|
v-if="collapsible"
|
|
10
10
|
:class="{ 'dito-opened': !collapsed }"
|
|
11
11
|
)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
12
|
+
.dito-label__inner
|
|
13
|
+
DitoElement.dito-label-prefix(
|
|
14
|
+
v-for="(prefix, index) of prefixes"
|
|
15
|
+
:key="`prefix-${index}`"
|
|
16
|
+
tag="span"
|
|
17
|
+
:content="prefix"
|
|
18
|
+
)
|
|
19
|
+
label(
|
|
20
|
+
:for="dataPath"
|
|
21
|
+
v-html="text"
|
|
22
|
+
)
|
|
23
|
+
DitoElement.dito-label-suffix(
|
|
24
|
+
v-for="(suffix, index) of suffixes"
|
|
25
|
+
:key="`suffix-${index}`"
|
|
26
|
+
tag="span"
|
|
27
|
+
:content="suffix"
|
|
28
|
+
)
|
|
29
|
+
.dito-info(
|
|
30
|
+
v-if="info"
|
|
31
|
+
:data-tippy-content="info"
|
|
32
|
+
data-tippy-theme="info"
|
|
33
|
+
)
|
|
28
34
|
slot(name="edit-buttons")
|
|
29
35
|
</template>
|
|
30
36
|
|
|
@@ -40,7 +46,8 @@ export default DitoComponent.component('DitoLabel', {
|
|
|
40
46
|
label: { type: [String, Object], default: null },
|
|
41
47
|
dataPath: { type: String, default: null },
|
|
42
48
|
collapsed: { type: Boolean, default: false },
|
|
43
|
-
collapsible: { type: Boolean, default: false }
|
|
49
|
+
collapsible: { type: Boolean, default: false },
|
|
50
|
+
info: { type: String, default: null }
|
|
44
51
|
},
|
|
45
52
|
|
|
46
53
|
computed: {
|
|
@@ -83,6 +90,8 @@ export default DitoComponent.component('DitoLabel', {
|
|
|
83
90
|
@import '../styles/_imports';
|
|
84
91
|
|
|
85
92
|
.dito-label {
|
|
93
|
+
$self: &;
|
|
94
|
+
|
|
86
95
|
--label-padding: 0;
|
|
87
96
|
// For buttons and chevron to align right:
|
|
88
97
|
display: flex;
|
|
@@ -92,8 +101,13 @@ export default DitoComponent.component('DitoLabel', {
|
|
|
92
101
|
padding: var(--label-padding);
|
|
93
102
|
margin: 0 0 $form-spacing-half 0;
|
|
94
103
|
|
|
104
|
+
&__inner {
|
|
105
|
+
display: flex;
|
|
106
|
+
// Stretch to full available width so that buttons appear right-aligned:
|
|
107
|
+
flex: 1 1 auto;
|
|
108
|
+
}
|
|
109
|
+
|
|
95
110
|
label {
|
|
96
|
-
display: inline;
|
|
97
111
|
cursor: inherit;
|
|
98
112
|
font-weight: bold;
|
|
99
113
|
white-space: nowrap;
|
|
@@ -102,23 +116,14 @@ export default DitoComponent.component('DitoLabel', {
|
|
|
102
116
|
label,
|
|
103
117
|
.dito-label-prefix,
|
|
104
118
|
.dito-label-suffix {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
// so that buttons always appear right-aligned:
|
|
108
|
-
flex: 1 1 auto;
|
|
109
|
-
}
|
|
119
|
+
@include user-select(none);
|
|
120
|
+
@include ellipsis;
|
|
110
121
|
|
|
111
122
|
&::after {
|
|
112
|
-
content: '\a0'; //  
|
|
123
|
+
content: '\a0'; //
|
|
113
124
|
}
|
|
114
125
|
}
|
|
115
126
|
|
|
116
|
-
.dito-label-prefix,
|
|
117
|
-
.dito-label-suffix {
|
|
118
|
-
@include user-select(none);
|
|
119
|
-
@include ellipsis;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
127
|
.dito-buttons {
|
|
123
128
|
// Move the label padding inside .dito-buttons, so that it captures all
|
|
124
129
|
// near mouse events:
|
|
@@ -131,11 +136,9 @@ export default DitoComponent.component('DitoLabel', {
|
|
|
131
136
|
width: 100%;
|
|
132
137
|
// In order for ellipsis to work on labels without affecting other layout,
|
|
133
138
|
// we need to position it absolutely inside its container.
|
|
134
|
-
|
|
135
|
-
@include ellipsis;
|
|
136
|
-
|
|
139
|
+
#{$self}__inner {
|
|
137
140
|
position: absolute;
|
|
138
|
-
|
|
141
|
+
inset: 0;
|
|
139
142
|
}
|
|
140
143
|
|
|
141
144
|
&::after {
|
|
@@ -144,6 +147,10 @@ export default DitoComponent.component('DitoLabel', {
|
|
|
144
147
|
content: '\200b'; // zero-width space;
|
|
145
148
|
}
|
|
146
149
|
}
|
|
150
|
+
|
|
151
|
+
.dito-info {
|
|
152
|
+
margin-left: 0.35em;
|
|
153
|
+
}
|
|
147
154
|
}
|
|
148
155
|
|
|
149
156
|
a.dito-label {
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
</template>
|
|
35
35
|
|
|
36
36
|
<script>
|
|
37
|
+
import { delegate as tippyDelegate } from 'tippy.js'
|
|
37
38
|
import { asArray, mapConcurrently, stripTags } from '@ditojs/utils'
|
|
38
39
|
import DitoComponent from '../DitoComponent.js'
|
|
39
40
|
import DitoUser from '../DitoUser.js'
|
|
@@ -90,6 +91,9 @@ export default DitoComponent.component('DitoRoot', {
|
|
|
90
91
|
},
|
|
91
92
|
|
|
92
93
|
async mounted() {
|
|
94
|
+
tippyDelegate(this.$el, {
|
|
95
|
+
target: '[data-tippy-content]'
|
|
96
|
+
})
|
|
93
97
|
// Clear the label marked as active on all mouse and keyboard events, except
|
|
94
98
|
// the ones that DitoLabel itself intercepts.
|
|
95
99
|
this.domOn(document, {
|
package/src/mixins/TypeMixin.js
CHANGED
|
@@ -3,7 +3,7 @@ import ValidationMixin from './ValidationMixin.js'
|
|
|
3
3
|
import { getSchemaAccessor } from '../utils/accessor.js'
|
|
4
4
|
import { computeValue } from '../utils/schema.js'
|
|
5
5
|
import { getItem, getParentItem } from '../utils/data.js'
|
|
6
|
-
import {
|
|
6
|
+
import { asArray, camelize } from '@ditojs/utils'
|
|
7
7
|
|
|
8
8
|
// @vue/component
|
|
9
9
|
export default {
|
|
@@ -17,6 +17,8 @@ export default {
|
|
|
17
17
|
data: { type: [Object, Array], required: true },
|
|
18
18
|
meta: { type: Object, required: true },
|
|
19
19
|
store: { type: Object, required: true },
|
|
20
|
+
width: { type: [Number, String], default: null },
|
|
21
|
+
label: { type: String, default: null },
|
|
20
22
|
single: { type: Boolean, default: false },
|
|
21
23
|
nested: { type: Boolean, default: true },
|
|
22
24
|
disabled: { type: Boolean, default: false }
|
|
@@ -109,21 +111,6 @@ export default {
|
|
|
109
111
|
return this.processedData
|
|
110
112
|
},
|
|
111
113
|
|
|
112
|
-
label: getSchemaAccessor('label', {
|
|
113
|
-
type: [String, Boolean],
|
|
114
|
-
get(label) {
|
|
115
|
-
return isString(label)
|
|
116
|
-
? label
|
|
117
|
-
: label !== false && this.$options.generateLabel
|
|
118
|
-
? this.getLabel(this.schema)
|
|
119
|
-
: null
|
|
120
|
-
}
|
|
121
|
-
}),
|
|
122
|
-
|
|
123
|
-
width: getSchemaAccessor('width', {
|
|
124
|
-
type: [String, Number]
|
|
125
|
-
}),
|
|
126
|
-
|
|
127
114
|
visible: getSchemaAccessor('visible', {
|
|
128
115
|
type: Boolean,
|
|
129
116
|
default() {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
.dito-info {
|
|
2
|
+
--size: calc(1em * var(--line-height));
|
|
3
|
+
|
|
4
|
+
display: inline-block;
|
|
5
|
+
position: relative;
|
|
6
|
+
flex: 0 0 var(--size);
|
|
7
|
+
width: var(--size);
|
|
8
|
+
height: var(--size);
|
|
9
|
+
text-align: center;
|
|
10
|
+
vertical-align: top;
|
|
11
|
+
margin-left: 0.35em;
|
|
12
|
+
color: $color-active;
|
|
13
|
+
|
|
14
|
+
&::before {
|
|
15
|
+
@extend %icon-info;
|
|
16
|
+
|
|
17
|
+
width: var(--size);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.tippy-box[data-theme~='info'] {
|
|
22
|
+
background-color: $color-active;
|
|
23
|
+
color: $color-white;
|
|
24
|
+
|
|
25
|
+
> .tippy-arrow::before {
|
|
26
|
+
color: $color-active;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.tippy-content {
|
|
30
|
+
white-space: pre-line;
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/styles/style.scss
CHANGED
|
@@ -6,7 +6,20 @@ button.dito-button(
|
|
|
6
6
|
:title="title"
|
|
7
7
|
:class="buttonClass"
|
|
8
8
|
v-bind="attributes"
|
|
9
|
-
)
|
|
9
|
+
)
|
|
10
|
+
template(
|
|
11
|
+
v-if="info || width === 'fill'"
|
|
12
|
+
)
|
|
13
|
+
.dito-button__text
|
|
14
|
+
span {{ text }}
|
|
15
|
+
.dito-info(
|
|
16
|
+
v-if="!label && info"
|
|
17
|
+
:data-tippy-content="info"
|
|
18
|
+
data-tippy-theme="info"
|
|
19
|
+
)
|
|
20
|
+
template(
|
|
21
|
+
v-else
|
|
22
|
+
) {{ text }}
|
|
10
23
|
</template>
|
|
11
24
|
|
|
12
25
|
<script>
|
|
@@ -41,6 +54,11 @@ export default DitoTypeComponent.register(
|
|
|
41
54
|
return this.text || labelize(this.verb)
|
|
42
55
|
},
|
|
43
56
|
|
|
57
|
+
info: getSchemaAccessor('info', {
|
|
58
|
+
type: String,
|
|
59
|
+
default: null
|
|
60
|
+
}),
|
|
61
|
+
|
|
44
62
|
closeForm: getSchemaAccessor('closeForm', {
|
|
45
63
|
type: Boolean,
|
|
46
64
|
default: false
|
|
@@ -74,3 +92,25 @@ export default DitoTypeComponent.register(
|
|
|
74
92
|
}
|
|
75
93
|
)
|
|
76
94
|
</script>
|
|
95
|
+
|
|
96
|
+
<style lang="scss">
|
|
97
|
+
@import '../styles/_imports';
|
|
98
|
+
|
|
99
|
+
.dito-button {
|
|
100
|
+
display: flex;
|
|
101
|
+
|
|
102
|
+
&__text {
|
|
103
|
+
position: relative;
|
|
104
|
+
width: 100%;
|
|
105
|
+
min-width: min-content;
|
|
106
|
+
height: calc(1em * var(--line-height));
|
|
107
|
+
|
|
108
|
+
span {
|
|
109
|
+
@include ellipsis;
|
|
110
|
+
|
|
111
|
+
position: absolute;
|
|
112
|
+
inset: 0;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
</style>
|