release v2.0.0 #4
|
@ -7,6 +7,6 @@
|
|||
import { defineComponent } from '@vue/composition-api';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App'
|
||||
name: 'App',
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -19,7 +19,7 @@ export const setBaseUrl = (url: string) => {
|
|||
message: 'Serveraddresse gespeichert',
|
||||
position: 'bottom',
|
||||
caption: `${url}`,
|
||||
color: 'positive'
|
||||
color: 'positive',
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
|
@ -38,7 +38,7 @@ export default boot<Store<StateInterface>>(({ Vue, store, router }) => {
|
|||
/***
|
||||
* Intercept requests and insert Token if available
|
||||
*/
|
||||
axios.interceptors.request.use(config => {
|
||||
axios.interceptors.request.use((config) => {
|
||||
const session = store.state.session.currentSession;
|
||||
if (session?.token) {
|
||||
config.headers = { Authorization: 'Bearer ' + session.token };
|
||||
|
@ -52,8 +52,8 @@ export default boot<Store<StateInterface>>(({ Vue, store, router }) => {
|
|||
* - filter timeout or 502-504 --> backendOffline
|
||||
*/
|
||||
axios.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error) {
|
||||
const e = <AxiosError>error;
|
||||
if (
|
||||
|
@ -62,7 +62,7 @@ export default boot<Store<StateInterface>>(({ Vue, store, router }) => {
|
|||
) {
|
||||
return router.push({
|
||||
name: 'offline',
|
||||
query: { redirect: router.currentRoute.fullPath }
|
||||
query: { redirect: router.currentRoute.fullPath },
|
||||
});
|
||||
} else if (e.response && e.response.status == 401) {
|
||||
if (router.currentRoute.name !== 'login') return store.dispatch('session/clearCurrent');
|
||||
|
|
|
@ -8,6 +8,6 @@ export default boot((/* { app, router, Vue ... } */) => {
|
|||
Loading.setDefaults({
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
spinner: DarkCircularProgress
|
||||
spinner: DarkCircularProgress,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ export default boot<Store<StateInterface>>(({ router, store }) => {
|
|||
// Secured area (LOGIN REQUIRED)
|
||||
// Check login is ok
|
||||
if (!session || session.expires <= new Date()) {
|
||||
store.dispatch('session/logout').catch(error => {
|
||||
store.dispatch('session/logout').catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
return;
|
||||
|
|
|
@ -9,6 +9,6 @@ export default boot((/* { app, router, Vue ... } */) => {
|
|||
icon: 'mdi-alert-circle',
|
||||
progress: true,
|
||||
position: 'bottom',
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }]
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }],
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,7 +12,7 @@ const config = {
|
|||
// Do not change required Modules !!
|
||||
requiredModules: ['User'],
|
||||
// here you can import plugins.
|
||||
loadModules: ['Balance', 'Schedule', 'Pricelist']
|
||||
loadModules: ['Balance', 'Schedule', 'Pricelist'],
|
||||
};
|
||||
|
||||
// do not change anything here !!
|
||||
|
@ -40,7 +40,7 @@ function combineRoutes(
|
|||
source: FG_Plugin.PluginRouteConfig[],
|
||||
mainPath: '/' | '/main' = '/'
|
||||
): RouteConfig[] {
|
||||
target.forEach(target => {
|
||||
target.forEach((target) => {
|
||||
if (target.path === mainPath) {
|
||||
source.forEach((sourceMainConfig: FG_Plugin.PluginRouteConfig) => {
|
||||
const targetMainConfig = target.children?.find((targetMainConfig: RouteConfig) => {
|
||||
|
@ -48,7 +48,7 @@ function combineRoutes(
|
|||
});
|
||||
if (targetMainConfig) {
|
||||
const sourceChildren: RouteConfig[] = [];
|
||||
sourceMainConfig.children?.forEach(child => {
|
||||
sourceMainConfig.children?.forEach((child) => {
|
||||
sourceChildren.push(<RouteConfig>child);
|
||||
});
|
||||
if (targetMainConfig.children) {
|
||||
|
@ -92,7 +92,7 @@ function combineMainLinks(
|
|||
icon: sourcePluginChildLink.icon,
|
||||
link: sourcePluginChildLink.name,
|
||||
name: sourcePluginChildLink.name,
|
||||
permissions: sourcePluginChildLink.meta?.permissions
|
||||
permissions: sourcePluginChildLink.meta?.permissions,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
@ -101,9 +101,9 @@ function combineMainLinks(
|
|||
icon: source.icon,
|
||||
link: source.name,
|
||||
name: source.name,
|
||||
permissions: source.meta?.permissions
|
||||
permissions: source.meta?.permissions,
|
||||
};
|
||||
source.children?.forEach(child => {
|
||||
source.children?.forEach((child) => {
|
||||
if (mainLink.children === undefined) {
|
||||
mainLink.children = [];
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ function combineMainLinks(
|
|||
icon: child.icon,
|
||||
link: child.name,
|
||||
name: child.name,
|
||||
permissions: child.meta?.permissions
|
||||
permissions: child.meta?.permissions,
|
||||
});
|
||||
});
|
||||
target.push(mainLink);
|
||||
|
@ -124,12 +124,12 @@ function loadShortCuts(
|
|||
target: FG_Plugin.ShortCutLink[],
|
||||
source: FG_Plugin.PluginRouteConfig[]
|
||||
): FG_Plugin.ShortCutLink[] {
|
||||
source.forEach(route => {
|
||||
source.forEach((route) => {
|
||||
if (route.shortcut) {
|
||||
target.push(<FG_Plugin.ShortCutLink>{
|
||||
link: route.name,
|
||||
icon: route.icon,
|
||||
permissions: route.meta?.permissions
|
||||
permissions: route.meta?.permissions,
|
||||
});
|
||||
}
|
||||
if (route.children) {
|
||||
|
@ -148,14 +148,14 @@ function loadPlugin(
|
|||
store: Store<any>,
|
||||
router: VueRouter
|
||||
): FG_Plugin.LoadedPlugins {
|
||||
modules.forEach(requiredModule => {
|
||||
const plugin = plugins.find(plugin => {
|
||||
modules.forEach((requiredModule) => {
|
||||
const plugin = plugins.find((plugin) => {
|
||||
return plugin.name == requiredModule;
|
||||
});
|
||||
if (plugin) {
|
||||
if (plugin.mainRoutes) {
|
||||
loadedPlugins.routes = combineRoutes(loadedPlugins.routes, plugin.mainRoutes, '/main');
|
||||
plugin.mainRoutes.forEach(route => {
|
||||
plugin.mainRoutes.forEach((route) => {
|
||||
loadedPlugins.mainLinks = combineMainLinks(loadedPlugins.mainLinks, route);
|
||||
});
|
||||
loadedPlugins.shortcuts = loadShortCuts(loadedPlugins.shortcuts, plugin.mainRoutes);
|
||||
|
@ -165,7 +165,7 @@ function loadPlugin(
|
|||
loadedPlugins.shortcutsOut = loadShortCuts(loadedPlugins.shortcutsOut, plugin.outRoutes);
|
||||
}
|
||||
if (plugin.widgets.length > 0) {
|
||||
plugin.widgets.forEach(widget => (widget.name = plugin.name + '_' + widget.name));
|
||||
plugin.widgets.forEach((widget) => (widget.name = plugin.name + '_' + widget.name));
|
||||
Array.prototype.push.apply(loadedPlugins.widgets, plugin.widgets);
|
||||
}
|
||||
if (plugin.store) {
|
||||
|
@ -175,11 +175,11 @@ function loadPlugin(
|
|||
}
|
||||
loadedPlugins.plugins.push({
|
||||
name: plugin.name,
|
||||
version: plugin.version
|
||||
version: plugin.version,
|
||||
});
|
||||
} else {
|
||||
console.exception(`Could not find required Plugin ${requiredModule}`);
|
||||
router.push({ name: 'error' }).catch(e => {
|
||||
router.push({ name: 'error' }).catch((e) => {
|
||||
console.warn(e);
|
||||
});
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ export default boot<Store<StateInterface>>(({ Vue, router, store }) => {
|
|||
mainLinks: [],
|
||||
shortcuts: [],
|
||||
shortcutsOut: [],
|
||||
widgets: []
|
||||
widgets: [],
|
||||
};
|
||||
|
||||
// get all plugins
|
||||
|
@ -225,7 +225,7 @@ export default boot<Store<StateInterface>>(({ Vue, router, store }) => {
|
|||
|
||||
// check dependencies
|
||||
backendPromise
|
||||
.then(backend => {
|
||||
.then((backend) => {
|
||||
console.log(backend);
|
||||
if (backend) {
|
||||
plugins.forEach((plugin: FG_Plugin.Plugin) => {
|
||||
|
@ -237,7 +237,7 @@ export default boot<Store<StateInterface>>(({ Vue, router, store }) => {
|
|||
)
|
||||
) {
|
||||
console.error(`Plugin ${plugin.name} need Plugin ${requiredModule}`);
|
||||
router.push({ name: 'error' }).catch(e => {
|
||||
router.push({ name: 'error' }).catch((e) => {
|
||||
console.warn(e);
|
||||
});
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ export default boot<Store<StateInterface>>(({ Vue, router, store }) => {
|
|||
console.error(
|
||||
`Plugin ${plugin.name} need Plugin ${requiredBackendModule} in backend.`
|
||||
);
|
||||
router.push({ name: 'error' }).catch(err => {
|
||||
router.push({ name: 'error' }).catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ export default boot<Store<StateInterface>>(({ Vue, router, store }) => {
|
|||
});
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
|
||||
|
|
|
@ -27,26 +27,26 @@ export default defineComponent({
|
|||
name: 'Developer',
|
||||
props: {
|
||||
pic: {
|
||||
default: 'logo-dark.svg'
|
||||
default: 'logo-dark.svg',
|
||||
},
|
||||
firstname: {
|
||||
//required: true,
|
||||
default: 'firstname'
|
||||
default: 'firstname',
|
||||
},
|
||||
lastname: {
|
||||
//required: true,
|
||||
default: 'lastname'
|
||||
default: 'lastname',
|
||||
},
|
||||
job: {
|
||||
default: 'student'
|
||||
default: 'student',
|
||||
},
|
||||
club: {
|
||||
default: 'Studentenclub Wu5 e.V.'
|
||||
default: 'Studentenclub Wu5 e.V.',
|
||||
},
|
||||
description: {
|
||||
default:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '
|
||||
}
|
||||
}
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ',
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -18,6 +18,6 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
export default defineComponent({
|
||||
name: 'CircularProgress'
|
||||
name: 'CircularProgress',
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -18,6 +18,6 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
export default defineComponent({
|
||||
name: 'DarkCircularProgress'
|
||||
name: 'DarkCircularProgress',
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -9,6 +9,6 @@ export default defineComponent({
|
|||
name: 'EmptyParent',
|
||||
setup() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -22,26 +22,26 @@ export default defineComponent({
|
|||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
|
||||
caption: {
|
||||
type: String,
|
||||
default: ''
|
||||
default: '',
|
||||
},
|
||||
|
||||
link: {
|
||||
type: String,
|
||||
default: 'home'
|
||||
default: 'home',
|
||||
},
|
||||
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
default: '',
|
||||
},
|
||||
permissions: {
|
||||
default: undefined
|
||||
}
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
|
||||
setup(props, { root }) {
|
||||
|
@ -59,6 +59,6 @@ export default defineComponent({
|
|||
const isGranted = computed(() => hasPermissions(props.permissions || [], root.$store));
|
||||
|
||||
return { realTitle: title, isGranted };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -11,19 +11,19 @@ export default defineComponent({
|
|||
props: {
|
||||
link: {
|
||||
required: true,
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
icon: {
|
||||
required: true,
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
permissions: {
|
||||
default: undefined
|
||||
}
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
setup(props, { root }) {
|
||||
const isGranted = computed(() => hasPermissions(props.permissions || [], root.$store));
|
||||
return { isGranted };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -50,21 +50,23 @@ export default defineComponent({
|
|||
name: 'IsoDateInput',
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
label: {},
|
||||
readonly: {
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
default: 'date',
|
||||
validator: function(value: string) {
|
||||
validator: function (value: string) {
|
||||
return ['date', 'time', 'datetime'].indexOf(value) !== -1;
|
||||
}
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
default: () => { return [] }
|
||||
}
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
},
|
||||
setup(props: Props, { emit }: { emit: any }) {
|
||||
function getDateTime() {
|
||||
|
@ -185,7 +187,7 @@ export default defineComponent({
|
|||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const customRules = [
|
||||
props.type == 'date' ? isDate : props.type == 'time' ? isTime : isDateTime,
|
||||
...props.rules
|
||||
...props.rules,
|
||||
];
|
||||
|
||||
return {
|
||||
|
@ -196,8 +198,8 @@ export default defineComponent({
|
|||
customRules,
|
||||
timeChanged,
|
||||
placeholder,
|
||||
dateTimeChanged
|
||||
dateTimeChanged,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
// to match your app's branding.
|
||||
// Tip: Use the "Theme Builder" on Quasar's documentation website.
|
||||
|
||||
$primary : #1976D2;
|
||||
$secondary : #26A69A;
|
||||
$accent : #9C27B0;
|
||||
$primary: #1976d2;
|
||||
$secondary: #26a69a;
|
||||
$accent: #9c27b0;
|
||||
|
||||
$dark : #1D1D1D;
|
||||
$dark: #1d1d1d;
|
||||
|
||||
$positive : #21BA45;
|
||||
$negative : #C10015;
|
||||
$info : #31CCEC;
|
||||
$warning : #F2C037;
|
||||
$positive: #21ba45;
|
||||
$negative: #c10015;
|
||||
$info: #31ccec;
|
||||
$warning: #f2c037;
|
||||
|
|
|
@ -42,27 +42,27 @@ declare namespace FG {
|
|||
volume?: number;
|
||||
cost_price_pro_volume?: number;
|
||||
cost_price_package_netto?: number;
|
||||
tags: Array<Tag>;
|
||||
type: DrinkType;
|
||||
tags?: Array<Tag>;
|
||||
type?: DrinkType;
|
||||
volumes: Array<DrinkPriceVolume>;
|
||||
}
|
||||
interface DrinkIngredient {
|
||||
id: number;
|
||||
volume: number;
|
||||
drink_ingredient_id: number;
|
||||
price: number;
|
||||
}
|
||||
interface DrinkPrice {
|
||||
id: number;
|
||||
price: number;
|
||||
public: bool;
|
||||
public: boolean;
|
||||
description?: string;
|
||||
}
|
||||
interface DrinkPriceVolume {
|
||||
id: number;
|
||||
volume: number;
|
||||
ingredients: Array<DrinkIngredient | ExtraIngredient>;
|
||||
min_prices: Array<MinPrices>;
|
||||
prices: Array<DrinkPrice>;
|
||||
ingredients: Array<Ingredient>;
|
||||
}
|
||||
interface DrinkType {
|
||||
id: number;
|
||||
|
@ -75,9 +75,12 @@ declare namespace FG {
|
|||
}
|
||||
interface Ingredient {
|
||||
id: number;
|
||||
volume_id: number;
|
||||
drink_ingredient: DrinkIngredient;
|
||||
extra_ingredient: ExtraIngredient;
|
||||
drink_ingredient?: DrinkIngredient;
|
||||
extra_ingredient?: ExtraIngredient;
|
||||
}
|
||||
interface MinPrices {
|
||||
percentage: number;
|
||||
price: number;
|
||||
}
|
||||
interface Tag {
|
||||
id: number;
|
||||
|
|
|
@ -12,20 +12,10 @@
|
|||
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>"
|
||||
/>
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="flaschengeist-logo.svg">
|
||||
<link rel="icon" type="image/svg+xml" href="flaschengeist-logo.svg" />
|
||||
<link rel="alternate icon" type="image/ico" href="favicon.ico" />
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
type="image/png"
|
||||
sizes="128x128"
|
||||
href="favicon-128x128.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
type="image/png"
|
||||
sizes="256x256"
|
||||
href="favicon-256x256.png"
|
||||
/>
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="128x128" href="favicon-128x128.png" />
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="256x256" href="favicon-256x256.png" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
|
@ -112,23 +112,23 @@ const links = [
|
|||
name: 'about',
|
||||
title: 'Über Flaschengeist',
|
||||
link: 'about',
|
||||
icon: 'mdi-information'
|
||||
}
|
||||
icon: 'mdi-information',
|
||||
},
|
||||
];
|
||||
|
||||
const shortcuts = [
|
||||
{
|
||||
link: 'about',
|
||||
icon: 'mdi-information'
|
||||
icon: 'mdi-information',
|
||||
},
|
||||
{
|
||||
link: 'user',
|
||||
icon: 'mdi-account'
|
||||
icon: 'mdi-account',
|
||||
},
|
||||
{
|
||||
link: 'user-plugin1',
|
||||
icon: 'mdi-account-plus'
|
||||
}
|
||||
icon: 'mdi-account-plus',
|
||||
},
|
||||
];
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
|
@ -146,7 +146,7 @@ export default defineComponent({
|
|||
const leftDrawerOpen = ref(
|
||||
computed({
|
||||
get: () => (leftDrawer.value || Screen.gt.sm ? true : false),
|
||||
set: (val: boolean) => (leftDrawer.value = val)
|
||||
set: (val: boolean) => (leftDrawer.value = val),
|
||||
})
|
||||
);
|
||||
const leftDrawerMini = ref(false);
|
||||
|
@ -189,8 +189,8 @@ export default defineComponent({
|
|||
links,
|
||||
pluginChildLinks,
|
||||
shortcuts,
|
||||
logout
|
||||
logout,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
<q-avatar rounded>
|
||||
<img src="flaschengeist-logo-white.svg" />
|
||||
</q-avatar>
|
||||
<span class="gt-xs">
|
||||
Flaschengeist
|
||||
</span>
|
||||
<span class="gt-xs"> Flaschengeist </span>
|
||||
</q-toolbar-title>
|
||||
<div>
|
||||
<short-cut-link
|
||||
|
@ -49,6 +47,6 @@ import ShortCutLink from 'components/navigation/ShortCutLink.vue';
|
|||
|
||||
export default defineComponent({
|
||||
name: 'OutLayout',
|
||||
components: { ShortCutLink }
|
||||
components: { ShortCutLink },
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<q-page
|
||||
padding
|
||||
style="grid-auto-rows: 1fr;"
|
||||
style="grid-auto-rows: 1fr"
|
||||
class="fit row justify-around items-start q-col-gutter-sm"
|
||||
>
|
||||
<div v-for="(item, index) in widgets" :key="index" class="col-4 full-height col-sm-6 col-xs-12">
|
||||
|
@ -21,14 +21,14 @@ export default defineComponent({
|
|||
const widgets = ref<Array<AsyncComponentPromise>>([]);
|
||||
|
||||
onMounted(() => {
|
||||
root.$flaschengeistPlugins.widgets.forEach(widget => {
|
||||
root.$flaschengeistPlugins.widgets.forEach((widget) => {
|
||||
if (hasPermissions(widget.permissions, root.$store)) widgets.value.push(widget.widget);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
widgets
|
||||
widgets,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -82,14 +82,14 @@ export default defineComponent({
|
|||
|
||||
function doLogin() {
|
||||
Loading.show({
|
||||
message: 'Du wirst angemeldet'
|
||||
message: 'Du wirst angemeldet',
|
||||
});
|
||||
root.$store
|
||||
.dispatch('session/login', {
|
||||
userid: userid.value,
|
||||
password: password.value
|
||||
password: password.value,
|
||||
})
|
||||
.then(async finished => {
|
||||
.then(async (finished) => {
|
||||
await finished;
|
||||
const x = root.$route.query['redirect'];
|
||||
void root.$router.push(typeof x === 'string' ? { path: x } : mainRoute);
|
||||
|
@ -103,7 +103,7 @@ export default defineComponent({
|
|||
message: 'Benutzername oder Passwort sind falsch.',
|
||||
timeout: 10000,
|
||||
progress: true,
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }]
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }],
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -120,13 +120,13 @@ export default defineComponent({
|
|||
message: 'Der Benutzername darf nicht leer sein.',
|
||||
timeout: 10000,
|
||||
progress: true,
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }]
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }],
|
||||
});
|
||||
return;
|
||||
}
|
||||
void root.$store
|
||||
.dispatch('session/requestPasswordReset', {
|
||||
userid: userid.value
|
||||
userid: userid.value,
|
||||
})
|
||||
.then(() => {
|
||||
userid.value = '';
|
||||
|
@ -138,7 +138,7 @@ export default defineComponent({
|
|||
'Sollte der Benutzername korrekt und vorhanden sein, erhälst du jetzt eine E-Mail.',
|
||||
timeout: 10000,
|
||||
progress: true,
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }]
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -152,8 +152,8 @@ export default defineComponent({
|
|||
server,
|
||||
changeUrl,
|
||||
visible,
|
||||
openServerSettings
|
||||
openServerSettings,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div>
|
||||
<div>
|
||||
<svg
|
||||
style="max-width: 400px;"
|
||||
style="max-width: 400px"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 292.761 292.761"
|
||||
|
@ -25,9 +25,7 @@
|
|||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="text-h2">
|
||||
Der Admin is über's Kabel gestolpert!
|
||||
</div>
|
||||
<div class="text-h2">Der Admin is über's Kabel gestolpert!</div>
|
||||
<div>
|
||||
Aktuell kann der Backend Server nicht erreicht werden, wir versuchen es in
|
||||
{{ reload }} Sekunden erneut.
|
||||
|
@ -52,6 +50,6 @@ export default defineComponent({
|
|||
}, 1000);
|
||||
onUnmounted(() => clearInterval(ival));
|
||||
return { reload };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div>
|
||||
<div>
|
||||
<svg
|
||||
style="max-width: 400px;"
|
||||
style="max-width: 400px"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 292.761 292.761"
|
||||
|
@ -25,9 +25,7 @@
|
|||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="text-h2">
|
||||
Der Admin war betrunken!!
|
||||
</div>
|
||||
<div class="text-h2">Der Admin war betrunken!!</div>
|
||||
<div>
|
||||
Einige Plugins konnten nicht geladen werden.<br />Sollte diese Seite jemals auftauchen,
|
||||
kontaktiere einen nüchternen Admin.
|
||||
|
@ -40,7 +38,7 @@
|
|||
import { defineComponent } from '@vue/composition-api';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PluginError.vue'
|
||||
name: 'PluginError.vue',
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ export default defineComponent({
|
|||
|
||||
const rules = [
|
||||
(val: string) =>
|
||||
(val && val.length >= 8) || 'Das Passwort muss mindestens 8 Zeichen lang sein!'
|
||||
(val && val.length >= 8) || 'Das Passwort muss mindestens 8 Zeichen lang sein!',
|
||||
];
|
||||
|
||||
function doReset() {
|
||||
|
@ -57,19 +57,19 @@ export default defineComponent({
|
|||
message: 'Die Passwörter stimmen nicht überein!',
|
||||
timeout: 10000,
|
||||
progress: true,
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }]
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }],
|
||||
});
|
||||
password2.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
Loading.show({
|
||||
message: 'Das Passwort wird zurückgesetzt'
|
||||
message: 'Das Passwort wird zurückgesetzt',
|
||||
});
|
||||
root.$store
|
||||
.dispatch('session/resetPassword', {
|
||||
password: password.value,
|
||||
token: root.$route.query.token
|
||||
token: root.$route.query.token,
|
||||
})
|
||||
.catch((error: AxiosResponse) => {
|
||||
if (error.status == 403) {
|
||||
|
@ -79,7 +79,7 @@ export default defineComponent({
|
|||
message: 'Der Link ist abgelaufen!',
|
||||
timeout: 10000,
|
||||
progress: true,
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }]
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }],
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -90,6 +90,6 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
return { password, password2, doReset, rules };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -12,11 +12,9 @@
|
|||
/>
|
||||
<div class="col-12 text-h4 text-center q-pa-sm">
|
||||
Flaschengeist
|
||||
<div class="text-caption">
|
||||
Version 2.0.0
|
||||
</div>
|
||||
<div class="text-caption">Version 2.0.0</div>
|
||||
</div>
|
||||
<div class="col-12 text-center q-ma-sm" style="max-width: 600px;">
|
||||
<div class="col-12 text-center q-ma-sm" style="max-width: 600px">
|
||||
Flaschengeist ist ein dynamischen Managementsystem für Studentenclubs. Es ermöglicht unter
|
||||
anderem die Mitgliederverwaltung, Dienstverwaltung, Arbeitsgruppenverwaltung und vieles
|
||||
meher. Es kann fast alles ermöglich werden, wenn ein Plugin dafür geschrieben wird. Jeder
|
||||
|
@ -25,9 +23,7 @@
|
|||
</div>
|
||||
|
||||
<q-separator />
|
||||
<div class="col-12 text-h6 q-pa-sm" v-if="$route.name == 'about'">
|
||||
Geladene Plugins:
|
||||
</div>
|
||||
<div class="col-12 text-h6 q-pa-sm" v-if="$route.name == 'about'">Geladene Plugins:</div>
|
||||
<div class="col-12 q-pa-sm" v-if="$route.name == 'about'">
|
||||
<q-chip
|
||||
v-for="(plugin, index) in $flaschengeistPlugins.plugins"
|
||||
|
@ -43,9 +39,7 @@
|
|||
</q-chip>
|
||||
</div>
|
||||
<q-separator />
|
||||
<div class="col-12 text-h6 q-pa-sm">
|
||||
Entwickler:
|
||||
</div>
|
||||
<div class="col-12 text-h6 q-pa-sm">Entwickler:</div>
|
||||
|
||||
<div class="fit row inline wrap justify-around items-start content-start">
|
||||
<developer
|
||||
|
@ -77,7 +71,7 @@ const developers = [
|
|||
pic:
|
||||
'https://scontent-frt3-2.xx.fbcdn.net/v/t1.0-9/31768724_1663023210401956_3834323197281435648_n.jpg?_nc_cat=109&_nc_sid=09cbfe&_nc_ohc=jWvUfn_xJ9YAX_oJ3CE&_nc_ht=scontent-frt3-2.xx&oh=15249378051f1e27f8b15122effb5c4a&oe=5FAC6A17',
|
||||
description:
|
||||
'Eigentlich wöllte ich jetzt hier echt viel hinschreiben. Aber ich habe keinen Plan was. Früher war ich einfach nur Tim G. und habe für andere den Kaffe geholt. Unter anderen für Ferdinand Thiessen.'
|
||||
'Eigentlich wöllte ich jetzt hier echt viel hinschreiben. Aber ich habe keinen Plan was. Früher war ich einfach nur Tim G. und habe für andere den Kaffe geholt. Unter anderen für Ferdinand Thiessen.',
|
||||
},
|
||||
{
|
||||
firstname: 'Ferdinand',
|
||||
|
@ -87,7 +81,7 @@ const developers = [
|
|||
'https://scontent-frx5-1.xx.fbcdn.net/v/t1.0-9/17022243_1418942461493397_9069541318944803902_n.jpg?_nc_cat=110&_nc_sid=174925&_nc_ohc=HjkSm8vcRW8AX8bTnJ8&_nc_ht=scontent-frx5-1.xx&oh=f09bd36525f3c6e55feaafb3b05b43d2&oe=5FAD432A',
|
||||
job: 'Backend-Developer; Co-Maintainer',
|
||||
description:
|
||||
'Geiler Typ. Einfach mal so alles Aufgeräumt. Aufeinmal könnte man aus dem Code eine Dokumentation zaubern!'
|
||||
'Geiler Typ. Einfach mal so alles Aufgeräumt. Aufeinmal könnte man aus dem Code eine Dokumentation zaubern!',
|
||||
},
|
||||
{
|
||||
firstname: 'Dominik',
|
||||
|
@ -96,14 +90,14 @@ const developers = [
|
|||
job: 'Eigentlich Frontend-Developer',
|
||||
description: 'Er findet sich langsam rein.',
|
||||
pic:
|
||||
'https://scontent-frt3-1.xx.fbcdn.net/v/t31.0-8/10363433_647611335326483_3447118968375865826_o.jpg?_nc_cat=104&_nc_sid=09cbfe&_nc_ohc=nWMgo-6Ih74AX_NiGUz&_nc_ht=scontent-frt3-1.xx&oh=f16d2edfe86f68d54900099087edb9c9&oe=5FAACFD4'
|
||||
}
|
||||
'https://scontent-frt3-1.xx.fbcdn.net/v/t31.0-8/10363433_647611335326483_3447118968375865826_o.jpg?_nc_cat=104&_nc_sid=09cbfe&_nc_ohc=nWMgo-6Ih74AX_NiGUz&_nc_ht=scontent-frt3-1.xx&oh=f16d2edfe86f68d54900099087edb9c9&oe=5FAACFD4',
|
||||
},
|
||||
];
|
||||
export default defineComponent({
|
||||
// name: 'PageName'
|
||||
components: { Developer },
|
||||
setup() {
|
||||
return { developers };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
<template>
|
||||
<q-card>
|
||||
<BalanceHeader @update:user="userUpdated" :showSelector="showSelector" @open-history="openHistory"/>
|
||||
<BalanceHeader
|
||||
@update:user="userUpdated"
|
||||
:showSelector="showSelector"
|
||||
@open-history="openHistory"
|
||||
/>
|
||||
<q-separator />
|
||||
|
||||
<q-card-section class="row q-col-gutter-md" v-if="shortCuts">
|
||||
|
@ -73,7 +77,7 @@ export default defineComponent({
|
|||
if (store.state.balance.transactions.length == 0)
|
||||
// No transaction, load at most six since yesterday
|
||||
void store.dispatch('balance/getTransactions', {
|
||||
filter: { limit: 6, from: new Date(new Date().setDate(new Date().getDate() - 1)) }
|
||||
filter: { limit: 6, from: new Date(new Date().setDate(new Date().getDate() - 1)) },
|
||||
});
|
||||
});
|
||||
const store = <Store<StateInterfaceBalance>>root.$store;
|
||||
|
@ -100,11 +104,11 @@ export default defineComponent({
|
|||
function changeBalance(amount: number) {
|
||||
store
|
||||
.dispatch('balance/changeBalance', { amount: amount, user: user.value?.userid })
|
||||
.catch(err => console.log(err));
|
||||
.catch((err) => console.log(err));
|
||||
}
|
||||
|
||||
function openHistory() {
|
||||
emit('open-history')
|
||||
emit('open-history');
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -118,8 +122,8 @@ export default defineComponent({
|
|||
showSelector,
|
||||
shortCuts,
|
||||
userUpdated,
|
||||
openHistory
|
||||
openHistory,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -51,6 +51,6 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
return { user, balance, isLocked, userUpdated, openHistory };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
<template>
|
||||
<q-card>
|
||||
<BalanceHeader @update:user="senderUpdated" :showSelector="showSelector" @open-history="openHistory"/>
|
||||
<BalanceHeader
|
||||
@update:user="senderUpdated"
|
||||
:showSelector="showSelector"
|
||||
@open-history="openHistory"
|
||||
/>
|
||||
<q-separator />
|
||||
<q-card-section class="row q-col-gutter-md items-center">
|
||||
<div class="col-sm-4 col-xs-12">
|
||||
|
@ -64,9 +68,9 @@ export default defineComponent({
|
|||
.dispatch('balance/changeBalance', {
|
||||
amount: amount.value,
|
||||
sender: sender.value?.userid,
|
||||
user: receiver.value?.userid
|
||||
user: receiver.value?.userid,
|
||||
})
|
||||
.catch(err => console.log(err));
|
||||
.catch((err) => console.log(err));
|
||||
}
|
||||
|
||||
function openHistory() {
|
||||
|
@ -82,8 +86,8 @@ export default defineComponent({
|
|||
senderUpdated,
|
||||
receiverUpdated,
|
||||
sendDisabled,
|
||||
openHistory
|
||||
openHistory,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,36 +1,31 @@
|
|||
<template>
|
||||
<div>
|
||||
<q-card flat square>
|
||||
<q-card-section class="row items-center justify-between" horizontal>
|
||||
<div class="col-5 text-left q-px-sm">
|
||||
<div
|
||||
v-bind:class="{ 'text-negative': isNegative() }"
|
||||
class="text-weight-bold text-h6"
|
||||
>
|
||||
<span v-if="isNegative()">-</span>{{ transaction.amount.toFixed(2) }} €
|
||||
<div>
|
||||
<q-card flat square>
|
||||
<q-card-section class="row items-center justify-between" horizontal>
|
||||
<div class="col-5 text-left q-px-sm">
|
||||
<div v-bind:class="{ 'text-negative': isNegative() }" class="text-weight-bold text-h6">
|
||||
<span v-if="isNegative()">-</span>{{ transaction.amount.toFixed(2) }} €
|
||||
</div>
|
||||
<div class="text-caption">{{ text }}</div>
|
||||
<div class="text-caption">{{ timeStr }}</div>
|
||||
</div>
|
||||
<div class="text-caption">{{ text }}</div>
|
||||
<div class="text-caption">{{ timeStr }}</div>
|
||||
</div>
|
||||
<div class="col-5 q-px-sm text-center">
|
||||
<div class="text-subtitle1" v-if="isReversed">
|
||||
Storniert
|
||||
<div class="col-5 q-px-sm text-center">
|
||||
<div class="text-subtitle1" v-if="isReversed">Storniert</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2 q-pr-sm" style="text-align: right">
|
||||
<q-btn
|
||||
:color="isReversed ? 'positive' : 'negative'"
|
||||
aria-label="Reverse transaction"
|
||||
:icon="!isReversed ? 'mdi-trash-can' : 'mdi-check-bold'"
|
||||
size="sm"
|
||||
round
|
||||
:disable="!canReverse"
|
||||
@click="reverse"
|
||||
/>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<q-separator />
|
||||
<div class="col-2 q-pr-sm" style="text-align: right">
|
||||
<q-btn
|
||||
:color="isReversed ? 'positive' : 'negative'"
|
||||
aria-label="Reverse transaction"
|
||||
:icon="!isReversed ? 'mdi-trash-can' : 'mdi-check-bold'"
|
||||
size="sm"
|
||||
round
|
||||
:disable="!canReverse"
|
||||
@click="reverse"
|
||||
/>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<q-separator />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -50,8 +45,8 @@ export default defineComponent({
|
|||
props: {
|
||||
transaction: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
watch: { transaction: 'refreshText' },
|
||||
setup(props: Props, { root, emit }) {
|
||||
|
@ -70,7 +65,7 @@ export default defineComponent({
|
|||
text.value = 'Anschreiben';
|
||||
if (props.transaction.receiver_id !== null) {
|
||||
const user = <FG.User>await store.dispatch('user/getUser', {
|
||||
userid: props.transaction.receiver_id
|
||||
userid: props.transaction.receiver_id,
|
||||
});
|
||||
text.value = `Gesendet an ${user.display_name}`;
|
||||
}
|
||||
|
@ -78,7 +73,7 @@ export default defineComponent({
|
|||
text.value = 'Gutschrift';
|
||||
if (props.transaction.sender_id !== null) {
|
||||
const user = <FG.User>await store.dispatch('user/getUser', {
|
||||
userid: props.transaction.sender_id
|
||||
userid: props.transaction.sender_id,
|
||||
});
|
||||
text.value = `Bekommen von ${user.display_name}`;
|
||||
}
|
||||
|
@ -104,7 +99,7 @@ export default defineComponent({
|
|||
.then(() => {
|
||||
emit('update:transaction', props.transaction);
|
||||
})
|
||||
.catch(error => console.log(error));
|
||||
.catch((error) => console.log(error));
|
||||
}
|
||||
|
||||
const timeStr = computed(() => {
|
||||
|
@ -114,6 +109,6 @@ export default defineComponent({
|
|||
});
|
||||
|
||||
return { timeStr, reverse, isNegative, text, refreshText, canReverse, isReversed };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -15,7 +15,7 @@ export default defineComponent({
|
|||
name: 'BalanceWidget',
|
||||
setup(_, { root }) {
|
||||
onBeforeMount(() => {
|
||||
store.dispatch('balance/getBalance').catch(err => {
|
||||
store.dispatch('balance/getBalance').catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
});
|
||||
|
@ -29,6 +29,6 @@ export default defineComponent({
|
|||
);
|
||||
|
||||
return { balance };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -37,28 +37,28 @@ export default defineComponent({
|
|||
field: 'userid',
|
||||
required: true,
|
||||
align: 'left',
|
||||
sortable: true
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'credit',
|
||||
label: 'Haben',
|
||||
field: 'credit',
|
||||
format: (val: number) => val.toFixed(2)
|
||||
format: (val: number) => val.toFixed(2),
|
||||
},
|
||||
{
|
||||
name: 'debit',
|
||||
label: 'Soll',
|
||||
field: 'debit',
|
||||
format: (val: number) => val.toFixed(2)
|
||||
format: (val: number) => val.toFixed(2),
|
||||
},
|
||||
{
|
||||
name: 'balance',
|
||||
label: 'Kontostand',
|
||||
format: (_: undefined, row: { debit: number; credit: number }) =>
|
||||
(row.credit - row.debit).toFixed(2)
|
||||
}
|
||||
(row.credit - row.debit).toFixed(2),
|
||||
},
|
||||
];
|
||||
return { rows, columns };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -9,7 +9,15 @@
|
|||
/>
|
||||
</q-tabs>
|
||||
<div class="fit row justify-end" v-else>
|
||||
<q-btn flat round icon="mdi-menu" @click="showDrawer = !showDrawer; show = false" />
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
icon="mdi-menu"
|
||||
@click="
|
||||
showDrawer = !showDrawer;
|
||||
show = false;
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<q-drawer side="right" v-model="showDrawer" @click="showDrawer = !showDrawer" behavior="mobile">
|
||||
<q-list v-model="tab" v-if="!$q.screen.gt.sm && !show">
|
||||
|
@ -24,14 +32,10 @@
|
|||
</q-item>
|
||||
</q-list>
|
||||
<q-list v-if="show">
|
||||
<div
|
||||
v-for="(transaction, index) in transactions"
|
||||
v-bind:key="index"
|
||||
class="col-sm-12"
|
||||
>
|
||||
<!-- TODO: In Vue3 use v-model:transaction="..." -->
|
||||
<Transaction :transaction.sync="transactions[index]" />
|
||||
</div>
|
||||
<div v-for="(transaction, index) in transactions" v-bind:key="index" class="col-sm-12">
|
||||
<!-- TODO: In Vue3 use v-model:transaction="..." -->
|
||||
<Transaction :transaction.sync="transactions[index]" />
|
||||
</div>
|
||||
</q-list>
|
||||
</q-drawer>
|
||||
<q-page padding class="fit row justify-left q-col-gutter-sm">
|
||||
|
@ -42,10 +46,20 @@
|
|||
animated
|
||||
>
|
||||
<q-tab-panel name="add" class="q-px-xs">
|
||||
<BalanceAdd @open-history="showDrawer = !showDrawer; show = true"/>
|
||||
<BalanceAdd
|
||||
@open-history="
|
||||
showDrawer = !showDrawer;
|
||||
show = true;
|
||||
"
|
||||
/>
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="transfer" class="q-px-xs">
|
||||
<BalanceTransfer @open-history="showDrawer = !showDrawer; show = true"/>
|
||||
<BalanceTransfer
|
||||
@open-history="
|
||||
showDrawer = !showDrawer;
|
||||
show = true;
|
||||
"
|
||||
/>
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</q-page>
|
||||
|
@ -68,19 +82,20 @@ export default defineComponent({
|
|||
components: { BalanceAdd, BalanceTransfer, Transaction },
|
||||
setup(_, { root }) {
|
||||
const store = <Store<StateInterfaceBalance>>root.$store;
|
||||
const now = new Date()
|
||||
const now = new Date();
|
||||
onMounted(() => {
|
||||
void store.dispatch('balance/getTransactions', {filter: {from: new Date(now.getFullYear(), now.getMonth(), now.getDate())}})
|
||||
})
|
||||
const transactions = computed(() =>
|
||||
{
|
||||
const a =store.state.balance.transactions
|
||||
.filter(t => t.original_id == undefined)
|
||||
.filter(t => t.time > new Date(now.getFullYear(), now.getMonth(), now.getDate()))
|
||||
.sort((a, b) => (a.time >= b.time ? -1 : 1))
|
||||
console.log(a)
|
||||
return a
|
||||
void store.dispatch('balance/getTransactions', {
|
||||
filter: { from: new Date(now.getFullYear(), now.getMonth(), now.getDate()) },
|
||||
});
|
||||
});
|
||||
const transactions = computed(() => {
|
||||
const a = store.state.balance.transactions
|
||||
.filter((t) => t.original_id == undefined)
|
||||
.filter((t) => t.time > new Date(now.getFullYear(), now.getMonth(), now.getDate()))
|
||||
.sort((a, b) => (a.time >= b.time ? -1 : 1));
|
||||
console.log(a);
|
||||
return a;
|
||||
});
|
||||
|
||||
const canAdd = () =>
|
||||
hasSomePermissions([PERMISSIONS.DEBIT, PERMISSIONS.CREDIT, PERMISSIONS.DEBIT_OWN], store);
|
||||
|
@ -94,12 +109,12 @@ export default defineComponent({
|
|||
...(canAdd() ? [{ name: 'add', label: 'Anschreiben' }] : []),
|
||||
...(hasSomePermissions([PERMISSIONS.SEND, PERMISSIONS.SEND_OTHER], store)
|
||||
? [{ name: 'transfer', label: 'Übertragen' }]
|
||||
: [])
|
||||
: []),
|
||||
];
|
||||
|
||||
const drawer = ref<boolean>(false);
|
||||
|
||||
/* const showDrawer = computed({
|
||||
/* const showDrawer = computed({
|
||||
get: () => {
|
||||
return !Screen.gt.sm && drawer.value;
|
||||
},
|
||||
|
@ -116,8 +131,8 @@ export default defineComponent({
|
|||
tab,
|
||||
tabs,
|
||||
transactions,
|
||||
show
|
||||
show,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -47,7 +47,7 @@ export default defineComponent({
|
|||
void store.dispatch('user/getUsers').then(() =>
|
||||
onRequest({
|
||||
pagination: pagination.value,
|
||||
filter: undefined
|
||||
filter: undefined,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
@ -60,7 +60,7 @@ export default defineComponent({
|
|||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 3,
|
||||
rowsNumber: 10
|
||||
rowsNumber: 10,
|
||||
});
|
||||
|
||||
interface PaginationInterface {
|
||||
|
@ -85,8 +85,8 @@ export default defineComponent({
|
|||
offset: startRow,
|
||||
limit: fetchCount,
|
||||
showCancelled: showCancelled.value,
|
||||
showReversals: false
|
||||
}
|
||||
showReversals: false,
|
||||
},
|
||||
})
|
||||
.then((result: TransactionsResponse) => {
|
||||
// clear out existing data and add new
|
||||
|
@ -114,7 +114,7 @@ export default defineComponent({
|
|||
field: 'time',
|
||||
required: true,
|
||||
sortable: true,
|
||||
format: (val: Date) => formatDateTime(new Date(val), true, true, true)
|
||||
format: (val: Date) => formatDateTime(new Date(val), true, true, true),
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
|
@ -128,7 +128,7 @@ export default defineComponent({
|
|||
else return 'Gesendet an X';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'text',
|
||||
|
@ -142,27 +142,27 @@ export default defineComponent({
|
|||
else return 'Gesendet an X';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'amount',
|
||||
label: 'Betrag',
|
||||
field: 'amount',
|
||||
format: (val: number) => `${val.toFixed(2)}€`
|
||||
format: (val: number) => `${val.toFixed(2)}€`,
|
||||
},
|
||||
{
|
||||
name: 'author_id',
|
||||
label: 'Benutzer',
|
||||
field: 'author_id',
|
||||
format: (val: string) => {
|
||||
const user = store.state.user.users.filter(x => x.userid == val);
|
||||
const user = store.state.user.users.filter((x) => x.userid == val);
|
||||
if (user.length > 0) return user[0].display_name;
|
||||
else return val;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return { data, pagination, onRequest, loading, balance, columns, showCancelled };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -15,7 +15,7 @@ const PERMISSIONS = {
|
|||
// Can set limit for users
|
||||
SET_LIMIT: 'balance_set_limit',
|
||||
//Allow sending / sub while exceeding the set limit
|
||||
EXCEED_LIMIT: 'balance_exceed_limit'
|
||||
EXCEED_LIMIT: 'balance_exceed_limit',
|
||||
};
|
||||
|
||||
export default PERMISSIONS;
|
||||
|
|
|
@ -16,9 +16,9 @@ const plugin: FG_Plugin.Plugin = {
|
|||
priority: 0,
|
||||
name: 'current',
|
||||
permissions: ['balance_show'],
|
||||
widget: () => import('./components/Widget.vue')
|
||||
}
|
||||
]
|
||||
widget: () => import('./components/Widget.vue'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
|
|
@ -16,7 +16,7 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
|||
path: 'overview',
|
||||
name: 'balance-view',
|
||||
meta: { permissions: [permissions.SHOW] },
|
||||
component: () => import('../pages/Overview.vue')
|
||||
component: () => import('../pages/Overview.vue'),
|
||||
},
|
||||
{
|
||||
title: 'Buchen',
|
||||
|
@ -25,7 +25,7 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
|||
name: 'balance-change',
|
||||
shortcut: true,
|
||||
meta: { permissions: [permissions.DEBIT_OWN, permissions.SHOW] },
|
||||
component: () => import('../pages/MainPage.vue')
|
||||
component: () => import('../pages/MainPage.vue'),
|
||||
},
|
||||
{
|
||||
title: 'Verwaltung',
|
||||
|
@ -33,10 +33,10 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
|||
path: 'admin',
|
||||
name: 'balance-admin',
|
||||
meta: { permissions: [permissions.SET_LIMIT, permissions.SHOW_OTHER] },
|
||||
component: () => import('../pages/Admin.vue')
|
||||
}
|
||||
]
|
||||
}
|
||||
component: () => import('../pages/Admin.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default mainRoutes;
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
<q-btn label="neues Getränk" color="positive" icon-right="add">
|
||||
<q-menu anchor="center middle" self="center middle">
|
||||
<div class="q-pa-sm">
|
||||
<div class="q-table__title q-pa-sm">
|
||||
Neues Getränk
|
||||
</div>
|
||||
<div class="q-table__title q-pa-sm">Neues Getränk</div>
|
||||
<div class="row">
|
||||
<q-input
|
||||
class="col-sm-4 col-xs-6 q-pa-sm"
|
||||
|
@ -159,8 +157,8 @@
|
|||
{{ drinks_props.row.volume ? `${drinks_props.row.volume} L` : 'o.A.' }}
|
||||
<q-popup-edit
|
||||
v-if="
|
||||
!drinks_props.row.volumes.some(volume =>
|
||||
volume.ingredients.some(ingredient => ingredient.drink_ingredient)
|
||||
!drinks_props.row.volumes.some((volume) =>
|
||||
volume.ingredients.some((ingredient) => ingredient.drink_ingredient)
|
||||
)
|
||||
"
|
||||
v-model.number="drinks_props.row.volume"
|
||||
|
@ -186,8 +184,8 @@
|
|||
{{ drinks_props.row.package_size || 'o.A.' }}
|
||||
<q-popup-edit
|
||||
v-if="
|
||||
!drinks_props.row.volumes.some(volume =>
|
||||
volume.ingredients.some(ingredient => ingredient.drink_ingredient)
|
||||
!drinks_props.row.volumes.some((volume) =>
|
||||
volume.ingredients.some((ingredient) => ingredient.drink_ingredient)
|
||||
)
|
||||
"
|
||||
v-model="drinks_props.row.package_size"
|
||||
|
@ -214,8 +212,8 @@
|
|||
}}
|
||||
<q-popup-edit
|
||||
v-if="
|
||||
!drinks_props.row.volumes.some(volume =>
|
||||
volume.ingredients.some(ingredient => ingredient.drink_ingredient)
|
||||
!drinks_props.row.volumes.some((volume) =>
|
||||
volume.ingredients.some((ingredient) => ingredient.drink_ingredient)
|
||||
)
|
||||
"
|
||||
v-model="drinks_props.row.cost_price_package_netto"
|
||||
|
@ -250,9 +248,9 @@
|
|||
!!drinks_props.row.volume &&
|
||||
!!drinks_props.row.package_size
|
||||
) &&
|
||||
!drinks_props.row.volumes.some(volume =>
|
||||
volume.ingredients.some(ingredient => ingredient.drink_ingredient)
|
||||
)
|
||||
!drinks_props.row.volumes.some((volume) =>
|
||||
volume.ingredients.some((ingredient) => ingredient.drink_ingredient)
|
||||
)
|
||||
"
|
||||
v-model="drinks_props.row.cost_price_pro_volume.value"
|
||||
buttons
|
||||
|
@ -611,82 +609,82 @@ export default defineComponent({
|
|||
{
|
||||
name: 'name',
|
||||
label: 'Getränkename',
|
||||
field: 'name'
|
||||
field: 'name',
|
||||
},
|
||||
{
|
||||
name: 'article_id',
|
||||
label: 'Artikelnummer',
|
||||
field: 'article_id'
|
||||
field: 'article_id',
|
||||
},
|
||||
{
|
||||
name: 'drink_type',
|
||||
label: 'Kategorie',
|
||||
field: 'type',
|
||||
format: (val: FG.DrinkType) => `${val.name}`
|
||||
format: (val: FG.DrinkType) => `${val.name}`,
|
||||
},
|
||||
{
|
||||
name: 'volume_package',
|
||||
label: 'Inhalt in l des Gebinde',
|
||||
field: 'volume'
|
||||
field: 'volume',
|
||||
},
|
||||
{
|
||||
name: 'package_size',
|
||||
label: 'Gebindegröße',
|
||||
field: 'package_size'
|
||||
field: 'package_size',
|
||||
},
|
||||
{
|
||||
name: 'cost_price_package_netto',
|
||||
label: 'Preis Netto/Gebinde',
|
||||
field: 'cost_price_package_netto',
|
||||
format: (val: number | null) => (val ? `${val.toFixed(3)}€` : '')
|
||||
format: (val: number | null) => (val ? `${val.toFixed(3)}€` : ''),
|
||||
},
|
||||
{
|
||||
name: 'cost_price_pro_volume',
|
||||
label: 'Preis mit 19%/Liter',
|
||||
field: 'cost_price_pro_volume',
|
||||
format: (val: number | null) => (val ? `${val.toFixed(3)}€` : '')
|
||||
format: (val: number | null) => (val ? `${val.toFixed(3)}€` : ''),
|
||||
},
|
||||
{
|
||||
name: 'volumes',
|
||||
label: 'Preiskalkulation',
|
||||
field: 'volumes'
|
||||
}
|
||||
field: 'volumes',
|
||||
},
|
||||
];
|
||||
const column_calc = [
|
||||
{
|
||||
name: 'volume',
|
||||
label: 'Abgabe in l',
|
||||
field: 'volume',
|
||||
format: (val: number) => `${val} L`
|
||||
format: (val: number) => `${val} L`,
|
||||
},
|
||||
{
|
||||
name: 'min_prices',
|
||||
label: 'Minimal Preise',
|
||||
field: 'min_prices'
|
||||
field: 'min_prices',
|
||||
},
|
||||
{
|
||||
name: 'prices',
|
||||
label: 'Preise',
|
||||
field: 'prices'
|
||||
}
|
||||
field: 'prices',
|
||||
},
|
||||
];
|
||||
const column_prices = [
|
||||
{
|
||||
name: 'price',
|
||||
label: 'Preis',
|
||||
field: 'price',
|
||||
format: (val: number) => `${val.toFixed(2)}€`
|
||||
format: (val: number) => `${val.toFixed(2)}€`,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: 'Beschreibung',
|
||||
field: 'description'
|
||||
field: 'description',
|
||||
},
|
||||
{
|
||||
name: 'public',
|
||||
label: 'Öffentlich',
|
||||
field: 'public'
|
||||
}
|
||||
field: 'public',
|
||||
},
|
||||
];
|
||||
const visibleColumn = ref([
|
||||
'name',
|
||||
|
@ -701,7 +699,7 @@ export default defineComponent({
|
|||
'prices',
|
||||
'price',
|
||||
'description',
|
||||
'public'
|
||||
'public',
|
||||
]);
|
||||
const emptyVolume: DrinkPriceVolume = {
|
||||
id: -1,
|
||||
|
@ -710,10 +708,10 @@ export default defineComponent({
|
|||
min_prices: [
|
||||
{ percentage: 100, price: null },
|
||||
{ percentage: 250, price: null },
|
||||
{ percentage: 300, price: null }
|
||||
{ percentage: 300, price: null },
|
||||
],
|
||||
prices: [],
|
||||
ingredients: []
|
||||
ingredients: [],
|
||||
};
|
||||
const newVolume = ref<DrinkPriceVolume>(emptyVolume);
|
||||
function addVolume(drink: Drink) {
|
||||
|
@ -749,7 +747,7 @@ export default defineComponent({
|
|||
cost_price_package_netto: undefined,
|
||||
tags: [],
|
||||
type: undefined,
|
||||
volumes: []
|
||||
volumes: [],
|
||||
};
|
||||
|
||||
const newDrink = ref<FG.Drink>(emptyDrink);
|
||||
|
@ -770,9 +768,9 @@ export default defineComponent({
|
|||
}
|
||||
return newDrink.value.cost_price_pro_volume;
|
||||
},
|
||||
set: val => {
|
||||
set: (val) => {
|
||||
newDrink.value.cost_price_pro_volume = val;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const drinkTypes = computed(() => store.state.drinkTypes);
|
||||
|
@ -811,9 +809,9 @@ export default defineComponent({
|
|||
cancelAddDrink,
|
||||
updateDrink,
|
||||
deleteDrink,
|
||||
console
|
||||
console,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
<div class="col" v-if="ingredient.drink_ingredient">
|
||||
<div class="full-width row justify-evenly q-py-xs">
|
||||
<div class="col">
|
||||
{{ ingredient.drink_ingredient.drink_ingredient.name }}
|
||||
{{ get_drink_ingredient_name(ingredient.drink_ingredient.drink_ingredient_id) }}
|
||||
<q-popup-edit
|
||||
buttons
|
||||
label-cancel="Abbrechen"
|
||||
label-set="Speichern"
|
||||
v-model="ingredient.drink_ingredient.drink_ingredient"
|
||||
v-model="ingredient.drink_ingredient.drink_ingredient_id"
|
||||
@save="updateIngredient(ingredient, volume)"
|
||||
>
|
||||
<q-select
|
||||
|
@ -24,7 +24,10 @@
|
|||
dense
|
||||
:options="drinks"
|
||||
option-label="name"
|
||||
v-model="ingredient.drink_ingredient.drink_ingredient"
|
||||
option-value="id"
|
||||
v-model="ingredient.drink_ingredient.drink_ingredient_id"
|
||||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-popup-edit>
|
||||
</div>
|
||||
|
@ -149,32 +152,32 @@ export default defineComponent({
|
|||
props: {
|
||||
ingredients: {
|
||||
type: Array as () => Array<FG.Ingredient>,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
volume: {
|
||||
type: Object as () => DrinkPriceVolume,
|
||||
required: true
|
||||
}
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const emptyIngredient: FG.Ingredient = {
|
||||
id: -1,
|
||||
drink_ingredient: null,
|
||||
extra_ingredient: null
|
||||
drink_ingredient: undefined,
|
||||
extra_ingredient: undefined,
|
||||
};
|
||||
const newIngredient = ref<FG.Drink | FG.ExtraIngredient>();
|
||||
const newIngredientVolume = ref<number>(0);
|
||||
function addIngredient(volume: DrinkPriceVolume) {
|
||||
if ((<FG.Drink>newIngredient.value)?.volume) {
|
||||
if ((<FG.Drink>newIngredient.value)?.volume && newIngredient.value) {
|
||||
store.actions.setIngredient(
|
||||
{
|
||||
id: -1,
|
||||
drink_ingredient: {
|
||||
id: -1,
|
||||
drink_ingredient: <FG.Drink>newIngredient.value,
|
||||
volume: newIngredientVolume.value
|
||||
drink_ingredient_id: newIngredient.value.id,
|
||||
volume: newIngredientVolume.value,
|
||||
},
|
||||
extra_ingredient: null
|
||||
extra_ingredient: undefined,
|
||||
},
|
||||
volume
|
||||
);
|
||||
|
@ -182,8 +185,8 @@ export default defineComponent({
|
|||
store.actions.setIngredient(
|
||||
{
|
||||
id: -1,
|
||||
drink_ingredient: null,
|
||||
extra_ingredient: <FG.ExtraIngredient>newIngredient.value
|
||||
drink_ingredient: undefined,
|
||||
extra_ingredient: <FG.ExtraIngredient>newIngredient.value,
|
||||
},
|
||||
volume
|
||||
);
|
||||
|
@ -202,10 +205,16 @@ export default defineComponent({
|
|||
store.actions.deleteIngredient(ingredient, volume);
|
||||
}
|
||||
const drinks = computed(() =>
|
||||
store.state.drinks.filter(drink => !!drink.cost_price_pro_volume)
|
||||
store.state.drinks.filter((drink) => {
|
||||
return drink.cost_price_pro_volume.value;
|
||||
})
|
||||
);
|
||||
const extra_ingredients = computed(() => store.state.extraIngredients);
|
||||
|
||||
function get_drink_ingredient_name(id: number) {
|
||||
return store.state.drinks.find((a) => a.id === id)?.name;
|
||||
}
|
||||
|
||||
return {
|
||||
addIngredient,
|
||||
drinks,
|
||||
|
@ -214,9 +223,10 @@ export default defineComponent({
|
|||
newIngredientVolume,
|
||||
cancelAddIngredient,
|
||||
updateIngredient,
|
||||
deleteIngredient
|
||||
deleteIngredient,
|
||||
get_drink_ingredient_name,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -146,27 +146,27 @@ export default defineComponent({
|
|||
props: {
|
||||
columns: {
|
||||
type: Array,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
row: {
|
||||
type: Object as () => DrinkPriceVolume,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
visibleColumns: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const emptyPrice = {
|
||||
id: -1,
|
||||
price: 0,
|
||||
description: '',
|
||||
public: true
|
||||
public: true,
|
||||
};
|
||||
const newPrice = ref(emptyPrice);
|
||||
function addPrice(volume: DrinkPriceVolume) {
|
||||
|
@ -188,7 +188,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
const pagination = ref({
|
||||
rowsPerPage: props.row.prices.length
|
||||
rowsPerPage: props.row.prices.length,
|
||||
});
|
||||
|
||||
return {
|
||||
|
@ -198,9 +198,9 @@ export default defineComponent({
|
|||
updatePrice,
|
||||
deletePrice,
|
||||
pagination,
|
||||
console
|
||||
console,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</q-dialog>
|
||||
|
||||
<q-page padding>
|
||||
<q-table title="Getränkearten" :data="rows" :row-key="row => row.id" :columns="columns">
|
||||
<q-table title="Getränkearten" :data="rows" :row-key="(row) => row.id" :columns="columns">
|
||||
<template v-slot:top-right>
|
||||
<q-input
|
||||
class="q-px-sm"
|
||||
|
@ -74,14 +74,14 @@ export default defineComponent({
|
|||
label: 'Getränkeart',
|
||||
field: 'name',
|
||||
align: 'left',
|
||||
sortable: true
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
label: 'Aktionen',
|
||||
field: 'actions',
|
||||
align: 'right'
|
||||
}
|
||||
align: 'right',
|
||||
},
|
||||
];
|
||||
|
||||
function addType() {
|
||||
|
@ -98,7 +98,7 @@ export default defineComponent({
|
|||
void store
|
||||
.dispatch('drink/changeDrinkTypeName', {
|
||||
id: actualDrinkType.value.id,
|
||||
name: newDrinkTypeName.value
|
||||
name: newDrinkTypeName.value,
|
||||
})
|
||||
.finally(() => discardChanges());
|
||||
}
|
||||
|
@ -124,9 +124,9 @@ export default defineComponent({
|
|||
actualDrinkType,
|
||||
newDrinkTypeName,
|
||||
discardChanges,
|
||||
saveChanges
|
||||
saveChanges,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</q-dialog>
|
||||
|
||||
<q-page padding>
|
||||
<q-table title="Getränkearten" :data="rows" :row-key="row => row.id" :columns="columns">
|
||||
<q-table title="Getränkearten" :data="rows" :row-key="(row) => row.id" :columns="columns">
|
||||
<template v-slot:top-right>
|
||||
<q-input
|
||||
class="q-px-sm"
|
||||
|
@ -71,7 +71,7 @@ export default defineComponent({
|
|||
const emptyExtraIngredient: FG.ExtraIngredient = {
|
||||
name: '',
|
||||
price: 0,
|
||||
id: -1
|
||||
id: -1,
|
||||
};
|
||||
const newExtraIngredient = ref(emptyExtraIngredient);
|
||||
const newDrinkTypeName = ref('');
|
||||
|
@ -85,21 +85,21 @@ export default defineComponent({
|
|||
label: 'Bezeichnung',
|
||||
field: 'name',
|
||||
align: 'left',
|
||||
sortable: true
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'price',
|
||||
label: 'Preis',
|
||||
field: 'price',
|
||||
sortable: true,
|
||||
format: (val: number) => `${val.toFixed(2)}€`
|
||||
format: (val: number) => `${val.toFixed(2)}€`,
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
label: 'Aktionen',
|
||||
field: 'actions',
|
||||
align: 'right'
|
||||
}
|
||||
align: 'right',
|
||||
},
|
||||
];
|
||||
|
||||
function addExtraIngredient() {
|
||||
|
@ -137,9 +137,9 @@ export default defineComponent({
|
|||
editType,
|
||||
actualExtraIngredient,
|
||||
discardChanges,
|
||||
saveChanges
|
||||
saveChanges,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,67 +1,62 @@
|
|||
<template>
|
||||
<div>
|
||||
<q-table
|
||||
title="Getränke"
|
||||
:columns="columns"
|
||||
:data="drinks"
|
||||
row-key="name"
|
||||
>
|
||||
<template v-slot:body-cell-prices="{row: {prices}}">
|
||||
<div>
|
||||
<q-table title="Getränke" :columns="columns" :data="drinks" row-key="name">
|
||||
<template v-slot:body-cell-prices="{ row: { prices } }">
|
||||
<q-td>
|
||||
<div v-for="price in prices" :key="price.id" class="row">
|
||||
<div class="col">
|
||||
{{price.volume | setVolume}}
|
||||
</div>
|
||||
<div class="col">
|
||||
{{price.price | setCurrency}}
|
||||
</div>
|
||||
<div class="col">
|
||||
{{price.description}}
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="price in prices" :key="price.id" class="row">
|
||||
<div class="col">
|
||||
{{ price.volume | setVolume }}
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ price.price | setCurrency }}
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ price.description }}
|
||||
</div>
|
||||
</div>
|
||||
</q-td>
|
||||
</template>
|
||||
</template>
|
||||
</q-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, onBeforeMount, ref} from '@vue/composition-api';
|
||||
import {StateInterface} from 'src/store';
|
||||
import {DrinkInterface} from '../store/drinks';
|
||||
import {Store} from 'vuex';
|
||||
import { defineComponent, onBeforeMount, ref } from '@vue/composition-api';
|
||||
import { StateInterface } from 'src/store';
|
||||
import { DrinkInterface } from '../store/drinks';
|
||||
import { Store } from 'vuex';
|
||||
export default defineComponent({
|
||||
name: 'Pricelist',
|
||||
filters: {
|
||||
name: 'Pricelist',
|
||||
filters: {
|
||||
setVolume(volume: number) {
|
||||
if (volume*10 > 1) {
|
||||
return `${volume}l`
|
||||
}
|
||||
return `${volume*100}cl`
|
||||
if (volume * 10 > 1) {
|
||||
return `${volume}l`;
|
||||
}
|
||||
return `${volume * 100}cl`;
|
||||
},
|
||||
setCurrency(price: number) {
|
||||
return `${price.toFixed(2)}€`
|
||||
}
|
||||
return `${price.toFixed(2)}€`;
|
||||
},
|
||||
setup(_, {root}) {
|
||||
const store = <Store<StateInterface>>root.$store;
|
||||
const state = <DrinkInterface>store.state.drink;
|
||||
const drinks = ref(state.drinks)
|
||||
onBeforeMount(() => {
|
||||
void store.dispatch('drink/getDrinks');
|
||||
})
|
||||
const columns = [
|
||||
{
|
||||
name: 'name',
|
||||
label: 'Getränk',
|
||||
field: 'name'
|
||||
},
|
||||
{
|
||||
name: 'prices',
|
||||
label: 'Preise',
|
||||
field: 'prices'
|
||||
}
|
||||
]
|
||||
return {columns, drinks}
|
||||
}
|
||||
})
|
||||
},
|
||||
setup(_, { root }) {
|
||||
const store = <Store<StateInterface>>root.$store;
|
||||
const state = <DrinkInterface>store.state.drink;
|
||||
const drinks = ref(state.drinks);
|
||||
onBeforeMount(() => {
|
||||
void store.dispatch('drink/getDrinks');
|
||||
});
|
||||
const columns = [
|
||||
{
|
||||
name: 'name',
|
||||
label: 'Getränk',
|
||||
field: 'name',
|
||||
},
|
||||
{
|
||||
name: 'prices',
|
||||
label: 'Preise',
|
||||
field: 'prices',
|
||||
},
|
||||
];
|
||||
return { columns, drinks };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -39,6 +39,6 @@ export default defineComponent({
|
|||
});
|
||||
|
||||
return { checkMain, mainRoutes };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
<template>
|
||||
<Pricelist />
|
||||
<Pricelist />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pricelist from '../components/Pricelist.vue'
|
||||
import Pricelist from '../components/Pricelist.vue';
|
||||
export default {
|
||||
name: 'PricelistPage',
|
||||
components: {Pricelist}
|
||||
}
|
||||
components: { Pricelist },
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<q-page paddding class="fit row justify-center content-start items-start q-gutter-sm">
|
||||
<q-tab-panels
|
||||
v-model="tab"
|
||||
style="background-color: transparent;"
|
||||
style="background-color: transparent"
|
||||
animated
|
||||
class="q-ma-none q-pa-none fit row justify-center content-start items-start"
|
||||
>
|
||||
|
@ -68,19 +68,19 @@ export default defineComponent({
|
|||
},
|
||||
set: (val: boolean) => {
|
||||
drawer.value = val;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const tabs: Tab[] = [
|
||||
{ name: 'pricelist', label: 'Getränke' },
|
||||
{ name: 'extra_ingredients', label: 'Zutaten' },
|
||||
{ name: 'drink_types', label: 'Getränketypen' }
|
||||
{ name: 'drink_types', label: 'Getränketypen' },
|
||||
];
|
||||
|
||||
const tab = ref<string>('pricelist');
|
||||
|
||||
return { tabs, tab, showDrawer };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ const state = reactive<{
|
|||
extraIngredients: [],
|
||||
});
|
||||
|
||||
interface MinPrice extends Omit<FG.DrinkMinPrice, 'price'> {
|
||||
interface MinPrice extends Omit<FG.MinPrices, 'price'> {
|
||||
price: WritableComputedRef<number> | null;
|
||||
}
|
||||
interface DrinkPriceVolume extends Omit<Omit<FG.DrinkPriceVolume, 'volume'>, 'min_prices'> {
|
||||
|
@ -218,10 +218,10 @@ const actions = {
|
|||
axios
|
||||
.put(`pricelist/ingredients/${ingredient.id}`, ingredient)
|
||||
.then((response: AxiosResponse<FG.Ingredient>) => {
|
||||
const index = volume.ingredients.findIndex((a) => a.id === response.data.id);
|
||||
/*const index = volume.ingredients.findIndex(a => a.id === response.data.id);
|
||||
if (index > -1) {
|
||||
volume.ingredients[index] = response.data;
|
||||
}
|
||||
}*/
|
||||
})
|
||||
.catch((err) => console.warn(err));
|
||||
},
|
||||
|
@ -337,7 +337,7 @@ function create_min_prices(drink: Drink, volume: DrinkPriceVolume, percentage: n
|
|||
volume.ingredients.forEach((ingredient) => {
|
||||
if (ingredient.drink_ingredient) {
|
||||
const _drink = state.drinks.find(
|
||||
(a) => a.id === ingredient.drink_ingredient?.drink_ingredient?.id
|
||||
(a) => a.id === ingredient.drink_ingredient?.drink_ingredient_id
|
||||
);
|
||||
retVal += ingredient.drink_ingredient.volume * (_drink?.cost_price_pro_volume.value || 0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<q-card class="row justify-center content-center" style="text-align: center;">
|
||||
<q-card class="row justify-center content-center" style="text-align: center">
|
||||
<q-card-section>
|
||||
<div class="text-h6 col-12">Dienste diesen Monat: {{ jobs }}</div>
|
||||
<div class="text-h6 col-12">Nächster Dienst: {{ nextJob | date }}</div>
|
||||
|
@ -19,6 +19,6 @@ export default defineComponent({
|
|||
const jobs = randomNumber(0, 5);
|
||||
const nextJob = new Date(2021, randomNumber(1, 12), randomNumber(1, 31));
|
||||
return { jobs, nextJob };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -87,14 +87,14 @@ export default defineComponent({
|
|||
end: undefined,
|
||||
comment: '',
|
||||
services: [],
|
||||
required_services: 2
|
||||
required_services: 2,
|
||||
} as unknown) as FG.Job);
|
||||
|
||||
const event = ref<FG.Event>({
|
||||
id: NaN,
|
||||
start: new Date(),
|
||||
description: '',
|
||||
jobs: [Object.assign({}, newJob.value)]
|
||||
jobs: [Object.assign({}, newJob.value)],
|
||||
} as FG.Event);
|
||||
|
||||
onBeforeMount(() => {
|
||||
|
@ -142,7 +142,7 @@ export default defineComponent({
|
|||
console.log('Event:', event);
|
||||
void store
|
||||
.dispatch('schedule/addEvent', event.value)
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
console.warn(error);
|
||||
})
|
||||
.then(() => {
|
||||
|
@ -182,9 +182,9 @@ export default defineComponent({
|
|||
setEnd,
|
||||
setComment,
|
||||
setJobType,
|
||||
setRequired
|
||||
setRequired,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -76,14 +76,14 @@ export default defineComponent({
|
|||
label: 'Veranstaltungstyp',
|
||||
field: 'name',
|
||||
align: 'left',
|
||||
sortable: true
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
label: 'Aktionen',
|
||||
field: 'actions',
|
||||
align: 'right'
|
||||
}
|
||||
align: 'right',
|
||||
},
|
||||
];
|
||||
|
||||
function addType() {
|
||||
|
@ -101,7 +101,7 @@ export default defineComponent({
|
|||
.dispatch('schedule/changeEventTypeName', {
|
||||
id: actualEvent.value.id,
|
||||
name: newEventName.value,
|
||||
oldname: actualEvent.value.name
|
||||
oldname: actualEvent.value.name,
|
||||
})
|
||||
.finally(() => {
|
||||
discardChanges();
|
||||
|
@ -128,9 +128,9 @@ export default defineComponent({
|
|||
actualEvent,
|
||||
newEventName,
|
||||
discardChanges,
|
||||
saveChanges
|
||||
saveChanges,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
:rules="[noValidDate, isAfterDate, notEmpty]"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section class=" row fit justify-start content-center items-center">
|
||||
<q-card-section class="row fit justify-start content-center items-center">
|
||||
<q-select
|
||||
:key="refreshKey"
|
||||
filled
|
||||
|
@ -77,17 +77,17 @@ export default defineComponent({
|
|||
components: { IsoDateInput },
|
||||
props: {
|
||||
job: {
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
jobCanDelete: {
|
||||
default: false
|
||||
}
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
job: function() {
|
||||
job: function () {
|
||||
// this.type.name = this.type.name;
|
||||
this.$props.job.type = this.$props.job.type;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
setup(props: Props, { root, emit }) {
|
||||
|
@ -157,9 +157,9 @@ export default defineComponent({
|
|||
notEmpty,
|
||||
noValidDate,
|
||||
isAfterDate,
|
||||
refreshKey
|
||||
refreshKey,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -73,14 +73,14 @@ export default defineComponent({
|
|||
label: 'Name',
|
||||
field: 'name',
|
||||
align: 'left',
|
||||
sortable: true
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
label: 'Aktionen',
|
||||
field: 'actions',
|
||||
align: 'right'
|
||||
}
|
||||
align: 'right',
|
||||
},
|
||||
];
|
||||
|
||||
function addType() {
|
||||
|
@ -121,9 +121,9 @@ export default defineComponent({
|
|||
actualJob,
|
||||
newJobName,
|
||||
discardChanges,
|
||||
saveChanges
|
||||
saveChanges,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<q-page padding>
|
||||
<q-card>
|
||||
<template>
|
||||
<div style="max-width: 1800px; width: 100%;">
|
||||
<div style="max-width: 1800px; width: 100%">
|
||||
<q-toolbar class="bg-primary text-white q-my-md shadow-2 items-center row justify-center">
|
||||
<div class="row justify-center items-center">
|
||||
<q-btn flat dense label="Prev" @click="calendarPrev" />
|
||||
|
@ -41,7 +41,7 @@
|
|||
toggle-color=""
|
||||
:options="[
|
||||
{ label: 'Tag', value: 'day-agenda' },
|
||||
{ label: 'Woche', value: 'week-agenda' }
|
||||
{ label: 'Woche', value: 'week-agenda' },
|
||||
]"
|
||||
/>
|
||||
</q-toolbar>
|
||||
|
@ -50,11 +50,11 @@
|
|||
:view="calendarView"
|
||||
:weekdays="[1, 2, 3, 4, 5, 6, 0]"
|
||||
locale="de-de"
|
||||
style="height: 100%; min-height: 400px;"
|
||||
style="height: 100%; min-height: 400px"
|
||||
ref="calendar"
|
||||
>
|
||||
<template #day-body="{ timestamp }" style="min-height: 200px;">
|
||||
<template !v-if="getAgenda(timestamp)" style="min-height: 200px;"> </template>
|
||||
<template #day-body="{ timestamp }" style="min-height: 200px">
|
||||
<template !v-if="getAgenda(timestamp)" style="min-height: 200px"> </template>
|
||||
<template v-for="agenda in getAgenda(timestamp)">
|
||||
<eventslot :event="agenda" :key="agenda.id" />
|
||||
</template>
|
||||
|
@ -79,7 +79,7 @@ export default defineComponent({
|
|||
name: 'AgendaView',
|
||||
components: { Eventslot },
|
||||
filters: {
|
||||
toMonth: function(value: string) {
|
||||
toMonth: function (value: string) {
|
||||
if (value) {
|
||||
return date.formatDate(new Date(value), 'MMMM', {
|
||||
months: [
|
||||
|
@ -94,16 +94,16 @@ export default defineComponent({
|
|||
'September',
|
||||
'Oktober',
|
||||
'November',
|
||||
'Dezember'
|
||||
]
|
||||
'Dezember',
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
toYear: function(value: string) {
|
||||
toYear: function (value: string) {
|
||||
if (value) {
|
||||
return date.formatDate(new Date(value), 'YYYY');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
setup(_, { root }) {
|
||||
|
@ -117,12 +117,12 @@ export default defineComponent({
|
|||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
console.log('Hier Passiert was');
|
||||
state.value.events
|
||||
.filter(event => {
|
||||
.filter((event) => {
|
||||
const thisWeek = date.formatDate(new Date(selectedDate.value), 'w');
|
||||
console.log(thisWeek, date.formatDate(event.start, 'w'));
|
||||
return date.formatDate(event.start, 'w') == thisWeek;
|
||||
})
|
||||
.forEach(event => {
|
||||
.forEach((event) => {
|
||||
let day = event.start.getDay();
|
||||
console.log('event', event, day, !agenda[day]);
|
||||
if (!agenda[day]) {
|
||||
|
@ -172,9 +172,9 @@ export default defineComponent({
|
|||
updateProxy,
|
||||
saveNewSelectedDate,
|
||||
proxyDate,
|
||||
calendarView
|
||||
calendarView,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<q-card
|
||||
class="background: radial-gradient(circle, #35a2ff 0%, #014a88 100%) justify-start content-center items-center rounded-borders border-primary shadow-5 q-mb-xs"
|
||||
class="background: radial-gradient(circle, #35a2ff 0%, #014a88 100%) justify-start content-center items-center rounded-borders border-primary shadow-5 q-mb-xs"
|
||||
bordered
|
||||
>
|
||||
<header class="text-primary q-px-xs">
|
||||
|
@ -8,7 +8,7 @@
|
|||
{{ event.type.name }}
|
||||
</div>
|
||||
|
||||
<div v-if="event.description" class=" col text-weight-medium " style="font-size: 10px">
|
||||
<div v-if="event.description" class="col text-weight-medium" style="font-size: 10px">
|
||||
Info
|
||||
{{ event.description }}
|
||||
</div>
|
||||
|
@ -29,14 +29,14 @@
|
|||
<q-select
|
||||
filled
|
||||
v-model="job.services"
|
||||
:option-label="opt => userDisplay(opt)"
|
||||
:option-label="(opt) => userDisplay(opt)"
|
||||
multiple
|
||||
disable
|
||||
use-chips
|
||||
stack-label
|
||||
label="Dienste"
|
||||
class="col-auto q-px-xs"
|
||||
style="font-size: 6px "
|
||||
style="font-size: 6px"
|
||||
counter
|
||||
:max-values="job.required_services"
|
||||
:key="refreshKey"
|
||||
|
@ -81,15 +81,15 @@ export default defineComponent({
|
|||
components: {},
|
||||
props: {
|
||||
event: {
|
||||
required: true
|
||||
}
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
formatToHour: function(value: Date) {
|
||||
formatToHour: function (value: Date) {
|
||||
if (value) {
|
||||
return date.formatDate(value, 'HH:mm');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
setup(props: Props, { root, emit }) {
|
||||
|
@ -104,14 +104,14 @@ export default defineComponent({
|
|||
refreshKey.value += 1;
|
||||
}
|
||||
onBeforeMount(() => {
|
||||
store.dispatch('user/getUsers').catch(error => {
|
||||
store.dispatch('user/getUsers').catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
});
|
||||
|
||||
function isUserEnrolled(job: FG.Job) {
|
||||
return (
|
||||
job.services.filter(service => service.userid == state.currentUser?.userid).length >= 1
|
||||
job.services.filter((service) => service.userid == state.currentUser?.userid).length >= 1
|
||||
);
|
||||
}
|
||||
function jobFull(job: FG.Job) {
|
||||
|
@ -119,7 +119,7 @@ export default defineComponent({
|
|||
return job.services.length >= job.required_services;
|
||||
}
|
||||
function userDisplay(userid: string) {
|
||||
return state.users.find(user => (user.userid = userid))?.display_name;
|
||||
return state.users.find((user) => (user.userid = userid))?.display_name;
|
||||
}
|
||||
|
||||
function enrollForJob(this: any, job: FG.Job) {
|
||||
|
@ -127,16 +127,16 @@ export default defineComponent({
|
|||
if (state.currentUser) {
|
||||
const newService: FG.Service = {
|
||||
userid: state.currentUser?.userid,
|
||||
value: 1
|
||||
value: 1,
|
||||
};
|
||||
|
||||
const newUserService = { user: newService };
|
||||
const UpdateInformation = {
|
||||
eventId: <number>this.event.id,
|
||||
JobId: job.id,
|
||||
service: newUserService
|
||||
service: newUserService,
|
||||
};
|
||||
void store.dispatch('schedule/updateEvent', UpdateInformation).catch(error => {
|
||||
void store.dispatch('schedule/updateEvent', UpdateInformation).catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
}
|
||||
|
@ -147,16 +147,16 @@ export default defineComponent({
|
|||
if (state.currentUser) {
|
||||
const newService: FG.Service = {
|
||||
userid: state.currentUser?.userid,
|
||||
value: -1
|
||||
value: -1,
|
||||
};
|
||||
|
||||
const newUserService = { user: newService };
|
||||
const UpdateInformation = {
|
||||
eventId: <number>this.event.id,
|
||||
JobId: job.id,
|
||||
service: newUserService
|
||||
service: newUserService,
|
||||
};
|
||||
void store.dispatch('schedule/updateEvent', UpdateInformation).catch(error => {
|
||||
void store.dispatch('schedule/updateEvent', UpdateInformation).catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
}
|
||||
|
@ -173,9 +173,9 @@ export default defineComponent({
|
|||
signOutFromJob,
|
||||
jobFull,
|
||||
userDisplay,
|
||||
refresh
|
||||
refresh,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ export default defineComponent({
|
|||
setLoadingBar(loading);
|
||||
|
||||
return { checkMain, mainRoutes };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped></style>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<q-page padding class="fit row justify-center content-start items-start q-gutter-sm">
|
||||
<q-tab-panels
|
||||
v-model="tab"
|
||||
style="background-color: transparent;"
|
||||
style="background-color: transparent"
|
||||
class="q-ma-none q-pa-none fit row justify-center content-start items-start"
|
||||
animated
|
||||
>
|
||||
|
@ -72,7 +72,7 @@ export default defineComponent({
|
|||
const tabs: Tab[] = [
|
||||
{ name: 'create', label: 'Veranstaltungen' },
|
||||
{ name: 'eventtypes', label: 'Veranstaltungsarten' },
|
||||
{ name: 'jobtypes', label: 'Dienstarten' }
|
||||
{ name: 'jobtypes', label: 'Dienstarten' },
|
||||
];
|
||||
|
||||
const drawer = ref<boolean>(false);
|
||||
|
@ -83,7 +83,7 @@ export default defineComponent({
|
|||
},
|
||||
set: (val: boolean) => {
|
||||
drawer.value = val;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const tab = ref<string>('create');
|
||||
|
@ -92,8 +92,8 @@ export default defineComponent({
|
|||
canEditRoles,
|
||||
showDrawer,
|
||||
tab,
|
||||
tabs
|
||||
tabs,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<q-page padding class="fit row justify-center content-start items-start q-gutter-sm">
|
||||
<q-tab-panels
|
||||
v-model="tab"
|
||||
style="background-color: transparent;"
|
||||
style="background-color: transparent"
|
||||
class="q-ma-none q-pa-none fit row justify-center content-start items-start"
|
||||
animated
|
||||
>
|
||||
|
@ -71,7 +71,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
const tabs: Tab[] = [
|
||||
{ name: 'agendaView', label: 'Kalendar' }
|
||||
{ name: 'agendaView', label: 'Kalendar' },
|
||||
// { name: 'eventtypes', label: 'Veranstaltungsarten' },
|
||||
// { name: 'jobtypes', label: 'Dienstarten' }
|
||||
];
|
||||
|
@ -84,7 +84,7 @@ export default defineComponent({
|
|||
},
|
||||
set: (val: boolean) => {
|
||||
drawer.value = val;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const tab = ref<string>('agendaView');
|
||||
|
@ -93,8 +93,8 @@ export default defineComponent({
|
|||
canEditRoles,
|
||||
showDrawer,
|
||||
tab,
|
||||
tabs
|
||||
tabs,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -8,5 +8,5 @@ export const PERMISSIONS = {
|
|||
// Kann neue Nutzer hinzufügen
|
||||
REGISTER: 'users_register',
|
||||
// Kann Rollen löschen oder bearbeiten, z.b. Rechte hinzufügen etc
|
||||
ROLES_EDIT: 'roles_edit'
|
||||
ROLES_EDIT: 'roles_edit',
|
||||
};
|
||||
|
|
|
@ -16,9 +16,9 @@ const plugin: FG_Plugin.Plugin = {
|
|||
priority: 0,
|
||||
name: 'stats',
|
||||
permissions: [],
|
||||
widget: () => import('./components/Widget.vue')
|
||||
}
|
||||
]
|
||||
widget: () => import('./components/Widget.vue'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
|
|
@ -16,7 +16,7 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
|||
name: 'schedule-overview',
|
||||
shortcut: true,
|
||||
meta: { permissions: [] },
|
||||
component: () => import('../pages/Overview.vue')
|
||||
component: () => import('../pages/Overview.vue'),
|
||||
},
|
||||
{
|
||||
title: 'Dienstverwaltung',
|
||||
|
@ -25,7 +25,7 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
|||
name: 'schedule-management',
|
||||
shortcut: false,
|
||||
meta: { permissions: [] },
|
||||
component: () => import('../pages/Management.vue')
|
||||
component: () => import('../pages/Management.vue'),
|
||||
},
|
||||
{
|
||||
title: 'Dienstanfragen',
|
||||
|
@ -34,10 +34,10 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
|||
name: 'schedule-requests',
|
||||
shortcut: false,
|
||||
meta: { permissions: [] },
|
||||
component: () => import('../pages/Requests.vue')
|
||||
}
|
||||
]
|
||||
}
|
||||
component: () => import('../pages/Requests.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default mainRoutes;
|
||||
|
|
|
@ -22,7 +22,7 @@ export interface ScheduleInterface {
|
|||
const state: ScheduleInterface = {
|
||||
jobTypes: [],
|
||||
eventTypes: [],
|
||||
events: []
|
||||
events: [],
|
||||
};
|
||||
|
||||
interface Event {
|
||||
|
@ -51,11 +51,11 @@ const mutations: MutationTree<ScheduleInterface> = {
|
|||
state.jobTypes.unshift(jobType);
|
||||
},
|
||||
removeJobType(state, id: number) {
|
||||
const index = state.jobTypes.findIndex(item => item.id == id);
|
||||
const index = state.jobTypes.findIndex((item) => item.id == id);
|
||||
state.jobTypes.splice(index, 1);
|
||||
},
|
||||
setJobType(state, jobType: JobType) {
|
||||
const _jobtype = state.jobTypes.find(item => item.id == jobType.id);
|
||||
const _jobtype = state.jobTypes.find((item) => item.id == jobType.id);
|
||||
if (_jobtype) {
|
||||
_jobtype.name = jobType.name;
|
||||
}
|
||||
|
@ -67,11 +67,11 @@ const mutations: MutationTree<ScheduleInterface> = {
|
|||
state.eventTypes.unshift(eventType);
|
||||
},
|
||||
removeEventType(state, id: number) {
|
||||
const index = state.eventTypes.findIndex(item => item.id == id);
|
||||
const index = state.eventTypes.findIndex((item) => item.id == id);
|
||||
state.eventTypes.splice(index, 1);
|
||||
},
|
||||
setEventType(state, eventType: EventType) {
|
||||
const _eventtype = state.eventTypes.find(item => item.id == eventType.id);
|
||||
const _eventtype = state.eventTypes.find((item) => item.id == eventType.id);
|
||||
if (_eventtype) {
|
||||
_eventtype.name = eventType.name;
|
||||
}
|
||||
|
@ -85,11 +85,11 @@ const mutations: MutationTree<ScheduleInterface> = {
|
|||
updateEvent(state, event: FG.Event) {
|
||||
/*let eventToChange = state.events.find(ev => ev.id == event.id);
|
||||
eventToChange = event; */
|
||||
const index = state.events.findIndex(ev => ev.id == event.id);
|
||||
const index = state.events.findIndex((ev) => ev.id == event.id);
|
||||
if (index > -1) {
|
||||
state.events[index] = event;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
||||
|
@ -100,7 +100,7 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
console.log('action:', response.data);
|
||||
commit('setJobTypes', response.data);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
},
|
||||
|
@ -111,7 +111,7 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
.then((response: AxiosResponse<JobType>) => {
|
||||
commit('addJobType', response.data);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
},
|
||||
|
@ -122,7 +122,7 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
.then(() => {
|
||||
commit('removeJobType', data);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
},
|
||||
|
@ -133,7 +133,7 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
.then(() => {
|
||||
commit('setJobType', jobtype);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
},
|
||||
|
@ -145,7 +145,7 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
console.log('action:', response.data);
|
||||
commit('setEventTypes', response.data);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
},
|
||||
|
@ -157,7 +157,7 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
.then((response: AxiosResponse<EventType>) => {
|
||||
commit('addEventType', response.data);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
},
|
||||
|
@ -167,7 +167,7 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
.then(() => {
|
||||
commit('removeEventType', data);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
},
|
||||
|
@ -177,7 +177,7 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
.then(() => {
|
||||
commit('setEventType', eventtype);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
},
|
||||
|
@ -188,7 +188,7 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
.then((response: AxiosResponse<Event>) => {
|
||||
commit('addEvent', response.data);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
console.log('Events: ', state.events);
|
||||
|
@ -206,7 +206,7 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
response.data.start = new Date(response.data.start);
|
||||
commit('updateEvent', response.data);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
},
|
||||
|
@ -215,15 +215,15 @@ const actions: ActionTree<ScheduleInterface, StateInterface> = {
|
|||
.get('/schedule/events')
|
||||
.then((response: AxiosResponse<Event[]>) => {
|
||||
console.log('action:', response.data);
|
||||
response.data.forEach(event => {
|
||||
response.data.forEach((event) => {
|
||||
event.start = new Date(event.start);
|
||||
});
|
||||
commit('setEvents', response.data);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
const getters: GetterTree<ScheduleInterface, StateInterface> = {
|
||||
jobTypes(state) {
|
||||
|
@ -231,7 +231,7 @@ const getters: GetterTree<ScheduleInterface, StateInterface> = {
|
|||
},
|
||||
events(state) {
|
||||
return state.events;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const schedule: Module<ScheduleInterface, StateInterface> = {
|
||||
|
@ -239,7 +239,7 @@ const schedule: Module<ScheduleInterface, StateInterface> = {
|
|||
state,
|
||||
mutations,
|
||||
actions,
|
||||
getters
|
||||
getters,
|
||||
};
|
||||
|
||||
export default schedule;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<template>
|
||||
<q-card class="12">
|
||||
<q-card-section class="fit row justify-start content-center items-center">
|
||||
<div class="col-xs-12 col-sm-6 text-center text-h6">
|
||||
Neues Mitglied
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 text-center text-h6">Neues Mitglied</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<MainUserSettings :user="user" @update:user="setUser" :new-user="true" />
|
||||
|
@ -27,15 +25,15 @@ export default defineComponent({
|
|||
firstname: '',
|
||||
lastname: '',
|
||||
mail: '',
|
||||
roles: []
|
||||
roles: [],
|
||||
});
|
||||
function setUser(value: FG.User) {
|
||||
store.dispatch('user/setUser', value).catch(error => {
|
||||
store.dispatch('user/setUser', value).catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
}
|
||||
return { user, setUser };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<template>
|
||||
<q-card class="col-12">
|
||||
<q-card-section class="fit row justify-start content-center items-center">
|
||||
<div class="col-xs-12 col-sm-6 text-center text-h6">
|
||||
Benutzereinstellungen
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 text-center text-h6">Benutzereinstellungen</div>
|
||||
<div class="col-xs-12 col-sm-6 q-pa-sm">
|
||||
<UserSelector :user="user" @update:user="userUpdated" />
|
||||
</div>
|
||||
|
@ -33,7 +31,7 @@ export default defineComponent({
|
|||
};
|
||||
|
||||
function updateUser(value: FG.User) {
|
||||
store.dispatch('user/updateUser', value).catch(error => {
|
||||
store.dispatch('user/updateUser', value).catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
}
|
||||
|
@ -41,9 +39,9 @@ export default defineComponent({
|
|||
return {
|
||||
user,
|
||||
userUpdated,
|
||||
updateUser
|
||||
updateUser,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ export default defineComponent({
|
|||
const store = <Store<StateInterface>>root.$store;
|
||||
|
||||
onBeforeMount(() => {
|
||||
store.dispatch('user/getUsers').catch(error => {
|
||||
store.dispatch('user/getUsers').catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
|
@ -40,8 +40,8 @@ export default defineComponent({
|
|||
|
||||
return {
|
||||
updated,
|
||||
users
|
||||
users,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<q-card style="text-align: center;">
|
||||
<q-card style="text-align: center">
|
||||
<q-card-section class="row justify-center content-stretch">
|
||||
<div class="col-4">
|
||||
<div style="width: 100%; padding-bottom: 100%; position: relative;">
|
||||
<q-avatar style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">
|
||||
<div style="width: 100%; padding-bottom: 100%; position: relative">
|
||||
<q-avatar style="position: absolute; top: 0; left: 0; width: 100%; height: 100%">
|
||||
<img :src="avatarLink" />
|
||||
</q-avatar>
|
||||
</div>
|
||||
|
@ -56,10 +56,10 @@ export default defineComponent({
|
|||
const birthday = computed(() =>
|
||||
store.state.user.users
|
||||
.filter(userHasBirthday)
|
||||
.filter(user => user.userid !== store.state.user.currentUser?.userid)
|
||||
.filter((user) => user.userid !== store.state.user.currentUser?.userid)
|
||||
);
|
||||
|
||||
return { avatarLink, name, hasBirthday, birthday };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -124,17 +124,17 @@ export default defineComponent({
|
|||
components: { IsoDateInput: IsoDateInput },
|
||||
props: {
|
||||
user: {
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
newUser: {
|
||||
default: false
|
||||
}
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup(props: Props, { root, emit }) {
|
||||
const store = <Store<StateInterface>>root.$store;
|
||||
|
||||
onBeforeMount(() => {
|
||||
store.dispatch('user/getRoles', false).catch(error => {
|
||||
store.dispatch('user/getRoles', false).catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
});
|
||||
|
@ -148,7 +148,7 @@ export default defineComponent({
|
|||
const oldUser = computed(() => {
|
||||
if (isCurrentUser.value) return <FG.User>store.state.user.currentUser;
|
||||
else
|
||||
return store.state.user.users.filter(user => {
|
||||
return store.state.user.users.filter((user) => {
|
||||
user.userid === props.user?.userid;
|
||||
})[0];
|
||||
});
|
||||
|
@ -161,12 +161,12 @@ export default defineComponent({
|
|||
message: 'Datei zu groß oder keine gültige Bilddatei.',
|
||||
timeout: 10000,
|
||||
progress: true,
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }]
|
||||
actions: [{ icon: 'mdi-close', color: 'white' }],
|
||||
});
|
||||
avatar.value = [];
|
||||
}
|
||||
|
||||
const allRoles = computed(() => store.state.user.roles.map(role => role.name));
|
||||
const allRoles = computed(() => store.state.user.roles.map((role) => role.name));
|
||||
const password = ref('');
|
||||
const new_password = ref('');
|
||||
const new_password2 = ref('');
|
||||
|
@ -175,11 +175,11 @@ export default defineComponent({
|
|||
let changed = <FG.User>props.user;
|
||||
if (typeof changed.birthday === 'string') changed.birthday = new Date(changed.birthday);
|
||||
changed = Object.assign(changed, {
|
||||
password: password.value
|
||||
password: password.value,
|
||||
});
|
||||
if (new_password.value != '') {
|
||||
changed = Object.assign(changed, {
|
||||
new_password: new_password.value
|
||||
new_password: new_password.value,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ export default defineComponent({
|
|||
store
|
||||
.dispatch('user/uploadAvatar', {
|
||||
user: changed,
|
||||
file: avatar.value
|
||||
file: avatar.value,
|
||||
})
|
||||
.catch((response: Response) => {
|
||||
if (response && response.status == 400) {
|
||||
|
@ -247,8 +247,8 @@ export default defineComponent({
|
|||
notEmpty,
|
||||
isUseridUsed,
|
||||
save,
|
||||
reset
|
||||
reset,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
<q-card class="col-12">
|
||||
<q-form @submit="save" @reset="reset">
|
||||
<q-card-section class="fit row justify-start content-center items-center">
|
||||
<span class="col-xs-12 col-sm-6 text-center text-h6">
|
||||
Rollen und Berechtigungen
|
||||
</span>
|
||||
<span class="col-xs-12 col-sm-6 text-center text-h6"> Rollen und Berechtigungen </span>
|
||||
<q-select
|
||||
filled
|
||||
use-input
|
||||
|
@ -57,10 +55,10 @@ export default defineComponent({
|
|||
const store = <Store<StateInterface>>root.$store;
|
||||
|
||||
onBeforeMount(() => {
|
||||
store.dispatch('user/getRoles').catch(error => {
|
||||
store.dispatch('user/getRoles').catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
store.dispatch('user/getPermissions').catch(error => {
|
||||
store.dispatch('user/getPermissions').catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
});
|
||||
|
@ -68,10 +66,10 @@ export default defineComponent({
|
|||
const role = ref<FG.Role | null>(null);
|
||||
const roles = computed(() => store.state.user.roles);
|
||||
const permissions = computed(() =>
|
||||
store.state.user.permissions.map(perm => {
|
||||
store.state.user.permissions.map((perm) => {
|
||||
return {
|
||||
value: perm,
|
||||
label: perm
|
||||
label: perm,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
@ -98,7 +96,7 @@ export default defineComponent({
|
|||
role.value = {
|
||||
id: rl.id,
|
||||
name: rl.name,
|
||||
permissions: Array.from(rl.permissions)
|
||||
permissions: Array.from(rl.permissions),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -119,7 +117,7 @@ export default defineComponent({
|
|||
|
||||
function reset() {
|
||||
if (role.value && role.value.id !== -1) {
|
||||
const original = roles.value.find(value => value.name === role.value?.name);
|
||||
const original = roles.value.find((value) => value.name === role.value?.name);
|
||||
if (original) updateRole(original);
|
||||
} else {
|
||||
role.value = null;
|
||||
|
@ -134,7 +132,7 @@ export default defineComponent({
|
|||
store
|
||||
.dispatch('user/deleteRole', role.value)
|
||||
.then(() => (role.value = null))
|
||||
.catch(error => console.warn(error));
|
||||
.catch((error) => console.warn(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,8 +148,8 @@ export default defineComponent({
|
|||
reset,
|
||||
removeRole,
|
||||
remove,
|
||||
newRoleName
|
||||
newRoleName,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -54,8 +54,8 @@ export default defineComponent({
|
|||
name: 'Sessions',
|
||||
props: {
|
||||
session: {
|
||||
required: true
|
||||
}
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup(props: { session: FG.Session }, { root }) {
|
||||
const store = <Store<StateInterface>>root.$store;
|
||||
|
@ -87,7 +87,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
function deleteSession(token: string) {
|
||||
store.dispatch('session/deleteSession', token).catch(error => {
|
||||
store.dispatch('session/deleteSession', token).catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ export default defineComponent({
|
|||
return (lifetime.value / (60 * 60 * 24)).toFixed(2);
|
||||
}
|
||||
},
|
||||
set: val => {
|
||||
set: (val) => {
|
||||
if (val) {
|
||||
switch (option.value) {
|
||||
case options.value[0]:
|
||||
|
@ -122,7 +122,7 @@ export default defineComponent({
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
function edit(value: boolean) {
|
||||
|
@ -135,7 +135,7 @@ export default defineComponent({
|
|||
isEdit.value = false;
|
||||
void store
|
||||
.dispatch('session/updateSession', { lifetime: lifetime.value, token: props.session.token })
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
@ -151,8 +151,8 @@ export default defineComponent({
|
|||
option,
|
||||
lifetime,
|
||||
computedLifetime,
|
||||
save
|
||||
save,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<q-page padding class="fit row justify-center content-start items-start q-gutter-sm">
|
||||
<q-tab-panels
|
||||
v-model="tab"
|
||||
style="background-color: transparent;"
|
||||
style="background-color: transparent"
|
||||
class="q-ma-none q-pa-none fit row justify-center content-start items-start"
|
||||
animated
|
||||
>
|
||||
|
@ -72,7 +72,7 @@ export default defineComponent({
|
|||
const tabs: Tab[] = [
|
||||
{ name: 'user', label: 'Mitglieder' },
|
||||
{ name: 'newUser', label: 'Neues Mitglied' },
|
||||
{ name: 'roles', label: 'Rollen' }
|
||||
{ name: 'roles', label: 'Rollen' },
|
||||
];
|
||||
|
||||
const drawer = ref<boolean>(false);
|
||||
|
@ -83,7 +83,7 @@ export default defineComponent({
|
|||
},
|
||||
set: (val: boolean) => {
|
||||
drawer.value = val;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const tab = ref<string>('user');
|
||||
|
@ -92,8 +92,8 @@ export default defineComponent({
|
|||
canEditRoles,
|
||||
showDrawer,
|
||||
tab,
|
||||
tabs
|
||||
tabs,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -32,6 +32,6 @@ export default defineComponent({
|
|||
return root.$route.matched.length == 2;
|
||||
});
|
||||
return { checkMain, mainRoutes };
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -28,7 +28,7 @@ export default defineComponent({
|
|||
const store = <Store<StateInterface>>root.$store;
|
||||
|
||||
onBeforeMount(() => {
|
||||
store.dispatch('session/getSessions').catch(error => {
|
||||
store.dispatch('session/getSessions').catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
});
|
||||
|
@ -37,7 +37,7 @@ export default defineComponent({
|
|||
const sessions = computed(() => store.state.session.sessions);
|
||||
const loading = computed(() => store.state.session.loading || store.state.user.loading > 0);
|
||||
function updateUser(value: FG.User) {
|
||||
store.dispatch('user/updateUser', value).catch(error => {
|
||||
store.dispatch('user/updateUser', value).catch((error) => {
|
||||
console.warn(error);
|
||||
});
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ export default defineComponent({
|
|||
return {
|
||||
currentUser,
|
||||
sessions,
|
||||
updateUser
|
||||
updateUser,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -8,5 +8,5 @@ export const PERMISSIONS = {
|
|||
// Kann neue Nutzer hinzufügen
|
||||
REGISTER: 'users_register',
|
||||
// Kann Rollen löschen oder bearbeiten, z.b. Rechte hinzufügen etc
|
||||
ROLES_EDIT: 'roles_edit'
|
||||
ROLES_EDIT: 'roles_edit',
|
||||
};
|
||||
|
|
|
@ -16,16 +16,16 @@ const plugin: FG_Plugin.Plugin = {
|
|||
Module<UserStateInterface, StateInterface> | Module<SessionInterface, StateInterface>
|
||||
>([
|
||||
['user', userStore],
|
||||
['session', sessionsStore]
|
||||
['session', sessionsStore],
|
||||
]),
|
||||
widgets: [
|
||||
{
|
||||
priority: 1,
|
||||
name: 'greeting',
|
||||
permissions: [],
|
||||
widget: () => import('./components/Widget.vue')
|
||||
}
|
||||
]
|
||||
widget: () => import('./components/Widget.vue'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
|
|
@ -15,7 +15,7 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
|||
name: 'user-settings',
|
||||
shortcut: true,
|
||||
meta: { permissions: ['user'] },
|
||||
component: () => import('../pages/Settings.vue')
|
||||
component: () => import('../pages/Settings.vue'),
|
||||
},
|
||||
{
|
||||
title: 'Admin',
|
||||
|
@ -24,10 +24,10 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
|||
name: 'admin-settings',
|
||||
shortcut: false,
|
||||
meta: { permissions: ['users_edit_other'] },
|
||||
component: () => import('../pages/AdminSettings.vue')
|
||||
}
|
||||
]
|
||||
}
|
||||
component: () => import('../pages/AdminSettings.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default mainRoutes;
|
||||
|
|
|
@ -27,7 +27,7 @@ const state: UserStateInterface = {
|
|||
permissions: [],
|
||||
currentUser: loadUserFromLocalStorage(),
|
||||
currentPermissions: SessionStorage.getItem<FG.Permission[]>('currentPermissions') || [],
|
||||
loading: 0
|
||||
loading: 0,
|
||||
};
|
||||
|
||||
const mutations: MutationTree<UserStateInterface> = {
|
||||
|
@ -50,7 +50,7 @@ const mutations: MutationTree<UserStateInterface> = {
|
|||
state.users = data;
|
||||
},
|
||||
setUser(state, data: FG.User) {
|
||||
const index = state.users.findIndex(x => x.userid === data.userid);
|
||||
const index = state.users.findIndex((x) => x.userid === data.userid);
|
||||
if (index > -1) state.users[index] = data;
|
||||
else state.users.push(data);
|
||||
},
|
||||
|
@ -61,7 +61,7 @@ const mutations: MutationTree<UserStateInterface> = {
|
|||
state.roles.push(data);
|
||||
},
|
||||
updateRole(state, data: FG.Role) {
|
||||
const idx = state.roles.findIndex(role => role.id === data.id);
|
||||
const idx = state.roles.findIndex((role) => role.id === data.id);
|
||||
if (idx >= 0) {
|
||||
state.roles[idx].name = data.name;
|
||||
state.roles[idx].permissions = data.permissions;
|
||||
|
@ -73,7 +73,7 @@ const mutations: MutationTree<UserStateInterface> = {
|
|||
setLoading(state, data = true) {
|
||||
if (data) state.loading += 1;
|
||||
else state.loading -= 1;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const actions: ActionTree<UserStateInterface, StateInterface> = {
|
||||
|
@ -86,7 +86,7 @@ const actions: ActionTree<UserStateInterface, StateInterface> = {
|
|||
commit('setCurrentUser', response.data);
|
||||
commit('setCurrentPermissions', response.data.permissions);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
})
|
||||
.finally(() => {
|
||||
|
@ -102,12 +102,12 @@ const actions: ActionTree<UserStateInterface, StateInterface> = {
|
|||
axios
|
||||
.get('/users')
|
||||
.then((response: AxiosResponse<FG.User[]>) => {
|
||||
response.data.forEach(user => {
|
||||
response.data.forEach((user) => {
|
||||
if (user.birthday) user.birthday = new Date(user.birthday);
|
||||
});
|
||||
commit('setUsers', response.data);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
})
|
||||
.finally(() => {
|
||||
|
@ -124,7 +124,7 @@ const actions: ActionTree<UserStateInterface, StateInterface> = {
|
|||
void dispatch('getCurrentUser');
|
||||
else void dispatch('getUsers');
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
})
|
||||
.finally(() => {
|
||||
|
@ -139,8 +139,8 @@ const actions: ActionTree<UserStateInterface, StateInterface> = {
|
|||
return axios
|
||||
.post(`/users/${payload.user.userid}/avatar`, formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
})
|
||||
.catch((error: AxiosError) => {
|
||||
return Promise.reject(error.response);
|
||||
|
@ -159,7 +159,7 @@ const actions: ActionTree<UserStateInterface, StateInterface> = {
|
|||
void dispatch('getCurrentUser');
|
||||
else void dispatch('getUsers');
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
console.warn(error);
|
||||
})
|
||||
.finally(() => {
|
||||
|
@ -210,7 +210,7 @@ const actions: ActionTree<UserStateInterface, StateInterface> = {
|
|||
.then(() => {
|
||||
commit(
|
||||
'setRoles',
|
||||
state.roles.filter(value => value.id !== data.id)
|
||||
state.roles.filter((value) => value.id !== data.id)
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
|
@ -239,12 +239,12 @@ const actions: ActionTree<UserStateInterface, StateInterface> = {
|
|||
} else {
|
||||
return Promise.resolve(user);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const getters: GetterTree<UserStateInterface, StateInterface> = {
|
||||
getUser: state => (userid: string) => {
|
||||
const user = state.users.filter(usr => usr.userid === userid);
|
||||
getUser: (state) => (userid: string) => {
|
||||
const user = state.users.filter((usr) => usr.userid === userid);
|
||||
return user.length > 0 ? user[0] : undefined;
|
||||
},
|
||||
currentUser({ currentUser }) {
|
||||
|
@ -260,8 +260,8 @@ const getters: GetterTree<UserStateInterface, StateInterface> = {
|
|||
return currentUser?.display_name;
|
||||
},
|
||||
roles({ roles }): string[] {
|
||||
return roles.map(role => role.name).flat();
|
||||
}
|
||||
return roles.map((role) => role.name).flat();
|
||||
},
|
||||
};
|
||||
|
||||
const userStore: Module<UserStateInterface, StateInterface> = {
|
||||
|
@ -269,7 +269,7 @@ const userStore: Module<UserStateInterface, StateInterface> = {
|
|||
actions,
|
||||
getters,
|
||||
mutations,
|
||||
state
|
||||
state,
|
||||
};
|
||||
|
||||
export default userStore;
|
||||
|
|
|
@ -14,10 +14,10 @@ export const Router: VueRouter = new VueRouter({
|
|||
// quasar.conf.js -> build -> vueRouterMode
|
||||
// quasar.conf.js -> build -> publicPath
|
||||
mode: process.env.VUE_ROUTER_MODE,
|
||||
base: process.env.VUE_ROUTER_BASE
|
||||
base: process.env.VUE_ROUTER_BASE,
|
||||
});
|
||||
|
||||
export default route<Store<StateInterface>>(function({ Vue }) {
|
||||
export default route<Store<StateInterface>>(function ({ Vue }) {
|
||||
Vue.use(VueRouter);
|
||||
|
||||
return Router;
|
||||
|
|
|
@ -9,19 +9,19 @@ const routes: RouteConfig[] = [
|
|||
{
|
||||
name: 'login',
|
||||
path: 'login',
|
||||
component: () => import('pages/Login.vue')
|
||||
component: () => import('pages/Login.vue'),
|
||||
},
|
||||
{
|
||||
name: 'password_reset',
|
||||
path: 'reset',
|
||||
component: () => import('pages/Reset.vue')
|
||||
component: () => import('pages/Reset.vue'),
|
||||
},
|
||||
{
|
||||
name: 'about_out',
|
||||
path: 'about',
|
||||
component: () => import('pages/about/About.vue')
|
||||
}
|
||||
]
|
||||
component: () => import('pages/about/About.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/main',
|
||||
|
@ -33,32 +33,32 @@ const routes: RouteConfig[] = [
|
|||
name: 'dashboard',
|
||||
path: 'dashboard',
|
||||
meta: { permissions: ['user'] },
|
||||
component: () => import('pages/Dashboard.vue')
|
||||
component: () => import('pages/Dashboard.vue'),
|
||||
},
|
||||
{
|
||||
name: 'about',
|
||||
path: 'about',
|
||||
meta: { permissions: ['user'] },
|
||||
component: () => import('pages/about/About.vue')
|
||||
}
|
||||
]
|
||||
component: () => import('pages/about/About.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/error',
|
||||
name: 'error',
|
||||
component: () => import('pages/PluginError.vue')
|
||||
component: () => import('pages/PluginError.vue'),
|
||||
},
|
||||
{
|
||||
path: '/offline',
|
||||
name: 'offline',
|
||||
component: () => import('pages/Offline.vue')
|
||||
component: () => import('pages/Offline.vue'),
|
||||
},
|
||||
// Always leave this as last one,
|
||||
// but you can also remove it
|
||||
{
|
||||
path: '*',
|
||||
redirect: 'login'
|
||||
}
|
||||
redirect: 'login',
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
||||
|
|
|
@ -13,7 +13,7 @@ export interface StateInterface {
|
|||
[key: string]: any;
|
||||
}
|
||||
|
||||
export default store(function({ Vue }) {
|
||||
export default store(function ({ Vue }) {
|
||||
Vue.use(Vuex);
|
||||
|
||||
const Store = new Vuex.Store<StateInterface>({
|
||||
|
@ -21,7 +21,7 @@ export default store(function({ Vue }) {
|
|||
|
||||
// enable strict mode (adds overhead!)
|
||||
// for dev mode only
|
||||
strict: !!process.env.DEV
|
||||
strict: !!process.env.DEV,
|
||||
});
|
||||
|
||||
return Store;
|
||||
|
|
|
@ -12,7 +12,7 @@ export function formatDateTime(
|
|||
weekday: useWeekday ? 'long' : undefined,
|
||||
hour: useTime ? '2-digit' : undefined,
|
||||
minute: useTime ? '2-digit' : undefined,
|
||||
second: useTime && useSeconds ? '2-digit' : undefined
|
||||
second: useTime && useSeconds ? '2-digit' : undefined,
|
||||
});
|
||||
return dateTimeFormat.format(date);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { watch, WatchSource } from '@vue/composition-api';
|
|||
import { LoadingBar } from 'quasar';
|
||||
|
||||
function setLoadingBar(loading: WatchSource<boolean>) {
|
||||
return watch<boolean>(loading, loading => {
|
||||
return watch<boolean>(loading, (loading) => {
|
||||
if (loading) LoadingBar.start(10000);
|
||||
if (!loading) LoadingBar.stop();
|
||||
});
|
||||
|
|
|
@ -7,10 +7,10 @@ export function hasPermission(permission: string, store: Store<StateInterface>)
|
|||
|
||||
export function hasPermissions(needed: string[], store: Store<StateInterface>) {
|
||||
const permissions = store.state.user.currentPermissions;
|
||||
return needed.every(value => permissions.includes(value));
|
||||
return needed.every((value) => permissions.includes(value));
|
||||
}
|
||||
|
||||
export function hasSomePermissions(needed: string[], store: Store<StateInterface>) {
|
||||
const permissions = store.state.user.currentPermissions;
|
||||
return needed.some(value => permissions.includes(value));
|
||||
return needed.some((value) => permissions.includes(value));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue