diff --git a/api/src/stores/user.ts b/api/src/stores/user.ts index abe5283..04405a6 100644 --- a/api/src/stores/user.ts +++ b/api/src/stores/user.ts @@ -1,6 +1,7 @@ import { defineStore } from 'pinia'; import { api } from '../internal'; import { isAxiosError, useMainStore } from '.'; +import { DisplayNameMode } from '@flaschengeist/users'; export function fixUser(u?: FG.User) { return !u ? u : Object.assign(u, { birthday: u.birthday ? new Date(u.birthday) : undefined }); @@ -22,6 +23,7 @@ export const useUserStore = defineStore({ state: () => ({ roles: [] as FG.Role[], permissions: [] as FG.Permission[], + userSettings: {} as FG.UserSettings, // list of all users, include deleted ones, use `users` getter for list of active ones _users: [] as FG.User[], // Internal flags for deciding if lists need to force-loaded @@ -31,7 +33,42 @@ export const useUserStore = defineStore({ getters: { users(state) { - return state._users.filter((u) => !u.deleted); + const u = state._users.filter((u) => !u.deleted); + + switch (this.userSettings['display_name']) { + case DisplayNameMode.FIRSTNAME_LASTNAME || DisplayNameMode.FIRSTNAME: + u.sort((a, b) => { + const a_lastname = a.lastname.toLowerCase(); + const b_lastname = b.lastname.toLowerCase(); + const a_firstname = a.firstname.toLowerCase(); + const b_firstname = b.firstname.toLowerCase(); + if (a_firstname === b_firstname) { + return a_lastname < b_lastname ? -1 : 1; + } + return a_firstname < b_firstname ? -1 : 1; + }); + break; + case DisplayNameMode.DISPLAYNAME: + u.sort((a, b) => { + const a_displayname = a.display_name.toLowerCase(); + const b_displayname = b.display_name.toLowerCase(); + return a_displayname < b_displayname ? -1 : 1; + }); + break; + default: + u.sort((a, b) => { + const a_lastname = a.lastname.toLowerCase(); + const b_lastname = b.lastname.toLowerCase(); + const a_firstname = a.firstname.toLowerCase(); + const b_firstname = b.firstname.toLowerCase(); + if (a_lastname === b_lastname) { + return a_firstname < b_firstname ? -1 : 1; + } + return a_lastname < b_lastname ? -1 : 1; + }); + } + + return u; }, }, @@ -207,5 +244,35 @@ export const useUserStore = defineStore({ await api.delete(`/roles/${role}`); this.roles = this.roles.filter((r) => r.id !== role); }, + + /** Get Settings for display name mode + * @param force If set to true a fresh list is loaded from backend even when a local copy is available + * @throws Probably an AxiosError if request failed + * @returns Settings for display name mode + */ + async getDisplayNameModeSetting(force = false): Promise { + const mainStore = useMainStore(); + if (force) { + const { data } = await api.get<{ data: string }>( + `users/${mainStore.currentUser.userid}/setting/display_name_mode` + ); + this.userSettings['display_name'] = data.data; + } + return this.userSettings['display_name']; + }, + + /** Set Settings for display name mode + * @param mode New display name mode + * @throws Probably an AxiosError if request failed + * @returns Settings for display name mode + */ + async setDisplayNameModeSetting(mode: string): Promise { + const mainStore = useMainStore(); + await api.put(`users/${mainStore.currentUser.userid}/setting/display_name_mode`, { + data: mode, + }); + this.userSettings['display_name'] = mode; + return mode; + }, }, }); diff --git a/package.json b/package.json index 985604c..6a03d77 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "license": "MIT", - "version": "2.0.0", + "version": "2.1.0", "productName": "flaschengeist-frontend", "name": "flaschengeist", "author": "Tim Gröger ", diff --git a/plugin.config.js b/plugin.config.js index 91d11af..30437ac 100644 --- a/plugin.config.js +++ b/plugin.config.js @@ -3,4 +3,4 @@ module.exports = [ // '@flaschengeist/balance', // '@flaschengeist/schedule', // '@flaschengeist/pricelist', -] + '@flaschengeist/schedule', diff --git a/quasar.conf.js b/quasar.conf.js index 7b475b3..2cf98d6 100644 --- a/quasar.conf.js +++ b/quasar.conf.js @@ -15,12 +15,18 @@ const { configure } = require('quasar/wrappers'); const operation = () => { const custom_plgns = require('./plugin.config.js'); const required_plgns = require('./src/vendor-plugin.config.js'); - const plugins = [...custom_plgns, ...required_plgns].map((v) => `import("${v}").catch(() => "${v}")`); - const replace = new ReplaceOperation('all', `\\/\\* *INSERT_PLUGIN_LIST *\\*\\/`, `${plugins.join(', ')}`); + const plugins = [...custom_plgns, ...required_plgns].map( + (v) => `import("${v}").catch(() => "${v}")` + ); + const replace = new ReplaceOperation( + 'all', + `\\/\\* *INSERT_PLUGIN_LIST *\\*\\/`, + `${plugins.join(', ')}` + ); return replace; }; -module.exports = configure(function(/* ctx */) { +module.exports = configure(function (/* ctx */) { return { // https://quasar.dev/quasar-cli/supporting-ts supportTS: { @@ -50,7 +56,7 @@ module.exports = configure(function(/* ctx */) { // 'ionicons-v5', // 'line-awesome', // 'material-icons', - 'mdi-v6', + 'mdi-v7', // 'themify', // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! @@ -60,7 +66,7 @@ module.exports = configure(function(/* ctx */) { // Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build build: { vueRouterMode: 'history', // available values: 'hash', 'history' - + //publicPath: 'flaschengeist2', // transpile: false, // Add dependencies for transpiling with Babel (Array of string/regex) @@ -214,5 +220,8 @@ module.exports = configure(function(/* ctx */) { // chainWebpack also available besides this extendWebpack }, }, + bin: { + linuxAndroidStudio: '/home/crimsen/.local/share/JetBrains/Toolbox/scripts/studio', + }, }; }); diff --git a/src/boot/plugins.ts b/src/boot/plugins.ts index b45bf7c..f9d4297 100644 --- a/src/boot/plugins.ts +++ b/src/boot/plugins.ts @@ -234,6 +234,12 @@ function loadPlugin( Array.prototype.push.apply(loadedPlugins.widgets, plugin.widgets); } + if (!plugin.settingWidgets) plugin.settingWidgets = []; + if (plugin.settingWidgets.length > 0) { + plugin.settingWidgets.forEach((widget) => (widget.name = plugin.id + '.' + widget.name)); + Array.prototype.push.apply(loadedPlugins.settingWidgets, plugin.settingWidgets); + } + loadedPlugins.plugins.push({ id: plugin.id, name: plugin.name, @@ -252,6 +258,7 @@ export async function loadPlugins(backend: FG.Backend, baseRoutes: RouteRecordRa shortcuts: [], outerShortcuts: [], widgets: [], + settingWidgets: [], }; // Wait for all plugins to be loaded