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