4722 - Routes refactor
gitea/salix-front/pipeline/head There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2022-11-21 17:33:21 +01:00
parent d33da3cf3c
commit 26d7640bc1
11 changed files with 525 additions and 359 deletions

112
package-lock.json generated
View File

@ -8,10 +8,11 @@
"name": "salix-front", "name": "salix-front",
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "dependencies": {
"@quasar/extras": "^1.15.5", "@quasar/extras": "^1.15.6",
"axios": "^0.21.1", "axios": "^0.21.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"quasar": "^2.10.0", "pinia": "^2.0.24",
"quasar": "^2.10.2",
"validator": "^13.7.0", "validator": "^13.7.0",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-i18n": "^9.0.0", "vue-i18n": "^9.0.0",
@ -3519,9 +3520,9 @@
} }
}, },
"node_modules/@quasar/extras": { "node_modules/@quasar/extras": {
"version": "1.15.5", "version": "1.15.6",
"resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.15.5.tgz", "resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.15.6.tgz",
"integrity": "sha512-JzKKx5/eKAip3X3bZUEJOOWT9NudqjF01gcce6rtyviko49OU4r+ekyJU3QQIKF8ZqnjZ+DpsVpMWBBZnO6hSQ==", "integrity": "sha512-lG3wrcz47c86N/j1ULZugmyVfwpmnsJpjtSWh+LhaFfe0g1kTMdAnxkWGKsa3ouZ4QBcnkrNan0kYSnKc3MiBg==",
"funding": { "funding": {
"type": "github", "type": "github",
"url": "https://donate.quasar.dev" "url": "https://donate.quasar.dev"
@ -4307,9 +4308,9 @@
} }
}, },
"node_modules/@vue/devtools-api": { "node_modules/@vue/devtools-api": {
"version": "6.1.3", "version": "6.4.5",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.3.tgz", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz",
"integrity": "sha512-79InfO2xHv+WHIrH1bHXQUiQD/wMls9qBk6WVwGCbdwP7/3zINtvqPNMtmSHXsIKjvUAHc8L0ouOj6ZQQRmcXg==" "integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ=="
}, },
"node_modules/@vue/reactivity": { "node_modules/@vue/reactivity": {
"version": "3.2.31", "version": "3.2.31",
@ -15743,6 +15744,56 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/pinia": {
"version": "2.0.24",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.24.tgz",
"integrity": "sha512-DDLd4Iphyc+6PYYYbx7jkb6WP9gecgu9bz9huyB5rb7CdJI3DhzYiZI+/Ih8MLewRrP9DSpslF/BgSNrJtZU7A==",
"dependencies": {
"@vue/devtools-api": "^6.4.5",
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"@vue/composition-api": "^1.4.0",
"typescript": ">=4.4.4",
"vue": "^2.6.14 || ^3.2.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
},
"typescript": {
"optional": true
}
}
},
"node_modules/pinia/node_modules/vue-demi": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/pirates": { "node_modules/pirates": {
"version": "4.0.5", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
@ -16622,9 +16673,9 @@
} }
}, },
"node_modules/quasar": { "node_modules/quasar": {
"version": "2.10.0", "version": "2.10.2",
"resolved": "https://registry.npmjs.org/quasar/-/quasar-2.10.0.tgz", "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.10.2.tgz",
"integrity": "sha512-PHGcrzPQfFa4tv9a5Z/3D2uat48D4WC9Ad/imzHk/k3G41t0eFMH6glCjAvpCWF2q8dBYIg4nEchiPhlujbKsw==", "integrity": "sha512-y6suu0f2hJKrnFPHzx+p2EBVGzDF6xHaqYGkDIsMNkhxsrO9Qi2+dZCjq1J6+48EJiqPEOn8t9X/gT7yLSSnLw==",
"engines": { "engines": {
"node": ">= 10.18.1", "node": ">= 10.18.1",
"npm": ">= 6.13.4", "npm": ">= 6.13.4",
@ -19517,7 +19568,7 @@
"version": "4.5.5", "version": "4.5.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
"dev": true, "devOptional": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
@ -23528,9 +23579,9 @@
} }
}, },
"@quasar/extras": { "@quasar/extras": {
"version": "1.15.5", "version": "1.15.6",
"resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.15.5.tgz", "resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.15.6.tgz",
"integrity": "sha512-JzKKx5/eKAip3X3bZUEJOOWT9NudqjF01gcce6rtyviko49OU4r+ekyJU3QQIKF8ZqnjZ+DpsVpMWBBZnO6hSQ==" "integrity": "sha512-lG3wrcz47c86N/j1ULZugmyVfwpmnsJpjtSWh+LhaFfe0g1kTMdAnxkWGKsa3ouZ4QBcnkrNan0kYSnKc3MiBg=="
}, },
"@quasar/fastclick": { "@quasar/fastclick": {
"version": "1.1.5", "version": "1.1.5",
@ -24211,9 +24262,9 @@
} }
}, },
"@vue/devtools-api": { "@vue/devtools-api": {
"version": "6.1.3", "version": "6.4.5",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.3.tgz", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz",
"integrity": "sha512-79InfO2xHv+WHIrH1bHXQUiQD/wMls9qBk6WVwGCbdwP7/3zINtvqPNMtmSHXsIKjvUAHc8L0ouOj6ZQQRmcXg==" "integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ=="
}, },
"@vue/reactivity": { "@vue/reactivity": {
"version": "3.2.31", "version": "3.2.31",
@ -32797,6 +32848,23 @@
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true "dev": true
}, },
"pinia": {
"version": "2.0.24",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.24.tgz",
"integrity": "sha512-DDLd4Iphyc+6PYYYbx7jkb6WP9gecgu9bz9huyB5rb7CdJI3DhzYiZI+/Ih8MLewRrP9DSpslF/BgSNrJtZU7A==",
"requires": {
"@vue/devtools-api": "^6.4.5",
"vue-demi": "*"
},
"dependencies": {
"vue-demi": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
"requires": {}
}
}
},
"pirates": { "pirates": {
"version": "4.0.5", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
@ -33385,9 +33453,9 @@
} }
}, },
"quasar": { "quasar": {
"version": "2.10.0", "version": "2.10.2",
"resolved": "https://registry.npmjs.org/quasar/-/quasar-2.10.0.tgz", "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.10.2.tgz",
"integrity": "sha512-PHGcrzPQfFa4tv9a5Z/3D2uat48D4WC9Ad/imzHk/k3G41t0eFMH6glCjAvpCWF2q8dBYIg4nEchiPhlujbKsw==" "integrity": "sha512-y6suu0f2hJKrnFPHzx+p2EBVGzDF6xHaqYGkDIsMNkhxsrO9Qi2+dZCjq1J6+48EJiqPEOn8t9X/gT7yLSSnLw=="
}, },
"queue-microtask": { "queue-microtask": {
"version": "1.2.3", "version": "1.2.3",
@ -35619,7 +35687,7 @@
"version": "4.5.5", "version": "4.5.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
"dev": true "devOptional": true
}, },
"uglify-js": { "uglify-js": {
"version": "3.15.3", "version": "3.15.3",

View File

@ -18,10 +18,11 @@
"test:e2e:ci": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\"" "test:e2e:ci": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\""
}, },
"dependencies": { "dependencies": {
"@quasar/extras": "^1.15.5", "@quasar/extras": "^1.15.6",
"axios": "^0.21.1", "axios": "^0.21.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"quasar": "^2.10.0", "pinia": "^2.0.24",
"quasar": "^2.10.2",
"validator": "^13.7.0", "validator": "^13.7.0",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-i18n": "^9.0.0", "vue-i18n": "^9.0.0",

View File

@ -1,55 +1,55 @@
<script setup> <!--<script setup>-->
import { onMounted } from 'vue'; <!--import { onMounted } from 'vue';-->
import { useI18n } from 'vue-i18n'; <!--import { useI18n } from 'vue-i18n';-->
import { useNavigation } from 'src/composables/useNavigation'; <!--import { useNavigation } from 'src/composables/useNavigation';-->
const { t } = useI18n(); <!--const { t } = useI18n();-->
const navigation = useNavigation(); <!--const navigation = useNavigation();-->
onMounted(() => { <!--onMounted(() => {-->
navigation.fetchFavorites(); <!-- navigation.fetchFavorites();-->
}); <!--});-->
</script> <!--</script>-->
<template> <!--<template>-->
<q-menu <!-- <q-menu-->
anchor="bottom left" <!-- anchor="bottom left"-->
class="row q-pa-md q-col-gutter-lg" <!-- class="row q-pa-md q-col-gutter-lg"-->
max-width="350px" <!-- max-width="350px"-->
max-height="400px" <!-- max-height="400px"-->
v-if="navigation.favorites.value.length" <!-- v-if="navigation.favorites.value.length"-->
> <!-- >-->
<div v-for="module of navigation.favorites.value" :key="module.title" class="row no-wrap q-pa-xs flex-item"> <!-- <div v-for="module of navigation.favorites.value" :key="module.title" class="row no-wrap q-pa-xs flex-item">-->
<q-btn <!-- <q-btn-->
align="evenly" <!-- align="evenly"-->
padding="16px" <!-- padding="16px"-->
flat <!-- flat-->
stack <!-- stack-->
size="lg" <!-- size="lg"-->
:icon="module.icon" <!-- :icon="module.icon"-->
color="primary" <!-- color="primary"-->
class="col-4 button" <!-- class="col-4 button"-->
:to="{ name: module.stateName }" <!-- :to="{ name: module.stateName }"-->
> <!-- >-->
<div class="text-center text-primary button-text"> <!-- <div class="text-center text-primary button-text">-->
{{ t(`${module.name}.pageTitles.${module.title}`) }} <!-- {{ t(`${module.name}.pageTitles.${module.title}`) }}-->
</div> <!-- </div>-->
</q-btn> <!-- </q-btn>-->
</div> <!-- </div>-->
</q-menu> <!-- </q-menu>-->
</template> <!--</template>-->
<style lang="scss" scoped> <!--<style lang="scss" scoped>-->
.flex-item { <!--.flex-item {-->
width: 100px; <!-- width: 100px;-->
} <!--}-->
.button { <!--.button {-->
width: 100%; <!-- width: 100%;-->
line-height: normal; <!-- line-height: normal;-->
align-items: center; <!-- align-items: center;-->
} <!--}-->
.button-text { <!--.button-text {-->
font-size: 10px; <!-- font-size: 10px;-->
margin-top: 5px; <!-- margin-top: 5px;-->
} <!--}-->
</style> <!--</style>-->

View File

@ -1,161 +1,235 @@
<script setup> <script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRole } from 'src/composables/useRole'; // import { useRole } from 'src/composables/useRole';
import { useQuasar } from 'quasar'; // import { useQuasar } from 'quasar';
import { useNavigation } from 'src/composables/useNavigation'; import { useNavigation } from 'src/composables/useNavigation';
import routes from 'src/router/modules';
const { t } = useI18n(); const { t } = useI18n();
const { hasAny } = useRole(); // const { hasAny } = useRole();
const navigation = useNavigation(); const navigation = useNavigation();
const quasar = useQuasar(); const $props = defineProps({
source: {
type: String,
default: 'main',
},
});
async function onToggleFavoriteModule(moduleName, event) { const items = ref([]);
await navigation.toggleFavorite(moduleName, event); for (const module of navigation.modules) {
const moduleDef = routes.find((route) => route.name.toLowerCase() === module);
const moduleMeta = moduleDef.meta;
quasar.notify({ const item = {
message: t('globals.dataSaved'), name: moduleDef.name,
type: 'positive', title: moduleMeta.title,
}); icon: moduleMeta.icon,
module: module,
children: [],
};
if (moduleDef.menus) {
const mainMenus = moduleDef.menus[$props.source];
for (const menu of mainMenus) {
const mainMenuItems = moduleDef.children[0].children;
const mainMenuItemDef = mainMenuItems.find((route) => route.name === menu.name);
const mainMenuItemMeta = mainMenuItemDef.meta;
item.children.push({
name: mainMenuItemDef.name,
title: mainMenuItemMeta.title,
icon: mainMenuItemMeta.icon,
});
}
}
items.value.push(item);
} }
// const quasar = useQuasar();
// async function onToggleFavoriteModule(moduleName, event) {
// await navigation.toggleFavorite(moduleName, event);
//
// quasar.notify({
// message: t('globals.dataSaved'),
// type: 'positive',
// });
// }
</script> </script>
<template> <template>
<q-list padding> <q-list padding>
<q-item-label header>{{ t('globals.favoriteModules') }}</q-item-label> <q-item-label header>{{ t('globals.favoriteModules') }}</q-item-label>
<template v-for="module in navigation.favorites.value" :key="module.title"> <template v-for="item in items" :key="item.name">
<div class="module" v-if="!module.children"> <q-expansion-item
<q-item group="somegroup"
clickable class="module"
v-ripple active-class="text-primary"
active-class="text-primary" :label="item.title"
:key="module.title" :to="{ name: item.name }"
:to="{ name: module.stateName }" expand-separator
v-if="!module.roles || !module.roles.length || hasAny(module.roles)" >
> <template #header>
<q-item-section avatar :if="module.icon"> <q-item-section avatar>
<q-icon :name="module.icon" /> <q-icon :name="item.icon"></q-icon>
</q-item-section> </q-item-section>
<q-item-section>{{ t(`${module.name}.pageTitles.${module.title}`) }}</q-item-section> <q-item-section>{{ t(`${item.module}.pageTitles.${item.title}`) }}</q-item-section>
<q-item-section side> <!-- <q-item-section side>-->
<div @click="onToggleFavoriteModule(module.name, $event)" class="row items-center"> <!-- <div-->
<q-icon name="vn:pin_off"></q-icon> <!-- @click="onToggleFavoriteModule(module.name, $event)"-->
</div> <!-- class="row items-center"-->
</q-item-section> <!-- v-if="module.name != 'dashboard'"-->
</q-item> <!-- >-->
</div> <!-- <q-icon name="vn:pin"></q-icon>-->
<!-- </div>-->
<template v-if="module.children"> <!-- </q-item-section>-->
<q-expansion-item </template>
class="module" <template v-for="section in item.children" :key="section.name">
active-class="text-primary" <q-item clickable v-ripple active-class="text-primary" :to="{ name: section.name }">
:label="t(`${module.name}.pageTitles.${module.title}`)" <q-item-section avatar :if="section.icon">
v-if="!module.roles || !module.roles.length || hasAny(module.roles)" <q-icon :name="section.icon" />
:to="{ name: module.stateName }"
>
<template #header>
<q-item-section avatar>
<q-icon :name="module.icon"></q-icon>
</q-item-section> </q-item-section>
<q-item-section>{{ t(`${module.name}.pageTitles.${module.title}`) }}</q-item-section> <q-item-section>{{ t(`${item.module}.pageTitles.${section.title}`) }}</q-item-section>
<q-item-section side> </q-item>
<div @click="onToggleFavoriteModule(module.name, $event)" class="row items-center"> </template>
<q-icon name="vn:pin_off"></q-icon> </q-expansion-item>
</div>
</q-item-section>
</template>
<template v-for="section in module.children" :key="section.title">
<q-item
clickable
v-ripple
active-class="text-primary"
:to="{ name: section.stateName }"
v-if="!section.roles || !section.roles.length || hasAny(section.roles)"
>
<q-item-section avatar :if="section.icon">
<q-icon :name="section.icon" />
</q-item-section>
<q-item-section>{{ t(`${module.name}.pageTitles.${section.title}`) }}</q-item-section>
</q-item>
</template>
</q-expansion-item>
</template>
</template> </template>
<!-- <template v-for="module in navigation.favorites.value" :key="module.title">-->
<!-- <div class="module" v-if="!module.children">-->
<!-- <q-item-->
<!-- clickable-->
<!-- v-ripple-->
<!-- active-class="text-primary"-->
<!-- :key="module.title"-->
<!-- :to="{ name: module.stateName }"-->
<!-- v-if="!module.roles || !module.roles.length || hasAny(module.roles)"-->
<!-- >-->
<!-- <q-item-section avatar :if="module.icon">-->
<!-- <q-icon :name="module.icon" />-->
<!-- </q-item-section>-->
<!-- <q-item-section>{{ t(`${module.name}.pageTitles.${module.title}`) }}</q-item-section>-->
<!-- <q-item-section side>-->
<!-- <div @click="onToggleFavoriteModule(module.name, $event)" class="row items-center">-->
<!-- <q-icon name="vn:pin_off"></q-icon>-->
<!-- </div>-->
<!-- </q-item-section>-->
<!-- </q-item>-->
<!-- </div>-->
<!-- <template v-if="module.children">-->
<!-- <q-expansion-item-->
<!-- class="module"-->
<!-- active-class="text-primary"-->
<!-- :label="t(`${module.name}.pageTitles.${module.title}`)"-->
<!-- v-if="!module.roles || !module.roles.length || hasAny(module.roles)"-->
<!-- :to="{ name: module.stateName }"-->
<!-- >-->
<!-- <template #header>-->
<!-- <q-item-section avatar>-->
<!-- <q-icon :name="module.icon"></q-icon>-->
<!-- </q-item-section>-->
<!-- <q-item-section>{{ t(`${module.name}.pageTitles.${module.title}`) }}</q-item-section>-->
<!-- <q-item-section side>-->
<!-- <div @click="onToggleFavoriteModule(module.name, $event)" class="row items-center">-->
<!-- <q-icon name="vn:pin_off"></q-icon>-->
<!-- </div>-->
<!-- </q-item-section>-->
<!-- </template>-->
<!-- <template v-for="section in module.children" :key="section.title">-->
<!-- <q-item-->
<!-- clickable-->
<!-- v-ripple-->
<!-- active-class="text-primary"-->
<!-- :to="{ name: section.stateName }"-->
<!-- v-if="!section.roles || !section.roles.length || hasAny(section.roles)"-->
<!-- >-->
<!-- <q-item-section avatar :if="section.icon">-->
<!-- <q-icon :name="section.icon" />-->
<!-- </q-item-section>-->
<!-- <q-item-section>{{ t(`${module.name}.pageTitles.${section.title}`) }}</q-item-section>-->
<!-- </q-item>-->
<!-- </template>-->
<!-- </q-expansion-item>-->
<!-- </template>-->
<!-- </template>-->
</q-list> </q-list>
<q-separator /> <q-separator />
<q-expansion-item :label="t('moduleIndex.allModules')"> <!-- <q-expansion-item :label="t('moduleIndex.allModules')">-->
<q-list padding> <!-- <q-list padding>-->
<template v-for="module in navigation.modules.value" :key="module.title"> <!-- <template v-for="module in navigation.modules.value" :key="module.title">-->
<div class="module" v-if="!module.children"> <!-- <div class="module" v-if="!module.children">-->
<q-item <!-- <q-item-->
class="module" <!-- class="module"-->
clickable <!-- clickable-->
v-ripple <!-- v-ripple-->
active-class="text-primary" <!-- active-class="text-primary"-->
:key="module.title" <!-- :key="module.title"-->
:to="{ name: module.stateName }" <!-- :to="{ name: module.stateName }"-->
v-if="!module.roles || !module.roles.length || hasAny(module.roles)" <!-- v-if="!module.roles || !module.roles.length || hasAny(module.roles)"-->
> <!-- >-->
<q-item-section avatar :if="module.icon"> <!-- <q-item-section avatar :if="module.icon">-->
<q-icon :name="module.icon" /> <!-- <q-icon :name="module.icon" />-->
</q-item-section> <!-- </q-item-section>-->
<q-item-section>{{ t(`${module.name}.pageTitles.${module.title}`) }}</q-item-section> <!-- <q-item-section>{{ t(`${module.name}.pageTitles.${module.title}`) }}</q-item-section>-->
<q-item-section side> <!-- <q-item-section side>-->
<div <!-- <div-->
@click="onToggleFavoriteModule(module.name, $event)" <!-- @click="onToggleFavoriteModule(module.name, $event)"-->
class="row items-center" <!-- class="row items-center"-->
v-if="module.name != 'dashboard'" <!-- v-if="module.name != 'dashboard'"-->
> <!-- >-->
<q-icon name="vn:pin"></q-icon> <!-- <q-icon name="vn:pin"></q-icon>-->
</div> <!-- </div>-->
</q-item-section> <!-- </q-item-section>-->
</q-item> <!-- </q-item>-->
</div> <!-- </div>-->
<template v-if="module.children"> <!-- <template v-if="module.children">-->
<q-expansion-item <!-- <q-expansion-item-->
class="module" <!-- class="module"-->
active-class="text-primary" <!-- active-class="text-primary"-->
:label="t(`${module.name}.pageTitles.${module.title}`)" <!-- :label="t(`${module.name}.pageTitles.${module.title}`)"-->
v-if="!module.roles || !module.roles.length || hasAny(module.roles)" <!-- v-if="!module.roles || !module.roles.length || hasAny(module.roles)"-->
:to="{ name: module.stateName }" <!-- :to="{ name: module.stateName }"-->
> <!-- >-->
<template #header> <!-- <template #header>-->
<q-item-section avatar> <!-- <q-item-section avatar>-->
<q-icon :name="module.icon"></q-icon> <!-- <q-icon :name="module.icon"></q-icon>-->
</q-item-section> <!-- </q-item-section>-->
<q-item-section>{{ t(`${module.name}.pageTitles.${module.title}`) }}</q-item-section> <!-- <q-item-section>{{ t(`${module.name}.pageTitles.${module.title}`) }}</q-item-section>-->
<q-item-section side> <!-- <q-item-section side>-->
<div <!-- <div-->
@click="onToggleFavoriteModule(module.name, $event)" <!-- @click="onToggleFavoriteModule(module.name, $event)"-->
class="row items-center" <!-- class="row items-center"-->
v-if="module.name != 'dashboard'" <!-- v-if="module.name != 'dashboard'"-->
> <!-- >-->
<q-icon name="vn:pin"></q-icon> <!-- <q-icon name="vn:pin"></q-icon>-->
</div> <!-- </div>-->
</q-item-section> <!-- </q-item-section>-->
</template> <!-- </template>-->
<template v-for="section in module.children" :key="section.title"> <!-- <template v-for="section in module.children" :key="section.title">-->
<q-item <!-- <q-item-->
clickable <!-- clickable-->
v-ripple <!-- v-ripple-->
active-class="text-primary" <!-- active-class="text-primary"-->
:to="{ name: section.stateName }" <!-- :to="{ name: section.stateName }"-->
v-if="!section.roles || !section.roles.length || hasAny(section.roles)" <!-- v-if="!section.roles || !section.roles.length || hasAny(section.roles)"-->
> <!-- >-->
<q-item-section avatar :if="section.icon"> <!-- <q-item-section avatar :if="section.icon">-->
<q-icon :name="section.icon" /> <!-- <q-icon :name="section.icon" />-->
</q-item-section> <!-- </q-item-section>-->
<q-item-section>{{ t(`${module.name}.pageTitles.${section.title}`) }}</q-item-section> <!-- <q-item-section>{{ t(`${module.name}.pageTitles.${section.title}`) }}</q-item-section>-->
</q-item> <!-- </q-item>-->
</template> <!-- </template>-->
</q-expansion-item> <!-- </q-expansion-item>-->
</template> <!-- </template>-->
</template> <!-- </template>-->
</q-list> <!-- </q-list>-->
</q-expansion-item> <!-- </q-expansion-item>-->
</template> </template>
<style> <style>

View File

@ -1,92 +1,98 @@
import routes from 'src/router/routes'; // import routes from 'src/router/routes';
import { ref } from 'vue'; // import { ref } from 'vue';
import axios from 'axios'; // import axios from 'axios';
const favorites = ref([]); // const favorites = ref([]);
const modules = ref([]); //const modules = ref([]);
const mainRoute = routes.find((route) => route.path === '/'); // const mainRoute = routes.find((route) => route.path === '/');
const moduleRoutes = (mainRoute && mainRoute.children) || []; // const moduleRoutes = (mainRoute && mainRoute.children) || [];
//
for (const route of moduleRoutes) { // for (const route of moduleRoutes) {
const module = { // const module = {
stateName: route.name, // stateName: route.name,
name: route.name.toLowerCase(), // name: route.name.toLowerCase(),
roles: [], // roles: [],
}; // };
//
if (route.meta) { // if (route.meta) {
Object.assign(module, route.meta); // Object.assign(module, route.meta);
} // }
//
if (route.children && route.children.length) { // if (route.children && route.children.length) {
const [moduleMain] = route.children; // const [moduleMain] = route.children;
const routes = moduleMain.children; // const routes = moduleMain.children;
//
module.children = routes.map((route) => { // module.children = routes.map((route) => {
const submodule = { // const submodule = {
stateName: route.name, // stateName: route.name,
name: route.name, // name: route.name,
}; // };
//
Object.assign(submodule, route.meta); // Object.assign(submodule, route.meta);
//
return submodule; // return submodule;
}); // });
} // }
modules.value.push(module); // modules.value.push(module);
} // }
export function useNavigation() { export function useNavigation() {
const salixModules = { const modules = [
customer: 'Clients', 'customer',
claim: 'Claims', 'claim',
entry: 'Entries', 'ticket'
invoiceIn: 'Invoices In', ];
invoiceOut: 'Invoices Out',
item: 'Items',
monitor: 'Monitors',
order: 'Orders',
route: 'Routes',
supplier: 'Suppliers',
ticket: 'Tickets',
travel: 'Travels',
user: 'Users',
worker: 'Workers',
zone: 'Zones',
};
async function fetchFavorites() { // const salixModules = {
const response = await axios.get('StarredModules/getStarredModules'); // customer: 'Clients',
// claim: 'Claims',
// entry: 'Entries',
// invoiceIn: 'Invoices In',
// invoiceOut: 'Invoices Out',
// item: 'Items',
// monitor: 'Monitors',
// order: 'Orders',
// route: 'Routes',
// supplier: 'Suppliers',
// ticket: 'Tickets',
// travel: 'Travels',
// user: 'Users',
// worker: 'Workers',
// zone: 'Zones',
// };
const filteredModules = modules.value.filter((module) => { // async function fetchFavorites() {
return response.data.find((element) => element.moduleFk == salixModules[module.name]); // const response = await axios.get('StarredModules/getStarredModules');
}); //
// const filteredModules = modules.value.filter((module) => {
// return response.data.find((element) => element.moduleFk == salixModules[module.name]);
// });
//
// return (favorites.value = filteredModules);
// }
//
// async function toggleFavorite(moduleName, event) {
// if (event.defaultPrevented) return;
// event.preventDefault();
// event.stopPropagation();
//
// const params = { moduleName: salixModules[moduleName] };
// const query = 'StarredModules/toggleStarredModule';
// await axios.post(query, params);
//
// updateFavorites(moduleName);
// }
//
// function updateFavorites(name) {
// if (!favorites.value.find((module) => module.name == name)) {
// const newStarreModule = modules.value.find((module) => module.name == name);
// favorites.value.push(newStarreModule);
// } else {
// const moduleToRemove = favorites.value.find((module) => module.name == name);
// favorites.value.splice(favorites.value.indexOf(moduleToRemove), 1);
// }
// }
return (favorites.value = filteredModules); return { modules};
} }
async function toggleFavorite(moduleName, event) {
if (event.defaultPrevented) return;
event.preventDefault();
event.stopPropagation();
const params = { moduleName: salixModules[moduleName] };
const query = 'StarredModules/toggleStarredModule';
await axios.post(query, params);
updateFavorites(moduleName);
}
function updateFavorites(name) {
if (!favorites.value.find((module) => module.name == name)) {
const newStarreModule = modules.value.find((module) => module.name == name);
favorites.value.push(newStarreModule);
} else {
const moduleToRemove = favorites.value.find((module) => module.name == name);
favorites.value.splice(favorites.value.indexOf(moduleToRemove), 1);
}
}
return { modules, favorites, toggleFavorite, fetchFavorites, updateFavorites };
}

View File

@ -2,6 +2,7 @@
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import CustomerDescriptor from './CustomerDescriptor.vue'; import CustomerDescriptor from './CustomerDescriptor.vue';
import LeftMenu from 'components/LeftMenu.vue';
const state = useState(); const state = useState();
const { t } = useI18n(); const { t } = useI18n();
@ -11,6 +12,7 @@ const { t } = useI18n();
<q-scroll-area class="fit"> <q-scroll-area class="fit">
<customer-descriptor /> <customer-descriptor />
<q-separator /> <q-separator />
<left-menu source="card" />
<q-list> <q-list>
<q-item :to="{ name: 'CustomerBasicData' }" clickable v-ripple> <q-item :to="{ name: 'CustomerBasicData' }" clickable v-ripple>
<q-item-section avatar> <q-item-section avatar>

View File

@ -1,12 +1,12 @@
<script setup> <script setup>
import { useI18n } from 'vue-i18n'; // import { useI18n } from 'vue-i18n';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import LeftMenu from 'components/LeftMenu.vue'; import LeftMenu from 'components/LeftMenu.vue';
import { useNavigation } from 'composables/useNavigation'; // import { useNavigation } from 'composables/useNavigation';
const { t } = useI18n(); // const { t } = useI18n();
const state = useState(); const state = useState();
const modules = useNavigation(); // const modules = useNavigation();
</script> </script>
<template> <template>
@ -15,45 +15,38 @@ const modules = useNavigation();
<LeftMenu /> <LeftMenu />
</q-scroll-area> </q-scroll-area>
</q-drawer> </q-drawer>
<q-page-container> <!-- <q-page-container>-->
<q-page class="q-pa-md"> <!-- <q-page class="q-pa-md">-->
<!-- <q-banner v-if="$q.screen.gt.xs" inline-actions rounded class="bg-orange text-white q-mb-lg"> <!-- <div class="row items-start wrap q-col-gutter-md q-mb-lg">-->
Employee notification message <!-- <div class="col-12 col-md" v-if="modules.favorites.value.length">-->
<template #action> <!-- <div class="text-h6 text-grey-8 q-mb-sm">{{ t('globals.favoriteModules') }}</div>-->
<q-btn flat label="Dismiss" /> <!-- <q-card class="row flex-container">-->
</template> <!-- <div-->
</q-banner> --> <!-- v-for="module of modules.favorites.value"-->
<!-- :key="module.title"-->
<div class="row items-start wrap q-col-gutter-md q-mb-lg"> <!-- class="row no-wrap q-pa-xs flex-item"-->
<div class="col-12 col-md" v-if="modules.favorites.value.length"> <!-- >-->
<div class="text-h6 text-grey-8 q-mb-sm">{{ t('globals.favoriteModules') }}</div> <!-- <q-btn-->
<q-card class="row flex-container"> <!-- align="evenly"-->
<div <!-- padding="16px"-->
v-for="module of modules.favorites.value" <!-- flat-->
:key="module.title" <!-- stack-->
class="row no-wrap q-pa-xs flex-item" <!-- size="lg"-->
> <!-- :icon="module.icon"-->
<q-btn <!-- color="orange-6"-->
align="evenly" <!-- class="col-4 button"-->
padding="16px" <!-- :to="{ name: module.stateName }"-->
flat <!-- >-->
stack <!-- <div class="text-center text-primary button-text">-->
size="lg" <!-- {{ t(`${module.name}.pageTitles.${module.title}`) }}-->
:icon="module.icon" <!-- </div>-->
color="orange-6" <!-- </q-btn>-->
class="col-4 button" <!-- </div>-->
:to="{ name: module.stateName }" <!-- </q-card>-->
> <!-- </div>-->
<div class="text-center text-primary button-text"> <!-- </div>-->
{{ t(`${module.name}.pageTitles.${module.title}`) }} <!-- </q-page>-->
</div> <!-- </q-page-container>-->
</q-btn>
</div>
</q-card>
</div>
</div>
</q-page>
</q-page-container>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,6 +1,5 @@
import { route } from 'quasar/wrappers'; import { route } from 'quasar/wrappers';
import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory } from 'vue-router'; import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory } from 'vue-router';
// import { Notify } from 'quasar';
import routes from './routes'; import routes from './routes';
import { i18n } from 'src/boot/i18n'; import { i18n } from 'src/boot/i18n';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';

