[Vue3] Fixed users plugin and some basic stuff, still broken.

This commit is contained in:
Ferdinand Thiessen 2021-01-30 08:38:44 +01:00
parent 117d8256be
commit 897c98c53a
24 changed files with 184 additions and 187 deletions

View File

@ -29,7 +29,7 @@ module.exports = configure(function (/* ctx */) {
// app boot file (/src/boot)
// --> boot files are part of "main.js"
// https://quasar.dev/quasar-cli/boot-files
boot: ['axios', 'plugins', 'loading', 'filter', 'login'],
boot: ['axios', 'plugins', 'loading', 'login'],
// https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css
css: ['app.scss'],

View File

@ -1,6 +1,6 @@
import { boot } from 'quasar/wrappers';
import { Loading } from 'quasar';
import DarkCircularProgress from 'components/loading/DarkCircularProgress.vue';
//import DarkCircularProgress from 'components/loading/DarkCircularProgress.vue';
// "async" is optional;
// more info on params: https://quasar.dev/quasar-cli/cli-documentation/boot-files#Anatomy-of-a-boot-file
@ -8,6 +8,7 @@ export default boot(() => {
Loading.setDefaults({
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
spinner: DarkCircularProgress,
// spinner: DarkCircularProgress,
// TODO : Das funktioniert wohl erstmal nicht mehr... gibt ne exception
});
});

View File

@ -2,12 +2,12 @@ import { boot } from 'quasar/wrappers';
import { Store } from 'vuex';
import { FG_Plugin } from 'src/plugins';
import routes from 'src/router/routes';
import { axios } from 'boot/axios';
import { api } from 'boot/axios';
import { AxiosResponse } from 'axios';
import { Router, RouteRecordRaw } from 'vue-router';
import { UserSessionState } from 'src/plugins/user/store';
const config = {
const config: { [key: string]: Array<string> } = {
// Do not change required Modules !!
requiredModules: ['User'],
// here you can import plugins.
@ -39,43 +39,49 @@ function setPermissions(object: FG_Plugin.PluginRouteConfig) {
object.route.meta['permissions'] = object.permissions;
}
function convertRoutes(parent: RouteRecordRaw, children?: FG_Plugin.PluginRouteConfig[]) {
if (children === undefined) return;
children.forEach((child) => {
setPermissions(child);
convertRoutes(child.route, child.children);
if (parent.children === undefined) parent.children = [];
parent.children.push(child.route);
});
}
function combineRoutes(
target: RouteRecordRaw[],
source: FG_Plugin.PluginRouteConfig[],
mainPath: '/' | '/main' = '/'
): RouteRecordRaw[] {
// Search parent
target.forEach((target) => {
if (target.path === mainPath) {
// Parent found = target
source.forEach((sourceMainConfig: FG_Plugin.PluginRouteConfig) => {
// Check if source is already in target
const targetMainConfig = target.children?.find((targetMainConfig: RouteRecordRaw) => {
return sourceMainConfig.route.path === targetMainConfig.path;
});
// Already in target routes, add only children
if (targetMainConfig) {
const sourceChildren: RouteRecordRaw[] = [];
sourceMainConfig.children?.forEach((child) => {
setPermissions(child);
sourceChildren.push(child.route);
});
if (targetMainConfig.children) {
targetMainConfig.children = Object.assign(targetMainConfig.children, sourceChildren);
} else {
targetMainConfig.children = sourceChildren;
}
convertRoutes(targetMainConfig, sourceMainConfig.children);
} else {
// Append to target
if (target.children === undefined) {
target.children = [];
}
convertRoutes(sourceMainConfig.route, sourceMainConfig.children);
if (
sourceMainConfig.children &&
sourceMainConfig.children.length > 0 &&
!sourceMainConfig.route.component
)
target.children.push({
Object.assign(sourceMainConfig.route, {
component: () => import('src/components/navigation/EmptyParent.vue'),
name: sourceMainConfig.route.name,
path: sourceMainConfig.route.path,
});
else target.children.push(sourceMainConfig.route);
target.children.push(sourceMainConfig.route);
}
});
}
@ -168,6 +174,7 @@ function loadPlugin(
loadedPlugins.mainLinks = combineMainLinks(loadedPlugins.mainLinks, route);
});
loadedPlugins.shortcuts = loadShortCuts(loadedPlugins.shortcuts, plugin.mainRoutes);
console.log(loadedPlugins);
}
if (plugin.outRoutes) {
loadedPlugins.routes = combineRoutes(loadedPlugins.routes, plugin.outRoutes);
@ -199,7 +206,7 @@ function loadPlugin(
async function getBackend(): Promise<Backend | null> {
let backend: Backend | null = null;
try {
const response: AxiosResponse<Backend> = await axios.get('/');
const response: AxiosResponse<Backend> = await api.get('/');
backend = response.data;
} catch (e) {
console.log(e);

View File

@ -33,7 +33,7 @@ export default defineComponent({
link: {
type: String,
default: 'home',
default: 'dashboard',
},
icon: {

View File

@ -38,14 +38,6 @@
<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
import { date } from 'quasar';
import { exception } from 'console';
interface Props {
value?: Date;
label?: string;
readonly: boolean;
type: string;
rules: Array<string>;
}
export default defineComponent({
name: 'IsoDateInput',
@ -107,7 +99,7 @@ export default defineComponent({
case 'datetime':
return 'YYYY-MM-DD HH:mm';
}
throw exception;
throw 'Invalid type given';
});
function dateChanged(dateString: string) {

View File

@ -24,7 +24,7 @@
<!-- Hier kommen die Shortlinks hin -->
<div>
<short-cut-link
v-for="(shortcut, index) in $flaschengeistPlugins.shortcuts"
v-for="(shortcut, index) in plugins.shortcuts"
:key="'shortcut' + index"
:link="shortcut.link"
:icon="shortcut.icon"
@ -46,7 +46,7 @@
<!-- Plugins -->
<q-list>
<essential-link
v-for="(link, index) in $flaschengeistPlugins.mainLinks"
v-for="(link, index) in plugins.mainLinks"
:key="'plugin' + index"
:title="link.title"
:link="link.link"
@ -172,7 +172,7 @@ export default defineComponent({
function logout() {
Loading.show({ message: 'Session wird abgemeldet' });
store.dispatch('session/logout').finally(() => {
store.dispatch('sessions/logout').finally(() => {
Loading.hide();
});
}
@ -185,6 +185,7 @@ export default defineComponent({
pluginChildLinks,
shortcuts,
logout,
plugins,
};
},
});

View File

@ -10,7 +10,7 @@
</q-toolbar-title>
<div>
<short-cut-link
v-for="(shortcut, index) in $flaschengeistPlugins.shortcutsOut"
v-for="(shortcut, index) in plugins.shortcutsOut"
:key="'shortcut' + index"
:link="shortcut.link"
:icon="shortcut.icon"
@ -42,11 +42,16 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { FG_Plugin } from 'src/plugins';
import { defineComponent, inject } from 'vue';
import ShortCutLink from 'components/navigation/ShortCutLink.vue';
export default defineComponent({
name: 'OutLayout',
components: { ShortCutLink },
setup() {
const plugins = inject<FG_Plugin.LoadedPlugins>('flaschengeistPlugins');
return { plugins };
},
});
</script>

View File

@ -11,18 +11,18 @@
</template>
<script lang="ts">
import { Component, defineComponent, onMounted, inject, ref } from 'vue';
import { Component, defineComponent, onMounted, inject, markRaw } from 'vue';
import { hasPermissions } from 'src/utils/permission';
import { FG_Plugin } from 'src/plugins';
export default defineComponent({
name: 'Dashboard',
setup() {
const widgets = ref<Array<Component>>([]);
const widgets = markRaw<Array<Component>>([]);
const flaschengeistPlugins = inject<FG_Plugin.LoadedPlugins>('flaschengeistPlugins');
onMounted(() => {
flaschengeistPlugins?.widgets.forEach((widget) => {
if (hasPermissions(widget.permissions)) widgets.value.push(widget.widget);
if (hasPermissions(widget.permissions)) widgets.push(widget.widget);
});
});

View File

@ -90,7 +90,7 @@ export default defineComponent({
message: 'Du wirst angemeldet',
});
store
.dispatch('session/login', {
.dispatch('sessions/login', {
userid: userid.value,
password: password.value,
})
@ -129,7 +129,7 @@ export default defineComponent({
return;
}
void store
.dispatch('session/requestPasswordReset', {
.dispatch('sessions/requestPasswordReset', {
userid: userid.value,
})
.then(() => {

View File

@ -72,7 +72,7 @@ export default defineComponent({
message: 'Das Passwort wird zurückgesetzt',
});
store
.dispatch('session/resetPassword', {
.dispatch('sessions/resetPassword', {
password: password.value,
token: router.currentRoute.value.query.token,
})

1
src/plugins.d.ts vendored
View File

@ -33,6 +33,7 @@ declare namespace FG_Plugin {
requiredBackendModules: string[];
mainRoutes?: PluginRouteConfig[];
outRoutes?: PluginRouteConfig[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
store?: Map<string, Module<any, any>>;
}

View File

@ -12,13 +12,14 @@
<script lang="ts">
import { defineComponent, ref } from 'vue';
import MainUserSettings from 'src/plugins/user/components/settings/MainUserSettings.vue';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
import { useStore } from 'vuex';
import { UserSessionState } from '../store';
export default defineComponent({
name: 'NewUser',
components: { MainUserSettings },
setup(_, { root }) {
const store = <Store<StateInterface>>root.$store;
setup() {
const store = useStore<UserSessionState>();
const user = ref<FG.User>({
userid: '',
display_name: '',
@ -28,7 +29,7 @@ export default defineComponent({
roles: [],
});
function setUser(value: FG.User) {
store.dispatch('user/setUser', value).catch((error) => {
store.dispatch('users/setUser', value).catch((error) => {
console.warn(error);
});
}

View File

@ -11,18 +11,18 @@
</template>
<script lang="ts">
import { useStore } from 'vuex';
import { defineComponent, ref } from 'vue';
import { Store } from 'vuex';
import { StateInterface } from '../../../store';
import { UserSessionState } from '../store';
import UserSelector from '../components/UserSelector.vue';
import MainUserSettings from '../components/settings/MainUserSettings.vue';
export default defineComponent({
name: 'UpdateUser',
components: { UserSelector, MainUserSettings },
setup(_, { root }) {
const store = <Store<StateInterface>>root.$store;
const user = ref(<FG.User>store.state.user.currentUser);
setup() {
const store = useStore<UserSessionState>();
const user = ref(<FG.User>store.state.users.currentUser);
// can be dropped with VUE3
const userUpdated = (value: FG.User) => {
@ -31,7 +31,7 @@ export default defineComponent({
};
function updateUser(value: FG.User) {
store.dispatch('user/updateUser', value).catch((error) => {
store.dispatch('users/updateUser', value).catch((error) => {
console.warn(error);
});
}

View File

@ -13,27 +13,22 @@
<script lang="ts">
import { computed, defineComponent, onBeforeMount } from 'vue';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
interface Props {
user: FG.User;
label: string;
}
import { useStore } from 'vuex';
import { UserSessionState } from '../store';
export default defineComponent({
name: 'UserSelector',
props: { user: { required: true }, label: { type: String, default: 'Benutzer' } },
setup(props: Props, { root, emit }) {
const store = <Store<StateInterface>>root.$store;
props: { user: { required: true, type: Object }, label: { type: String, default: 'Benutzer' } },
setup(_, { emit }) {
const store = useStore<UserSessionState>();
onBeforeMount(() => {
store.dispatch('user/getUsers').catch((error) => {
store.dispatch('users/getUsers').catch((error) => {
console.error(error);
});
});
const users = computed(() => store.state.user.users);
const users = computed(() => store.state.users.users);
const updated = (value: FG.User) => {
emit('update:user', value);
};

View File

@ -27,18 +27,18 @@
<script lang="ts">
import { computed, defineComponent, onMounted, ref } from 'vue';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
import { useStore } from 'vuex';
import { UserSessionState } from '../store';
export default defineComponent({
name: 'Greeting',
setup(_, { root }) {
const store = <Store<StateInterface>>root.$store;
onMounted(() => store.dispatch('user/getUsers', false));
setup() {
const store = useStore<UserSessionState>();
onMounted(() => store.dispatch('users/getUsers', false));
const name = ref(store.state.user.currentUser?.display_name);
const name = ref(store.state.users.currentUser?.display_name);
const avatarLink = ref(store.state.user.currentUser?.avatar_url);
const avatarLink = ref(store.state.users.currentUser?.avatar_url);
function userHasBirthday(user: FG.User) {
const today = new Date();
@ -50,13 +50,13 @@ export default defineComponent({
}
const hasBirthday = computed(() => {
return userHasBirthday(<FG.User>store.state.user.currentUser);
return userHasBirthday(<FG.User>store.state.users.currentUser);
});
const birthday = computed(() =>
store.state.user.users
store.state.users.users
.filter(userHasBirthday)
.filter((user) => user.userid !== store.state.user.currentUser?.userid)
.filter((user) => user.userid !== store.state.users.currentUser?.userid)
);
return { avatarLink, name, hasBirthday, birthday };

View File

@ -5,14 +5,14 @@
class="col-xs-12 col-sm-6 q-pa-sm"
label="Vorname"
:rules="[notEmpty]"
v-model="props.user.firstname"
v-model="user_model.firstname"
filled
/>
<q-input
class="col-xs-12 col-sm-6 q-pa-sm"
label="Nachname"
:rules="[notEmpty]"
v-model="props.user.lastname"
v-model="user_model.lastname"
filled
/>
@ -20,21 +20,21 @@
class="col-xs-12 col-sm-6 q-pa-sm"
label="Angezeigter Name"
:rules="[notEmpty]"
v-model="props.user.display_name"
v-model="user_model.display_name"
filled
/>
<q-input
class="col-xs-12 col-sm-6 q-pa-sm"
label="E-Mail"
:rules="[isEmail, notEmpty]"
v-model="props.user.mail"
v-model="user_model.mail"
filled
/>
<q-input
class="col-xs-12 col-sm-6 q-pa-sm"
label="Benutzername"
:readonly="!props.newUser"
v-model="props.user.userid"
:readonly="!newUser"
v-model="user_model.userid"
:rules="[isUseridUsed, notEmpty]"
filled
/>
@ -44,7 +44,7 @@
filled
multiple
use-chips
v-model="props.user.roles"
v-model="user_model.roles"
:readonly="!canSetRoles"
:options="allRoles"
option-label="name"
@ -52,7 +52,7 @@
/>
<IsoDateInput
class="col-xs-12 col-sm-6 q-pa-sm"
v-model="props.user.birthday"
v-model="user_model.birthday"
label="Geburtstag"
/>
<q-file
@ -70,8 +70,8 @@
</template>
</q-file>
</q-card-section>
<q-separator v-if="!props.newUser" />
<q-card-section class="fit row justify-start content-center items-center" v-if="!props.newUser">
<q-separator v-if="!newUser" />
<q-card-section class="fit row justify-start content-center items-center" v-if="!newUser">
<q-input
v-if="isCurrentUser"
class="col-xs-12 col-sm-6 col-md-4 q-pa-sm"
@ -107,51 +107,37 @@
</template>
<script lang="ts">
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { computed, defineComponent, ref, onBeforeMount } from 'vue';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
import { useStore } from 'vuex';
import { hasPermission } from 'src/utils/permission';
import IsoDateInput from 'src/components/utils/IsoDateInput.vue';
import { Notify } from 'quasar';
interface Props {
user?: FG.User;
newUser?: boolean;
}
import { UserSessionState } from '../../store';
export default defineComponent({
name: 'MainUserSettings',
components: { IsoDateInput: IsoDateInput },
props: {
user: {
required: true,
newUser: { type: Boolean, default: false },
user: { type: Object, required: true },
},
newUser: {
default: false,
},
},
setup(props: Props, { root, emit }) {
const store = <Store<StateInterface>>root.$store;
setup(props, { emit }) {
const store = useStore<UserSessionState>();
const user_model = ref<FG.User>(<FG.User>props.user);
onBeforeMount(() => {
store.dispatch('user/getRoles', false).catch((error) => {
store.dispatch('users/getRoles', false).catch((error) => {
console.warn(error);
});
});
const isCurrentUser = computed(
() => props.user?.userid === store.state.user.currentUser?.userid
() => user_model.value.userid === store.state.users.currentUser?.userid
);
const canSetRoles = computed(() => hasPermission('users_set_roles', store));
const oldUser = computed(() => {
if (isCurrentUser.value) return <FG.User>store.state.user.currentUser;
else
return store.state.user.users.filter((user) => {
user.userid === props.user?.userid;
})[0];
});
const canSetRoles = computed(() => hasPermission('users_set_roles'));
const avatar = ref([]);
function onAvatarRejected() {
@ -166,13 +152,13 @@ export default defineComponent({
avatar.value = [];
}
const allRoles = computed(() => store.state.user.roles.map((role) => role.name));
const allRoles = computed(() => store.state.users.roles.map((role) => role.name));
const password = ref('');
const new_password = ref('');
const new_password2 = ref('');
function save() {
let changed = <FG.User>props.user;
let changed = user_model.value;
if (typeof changed.birthday === 'string') changed.birthday = new Date(changed.birthday);
changed = Object.assign(changed, {
password: password.value,
@ -183,11 +169,12 @@ export default defineComponent({
});
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('update:user', changed);
if (avatar.value && (avatar.value.length > 0 || avatar.value instanceof File))
store
.dispatch('user/uploadAvatar', {
.dispatch('users/uploadAvatar', {
user: changed,
file: avatar.value,
})
@ -200,9 +187,8 @@ export default defineComponent({
}
function reset() {
//TODO: hier müssen wir uns etwas anderes einfallen lassen!
// eslint-disable-next-line vue/no-mutating-props
props.user = oldUser.value;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
user_model.value = <FG.User>props.user;
password.value = '';
new_password.value = '';
new_password2.value = '';
@ -224,7 +210,7 @@ export default defineComponent({
function isUseridUsed(val: string) {
return (
!store.state.user.users.find((user: FG.User) => {
!store.state.users.users.find((user: FG.User) => {
return user.userid == val;
}) ||
!props.newUser ||
@ -234,8 +220,8 @@ export default defineComponent({
return {
avatar,
user_model,
onAvatarRejected,
props,
allRoles,
canSetRoles,
password,

View File

@ -45,28 +45,28 @@
</template>
<script lang="ts">
import { useStore } from 'vuex';
import { UserSessionState } from '../../store';
import { computed, defineComponent, ref, onBeforeMount } from 'vue';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
export default defineComponent({
name: 'RoleSettings',
setup(_, { root }) {
const store = <Store<StateInterface>>root.$store;
setup() {
const store = useStore<UserSessionState>();
onBeforeMount(() => {
store.dispatch('user/getRoles').catch((error) => {
store.dispatch('users/getRoles').catch((error) => {
console.warn(error);
});
store.dispatch('user/getPermissions').catch((error) => {
store.dispatch('users/getPermissions').catch((error) => {
console.warn(error);
});
});
const role = ref<FG.Role | null>(null);
const roles = computed(() => store.state.user.roles);
const roles = computed(() => store.state.users.roles);
const permissions = computed(() =>
store.state.user.permissions.map((perm) => {
store.state.users.permissions.map((perm) => {
return {
value: perm,
label: perm,
@ -103,14 +103,14 @@ export default defineComponent({
function save() {
if (role.value) {
if (role.value.id === -1)
void store.dispatch('user/newRole', role.value).then((createdRole: FG.Role) => {
void store.dispatch('users/newRole', role.value).then((createdRole: FG.Role) => {
console.log(createdRole);
role.value = createdRole;
});
else {
if (newRoleName.value !== '') role.value.name = newRoleName.value;
console.log(role.value);
void store.dispatch('user/updateRole', role.value);
void store.dispatch('users/updateRole', role.value);
}
}
}
@ -130,7 +130,7 @@ export default defineComponent({
role.value = null;
} else {
store
.dispatch('user/deleteRole', role.value)
.dispatch('users/deleteRole', role.value)
.then(() => (role.value = null))
.catch((error) => console.warn(error));
}

View File

@ -21,7 +21,7 @@
Lebenszeit:
{{ session.lifetime }}
</div>
<div class="col-xs-12 col-sm-6">Läuft aus: {{ session.expires | dateTime(true) }}</div>
<div class="col-xs-12 col-sm-6">Läuft aus: {{ dateTime(session.expires) }}</div>
</div>
<div class="row q-my-sm" v-else>
<q-input
@ -46,19 +46,24 @@
</template>
<script lang="ts">
import { useStore } from 'vuex';
import { defineComponent, ref, computed } from 'vue';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
import { UserSessionState } from '../../store';
import { formatDateTime } from 'src/utils/datetime';
export default defineComponent({
name: 'Sessions',
props: {
session: {
required: true,
type: Object,
},
},
setup(props: { session: FG.Session }, { root }) {
const store = <Store<StateInterface>>root.$store;
setup(props) {
const store = useStore<UserSessionState>();
const dateTime = (date: Date) => formatDateTime(date, true);
const options = ref(['Minuten', 'Stunden', 'Tage']);
const option = ref<string>(options.value[0]);
const lifetime = ref(0);
@ -87,12 +92,12 @@ export default defineComponent({
}
function deleteSession(token: string) {
store.dispatch('session/deleteSession', token).catch((error) => {
store.dispatch('sessions/deleteSession', token).catch((error) => {
console.warn(error);
});
}
function isThisSession(token: string) {
return store.state.session.currentSession?.token === token;
return store.state.sessions.currentSession?.token === token;
}
const isEdit = ref(false);
@ -107,6 +112,7 @@ export default defineComponent({
case options.value[2]:
return (lifetime.value / (60 * 60 * 24)).toFixed(2);
}
throw 'Invalid option';
},
set: (val) => {
if (val) {
@ -126,7 +132,7 @@ export default defineComponent({
});
function edit(value: boolean) {
lifetime.value = props.session.lifetime;
lifetime.value = (<FG.Session>props.session).lifetime;
isEdit.value = value;
}
@ -134,7 +140,10 @@ export default defineComponent({
console.log(lifetime.value);
isEdit.value = false;
void store
.dispatch('session/updateSession', { lifetime: lifetime.value, token: props.session.token })
.dispatch('sessions/updateSession', {
lifetime: lifetime.value,
token: (<FG.Session>props.session).token,
})
.catch((error) => {
console.log(error);
});
@ -146,6 +155,7 @@ export default defineComponent({
isThisSession,
deleteSession,
isEdit,
dateTime,
edit,
options,
option,

View File

@ -46,23 +46,19 @@
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
import RoleSettings from '../components/settings/RoleSettings.vue';
import UpdateUser from '../components/UpdateUser.vue';
import NewUser from '../components/NewUser.vue';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
import { hasPermission } from 'src/utils/permission';
import { PERMISSIONS } from '../permissions';
import { Screen } from 'quasar';
import { PERMISSIONS } from '../permissions';
import NewUser from '../components/NewUser.vue';
import { computed, defineComponent, ref } from 'vue';
import { hasPermission } from 'src/utils/permission';
import UpdateUser from '../components/UpdateUser.vue';
import RoleSettings from '../components/settings/RoleSettings.vue';
export default defineComponent({
name: 'AdminSettings',
components: { RoleSettings, UpdateUser, NewUser },
setup(_, { root }) {
const store = <Store<StateInterface>>root.$store;
const canEditRoles = computed(() => hasPermission(PERMISSIONS.ROLES_EDIT, store));
setup() {
const canEditRoles = computed(() => hasPermission(PERMISSIONS.ROLES_EDIT));
interface Tab {
name: string;

View File

@ -10,7 +10,7 @@
:title="route.title"
:icon="route.icon"
:link="route.name"
:permissions="route.meta.permissions"
:permissions="route.permissions"
/>
</q-list>
</q-card-section>
@ -21,15 +21,19 @@
</template>
<script lang="ts">
import { useRoute } from 'vue-router';
import { computed, defineComponent } from 'vue';
import EssentialLink from 'src/components/navigation/EssentialLink.vue';
import mainRoutes from 'src/plugins/user/routes';
import EssentialLink from 'src/components/navigation/EssentialLink.vue';
export default defineComponent({
// name: 'PageName'
components: { EssentialLink },
setup(_, { root }) {
setup() {
const route = useRoute();
const checkMain = computed(() => {
return root.$route.matched.length == 2;
return route.matched.length == 2;
});
return { checkMain, mainRoutes };
},

View File

@ -17,27 +17,27 @@
import { computed, defineComponent, onBeforeMount, ref } from 'vue';
import Sessions from '../components/settings/Sessions.vue';
import MainUserSettings from '../components/settings/MainUserSettings.vue';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
import { useStore } from 'vuex';
import setLoadingBar from 'src/utils/loading';
import { UserSessionState } from '../store';
export default defineComponent({
// name: 'PageName'
components: { Sessions, MainUserSettings },
setup(_, _, {
const store = <Store<StateInterface>>root.$store;
setup() {
const store = useStore<UserSessionState>();
onBeforeMount(() => {
store.dispatch('session/getSessions').catch((error) => {
store.dispatch('sessions/getSessions').catch((error) => {
console.warn(error);
});
});
const currentUser = ref(<FG.User>store.state.user.currentUser);
const sessions = computed(() => store.state.session.sessions);
const loading = computed(() => store.state.session.loading || store.state.user.loading > 0);
const currentUser = ref(<FG.User>store.state.users.currentUser);
const sessions = computed(() => store.state.sessions.sessions);
const loading = computed(() => store.state.sessions.loading || store.state.users.loading > 0);
function updateUser(value: FG.User) {
store.dispatch('user/updateUser', value).catch((error) => {
store.dispatch('users/updateUser', value).catch((error) => {
console.warn(error);
});
}

View File

@ -1,9 +1,10 @@
import { Module } from 'vuex';
import userStore, { UserStateInterface } from './store/user';
import sessionsStore, { SessionInterface } from './store/session';
import routes from './routes';
import { StateInterface } from 'src/store';
import { FG_Plugin } from 'src/plugins';
import { defineAsyncComponent } from 'vue';
import { UserSessionState } from './store';
import usersStore, { UserStateInterface } from './store/user';
import sessionsStorage, { SessionStateInterface } from './store/session';
const plugin: FG_Plugin.Plugin = {
name: 'User',
@ -13,17 +14,17 @@ const plugin: FG_Plugin.Plugin = {
version: '0.0.1',
store: new Map<
string,
Module<UserStateInterface, StateInterface> | Module<SessionInterface, StateInterface>
Module<UserStateInterface, UserSessionState> | Module<SessionStateInterface, UserSessionState>
>([
['user', userStore],
['session', sessionsStore],
['users', usersStore],
['sessions', sessionsStorage],
]),
widgets: [
{
priority: 1,
name: 'greeting',
permissions: [],
widget: () => import('./components/Widget.vue'),
widget: defineAsyncComponent(() => import('./components/Widget.vue')),
},
],
};

View File

@ -1,7 +1,7 @@
import { FG_Plugin } from 'src/plugins';
const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
{
title: 'loadFromStore("user/displayName")',
title: 'loadFromStore("users/displayName")',
icon: 'mdi-account',
permissions: ['user'],
route: { path: 'user', name: 'user', component: () => import('../pages/MainPage.vue') },

View File

@ -4,7 +4,7 @@ import { api } from 'src/boot/axios';
import { AxiosError, AxiosResponse } from 'axios';
import { LocalStorage } from 'quasar';
import { UserSessionState } from '.';
import { useRouter } from 'vue-router';
import { Router } from 'src/router';
export interface SessionStateInterface {
currentSession?: FG.Session;
@ -63,8 +63,8 @@ const actions: ActionTree<SessionStateInterface, UserSessionState> = {
.then((response: AxiosResponse<LoginResponse>) => {
response.data.session.expires = new Date(response.data.session.expires);
commit('setCurrentSession', response.data.session);
commit('user/setCurrentUser', response.data.user, { root: true });
commit('user/setCurrentPermissions', response.data.permissions, {
commit('users/setCurrentUser', response.data.user, { root: true });
commit('users/setCurrentPermissions', response.data.permissions, {
root: true,
});
})
@ -113,18 +113,15 @@ const actions: ActionTree<SessionStateInterface, UserSessionState> = {
* Clear current session and logged in user
*/
clearCurrent({ commit }, redirect = true) {
const router = useRouter();
void router
.push({
void Router.push({
name: 'login',
query: redirect ? { redirect: router.currentRoute.value.fullPath } : {},
query: redirect ? { redirect: Router.currentRoute.value.fullPath } : {},
params: { logout: 'true' },
})
.then(() => {
}).then(() => {
commit('clearCurrentSession');
commit('user/clearCurrentUser', null, { root: true });
commit('users/clearCurrentUser', null, { root: true });
// ensure also volatile store gets cleared by refreshing the site
router.go(0);
Router.go(0);
});
},
/**