diff --git a/public/js/components/Form/Upload/Dms.js b/public/js/components/Form/Upload/Dms.js
index 82333dc7f..83b8d86bb 100644
--- a/public/js/components/Form/Upload/Dms.js
+++ b/public/js/components/Form/Upload/Dms.js
@@ -1,8 +1,10 @@
import DmsItem from './Dms/Item.js';
+import DmsPreview from './Dms/Preview.js';
export default {
components: {
- DmsItem
+ DmsItem,
+ DmsPreview
},
emits: [
'update:modelValue'
@@ -24,6 +26,21 @@ export default {
disabled: {
type: Boolean,
default: false
+ },
+ // shows the chosen images and pdfs below the input before the upload
+ preview: Boolean,
+ // small, medium, large or a css length like '400px'
+ previewHeight: {
+ type: String,
+ default: 'medium'
+ }
+ },
+ computed: {
+ previewFiles() {
+ if (!this.preview || !this.modelValue)
+ return [];
+ // stored dms files are json placeholders, they have no content to show
+ return Array.from(this.modelValue).filter(file => file instanceof File && file.type != 'application/x.fhc-dms+json');
}
},
methods: {
@@ -103,5 +120,6 @@ export default {
>
+
`
}
\ No newline at end of file
diff --git a/public/js/components/Form/Upload/Dms/Preview.js b/public/js/components/Form/Upload/Dms/Preview.js
new file mode 100644
index 000000000..e1b100929
--- /dev/null
+++ b/public/js/components/Form/Upload/Dms/Preview.js
@@ -0,0 +1,68 @@
+// only these types get a preview. html or svg in the iframe would run their scripts in the page origin
+const IMAGE_TYPES = ['image/png', 'image/jpeg', 'image/gif', 'image/webp'];
+
+const HEIGHTS = {
+ small: '30vh',
+ medium: '50vh',
+ large: '80vh'
+};
+
+/**
+ * Preview of one chosen file before the upload: an image as img, a pdf in the pdf viewer of the browser.
+ * height: small, medium, large or a css length like '400px'.
+ */
+export default {
+ props: {
+ file: {
+ type: File,
+ required: true
+ },
+ height: {
+ type: String,
+ default: 'medium'
+ }
+ },
+ data() {
+ return {
+ url: ''
+ };
+ },
+ computed: {
+ isImage() {
+ return IMAGE_TYPES.includes(this.file.type);
+ },
+ // android chrome has no inline pdf viewer, there a pdf gets no preview
+ isPdf() {
+ return this.file.type == 'application/pdf' && navigator.pdfViewerEnabled !== false;
+ },
+ cssHeight() {
+ return HEIGHTS[this.height] || this.height;
+ }
+ },
+ watch: {
+ file: {
+ handler() {
+ this.revokeUrl();
+ // an object url only references the file, no base64 copy in memory
+ if (this.isImage || this.isPdf)
+ this.url = URL.createObjectURL(this.file);
+ },
+ immediate: true
+ }
+ },
+ unmounted() {
+ this.revokeUrl();
+ },
+ methods: {
+ revokeUrl() {
+ if (this.url)
+ URL.revokeObjectURL(this.url);
+ this.url = '';
+ }
+ },
+ template: `
+
`
+}
diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php
index 4f60f178c..e65c59b17 100644
--- a/system/phrasesupdate.php
+++ b/system/phrasesupdate.php
@@ -33136,6 +33136,26 @@ array(
)
)
),
+ array(
+ 'app' => 'anwesenheiten',
+ 'category' => 'global',
+ 'phrase' => 'errorValidateUhrzeit',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => 'Die Endzeit muss nach der Startzeit liegen.',
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'The end time must be after the start time.',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
array(
'app' => 'anwesenheiten',
'category' => 'global',