11
11
</div >
12
12
13
13
<div class =" form-floating mb-3" >
14
- <textarea v-model =" form.description" style =" overflow-y : scroll ; height : 6rem " class =" form-control"
15
- id =" description" ></textarea >
14
+ <textarea
15
+ v-model =" form.description"
16
+ style =" overflow-y : scroll ; height : 6rem "
17
+ class =" form-control"
18
+ id =" description"
19
+ ></textarea >
16
20
<label for =" description" >{{ t("posts.form.description") }}</label >
17
21
</div >
18
22
19
23
<div class =" form-floating mb-3" >
20
24
<label for =" stringTags" >{{ t("posts.form.tags.tags") }}</label >
21
- <vue-tags-input v-model =" tag" :tags =" tags" :autocomplete-items =" tagList"
22
- :placeholder =" t('posts.form.tags.enter')" @tags-changed =" handleTagsChanged"
23
- @input =" handleAutocompletion" @before-adding-tag =" checkTag" />
25
+ <vue-tags-input
26
+ v-model =" tag"
27
+ :tags =" tags"
28
+ :autocomplete-items =" tagList"
29
+ :placeholder =" t('posts.form.tags.enter')"
30
+ @tags-changed =" handleTagsChanged"
31
+ @input =" handleAutocompletion"
32
+ @before-adding-tag =" checkTag"
33
+ />
24
34
</div >
25
35
26
36
<div class =" mb-3" >
27
- <ai-summaries :full-text =" form.markdown" :onSetDescription =" setDescription" :onAddTag =" addTag"
28
- :onSetKeyvisual =" setKeyvisual" ></ai-summaries >
37
+ <ai-summaries
38
+ :full-text =" form.markdown"
39
+ :onSetDescription =" setDescription"
40
+ :onAddTag =" addTag"
41
+ :onSetKeyvisual =" setKeyvisual"
42
+ ></ai-summaries >
29
43
</div >
30
44
31
45
<div class =" form-floating mb-3" >
32
- <textarea v-model =" form.markdown" class =" form-control" placeholder =" Blogpost" ref =" markdownArea"
33
- style =" height : 40vh ; min-height : 200px " aria-describedby =" markdownHelp"
34
- v-on:drop =" dropMarkdown($event)" required ></textarea >
46
+ <textarea
47
+ v-model =" form.markdown"
48
+ class =" form-control"
49
+ placeholder =" Blogpost"
50
+ ref =" markdownArea"
51
+ style =" height : 40vh ; min-height : 200px "
52
+ aria-describedby =" markdownHelp"
53
+ v-on:drop =" dropMarkdown($event)"
54
+ required
55
+ ></textarea >
35
56
<label for =" markdown" >{{ t("posts.form.message.label") }}</label >
36
57
<div id =" markdownHelp" class =" form-text" >{{ t("posts.form.message.hint") }}</div >
37
58
</div >
54
75
<h2 class =" display-6" >{{ (form?.title?.length ?? 0) > 0 ? form?.title : t("posts.form.preview.title") }}</h2 >
55
76
<div class =" card flex-md-row mb-4 box-shadow h-md-250" >
56
77
<div class =" card-body" style =" max-width : 100% " >
57
- <div v-if =" loading" style =" position : absolute ; width : 100% ; margin-top : 10vh ; text-align : center "
58
- class =" text-primary" >
78
+ <div v-if =" loading" style =" position : absolute ; width : 100% ; margin-top : 10vh ; text-align : center " class =" text-primary" >
59
79
<loading-spinner />
60
80
</div >
61
- <mark-down :markdown =" md" v-bind:custom-image-urls =" files" @loading =" loading = $event"
62
- :style =" loading ? 'opacity:0.2' : 'opacity:1'" ></mark-down >
81
+ <mark-down
82
+ :markdown =" md"
83
+ v-bind:custom-image-urls =" files"
84
+ @loading =" loading = $event"
85
+ :style =" loading ? 'opacity:0.2' : 'opacity:1'"
86
+ ></mark-down >
63
87
</div >
64
88
</div >
65
89
</div >
68
92
<div class =" card-body" >
69
93
<h3 >
70
94
{{ tc("posts.form.imageupload", Object.keys(files).length) }}
71
- <small class =" text-body-secondary f-4" v-if =" Object.keys(files).length > 0" >({{
72
- convertToHumanReadableFileSize(totalBytesInFiles) }})</small >
95
+ <small class =" text-body-secondary f-4" v-if =" Object.keys(files).length > 0"
96
+ >({{ convertToHumanReadableFileSize(totalBytesInFiles) }})</small
97
+ >
73
98
</h3 >
74
99
<!-- Hidden file input, used to open the file dialog, when the dropzone is clicked -->
75
- <input style =" display : none " type =" file" id =" file" multiple v-on:change =" handleFileChange($event)"
76
- accept =" .png, .gif, .jpg, .jpeg, image/png, image/jpeg, image/gif" />
77
- <div id =" dropzone" v-on:click =" openFileDialog()" v-on:drop =" handleFileChange($event)"
78
- v-on:dragover =" highlightDropzone($event, true)" v-on:dragleave =" highlightDropzone($event, false)"
79
- :class =" { active: dropzoneHighlight }" >
100
+ <input
101
+ style =" display : none "
102
+ type =" file"
103
+ id =" file"
104
+ multiple
105
+ v-on:change =" handleFileChange($event)"
106
+ accept =" .png, .gif, .jpg, .jpeg, image/png, image/jpeg, image/gif"
107
+ />
108
+ <div
109
+ id =" dropzone"
110
+ v-on:click =" openFileDialog()"
111
+ v-on:drop =" handleFileChange($event)"
112
+ v-on:dragover =" highlightDropzone($event, true)"
113
+ v-on:dragleave =" highlightDropzone($event, false)"
114
+ :class =" { active: dropzoneHighlight }"
115
+ >
80
116
<div class =" plus" ><fa-icon :icon =" faUpload" ></fa-icon ></div >
81
117
<span class =" label" v-if =" dropzoneHighlight" >Dateien fallen lassen</span >
82
118
<span class =" label" v-else >Neue Dateien hierher ziehen oder hier klicken um Dateien auszuwählen</span >
83
119
</div >
84
120
<Suspense v-for =" hash in Object.keys(files)" v-bind:key =" hash" >
85
- <ImagePreview :value =" files[hash]" :hash =" hash" @paste =" pasteImageFileToMarkdown($event, 'afterCursor')"
86
- @delete =" removeImageFileFromMarkdown(files[hash]); delete files[hash]" >
121
+ <ImagePreview
122
+ :value =" files[hash]"
123
+ :hash =" hash"
124
+ @paste =" pasteImageFileToMarkdown($event, 'afterCursor')"
125
+ @delete ="
126
+ removeImageFileFromMarkdown(files[hash]);
127
+ delete files[hash];
128
+ "
129
+ >
87
130
</ImagePreview >
88
131
</Suspense >
89
132
</div >
204
247
}
205
248
206
249
@keyframes shake {
207
-
208
250
10%,
209
251
90% {
210
252
transform : scale (0.9 ) translate3d (-1px , 0 , 0 );
@@ -251,8 +293,6 @@ import { computed, onMounted, reactive, ref, watch } from "vue";
251
293
import { useRoute , useRouter } from " vue-router" ;
252
294
import VueTagsInput from " @sipec/vue3-tags-input" ;
253
295
254
-
255
-
256
296
const tag = ref <string >(" " );
257
297
const tags = ref <{ text: string ; tiClasses? : string [] }[]>([]); // vue-tags-input internal format
258
298
const md = ref <string | null >(null );
@@ -279,7 +319,6 @@ const props = defineProps({
279
319
},
280
320
});
281
321
282
-
283
322
const totalBytesInFiles = computed (() =>
284
323
Object .values (files )
285
324
.map ((it ) => it .size )
@@ -309,7 +348,6 @@ onMounted(async () => {
309
348
// ADD already existing attachments to files
310
349
processAttachments (resJson .attachments );
311
350
}
312
-
313
351
} catch (e ) {
314
352
postHasError .value = true ;
315
353
}
@@ -321,15 +359,14 @@ onMounted(async () => {
321
359
}, 1000 );
322
360
});
323
361
324
-
325
362
// Function to process attachments and populate the files object
326
363
const processAttachments = (attachments : Attachment []) => {
327
364
attachments .forEach ((attachment ) => {
328
365
const blob = new Uint8Array ((attachment .file .binaryData as any ).data );
329
366
const file = new File ([blob ], attachment .filename , { type: attachment .file .mimeType });
330
367
files [attachment .file .sha256 ] = file ;
331
368
});
332
- }
369
+ };
333
370
334
371
// Create a computed property to generate URLs for the files
335
372
const filesWithUrls = computed (() => {
@@ -350,7 +387,7 @@ const removeImageFileFromMarkdown = (file: File) => {
350
387
setTimeout (() => {
351
388
form .markdown = markDownBeforeRemove .replace (strToRemove , " " );
352
389
}, 0 );
353
- }
390
+ };
354
391
355
392
const dropMarkdown = (evt : DragEvent ) => {
356
393
const items = evt .dataTransfer ?.items ;
0 commit comments