@ditojs/admin 2.0.5 → 2.1.1
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 +1511 -1435
- package/dist/dito-admin.umd.js +4 -4
- package/dist/style.css +1 -1
- package/package.json +31 -31
- package/src/DitoAdmin.js +66 -31
- package/src/DitoComponent.js +4 -1
- package/src/DitoContext.js +13 -5
- package/src/{TypeComponent.js → DitoTypeComponent.js} +8 -5
- package/src/components/DitoAccount.vue +20 -19
- package/src/components/DitoButtons.vue +14 -12
- package/src/components/DitoClipboard.vue +16 -8
- package/src/components/DitoContainer.vue +56 -43
- package/src/components/DitoCreateButton.vue +20 -15
- package/src/components/DitoDialog.vue +69 -48
- package/src/components/DitoEditButtons.vue +16 -14
- package/src/components/DitoElement.vue +2 -3
- package/src/components/DitoErrors.vue +18 -13
- package/src/components/DitoForm.vue +41 -24
- package/src/components/DitoFormNested.vue +12 -10
- package/src/components/DitoHeader.vue +103 -69
- package/src/components/DitoLabel.vue +108 -81
- package/src/components/DitoMenu.vue +52 -36
- package/src/components/DitoPagination.vue +9 -7
- package/src/components/DitoPane.vue +53 -45
- package/src/components/DitoPanel.vue +62 -42
- package/src/components/DitoPanels.vue +11 -10
- package/src/components/DitoRoot.vue +57 -46
- package/src/components/DitoSchema.vue +179 -131
- package/src/components/DitoSchemaInlined.vue +39 -28
- package/src/components/DitoScopes.vue +41 -31
- package/src/components/DitoSpinner.vue +31 -40
- package/src/components/DitoTableCell.vue +9 -9
- package/src/components/DitoTableHead.vue +52 -37
- package/src/components/DitoTabs.vue +39 -29
- package/src/components/DitoTreeItem.vue +140 -86
- package/src/components/DitoVNode.vue +1 -1
- package/src/components/DitoView.vue +13 -11
- package/src/mixins/DataMixin.js +11 -9
- package/src/mixins/DitoMixin.js +47 -25
- package/src/mixins/EmitterMixin.js +2 -1
- package/src/mixins/ItemMixin.js +15 -10
- package/src/mixins/LoadingMixin.js +2 -1
- package/src/mixins/NumberMixin.js +15 -10
- package/src/mixins/OptionsMixin.js +24 -12
- package/src/mixins/ResourceMixin.js +42 -34
- package/src/mixins/RouteMixin.js +8 -8
- package/src/mixins/SortableMixin.js +1 -1
- package/src/mixins/SourceMixin.js +68 -34
- package/src/mixins/TypeMixin.js +5 -4
- package/src/mixins/ValidationMixin.js +3 -0
- package/src/styles/_base.scss +17 -0
- package/src/styles/_button.scss +212 -0
- package/src/styles/_imports.scss +2 -0
- package/src/styles/_layout.scss +22 -0
- package/src/styles/_notifications.scss +54 -0
- package/src/styles/_pulldown.scss +39 -0
- package/src/styles/_scroll.scss +15 -0
- package/src/styles/_settings.scss +68 -0
- package/src/styles/_sortable.scss +13 -0
- package/src/styles/_table.scss +224 -0
- package/src/styles/style.scss +9 -0
- package/src/types/DitoTypeButton.vue +72 -0
- package/src/types/{TypeCheckbox.vue → DitoTypeCheckbox.vue} +12 -11
- package/src/types/{TypeCheckboxes.vue → DitoTypeCheckboxes.vue} +21 -15
- package/src/types/{TypeCode.vue → DitoTypeCode.vue} +46 -34
- package/src/types/{TypeColor.vue → DitoTypeColor.vue} +71 -52
- package/src/types/{TypeComponent.vue → DitoTypeComponent.vue} +2 -2
- package/src/types/DitoTypeComputed.vue +54 -0
- package/src/types/DitoTypeDate.vue +64 -0
- package/src/types/DitoTypeLabel.vue +23 -0
- package/src/types/{TypeList.vue → DitoTypeList.vue} +83 -61
- package/src/types/{TypeMarkup.vue → DitoTypeMarkup.vue} +172 -122
- package/src/types/DitoTypeMultiselect.vue +434 -0
- package/src/types/DitoTypeNumber.vue +46 -0
- package/src/types/{TypeObject.vue → DitoTypeObject.vue} +41 -26
- package/src/types/{TypePanel.vue → DitoTypePanel.vue} +2 -2
- package/src/types/{TypeProgress.vue → DitoTypeProgress.vue} +4 -6
- package/src/types/{TypeRadio.vue → DitoTypeRadio.vue} +17 -13
- package/src/types/{TypeSection.vue → DitoTypeSection.vue} +17 -17
- package/src/types/{TypeSelect.vue → DitoTypeSelect.vue} +39 -35
- package/src/types/{TypeSlider.vue → DitoTypeSlider.vue} +29 -23
- package/src/types/{TypeSwitch.vue → DitoTypeSwitch.vue} +15 -13
- package/src/types/DitoTypeText.vue +77 -0
- package/src/types/{TypeTextarea.vue → DitoTypeTextarea.vue} +17 -14
- package/src/types/DitoTypeTreeList.vue +191 -0
- package/src/types/{TypeUpload.vue → DitoTypeUpload.vue} +92 -65
- package/src/types/index.js +26 -26
- package/src/utils/SchemaGraph.js +21 -13
- package/src/utils/accessor.js +17 -9
- package/src/utils/data.js +4 -1
- package/src/utils/filter.js +8 -10
- package/src/utils/options.js +3 -3
- package/src/utils/resource.js +12 -10
- package/src/utils/schema.js +190 -125
- package/src/utils/type.js +31 -20
- package/src/validations/_decimals.js +1 -2
- package/types/index.d.ts +27 -23
- package/src/styles/_base.sass +0 -15
- package/src/styles/_button.sass +0 -127
- package/src/styles/_imports.sass +0 -2
- package/src/styles/_layout.sass +0 -13
- package/src/styles/_notifications.sass +0 -33
- package/src/styles/_pulldown.sass +0 -26
- package/src/styles/_scroll.sass +0 -13
- package/src/styles/_settings.sass +0 -55
- package/src/styles/_sortable.sass +0 -9
- package/src/styles/_table.sass +0 -153
- package/src/styles/style.sass +0 -10
- package/src/types/TypeButton.vue +0 -73
- package/src/types/TypeComputed.vue +0 -53
- package/src/types/TypeDate.vue +0 -64
- package/src/types/TypeLabel.vue +0 -19
- package/src/types/TypeMultiselect.vue +0 -376
- package/src/types/TypeNumber.vue +0 -44
- package/src/types/TypeText.vue +0 -67
- package/src/types/TypeTreeList.vue +0 -164
|
@@ -28,7 +28,7 @@ import { appendDataPath } from '../utils/data.js'
|
|
|
28
28
|
import { escapeHtml } from '@ditojs/utils'
|
|
29
29
|
|
|
30
30
|
// @vue/component
|
|
31
|
-
export default DitoComponent.component('
|
|
31
|
+
export default DitoComponent.component('DitoTableCell', {
|
|
32
32
|
props: {
|
|
33
33
|
cell: { type: Object, required: true },
|
|
34
34
|
schema: { type: Object, required: true },
|
|
@@ -46,14 +46,14 @@ export default DitoComponent.component('dito-table-cell', {
|
|
|
46
46
|
const value = item[name]
|
|
47
47
|
return render
|
|
48
48
|
? render.call(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
this,
|
|
50
|
+
new DitoContext(this, {
|
|
51
|
+
name,
|
|
52
|
+
value,
|
|
53
|
+
data: item,
|
|
54
|
+
dataPath: appendDataPath(this.dataPath, name)
|
|
55
|
+
})
|
|
56
|
+
)
|
|
57
57
|
: escapeHtml(value)
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
thead.dito-table-head
|
|
3
3
|
tr
|
|
4
4
|
template(
|
|
5
|
-
v-for="
|
|
5
|
+
v-for="column in columns"
|
|
6
6
|
)
|
|
7
7
|
th(
|
|
8
8
|
v-if="shouldRender(column)"
|
|
9
9
|
:class="getColumnClass(column)"
|
|
10
10
|
)
|
|
11
|
-
|
|
11
|
+
RouterLink(
|
|
12
12
|
v-if="column.sortable"
|
|
13
|
+
v-slot="{ navigate }"
|
|
13
14
|
:to="getSortLink(column)"
|
|
14
15
|
custom
|
|
15
|
-
v-slot="{ navigate }"
|
|
16
16
|
)
|
|
17
17
|
button.dito-button(
|
|
18
18
|
type="button"
|
|
@@ -24,45 +24,19 @@ thead.dito-table-head
|
|
|
24
24
|
span(
|
|
25
25
|
v-else
|
|
26
26
|
) {{ getLabel(column) }}
|
|
27
|
-
th(
|
|
28
|
-
|
|
27
|
+
th(
|
|
28
|
+
v-if="hasEditButtons"
|
|
29
|
+
)
|
|
30
|
+
//- Empty <span> is needed for styling, see _table.scss
|
|
29
31
|
span
|
|
30
32
|
</template>
|
|
31
33
|
|
|
32
|
-
<style lang="sass">
|
|
33
|
-
@import '../styles/_imports'
|
|
34
|
-
|
|
35
|
-
.dito-table-head
|
|
36
|
-
+user-select(none)
|
|
37
|
-
tr
|
|
38
|
-
th
|
|
39
|
-
padding: 0
|
|
40
|
-
font-weight: normal
|
|
41
|
-
text-align: left
|
|
42
|
-
white-space: nowrap
|
|
43
|
-
.dito-button
|
|
44
|
-
// Convention: Nested spans handle padding, see below
|
|
45
|
-
padding: 0
|
|
46
|
-
width: 100%
|
|
47
|
-
text-align: inherit
|
|
48
|
-
border-radius: 0
|
|
49
|
-
span
|
|
50
|
-
display: inline-block
|
|
51
|
-
// Convention: Nested spans handle padding
|
|
52
|
-
padding: $input-padding
|
|
53
|
-
&:empty::after
|
|
54
|
-
// Prevent empty <th> from collapsing
|
|
55
|
-
content: '\200b' // zero-width space
|
|
56
|
-
> span
|
|
57
|
-
display: block
|
|
58
|
-
</style>
|
|
59
|
-
|
|
60
34
|
<script>
|
|
61
35
|
import DitoComponent from '../DitoComponent.js'
|
|
62
36
|
import { hyphenate } from '@ditojs/utils'
|
|
63
37
|
|
|
64
38
|
// @vue/component
|
|
65
|
-
export default DitoComponent.component('
|
|
39
|
+
export default DitoComponent.component('DitoTableHead', {
|
|
66
40
|
props: {
|
|
67
41
|
query: { type: Object, required: true },
|
|
68
42
|
columns: { type: Object, required: true },
|
|
@@ -92,9 +66,10 @@ export default DitoComponent.component('dito-table-head', {
|
|
|
92
66
|
|
|
93
67
|
getSortLink(column) {
|
|
94
68
|
// Toggle order if the same column is clicked again.
|
|
95
|
-
const order =
|
|
96
|
-
|
|
97
|
-
|
|
69
|
+
const order =
|
|
70
|
+
this.sort.name === column.name && this.sort.order === 'asc'
|
|
71
|
+
? 'desc'
|
|
72
|
+
: 'asc'
|
|
98
73
|
return this.getQueryLink({
|
|
99
74
|
...this.query,
|
|
100
75
|
order: `${column.name} ${order}`
|
|
@@ -103,3 +78,43 @@ export default DitoComponent.component('dito-table-head', {
|
|
|
103
78
|
}
|
|
104
79
|
})
|
|
105
80
|
</script>
|
|
81
|
+
|
|
82
|
+
<style lang="scss">
|
|
83
|
+
@import '../styles/_imports';
|
|
84
|
+
|
|
85
|
+
.dito-table-head {
|
|
86
|
+
@include user-select(none);
|
|
87
|
+
|
|
88
|
+
tr {
|
|
89
|
+
th {
|
|
90
|
+
padding: 0;
|
|
91
|
+
font-weight: normal;
|
|
92
|
+
text-align: left;
|
|
93
|
+
white-space: nowrap;
|
|
94
|
+
|
|
95
|
+
.dito-button {
|
|
96
|
+
// Convention: Nested spans handle padding, see below
|
|
97
|
+
padding: 0;
|
|
98
|
+
width: 100%;
|
|
99
|
+
text-align: inherit;
|
|
100
|
+
border-radius: 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
span {
|
|
104
|
+
display: inline-block;
|
|
105
|
+
// Convention: Nested spans handle padding
|
|
106
|
+
padding: $input-padding;
|
|
107
|
+
|
|
108
|
+
&:empty::after {
|
|
109
|
+
// Prevent empty <th> from collapsing
|
|
110
|
+
content: '\200b'; // zero-width space;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
> span {
|
|
115
|
+
display: block;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
</style>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
template(
|
|
4
4
|
v-for="(tabSchema, key) in tabs"
|
|
5
5
|
)
|
|
6
|
-
|
|
6
|
+
RouterLink.dito-link(
|
|
7
7
|
v-if="shouldRender(tabSchema)"
|
|
8
8
|
:key="key"
|
|
9
9
|
:to="{ hash: `#${key}` }"
|
|
@@ -11,41 +11,51 @@
|
|
|
11
11
|
) {{ getLabel(tabSchema, key) }}
|
|
12
12
|
</template>
|
|
13
13
|
|
|
14
|
-
<style lang="sass">
|
|
15
|
-
@import '../styles/_imports'
|
|
16
|
-
|
|
17
|
-
$tab-color-background: $color-lightest
|
|
18
|
-
$tab-color-inactive: $color-light
|
|
19
|
-
$tab-color-active: $color-lightest
|
|
20
|
-
$tab-color-hover: $color-white
|
|
21
|
-
|
|
22
|
-
.dito-tabs
|
|
23
|
-
// See: https://codepen.io/tholex/pen/hveBx/
|
|
24
|
-
margin-left: auto
|
|
25
|
-
a
|
|
26
|
-
display: block
|
|
27
|
-
+user-select(none)
|
|
28
|
-
background: $tab-color-inactive
|
|
29
|
-
padding: $tab-padding-ver $tab-padding-hor
|
|
30
|
-
margin-left: $tab-margin
|
|
31
|
-
border-top-left-radius: $tab-radius
|
|
32
|
-
border-top-right-radius: $tab-radius
|
|
33
|
-
&:hover
|
|
34
|
-
background: $tab-color-hover
|
|
35
|
-
&:active
|
|
36
|
-
background: $tab-color-active
|
|
37
|
-
&.dito-active
|
|
38
|
-
background: $tab-color-background
|
|
39
|
-
</style>
|
|
40
|
-
|
|
41
14
|
<script>
|
|
42
15
|
import DitoComponent from '../DitoComponent.js'
|
|
43
16
|
|
|
44
17
|
// @vue/component
|
|
45
|
-
export default DitoComponent.component('
|
|
18
|
+
export default DitoComponent.component('DitoTabs', {
|
|
46
19
|
props: {
|
|
47
20
|
tabs: { type: Object, default: null },
|
|
48
21
|
selectedTab: { type: String, default: null }
|
|
49
22
|
}
|
|
50
23
|
})
|
|
51
24
|
</script>
|
|
25
|
+
|
|
26
|
+
<style lang="scss">
|
|
27
|
+
@import '../styles/_imports';
|
|
28
|
+
|
|
29
|
+
$tab-color-background: $color-lightest;
|
|
30
|
+
$tab-color-inactive: $color-light;
|
|
31
|
+
$tab-color-active: $color-lightest;
|
|
32
|
+
$tab-color-hover: $color-white;
|
|
33
|
+
|
|
34
|
+
.dito-tabs {
|
|
35
|
+
// See: https://codepen.io/tholex/pen/hveBx/
|
|
36
|
+
margin-left: auto;
|
|
37
|
+
|
|
38
|
+
a {
|
|
39
|
+
display: block;
|
|
40
|
+
@include user-select(none);
|
|
41
|
+
|
|
42
|
+
background: $tab-color-inactive;
|
|
43
|
+
padding: $tab-padding-ver $tab-padding-hor;
|
|
44
|
+
margin-left: $tab-margin;
|
|
45
|
+
border-top-left-radius: $tab-radius;
|
|
46
|
+
border-top-right-radius: $tab-radius;
|
|
47
|
+
|
|
48
|
+
&:hover {
|
|
49
|
+
background: $tab-color-hover;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&:active {
|
|
53
|
+
background: $tab-color-active;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&.dito-active {
|
|
57
|
+
background: $tab-color-background;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
</style>
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
}`
|
|
8
8
|
:style="level > 0 && { '--level': level }"
|
|
9
9
|
)
|
|
10
|
-
.dito-tree-header(
|
|
10
|
+
.dito-tree-header(
|
|
11
|
+
v-if="label"
|
|
12
|
+
)
|
|
11
13
|
.dito-tree-branch(
|
|
12
14
|
v-if="numEntries"
|
|
13
15
|
@click.stop="opened = !opened"
|
|
@@ -16,11 +18,21 @@
|
|
|
16
18
|
v-if="numEntries"
|
|
17
19
|
:class="{ 'dito-opened': opened }"
|
|
18
20
|
)
|
|
19
|
-
.dito-tree-label(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
.dito-tree-
|
|
23
|
-
|
|
21
|
+
.dito-tree-label(
|
|
22
|
+
v-html="label"
|
|
23
|
+
)
|
|
24
|
+
.dito-tree-info(
|
|
25
|
+
v-if="details"
|
|
26
|
+
) {{ details }}
|
|
27
|
+
.dito-tree-leaf(
|
|
28
|
+
v-else
|
|
29
|
+
)
|
|
30
|
+
.dito-tree-label(
|
|
31
|
+
v-html="label"
|
|
32
|
+
)
|
|
33
|
+
.dito-buttons.dito-buttons-small(
|
|
34
|
+
v-if="hasEditButtons"
|
|
35
|
+
)
|
|
24
36
|
//- Firefox doesn't like <button> here, so use <a> instead:
|
|
25
37
|
a.dito-button(
|
|
26
38
|
v-if="draggable"
|
|
@@ -29,14 +41,14 @@
|
|
|
29
41
|
button.dito-button(
|
|
30
42
|
v-if="editable"
|
|
31
43
|
type="button"
|
|
32
|
-
@click="onEdit"
|
|
33
44
|
v-bind="getButtonAttributes(verbs.edit)"
|
|
45
|
+
@click="onEdit"
|
|
34
46
|
)
|
|
35
47
|
button.dito-button(
|
|
36
48
|
v-if="deletable"
|
|
37
49
|
type="button"
|
|
38
|
-
@click="onDelete"
|
|
39
50
|
v-bind="getButtonAttributes(verbs.delete)"
|
|
51
|
+
@click="onDelete"
|
|
40
52
|
)
|
|
41
53
|
table.dito-properties(
|
|
42
54
|
v-if="properties"
|
|
@@ -46,12 +58,12 @@
|
|
|
46
58
|
v-for="property in properties"
|
|
47
59
|
)
|
|
48
60
|
td
|
|
49
|
-
|
|
61
|
+
DitoLabel(
|
|
50
62
|
v-if="property.label !== false"
|
|
51
63
|
:dataPath="getPropertyDataPath(property)"
|
|
52
64
|
:label="getLabel(property)"
|
|
53
65
|
)
|
|
54
|
-
|
|
66
|
+
DitoTableCell(
|
|
55
67
|
:cell="property"
|
|
56
68
|
:schema="property"
|
|
57
69
|
:dataPath="getPropertyDataPath(property)"
|
|
@@ -60,14 +72,14 @@
|
|
|
60
72
|
:store="store"
|
|
61
73
|
:disabled="disabled"
|
|
62
74
|
)
|
|
63
|
-
|
|
75
|
+
UseSortable(
|
|
64
76
|
v-if="childrenSchema"
|
|
65
77
|
v-show="opened"
|
|
66
78
|
:modelValue="updateOrder(childrenSchema, childrenList)"
|
|
67
|
-
@update:modelValue="value => childrenList = value"
|
|
68
79
|
:options="getSortableOptions(childrenDraggable, true)"
|
|
80
|
+
@update:modelValue="value => (childrenList = value)"
|
|
69
81
|
)
|
|
70
|
-
|
|
82
|
+
DitoTreeItem(
|
|
71
83
|
v-for="(item, index) in childrenItems"
|
|
72
84
|
:key="getItemUid(childrenSchema, item.data)"
|
|
73
85
|
:schema="childrenSchema"
|
|
@@ -84,71 +96,6 @@
|
|
|
84
96
|
//- pass `asObject: true` in the `getItemLabel()` call above.
|
|
85
97
|
</template>
|
|
86
98
|
|
|
87
|
-
<style lang="sass">
|
|
88
|
-
@import '../styles/_imports'
|
|
89
|
-
|
|
90
|
-
.dito-tree-item
|
|
91
|
-
--chevron-indent: #{$chevron-indent}
|
|
92
|
-
> .dito-tree-header
|
|
93
|
-
> .dito-tree-branch,
|
|
94
|
-
> .dito-tree-leaf
|
|
95
|
-
// Use `--level` CSS variable to calculated the accumulated indent
|
|
96
|
-
// padding directly instead of having it accumulate in nested CSS.
|
|
97
|
-
// This way, we can keep the .dito-active area cover the full width:
|
|
98
|
-
padding-left: calc(var(--chevron-indent) * (var(--level, 1) - 1))
|
|
99
|
-
.dito-tree-branch
|
|
100
|
-
cursor: pointer
|
|
101
|
-
.dito-tree-header
|
|
102
|
-
display: flex
|
|
103
|
-
justify-content: space-between
|
|
104
|
-
.dito-tree-branch,
|
|
105
|
-
.dito-tree-leaf
|
|
106
|
-
display: flex
|
|
107
|
-
flex: auto
|
|
108
|
-
position: relative
|
|
109
|
-
margin: 1px 0
|
|
110
|
-
+user-select(none)
|
|
111
|
-
.dito-tree-label,
|
|
112
|
-
.dito-tree-info
|
|
113
|
-
white-space: nowrap
|
|
114
|
-
.dito-tree-info
|
|
115
|
-
padding-left: 0.35em
|
|
116
|
-
color: rgba($color-black, .2)
|
|
117
|
-
.dito-buttons
|
|
118
|
-
display: flex
|
|
119
|
-
visibility: hidden
|
|
120
|
-
height: 100%
|
|
121
|
-
margin-left: 1em
|
|
122
|
-
margin: 1px 0 1px 1em
|
|
123
|
-
.dito-tree-header:hover
|
|
124
|
-
> .dito-buttons
|
|
125
|
-
visibility: visible
|
|
126
|
-
// Hide buttons during dragging
|
|
127
|
-
&.dito-dragging
|
|
128
|
-
.dito-tree-header
|
|
129
|
-
> .dito-buttons
|
|
130
|
-
visibility: hidden
|
|
131
|
-
&.dito-active
|
|
132
|
-
> .dito-tree-header
|
|
133
|
-
background: $color-active
|
|
134
|
-
padding: 0 $input-padding-hor
|
|
135
|
-
margin: 0 (-$input-padding-hor)
|
|
136
|
-
> .dito-tree-branch
|
|
137
|
-
> .dito-chevron::before
|
|
138
|
-
color: $color-white
|
|
139
|
-
> * > .dito-tree-label
|
|
140
|
-
color: $color-white
|
|
141
|
-
.dito-properties
|
|
142
|
-
display: block
|
|
143
|
-
margin-left: $chevron-indent
|
|
144
|
-
> tr
|
|
145
|
-
vertical-align: baseline
|
|
146
|
-
.dito-label
|
|
147
|
-
margin: 0
|
|
148
|
-
&::after
|
|
149
|
-
content: ': '
|
|
150
|
-
</style>
|
|
151
|
-
|
|
152
99
|
<script>
|
|
153
100
|
import DitoComponent from '../DitoComponent.js'
|
|
154
101
|
import SortableMixin from '../mixins/SortableMixin.js'
|
|
@@ -157,7 +104,7 @@ import { getSchemaAccessor } from '../utils/accessor.js'
|
|
|
157
104
|
import { getNamedSchemas, hasFormSchema } from '../utils/schema.js'
|
|
158
105
|
|
|
159
106
|
// @vue/component
|
|
160
|
-
export default DitoComponent.component('
|
|
107
|
+
export default DitoComponent.component('DitoTreeItem', {
|
|
161
108
|
mixins: [SortableMixin],
|
|
162
109
|
inject: ['container'],
|
|
163
110
|
|
|
@@ -247,11 +194,13 @@ export default DitoComponent.component('dito-tree-item', {
|
|
|
247
194
|
childrenList.map((data, index) => {
|
|
248
195
|
const path = (
|
|
249
196
|
childrenSchema.path &&
|
|
250
|
-
|
|
197
|
+
`${this.path}/${childrenSchema.path}/${index}`
|
|
198
|
+
)
|
|
199
|
+
const open = (
|
|
200
|
+
childrenOpen ||
|
|
201
|
+
// Only count as "in edit path" when it's not the full edit path.
|
|
202
|
+
editPath.startsWith(path) && path.length < editPath.length
|
|
251
203
|
)
|
|
252
|
-
const open = childrenOpen ||
|
|
253
|
-
// Only count as "in edit path" when it's not the full edit path.
|
|
254
|
-
editPath.startsWith(path) && path.length < editPath.length
|
|
255
204
|
const active = editPath === path
|
|
256
205
|
return {
|
|
257
206
|
data,
|
|
@@ -267,9 +216,12 @@ export default DitoComponent.component('dito-tree-item', {
|
|
|
267
216
|
|
|
268
217
|
details() {
|
|
269
218
|
const { numChildren } = this
|
|
270
|
-
return
|
|
271
|
-
numChildren
|
|
272
|
-
|
|
219
|
+
return (
|
|
220
|
+
numChildren &&
|
|
221
|
+
`${numChildren} ${
|
|
222
|
+
numChildren === 1 ? 'item' : 'items'
|
|
223
|
+
}`
|
|
224
|
+
)
|
|
273
225
|
},
|
|
274
226
|
|
|
275
227
|
hasEditButtons() {
|
|
@@ -327,3 +279,105 @@ export default DitoComponent.component('dito-tree-item', {
|
|
|
327
279
|
}
|
|
328
280
|
})
|
|
329
281
|
</script>
|
|
282
|
+
|
|
283
|
+
<style lang="scss">
|
|
284
|
+
@import '../styles/_imports';
|
|
285
|
+
|
|
286
|
+
.dito-tree-item {
|
|
287
|
+
--chevron-indent: #{$chevron-indent};
|
|
288
|
+
|
|
289
|
+
> .dito-tree-header {
|
|
290
|
+
> .dito-tree-branch,
|
|
291
|
+
> .dito-tree-leaf {
|
|
292
|
+
// Use `--level` CSS variable to calculated the accumulated indent
|
|
293
|
+
// padding directly instead of having it accumulate in nested CSS.
|
|
294
|
+
// This way, we can keep the .dito-active area cover the full width:
|
|
295
|
+
padding-left: calc(var(--chevron-indent) * (var(--level, 1) - 1));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.dito-tree-branch {
|
|
300
|
+
cursor: pointer;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.dito-tree-header {
|
|
304
|
+
display: flex;
|
|
305
|
+
justify-content: space-between;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.dito-tree-branch,
|
|
309
|
+
.dito-tree-leaf {
|
|
310
|
+
display: flex;
|
|
311
|
+
flex: auto;
|
|
312
|
+
position: relative;
|
|
313
|
+
margin: 1px 0;
|
|
314
|
+
@include user-select(none);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.dito-tree-label,
|
|
318
|
+
.dito-tree-info {
|
|
319
|
+
white-space: nowrap;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.dito-tree-info {
|
|
323
|
+
padding-left: 0.35em;
|
|
324
|
+
color: rgba($color-black, 0.2);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.dito-buttons {
|
|
328
|
+
display: flex;
|
|
329
|
+
visibility: hidden;
|
|
330
|
+
height: 100%;
|
|
331
|
+
margin: 1px 0 1px 1em;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.dito-tree-header:hover {
|
|
335
|
+
> .dito-buttons {
|
|
336
|
+
visibility: visible;
|
|
337
|
+
} // Hide buttons during dragging
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
&.dito-dragging {
|
|
341
|
+
.dito-tree-header {
|
|
342
|
+
> .dito-buttons {
|
|
343
|
+
visibility: hidden;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
&.dito-active {
|
|
349
|
+
> .dito-tree-header {
|
|
350
|
+
background: $color-active;
|
|
351
|
+
padding: 0 $input-padding-hor;
|
|
352
|
+
margin: 0 (-$input-padding-hor);
|
|
353
|
+
|
|
354
|
+
> .dito-tree-branch {
|
|
355
|
+
> .dito-chevron::before {
|
|
356
|
+
color: $color-white;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
> * > .dito-tree-label {
|
|
361
|
+
color: $color-white;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.dito-properties {
|
|
367
|
+
display: block;
|
|
368
|
+
margin-left: $chevron-indent;
|
|
369
|
+
|
|
370
|
+
> tr {
|
|
371
|
+
vertical-align: baseline;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.dito-label {
|
|
375
|
+
margin: 0;
|
|
376
|
+
|
|
377
|
+
&::after {
|
|
378
|
+
content: ': ';
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
</style>
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
template(
|
|
2
|
+
template(
|
|
3
|
+
v-if="user"
|
|
4
|
+
)
|
|
3
5
|
//- Only render DitoView when it is active, otherwise a normal router-view
|
|
4
6
|
//- instead, to nest further route components.
|
|
5
7
|
//- NOTE: This is different from the handling in DitoForm, where `v-show` is
|
|
6
8
|
//- used to always render forms even when other nested forms are present.
|
|
7
|
-
|
|
9
|
+
RouterView(
|
|
8
10
|
v-if="!isLastRoute"
|
|
9
11
|
:key="name"
|
|
10
12
|
)
|
|
@@ -12,7 +14,7 @@ template(v-if="user")
|
|
|
12
14
|
v-else-if="shouldRender(viewSchema)"
|
|
13
15
|
:data-resource="sourceSchema.path"
|
|
14
16
|
)
|
|
15
|
-
|
|
17
|
+
DitoSchema.dito-scroll(
|
|
16
18
|
:schema="viewSchema"
|
|
17
19
|
:data="data"
|
|
18
20
|
:meta="meta"
|
|
@@ -30,7 +32,7 @@ import { someSchemaComponent, isSingleComponentView } from '../utils/schema.js'
|
|
|
30
32
|
import { hasResource } from '../utils/resource.js'
|
|
31
33
|
|
|
32
34
|
// @vue/component
|
|
33
|
-
export default DitoComponent.component('
|
|
35
|
+
export default DitoComponent.component('DitoView', {
|
|
34
36
|
mixins: [RouteMixin],
|
|
35
37
|
|
|
36
38
|
provide() {
|
|
@@ -78,15 +80,15 @@ export default DitoComponent.component('dito-view', {
|
|
|
78
80
|
// so they can be rendered directly through DitoSchema also:
|
|
79
81
|
return this.isSingleComponentView
|
|
80
82
|
? {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
...schema,
|
|
84
|
+
components: {
|
|
85
|
+
[schema.name]: {
|
|
86
|
+
name: schema.name,
|
|
87
|
+
label: false,
|
|
88
|
+
...component
|
|
89
|
+
}
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
|
-
}
|
|
90
92
|
: schema
|
|
91
93
|
},
|
|
92
94
|
|
package/src/mixins/DataMixin.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
isObject,
|
|
2
|
+
isObject,
|
|
3
|
+
isFunction,
|
|
4
|
+
isPromise,
|
|
5
|
+
normalizeDataPath,
|
|
6
|
+
getValueAtDataPath
|
|
3
7
|
} from '@ditojs/utils'
|
|
4
8
|
import { reactive } from 'vue'
|
|
5
9
|
import LoadingMixin from './LoadingMixin.js'
|
|
@@ -25,14 +29,12 @@ export default {
|
|
|
25
29
|
}
|
|
26
30
|
let { data = undefined, dataPath = null } = schema
|
|
27
31
|
// See if there is async data loading already in process.
|
|
28
|
-
const asyncEntry = (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
})
|
|
35
|
-
)
|
|
32
|
+
const asyncEntry = (this.asyncDataEntries[name] ||= reactive({
|
|
33
|
+
dependencyFunction: null,
|
|
34
|
+
resolveCounter: 0,
|
|
35
|
+
resolvedData: null,
|
|
36
|
+
resolving: false
|
|
37
|
+
}))
|
|
36
38
|
// If the data callback provided a dependency function when it was called,
|
|
37
39
|
// cal it in every call of `handleDataSchema()` to force Vue to keep track
|
|
38
40
|
// of the async dependencies.
|