[core][plugin] Fixed compatibility with Pinia

* API BREAK! Menu link title now must be a string or a function return a string
* Pinia unwraps Refs so we had to get rid of the ComputedRef
* Use current typescript
This commit is contained in:
Ferdinand Thiessen 2021-05-20 20:31:37 +02:00
parent 734a3e51c9
commit 0873b2da22
6 changed files with 40 additions and 32 deletions

View File

@ -34,7 +34,7 @@
"eslint-plugin-vue": "^7.9.0", "eslint-plugin-vue": "^7.9.0",
"eslint-webpack-plugin": "^2.5.4", "eslint-webpack-plugin": "^2.5.4",
"prettier": "^2.3.0", "prettier": "^2.3.0",
"typescript": "^4.2.3", "typescript": "^4.2.4",
"vuedraggable": "^4.0.1" "vuedraggable": "^4.0.1"
}, },
"prettier": { "prettier": {

View File

@ -1,22 +1,30 @@
<template> <template>
<q-expansion-item v-if="isGranted(entry)" clickable tag="a" target="self" :label='title' :icon='entry.icon' expand-separator> <q-expansion-item
<q-list class='q-ml-lg'> v-if="isGranted(entry)"
<div v-for='child in entry.children' :key='child.link'> clickable
<q-item v-if='isGranted(child)' clickable :to='{name: child.link}'> tag="a"
<q-menu context-menu> target="self"
<q-btn v-close-popup label='Verknüpfung erstellen' dense @click='addShortCut(child)'/> :label="title"
</q-menu> :icon="entry.icon"
<q-item-section avatar> expand-separator
<q-icon :name='child.icon' /> >
</q-item-section> <q-list class="q-ml-lg">
<q-item-section> <div v-for="child in entry.children" :key="child.link">
<q-item-label> <q-item v-if="isGranted(child)" clickable :to="{ name: child.link }">
{{child.title}} <q-menu context-menu>
</q-item-label> <q-btn v-close-popup label="Verknüpfung erstellen" dense @click="addShortCut(child)" />
</q-item-section> </q-menu>
</q-item> <q-item-section avatar>
</div> <q-icon :name="child.icon" />
</q-list> </q-item-section>
<q-item-section>
<q-item-label>
{{ child.title }}
</q-item-label>
</q-item-section>
</q-item>
</div>
</q-list>
</q-expansion-item> </q-expansion-item>
</template> </template>
@ -27,7 +35,7 @@ import { FG_Plugin } from 'src/plugins';
export default defineComponent({ export default defineComponent({
name: 'EssentialExpansionLink', name: 'EssentialExpansionLink',
components: { }, components: {},
props: { props: {
entry: { entry: {
type: Object as PropType<FG_Plugin.MenuLink>, type: Object as PropType<FG_Plugin.MenuLink>,
@ -37,17 +45,18 @@ export default defineComponent({
emits: { emits: {
addShortCut: (val: FG_Plugin.MenuLink) => val.link, addShortCut: (val: FG_Plugin.MenuLink) => val.link,
}, },
setup(props, {emit}) { setup(props, { emit }) {
function isGranted(val: FG_Plugin.MenuLink) {
function isGranted(val: FG_Plugin.MenuLink) { return hasPermissions(val.permissions || [])}; 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 === 'function' ? props.entry.title() : props.entry.title
); );
function addShortCut(val: FG_Plugin.MenuLink) { function addShortCut(val: FG_Plugin.MenuLink) {
emit('addShortCut', val) emit('addShortCut', val);
} }
return { isGranted, title, addShortCut}; return { isGranted, title, addShortCut };
}, },
}); });
</script> </script>

View File

@ -27,7 +27,7 @@ export default defineComponent({
setup(props) { setup(props) {
const isGranted = computed(() => hasPermissions(props.entry.permissions || [])); const isGranted = computed(() => hasPermissions(props.entry.permissions || []));
const title = computed(() => const title = computed(() =>
typeof props.entry.title === 'object' ? props.entry.title.value : props.entry.title typeof props.entry.title === 'function' ? props.entry.title() : props.entry.title
); );
return { isGranted, title }; return { isGranted, title };
}, },

4
src/plugins.d.ts vendored
View File

@ -1,5 +1,5 @@
import { RouteLocationRaw, RouteRecordRaw, RouteRecordName } from 'vue-router'; import { RouteLocationRaw, RouteRecordRaw, RouteRecordName } from 'vue-router';
import { Component, ComputedRef } from 'vue'; import { Component } from 'vue';
declare namespace FG_Plugin { declare namespace FG_Plugin {
/** /**
@ -99,7 +99,7 @@ declare namespace FG_Plugin {
* Base interface for internal use * Base interface for internal use
*/ */
interface MenuEntry { interface MenuEntry {
title: string | ComputedRef<string>; title: string | (() => string);
icon: string; icon: string;
permissions?: string[]; permissions?: string[];
children?: this[]; children?: this[];

View File

@ -1,11 +1,10 @@
import { FG_Plugin } from 'src/plugins'; import { FG_Plugin } from 'src/plugins';
import { useMainStore } from 'src/stores'; import { useMainStore } from 'src/stores';
import { computed } from 'vue';
const mainRoutes: FG_Plugin.MenuRoute[] = [ const mainRoutes: FG_Plugin.MenuRoute[] = [
{ {
get title() { get title() {
return computed(() => useMainStore().currentUser.display_name); return () => useMainStore().currentUser.display_name;
}, },
icon: 'mdi-account', icon: 'mdi-account',
permissions: ['user'], permissions: ['user'],

View File

@ -8024,7 +8024,7 @@ typescript@4.2.2:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.2.tgz#1450f020618f872db0ea17317d16d8da8ddb8c4c" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.2.tgz#1450f020618f872db0ea17317d16d8da8ddb8c4c"
integrity sha512-tbb+NVrLfnsJy3M59lsDgrzWIflR4d4TIUjz+heUnHZwdF7YsrMTKoRERiIvI2lvBG95dfpLxB21WZhys1bgaQ== integrity sha512-tbb+NVrLfnsJy3M59lsDgrzWIflR4d4TIUjz+heUnHZwdF7YsrMTKoRERiIvI2lvBG95dfpLxB21WZhys1bgaQ==
typescript@^4.2.3: typescript@^4.2.4:
version "4.2.4" version "4.2.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961"
integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==