[core] dynamic shortcutlinks

This commit is contained in:
Tim Gröger 2021-04-18 23:26:54 +02:00
parent 81c5b10101
commit 3c7d711f59
4 changed files with 82 additions and 22 deletions

View File

@ -3,6 +3,9 @@
<q-list class='q-ml-lg'> <q-list class='q-ml-lg'>
<div v-for='child in entry.children' :key='child.link'> <div v-for='child in entry.children' :key='child.link'>
<q-item v-if='isGranted(child)' clickable :to='{name: child.link}'> <q-item v-if='isGranted(child)' clickable :to='{name: child.link}'>
<q-menu context-menu>
<q-btn v-close-popup label='Verknüpfung erstellen' dense @click='addShortCut(child)'/>
</q-menu>
<q-item-section avatar> <q-item-section avatar>
<q-icon :name='child.icon' /> <q-icon :name='child.icon' />
</q-item-section> </q-item-section>
@ -18,7 +21,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, onMounted, PropType } from 'vue'; import { computed, defineComponent, PropType } from 'vue';
import { hasPermissions } from 'src/utils/permission'; import { hasPermissions } from 'src/utils/permission';
import { FG_Plugin } from 'src/plugins'; import { FG_Plugin } from 'src/plugins';
@ -31,16 +34,20 @@ export default defineComponent({
required: true, required: true,
}, },
}, },
emits: {
addShortCut: (val: FG_Plugin.MenuLink) => val.link,
},
setup(props, {emit}) {
setup(props) {
function isGranted(val: FG_Plugin.MenuLink) { return hasPermissions(val.permissions || [])}; function isGranted(val: FG_Plugin.MenuLink) { return hasPermissions(val.permissions || [])};
const title = computed(() => const title = computed(() =>
typeof props.entry.title === 'object' ? props.entry.title.value : props.entry.title typeof props.entry.title === 'object' ? props.entry.title.value : props.entry.title
); );
onMounted(() => { function addShortCut(val: FG_Plugin.MenuLink) {
console.log(props.entry.children) emit('addShortCut', val)
}) }
return { isGranted, title };
return { isGranted, title, addShortCut};
}, },
}); });
</script> </script>

View File

@ -1,5 +1,9 @@
<template> <template>
<q-btn v-if="isGranted" flat dense :icon="shortcut.icon" :to="{ name: shortcut.link }" /> <q-btn v-if="isGranted" flat dense :icon="shortcut.icon" :to="{ name: shortcut.link }" round>
<q-menu v-if='context' context-menu>
<q-btn v-close-popup label='Verknüpfung entfernen' @click='deleteShortcut'/>
</q-menu>
</q-btn>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -12,12 +16,22 @@ export default defineComponent({
props: { props: {
shortcut: { shortcut: {
required: true, required: true,
type: Object as PropType<FG_Plugin.Shortcut>, type: Object as PropType<FG_Plugin.Shortcut | FG_Plugin.MenuLink>,
}, },
context: {
type: Boolean,
default: false,
}
}, },
setup(props) { emits: {
deleteShortcut: (val: FG_Plugin.MenuLink| FG_Plugin.Shortcut) => val.link
},
setup(props, {emit}) {
const isGranted = computed(() => hasPermissions(props.shortcut.permissions || [])); const isGranted = computed(() => hasPermissions(props.shortcut.permissions || []));
return { isGranted }; function deleteShortcut() {
emit('deleteShortcut', props.shortcut)
}
return { isGranted, deleteShortcut};
}, },
}); });
</script> </script>

View File

