@demos-europe/demosplan-ui 0.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.
Files changed (133) hide show
  1. package/LICENSE +21 -0
  2. package/buildTokens.js +59 -0
  3. package/components/DpButton/DpButton.stories.mdx +136 -0
  4. package/components/DpButton/DpButton.vue +118 -0
  5. package/components/DpDetails/DpDetails.stories.mdx +55 -0
  6. package/components/DpDetails/DpDetails.vue +58 -0
  7. package/components/DpIcon/DpIcon.stories.mdx +396 -0
  8. package/components/DpIcon/DpIcon.vue +51 -0
  9. package/components/DpIcon/util/iconVariables.js +148 -0
  10. package/components/DpInput/DpInput.stories.mdx +127 -0
  11. package/components/DpInput/DpInput.vue +284 -0
  12. package/components/DpLabel/DpLabel.stories.mdx +103 -0
  13. package/components/DpLabel/DpLabel.vue +112 -0
  14. package/components/DpLoading/DpLoading.stories.mdx +63 -0
  15. package/components/DpLoading/DpLoading.vue +63 -0
  16. package/components/core/DpAccordion.vue +108 -0
  17. package/components/core/DpAnonymizeText.vue +136 -0
  18. package/components/core/DpAutocomplete.vue +133 -0
  19. package/components/core/DpBulkEditHeader.vue +53 -0
  20. package/components/core/DpButtonIcon.vue +47 -0
  21. package/components/core/DpButtonRow.vue +155 -0
  22. package/components/core/DpCard.vue +54 -0
  23. package/components/core/DpChangeStateAtDate.vue +223 -0
  24. package/components/core/DpCheckboxGroup.vue +93 -0
  25. package/components/core/DpContextualHelp.vue +54 -0
  26. package/components/core/DpCopyPasteButton.vue +47 -0
  27. package/components/core/DpDashboardTaskCard.vue +123 -0
  28. package/components/core/DpDataTable/DataTableSearch.js +44 -0
  29. package/components/core/DpDataTable/DpColumnSelector.vue +133 -0
  30. package/components/core/DpDataTable/DpDataTable.vue +647 -0
  31. package/components/core/DpDataTable/DpDataTableExtended.vue +377 -0
  32. package/components/core/DpDataTable/DpResizeHandle.vue +37 -0
  33. package/components/core/DpDataTable/DpSelectPageItemCount.vue +70 -0
  34. package/components/core/DpDataTable/DpTableHeader.vue +197 -0
  35. package/components/core/DpDataTable/DpTableRow.vue +355 -0
  36. package/components/core/DpDataTable/DpWrapTrigger.vue +48 -0
  37. package/components/core/DpDataTable/lib/ResizableColumns.js +83 -0
  38. package/components/core/DpEditableList.vue +161 -0
  39. package/components/core/DpEditor/DpBoilerPlate.vue +140 -0
  40. package/components/core/DpEditor/DpBoilerPlateModal.vue +166 -0
  41. package/components/core/DpEditor/DpEditor.vue +1281 -0
  42. package/components/core/DpEditor/DpLinkModal.vue +117 -0
  43. package/components/core/DpEditor/DpRecommendationModal/DpInsertableRecommendation.vue +137 -0
  44. package/components/core/DpEditor/DpRecommendationModal.vue +283 -0
  45. package/components/core/DpEditor/DpResizableImage.vue +121 -0
  46. package/components/core/DpEditor/DpUploadModal.vue +121 -0
  47. package/components/core/DpEditor/libs/Decoration.js +66 -0
  48. package/components/core/DpEditor/libs/SegmentRangeChangePlugin.js +35 -0
  49. package/components/core/DpEditor/libs/editorAnonymize.js +66 -0
  50. package/components/core/DpEditor/libs/editorBuildSuggestion.js +269 -0
  51. package/components/core/DpEditor/libs/editorCustomDelete.js +32 -0
  52. package/components/core/DpEditor/libs/editorCustomImage.js +100 -0
  53. package/components/core/DpEditor/libs/editorCustomInsert.js +32 -0
  54. package/components/core/DpEditor/libs/editorCustomLink.js +46 -0
  55. package/components/core/DpEditor/libs/editorCustomMark.js +32 -0
  56. package/components/core/DpEditor/libs/editorInsertAtCursorPos.js +41 -0
  57. package/components/core/DpEditor/libs/editorObscure.js +60 -0
  58. package/components/core/DpEditor/libs/editorUnAnonymize.js +56 -0
  59. package/components/core/DpEditor/libs/handleWordPaste.js +360 -0
  60. package/components/core/DpEditor/libs/preventDrop.js +31 -0
  61. package/components/core/DpEditor/libs/preventKeyboardInput.js +27 -0
  62. package/components/core/DpEditor/libs/preventPaste.js +28 -0
  63. package/components/core/DpFlyout.vue +119 -0
  64. package/components/core/DpInlineNotification.vue +116 -0
  65. package/components/core/DpModal.vue +208 -0
  66. package/components/core/DpObscure.vue +29 -0
  67. package/components/core/DpPager.vue +139 -0
  68. package/components/core/DpProgressBar.vue +67 -0
  69. package/components/core/DpRegisterFlyout.vue +58 -0
  70. package/components/core/DpResettableInput.vue +140 -0
  71. package/components/core/DpSkeletonBox.vue +32 -0
  72. package/components/core/DpSlidebar.vue +86 -0
  73. package/components/core/DpSlidingPagination.vue +45 -0
  74. package/components/core/DpSplitButton.vue +77 -0
  75. package/components/core/DpSwitcher.vue +62 -0
  76. package/components/core/DpTableCardList/DpTableCard.vue +61 -0
  77. package/components/core/DpTableCardList/DpTableCardListHeader.vue +83 -0
  78. package/components/core/DpTabs/DpTab.vue +52 -0
  79. package/components/core/DpTabs/DpTabs.vue +165 -0
  80. package/components/core/DpTextWrapper.vue +65 -0
  81. package/components/core/DpToggleForm.vue +72 -0
  82. package/components/core/DpTooltipIcon.vue +52 -0
  83. package/components/core/DpTransitionExpand.vue +87 -0
  84. package/components/core/DpTreeList/DpTreeList.vue +334 -0
  85. package/components/core/DpTreeList/DpTreeListCheckbox.vue +79 -0
  86. package/components/core/DpTreeList/DpTreeListNode.vue +348 -0
  87. package/components/core/DpTreeList/DpTreeListToggle.vue +71 -0
  88. package/components/core/DpTreeList/utils/constants.js +14 -0
  89. package/components/core/DpUpload/DpUpload.vue +223 -0
  90. package/components/core/DpUpload/DpUploadFiles.vue +269 -0
  91. package/components/core/DpUpload/DpUploadedFile.vue +80 -0
  92. package/components/core/DpUpload/DpUploadedFileList.vue +56 -0
  93. package/components/core/DpUpload/utils/GetFileIdsByHash.js +42 -0
  94. package/components/core/DpUpload/utils/UppyTranslations.js +31 -0
  95. package/components/core/DpVideoPlayer.vue +115 -0
  96. package/components/core/HeightLimit.vue +121 -0
  97. package/components/core/MultistepNav.vue +89 -0
  98. package/components/core/form/DpCheckbox.vue +108 -0
  99. package/components/core/form/DpDateRangePicker.vue +186 -0
  100. package/components/core/form/DpDatepicker.vue +160 -0
  101. package/components/core/form/DpDatetimePicker.vue +194 -0
  102. package/components/core/form/DpFormRow.vue +79 -0
  103. package/components/core/form/DpMultiselect.vue +164 -0
  104. package/components/core/form/DpRadio.vue +128 -0
  105. package/components/core/form/DpSearchField.vue +110 -0
  106. package/components/core/form/DpSelect.vue +149 -0
  107. package/components/core/form/DpTextArea.vue +152 -0
  108. package/components/core/form/DpTimePicker.vue +374 -0
  109. package/components/core/form/DpToggle.vue +78 -0
  110. package/components/core/index.js +132 -0
  111. package/components/core/notify/DpNotifyContainer.vue +122 -0
  112. package/components/core/notify/DpNotifyMessage.vue +95 -0
  113. package/components/core/shared/DpStickyElement.vue +95 -0
  114. package/components/index.js +24 -0
  115. package/components/shared/translations.js +15 -0
  116. package/directives/CleanHtml/CleanHtml.js +50 -0
  117. package/directives/CleanHtml/CleanHtml.stories.mdx +64 -0
  118. package/directives/Tooltip/Tooltip.js +40 -0
  119. package/directives/Tooltip/Tooltip.stories.mdx +42 -0
  120. package/directives/index.js +17 -0
  121. package/lib/index.js +14 -0
  122. package/lib/prefixClass.js +47 -0
  123. package/mixins/index.js +14 -0
  124. package/mixins/prefixClassMixin.js +22 -0
  125. package/package.json +52 -0
  126. package/shared/props.js +86 -0
  127. package/style/index.css +7 -0
  128. package/tailwind.config.js +24 -0
  129. package/tokens/color.json +358 -0
  130. package/tokens/color.stories.mdx +45 -0
  131. package/tokens/fontSize.json +100 -0
  132. package/tokens/space.json +33 -0
  133. package/utils/lengthHint.js +69 -0
