@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.
- package/LICENSE +21 -0
- package/buildTokens.js +59 -0
- package/components/DpButton/DpButton.stories.mdx +136 -0
- package/components/DpButton/DpButton.vue +118 -0
- package/components/DpDetails/DpDetails.stories.mdx +55 -0
- package/components/DpDetails/DpDetails.vue +58 -0
- package/components/DpIcon/DpIcon.stories.mdx +396 -0
- package/components/DpIcon/DpIcon.vue +51 -0
- package/components/DpIcon/util/iconVariables.js +148 -0
- package/components/DpInput/DpInput.stories.mdx +127 -0
- package/components/DpInput/DpInput.vue +284 -0
- package/components/DpLabel/DpLabel.stories.mdx +103 -0
- package/components/DpLabel/DpLabel.vue +112 -0
- package/components/DpLoading/DpLoading.stories.mdx +63 -0
- package/components/DpLoading/DpLoading.vue +63 -0
- package/components/core/DpAccordion.vue +108 -0
- package/components/core/DpAnonymizeText.vue +136 -0
- package/components/core/DpAutocomplete.vue +133 -0
- package/components/core/DpBulkEditHeader.vue +53 -0
- package/components/core/DpButtonIcon.vue +47 -0
- package/components/core/DpButtonRow.vue +155 -0
- package/components/core/DpCard.vue +54 -0
- package/components/core/DpChangeStateAtDate.vue +223 -0
- package/components/core/DpCheckboxGroup.vue +93 -0
- package/components/core/DpContextualHelp.vue +54 -0
- package/components/core/DpCopyPasteButton.vue +47 -0
- package/components/core/DpDashboardTaskCard.vue +123 -0
- package/components/core/DpDataTable/DataTableSearch.js +44 -0
- package/components/core/DpDataTable/DpColumnSelector.vue +133 -0
- package/components/core/DpDataTable/DpDataTable.vue +647 -0
- package/components/core/DpDataTable/DpDataTableExtended.vue +377 -0
- package/components/core/DpDataTable/DpResizeHandle.vue +37 -0
- package/components/core/DpDataTable/DpSelectPageItemCount.vue +70 -0
- package/components/core/DpDataTable/DpTableHeader.vue +197 -0
- package/components/core/DpDataTable/DpTableRow.vue +355 -0
- package/components/core/DpDataTable/DpWrapTrigger.vue +48 -0
- package/components/core/DpDataTable/lib/ResizableColumns.js +83 -0
- package/components/core/DpEditableList.vue +161 -0
- package/components/core/DpEditor/DpBoilerPlate.vue +140 -0
- package/components/core/DpEditor/DpBoilerPlateModal.vue +166 -0
- package/components/core/DpEditor/DpEditor.vue +1281 -0
- package/components/core/DpEditor/DpLinkModal.vue +117 -0
- package/components/core/DpEditor/DpRecommendationModal/DpInsertableRecommendation.vue +137 -0
- package/components/core/DpEditor/DpRecommendationModal.vue +283 -0
- package/components/core/DpEditor/DpResizableImage.vue +121 -0
- package/components/core/DpEditor/DpUploadModal.vue +121 -0
- package/components/core/DpEditor/libs/Decoration.js +66 -0
- package/components/core/DpEditor/libs/SegmentRangeChangePlugin.js +35 -0
- package/components/core/DpEditor/libs/editorAnonymize.js +66 -0
- package/components/core/DpEditor/libs/editorBuildSuggestion.js +269 -0
- package/components/core/DpEditor/libs/editorCustomDelete.js +32 -0
- package/components/core/DpEditor/libs/editorCustomImage.js +100 -0
- package/components/core/DpEditor/libs/editorCustomInsert.js +32 -0
- package/components/core/DpEditor/libs/editorCustomLink.js +46 -0
- package/components/core/DpEditor/libs/editorCustomMark.js +32 -0
- package/components/core/DpEditor/libs/editorInsertAtCursorPos.js +41 -0
- package/components/core/DpEditor/libs/editorObscure.js +60 -0
- package/components/core/DpEditor/libs/editorUnAnonymize.js +56 -0
- package/components/core/DpEditor/libs/handleWordPaste.js +360 -0
- package/components/core/DpEditor/libs/preventDrop.js +31 -0
- package/components/core/DpEditor/libs/preventKeyboardInput.js +27 -0
- package/components/core/DpEditor/libs/preventPaste.js +28 -0
- package/components/core/DpFlyout.vue +119 -0
- package/components/core/DpInlineNotification.vue +116 -0
- package/components/core/DpModal.vue +208 -0
- package/components/core/DpObscure.vue +29 -0
- package/components/core/DpPager.vue +139 -0
- package/components/core/DpProgressBar.vue +67 -0
- package/components/core/DpRegisterFlyout.vue +58 -0
- package/components/core/DpResettableInput.vue +140 -0
- package/components/core/DpSkeletonBox.vue +32 -0
- package/components/core/DpSlidebar.vue +86 -0
- package/components/core/DpSlidingPagination.vue +45 -0
- package/components/core/DpSplitButton.vue +77 -0
- package/components/core/DpSwitcher.vue +62 -0
- package/components/core/DpTableCardList/DpTableCard.vue +61 -0
- package/components/core/DpTableCardList/DpTableCardListHeader.vue +83 -0
- package/components/core/DpTabs/DpTab.vue +52 -0
- package/components/core/DpTabs/DpTabs.vue +165 -0
- package/components/core/DpTextWrapper.vue +65 -0
- package/components/core/DpToggleForm.vue +72 -0
- package/components/core/DpTooltipIcon.vue +52 -0
- package/components/core/DpTransitionExpand.vue +87 -0
- package/components/core/DpTreeList/DpTreeList.vue +334 -0
- package/components/core/DpTreeList/DpTreeListCheckbox.vue +79 -0
- package/components/core/DpTreeList/DpTreeListNode.vue +348 -0
- package/components/core/DpTreeList/DpTreeListToggle.vue +71 -0
- package/components/core/DpTreeList/utils/constants.js +14 -0
- package/components/core/DpUpload/DpUpload.vue +223 -0
- package/components/core/DpUpload/DpUploadFiles.vue +269 -0
- package/components/core/DpUpload/DpUploadedFile.vue +80 -0
- package/components/core/DpUpload/DpUploadedFileList.vue +56 -0
- package/components/core/DpUpload/utils/GetFileIdsByHash.js +42 -0
- package/components/core/DpUpload/utils/UppyTranslations.js +31 -0
- package/components/core/DpVideoPlayer.vue +115 -0
- package/components/core/HeightLimit.vue +121 -0
- package/components/core/MultistepNav.vue +89 -0
- package/components/core/form/DpCheckbox.vue +108 -0
- package/components/core/form/DpDateRangePicker.vue +186 -0
- package/components/core/form/DpDatepicker.vue +160 -0
- package/components/core/form/DpDatetimePicker.vue +194 -0
- package/components/core/form/DpFormRow.vue +79 -0
- package/components/core/form/DpMultiselect.vue +164 -0
- package/components/core/form/DpRadio.vue +128 -0
- package/components/core/form/DpSearchField.vue +110 -0
- package/components/core/form/DpSelect.vue +149 -0
- package/components/core/form/DpTextArea.vue +152 -0
- package/components/core/form/DpTimePicker.vue +374 -0
- package/components/core/form/DpToggle.vue +78 -0
- package/components/core/index.js +132 -0
- package/components/core/notify/DpNotifyContainer.vue +122 -0
- package/components/core/notify/DpNotifyMessage.vue +95 -0
- package/components/core/shared/DpStickyElement.vue +95 -0
- package/components/index.js +24 -0
- package/components/shared/translations.js +15 -0
- package/directives/CleanHtml/CleanHtml.js +50 -0
- package/directives/CleanHtml/CleanHtml.stories.mdx +64 -0
- package/directives/Tooltip/Tooltip.js +40 -0
- package/directives/Tooltip/Tooltip.stories.mdx +42 -0
- package/directives/index.js +17 -0
- package/lib/index.js +14 -0
- package/lib/prefixClass.js +47 -0
- package/mixins/index.js +14 -0
- package/mixins/prefixClassMixin.js +22 -0
- package/package.json +52 -0
- package/shared/props.js +86 -0
- package/style/index.css +7 -0
- package/tailwind.config.js +24 -0
- package/tokens/color.json +358 -0
- package/tokens/color.stories.mdx +45 -0
- package/tokens/fontSize.json +100 -0
- package/tokens/space.json +33 -0
- package/utils/lengthHint.js +69 -0
|
@@ -0,0 +1,269 @@
|
|
|
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
|
+
<fieldset :class="prefixClass('layout')">
|
|
12
|
+
<legend
|
|
13
|
+
class="hide-visually"
|
|
14
|
+
v-text="Translator.trans('upload.files')" />
|
|
15
|
+
<dp-label
|
|
16
|
+
v-if="label.text"
|
|
17
|
+
class="layout__item"
|
|
18
|
+
v-bind="{
|
|
19
|
+
for: id,
|
|
20
|
+
required: required,
|
|
21
|
+
...label
|
|
22
|
+
}" />
|
|
23
|
+
<dp-upload
|
|
24
|
+
:allowed-file-types="allowedFileTypes"
|
|
25
|
+
:chunk-size="chunkSize"
|
|
26
|
+
:class="[prefixClass('layout__item u-1-of-1-palm'), prefixClass(sideBySide ? 'u-1-of-2' : 'u-1-of-1')]"
|
|
27
|
+
:max-number-of-files="maxNumberOfFiles"
|
|
28
|
+
:max-file-size="maxFileSize"
|
|
29
|
+
:translations="translations"
|
|
30
|
+
@upload-success="handleUpload" /><!--
|
|
31
|
+
|
|
32
|
+
--><dp-uploaded-file-list
|
|
33
|
+
v-if="uploadedFiles.length > 0"
|
|
34
|
+
@file-remove="handleRemove"
|
|
35
|
+
:class="[prefixClass('layout__item u-1-of-1-palm'), prefixClass(sideBySide ? 'u-1-of-2' : 'u-1-of-1 u-mt')]"
|
|
36
|
+
:files="uploadedFiles" />
|
|
37
|
+
|
|
38
|
+
<!--
|
|
39
|
+
If the component is used in the context of a "traditional" form post, the hashes (ids)
|
|
40
|
+
of the uploaded files must be included in that form post. Also, when requiring a file upload,
|
|
41
|
+
the hidden input element is used by dpValidate to check for validation state.
|
|
42
|
+
-->
|
|
43
|
+
<input
|
|
44
|
+
v-if="needsHiddenInput"
|
|
45
|
+
type="hidden"
|
|
46
|
+
:name="name !== 'uploadedFiles' ? `uploadedFiles[${name}]` : 'uploadedFiles'"
|
|
47
|
+
:required="required"
|
|
48
|
+
:data-dp-validate-if="dataDpValidateIf"
|
|
49
|
+
:value="fileHashes">
|
|
50
|
+
</fieldset>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<script>
|
|
54
|
+
import { DpLabel } from 'demosplan-ui/components'
|
|
55
|
+
import DpUpload from './DpUpload'
|
|
56
|
+
import DpUploadedFileList from './DpUploadedFileList'
|
|
57
|
+
import { prefixClassMixin } from 'demosplan-ui/mixins'
|
|
58
|
+
|
|
59
|
+
export default {
|
|
60
|
+
name: 'DpUploadFiles',
|
|
61
|
+
|
|
62
|
+
components: {
|
|
63
|
+
DpLabel,
|
|
64
|
+
DpUpload,
|
|
65
|
+
DpUploadedFileList
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
mixins: [prefixClassMixin],
|
|
69
|
+
|
|
70
|
+
props: {
|
|
71
|
+
/**
|
|
72
|
+
* Array of mimeTypes or a defined preset as String
|
|
73
|
+
* @see demosplan/DemosPlanCoreBundle/Resources/client/js/lib/FileInfo.js
|
|
74
|
+
*/
|
|
75
|
+
allowedFileTypes: {
|
|
76
|
+
type: [Array, String],
|
|
77
|
+
required: true,
|
|
78
|
+
default: 'pdf'
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Define chunk size for huge files like PDFs
|
|
83
|
+
*/
|
|
84
|
+
chunkSize: {
|
|
85
|
+
type: Number,
|
|
86
|
+
default: Infinity,
|
|
87
|
+
required: false
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Use to conditionally validate a required upload field
|
|
92
|
+
* "required" and "needsHiddenInput" need to be set to true in that case
|
|
93
|
+
*/
|
|
94
|
+
dataDpValidateIf: {
|
|
95
|
+
type: [Boolean, String],
|
|
96
|
+
required: false,
|
|
97
|
+
default: false
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
id: {
|
|
101
|
+
type: String,
|
|
102
|
+
required: false,
|
|
103
|
+
default: ''
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
label: {
|
|
107
|
+
type: Object,
|
|
108
|
+
default: () => ({}),
|
|
109
|
+
validator: (prop) => {
|
|
110
|
+
return Object.keys(prop).every(key => ['hint', 'text', 'tooltip'].includes(key))
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Sets the maximally allowed file size for a single file in bytes.
|
|
116
|
+
*/
|
|
117
|
+
maxFileSize: {
|
|
118
|
+
type: Number,
|
|
119
|
+
required: false,
|
|
120
|
+
default: 10000000
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Maximum number of files that can be uploaded
|
|
125
|
+
* Defaults to single file upload
|
|
126
|
+
*/
|
|
127
|
+
maxNumberOfFiles: {
|
|
128
|
+
type: Number,
|
|
129
|
+
required: false,
|
|
130
|
+
default: 1
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Used to set the name of the hidden input field if the backend needs a specific name.
|
|
135
|
+
*/
|
|
136
|
+
name: {
|
|
137
|
+
type: String,
|
|
138
|
+
required: false,
|
|
139
|
+
default: 'uploadedFiles'
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Adds a hidden input with fileHash(es) as its value to the DOM.
|
|
144
|
+
* Must be set to true if the uploaded file(s) are intended to be saved via form post, or if the "required"
|
|
145
|
+
* prop is set to true (because dpValidate uses the input field to check the validity).
|
|
146
|
+
*/
|
|
147
|
+
needsHiddenInput: {
|
|
148
|
+
type: Boolean,
|
|
149
|
+
default: false
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* If set to true, dpValidate checks if at least one file has been uploaded.
|
|
154
|
+
* "needsHiddenInput" must also be true in that case.
|
|
155
|
+
*/
|
|
156
|
+
required: {
|
|
157
|
+
type: Boolean,
|
|
158
|
+
required: false,
|
|
159
|
+
default: false
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Use to overwrite the default translations
|
|
164
|
+
* you can find all available keys here
|
|
165
|
+
* @see https://github.com/transloadit/uppy/blob/master/packages/%40uppy/locales/src/de_DE.js
|
|
166
|
+
* some are already overwritten here
|
|
167
|
+
* @see demosplan/DemosPlanCoreBundle/Resources/client/js/components/DpUpload/utils/UppyTranslations.js
|
|
168
|
+
*/
|
|
169
|
+
translations: {
|
|
170
|
+
type: Object,
|
|
171
|
+
required: false,
|
|
172
|
+
default: () => ({})
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* If true the uploaded files list will be displayed next to the dropzone
|
|
177
|
+
* if false it will be displayed below
|
|
178
|
+
*/
|
|
179
|
+
sideBySide: {
|
|
180
|
+
type: Boolean,
|
|
181
|
+
required: false,
|
|
182
|
+
default: false
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Set a storageName if you want the uploaded files to be stored
|
|
187
|
+
* in the sessionStorage (i.e., be available across page reloads)
|
|
188
|
+
*/
|
|
189
|
+
storageName: {
|
|
190
|
+
type: String,
|
|
191
|
+
required: false,
|
|
192
|
+
default: ''
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
data () {
|
|
197
|
+
return {
|
|
198
|
+
fileHashes: [],
|
|
199
|
+
uploadedFiles: []
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
watch: {
|
|
204
|
+
storageName () {
|
|
205
|
+
if (this.storageName) {
|
|
206
|
+
this.updateSessionStorage()
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
methods: {
|
|
212
|
+
addFile (file) {
|
|
213
|
+
// To only show as many files as allowed
|
|
214
|
+
if (this.maxNumberOfFiles <= this.uploadedFiles.length) {
|
|
215
|
+
this.fileHashes.shift()
|
|
216
|
+
this.uploadedFiles.shift()
|
|
217
|
+
}
|
|
218
|
+
if (this.needsHiddenInput) {
|
|
219
|
+
this.fileHashes.push(file.hash)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
this.uploadedFiles.push(file)
|
|
223
|
+
if (this.storageName) {
|
|
224
|
+
this.updateSessionStorage()
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
|
|
228
|
+
clearFilesList () {
|
|
229
|
+
this.uploadedFiles.forEach(file => {
|
|
230
|
+
this.removeFile(file)
|
|
231
|
+
})
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
handleRemove (file) {
|
|
235
|
+
this.removeFile(file)
|
|
236
|
+
this.$emit('file-remove', file)
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
handleUpload (file) {
|
|
240
|
+
this.addFile(file)
|
|
241
|
+
this.$emit('upload-success', file)
|
|
242
|
+
|
|
243
|
+
// Let plain javascript logic also use 'upload-success' event.
|
|
244
|
+
document.dispatchEvent(new CustomEvent('uploadSuccess', { detail: { file: file, fieldName: this.name } }))
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
removeFile (file) {
|
|
248
|
+
if (this.needsHiddenInput) {
|
|
249
|
+
this.fileHashes = this.fileHashes.filter(hash => hash !== file.hash)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
this.uploadedFiles = this.uploadedFiles.filter(el => el.hash !== file.hash)
|
|
253
|
+
if (this.storageName) {
|
|
254
|
+
this.updateSessionStorage()
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
updateSessionStorage () {
|
|
259
|
+
sessionStorage.setItem(this.storageName, JSON.stringify(this.uploadedFiles))
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
|
|
263
|
+
mounted () {
|
|
264
|
+
if (this.storageName) {
|
|
265
|
+
this.uploadedFiles = JSON.parse(sessionStorage.getItem(this.storageName)) || []
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
</script>
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
<span
|
|
13
|
+
aria-hidden="true"
|
|
14
|
+
v-if="file.mimeType === 'txt'">
|
|
15
|
+
<i
|
|
16
|
+
:class="fileIcon" />
|
|
17
|
+
</span>
|
|
18
|
+
<span v-if="isImage">
|
|
19
|
+
<img
|
|
20
|
+
:src="Routing.generate('core_file', { hash: file.hash })"
|
|
21
|
+
:aria-label="Translator.trans('image.preview')"
|
|
22
|
+
width="50px">
|
|
23
|
+
</span>
|
|
24
|
+
<span
|
|
25
|
+
:class="prefixClass('display--inline-block u-pl-0_5')"
|
|
26
|
+
style="width: calc(100% - 62px);">
|
|
27
|
+
{{ file.name }}
|
|
28
|
+
({{ file.size }})
|
|
29
|
+
<button
|
|
30
|
+
type="button"
|
|
31
|
+
:class="prefixClass('btn-icns u-m-0')"
|
|
32
|
+
:aria-label="Translator.trans('file.remove')"
|
|
33
|
+
@click="removeFile">
|
|
34
|
+
<i
|
|
35
|
+
:class="prefixClass('fa fa-trash')"
|
|
36
|
+
aria-hidden="true" />
|
|
37
|
+
</button>
|
|
38
|
+
</span>
|
|
39
|
+
</li>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script>
|
|
43
|
+
import { getFileInfo } from 'demosplan-utils/lib/FileInfo'
|
|
44
|
+
import { prefixClassMixin } from 'demosplan-ui/mixins'
|
|
45
|
+
|
|
46
|
+
export default {
|
|
47
|
+
name: 'DpUploadedFile',
|
|
48
|
+
|
|
49
|
+
mixins: [prefixClassMixin],
|
|
50
|
+
|
|
51
|
+
props: {
|
|
52
|
+
fileString: {
|
|
53
|
+
type: String,
|
|
54
|
+
required: true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
computed: {
|
|
59
|
+
file () {
|
|
60
|
+
return getFileInfo(this.fileString)
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
fileIcon () {
|
|
64
|
+
const icon = this.file.mimeType === 'txt' ? 'fa-file-text-o' : 'fa-folder-o'
|
|
65
|
+
return this.prefixClass('fa ' + icon)
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
isImage () {
|
|
69
|
+
const imageTypes = ['png', 'jpg', 'gif', 'bmp', 'ico', 'tiff', 'svg']
|
|
70
|
+
return typeof imageTypes.find(type => type === this.file.mimeType) !== 'undefined'
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
methods: {
|
|
75
|
+
removeFile () {
|
|
76
|
+
this.$emit('file-remove', this.file)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
</script>
|
|
@@ -0,0 +1,56 @@
|
|
|
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>
|
|
12
|
+
<h4 :class="prefixClass('u-mb-0_25')">
|
|
13
|
+
{{ Translator.trans('uploaded.files') }}
|
|
14
|
+
</h4>
|
|
15
|
+
<ul :class="prefixClass('o-list space-stack-xs')">
|
|
16
|
+
<dp-uploaded-file
|
|
17
|
+
v-for="(fileString, idx) in fileStrings"
|
|
18
|
+
:file-string="fileString"
|
|
19
|
+
@file-remove="file => $emit('file-remove', file)"
|
|
20
|
+
:key="idx" />
|
|
21
|
+
</ul>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script>
|
|
26
|
+
import DpUploadedFile from './DpUploadedFile'
|
|
27
|
+
import { prefixClassMixin } from 'demosplan-ui/mixins'
|
|
28
|
+
|
|
29
|
+
export default {
|
|
30
|
+
name: 'DpUploadedFileList',
|
|
31
|
+
|
|
32
|
+
components: {
|
|
33
|
+
DpUploadedFile
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
mixins: [prefixClassMixin],
|
|
37
|
+
|
|
38
|
+
props: {
|
|
39
|
+
files: {
|
|
40
|
+
type: Array,
|
|
41
|
+
required: false,
|
|
42
|
+
default: () => ([])
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
computed: {
|
|
47
|
+
fileStrings () {
|
|
48
|
+
return this.files.map(file => {
|
|
49
|
+
let str = Object.values(file).toString()
|
|
50
|
+
str = str.replace(/,/g, ':')
|
|
51
|
+
return str
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
</script>
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
import { dpApi } from 'demosplan-utils'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Fetch File-Ids by their hashes
|
|
14
|
+
*
|
|
15
|
+
* @param {Array<hashes>}
|
|
16
|
+
*
|
|
17
|
+
* @returns {Array<Ids>}
|
|
18
|
+
*/
|
|
19
|
+
function getFileIdsByHash (hashes) {
|
|
20
|
+
return dpApi.get(
|
|
21
|
+
Routing.generate('api_resource_list', { resourceType: 'File' }),
|
|
22
|
+
{
|
|
23
|
+
filter: {
|
|
24
|
+
hasHash: {
|
|
25
|
+
condition: {
|
|
26
|
+
operator: 'IN',
|
|
27
|
+
path: 'hash',
|
|
28
|
+
value: hashes
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
serialize: true
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
.then(({ data }) => {
|
|
38
|
+
return data.data.map(el => el.id)
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { getFileIdsByHash }
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
import { convertSize } from 'demosplan-utils/lib/FileInfo'
|
|
11
|
+
const de = () => {
|
|
12
|
+
return {
|
|
13
|
+
strings: {
|
|
14
|
+
/*
|
|
15
|
+
* Text to show on the droppable area.
|
|
16
|
+
* `%{browse}` is replaced with a link that opens the system file selection dialog.
|
|
17
|
+
*/
|
|
18
|
+
dropHereOr: Translator.trans('form.button.upload.pdf', {
|
|
19
|
+
browse: '{browse}',
|
|
20
|
+
maxUploadSize: convertSize('GB', window.dplan.settings.maxUploadSize)
|
|
21
|
+
}),
|
|
22
|
+
failedToUpload: Translator.trans('form.button.upload.failed', {
|
|
23
|
+
file: '{file}'
|
|
24
|
+
}),
|
|
25
|
+
// This string is clickable and opens the system file selection dialog.
|
|
26
|
+
browse: Translator.trans('form.button.upload.search')
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { de }
|
|
@@ -0,0 +1,115 @@
|
|
|
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 class="position--relative">
|
|
12
|
+
<video
|
|
13
|
+
:aria-labelledby="ariaLabelledby"
|
|
14
|
+
:id="id"
|
|
15
|
+
playsinline
|
|
16
|
+
:data-poster="poster">
|
|
17
|
+
<source
|
|
18
|
+
v-for="source in sources"
|
|
19
|
+
:key="source.src"
|
|
20
|
+
:src="source.src"
|
|
21
|
+
:type="source.type">
|
|
22
|
+
<track
|
|
23
|
+
v-for="track in tracks"
|
|
24
|
+
:key="track.src"
|
|
25
|
+
:src="track.src"
|
|
26
|
+
:srclang="track.srclang"
|
|
27
|
+
:label="track.label"
|
|
28
|
+
:kind="track.kind"
|
|
29
|
+
:default="!!track.default">
|
|
30
|
+
</video>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script>
|
|
35
|
+
export default {
|
|
36
|
+
name: 'DpVideoPlayer',
|
|
37
|
+
|
|
38
|
+
props: {
|
|
39
|
+
/**
|
|
40
|
+
* You may pass the id of an element containing content that describes the video.
|
|
41
|
+
*/
|
|
42
|
+
ariaLabelledby: {
|
|
43
|
+
type: [String, Boolean],
|
|
44
|
+
required: false,
|
|
45
|
+
default: false
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
iconUrl: {
|
|
49
|
+
type: String,
|
|
50
|
+
required: true
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
id: {
|
|
54
|
+
type: String,
|
|
55
|
+
required: true
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
poster: {
|
|
59
|
+
type: String,
|
|
60
|
+
required: false,
|
|
61
|
+
default: ''
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
sources: {
|
|
65
|
+
required: false,
|
|
66
|
+
validator: (value) => {
|
|
67
|
+
// Check if all sources have a src and a type attribute
|
|
68
|
+
return Array.isArray(value) && value.filter(source => source.src && source.type).length === value.length
|
|
69
|
+
},
|
|
70
|
+
default: () => ([])
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
tracks: {
|
|
74
|
+
required: false,
|
|
75
|
+
validator: (value) => {
|
|
76
|
+
// Check if all tracks have their required attributes
|
|
77
|
+
return Array.isArray(value) && value.filter(track => track.kind && track.srclang && track.label && track.src).length === value.length
|
|
78
|
+
},
|
|
79
|
+
default: () => ([])
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
data () {
|
|
84
|
+
return {
|
|
85
|
+
player: {}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
created () {
|
|
90
|
+
this.player = import('plyr/dist/plyr.polyfilled.min')
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
mounted () {
|
|
94
|
+
this.player.then(Plyr => {
|
|
95
|
+
// eslint-disable-next-line new-cap
|
|
96
|
+
this.player = new Plyr.default('#' + this.id, {
|
|
97
|
+
iconUrl: this.iconUrl,
|
|
98
|
+
// For a full list of available controls see https://github.com/sampotts/plyr/blob/master/CONTROLS.md
|
|
99
|
+
controls: [
|
|
100
|
+
'play-large',
|
|
101
|
+
'play',
|
|
102
|
+
'progress',
|
|
103
|
+
'duration',
|
|
104
|
+
'mute',
|
|
105
|
+
'volume',
|
|
106
|
+
'captions',
|
|
107
|
+
'settings',
|
|
108
|
+
'download',
|
|
109
|
+
'fullscreen'
|
|
110
|
+
]
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
</script>
|
|
@@ -0,0 +1,121 @@
|
|
|
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
|
+
<documentation>
|
|
11
|
+
<usage variant="Without Ajax">
|
|
12
|
+
<dp-height-limit
|
|
13
|
+
:short="shortText"
|
|
14
|
+
:full="fullText"
|
|
15
|
+
no-event
|
|
16
|
+
:element="element"
|
|
17
|
+
></dp-height-limit>
|
|
18
|
+
</usage>
|
|
19
|
+
|
|
20
|
+
<usage variant="With Ajax">
|
|
21
|
+
<dp-height-limit
|
|
22
|
+
:short="shortText"
|
|
23
|
+
:full="fullText"
|
|
24
|
+
no-event
|
|
25
|
+
:element="element"
|
|
26
|
+
></dp-height-limit>
|
|
27
|
+
</usage>
|
|
28
|
+
</documentation>
|
|
29
|
+
|
|
30
|
+
<template>
|
|
31
|
+
<div class="overflow-word-break overflow-x-auto">
|
|
32
|
+
<dp-text-wrapper :text="currentText !== '' ? currentText : ' '" />
|
|
33
|
+
|
|
34
|
+
<button
|
|
35
|
+
class="btn--blank o-link--default"
|
|
36
|
+
type="button"
|
|
37
|
+
:aria-label="Translator.trans('aria.toggle')"
|
|
38
|
+
@click.stop="toggle"
|
|
39
|
+
v-if="isShortened">
|
|
40
|
+
{{ Translator.trans(isExpanded ? 'show.less' : 'show.more') }}
|
|
41
|
+
</button>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script>
|
|
46
|
+
import DpTextWrapper from './DpTextWrapper'
|
|
47
|
+
|
|
48
|
+
export default {
|
|
49
|
+
name: 'DpHeightLimit',
|
|
50
|
+
|
|
51
|
+
components: {
|
|
52
|
+
DpTextWrapper
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
props: {
|
|
56
|
+
/**
|
|
57
|
+
* The short text
|
|
58
|
+
*/
|
|
59
|
+
shortText: {
|
|
60
|
+
type: String,
|
|
61
|
+
required: true
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The long text
|
|
66
|
+
*/
|
|
67
|
+
fullText: {
|
|
68
|
+
type: String,
|
|
69
|
+
required: true
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* If this is true, no callback-event will be fired for full text loading
|
|
74
|
+
*/
|
|
75
|
+
noEvent: {
|
|
76
|
+
type: Boolean,
|
|
77
|
+
required: false,
|
|
78
|
+
default: false
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Translation string for element to be height-toggled
|
|
83
|
+
*/
|
|
84
|
+
element: {
|
|
85
|
+
type: String,
|
|
86
|
+
required: true
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
isShortened: {
|
|
90
|
+
type: Boolean,
|
|
91
|
+
required: false,
|
|
92
|
+
default: false
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
data () {
|
|
97
|
+
return {
|
|
98
|
+
isExpanded: false
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
computed: {
|
|
103
|
+
currentText () {
|
|
104
|
+
return (this.isExpanded) ? this.fullText : this.shortText
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
methods: {
|
|
109
|
+
toggle () {
|
|
110
|
+
if (this.noEvent) {
|
|
111
|
+
this.isExpanded = !this.isExpanded
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
this.$emit('heightLimit:toggle', () => {
|
|
116
|
+
this.isExpanded = !this.isExpanded
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
</script>
|