Add log view

This commit is contained in:
Anton Vakhrushev 2020-05-16 11:45:35 +03:00
parent f1e05bc936
commit 40d723b29e
5 changed files with 130 additions and 12 deletions

View File

@ -11,6 +11,7 @@ import {
showResourceSlotIds, showResourceSlotIds,
} from './Page/SlotBlock'; } from './Page/SlotBlock';
import Vue from 'vue'; import Vue from 'vue';
import Vuex from 'vuex';
import DashboardApp from './DashboardView/Dashboard.vue'; import DashboardApp from './DashboardView/Dashboard.vue';
import { ResourcesToLevel } from './Task/ResourcesToLevel'; import { ResourcesToLevel } from './Task/ResourcesToLevel';
import { ConsoleLogger, Logger } from './Logger'; import { ConsoleLogger, Logger } from './Logger';
@ -20,6 +21,9 @@ import { ExecutionStorage } from './Storage/ExecutionStorage';
import { VillageState, VillageStateRepository } from './VillageState'; import { VillageState, VillageStateRepository } from './VillageState';
import { Task } from './Queue/TaskProvider'; import { Task } from './Queue/TaskProvider';
import { Action } from './Queue/ActionQueue'; import { Action } from './Queue/ActionQueue';
import { createStore } from './DashboardView/Store';
Vue.use(Vuex);
interface QuickAction { interface QuickAction {
label: string; label: string;
@ -160,6 +164,7 @@ export class ControlPanel {
new Vue({ new Vue({
el: `#${appId}`, el: `#${appId}`,
data: gameState, data: gameState,
store: createStore(),
render: h => h(DashboardApp), render: h => h(DashboardApp),
}); });
} }

View File

@ -1,13 +1,16 @@
<template> <template>
<main id="dashboard"> <main id="dashboard">
<div id="dashboard-inner"> <section id="dashboard-primary">
<hdr></hdr> <hdr></hdr>
<village-state-list></village-state-list> <village-state-list />
<hr class="separator" /> <hr class="separator" />
<quick-actions></quick-actions> <quick-actions />
<hr class="separator" /> <hr class="separator" />
<task-list></task-list> <task-list />
</div> </section>
<section id="dashboard-secondary">
<log-list v-if="isLogsVisible" />
</section>
</main> </main>
</template> </template>
@ -16,39 +19,56 @@ import Header from './Header';
import TaskList from './TaskList'; import TaskList from './TaskList';
import QuickActions from './QuickActions'; import QuickActions from './QuickActions';
import VillageStateList from './VillageStateList'; import VillageStateList from './VillageStateList';
import LogList from './LogList';
import { mapState } from 'vuex';
export default { export default {
components: { components: {
'hdr': Header, 'hdr': Header,
'task-list': TaskList, 'task-list': TaskList,
'quick-actions': QuickActions, 'quick-actions': QuickActions,
'village-state-list': VillageStateList, 'village-state-list': VillageStateList,
'log-list': LogList,
}, },
data() { data() {
return { return {
shared: this.$root.$data, shared: this.$root.$data,
}; };
}, },
computed: mapState({
isLogsVisible: state => state.views.logs,
}),
}; };
</script> </script>
<style scoped> <style scoped>
#dashboard { #dashboard {
position: absolute; position: absolute;
display: block; display: flex;
left: 0; left: 0;
top: 0; top: 0;
height: 100%;
width: 500px;
z-index: 9999; z-index: 9999;
/*overflow: hidden;*/ box-sizing: border-box;
} }
#dashboard * { #dashboard * {
box-sizing: border-box; box-sizing: border-box;
} }
#dashboard-inner { #dashboard-primary {
/*height: 100vh;*/
/*overflow-y: scroll;*/
background-color: white; background-color: white;
width: 500px;
padding: 5px; padding: 5px;
} }
#dashboard-secondary {
background-color: transparent;
max-width: 800px;
width: 800px;
margin-top: 120px;
padding-left: 10px;
}
#dashboard-secondary:empty {
display: none;
}
.separator { .separator {
margin: 10px auto; margin: 10px auto;
} }

View File

@ -0,0 +1,51 @@
<template>
<section class="log-list">
<p><strong>Logs</strong>, <a href="#" v-on:click.prevent="close">close</a></p>
<table class="log-table">
<tr v-for="record in logs" class="log-record">
<td v-text="record.level"></td>
<td v-text="formatDate(record.ts)"></td>
<td v-text="record.message"></td>
</tr>
</table>
</section>
</template>
<script>
import { mapGetters } from 'vuex';
import * as dateFormat from 'dateformat';
import { Mutations } from './Store';
export default {
computed: {
...mapGetters({
logs: 'reverseLogs',
}),
},
methods: {
formatDate(ts) {
const d = new Date(ts * 1000);
return dateFormat(d, 'HH:MM:ss');
},
close() {
this.$store.commit(Mutations.hideLogs);
},
},
};
</script>
<style scoped>
.log-list {
background-color: white;
}
.log-table {
width: 100%;
border-collapse: collapse;
margin: 6px auto 0;
}
.log-record > td {
border-top: 1px solid #ddd;
border-left: 1px solid #ddd;
padding: 2px 4px;
}
</style>

View File

@ -0,0 +1,44 @@
import Vuex from 'vuex';
import { StorageLogRecord } from '../Logger';
import { LogStorage } from '../Storage/LogStorage';
export enum Mutations {
showLogs = 'showLogs',
hideLogs = 'hideLogs',
updateLogs = 'updateLogs',
}
export function createStore() {
const store = new Vuex.Store({
state: {
views: {
logs: false,
},
logs: [],
},
mutations: {
[Mutations.showLogs](state) {
state.views.logs = true;
},
[Mutations.hideLogs](state) {
state.views.logs = false;
},
[Mutations.updateLogs](state, { logs }) {
state.logs = logs;
},
},
getters: {
reverseLogs: state => {
return state.logs.slice().reverse();
},
},
});
setInterval(() => {
const logStorage = new LogStorage();
const logs = logStorage.getRecords();
store.commit(Mutations.updateLogs, { logs });
}, 1000);
return store;
}

View File

@ -69,9 +69,7 @@ export default {
margin-bottom: 0; margin-bottom: 0;
} }
.container { .container {
overflow-y: scroll;
overflow-x: hidden; overflow-x: hidden;
max-height: 300px;
} }
.task-table { .task-table {
width: 100%; width: 100%;