@@ -0,0 +1,348 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <template>
11
+ <li
12
+ class="border--top position--relative"
13
+ data-cy="treeListNode">
14
+ <div class="c-treelist__node flex">
15
+ <div
16
+ class="display--inline-block u-p-0_25 u-pr-0 u-mt-0_125"
17
+ :class="dragHandle"
18
+ v-if="isDraggable">
19
+ <dp-icon
20
+ class="c-treelist__drag-handle-icon"
21
+ icon="drag-handle" />
22
+ </div>
23
+ <dp-tree-list-checkbox
24
+ v-if="isSelectable"
25
+ :checked="isSelected"
26
+ :name="checkboxIdentifier"
27
+ :string-value="nodeId"
28
+ @check="setSelectionState({ selectionState: !isSelected })" />
29
+ <div
30
+ class="flex flex-grow flex-items-start"
31
+ :style="indentationStyle">
32
+ <dp-tree-list-toggle
33
+ class="c-treelist__folder text--left u-pv-0_25"
34
+ :class="{'pointer-events-none': 0 === children.length}"
35
+ :icon-class-prop="iconClassFolder"
36
+ v-if="isBranch"
37
+ v-model="isExpanded" />
38
+ <div class="flex-grow u-pl-0 u-p-0_25">
39
+ <slot
40
+ v-if="isBranch"
41
+ name="branch"
42
+ :node-element="node"
43
+ :node-children="children"
44
+ :node-id="nodeId"
45
+ :parent-id="parentId" />
46
+ <slot
47
+ v-if="isLeaf"
48
+ name="leaf"
49
+ :node-element="node"
50
+ :node-id="nodeId"
51
+ :parent-id="parentId" />
52
+ </div>
53
+ </div>
54
+ <dp-tree-list-toggle
55
+ data-cy="treeListToggle"
56
+ v-if="isBranch"
57
+ class="align-self-start"
58
+ :disabled="!hasToggle"
59
+ v-tooltip="Translator.trans(!hasToggle ? 'no.elements.existing' : '')"
60
+ v-model="isExpanded" />
61
+ <div
62
+ v-else
63
+ class="min-width-25" />
64
+ </div>
65
+ <draggable
66
+ v-model="tree"
67
+ v-bind="options.draggable"
68
+ class="list-style-none u-mb-0 u-1-of-1"
69
+ :disabled="hasDraggableChildren === false"
70
+ :group="options.dragAcrossBranches ? 'treelistgroup' : nodeId"
71
+ tag="ul"
72
+ :move="onMove"
73
+ @change="(action) => handleChange(action, nodeId)"
74
+ @end="handleDrag('end')"
75
+ @start="handleDrag('start')">
76
+ <dp-tree-list-node
77
+ v-for="child in children"
78
+ v-show="true === isExpanded"
79
+ :ref="`node_${child.id}`"
80
+ :key="child.id"
81
+ :check-branch="checkBranch"
82
+ :children="child.children || []"
83
+ :handle-change="handleChange"
84
+ :handle-drag="handleDrag"
85
+ :level="level + 1"
86
+ :node="child"
87
+ :node-id="child.id"
88
+ :on-move="onMove"
89
+ :options="options"
90
+ :parent-id="nodeId"
91
+ :parent-selected="isSelected"
92
+ @draggable-change="bubbleDraggableChange"
93
+ @end="handleDrag('end')"
94
+ @node-selected="handleChildSelectionChange"
95
+ @start="handleDrag('start')"
96
+ @tree-data-change="bubbleChangeEvent">
97
+ <template
98
+ v-for="slot in Object.keys($scopedSlots)"
99
+ v-slot:[slot]="scope">
100
+ <slot
101
+ :name="slot"
102
+ v-bind="scope" />
103
+ </template>
104
+ </dp-tree-list-node>
105
+ </draggable>
106
+ </li>
107
+ </template>
108
+
109
+ <script>
110
+ import { checkboxWidth, dragHandleWidth, levelIndentationWidth } from './utils/constants'
111
+ import { DpIcon } from 'demosplan-ui/components'
112
+ import DpTreeListCheckbox from './DpTreeListCheckbox'
113
+ import DpTreeListToggle from './DpTreeListToggle'
114
+ import draggable from 'vuedraggable'
115
+
116
+ export default {
117
+ name: 'DpTreeListNode',
118
+
119
+ components: {
120
+ DpIcon,
121
+ DpTreeListCheckbox,
122
+ DpTreeListToggle,
123
+ draggable
124
+ },
125
+
126
+ props: {
127
+ checkBranch: {
128
+ type: Function,
129
+ required: true
130
+ },
131
+
132
+ children: {
133
+ type: Array,
134
+ required: true
135
+ },
136
+
137
+ draggable: {
138
+ type: Boolean,
139
+ required: false,
140
+ default: true
141
+ },
142
+
143
+ /*
144
+ * The function to handle the draggable "change" event is passed as a prop here.
145
+ * This way we do not run into performance issues with deeply nested lists.
146
+ * @see https://www.digitalocean.com/community/tutorials/vuejs-communicating-recursive-components
147
+ */
148
+ handleChange: {
149
+ type: Function,
150
+ required: true
151
+ },
152
+
153
+ /*
154
+ * The function to handle the draggable "start" and "end" events is passed as a prop here.
155
+ */
156
+ handleDrag: {
157
+ type: Function,
158
+ required: true
159
+ },
160
+
161
+ level: {
162
+ type: Number,
163
+ required: true
164
+ },
165
+
166
+ node: {
167
+ type: Object,
168
+ required: true
169
+ },
170
+
171
+ nodeId: {
172
+ type: String,
173
+ required: true
174
+ },
175
+
176
+ onMove: {
177
+ type: Function,
178
+ required: true
179
+ },
180
+
181
+ options: {
182
+ type: Object,
183
+ required: false,
184
+ default: () => ({})
185
+ },
186
+
187
+ parentId: {
188
+ type: String,
189
+ required: false,
190
+ default: ''
191
+ },
192
+
193
+ parentSelected: {
194
+ type: Boolean,
195
+ required: false,
196
+ default: false
197
+ }
198
+ },
199
+
200
+ data () {
201
+ return {
202
+ isExpanded: false,
203
+ isSelected: false
204
+ }
205
+ },
206
+
207
+ computed: {
208
+ checkboxIdentifier () {
209
+ const prefix = this.isBranch
210
+ ? this.options.checkboxIdentifier.branch
211
+ : this.options.checkboxIdentifier.leaf
212
+ return prefix + ':' + this.nodeId
213
+ },
214
+
215
+ dragHandle () {
216
+ const str = this.options.draggable.handle
217
+ return str.substring(1, str.length)
218
+ },
219
+
220
+ hasDraggableChildren () {
221
+ return this.isBranch && (this.options.dragLeaves || this.options.dragBranches) && this.draggable
222
+ },
223
+
224
+ hasToggle () {
225
+ return this.isBranch && this.children.length > 0
226
+ },
227
+
228
+ iconClassFolder () {
229
+ const hasContent = this.children.length > 0
230
+ let folderClass
231
+ if (hasContent) {
232
+ folderClass = this.isExpanded ? 'fa-folder-open' : 'fa-folder'
233
+ } else {
234
+ folderClass = 'fa-folder-o'
235
+ }
236
+ return 'fa ' + folderClass
237
+ },
238
+
239
+ indentationStyle () {
240
+ let margin = this.level * levelIndentationWidth
241
+
242
+ // If leaves are draggable, but branches are not, or vice versa, add extra space
243
+ if ((this.isBranch && !this.options.dragBranches && this.options.dragLeaves) ||
244
+ (this.isLeaf && this.options.dragBranches && !this.options.dragLeaves)) {
245
+ margin += dragHandleWidth
246
+ }
247
+
248
+ // If leaves are selectable, but branches are not, or vice versa, add extra space
249
+ if ((this.isBranch && !this.options.branchesSelectable && this.options.leavesSelectable) ||
250
+ (this.isLeaf && this.options.branchesSelectable && !this.options.leavesSelectable)) {
251
+ margin += checkboxWidth
252
+ }
253
+
254
+ return `margin-left: ${margin}px;`
255
+ },
256
+
257
+ isBranch () {
258
+ return this.checkBranch({ node: this.node, children: this.children, id: this.nodeId })
259
+ },
260
+
261
+ isDraggable () {
262
+ return this.isDraggableLeaf || this.isDraggableBranch
263
+ },
264
+
265
+ isDraggableBranch () {
266
+ return this.options.dragBranches && this.isBranch
267
+ },
268
+
269
+ isDraggableLeaf () {
270
+ return this.options.dragLeaves && this.isLeaf
271
+ },
272
+
273
+ isLeaf () {
274
+ return this.isBranch === false
275
+ },
276
+
277
+ isSelectable () {
278
+ return (this.isBranch && this.options.branchesSelectable) || (this.isLeaf && this.options.leavesSelectable) || false
279
+ },
280
+
281
+ // See docblock in `tree` computed of parent component.
282
+ tree: {
283
+ get () {
284
+ return this.children
285
+ },
286
+
287
+ set (val) {
288
+ this.$emit('tree-data-change', { nodeId: this.nodeId, newOrder: val })
289
+ }
290
+ }
291
+ },
292
+
293
+ watch: {
294
+ parentSelected (val) {
295
+ if (this.options.selectOn.parentSelect && val === true && this.isSelected === false) {
296
+ this.setSelectionState({ selectionState: val, fromParent: true })
297
+ }
298
+
299
+ if (this.options.deselectOn.parentDeselect && val === false && this.isSelected === true) {
300
+ this.setSelectionState({ selectionState: val, fromParent: true })
301
+ }
302
+ }
303
+ },
304
+
305
+ methods: {
306
+ bubbleChangeEvent (payload) {
307
+ this.$emit('tree-data-change', payload)
308
+ },
309
+
310
+ bubbleDraggableChange (payload) {
311
+ this.$emit('draggable-change', payload)
312
+ },
313
+
314
+ handleChildSelectionChange (selections) {
315
+ // Extract child selection state from the latest selection event
316
+ const childSelectionState = selections[selections.length - 1].selectionState
317
+
318
+ if (this.options.deselectOn.childDeselect && childSelectionState === false && this.isSelected === true) {
319
+ this.setSelectionState({ selectionState: childSelectionState, selections })
320
+ } else if (this.options.selectOn.childSelect && childSelectionState === true && this.isSelected === false) {
321
+ this.setSelectionState({ selectionState: childSelectionState, selections })
322
+ // Just bubble the event if the current node doesn't require any changes
323
+ } else {
324
+ this.$emit('node-selected', selections)
325
+ }
326
+ },
327
+
328
+ setSelectionState ({ selectionState, selections = [], fromParent = false }) {
329
+ const selectionsCpy = [...selections]
330
+
331
+ this.isSelected = selectionState
332
+ selectionsCpy.push({
333
+ nodeId: this.nodeId,
334
+ nodeType: this.isBranch === true ? 'branch' : 'leaf',
335
+ selectionState: selectionState
336
+ })
337
+
338
+ if (fromParent === false) {
339
+ this.$emit('node-selected', selectionsCpy)
340
+ }
341
+ }
342
+ },
343
+
344
+ mounted () {
345
+ this.$root.$on('treelist:toggle-all', (expanded) => (this.isExpanded = expanded))
346
+ }
347
+ }
348
+ </script>
@@ -0,0 +1,71 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <template>
11
+ <button
12
+ type="button"
13
+ class="o-link--default btn--blank"
14
+ :aria-label="label"
15
+ @click="toggle">
16
+ <i
17
+ :class="iconClass"
18
+ aria-hidden="true" />
19
+ </button>
20
+ </template>
21
+
22
+ <script>
23
+ export default {
24
+ name: 'DpTreeListToggle',
25
+
26
+ props: {
27
+ value: {
28
+ type: Boolean,
29
+ required: false,
30
+ default: false
31
+ },
32
+
33
+ iconClassProp: {
34
+ type: String,
35
+ required: false,
36
+ default: ''
37
+ },
38
+
39
+ toggleAll: {
40
+ type: Boolean,
41
+ required: false,
42
+ default: false
43
+ }
44
+ },
45
+
46
+ computed: {
47
+ /*
48
+ * May be passed from outside, but defaults to angle icon controlled by state.
49
+ * This is somewhat messy but removes cruft from DpTreeListNode.
50
+ */
51
+ iconClass () {
52
+ return this.iconClassProp !== ''
53
+ ? this.iconClassProp
54
+ : ('font-size-large line-height--1 u-p-0_25 fa ' + (this.value ? 'fa-angle-up' : 'fa-angle-down'))
55
+ },
56
+
57
+ label () {
58
+ // Here, the relatively generic term "element" is chosen to keep the wording generic.
59
+ return this.toggleAll
60
+ ? Translator.trans(this.value ? 'aria.collapse.all' : 'aria.expand.all')
61
+ : Translator.trans(this.value ? 'aria.collapse' : 'aria.expand')
62
+ }
63
+ },
64
+
65
+ methods: {
66
+ toggle () {
67
+ this.$emit('input', !this.value)
68
+ }
69
+ }
70
+ }
71
+ </script>
@@ -0,0 +1,14 @@
1
+ /**
2
+ * (c) 2010-present DEMOS E-Partizipation GmbH.
3
+ *
4
+ * This file is part of the package @demos-europe/demosplan-ui,
5
+ * for more information see the license file.
6
+ *
7
+ * All rights reserved
8
+ */
9
+
10
+ const checkboxWidth = 30
11
+ const dragHandleWidth = 22
12
+ const levelIndentationWidth = 25
13
+
14
+ export { checkboxWidth, dragHandleWidth, levelIndentationWidth }
@@ -0,0 +1,223 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <template>
11
+ <div ref="fileInput" />
12
+ </template>
13
+
14
+ <script>
15
+ import { de } from './utils/UppyTranslations'
16
+ import DragDrop from '@uppy/drag-drop'
17
+ import { getFileTypes } from 'demosplan-utils/lib/FileInfo'
18
+ import { hasOwnProp } from 'demosplan-utils'
19
+ import ProgressBar from '@uppy/progress-bar'
20
+ import Tus from '@uppy/tus'
21
+ import Uppy from '@uppy/core'
22
+
23
+ export default {
24
+ name: 'DpUpload',
25
+
26
+ props: {
27
+ /**
28
+ * Array of mimeTypes or a defined preset as String
29
+ * @see '@DemosPlanCoreBundle/lib/FileInfo'
30
+ */
31
+ allowedFileTypes: {
32
+ type: [Array, String],
33
+ required: false,
34
+ default: 'pdf'
35
+ },
36
+
37
+ /**
38
+ * Warning message that will be rendered if files are added that are not allowed in `allowedFileTypes`.
39
+ */
40
+ allowedFileTypesWarning: {
41
+ type: String,
42
+ default: 'warning.filetype'
43
+ },
44
+
45
+ /**
46
+ * Allow users to upload more files after uploading some
47
+ */
48
+ allowMultipleUploads: {
49
+ type: Boolean,
50
+ default: false
51
+ },
52
+
53
+ /**
54
+ * Define chunk size for huge files like PDFs
55
+ */
56
+ chunkSize: {
57
+ type: Number,
58
+ default: Infinity,
59
+ required: false
60
+ },
61
+
62
+ /**
63
+ * Maximum file size in bytes for each individual file
64
+ */
65
+ maxFileSize: {
66
+ type: Number,
67
+ default: 10000000
68
+ },
69
+
70
+ /**
71
+ * Maximum number of files that can be uploaded.
72
+ * By default its a single file upload.
73
+ */
74
+ maxNumberOfFiles: {
75
+ type: Number,
76
+ required: false,
77
+ default: 1
78
+ },
79
+
80
+ translations: {
81
+ type: Object,
82
+ required: false,
83
+ default: () => ({})
84
+ }
85
+ },
86
+
87
+ data () {
88
+ return {
89
+ currentFileHash: '',
90
+ currentFileId: '',
91
+ uppy: null
92
+ }
93
+ },
94
+
95
+ computed: {
96
+ allowedFileTypeArray () {
97
+ return getFileTypes(this.allowedFileTypes)
98
+ }
99
+ },
100
+
101
+ methods: {
102
+ getCookieValue (a) {
103
+ const b = document.cookie.match('(^|[^;]+)\\s*' + a + '\\s*=\\s*([^;]+)')
104
+ return b ? b.pop() : ''
105
+ },
106
+
107
+ initialize () {
108
+ const locale = { strings: { ...de().strings, ...this.translations } }
109
+ this.uppy = new Uppy({
110
+ disabled: true,
111
+ autoProceed: true,
112
+ allowMultipleUploads: this.allowMultipleUploads,
113
+ restrictions: {
114
+ allowedFileTypes: this.allowedFileTypeArray,
115
+ maxFileSize: this.maxFileSize,
116
+ maxNumberOfFiles: this.maxNumberOfFiles
117
+ },
118
+ locale: locale
119
+ })
120
+
121
+ this.uppy.use(DragDrop, {
122
+ target: this.$refs.fileInput,
123
+ width: '100%',
124
+ note: null,
125
+ locale: locale
126
+ })
127
+
128
+ this.uppy.use(ProgressBar, {
129
+ target: this.$refs.fileInput,
130
+ fixed: false,
131
+ hideAfterFinish: false
132
+ })
133
+
134
+ let currentProcedureId = null
135
+
136
+ if (typeof dplan !== 'undefined' && hasOwnProp(dplan, 'procedureId')) {
137
+ currentProcedureId = dplan.procedureId
138
+ }
139
+ const headers = {}
140
+ // Add current procedure id only if set
141
+ if (currentProcedureId !== null && currentProcedureId !== '0') {
142
+ headers['X-Demosplan-Procedure-Id'] = currentProcedureId
143
+ }
144
+
145
+ // If we have a basic auth, for some reason it has to be added to the header
146
+ if (dplan.settings.basicAuth !== '') {
147
+ headers.Authorization = dplan.settings.basicAuth
148
+ }
149
+
150
+ this.uppy.use(Tus, {
151
+ endpoint: dplan.paths.uploadPost,
152
+ chunkSize: 819200, // 800 KiB
153
+ limit: 5,
154
+ onAfterResponse: (_req, res) => {
155
+ this.currentFileHash = res.getHeader('X-Demosplan-File-Hash')
156
+ this.currentFileId = res.getHeader('X-Demosplan-File-Id')
157
+ },
158
+ removeFingerprintOnSuccess: true,
159
+ headers
160
+ })
161
+ }
162
+ },
163
+
164
+ mounted () {
165
+ this.initialize()
166
+
167
+ this.uppy.on('complete', result => {
168
+ setTimeout(() => {
169
+ /*
170
+ * Triggers uppy file-removed event (we are instead using a custom file-remove event. we do not want files to
171
+ * be removed on resetting the uppy ui
172
+ */
173
+ this.uppy.cancelAll()
174
+ }, 2000)
175
+
176
+ this.$emit('uploads-completed', result)
177
+ })
178
+
179
+ this.uppy.on('upload-error', (file, error, response) => {
180
+ console.error(error)
181
+ dplan.notify.error(Translator.trans('error.fileupload'))
182
+ this.$emit('file-error', { file, error, response })
183
+ })
184
+
185
+ this.uppy.on('file-added', file => {
186
+ this.$emit('file-added', file)
187
+ })
188
+
189
+ this.uppy.on('upload', data => {
190
+ this.$emit('upload', data)
191
+ })
192
+
193
+ this.uppy.on('restriction-failed', () => {
194
+ dplan.notify.warning(Translator.trans(this.allowedFileTypesWarning))
195
+ })
196
+
197
+ /*
198
+ * `upload-success` fires each time a single upload completes successfully.
199
+ * @see https://uppy.io/docs/uppy/#upload-success
200
+ */
201
+ this.uppy.on('upload-success', (file) => {
202
+ const { name, size, type } = file.data
203
+ const newFile = {
204
+ name: name,
205
+ hash: this.currentFileHash,
206
+ size: size,
207
+ type: type,
208
+ id: file.id, // The uppy internal file id
209
+ fileId: this.currentFileId // The id of the file within demosplan
210
+ }
211
+ this.currentFileHash = ''
212
+ this.currentFileId = ''
213
+ this.$emit('upload-success', newFile)
214
+ })
215
+ },
216
+
217
+ beforeDestroy () {
218
+ if (this.uppy) {
219
+ this.uppy.close()
220
+ }
221
+ }
222
+ }
223
+ </script>