Store botlist as objects, not string list

This commit is contained in:
Matthias 2021-08-29 13:54:45 +02:00
parent f346f49e60
commit 1c4e2aed54
6 changed files with 67 additions and 36 deletions

View File

@ -4,12 +4,12 @@
<b-list-group>
<b-list-group-item
v-for="bot in allAvailableBots"
:key="bot"
:key="bot.botId"
button
:active="bot === selectedBot"
@click="selectBot(bot)"
:active="bot.botId === selectedBot"
@click="selectBot(bot.botId)"
>
{{ bot }}
{{ bot.botName || bot.botId }}
<b-button class="btn-xs ml-1" size="sm" title="Delete trade" @click="clickRemoveBot(bot)">
<EditIcon :size="16" title="Delete trade" />
</b-button>
@ -29,6 +29,7 @@ import { MultiBotStoreGetters } from '@/store/modules/botStoreWrapper';
import LoginModal from '@/views/LoginModal.vue';
import EditIcon from 'vue-material-design-icons/Cog.vue';
import DeleteIcon from 'vue-material-design-icons/Delete.vue';
import { BotDescriptor, BotDescriptors } from '@/types';
const ftbot = namespace('ftbot');
@ -36,17 +37,17 @@ const ftbot = namespace('ftbot');
export default class BotList extends Vue {
@ftbot.Getter [MultiBotStoreGetters.selectedBot]: string;
@ftbot.Getter [MultiBotStoreGetters.allAvailableBots]: string[];
@ftbot.Getter [MultiBotStoreGetters.allAvailableBots]: BotDescriptors;
@ftbot.Action removeBot;
@ftbot.Action selectBot;
clickRemoveBot(botId) {
clickRemoveBot(botId: BotDescriptor) {
//
this.$bvModal.msgBoxConfirm(`Really remove (logout) from ${botId}?`).then((value: boolean) => {
if (value) {
this.removeBot(botId);
this.removeBot(botId.botId);
}
});
}

View File

@ -73,7 +73,7 @@ import { Component, Vue, Emit, Prop } from 'vue-property-decorator';
import { Action, namespace } from 'vuex-class';
import { useUserService } from '@/shared/userService';
import { AuthPayload } from '@/types';
import { AuthPayload, BotDescriptor } from '@/types';
import { MultiBotStoreGetters } from '@/store/modules/botStoreWrapper';
const defaultURL = window.location.origin || 'http://localhost:8080';
@ -85,7 +85,8 @@ export default class Login extends Vue {
@ftbot.Getter [MultiBotStoreGetters.nextBotId]: string;
@ftbot.Action addBot;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@ftbot.Action addBot!: (payload: BotDescriptor) => void;
@Prop({ default: false }) inModal!: boolean;
@ -148,7 +149,10 @@ export default class Login extends Vue {
userService
.login(this.auth)
.then(() => {
this.addBot(this.nextBotId);
this.addBot({
botName: this.auth.botName,
botId: this.nextBotId,
});
// TODO: Investigate how this needs to be done properly
// setBaseUrl(userService.getAPIUrl());

View File

@ -1,6 +1,6 @@
import axios from 'axios';
import { AuthPayload, AuthStorage, AuthStorageMulti } from '@/types';
import { AuthPayload, BotDescriptors, AuthStorage, AuthStorageMulti } from '@/types';
const AUTH_LOGIN_INFO = 'auth_login_info';
const APIBASE = '/api/v1';
@ -63,6 +63,18 @@ export class UserService {
};
}
public static getAvailableBots(): BotDescriptors {
const allInfo = UserService.getAllLoginInfos();
const response: BotDescriptors = {};
Object.entries(allInfo).forEach(([k, v]) => {
response[k] = {
botId: k,
botName: v.botName,
};
});
return response;
}
public static getAvailableBotList(): string[] {
const allInfo = UserService.getAllLoginInfos();
return Object.keys(allInfo);
@ -158,6 +170,7 @@ export class UserService {
* Call on startup to migrate old login info to new login
*/
public migrateLogin() {
// TODO: this is actually never called!
const AUTH_REFRESH_TOKEN = 'auth_ref_token'; // Legacy key - do not use
const AUTH_ACCESS_TOKEN = 'auth_access_token';
const AUTH_API_URL = 'auth_api_url';

View File

@ -143,8 +143,8 @@ const store = new Vuex.Store({
});
store.registerModule('ftbot', createBotStore(store));
UserService.getAvailableBotList().forEach((e) => {
store.dispatch('ftbot/addBot', e);
Object.entries(UserService.getAvailableBots()).forEach(([k, v]) => {
store.dispatch('ftbot/addBot', v);
});
store.dispatch('ftbot/selectFirstBot');
export default store;

View File

@ -1,8 +1,9 @@
import { BotDescriptor, BotDescriptors } from '@/types';
import { BotStoreActions, BotStoreGetters, createBotSubStore } from './ftbot';
interface FTMultiBotState {
selectedBot: string;
availableBots: string[];
availableBots: BotDescriptors;
}
export enum MultiBotStoreGetters {
@ -15,29 +16,30 @@ export enum MultiBotStoreGetters {
export default function createBotStore(store) {
const state: FTMultiBotState = {
selectedBot: '',
availableBots: [],
availableBots: {},
};
// All getters working on all bots should be prefixed with all.
const getters = {
[MultiBotStoreGetters.hasBots](state: FTMultiBotState): boolean {
return state.availableBots.length > 0;
return Object.keys(state.availableBots).length > 0;
},
[MultiBotStoreGetters.selectedBot](state: FTMultiBotState): string {
return state.selectedBot;
},
[MultiBotStoreGetters.allAvailableBots](state: FTMultiBotState): string[] {
[MultiBotStoreGetters.allAvailableBots](state: FTMultiBotState): BotDescriptors {
return state.availableBots;
},
[MultiBotStoreGetters.nextBotId](state: FTMultiBotState): string {
let botCount = state.availableBots.length;
while (state.availableBots.includes(`ftbot.${botCount}`)) {
let botCount = Object.keys(state.availableBots).length;
while (`ftbot.${botCount}` in state.availableBots) {
botCount += 1;
}
return `ftbot.${botCount}`;
},
};
// Autocreate getters
// Autocreate getters from botStores
Object.keys(BotStoreGetters).forEach((e) => {
getters[e] = (state, getters) => {
return getters[`${state.selectedBot}/${e}`];
@ -46,37 +48,37 @@ export default function createBotStore(store) {
const mutations = {
selectBot(state: FTMultiBotState, botId: string) {
if (state.availableBots.includes(botId)) {
if (botId in state.availableBots) {
state.selectedBot = botId;
} else {
console.warn(`Botid ${botId} not available, but selected`);
console.warn(`Botid ${botId} not available, but selected.`);
}
},
addBot(state: FTMultiBotState, botId: string) {
state.availableBots = [...state.availableBots, botId];
addBot(state: FTMultiBotState, bot: BotDescriptor) {
state.availableBots[bot.botId] = bot;
},
removeBot(state: FTMultiBotState, botId: string) {
const index = state.availableBots.indexOf(botId);
if (index > -1) {
state.availableBots.splice(index, 1);
state.availableBots = [...state.availableBots];
if (botId in state.availableBots) {
delete state.availableBots[botId];
}
},
};
const actions = {
// Actions automatically filled below
addBot({ getters, commit }, botId: string) {
if (getters.allAvailableBots.includes(botId)) {
addBot({ getters, commit }, bot: BotDescriptor) {
if (Object.keys(getters.allAvailableBots).includes(bot.botId)) {
// throw 'Bot already present';
// TODO: handle error!
console.log('Bot already present');
return;
}
console.log('add bot', botId);
store.registerModule(['ftbot', botId], createBotSubStore(botId));
commit('addBot', botId);
console.log('add bot', bot);
store.registerModule(['ftbot', bot.botId], createBotSubStore(bot.botId));
commit('addBot', bot);
},
removeBot({ commit, getters, dispatch }, botId: string) {
if (getters.allAvailableBots.includes(botId)) {
if (Object.keys(getters.allAvailableBots).includes(botId)) {
dispatch(`${botId}/logout`);
store.unregisterModule([`ftbot`, botId]);
commit('removeBot', botId);
@ -86,14 +88,16 @@ export default function createBotStore(store) {
},
selectFirstBot({ commit, getters }) {
if (getters.hasBots) {
commit('selectBot', getters.allAvailableBots[0]);
const firstBot = Object.keys(getters.allAvailableBots)[0];
console.log(firstBot);
commit('selectBot', getters.allAvailableBots[firstBot].botId);
}
},
selectBot({ commit }, botId: string) {
commit('selectBot', botId);
},
};
// Autocreate Actions
// Autocreate Actions from botstores
Object.keys(BotStoreActions).forEach((e) => {
actions[e] = ({ state, dispatch, getters }, ...args) => {
if (getters.hasBots) {

View File

@ -15,3 +15,12 @@ export interface AuthStorage {
export interface AuthStorageMulti {
[key: string]: AuthStorage;
}
export interface BotDescriptor {
botName: string;
botId: string;
}
export interface BotDescriptors {
[key: string]: BotDescriptor;
}