Allow login to multiple bots

This commit is contained in:
Matthias 2021-08-29 10:29:53 +02:00
parent acd702dab3
commit 0955c21082
7 changed files with 79 additions and 12 deletions

View File

@ -0,0 +1,29 @@
<template>
<div>
<h3>Available bots</h3>
<div v-for="bot in allAvailableBots" :key="bot">
{{ bot }}
</div>
<LoginModal login-text="Add new bot" />
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { namespace } from 'vuex-class';
import { MultiBotStoreGetters } from '@/store/modules/botStoreWrapper';
import LoginModal from '@/views/LoginModal.vue';
const ftbot = namespace('ftbot');
@Component({ components: { LoginModal } })
export default class BotList extends Vue {
@ftbot.Getter [MultiBotStoreGetters.allAvailableBots]: string[];
clickAddBot() {
//
}
}
</script>
<style scoped></style>

View File

@ -60,17 +60,23 @@
<script lang="ts">
import { Component, Vue, Emit, Prop } from 'vue-property-decorator';
import { Action } from 'vuex-class';
import userService from '@/shared/userService';
import { Action, namespace } from 'vuex-class';
import { useUserService } from '@/shared/userService';
import { AuthPayload } from '@/types';
import { MultiBotStoreGetters } from '@/store/modules/botStoreWrapper';
const defaultURL = window.location.origin || 'http://localhost:8080';
const ftbot = namespace('ftbot');
@Component({})
export default class Login extends Vue {
@Action setLoggedIn;
@ftbot.Getter [MultiBotStoreGetters.nextBotId]: string;
@ftbot.Action addBot;
@Prop({ default: false }) inModal!: boolean;
$refs!: {
@ -126,11 +132,12 @@ export default class Login extends Vue {
return;
}
this.errorMessage = '';
const userService = useUserService(this.nextBotId);
// Push the name to submitted names
userService
.login(this.auth)
.then(() => {
this.setLoggedIn(true);
this.addBot(this.nextBotId);
// TODO: Investigate how this needs to be done properly
// setBaseUrl(userService.getAPIUrl());

View File

@ -17,7 +17,7 @@ export class UserService {
* Stores info for current botId in the object of all bots.
*/
private storeLoginInfo(loginInfo: AuthStorage): void {
const allInfo = this.getAllLoginInfos();
const allInfo = UserService.getAllLoginInfos();
allInfo[this.botId] = loginInfo;
localStorage.setItem(AUTH_LOGIN_INFO, JSON.stringify(allInfo));
}
@ -26,7 +26,7 @@ export class UserService {
* Logout - removing info for this particular bot.
*/
private removeLoginInfo(): void {
const info = this.getAllLoginInfos();
const info = UserService.getAllLoginInfos();
delete info[this.botId];
localStorage.setItem(AUTH_LOGIN_INFO, JSON.stringify(info));
}
@ -41,7 +41,7 @@ export class UserService {
* Retrieve full logininfo object (for all registered bots)
* @returns
*/
private getAllLoginInfos(): AuthStorageMulti {
private static getAllLoginInfos(): AuthStorageMulti {
const info = JSON.parse(localStorage.getItem(AUTH_LOGIN_INFO) || '{}');
return info;
}
@ -51,7 +51,7 @@ export class UserService {
* @returns Login Info object
*/
private getLoginInfo(): AuthStorage {
const info = this.getAllLoginInfos();
const info = UserService.getAllLoginInfos();
if (this.botId in info && 'apiUrl' in info[this.botId] && 'refreshToken' in info[this.botId]) {
return info[this.botId];
}
@ -62,6 +62,11 @@ export class UserService {
};
}
public static getAvailableBotList(): string[] {
const allInfo = UserService.getAllLoginInfos();
return Object.keys(allInfo);
}
public getAccessToken(): string {
return this.getLoginInfo().accessToken;
}
@ -183,4 +188,4 @@ export function useUserService(botId: string) {
return userservice;
}
export default useUserService('ftbot.0');
// export default useUserService('ftbot.0');

View File

@ -3,6 +3,7 @@ import Vuex from 'vuex';
import { getCurrentTheme, getTheme, storeCurrentTheme } from '@/shared/themes';
import axios, { AxiosInstance } from 'axios';
import { UserService } from '@/shared/userService';
import createBotStore from './modules/botStoreWrapper';
import { BotStoreGetters } from './modules/ftbot';
import alertsModule from './modules/alerts';
@ -142,5 +143,7 @@ const store = new Vuex.Store({
});
store.registerModule('ftbot', createBotStore(store));
store.dispatch('ftbot/addBot', 'ftbot.0');
UserService.getAvailableBotList().forEach((e) => {
store.dispatch('ftbot/addBot', e);
});
export default store;

View File

@ -9,6 +9,7 @@ export enum MultiBotStoreGetters {
hasBots = 'hasBots',
selectedBot = 'selectedBot',
allAvailableBots = 'allAvailableBots',
nextBotId = 'nextBotId',
}
export default function createBotStore(store) {
@ -28,6 +29,13 @@ export default function createBotStore(store) {
[MultiBotStoreGetters.allAvailableBots](state: FTMultiBotState): string[] {
return state.availableBots;
},
[MultiBotStoreGetters.nextBotId](state: FTMultiBotState): string {
let botCount = state.availableBots.length;
while (`ftbot.${botCount}` in state.availableBots) {
botCount += 1;
}
return `ftbot.${botCount}`;
},
};
// Autocreate getters
Object.keys(BotStoreGetters).forEach((e) => {
@ -37,6 +45,13 @@ export default function createBotStore(store) {
});
const mutations = {
selectBot(state: FTMultiBotState, botId: string) {
if (botId in state.availableBots) {
state.selectedBot = botId;
} else {
console.warn(`Botid ${botId} not available, but selected`);
}
},
addBot(state: FTMultiBotState, botId: string) {
state.availableBots = [...state.availableBots, botId];
},

View File

@ -1,5 +1,7 @@
<template>
<div class="home">
<bot-list />
<hr />
<!-- <img alt="Freqtrade logo" src="../assets/freqtrade-logo.png" width="450px" class="my-5" /> -->
<div alt="Freqtrade logo" class="logo-svg my-5 mx-auto" />
<div>
@ -19,7 +21,11 @@
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
import BotList from '@/components/BotList.vue';
@Component({
components: { BotList },
})
export default class Home extends Vue {}
</script>

View File

@ -1,6 +1,6 @@
<template>
<div>
<b-button v-b-modal.modal-prevent-closing>Login</b-button>
<b-button v-b-modal.modal-prevent-closing>{{ loginText }}</b-button>
<b-modal id="modal-prevent-closing" ref="modal" title="Submit Your Name" @ok="handleOk">
<Login id="loginForm" ref="loginForm" in-modal />
</b-modal>
@ -8,7 +8,7 @@
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { Component, Prop, Vue } from 'vue-property-decorator';
import Login from '@/components/Login.vue';
@ -20,6 +20,8 @@ export default class LoginModal extends Vue {
loginForm: HTMLFormElement;
};
@Prop({ required: false, default: 'Login', type: String }) loginText!: string;
resetLogin() {
// this.$refs.loginForm.resetLogin();
}