View File

@ -5,10 +5,17 @@ export default {
path: '/claim', path: '/claim',
meta: { meta: {
title: 'claims', title: 'claims',
icon: 'vn:claims' icon: 'vn:claims',
}, },
component: RouterView, component: RouterView,
redirect: { name: 'ClaimMain' }, redirect: { name: 'ClaimMain' },
menus: {
main: [
{ name: 'ClaimList', icon: 'view_list' },
{ name: 'ClaimRmaList', icon: 'vn:barcode' },
],
card: [{ name: 'CustomerBasicData', icon: 'vn:settings' }],
},
children: [ children: [
{ {
name: 'ClaimMain', name: 'ClaimMain',
@ -31,11 +38,11 @@ export default {
meta: { meta: {
title: 'rmaList', title: 'rmaList',
icon: 'vn:barcode', icon: 'vn:barcode',
roles: ['claimManager'] roles: ['claimManager'],
}, },
component: () => import('src/pages/Claim/ClaimRmaList.vue'), component: () => import('src/pages/Claim/ClaimRmaList.vue'),
} },
] ],
}, },
{ {
name: 'ClaimCard', name: 'ClaimCard',
@ -47,7 +54,7 @@ export default {
name: 'ClaimSummary', name: 'ClaimSummary',
path: 'summary', path: 'summary',
meta: { meta: {
title: 'summary' title: 'summary',
}, },
component: () => import('src/pages/Claim/Card/ClaimSummary.vue'), component: () => import('src/pages/Claim/Card/ClaimSummary.vue'),
}, },
@ -56,7 +63,7 @@ export default {
path: 'basic-data', path: 'basic-data',
meta: { meta: {
title: 'basicData', title: 'basicData',
roles: ['salesPerson'] roles: ['salesPerson'],
}, },
component: () => import('src/pages/Claim/Card/ClaimBasicData.vue'), component: () => import('src/pages/Claim/Card/ClaimBasicData.vue'),
}, },
@ -65,11 +72,11 @@ export default {
path: 'rma', path: 'rma',
meta: { meta: {
title: 'rma', title: 'rma',
roles: ['claimManager'] roles: ['claimManager'],
}, },
component: () => import('src/pages/Claim/Card/ClaimRma.vue') component: () => import('src/pages/Claim/Card/ClaimRma.vue'),
} },
] ],
}, },
] ],
}; };

