release v2.0.0 #4
|
@ -18,6 +18,8 @@ yarn.lock
|
|||
|
||||
# Capacitor related directories and files
|
||||
/src-capacitor/www
|
||||
/src-capacitor/android
|
||||
/src-capacitor/ios
|
||||
/src-capacitor/node_modules
|
||||
|
||||
# BEX related directories and files
|
||||
|
|
|
@ -4,5 +4,6 @@ export * from './src/stores/';
|
|||
|
||||
export * from './src/utils/datetime';
|
||||
export * from './src/utils/permission';
|
||||
export * from './src/utils/persistent';
|
||||
export * from './src/utils/validators';
|
||||
export * from './src/utils/misc';
|
||||
|
|
|
@ -1,28 +1,31 @@
|
|||
import { LocalStorage, SessionStorage } from 'quasar';
|
||||
import { FG_Plugin } from '@flaschengeist/types';
|
||||
import { fixSession, useSessionStore, useUserStore } from '.';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { api } from '../internal';
|
||||
import { defineStore } from 'pinia';
|
||||
import { PersistentStorage } from '../utils/persistent';
|
||||
|
||||
function loadCurrentSession() {
|
||||
const session = LocalStorage.getItem<FG.Session>('session');
|
||||
if (session) session.expires = new Date(session.expires);
|
||||
return session || undefined;
|
||||
function loadToken() {
|
||||
return PersistentStorage.get<string>('fg_token');
|
||||
}
|
||||
|
||||
function loadUser() {
|
||||
const user = SessionStorage.getItem<FG.User>('user');
|
||||
if (user && user.birthday) user.birthday = new Date(user.birthday);
|
||||
return user || undefined;
|
||||
function clearToken() {
|
||||
void PersistentStorage.remove('fg_token');
|
||||
}
|
||||
|
||||
export function saveToken(token?: string) {
|
||||
if (token === undefined) return clearToken();
|
||||
PersistentStorage.set('fg_token', token).catch(() =>
|
||||
console.error('Could not save token to storage')
|
||||
);
|
||||
}
|
||||
|
||||
export const useMainStore = defineStore({
|
||||
id: 'main',
|
||||
|
||||
state: () => ({
|
||||
session: loadCurrentSession(),
|
||||
user: loadUser(),
|
||||
session: undefined as FG.Session | undefined,
|
||||
user: undefined as FG.User | undefined,
|
||||
notifications: [] as Array<FG_Plugin.Notification>,
|
||||
shortcuts: [] as Array<FG_Plugin.MenuLink>,
|
||||
}),
|
||||
|
@ -45,18 +48,17 @@ export const useMainStore = defineStore({
|
|||
* Updates session and loads current user
|
||||
*/
|
||||
async init() {
|
||||
if (this.session) {
|
||||
const sessionStore = useSessionStore();
|
||||
const session = await sessionStore.getSession(this.session.token);
|
||||
if (session) {
|
||||
this.session = session;
|
||||
const userStore = useUserStore();
|
||||
const user = await userStore.getUser(this.session.userid);
|
||||
if (user) {
|
||||
this.user = user;
|
||||
SessionStorage.set('user', user);
|
||||
}
|
||||
const sessionStore = useSessionStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
try {
|
||||
const token = await loadToken();
|
||||
if (token !== null) {
|
||||
this.session = await sessionStore.getSession(token);
|
||||
if (this.session !== undefined) this.user = await userStore.getUser(this.session.userid);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Could not load token from storage', error);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -141,14 +143,10 @@ export const useMainStore = defineStore({
|
|||
async setShortcuts() {
|
||||
await api.put(`users/${this.currentUser.userid}/shortcuts`, this.shortcuts);
|
||||
},
|
||||
handleLoggedOut() {
|
||||
LocalStorage.clear();
|
||||
|
||||
this.$patch({
|
||||
session: undefined,
|
||||
user: undefined,
|
||||
});
|
||||
SessionStorage.clear();
|
||||
handleLoggedOut() {
|
||||
this.$reset();
|
||||
void clearToken();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import { LocalStorage, Platform } from 'quasar';
|
||||
import { Storage } from '@capacitor/storage';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type PersitentTypes = Date | RegExp | number | boolean | string | object;
|
||||
|
||||
export class PersistentStorage {
|
||||
static clear() {
|
||||
if (Platform.is.capacitor) return Storage.clear();
|
||||
else return Promise.resolve(LocalStorage.clear());
|
||||
}
|
||||
|
||||
static remove(key: string) {
|
||||
if (Platform.is.capacitor) return Storage.remove({ key: key });
|
||||
else return Promise.resolve(LocalStorage.remove(key));
|
||||
}
|
||||
|
||||
static set(key: string, value: PersitentTypes) {
|
||||
if (Platform.is.capacitor) return Storage.set({ key, value: JSON.stringify(value) });
|
||||
else return Promise.resolve(LocalStorage.set(key, value));
|
||||
}
|
||||
|
||||
static get<T extends PersitentTypes>(key: string) {
|
||||
if (Platform.is.capacitor)
|
||||
return Storage.get({ key }).then((v) =>
|
||||
v.value === null ? null : (JSON.parse(v.value) as T)
|
||||
);
|
||||
else return Promise.resolve(LocalStorage.getItem<T>(key));
|
||||
}
|
||||
|
||||
static keys() {
|
||||
if (Platform.is.capacitor) return Storage.keys().then((v) => v.keys);
|
||||
else return Promise.resolve(LocalStorage.getAllKeys());
|
||||
}
|
||||
}
|
|
@ -15,10 +15,10 @@
|
|||
"lint": "eslint --ext .js,.ts,.vue ./src ./api"
|
||||
},
|
||||
"dependencies": {
|
||||
"@capacitor/storage": "^1.2.3",
|
||||
"@flaschengeist/api": "file:./api",
|
||||
"@flaschengeist/users": "^1.0.0-alpha.1",
|
||||
"axios": "^0.24.0",
|
||||
"cordova": "^10.0.0",
|
||||
"pinia": "^2.0.4",
|
||||
"quasar": "^2.3.3"
|
||||
},
|
||||
|
@ -51,11 +51,11 @@
|
|||
"Firefox esr",
|
||||
"last 6 Chrome versions",
|
||||
"last 4 Firefox versions",
|
||||
"last 4 Edge versions",
|
||||
"last 4 Safari versions",
|
||||
"last 4 Edge versions",
|
||||
"last 4 Safari versions",
|
||||
"last 4 ChromeAndroid versions",
|
||||
"last 1 FirefoxAndroid versions"
|
||||
],
|
||||
],
|
||||
"cordova": [
|
||||
"iOS >= 13.0",
|
||||
"Android >= 76"
|
||||
|
|
|
@ -75,7 +75,7 @@ module.exports = configure(function (/* ctx */) {
|
|||
chain.plugin('eslint-webpack-plugin')
|
||||
.use(ESLintPlugin, [{
|
||||
extensions: [ 'ts', 'js', 'vue' ],
|
||||
exclude: 'node_modules'
|
||||
exclude: ['node_modules', 'src-capacitor']
|
||||
}])
|
||||
chain.plugin('modify-source-webpack-plugin')
|
||||
.use(ModifySourcePlugin, [{
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* eslint-disable */
|
||||
// THIS FEATURE-FLAG FILE IS AUTOGENERATED,
|
||||
// REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING
|
||||
import 'quasar/dist/types/feature-flag';
|
||||
import "quasar/dist/types/feature-flag";
|
||||
|
||||
declare module 'quasar/dist/types/feature-flag' {
|
||||
declare module "quasar/dist/types/feature-flag" {
|
||||
interface QuasarFeatureFlags {
|
||||
cordova: true;
|
||||
capacitor: true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"appId": "dev.flaschengeist",
|
||||
"appName": "flaschengeist-frontend",
|
||||
"bundledWebRuntime": false,
|
||||
"npmClient": "yarn",
|
||||
"webDir": "www",
|
||||
"ios": {
|
||||
"allowsLinkPreview": false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "flaschengeist",
|
||||
"version": "2.0.0-alpha.1",
|
||||
"description": "Modular student club administration system",
|
||||
"author": "Tim Gröger <flaschengeist@wu5.de>",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@capacitor/android": "^3.3.2",
|
||||
"@capacitor/app": "^1.0.0",
|
||||
"@capacitor/cli": "^3.0.0",
|
||||
"@capacitor/core": "^3.0.0",
|
||||
"@capacitor/ios": "^3.0.0-beta.0",
|
||||
"@capacitor/splash-screen": "^1.0.0",
|
||||
"@capacitor/storage": "^1.2.3"
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
.DS_Store
|
||||
|
||||
# Generated by package manager
|
||||
node_modules/
|
||||
|
||||
# Generated by Cordova
|
||||
/plugins/
|
||||
/platforms/
|
|
@ -1,76 +0,0 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<widget id="de.wu5.flaschengeist" version="2.0.0-alpha.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||
<name>Flaschengeist</name>
|
||||
<description>Modular student club administration system</description>
|
||||
<author email="dev@cordova.apache.org" href="http://cordova.io">
|
||||
Apache Cordova Team
|
||||
</author>
|
||||
<content src="index.html" />
|
||||
<access origin="*" />
|
||||
<allow-intent href="http://*/*" />
|
||||
<allow-intent href="https://*/*" />
|
||||
<allow-intent href="tel:*" />
|
||||
<allow-intent href="sms:*" />
|
||||
<allow-intent href="mailto:*" />
|
||||
<allow-intent href="geo:*" />
|
||||
<platform name="android">
|
||||
<allow-intent href="market:*" />
|
||||
<icon density="ldpi" src="res/android/ldpi.png" />
|
||||
<icon density="mdpi" src="res/android/mdpi.png" />
|
||||
<icon density="hdpi" src="res/android/hdpi.png" />
|
||||
<icon density="xhdpi" src="res/android/xhdpi.png" />
|
||||
<icon density="xxhdpi" src="res/android/xxhdpi.png" />
|
||||
<icon density="xxxhdpi" src="res/android/xxxhdpi.png" />
|
||||
<splash density="land-ldpi" src="res/screen/android/splash-land-ldpi.png" />
|
||||
<splash density="port-ldpi" src="res/screen/android/splash-port-ldpi.png" />
|
||||
<splash density="land-mdpi" src="res/screen/android/splash-land-mdpi.png" />
|
||||
<splash density="port-mdpi" src="res/screen/android/splash-port-mdpi.png" />
|
||||
<splash density="land-hdpi" src="res/screen/android/splash-land-hdpi.png" />
|
||||
<splash density="port-hdpi" src="res/screen/android/splash-port-hdpi.png" />
|
||||
<splash density="land-xhdpi" src="res/screen/android/splash-land-xhdpi.png" />
|
||||
<splash density="port-xhdpi" src="res/screen/android/splash-port-xhdpi.png" />
|
||||
<splash density="land-xxhdpi" src="res/screen/android/splash-land-xxhdpi.png" />
|
||||
<splash density="port-xxhdpi" src="res/screen/android/splash-port-xxhdpi.png" />
|
||||
<splash density="land-xxxhdpi" src="res/screen/android/splash-land-xxxhdpi.png" />
|
||||
<splash density="port-xxxhdpi" src="res/screen/android/splash-port-xxxhdpi.png" />
|
||||
</platform>
|
||||
<platform name="ios">
|
||||
<allow-intent href="itms:*" />
|
||||
<allow-intent href="itms-apps:*" />
|
||||
<icon height="57" src="res/ios/icon.png" width="57" />
|
||||
<icon height="114" src="res/ios/icon@2x.png" width="114" />
|
||||
<icon height="40" src="res/ios/icon-20@2x.png" width="40" />
|
||||
<icon height="60" src="res/ios/icon-20@3x.png" width="60" />
|
||||
<icon height="29" src="res/ios/icon-29.png" width="29" />
|
||||
<icon height="58" src="res/ios/icon-29@2x.png" width="58" />
|
||||
<icon height="87" src="res/ios/icon-29@3x.png" width="87" />
|
||||
<icon height="80" src="res/ios/icon-40@2x.png" width="80" />
|
||||
<icon height="120" src="res/ios/icon-60@2x.png" width="120" />
|
||||
<icon height="180" src="res/ios/icon-60@3x.png" width="180" />
|
||||
<icon height="20" src="res/ios/icon-20.png" width="20" />
|
||||
<icon height="40" src="res/ios/icon-40.png" width="40" />
|
||||
<icon height="50" src="res/ios/icon-50.png" width="50" />
|
||||
<icon height="100" src="res/ios/icon-50@2x.png" width="100" />
|
||||
<icon height="72" src="res/ios/icon-72.png" width="72" />
|
||||
<icon height="144" src="res/ios/icon-72@2x.png" width="144" />
|
||||
<icon height="76" src="res/ios/icon-76.png" width="76" />
|
||||
<icon height="152" src="res/ios/icon-76@2x.png" width="152" />
|
||||
<icon height="167" src="res/ios/icon-83.5@2x.png" width="167" />
|
||||
<icon height="1024" src="res/ios/icon-1024.png" width="1024" />
|
||||
<icon height="48" src="res/ios/icon-24@2x.png" width="48" />
|
||||
<icon height="55" src="res/ios/icon-27.5@2x.png" width="55" />
|
||||
<icon height="88" src="res/ios/icon-44@2x.png" width="88" />
|
||||
<icon height="172" src="res/ios/icon-86@2x.png" width="172" />
|
||||
<icon height="196" src="res/ios/icon-98@2x.png" width="196" />
|
||||
<splash src="res/screen/ios/Default@2x~iphone~anyany.png" />
|
||||
<splash src="res/screen/ios/Default@2x~iphone~comany.png" />
|
||||
<splash src="res/screen/ios/Default@2x~iphone~comcom.png" />
|
||||
<splash src="res/screen/ios/Default@3x~iphone~anyany.png" />
|
||||
<splash src="res/screen/ios/Default@3x~iphone~anycom.png" />
|
||||
<splash src="res/screen/ios/Default@3x~iphone~comany.png" />
|
||||
<splash src="res/screen/ios/Default@2x~ipad~anyany.png" />
|
||||
<splash src="res/screen/ios/Default@2x~ipad~comany.png" />
|
||||
</platform>
|
||||
<allow-navigation href="about:*" />
|
||||
<preference name="SplashMaintainAspectRatio" value="true" />
|
||||
</widget>
|
File diff suppressed because it is too large
Load Diff
|
@ -1,31 +0,0 @@
|
|||
{
|
||||
"name": "de.wu5.flaschengeist",
|
||||
"displayName": "Flaschengeist",
|
||||
"version": "1.0.0",
|
||||
"description": "A sample Apache Cordova application that responds to the deviceready event.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"ecosystem:cordova"
|
||||
],
|
||||
"author": "Apache Cordova Team",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"cordova-android": "^9.0.0",
|
||||
"cordova-ios": "^6.1.1",
|
||||
"cordova-plugin-splashscreen": "^6.0.0",
|
||||
"cordova-plugin-whitelist": "^1.3.4"
|
||||
},
|
||||
"cordova": {
|
||||
"plugins": {
|
||||
"cordova-plugin-whitelist": {},
|
||||
"cordova-plugin-splashscreen": {}
|
||||
},
|
||||
"platforms": [
|
||||
"ios",
|
||||
"android"
|
||||
]
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,4 @@
|
|||
import { useMainStore, api } from '@flaschengeist/api';
|
||||
import { LocalStorage, Notify } from 'quasar';
|
||||
import { AxiosError } from 'axios';
|
||||
import { boot } from 'quasar/wrappers';
|
||||
import config from 'src/config';
|
||||
|
@ -31,7 +30,8 @@ function minify(o: unknown, cloned = false) {
|
|||
}
|
||||
|
||||
export default boot(({ router }) => {
|
||||
api.defaults.baseURL = LocalStorage.getItem<string>('baseURL') || config.baseURL;
|
||||
// Persisted value is read in plugins.ts boot file!
|
||||
api.defaults.baseURL = config.baseURL;
|
||||
|
||||
/***
|
||||
* Intercept requests
|
||||
|
@ -95,17 +95,3 @@ export default boot(({ router }) => {
|
|||
});
|
||||
|
||||
export { api };
|
||||
|
||||
export const setBaseURL = (url: string) => {
|
||||
LocalStorage.set('baseURL', url);
|
||||
api.defaults.baseURL = url;
|
||||
Notify.create({
|
||||
message: 'Serveraddresse gespeichert',
|
||||
position: 'bottom',
|
||||
caption: `${url}`,
|
||||
color: 'positive',
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 5000);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Notify } from 'quasar';
|
||||
import { Notify, Platform } from 'quasar';
|
||||
import { api } from 'src/boot/axios';
|
||||
import { boot } from 'quasar/wrappers';
|
||||
import routes from 'src/router/routes';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
import { FG_Plugin } from '@flaschengeist/types';
|
||||
import { PersistentStorage } from '@flaschengeist/api';
|
||||
|
||||
/****************************************************
|
||||
******** Internal area for some magic **************
|
||||
|
@ -264,16 +264,24 @@ function loadPlugin(
|
|||
return true;
|
||||
}
|
||||
|
||||
async function loadBaseUrl() {
|
||||
return PersistentStorage.get<string>('baseURL').then((url) => {
|
||||
if (url !== null) api.defaults.baseURL = url;
|
||||
console.log('loaded: ', url, api.defaults.baseURL);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Loading backend information
|
||||
* @returns Backend object or null
|
||||
*/
|
||||
async function getBackend() {
|
||||
try {
|
||||
const { data }: AxiosResponse<Backend> = await api.get('/');
|
||||
const { data } = await api.get<Backend>('/');
|
||||
if (!data || typeof data !== 'object' || !('plugins' in data))
|
||||
throw Error('Invalid backend response received');
|
||||
return data;
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
console.error('Loading backend', e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -282,10 +290,13 @@ async function getBackend() {
|
|||
* Boot file, load all required plugins, check for dependencies
|
||||
*/
|
||||
export default boot(async ({ router, app }) => {
|
||||
await loadBaseUrl();
|
||||
const backend = await getBackend();
|
||||
if (!backend || typeof backend !== 'object' || !('plugins' in backend)) {
|
||||
console.log('Backend error');
|
||||
router.isReady().finally(() => void router.push({ name: 'offline', params: { refresh: 1 } }));
|
||||
if (backend === null) {
|
||||
router.isReady().finally(() => {
|
||||
if (Platform.is.capacitor) void router.push({ name: 'setup_backend' });
|
||||
else void router.push({ name: 'offline', params: { refresh: 1 } });
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
import { useMainStore, pinia } from '@flaschengeist/api';
|
||||
import { saveToken } from 'app/api';
|
||||
import { boot } from 'quasar/wrappers';
|
||||
|
||||
export default boot(({ app }) => {
|
||||
app.use(pinia);
|
||||
|
||||
const store = useMainStore();
|
||||
void store.init();
|
||||
store.init().finally(() => {
|
||||
store.$subscribe((mutation, state) => {
|
||||
saveToken(state.session?.token);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<div class="row justify-center items-center content-center q-pa-md">
|
||||
<q-card class="col-xs-11 col-sm-8 col-md-6 col-lg-4 justify-center items-center content-center">
|
||||
<q-toolbar class="bg-primary text-white">
|
||||
<q-toolbar-title>Servereinstellung</q-toolbar-title>
|
||||
</q-toolbar>
|
||||
<q-card-section>
|
||||
<q-form class="q-gutter-md" @submit="changeUrl">
|
||||
<q-input v-model="server" filled label="Server" dense />
|
||||
<q-btn dense color="primary" label="Speichern" type="submit" />
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useRouter } from 'vue-router';
|
||||
import { notEmpty, PersistentStorage } from '@flaschengeist/api';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { api } from 'boot/axios';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PageBackend',
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
|
||||
const server = ref(api.defaults.baseURL);
|
||||
|
||||
function changeUrl() {
|
||||
if (server.value) {
|
||||
void PersistentStorage.set('baseURL', server.value).then(() => {
|
||||
console.log('uiuiui');
|
||||
void router.push({ name: 'login' }).then(() => router.go(0));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
changeUrl,
|
||||
notEmpty,
|
||||
server,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -44,25 +44,13 @@
|
|||
</q-card-section>
|
||||
<div class="row justify-end">
|
||||
<q-btn
|
||||
v-if="quasar.platform.is.cordova || quasar.platform.is.electron"
|
||||
v-if="$q.platform.is.capacitor || $q.platform.is.electron"
|
||||
flat
|
||||
round
|
||||
icon="mdi-menu-down"
|
||||
@click="openServerSettings"
|
||||
:to="{ name: 'setup_backend' }"
|
||||
/>
|
||||
</div>
|
||||
<q-slide-transition v-if="quasar.platform.is.cordova || quasar.platform.is.electron">
|
||||
<div v-show="visible">
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<q-form ref="ServerSettingsForm" class="q-gutter-md" @submit="changeUrl">
|
||||
<div class="text-h6">Servereinstellung</div>
|
||||
<q-input v-model="server" filled label="Server" dense />
|
||||
<q-btn size="xs" dense color="primary" label="Speichern" type="submit" />
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</div>
|
||||
</q-slide-transition>
|
||||
</q-card>
|
||||
</q-page>
|
||||
</template>
|
||||
|
@ -73,34 +61,20 @@ import { Loading, Notify } from 'quasar';
|
|||
import { notEmpty, useMainStore, useUserStore } from '@flaschengeist/api';
|
||||
import { PasswordInput } from '@flaschengeist/api/components';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { setBaseURL, api } from 'boot/axios';
|
||||
import { useQuasar } from 'quasar';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PageLogin',
|
||||
components: { PasswordInput },
|
||||
setup() {
|
||||
const mainRoute = { name: 'dashboard' };
|
||||
|
||||
const mainStore = useMainStore();
|
||||
const userStore = useUserStore();
|
||||
const mainRoute = { name: 'dashboard' };
|
||||
const router = useRouter();
|
||||
|
||||
/* Stuff for the real login page */
|
||||
const userid = ref('');
|
||||
const password = ref('');
|
||||
const server = ref<string | undefined>(api.defaults.baseURL);
|
||||
const visible = ref(false);
|
||||
const quasar = useQuasar();
|
||||
|
||||
function openServerSettings() {
|
||||
visible.value = !visible.value;
|
||||
}
|
||||
|
||||
function changeUrl() {
|
||||
if (server.value) {
|
||||
setBaseURL(server.value);
|
||||
}
|
||||
}
|
||||
|
||||
async function doLogin() {
|
||||
Loading.show({ message: 'Du wirst angemeldet' });
|
||||
|
@ -155,16 +129,11 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
return {
|
||||
changeUrl,
|
||||
doLogin,
|
||||
doReset,
|
||||
notEmpty,
|
||||
openServerSettings,
|
||||
password,
|
||||
server,
|
||||
userid,
|
||||
visible,
|
||||
quasar,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -53,6 +53,11 @@ const routes: RouteRecordRaw[] = [
|
|||
name: 'offline',
|
||||
component: () => import('pages/Offline.vue'),
|
||||
},
|
||||
{
|
||||
path: '/setup-backend',
|
||||
name: 'setup_backend',
|
||||
component: () => import('pages/Backend.vue'),
|
||||
},
|
||||
// Always leave this as last one,
|
||||
// but you can also remove it
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue