Add log view
This commit is contained in:
		| @@ -11,6 +11,7 @@ import { | ||||
|     showResourceSlotIds, | ||||
| } from './Page/SlotBlock'; | ||||
| import Vue from 'vue'; | ||||
| import Vuex from 'vuex'; | ||||
| import DashboardApp from './DashboardView/Dashboard.vue'; | ||||
| import { ResourcesToLevel } from './Task/ResourcesToLevel'; | ||||
| import { ConsoleLogger, Logger } from './Logger'; | ||||
| @@ -20,6 +21,9 @@ import { ExecutionStorage } from './Storage/ExecutionStorage'; | ||||
| import { VillageState, VillageStateRepository } from './VillageState'; | ||||
| import { Task } from './Queue/TaskProvider'; | ||||
| import { Action } from './Queue/ActionQueue'; | ||||
| import { createStore } from './DashboardView/Store'; | ||||
|  | ||||
| Vue.use(Vuex); | ||||
|  | ||||
| interface QuickAction { | ||||
|     label: string; | ||||
| @@ -160,6 +164,7 @@ export class ControlPanel { | ||||
|         new Vue({ | ||||
|             el: `#${appId}`, | ||||
|             data: gameState, | ||||
|             store: createStore(), | ||||
|             render: h => h(DashboardApp), | ||||
|         }); | ||||
|     } | ||||
|   | ||||
| @@ -1,13 +1,16 @@ | ||||
| <template> | ||||
|   <main id="dashboard"> | ||||
|     <div id="dashboard-inner"> | ||||
|     <section id="dashboard-primary"> | ||||
|       <hdr></hdr> | ||||
|       <village-state-list></village-state-list> | ||||
|       <village-state-list /> | ||||
|       <hr class="separator" /> | ||||
|       <quick-actions></quick-actions> | ||||
|       <quick-actions /> | ||||
|       <hr class="separator" /> | ||||
|       <task-list></task-list> | ||||
|     </div> | ||||
|       <task-list /> | ||||
|     </section> | ||||
|     <section id="dashboard-secondary"> | ||||
|       <log-list v-if="isLogsVisible" /> | ||||
|     </section> | ||||
|   </main> | ||||
| </template> | ||||
|  | ||||
| @@ -16,39 +19,56 @@ import Header from './Header'; | ||||
| import TaskList from './TaskList'; | ||||
| import QuickActions from './QuickActions'; | ||||
| import VillageStateList from './VillageStateList'; | ||||
| import LogList from './LogList'; | ||||
| import { mapState } from 'vuex'; | ||||
| export default { | ||||
|   components: { | ||||
|     'hdr': Header, | ||||
|     'task-list': TaskList, | ||||
|     'quick-actions': QuickActions, | ||||
|     'village-state-list': VillageStateList, | ||||
|     'log-list': LogList, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       shared: this.$root.$data, | ||||
|     }; | ||||
|   }, | ||||
|   computed: mapState({ | ||||
|     isLogsVisible: state => state.views.logs, | ||||
|   }), | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| #dashboard { | ||||
|   position: absolute; | ||||
|   display: block; | ||||
|   display: flex; | ||||
|   left: 0; | ||||
|   top: 0; | ||||
|   height: 100%; | ||||
|   width: 500px; | ||||
|   z-index: 9999; | ||||
|   /*overflow: hidden;*/ | ||||
|   box-sizing: border-box; | ||||
| } | ||||
| #dashboard * { | ||||
|   box-sizing: border-box; | ||||
| } | ||||
| #dashboard-inner { | ||||
| #dashboard-primary { | ||||
|   /*height: 100vh;*/ | ||||
|   /*overflow-y: scroll;*/ | ||||
|   background-color: white; | ||||
|   width: 500px; | ||||
|   padding: 5px; | ||||
| } | ||||
| #dashboard-secondary { | ||||
|   background-color: transparent; | ||||
|   max-width: 800px; | ||||
|   width: 800px; | ||||
|   margin-top: 120px; | ||||
|   padding-left: 10px; | ||||
| } | ||||
| #dashboard-secondary:empty { | ||||
|   display: none; | ||||
| } | ||||
| .separator { | ||||
|   margin: 10px auto; | ||||
| } | ||||
|   | ||||
							
								
								
									
										51
									
								
								src/DashboardView/LogList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/DashboardView/LogList.vue
									
									
									
									
									
										Normal 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> | ||||
							
								
								
									
										44
									
								
								src/DashboardView/Store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/DashboardView/Store.ts
									
									
									
									
									
										Normal 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; | ||||
| } | ||||
| @@ -69,9 +69,7 @@ export default { | ||||
|   margin-bottom: 0; | ||||
| } | ||||
| .container { | ||||
|   overflow-y: scroll; | ||||
|   overflow-x: hidden; | ||||
|   max-height: 300px; | ||||
| } | ||||
| .task-table { | ||||
|   width: 100%; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user