View File

@ -5,10 +5,17 @@ export default {
name: 'Customer', name: 'Customer',
meta: { meta: {
title: 'customers', title: 'customers',
icon: 'vn:client' icon: 'vn:client',
}, },
component: RouterView, component: RouterView,
redirect: { name: 'CustomerMain' }, redirect: { name: 'CustomerMain' },
menus: {
main: [
{ name: 'CustomerList', icon: 'view_list' },
{ name: 'CustomerCreate', icon: 'vn:addperson' },
],
card: [{ name: 'CustomerBasicData', icon: 'vn:settings' }],
},
children: [ children: [
{ {
path: '', path: '',
@ -35,7 +42,7 @@ export default {
}, },
component: () => import('src/pages/Customer/CustomerCreate.vue'), component: () => import('src/pages/Customer/CustomerCreate.vue'),
}, },
] ],
}, },
{ {
name: 'CustomerCard', name: 'CustomerCard',
@ -47,7 +54,7 @@ export default {
name: 'CustomerSummary', name: 'CustomerSummary',
path: 'summary', path: 'summary',
meta: { meta: {
title: 'summary' title: 'summary',
}, },
component: () => import('src/pages/Customer/Card/CustomerSummary.vue'), component: () => import('src/pages/Customer/Card/CustomerSummary.vue'),
}, },
@ -55,11 +62,11 @@ export default {
path: 'basic-data', path: 'basic-data',
name: 'CustomerBasicData', name: 'CustomerBasicData',
meta: { meta: {
title: 'basicData' title: 'basicData',
}, },
component: () => import('src/pages/Customer/Card/CustomerBasicData.vue'), component: () => import('src/pages/Customer/Card/CustomerBasicData.vue'),
} },
] ],
}, },
] ],
}; };

View File

@ -0,0 +1,9 @@
import Customer from './customer';
import Ticket from './ticket';
import Claim from './claim';
export default [
Customer,
Ticket,
Claim
]