extended editor

This commit is contained in:
Torsten Schulz
2024-06-21 18:06:17 +02:00
parent dcfd478464
commit 97c72540cf
20 changed files with 754 additions and 35 deletions

View File

@@ -0,0 +1,98 @@
<template>
<div v-if="showDialog" class="modal">
<div class="modal-content">
<span class="close" @click="closeDialog">&times;</span>
<h2>Datei zum Download hinzufügen</h2>
<table>
<tr>
<td>
<label for="file-select">Datei auswählen:</label>
</td>
<td>
<select id="file-select" v-model="selectedFile">
<option v-for="file in files" :key="file.id" :value="file">
{{ file.title }} ({{ file.originalName }})
</option>
</select>
</td>
</tr>
</table>
<button @click="confirm">Hinzufügen</button>
</div>
</div>
</template>
<script>
import axios from '@/axios';
export default {
name: 'AddDownloadDialog',
data() {
return {
showDialog: false,
selectedFile: null,
files: [],
};
},
methods: {
async openAddDownloadDialog() {
this.showDialog = true;
try {
const response = await axios.get('/files');
this.files = response.data;
} catch (error) {
console.error('Fehler beim Abrufen der Dateien:', error);
}
},
closeDialog() {
this.showDialog = false;
this.selectedFile = null;
},
confirm() {
if (this.selectedFile) {
this.$emit('confirm', this.selectedFile.hash);
this.closeDialog();
} else {
alert('Bitte wählen Sie eine Datei aus.');
}
},
},
};
</script>
<style scoped>
.modal {
display: flex;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
}
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<span @click="downloadFile">{{ title }}</span>
</template>
<script>
export default {
name: 'DownloadLink',
props: {
title: {
type: String,
required: true,
},
hash: {
type: String,
required: true,
},
extension: {
type: String,
required: true,
},
},
methods: {
downloadFile() {
const filePath = `${__dirname}/files/uploads/${this.hash}${this.extension}`;
const link = document.createElement('a');
link.href = filePath;
link.download = this.title + this.extension;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
},
};
</script>
<style scoped>
span {
cursor: pointer;
color: blue;
text-decoration: underline;
}
</style>

View File

@@ -0,0 +1,47 @@
<template>
<span @click="downloadFile">{{ title }}</span>
</template>
<script>
import axios from 'axios';
export default {
name: 'DownloadLink',
props: {
title: {
type: String,
required: true,
},
hash: {
type: String,
required: true,
},
extension: {
type: String,
required: true,
},
},
methods: {
async downloadFile() {
const response = await axios.get(`/files/download/${this.hash}`, {
responseType: 'blob'
});
const blob = new Blob([response.data], { type: response.data.type });
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = `${this.title}${this.extension}`;
link.click();
window.URL.revokeObjectURL(link.href);
},
},
};
</script>
<style scoped>
span {
cursor: pointer;
color: blue;
text-decoration: underline;
}
</style>

View File

@@ -7,6 +7,7 @@ import { createApp, h, ref, watch } from 'vue';
import WorshipRender from './WorshipRender.vue';
import ImageRender from './ImageRender.vue';
import EventRender from './EventRender.vue';
import DownloadLink from './DownloadLink.vue';
export default {
name: 'RenderContentComponent',
@@ -21,8 +22,9 @@ export default {
const renderContent = (content) => {
let result = renderWorship(content);
result = renderImage(result); // Use result here
result = renderEvent(result); // Use result here
result = renderImage(result);
result = renderEvent(result);
result = renderDownload(result);
return result;
};
@@ -58,7 +60,6 @@ export default {
if (placeholder) {
const app = createApp({
render() {
console.log(config);
return h(ImageRender, { id: config });
},
});
@@ -74,9 +75,7 @@ export default {
const eventsPattern = /{{ events:(.*?) }}/g;
let result = content;
result = result.replace(eventsPattern, (match, config) => {
console.log(config);
const props = parseConfig(config);
console.log(props);
const placeholderId = `event-render-placeholder-${Math.random().toString(36).substr(2, 9)}`;
setTimeout(() => {
const placeholder = document.getElementById(placeholderId);
@@ -94,6 +93,27 @@ export default {
return result;
};
const renderDownload = (content) => {
const downloadPattern = /{{ download title="(.*?)" hash="(.*?)" extension="(.*?)" }}/g;
let result = content;
result = result.replace(downloadPattern, (match, title, hash, extension) => {
const placeholderId = `download-render-placeholder-${Math.random().toString(36).substr(2, 9)}`;
setTimeout(() => {
const placeholder = document.getElementById(placeholderId);
if (placeholder) {
const app = createApp({
render() {
return h(DownloadLink, { title, hash, extension });
},
});
app.mount(placeholder);
}
}, 0);
return `<div id="${placeholderId}"></div>`;
});
return result;
};
const parseConfig = (configString) => {
const config = {};
const configArray = configString.split(',');