salix-front/src/components/LeftMenu.vue

201 lines
6.5 KiB
Vue
Raw Normal View History

2022-03-28 07:06:36 +00:00
<script setup>
2022-11-29 13:45:48 +00:00
import axios from 'axios';
import { onMounted, ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
2022-11-24 13:54:38 +00:00
import { useQuasar } from 'quasar';
2022-11-24 06:21:45 +00:00
import { useRoute } from 'vue-router';
2022-11-29 06:10:04 +00:00
import { useNavigationStore } from 'src/stores/useNavigationStore';
2022-11-29 13:45:48 +00:00
import { toLowerCamel } from 'src/filters';
2022-11-21 16:33:21 +00:00
import routes from 'src/router/modules';
2022-11-29 13:45:48 +00:00
import LeftMenuItem from './LeftMenuItem.vue';
import LeftMenuItemGroup from './LeftMenuItemGroup.vue';
const { t } = useI18n();
2022-11-24 06:21:45 +00:00
const route = useRoute();
2022-11-24 13:54:38 +00:00
const quasar = useQuasar();
2022-11-29 06:10:04 +00:00
const navigation = useNavigationStore();
2022-11-24 06:21:45 +00:00
const props = defineProps({
2022-11-21 16:33:21 +00:00
source: {
type: String,
default: 'main',
},
});
2022-12-19 13:32:55 +00:00
onMounted(async () => {
await navigation.fetchPinned();
getRoutes();
2022-11-29 13:45:48 +00:00
});
2022-11-24 06:21:45 +00:00
function findMatches(search, item) {
const matches = [];
function findRoute(search, item) {
for (const child of item.children) {
if (search.indexOf(child.name) > -1) {
matches.push(child);
} else if (child.children) {
findRoute(search, child);
}
}
}
findRoute(search, item);
return matches;
}
function addChildren(module, route, parent) {
if (route.menus) {
const mainMenus = route.menus[props.source];
const matches = findMatches(mainMenus, route);
2022-12-13 11:21:12 +00:00
2022-11-24 06:21:45 +00:00
for (const child of matches) {
2022-11-29 13:45:48 +00:00
navigation.addMenuItem(module, child, parent);
2022-11-24 06:21:45 +00:00
}
}
}
2022-12-13 11:21:12 +00:00
2022-11-29 13:45:48 +00:00
const pinnedItems = computed(() => {
return items.value.filter((item) => item.isPinned);
});
2022-11-24 06:21:45 +00:00
const items = ref([]);
2022-11-29 13:45:48 +00:00
function getRoutes() {
if (props.source === 'main') {
const modules = Object.assign([], navigation.getModules().value);
2022-12-13 11:21:12 +00:00
2022-11-29 13:45:48 +00:00
for (const item of modules) {
const moduleDef = routes.find((route) => toLowerCamel(route.name) === item.module);
item.children = [];
2022-11-29 06:10:04 +00:00
2022-12-13 11:21:12 +00:00
if (!moduleDef) continue;
2022-11-29 13:45:48 +00:00
addChildren(item.module, moduleDef, item.children);
}
2022-11-24 06:21:45 +00:00
2022-11-29 13:45:48 +00:00
items.value = modules;
2022-11-21 16:33:21 +00:00
}
2022-11-24 06:21:45 +00:00
2022-11-29 13:45:48 +00:00
if (props.source === 'card') {
const currentRoute = route.matched[1];
const currentModule = toLowerCamel(currentRoute.name);
const moduleDef = routes.find((route) => toLowerCamel(route.name) === currentModule);
2022-11-21 16:33:21 +00:00
2022-12-13 11:21:12 +00:00
if (!moduleDef) return;
2022-11-29 13:45:48 +00:00
addChildren(currentModule, moduleDef, items.value);
}
}
2022-11-24 06:21:45 +00:00
2022-11-29 13:45:48 +00:00
async function togglePinned(item, event) {
2022-11-29 06:10:04 +00:00
if (event.defaultPrevented) return;
event.preventDefault();
event.stopPropagation();
2022-11-29 13:45:48 +00:00
const data = { moduleName: item.module };
const response = await axios.post('StarredModules/toggleStarredModule', data);
item.isPinned = false;
if (response.data && response.data.id) {
item.isPinned = true;
}
navigation.togglePinned(item.module);
2022-11-21 16:33:21 +00:00
2022-11-24 13:54:38 +00:00
quasar.notify({
message: t('globals.dataSaved'),
type: 'positive',
});
}
</script>
<template>
2022-10-17 14:23:19 +00:00
<q-list padding>
2022-11-29 13:45:48 +00:00
<template v-if="$props.source === 'main'">
<q-item-label header>
{{ t('globals.pinnedModules') }}
</q-item-label>
<template v-for="item in pinnedItems" :key="item.name">
<template v-if="item.children">
<left-menu-item-group :item="item" group="pinnedModules" class="pinned">
<template #side>
<q-btn
v-if="item.isPinned === true"
@click="togglePinned(item, $event)"
icon="vn:pin_off"
size="xs"
flat
round
2022-11-24 13:54:38 +00:00
>
2022-11-29 13:45:48 +00:00
<q-tooltip>{{ t('components.leftMenu.removeFromPinned') }}</q-tooltip>
</q-btn>
<q-btn
v-if="item.isPinned === false"
@click="togglePinned(item, $event)"
icon="vn:pin"
size="xs"
flat
round
>
<q-tooltip>{{ t('components.leftMenu.addToPinned') }}</q-tooltip>
</q-btn>
</template>
</left-menu-item-group>
</template>
<left-menu-item v-if="!item.children" :item="item" />
2022-11-24 06:21:45 +00:00
</template>
2022-11-29 13:45:48 +00:00
<q-separator />
<q-expansion-item :label="t('moduleIndex.allModules')">
2022-11-24 13:54:38 +00:00
<template v-for="item in items" :key="item.name">
<template v-if="item.children">
2022-11-29 13:45:48 +00:00
<left-menu-item-group :item="item" group="modules">
<template #side>
<q-btn
v-if="item.isPinned === true"
@click="togglePinned(item, $event)"
icon="vn:pin_off"
size="xs"
flat
round
>
<q-tooltip>{{ t('components.leftMenu.removeFromPinned') }}</q-tooltip>
</q-btn>
<q-btn
v-if="item.isPinned === false"
@click="togglePinned(item, $event)"
icon="vn:pin"
size="xs"
flat
round
>
<q-tooltip>{{ t('components.leftMenu.addToPinned') }}</q-tooltip>
</q-btn>
2022-11-24 13:54:38 +00:00
</template>
2022-11-29 13:45:48 +00:00
</left-menu-item-group>
2022-11-24 13:54:38 +00:00
</template>
</template>
2022-11-29 13:45:48 +00:00
</q-expansion-item>
<q-separator />
</template>
<template v-if="$props.source === 'card'">
<template v-for="item in items" :key="item.name">
<left-menu-item v-if="!item.children" :item="item" />
</template>
</template>
2022-10-17 14:23:19 +00:00
</q-list>
</template>
2022-11-29 13:45:48 +00:00
<style>
.pinned .icon-pin,
.pinned .icon-pin_off {
visibility: hidden;
}
.pinned:hover .icon-pin,
.pinned:hover .icon-pin_off {
visibility: visible;
}
</style>