@ditojs/admin 1.30.0 → 2.0.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 +5291 -6856
- package/dist/dito-admin.umd.js +5 -5
- package/dist/style.css +1 -1
- package/package.json +42 -27
- package/src/DitoAdmin.js +44 -58
- package/src/DitoComponent.js +18 -50
- package/src/DitoContext.js +7 -3
- package/src/TypeComponent.js +15 -13
- package/src/appState.js +4 -2
- package/src/components/DitoAccount.vue +14 -14
- package/src/components/DitoButtons.vue +18 -10
- package/src/components/DitoClipboard.vue +16 -16
- package/src/components/DitoContainer.vue +32 -32
- package/src/components/DitoCreateButton.vue +22 -23
- package/src/components/DitoDialog.vue +73 -18
- package/src/components/DitoEditButtons.vue +31 -31
- package/src/components/DitoElement.vue +6 -6
- package/src/components/DitoErrors.vue +6 -6
- package/src/components/DitoForm.vue +42 -43
- package/src/components/DitoFormNested.vue +7 -3
- package/src/components/DitoHeader.vue +19 -19
- package/src/components/DitoLabel.vue +25 -25
- package/src/components/DitoMenu.vue +9 -9
- package/src/components/DitoPagination.vue +5 -5
- package/src/components/DitoPane.vue +32 -32
- package/src/components/DitoPanel.vue +18 -18
- package/src/components/DitoPanels.vue +5 -3
- package/src/components/DitoRoot.vue +107 -30
- package/src/components/DitoSchema.vue +76 -74
- package/src/components/DitoSchemaInlined.vue +29 -29
- package/src/components/DitoScopes.vue +14 -13
- package/src/components/DitoSpinner.vue +101 -0
- package/src/components/DitoTableCell.vue +19 -25
- package/src/components/DitoTableHead.vue +10 -7
- package/src/components/DitoTabs.vue +7 -6
- package/src/components/DitoTreeItem.vue +89 -85
- package/src/components/DitoVNode.vue +9 -7
- package/src/components/DitoView.vue +25 -21
- package/src/mixins/DataMixin.js +2 -2
- package/src/mixins/DitoMixin.js +43 -46
- package/src/mixins/DomMixin.js +1 -1
- package/src/mixins/EmitterMixin.js +11 -11
- package/src/mixins/RouteMixin.js +20 -10
- package/src/mixins/SchemaParentMixin.js +2 -2
- package/src/mixins/SourceMixin.js +7 -9
- package/src/mixins/TypeMixin.js +29 -34
- package/src/mixins/ValidationMixin.js +4 -19
- package/src/types/TypeButton.vue +11 -15
- package/src/types/TypeCheckbox.vue +7 -8
- package/src/types/TypeCheckboxes.vue +14 -15
- package/src/types/TypeCode.vue +5 -5
- package/src/types/TypeColor.vue +9 -12
- package/src/types/TypeComponent.vue +12 -7
- package/src/types/TypeComputed.vue +13 -12
- package/src/types/TypeDate.vue +10 -11
- package/src/types/TypeLabel.vue +1 -1
- package/src/types/TypeList.vue +115 -92
- package/src/types/TypeMarkup.vue +166 -125
- package/src/types/TypeMultiselect.vue +37 -47
- package/src/types/TypeNumber.vue +10 -11
- package/src/types/TypeObject.vue +62 -46
- package/src/types/TypeProgress.vue +7 -8
- package/src/types/TypeRadio.vue +15 -14
- package/src/types/TypeSection.vue +10 -10
- package/src/types/TypeSelect.vue +32 -33
- package/src/types/TypeSlider.vue +20 -22
- package/src/types/TypeSwitch.vue +8 -9
- package/src/types/TypeText.vue +7 -8
- package/src/types/TypeTextarea.vue +8 -9
- package/src/types/TypeTreeList.vue +40 -34
- package/src/types/TypeUpload.vue +61 -61
- package/src/utils/accessor.js +1 -1
- package/src/utils/data.js +0 -4
- package/src/utils/options.js +48 -0
- package/src/utils/path.js +5 -0
- package/src/utils/schema.js +73 -56
- package/src/utils/vue.js +11 -0
- package/types/index.d.ts +1 -1
package/src/types/TypeObject.vue
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
.dito-object(
|
|
3
|
+
v-if="isReady"
|
|
4
|
+
:id="dataPath"
|
|
5
|
+
:class="schema.class"
|
|
6
|
+
:style="schema.style"
|
|
7
|
+
)
|
|
8
|
+
.dito-object-content(
|
|
9
|
+
v-if="objectData"
|
|
7
10
|
)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// Support the same rendering options as TypeList:
|
|
12
|
-
dito-schema-inlined(
|
|
13
|
-
v-if="isInlined"
|
|
11
|
+
//- Support the same rendering options as TypeList:
|
|
12
|
+
dito-schema-inlined(
|
|
13
|
+
v-if="isInlined"
|
|
14
14
|
:label="objectLabel"
|
|
15
|
-
|
|
16
|
-
:dataPath="dataPath"
|
|
17
|
-
:data="objectData"
|
|
18
|
-
:meta="nestedMeta"
|
|
19
|
-
:store="store"
|
|
20
|
-
:disabled="disabled || isLoading"
|
|
21
|
-
:collapsed="collapsed"
|
|
22
|
-
:collapsible="collapsible"
|
|
23
|
-
)
|
|
24
|
-
component(
|
|
25
|
-
v-else-if="component"
|
|
26
|
-
:is="component"
|
|
27
|
-
:dataPath="dataPath"
|
|
28
|
-
:data="objectData"
|
|
29
|
-
:nested="false"
|
|
30
|
-
)
|
|
31
|
-
span(
|
|
32
|
-
v-else-if="render"
|
|
33
|
-
v-html="render(getContext())"
|
|
34
|
-
)
|
|
35
|
-
span(
|
|
36
|
-
v-else
|
|
37
|
-
v-html="getItemLabel(schema, objectData)"
|
|
38
|
-
)
|
|
39
|
-
dito-edit-buttons(
|
|
40
|
-
:creatable="creatable"
|
|
41
|
-
:deletable="objectData && deletable"
|
|
42
|
-
:editable="objectData && editable"
|
|
43
|
-
:createPath="path"
|
|
44
|
-
:editPath="path"
|
|
45
|
-
:buttons="buttonSchemas"
|
|
46
|
-
:schema="schema"
|
|
15
|
+
:schema="getItemFormSchema(schema, objectData, context)"
|
|
47
16
|
:dataPath="dataPath"
|
|
48
17
|
:data="objectData"
|
|
49
|
-
:
|
|
50
|
-
:meta="meta"
|
|
18
|
+
:meta="nestedMeta"
|
|
51
19
|
:store="store"
|
|
52
|
-
|
|
20
|
+
:disabled="disabled || isLoading"
|
|
21
|
+
:collapsed="collapsed"
|
|
22
|
+
:collapsible="collapsible"
|
|
23
|
+
)
|
|
24
|
+
component(
|
|
25
|
+
v-else-if="schema.component"
|
|
26
|
+
:is="schema.component"
|
|
27
|
+
:dataPath="dataPath"
|
|
28
|
+
:data="objectData"
|
|
29
|
+
:nested="false"
|
|
30
|
+
)
|
|
31
|
+
span(
|
|
32
|
+
v-else-if="render"
|
|
33
|
+
v-html="render(getContext())"
|
|
53
34
|
)
|
|
35
|
+
span(
|
|
36
|
+
v-else
|
|
37
|
+
v-html="getItemLabel(schema, objectData)"
|
|
38
|
+
)
|
|
39
|
+
dito-edit-buttons(
|
|
40
|
+
:creatable="creatable"
|
|
41
|
+
:deletable="objectData && deletable"
|
|
42
|
+
:editable="objectData && editable"
|
|
43
|
+
:createPath="path"
|
|
44
|
+
:editPath="path"
|
|
45
|
+
:buttons="buttonSchemas"
|
|
46
|
+
:schema="schema"
|
|
47
|
+
:dataPath="dataPath"
|
|
48
|
+
:data="objectData"
|
|
49
|
+
:path="path"
|
|
50
|
+
:meta="meta"
|
|
51
|
+
:store="store"
|
|
52
|
+
@delete="deleteItem(objectData)"
|
|
53
|
+
)
|
|
54
54
|
</template>
|
|
55
55
|
|
|
56
56
|
<style lang="sass">
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
import TypeComponent from '../TypeComponent.js'
|
|
75
75
|
import DitoContext from '../DitoContext.js'
|
|
76
76
|
import SourceMixin from '../mixins/SourceMixin.js'
|
|
77
|
+
import { resolveSchemaComponent } from '../utils/schema.js'
|
|
77
78
|
|
|
78
79
|
// @vue/component
|
|
79
80
|
export default TypeComponent.register('object', {
|
|
@@ -97,6 +98,21 @@ export default TypeComponent.register('object', {
|
|
|
97
98
|
getContext() {
|
|
98
99
|
return new DitoContext(this, { data: this.objectData })
|
|
99
100
|
}
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
async processSchema(
|
|
104
|
+
api, schema, name, routes, level,
|
|
105
|
+
nested = false, flatten = false,
|
|
106
|
+
process = null
|
|
107
|
+
) {
|
|
108
|
+
await Promise.all([
|
|
109
|
+
resolveSchemaComponent(schema),
|
|
110
|
+
SourceMixin.processSchema(
|
|
111
|
+
api, schema, name, routes, level,
|
|
112
|
+
nested, flatten,
|
|
113
|
+
process
|
|
114
|
+
)
|
|
115
|
+
])
|
|
100
116
|
}
|
|
101
117
|
})
|
|
102
118
|
</script>
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
)
|
|
2
|
+
progress.dito-progress(
|
|
3
|
+
ref="element"
|
|
4
|
+
:id="dataPath"
|
|
5
|
+
:value="progressValue"
|
|
6
|
+
:max="progressMax"
|
|
7
|
+
v-bind="attributes"
|
|
8
|
+
)
|
|
10
9
|
</template>
|
|
11
10
|
|
|
12
11
|
<script>
|
package/src/types/TypeRadio.vue
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
ul.dito-radio-buttons(
|
|
3
|
+
:id="dataPath"
|
|
4
|
+
:class="`dito-layout-${schema.layout || 'vertical'}`"
|
|
5
|
+
)
|
|
6
|
+
li(
|
|
7
|
+
v-for="option in options"
|
|
5
8
|
)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
)
|
|
16
|
-
| {{ getLabelForOption(option) }}
|
|
9
|
+
label
|
|
10
|
+
input.dito-radio-button(
|
|
11
|
+
ref="element"
|
|
12
|
+
type="radio"
|
|
13
|
+
:value="getValueForOption(option)"
|
|
14
|
+
v-model="selectedValue"
|
|
15
|
+
v-bind="attributes"
|
|
16
|
+
)
|
|
17
|
+
| {{ getLabelForOption(option) }}
|
|
17
18
|
</template>
|
|
18
19
|
|
|
19
20
|
<style lang="sass">
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
.dito-section(
|
|
3
|
+
:class="{ 'dito-section-labelled' : !!schema.label }"
|
|
4
|
+
)
|
|
5
|
+
dito-pane.dito-section-pane(
|
|
6
|
+
:schema="getItemFormSchema(schema, item, context)"
|
|
7
|
+
:dataPath="dataPath"
|
|
8
|
+
:data="item"
|
|
9
|
+
:meta="meta"
|
|
10
|
+
:store="store"
|
|
11
|
+
:disabled="disabled"
|
|
4
12
|
)
|
|
5
|
-
dito-pane.dito-section-pane(
|
|
6
|
-
:schema="getItemFormSchema(schema, item, context)"
|
|
7
|
-
:dataPath="dataPath"
|
|
8
|
-
:data="item"
|
|
9
|
-
:meta="meta"
|
|
10
|
-
:store="store"
|
|
11
|
-
:disabled="disabled"
|
|
12
|
-
)
|
|
13
13
|
</template>
|
|
14
14
|
|
|
15
15
|
<style lang="sass">
|
package/src/types/TypeSelect.vue
CHANGED
|
@@ -1,44 +1,43 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
//- Nesting is needed to make an arrow appear over the select item:
|
|
3
|
+
.dito-select
|
|
4
|
+
select(
|
|
5
|
+
ref="element"
|
|
6
|
+
:id="dataPath"
|
|
7
|
+
v-model="selectedValue"
|
|
8
|
+
v-bind="attributes"
|
|
9
|
+
@mousedown="populate = true"
|
|
10
|
+
@focus="populate = true"
|
|
11
|
+
)
|
|
12
|
+
template(
|
|
13
|
+
v-if="populate"
|
|
12
14
|
)
|
|
13
15
|
template(
|
|
14
|
-
v-
|
|
16
|
+
v-for="option in options"
|
|
15
17
|
)
|
|
16
|
-
|
|
17
|
-
v-
|
|
18
|
+
optgroup(
|
|
19
|
+
v-if="groupBy"
|
|
20
|
+
:label="option[groupByLabel]"
|
|
18
21
|
)
|
|
19
|
-
optgroup(
|
|
20
|
-
v-if="groupBy"
|
|
21
|
-
:label="option[groupByLabel]"
|
|
22
|
-
)
|
|
23
|
-
option(
|
|
24
|
-
v-for="opt in option[groupByOptions]"
|
|
25
|
-
:value="getValueForOption(opt)"
|
|
26
|
-
) {{ getLabelForOption(opt) }}
|
|
27
22
|
option(
|
|
28
|
-
v-
|
|
29
|
-
:value="getValueForOption(
|
|
30
|
-
) {{ getLabelForOption(
|
|
31
|
-
template(
|
|
32
|
-
v-else-if="selectedOption"
|
|
33
|
-
)
|
|
23
|
+
v-for="opt in option[groupByOptions]"
|
|
24
|
+
:value="getValueForOption(opt)"
|
|
25
|
+
) {{ getLabelForOption(opt) }}
|
|
34
26
|
option(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
:disabled="disabled"
|
|
27
|
+
v-else
|
|
28
|
+
:value="getValueForOption(option)"
|
|
29
|
+
) {{ getLabelForOption(option) }}
|
|
30
|
+
template(
|
|
31
|
+
v-else-if="selectedOption"
|
|
41
32
|
)
|
|
33
|
+
option(
|
|
34
|
+
:value="selectedValue"
|
|
35
|
+
) {{ getLabelForOption(selectedOption) }}
|
|
36
|
+
button.dito-button-clear.dito-button-overlay(
|
|
37
|
+
v-if="showClearButton"
|
|
38
|
+
@click="clear"
|
|
39
|
+
:disabled="disabled"
|
|
40
|
+
)
|
|
42
41
|
</template>
|
|
43
42
|
|
|
44
43
|
<style lang="sass">
|
package/src/types/TypeSlider.vue
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
input
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
:step="stepValue"
|
|
23
|
-
)
|
|
2
|
+
.dito-slider
|
|
3
|
+
input.dito-range(
|
|
4
|
+
ref="element"
|
|
5
|
+
:id="dataPath"
|
|
6
|
+
type="range"
|
|
7
|
+
v-model="inputValue"
|
|
8
|
+
v-bind="attributes"
|
|
9
|
+
:min="min"
|
|
10
|
+
:max="max"
|
|
11
|
+
:step="stepValue"
|
|
12
|
+
)
|
|
13
|
+
input-field.dito-number(
|
|
14
|
+
v-if="input"
|
|
15
|
+
type="number"
|
|
16
|
+
v-model="inputValue"
|
|
17
|
+
v-bind="attributes"
|
|
18
|
+
:min="min"
|
|
19
|
+
:max="max"
|
|
20
|
+
:step="stepValue"
|
|
21
|
+
)
|
|
24
22
|
</template>
|
|
25
23
|
|
|
26
24
|
<style lang="sass">
|
package/src/types/TypeSwitch.vue
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
)
|
|
2
|
+
switch-button.dito-switch(
|
|
3
|
+
ref="element"
|
|
4
|
+
:id="dataPath"
|
|
5
|
+
:sync="true"
|
|
6
|
+
:labels="labels"
|
|
7
|
+
v-model="value"
|
|
8
|
+
v-bind="attributes"
|
|
9
|
+
)
|
|
11
10
|
</template>
|
|
12
11
|
|
|
13
12
|
<style lang="sass">
|
package/src/types/TypeText.vue
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
)
|
|
2
|
+
input-field.dito-text(
|
|
3
|
+
ref="element"
|
|
4
|
+
:id="dataPath"
|
|
5
|
+
:type="inputType"
|
|
6
|
+
v-model="inputValue"
|
|
7
|
+
v-bind="attributes"
|
|
8
|
+
)
|
|
10
9
|
</template>
|
|
11
10
|
|
|
12
11
|
<script>
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
)
|
|
2
|
+
textarea.dito-textarea.dito-input(
|
|
3
|
+
ref="element"
|
|
4
|
+
:id="dataPath"
|
|
5
|
+
v-model="value"
|
|
6
|
+
v-bind="attributes"
|
|
7
|
+
:rows="lines"
|
|
8
|
+
:class="{ 'dito-resizable': resizable }"
|
|
9
|
+
)
|
|
11
10
|
</template>
|
|
12
11
|
|
|
13
12
|
<style lang="sass">
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
.dito-tree-list
|
|
3
|
+
dito-scopes(
|
|
4
|
+
v-if="scopes"
|
|
5
|
+
:query="query"
|
|
6
|
+
:scopes="scopes"
|
|
7
|
+
)
|
|
8
|
+
.dito-tree-panel
|
|
9
|
+
dito-tree-item(
|
|
10
|
+
:schema="treeSchema"
|
|
11
|
+
:dataPath="treeDataPath"
|
|
12
|
+
:data="treeData"
|
|
13
|
+
:draggable="draggable"
|
|
14
|
+
:open="true"
|
|
7
15
|
)
|
|
8
|
-
.dito-tree-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
:draggable="draggable"
|
|
14
|
-
:open="true"
|
|
15
|
-
)
|
|
16
|
-
.dito-tree-form-container(
|
|
17
|
-
v-if="hasEditableForms"
|
|
18
|
-
)
|
|
19
|
-
// Include a router-view for the optional DitoFormInlined
|
|
20
|
-
router-view
|
|
16
|
+
.dito-tree-form-container(
|
|
17
|
+
v-if="hasEditableForms"
|
|
18
|
+
)
|
|
19
|
+
//- Include a router-view for the optional DitoFormInlined
|
|
20
|
+
router-view
|
|
21
21
|
</template>
|
|
22
22
|
|
|
23
23
|
<style lang="sass">
|
|
@@ -44,7 +44,9 @@
|
|
|
44
44
|
<script>
|
|
45
45
|
import TypeComponent from '../TypeComponent.js'
|
|
46
46
|
import SourceMixin from '../mixins/SourceMixin.js'
|
|
47
|
-
import {
|
|
47
|
+
import {
|
|
48
|
+
hasFormSchema, getFormSchemas, resolveSchemaComponents
|
|
49
|
+
} from '../utils/schema.js'
|
|
48
50
|
|
|
49
51
|
export default TypeComponent.register([
|
|
50
52
|
'tree-list', 'tree-object'
|
|
@@ -120,23 +122,27 @@ export default TypeComponent.register([
|
|
|
120
122
|
nested = true, flatten = false,
|
|
121
123
|
process = null
|
|
122
124
|
) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
125
|
+
await Promise.all([
|
|
126
|
+
resolveSchemaComponents(schema.properties),
|
|
127
|
+
SourceMixin.processSchema(
|
|
128
|
+
api, schema, name, routes, level,
|
|
129
|
+
nested, flatten,
|
|
130
|
+
// Pass process() to add more routes to childRoutes:
|
|
131
|
+
(childRoutes, level) => {
|
|
132
|
+
const { children } = schema
|
|
133
|
+
if (children) {
|
|
130
134
|
// Add `type` to the nested tree list.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
children.type = 'tree-list'
|
|
136
|
+
// Recursively call `processSchema()` for the nested tree list:
|
|
137
|
+
return this.processSchema(
|
|
138
|
+
api, children, children.name, childRoutes, level,
|
|
139
|
+
nested, true, // Pass `true` for `flatten` in tree lists.
|
|
140
|
+
process
|
|
141
|
+
)
|
|
142
|
+
}
|
|
137
143
|
}
|
|
138
|
-
|
|
139
|
-
)
|
|
144
|
+
)
|
|
145
|
+
])
|
|
140
146
|
},
|
|
141
147
|
|
|
142
148
|
getFormSchemasForProcessing(schema, context) {
|
package/src/types/TypeUpload.vue
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
.dito-upload
|
|
3
|
+
table.dito-table.dito-table-separators.dito-table-background
|
|
4
|
+
//- Styling comes from DitoTableHead
|
|
5
|
+
thead.dito-table-head
|
|
6
|
+
tr
|
|
7
|
+
th
|
|
8
|
+
span Name
|
|
9
|
+
th
|
|
10
|
+
span Size
|
|
11
|
+
th
|
|
12
|
+
span Status
|
|
13
|
+
th
|
|
14
|
+
span
|
|
15
|
+
vue-sortable(
|
|
16
|
+
tag="tbody"
|
|
17
|
+
:list="files"
|
|
18
|
+
:options="getDragOptions(draggable)"
|
|
19
|
+
itemKey="key"
|
|
20
|
+
@start="onStartDrag"
|
|
21
|
+
@end="onEndDrag"
|
|
22
|
+
)
|
|
23
|
+
template(#item="{ element: file, index }")
|
|
6
24
|
tr
|
|
7
|
-
th
|
|
8
|
-
span Name
|
|
9
|
-
th
|
|
10
|
-
span Size
|
|
11
|
-
th
|
|
12
|
-
span Status
|
|
13
|
-
th
|
|
14
|
-
span
|
|
15
|
-
vue-draggable(
|
|
16
|
-
tag="tbody"
|
|
17
|
-
v-bind="getDragOptions(draggable)"
|
|
18
|
-
:list="files"
|
|
19
|
-
@start="onStartDrag"
|
|
20
|
-
@end="onEndDrag"
|
|
21
|
-
)
|
|
22
|
-
tr(
|
|
23
|
-
v-for="(file, index) in files"
|
|
24
|
-
:key="file.key"
|
|
25
|
-
)
|
|
26
25
|
td(v-html="renderFile(file, index)")
|
|
27
|
-
td {{ file.size
|
|
26
|
+
td {{ formatFileSize(file.size) }}
|
|
28
27
|
td
|
|
29
28
|
template(v-if="file.upload")
|
|
30
29
|
template(v-if="file.upload.error")
|
|
@@ -48,41 +47,41 @@
|
|
|
48
47
|
@click="deleteFile(file, index)"
|
|
49
48
|
v-bind="getButtonAttributes(verbs.delete)"
|
|
50
49
|
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
tfoot
|
|
51
|
+
tr
|
|
52
|
+
td(:colspan="4")
|
|
53
|
+
.dito-upload-footer
|
|
54
|
+
progress.dito-progress(
|
|
55
|
+
v-if="isUploadActive"
|
|
56
|
+
:value="uploadProgress"
|
|
57
|
+
max="100"
|
|
58
|
+
)
|
|
59
|
+
.dito-buttons.dito-buttons-round
|
|
60
|
+
button.dito-button(
|
|
56
61
|
v-if="isUploadActive"
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
type="button"
|
|
63
|
+
@click.prevent="upload.active = false"
|
|
64
|
+
) Cancel All
|
|
65
|
+
button.dito-button(
|
|
66
|
+
v-else-if="isUploadReady"
|
|
67
|
+
type="button"
|
|
68
|
+
@click.prevent="upload.active = true"
|
|
69
|
+
) Upload All
|
|
70
|
+
vue-upload.dito-button.dito-button-add-upload(
|
|
71
|
+
:input-id="dataPath"
|
|
72
|
+
:name="dataPath"
|
|
73
|
+
:disabled="disabled"
|
|
74
|
+
:post-action="uploadPath"
|
|
75
|
+
:extensions="extensions"
|
|
76
|
+
:accept="accept"
|
|
77
|
+
:multiple="multiple"
|
|
78
|
+
:size="maxSize"
|
|
79
|
+
v-model="uploads"
|
|
80
|
+
@input-filter="inputFilter"
|
|
81
|
+
@input-file="inputFile"
|
|
82
|
+
ref="upload"
|
|
83
|
+
title="Upload Files"
|
|
59
84
|
)
|
|
60
|
-
.dito-buttons.dito-buttons-round
|
|
61
|
-
button.dito-button(
|
|
62
|
-
v-if="isUploadActive"
|
|
63
|
-
type="button"
|
|
64
|
-
@click.prevent="upload.active = false"
|
|
65
|
-
) Cancel All
|
|
66
|
-
button.dito-button(
|
|
67
|
-
v-else-if="isUploadReady"
|
|
68
|
-
type="button"
|
|
69
|
-
@click.prevent="upload.active = true"
|
|
70
|
-
) Upload All
|
|
71
|
-
vue-upload.dito-button.dito-button-add-upload(
|
|
72
|
-
:input-id="dataPath"
|
|
73
|
-
:name="dataPath"
|
|
74
|
-
:disabled="disabled"
|
|
75
|
-
:post-action="uploadPath"
|
|
76
|
-
:extensions="extensions"
|
|
77
|
-
:accept="accept"
|
|
78
|
-
:multiple="multiple"
|
|
79
|
-
:size="maxSize"
|
|
80
|
-
v-model="uploads"
|
|
81
|
-
@input-filter="inputFilter"
|
|
82
|
-
@input-file="inputFile"
|
|
83
|
-
ref="upload"
|
|
84
|
-
title="Upload Files"
|
|
85
|
-
)
|
|
86
85
|
</template>
|
|
87
86
|
|
|
88
87
|
<style lang="sass">
|
|
@@ -111,7 +110,7 @@ import TypeComponent from '../TypeComponent.js'
|
|
|
111
110
|
import DitoContext from '../DitoContext.js'
|
|
112
111
|
import OrderedMixin from '../mixins/OrderedMixin.js'
|
|
113
112
|
import VueUpload from 'vue-upload-component'
|
|
114
|
-
import
|
|
113
|
+
import { Sortable as VueSortable } from 'sortablejs-vue3'
|
|
115
114
|
import parseFileSize from 'filesize-parser'
|
|
116
115
|
import { getSchemaAccessor } from '../utils/accessor.js'
|
|
117
116
|
import { formatFileSize } from '../utils/units.js'
|
|
@@ -120,8 +119,7 @@ import { isArray, asArray, escapeHtml } from '@ditojs/utils'
|
|
|
120
119
|
|
|
121
120
|
// @vue/component
|
|
122
121
|
export default TypeComponent.register('upload', {
|
|
123
|
-
components: { VueUpload,
|
|
124
|
-
filters: { formatFileSize },
|
|
122
|
+
components: { VueUpload, VueSortable },
|
|
125
123
|
mixins: [OrderedMixin],
|
|
126
124
|
|
|
127
125
|
data() {
|
|
@@ -202,6 +200,8 @@ export default TypeComponent.register('upload', {
|
|
|
202
200
|
},
|
|
203
201
|
|
|
204
202
|
methods: {
|
|
203
|
+
formatFileSize,
|
|
204
|
+
|
|
205
205
|
renderFile(file, index) {
|
|
206
206
|
const { render } = this.schema
|
|
207
207
|
return render
|
|
@@ -263,7 +263,7 @@ export default TypeComponent.register('upload', {
|
|
|
263
263
|
const index = this.getFileIndex(file)
|
|
264
264
|
if (index >= 0) {
|
|
265
265
|
if (newFile) {
|
|
266
|
-
this
|
|
266
|
+
this.value[index] = newFile
|
|
267
267
|
} else {
|
|
268
268
|
this.value.splice(index, 1)
|
|
269
269
|
}
|