@ditojs/admin 2.75.0 → 2.75.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ditojs/admin",
3
- "version": "2.75.0",
3
+ "version": "2.75.2",
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",
@@ -93,5 +93,5 @@
93
93
  "typescript": "^5.9.3",
94
94
  "vite": "^7.3.1"
95
95
  },
96
- "gitHead": "cfc4ee21dc3f5808b5a78a3b1fab83500c05907a"
96
+ "gitHead": "70ff8a3042925a27c2b2a792505db04038f92493"
97
97
  }
@@ -1,11 +1,11 @@
1
1
  <template lang="pug">
2
2
  component(
3
3
  v-if="item.type === 'text'"
4
- :is="item.as || 'span'"
4
+ :is="item.as || 'div'"
5
5
  ) {{ item.text }}
6
6
  component(
7
7
  v-else-if="item.type === 'html'"
8
- :is="item.as || 'span'"
8
+ :is="item.as || 'div'"
9
9
  v-html="item.html"
10
10
  )
11
11
  DitoSpinner(
@@ -48,9 +48,21 @@ export default DitoComponent.component('DitoAffix', {
48
48
  </script>
49
49
 
50
50
  <style lang="scss">
51
+ @import '../styles/_imports';
52
+
51
53
  .dito-affix {
54
+ &--html,
52
55
  &--text {
53
56
  display: inline-block;
54
57
  }
58
+
59
+ &--ellipsis {
60
+ @include ellipsis;
61
+
62
+ flex: 1;
63
+ display: block;
64
+ min-width: 0;
65
+ width: 0;
66
+ }
55
67
  }
56
68
  </style>
@@ -7,7 +7,7 @@
7
7
  DitoAffix.dito-affix(
8
8
  v-for="(item, index) in visibleItems"
9
9
  :key="index"
10
- :class="[`dito-affix--${item.type}`, item.class]"
10
+ :class="getItemClasses(item)"
11
11
  :style="item.style"
12
12
  :item="item"
13
13
  :parentContext="parentContext"
@@ -21,6 +21,10 @@
21
21
  @mousedown.stop
22
22
  )
23
23
  slot(name="append")
24
+ .dito-info(
25
+ v-if="inlineInfo"
26
+ :data-info="inlineInfo"
27
+ )
24
28
  </template>
25
29
 
26
30
  <script>
@@ -36,10 +40,12 @@ export default DitoComponent.component('DitoAffixes', {
36
40
 
37
41
  props: {
38
42
  items: { type: [String, Object, Array], default: null },
43
+ mode: { type: String, default: null },
39
44
  position: { type: String, default: null },
40
45
  absolute: { type: Boolean, default: false },
41
46
  clearable: { type: Boolean, default: false },
42
47
  disabled: { type: Boolean, default: false },
48
+ inlineInfo: { type: String, default: null },
43
49
  parentContext: { type: Object, required: true }
44
50
  },
45
51
 
@@ -75,6 +81,7 @@ export default DitoComponent.component('DitoAffixes', {
75
81
  const prefix = 'dito-affixes'
76
82
  return {
77
83
  [`${prefix}--${this.position}`]: this.position,
84
+ [`${prefix}--${this.mode}`]: this.mode,
78
85
  [`${prefix}--absolute`]: this.absolute
79
86
  }
80
87
  },
@@ -83,10 +90,26 @@ export default DitoComponent.component('DitoAffixes', {
83
90
  return (
84
91
  this.visibleItems.length > 0 ||
85
92
  this.clearable ||
93
+ this.inlineInfo ||
86
94
  hasSlotContent(this.$slots.prepend) ||
87
95
  hasSlotContent(this.$slots.append)
88
96
  )
89
97
  }
98
+ },
99
+
100
+ methods: {
101
+ getItemClasses(item) {
102
+ const prefix = 'dito-affix'
103
+ return [
104
+ {
105
+ [`${prefix}--${item.type}`]: item.type,
106
+ [`${prefix}--ellipsis`]: (
107
+ this.mode === 'ellipsis' && ['text', 'html'].includes(item.type)
108
+ )
109
+ },
110
+ item.class
111
+ ]
112
+ }
90
113
  }
91
114
  })
92
115
  </script>
@@ -122,16 +145,20 @@ export default DitoComponent.component('DitoAffixes', {
122
145
  }
123
146
  }
124
147
 
125
- @at-root .dito-component & {
148
+ &--ellipsis {
149
+ flex: 1;
150
+ }
151
+
152
+ &--input {
126
153
  color: $color-grey;
127
154
 
128
155
  .dito-icon--disabled {
129
156
  color: $color-light;
130
157
  }
131
- }
132
158
 
133
- @at-root .dito-component:focus-within:not(:has(.dito-component)) & {
134
- color: $color-active;
159
+ @at-root .dito-component:not(:has(.dito-component)):focus-within & {
160
+ color: $color-active;
161
+ }
135
162
  }
136
163
 
137
164
  &__clear {
@@ -148,7 +175,7 @@ export default DitoComponent.component('DitoAffixes', {
148
175
  padding: 0;
149
176
  border: 0;
150
177
 
151
- @at-root .dito-component:hover:not(:has(.dito-component)) & {
178
+ @at-root .dito-component:not(:has(.dito-component)):hover & {
152
179
  display: block;
153
180
  }
154
181
 
@@ -210,9 +210,9 @@ export default DitoComponent.component('DitoContainer', {
210
210
  const { class: classes } = this.schema
211
211
  const prefix = 'dito-container'
212
212
  return {
213
- [`${prefix}--single`]: this.single,
214
213
  [`${prefix}--disabled`]: this.componentDisabled,
215
214
  [`${prefix}--has-errors`]: !!this.errors,
215
+ [`${prefix}--single`]: this.single,
216
216
  [`${prefix}--compact`]: this.compact,
217
217
  [`${prefix}--label-vertical`]: this.verticalLabels,
218
218
  [`${prefix}--omit-spacing`]: omitSpacing(this.schema),
@@ -13,7 +13,7 @@ component.dito-label(
13
13
  .dito-label__inner(
14
14
  v-if="text || prefixes.length > 0 || suffixes.length > 0"
15
15
  )
16
- DitoAffixes.dito-label__prefix(
16
+ DitoAffixes(
17
17
  :items="prefixes"
18
18
  position="prefix"
19
19
  :parentContext="context"
@@ -23,8 +23,9 @@ component.dito-label(
23
23
  :for="dataPath"
24
24
  v-html="text"
25
25
  )
26
- DitoAffixes.dito-label__suffix(
26
+ DitoAffixes(
27
27
  :items="suffixes"
28
+ mode="ellipsis"
28
29
  position="suffix"
29
30
  :parentContext="context"
30
31
  )
@@ -117,9 +118,12 @@ export default DitoComponent.component('DitoLabel', {
117
118
  display: flex;
118
119
  align-items: center;
119
120
  overflow: hidden;
121
+ gap: $input-padding-hor;
120
122
  }
121
123
 
122
124
  label {
125
+ @include ellipsis;
126
+
123
127
  cursor: inherit;
124
128
  font-weight: bold;
125
129
  line-height: $input-height;
@@ -140,44 +144,6 @@ export default DitoComponent.component('DitoLabel', {
140
144
  transform: translateY(-4px);
141
145
  }
142
146
 
143
- &__prefix,
144
- &__suffix {
145
- flex: 1;
146
- position: relative;
147
- line-height: $input-height;
148
-
149
- // For ellipsis to work on prefix and suffix with flex layout, we need to
150
- // use a nested absolutely positioned span.
151
-
152
- &::before {
153
- content: '\200b'; // zero-width space to keep container from collapsing.
154
- }
155
-
156
- span {
157
- position: absolute;
158
- inset: 0;
159
- }
160
- }
161
-
162
- label,
163
- &__prefix span,
164
- &__suffix span {
165
- @include user-select(none);
166
- @include ellipsis;
167
-
168
- white-space: nowrap;
169
- }
170
-
171
- &__prefix + label,
172
- label + &__suffix {
173
- &,
174
- span {
175
- &::before {
176
- content: '\a0'; // &nbsp;
177
- }
178
- }
179
- }
180
-
181
147
  .dito-buttons {
182
148
  // Move the label padding inside .dito-buttons, so that it captures all
183
149
  // near mouse events:
@@ -23,7 +23,7 @@ export default DitoComponent.component('DitoNotifications', {
23
23
  },
24
24
 
25
25
  methods: {
26
- notify({ type = 'info', title, text, error } = {}) {
26
+ notify({ type = 'info', title, text, error, duration } = {}) {
27
27
  title ||= (
28
28
  {
29
29
  warning: 'Warning',
@@ -59,8 +59,13 @@ export default DitoComponent.component('DitoNotifications', {
59
59
  // amount of milliseconds multiplied with the amount of characters
60
60
  // displayed in the notification, plus 40 (40 + title + message):
61
61
  const { durationFactor = 20 } = notifications
62
- const duration = (40 + text.length + title.length) * durationFactor
63
- this.$notify({ type, title, text, duration })
62
+ duration ??= (40 + text.length + title.length) * durationFactor
63
+ this.$notify({
64
+ type,
65
+ title,
66
+ text,
67
+ duration: duration === 0 ? -1 : duration // < 0 -> <= 0 = sticky
68
+ })
64
69
  }
65
70
  },
66
71
 
@@ -65,8 +65,8 @@ export default DitoComponent.component('DitoPane', {
65
65
  meta: { type: Object, required: true },
66
66
  store: { type: Object, required: true },
67
67
  tab: { type: String, default: null },
68
- padding: { type: String, default: null },
69
68
  single: { type: Boolean, default: false },
69
+ padding: { type: String, default: null },
70
70
  disabled: { type: Boolean, default: false },
71
71
  compact: { type: Boolean, default: false },
72
72
  generateLabels: { type: Boolean, default: false },
@@ -86,9 +86,10 @@ export default DitoComponent.component('DitoPane', {
86
86
  },
87
87
 
88
88
  classes() {
89
+ const prefix = 'dito-pane'
89
90
  return {
90
- 'dito-pane--single': this.isSingleComponent,
91
- [`dito-pane--padding-${this.padding}`]: !!this.padding
91
+ [`${prefix}--single`]: this.isSingleComponent,
92
+ [`${prefix}--padding-${this.padding}`]: !!this.padding
92
93
  }
93
94
  },
94
95
 
@@ -72,7 +72,7 @@ slot(name="prepend")
72
72
  :meta="meta"
73
73
  :store="store"
74
74
  :padding="padding"
75
- :single="!inlined && !hasMainPane"
75
+ :single="single && !inlined && !hasMainPane"
76
76
  :disabled="disabled"
77
77
  :compact="compact"
78
78
  :generateLabels="generateLabels"
@@ -87,7 +87,7 @@ slot(name="prepend")
87
87
  :meta="meta"
88
88
  :store="store"
89
89
  :padding="padding"
90
- :single="!inlined && !hasTabs"
90
+ :single="single && !inlined && !hasTabs"
91
91
  :disabled="disabled"
92
92
  :compact="compact"
93
93
  :generateLabels="generateLabels"
@@ -156,6 +156,7 @@ export default DitoComponent.component('DitoSchema', {
156
156
  meta: { type: Object, default: () => ({}) },
157
157
  store: { type: Object, default: () => ({}) },
158
158
  label: { type: [String, Object], default: null },
159
+ single: { type: Boolean, default: false },
159
160
  padding: { type: String, default: null },
160
161
  active: { type: Boolean, default: true },
161
162
  inlined: { type: Boolean, default: false },
@@ -23,6 +23,7 @@ template(
23
23
  padding="root"
24
24
  :disabled="isLoading"
25
25
  scrollable
26
+ single
26
27
  )
27
28
  </template>
28
29
 
@@ -101,6 +101,17 @@ export default {
101
101
  type: String
102
102
  }),
103
103
 
104
+ info: getSchemaAccessor('info', {
105
+ type: String,
106
+ default: null
107
+ }),
108
+
109
+ inlineInfo() {
110
+ // When a label is present, info is shown in the label component.
111
+ // Otherwise, we have to show it inline.
112
+ return !this.label ? this.info : null
113
+ },
114
+
104
115
  events() {
105
116
  const events = this.getEvents()
106
117
  // Register callbacks for all provides non-recognized events,
@@ -72,11 +72,6 @@ export default DitoTypeComponent.register(
72
72
  return this.text || labelize(this.verb)
73
73
  },
74
74
 
75
- info: getSchemaAccessor('info', {
76
- type: String,
77
- default: null
78
- }),
79
-
80
75
  prefixes() {
81
76
  return asArray(this.schema.prefix)
82
77
  },
@@ -17,6 +17,7 @@ DitoTrigger.dito-color(
17
17
  DitoAffixes(
18
18
  :items="schema.prefix"
19
19
  position="prefix"
20
+ mode="input"
20
21
  :disabled="disabled"
21
22
  :parentContext="context"
22
23
  )
@@ -24,8 +25,10 @@ DitoTrigger.dito-color(
24
25
  DitoAffixes(
25
26
  :items="schema.suffix"
26
27
  position="suffix"
28
+ mode="input"
27
29
  :clearable="showClearButton"
28
30
  :disabled="disabled"
31
+ :inlineInfo="inlineInfo"
29
32
  :parentContext="context"
30
33
  @clear="clear"
31
34
  )
@@ -13,6 +13,7 @@
13
13
  DitoAffixes(
14
14
  :items="schema.prefix"
15
15
  position="prefix"
16
+ mode="input"
16
17
  absolute
17
18
  :disabled="disabled"
18
19
  :parentContext="context"
@@ -21,9 +22,11 @@
21
22
  DitoAffixes(
22
23
  :items="schema.suffix"
23
24
  position="suffix"
25
+ mode="input"
24
26
  absolute
25
27
  :clearable="showClearButton"
26
28
  :disabled="disabled"
29
+ :inlineInfo="inlineInfo"
27
30
  :parentContext="context"
28
31
  @clear="clear"
29
32
  )
@@ -4,6 +4,7 @@
4
4
  DitoAffixes(
5
5
  :items="schema.prefix"
6
6
  position="prefix"
7
+ mode="input"
7
8
  absolute
8
9
  :disabled="disabled"
9
10
  :parentContext="context"
@@ -37,9 +38,11 @@
37
38
  DitoAffixes(
38
39
  :items="schema.suffix"
39
40
  position="suffix"
41
+ mode="input"
40
42
  absolute
41
43
  :clearable="showClearButton"
42
44
  :disabled="disabled"
45
+ :inlineInfo="inlineInfo"
43
46
  :parentContext="context"
44
47
  @clear="clear"
45
48
  )
@@ -13,6 +13,7 @@ DitoInput.dito-number(
13
13
  DitoAffixes(
14
14
  :items="schema.prefix"
15
15
  position="prefix"
16
+ mode="input"
16
17
  :disabled="disabled"
17
18
  :parentContext="context"
18
19
  )
@@ -20,8 +21,10 @@ DitoInput.dito-number(
20
21
  DitoAffixes(
21
22
  :items="schema.suffix"
22
23
  position="suffix"
24
+ mode="input"
23
25
  :clearable="showClearButton"
24
26
  :disabled="disabled"
27
+ :inlineInfo="inlineInfo"
25
28
  :parentContext="context"
26
29
  @clear="clear"
27
30
  )
@@ -5,6 +5,7 @@
5
5
  DitoAffixes(
6
6
  :items="schema.prefix"
7
7
  position="prefix"
8
+ mode="input"
8
9
  absolute
9
10
  :disabled="disabled"
10
11
  :parentContext="context"
@@ -42,9 +43,11 @@
42
43
  DitoAffixes(
43
44
  :items="schema.suffix"
44
45
  position="suffix"
46
+ mode="input"
45
47
  absolute
46
48
  :clearable="showClearButton"
47
49
  :disabled="disabled"
50
+ :inlineInfo="inlineInfo"
48
51
  :parentContext="context"
49
52
  @clear="clear"
50
53
  )
@@ -10,6 +10,7 @@ DitoInput.dito-text(
10
10
  DitoAffixes(
11
11
  :items="schema.prefix"
12
12
  position="prefix"
13
+ mode="input"
13
14
  :disabled="disabled"
14
15
  :parentContext="context"
15
16
  )
@@ -17,8 +18,10 @@ DitoInput.dito-text(
17
18
  DitoAffixes(
18
19
  :items="schema.suffix"
19
20
  position="suffix"
21
+ mode="input"
20
22
  :clearable="showClearButton"
21
23
  :disabled="disabled"
24
+ :inlineInfo="inlineInfo"
22
25
  :parentContext="context"
23
26
  @clear="clear"
24
27
  )