Added Worship page rendering
This commit is contained in:
@@ -1,207 +0,0 @@
|
||||
<template>
|
||||
<div class="admin-menu-management">
|
||||
<h2>Menüverwaltung</h2>
|
||||
<div>
|
||||
<h3>Neuen Menüpunkt hinzufügen</h3>
|
||||
<form @submit.prevent="addMenuItem">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" v-model="newItem.name" required />
|
||||
|
||||
<label for="link">Link:</label>
|
||||
<input type="text" v-model="newItem.link" required />
|
||||
|
||||
<label for="component">Component:</label>
|
||||
<input type="text" v-model="newItem.component" required />
|
||||
|
||||
<label for="showInMenu">Im Menü anzeigen:</label>
|
||||
<input type="checkbox" v-model="newItem.showInMenu" />
|
||||
|
||||
<label for="requiresAuth">Authentifizierung erforderlich:</label>
|
||||
<input type="checkbox" v-model="newItem.requiresAuth" />
|
||||
|
||||
<label for="image">Bild:</label>
|
||||
<input type="text" v-model="newItem.image" />
|
||||
|
||||
<label for="parentId">Eltern-Menüpunkt:</label>
|
||||
<select v-model="newItem.parentId">
|
||||
<option :value="null">Kein Eltern-Menüpunkt</option>
|
||||
<option v-for="item in menuItems" :key="item.id" :value="item.id">
|
||||
{{ item.name }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<button type="submit">Hinzufügen</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>Menüpunkte bearbeiten</h3>
|
||||
<ul>
|
||||
<li v-for="item in menuItems" :key="item.id">
|
||||
{{ item.name }}
|
||||
<button @click="editMenuItem(item)">Bearbeiten</button>
|
||||
<button @click="deleteMenuItem(item.id)">Löschen</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div v-if="editingItem">
|
||||
<h3>Menüpunkt bearbeiten</h3>
|
||||
<form @submit.prevent="updateMenuItem">
|
||||
<label for="editName">Name:</label>
|
||||
<input type="text" v-model="editingItem.name" required />
|
||||
|
||||
<label for="editLink">Link:</label>
|
||||
<input type="text" v-model="editingItem.link" required />
|
||||
|
||||
<label for="editComponent">Component:</label>
|
||||
<input type="text" v-model="editingItem.component" required />
|
||||
|
||||
<label for="editShowInMenu">Im Menü anzeigen:</label>
|
||||
<input type="checkbox" v-model="editingItem.showInMenu" />
|
||||
|
||||
<label for="editRequiresAuth">Authentifizierung erforderlich:</label>
|
||||
<input type="checkbox" v-model="editingItem.requiresAuth" />
|
||||
|
||||
<label for="editImage">Bild:</label>
|
||||
<input type="text" v-model="editingItem.image" />
|
||||
|
||||
<label for="editParentId">Eltern-Menüpunkt:</label>
|
||||
<select v-model="editingItem.parentId">
|
||||
<option :value="null">Kein Eltern-Menüpunkt</option>
|
||||
<option v-for="item in menuItems" :key="item.id" :value="item.id">
|
||||
{{ item.name }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<button type="submit">Aktualisieren</button>
|
||||
<button @click="cancelEdit">Abbrechen</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapState, mapActions } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'AdminMenuManagement',
|
||||
data() {
|
||||
return {
|
||||
newItem: {
|
||||
name: '',
|
||||
link: '',
|
||||
component: '',
|
||||
showInMenu: false,
|
||||
requiresAuth: false,
|
||||
image: '',
|
||||
parentId: null
|
||||
},
|
||||
editingItem: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(['menuData']),
|
||||
menuItems() {
|
||||
return this.menuData;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['loadMenuData']),
|
||||
async addMenuItem() {
|
||||
this.menuData.push(this.newItem);
|
||||
await this.saveMenuData();
|
||||
this.resetNewItem();
|
||||
},
|
||||
editMenuItem(item) {
|
||||
this.editingItem = { ...item };
|
||||
},
|
||||
async updateMenuItem() {
|
||||
const index = this.menuData.findIndex(item => item.id === this.editingItem.id);
|
||||
if (index !== -1) {
|
||||
this.menuData.splice(index, 1, this.editingItem);
|
||||
await this.saveMenuData();
|
||||
this.cancelEdit();
|
||||
}
|
||||
},
|
||||
async deleteMenuItem(id) {
|
||||
this.menuData = this.menuData.filter(item => item.id !== id);
|
||||
await this.saveMenuData();
|
||||
},
|
||||
cancelEdit() {
|
||||
this.editingItem = null;
|
||||
},
|
||||
resetNewItem() {
|
||||
this.newItem = {
|
||||
name: '',
|
||||
link: '',
|
||||
component: '',
|
||||
showInMenu: false,
|
||||
requiresAuth: false,
|
||||
image: '',
|
||||
parentId: null
|
||||
};
|
||||
},
|
||||
async saveMenuData() {
|
||||
try {
|
||||
await fetch('/menu-data', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(this.menuData)
|
||||
});
|
||||
await this.loadMenuData();
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Speichern der Menü-Daten:', error);
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadMenuData();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.admin-menu-management {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
form {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
form label {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
form input,
|
||||
form select {
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-top: 10px;
|
||||
padding: 5px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 10px 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
li button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { ref, computed, onMounted, watch } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
import axios from '../../axios';
|
||||
import { EditorContent, useEditor } from '@tiptap/vue-3';
|
||||
@@ -97,7 +97,7 @@ export default {
|
||||
],
|
||||
content: '',
|
||||
onUpdate: ({ editor }) => {
|
||||
store.commit('UPDATE_PAGE_CONTENT', editor.getHTML());
|
||||
store.commit('SET_PAGE_CONTENT', editor.getHTML());
|
||||
},
|
||||
});
|
||||
|
||||
@@ -118,6 +118,7 @@ export default {
|
||||
const allPages = [];
|
||||
flattenPages(data, allPages);
|
||||
pages.value = allPages.sort((a, b) => a.name.localeCompare(b.name));
|
||||
store.commit('setMenuData', data);
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der Seiten:', error);
|
||||
}
|
||||
@@ -127,7 +128,6 @@ export default {
|
||||
try {
|
||||
await store.dispatch('loadPageContent', selectedPage.value);
|
||||
const content = store.getters.pageContent;
|
||||
|
||||
const setEditorContent = () => {
|
||||
if (editor.value && editor.value.commands) {
|
||||
editor.value.commands.setContent(content, false);
|
||||
@@ -135,7 +135,6 @@ export default {
|
||||
setTimeout(setEditorContent, 100);
|
||||
}
|
||||
};
|
||||
|
||||
setEditorContent();
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden des Seiteninhalts:', error);
|
||||
@@ -167,6 +166,15 @@ export default {
|
||||
return pages.value;
|
||||
});
|
||||
|
||||
watch(selectedPage, (newPage) => {
|
||||
store.dispatch('setSelectedPage', newPage);
|
||||
const page = pages.value.find(page => page.link === newPage);
|
||||
if (page) {
|
||||
store.dispatch('setPageTitle', page.name);
|
||||
}
|
||||
loadPageContent();
|
||||
});
|
||||
|
||||
const openWorshipDialog = () => {
|
||||
worshipDialog.value.openWorshipDialog();
|
||||
};
|
||||
|
||||
@@ -1,272 +1,280 @@
|
||||
<template>
|
||||
<div class="menu-management">
|
||||
<h1>Menüverwaltung</h1>
|
||||
<div class="button-container">
|
||||
<button @click="addMenuItem">Hauptmenü hinzufügen</button>
|
||||
<button @click="saveMenuData">Speichern</button>
|
||||
</div>
|
||||
<div v-if="selectedMenuItem" class="edit-form">
|
||||
<h2>Menüpunkt bearbeiten</h2>
|
||||
<form @submit.prevent="saveMenuData">
|
||||
<label for="name">Name</label>
|
||||
<input id="name" v-model="selectedMenuItem.name" placeholder="Name" />
|
||||
|
||||
<label for="link">Link</label>
|
||||
<input id="link" v-model="selectedMenuItem.link" placeholder="Link" />
|
||||
|
||||
<label for="order-id">Order ID</label>
|
||||
<input id="order-id" v-model.number="selectedMenuItem.orderId" placeholder="Order ID" type="number" class="order-id" />
|
||||
|
||||
<div class="checkbox-container">
|
||||
<label>
|
||||
<input type="checkbox" v-model="selectedMenuItem.showInMenu" />
|
||||
Im Menü anzeigen
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" v-model="selectedMenuItem.requiresAuth" />
|
||||
Authentifizierung erforderlich
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<label for="parent-id">Elternelement</label>
|
||||
<select id="parent-id" v-model="selectedMenuItem.parent_id">
|
||||
<option value="">Ohne Elternelement</option>
|
||||
<option v-for="item in flattenedMenuData" :key="item.id" :value="item.id">
|
||||
<span v-html="getIndentedName(item)"></span>
|
||||
</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
<div class="tree-view">
|
||||
<ul>
|
||||
<li v-for="menuItem in sortedMenuData" :key="menuItem.id">
|
||||
<div class="menu-item">
|
||||
<span @click="selectMenuItem(menuItem)">
|
||||
{{ menuItem.name }} (ID: {{ menuItem.orderId }})
|
||||
</span>
|
||||
<div class="action-buttons">
|
||||
<button @click="addSubmenu(menuItem)" class="action-button">Untermenü hinzufügen</button>
|
||||
<button @click="removeMenuItem(menuItem)" class="action-button">Löschen</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul v-if="menuItem.submenu.length">
|
||||
<li v-for="submenuItem in sortedSubmenu(menuItem)" :key="submenuItem.id">
|
||||
<div class="menu-item">
|
||||
<span @click="selectMenuItem(submenuItem)">
|
||||
{{ submenuItem.name }} (ID: {{ submenuItem.orderId }})
|
||||
</span>
|
||||
<div class="action-buttons">
|
||||
<button @click="addSubmenu(menuItem)" class="action-button">Untermenü hinzufügen</button>
|
||||
<button @click="removeSubmenu(menuItem, submenuItem)" class="action-button">Löschen</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="menu-management">
|
||||
<h1>Menüverwaltung</h1>
|
||||
<div class="button-container">
|
||||
<button @click="addMenuItem">Hauptmenü hinzufügen</button>
|
||||
<button @click="saveMenuData">Speichern</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import axios from '../../axios';
|
||||
|
||||
export default {
|
||||
name: 'MenuManagement',
|
||||
setup() {
|
||||
const menuData = ref([]);
|
||||
const selectedMenuItem = ref(null);
|
||||
|
||||
const fetchMenuData = async () => {
|
||||
try {
|
||||
const response = await axios.get('/menu-data');
|
||||
menuData.value = response.data;
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der Menü-Daten:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const saveMenuData = async () => {
|
||||
try {
|
||||
const flatMenuData = flattenMenuData(menuData.value);
|
||||
await axios.post('/menu-data', flatMenuData);
|
||||
alert('Menü-Daten erfolgreich gespeichert');
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Speichern der Menü-Daten:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const flattenMenuData = (data, parentId = null) => {
|
||||
return data.reduce((acc, item) => {
|
||||
const newItem = { ...item, parent_id: parentId };
|
||||
const { submenu, ...rest } = newItem;
|
||||
acc.push(rest);
|
||||
if (submenu && submenu.length) {
|
||||
acc.push(...flattenMenuData(submenu, newItem.id));
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
};
|
||||
|
||||
const addMenuItem = () => {
|
||||
const newItem = {
|
||||
name: '',
|
||||
link: '',
|
||||
component: '',
|
||||
showInMenu: true,
|
||||
requiresAuth: false,
|
||||
orderId: 0,
|
||||
submenu: [],
|
||||
parent_id: null,
|
||||
};
|
||||
menuData.value.push(newItem);
|
||||
selectMenuItem(newItem);
|
||||
};
|
||||
|
||||
const addSubmenu = (menuItem) => {
|
||||
const newSubItem = {
|
||||
name: '',
|
||||
link: '',
|
||||
component: '',
|
||||
showInMenu: true,
|
||||
requiresAuth: false,
|
||||
orderId: 0,
|
||||
parent_id: menuItem.id,
|
||||
};
|
||||
menuItem.submenu.push(newSubItem);
|
||||
selectMenuItem(newSubItem);
|
||||
};
|
||||
|
||||
const removeMenuItem = (menuItem) => {
|
||||
const index = menuData.value.indexOf(menuItem);
|
||||
if (index > -1) {
|
||||
menuData.value.splice(index, 1);
|
||||
}
|
||||
selectedMenuItem.value = null;
|
||||
};
|
||||
|
||||
const removeSubmenu = (menuItem, submenuItem) => {
|
||||
const index = menuItem.submenu.indexOf(submenuItem);
|
||||
if (index > -1) {
|
||||
menuItem.submenu.splice(index, 1);
|
||||
}
|
||||
selectedMenuItem.value = null;
|
||||
};
|
||||
|
||||
const selectMenuItem = (menuItem) => {
|
||||
selectedMenuItem.value = menuItem;
|
||||
};
|
||||
|
||||
const sortedMenuData = computed(() => {
|
||||
return [...menuData.value].sort((a, b) => a.orderId - b.orderId);
|
||||
});
|
||||
|
||||
const sortedSubmenu = (menuItem) => {
|
||||
return menuItem.submenu.slice().sort((a, b) => a.orderId - b.orderId);
|
||||
};
|
||||
|
||||
const getIndentedName = (item) => {
|
||||
return ' '.repeat(item.indent * 2) + item.name;
|
||||
};
|
||||
|
||||
onMounted(fetchMenuData);
|
||||
|
||||
return {
|
||||
menuData,
|
||||
sortedMenuData,
|
||||
sortedSubmenu,
|
||||
selectedMenuItem,
|
||||
fetchMenuData,
|
||||
saveMenuData,
|
||||
addMenuItem,
|
||||
addSubmenu,
|
||||
removeMenuItem,
|
||||
removeSubmenu,
|
||||
selectMenuItem,
|
||||
getIndentedName,
|
||||
};
|
||||
},
|
||||
<div v-if="selectedMenuItem" class="edit-form">
|
||||
<h2>Menüpunkt bearbeiten</h2>
|
||||
<form @submit.prevent="saveMenuData">
|
||||
<label for="name">Name</label>
|
||||
<input id="name" v-model="selectedMenuItem.name" placeholder="Name" />
|
||||
|
||||
<label for="link">Link</label>
|
||||
<input id="link" v-model="selectedMenuItem.link" placeholder="Link" />
|
||||
|
||||
<label for="page-title">Seitenname</label>
|
||||
<input id="page-title" v-model="selectedMenuItem.pageTitle" placeholder="Seitenname" />
|
||||
|
||||
<label for="order-id">Order ID</label>
|
||||
<input id="order-id" v-model.number="selectedMenuItem.orderId" placeholder="Order ID" type="number"
|
||||
class="order-id" />
|
||||
|
||||
<div class="checkbox-container">
|
||||
<label>
|
||||
<input type="checkbox" v-model="selectedMenuItem.showInMenu" />
|
||||
Im Menü anzeigen
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" v-model="selectedMenuItem.requiresAuth" />
|
||||
Authentifizierung erforderlich
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<label for="parent-id">Elternelement</label>
|
||||
<select id="parent-id" v-model="selectedMenuItem.parent_id">
|
||||
<option value="">Ohne Elternelement</option>
|
||||
<option v-for="item in flattenedMenuData" :key="item.id" :value="item.id">
|
||||
<span v-html="getIndentedName(item)"></span>
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<label for="component">Vue-Komponente</label>
|
||||
<input id="component" v-model="selectedMenuItem.component" placeholder="Vue-Komponente" />
|
||||
</form>
|
||||
</div>
|
||||
<div class="tree-view">
|
||||
<ul>
|
||||
<li v-for="menuItem in sortedMenuData" :key="menuItem.id">
|
||||
<div class="menu-item">
|
||||
<span @click="selectMenuItem(menuItem)">
|
||||
{{ menuItem.name }} (ID: {{ menuItem.orderId }})
|
||||
</span>
|
||||
<div class="action-buttons">
|
||||
<button @click="addSubmenu(menuItem)" class="action-button">Untermenü hinzufügen</button>
|
||||
<button @click="removeMenuItem(menuItem)" class="action-button">Löschen</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul v-if="menuItem.submenu.length">
|
||||
<li v-for="submenuItem in sortedSubmenu(menuItem)" :key="submenuItem.id">
|
||||
<div class="menu-item">
|
||||
<span @click="selectMenuItem(submenuItem)">
|
||||
{{ submenuItem.name }} (ID: {{ submenuItem.orderId }})
|
||||
</span>
|
||||
<div class="action-buttons">
|
||||
<button @click="addSubmenu(menuItem)" class="action-button">Untermenü hinzufügen</button>
|
||||
<button @click="removeSubmenu(menuItem, submenuItem)" class="action-button">Löschen</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import axios from '../../axios';
|
||||
|
||||
export default {
|
||||
name: 'MenuManagement',
|
||||
setup() {
|
||||
const menuData = ref([]);
|
||||
const selectedMenuItem = ref(null);
|
||||
|
||||
const fetchMenuData = async () => {
|
||||
try {
|
||||
const response = await axios.get('/menu-data');
|
||||
menuData.value = response.data;
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der Menü-Daten:', error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.menu-management {
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
display: inline-flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.tree-view {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.tree-view ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tree-view li {
|
||||
margin-bottom: 5px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.tree-view .menu-item {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tree-view span {
|
||||
cursor: pointer;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.tree-view button {
|
||||
border: none;
|
||||
height: 1.6em;
|
||||
padding: 0 0.5em;
|
||||
margin: 1px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.tree-view span:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.edit-form {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.edit-form label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.edit-form input:not([type="checkbox"]) {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.edit-form .checkbox-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.edit-form .order-id {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.edit-form button {
|
||||
margin-top: 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
const saveMenuData = async () => {
|
||||
try {
|
||||
const flatMenuData = flattenMenuData(menuData.value);
|
||||
await axios.post('/menu-data', flatMenuData);
|
||||
alert('Menü-Daten erfolgreich gespeichert');
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Speichern der Menü-Daten:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const flattenMenuData = (data, parentId = null) => {
|
||||
return data.reduce((acc, item) => {
|
||||
const newItem = { ...item, parent_id: parentId, page_title: item.pageTitle };
|
||||
const { submenu, ...rest } = newItem;
|
||||
acc.push(rest);
|
||||
if (submenu && submenu.length) {
|
||||
acc.push(...flattenMenuData(submenu, newItem.id));
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
};
|
||||
|
||||
const addMenuItem = () => {
|
||||
const newItem = {
|
||||
name: '',
|
||||
link: '',
|
||||
component: '',
|
||||
pageTitle: '',
|
||||
showInMenu: true,
|
||||
requiresAuth: false,
|
||||
orderId: 0,
|
||||
submenu: [],
|
||||
parent_id: null,
|
||||
};
|
||||
menuData.value.push(newItem);
|
||||
selectMenuItem(newItem);
|
||||
};
|
||||
|
||||
const addSubmenu = (menuItem) => {
|
||||
const newSubItem = {
|
||||
name: '',
|
||||
link: '',
|
||||
component: '',
|
||||
pageTitle: '',
|
||||
showInMenu: true,
|
||||
requiresAuth: false,
|
||||
orderId: 0,
|
||||
parent_id: menuItem.id,
|
||||
};
|
||||
menuItem.submenu.push(newSubItem);
|
||||
selectMenuItem(newSubItem);
|
||||
};
|
||||
|
||||
const removeMenuItem = (menuItem) => {
|
||||
const index = menuData.value.indexOf(menuItem);
|
||||
if (index > -1) {
|
||||
menuData.value.splice(index, 1);
|
||||
}
|
||||
selectedMenuItem.value = null;
|
||||
};
|
||||
|
||||
const removeSubmenu = (menuItem, submenuItem) => {
|
||||
const index = menuItem.submenu.indexOf(submenuItem);
|
||||
if (index > -1) {
|
||||
menuItem.submenu.splice(index, 1);
|
||||
}
|
||||
selectedMenuItem.value = null;
|
||||
};
|
||||
|
||||
const selectMenuItem = (menuItem) => {
|
||||
selectedMenuItem.value = menuItem;
|
||||
};
|
||||
|
||||
const sortedMenuData = computed(() => {
|
||||
return [...menuData.value].sort((a, b) => a.orderId - b.orderId);
|
||||
});
|
||||
|
||||
const sortedSubmenu = (menuItem) => {
|
||||
return menuItem.submenu.slice().sort((a, b) => a.orderId - b.orderId);
|
||||
};
|
||||
|
||||
const getIndentedName = (item) => {
|
||||
return ' '.repeat(item.indent * 2) + item.name;
|
||||
};
|
||||
|
||||
onMounted(fetchMenuData);
|
||||
|
||||
return {
|
||||
menuData,
|
||||
sortedMenuData,
|
||||
sortedSubmenu,
|
||||
selectedMenuItem,
|
||||
fetchMenuData,
|
||||
saveMenuData,
|
||||
addMenuItem,
|
||||
addSubmenu,
|
||||
removeMenuItem,
|
||||
removeSubmenu,
|
||||
selectMenuItem,
|
||||
getIndentedName,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.menu-management {
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
display: inline-flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.tree-view {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.tree-view ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tree-view li {
|
||||
margin-bottom: 5px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.tree-view .menu-item {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tree-view span {
|
||||
cursor: pointer;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.tree-view button {
|
||||
border: none;
|
||||
height: 1.6em;
|
||||
padding: 0 0.5em;
|
||||
margin: 1px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.tree-view span:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.edit-form {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.edit-form label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.edit-form input:not([type="checkbox"]) {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.edit-form .checkbox-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.edit-form .order-id {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.edit-form button {
|
||||
margin-top: 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,26 +1,55 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="previewinfo">Dies ist eine Vorschau.</div>
|
||||
<div v-html="renderedContent"></div>
|
||||
<h1>{{ title }}</h1>
|
||||
<RenderContentComponent :content="content" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed } from 'vue';
|
||||
import { computed, watchEffect } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
import { render } from '@/utils/render';
|
||||
import RenderContentComponent from '@/components/RenderContentComponent.vue';
|
||||
|
||||
export default {
|
||||
name: 'PagePreview',
|
||||
components: {
|
||||
RenderContentComponent
|
||||
},
|
||||
setup() {
|
||||
const store = useStore();
|
||||
const content = computed(() => store.state.pageContent);
|
||||
const renderedContent = computed(() => render(content.value));
|
||||
const selectedPage = computed(() => store.state.selectedPage);
|
||||
const menuData = computed(() => store.state.menuData);
|
||||
const title = computed(() => store.state.pageTitle);
|
||||
|
||||
const setTitle = (link) => {
|
||||
const findTitle = (menuItems, link) => {
|
||||
for (const item of menuItems) {
|
||||
if (item.link === link) {
|
||||
return item.pageTitle || item.name;
|
||||
}
|
||||
if (item.submenu && item.submenu.length > 0) {
|
||||
const found = findTitle(item.submenu, link);
|
||||
if (found) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
store.dispatch('setPageTitle', findTitle(menuData.value, link));
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
setTitle(selectedPage.value);
|
||||
});
|
||||
|
||||
return {
|
||||
renderedContent,
|
||||
content,
|
||||
title
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
<label for="date">Datum:</label>
|
||||
<input type="date" id="date" v-model="worshipData.date" required>
|
||||
|
||||
<label for="dayName">Name des Tags:</label>
|
||||
<input type="text" id="dayName" v-model="worshipData.dayName" required>
|
||||
|
||||
<label for="time">Uhrzeit:</label>
|
||||
<input type="time" id="time" v-model="worshipData.time" required>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user