@ -33,10 +33,17 @@
<div v-else class="q-pa-sm">Keine neuen Benachrichtigungen</div> <div v-else class="q-pa-sm">Keine neuen Benachrichtigungen</div>
</q-menu> </q-menu>
</q-btn> </q-btn>
<shortcut-link <!--<shortcut-link
v-for="(shortcut, index) in shortcuts" v-for="(shortcut, index) in shortcuts"
:key="'shortcut' + index" :key="'shortcut' + index"
:shortcut="shortcut" :shortcut="shortcut"
/>-->
<shortcut-link
v-for="(shortcut, index) in shortCuts"
:key="'shortcut' + index"
:shortcut="shortcut"
context
@delete-shortcut="deleteShortcut"
/> />
<q-btn flat round dense icon="mdi-exit-to-app" @click="logout()" /> <q-btn flat round dense icon="mdi-exit-to-app" @click="logout()" />
</q-toolbar> </q-toolbar>
@ -52,9 +59,10 @@
<!-- Plugins --> <!-- Plugins -->
<q-list> <q-list>
<essential-expansion-link <essential-expansion-link
v-for="(entry, index) in menuLinks" v-for="(entry, index) in mainLinks"
:key="'plugin' + index" :key="'plugin' + index"
:entry="entry" :entry="entry"
@add-short-cut="addShortcut"
/> />
<!--<q-separator /> <!--<q-separator />
Plugin functions Plugin functions
@ -88,7 +96,6 @@ import { useRouter } from 'vue-router';
import { Screen } from 'quasar'; import { Screen } from 'quasar';
import config from 'src/config'; import config from 'src/config';
import EssentialExpansionLink from 'components/navigation/EssentialExpansionLink.vue'; import EssentialExpansionLink from 'components/navigation/EssentialExpansionLink.vue';
const essentials: FG_Plugin.MenuLink[] = [ const essentials: FG_Plugin.MenuLink[] = [
{ {
title: 'Über Flaschengeist', title: 'Über Flaschengeist',
@ -106,21 +113,16 @@ export default defineComponent({
const flaschengeist = inject<FG_Plugin.Flaschengeist>('flaschengeist'); const flaschengeist = inject<FG_Plugin.Flaschengeist>('flaschengeist');
const leftDrawer = ref(true); const leftDrawer = ref(true);
const leftDrawerMini = ref(false); const leftDrawerMini = ref(false);
const shortcuts = flaschengeist?.shortcuts || [];
const mainLinks = flaschengeist?.menuLinks || []; const mainLinks = flaschengeist?.menuLinks || [];
const notifications = computed(() => mainStore.notifications.slice().reverse()); const notifications = computed(() => mainStore.notifications.slice().reverse());
const polling = ref(NaN); const polling = ref(NaN);
const useNative = 'Notification' in window && window.Notification !== undefined; const useNative = 'Notification' in window && window.Notification !== undefined;
const noPermission = ref(!useNative || window.Notification.permission !== 'granted'); const noPermission = ref(!useNative || window.Notification.permission !== 'granted');
const subLinks = computed(() => {
const matched = router.currentRoute.value.matched[1];
return flaschengeist?.menuLinks.find((link) => matched.name == link.link)?.children;
});
onBeforeMount(() => { onBeforeMount(() => {
polling.value = window.setInterval(() => pollNotification(), config.pollingInterval); polling.value = window.setInterval(() => pollNotification(), config.pollingInterval);
pollNotification(); pollNotification();
void mainStore.getShortcuts();
}); });
onBeforeUnmount(() => window.clearInterval(polling.value)); onBeforeUnmount(() => window.clearInterval(polling.value));
@ -166,21 +168,46 @@ export default defineComponent({
}); });
} }
const shortCuts = computed({
get: () => mainStore.shortcuts,
set: (val: Array<FG_Plugin.MenuLink>) => {
console.log('hier bin ich', val);
mainStore.shortcuts = val;
},
});
function addShortcut(val: FG_Plugin.MenuLink) {
const idx = shortCuts.value.findIndex((a: FG_Plugin.MenuLink) => a.link === val.link);
if (idx < 0) {
shortCuts.value.push(val);
void mainStore.setShortcuts();
}
}
function deleteShortcut(val: FG_Plugin.MenuLink) {
console.log('deleteShortcut');
const idx = shortCuts.value.findIndex((a: FG_Plugin.MenuLink) => a.link === val.link);
if (idx > -1) {
shortCuts.value.splice(idx, 1);
void mainStore.setShortcuts();
}
}
return { return {
essentials, essentials,
leftDrawer, leftDrawer,
leftDrawerMini, leftDrawerMini,
logout, logout,
menuLinks: computed(() => flaschengeist?.menuLinks),
mainLinks, mainLinks,
notifications, notifications,
noPermission, noPermission,
openMenu, openMenu,
remove, remove,
requestPermission, requestPermission,
shortcuts,
subLinks,
useNative, useNative,
shortCuts,
addShortcut,
deleteShortcut,
}; };
}, },
}); });

View File

@ -25,6 +25,7 @@ export const useMainStore = defineStore({
session: loadCurrentSession(), session: loadCurrentSession(),
user: loadUser(), user: loadUser(),
notifications: [] as Array<FG_Plugin.Notification>, notifications: [] as Array<FG_Plugin.Notification>,
shortcuts: [] as FG_Plugin.MenuLink[],
}), }),
getters: { getters: {
@ -139,6 +140,17 @@ export const useMainStore = defineStore({
this.notifications.splice(idx, this.notifications.length - idx - 1); this.notifications.splice(idx, this.notifications.length - idx - 1);
} }
}, },
async getShortcuts() {
const { data } = await api.get<Array<FG_Plugin.MenuLink>>(
`users/${this.currentUser.userid}/shortcuts`
);
this.shortcuts = data;
},
async setShortcuts() {
await api.put(`users/${this.currentUser.userid}/shortcuts`, this.shortcuts);
},
}, },
}); });