Statystyki DR (wip)

This commit is contained in:
2023-12-16 17:49:54 +01:00
parent e0d3d2585d
commit f4be32aa39
8 changed files with 120 additions and 193 deletions
@@ -1,64 +1,51 @@
<template> <template>
<div class="stats_container" v-click-outside="() => (cardVisible = false)"> <div
<button class="stats_button" @click="toggleCard"> class="journal-stats dispatcher"
Statystyki dyżurnego {{ store.dispatcherStatsName }} v-if="store.dispatcherStatsName && store.dispatcherStatsData"
</button> >
<span class="loading" v-if="!store.dispatcherStatsData._count._all">
Ten dyżurny nie ma jeszcze szczegółowych statystyk!
</span>
<div class="stats_card" v-if="store.dispatcherStatsName && cardVisible"> <span v-else>
<div> <h3>
<Loading v-if="!store.dispatcherStatsData" /> <i18n-t keypath="journal.dispatcher-stats-title">
<template #name>
<span class="text--primary">{{ store.dispatcherStatsName.toUpperCase() }}</span>
</template>
</i18n-t>
</h3>
<div class="loading" v-else-if="!store.dispatcherStatsData._count._all"> <hr class="header-separator" />
Ten dyżurny nie ma jeszcze szczegółowych statystyk!
</div>
<div v-else> <div class="info-stats" v-if="store.dispatcherStatsData._count._all">
<h3>STATYSTYKI WYSTAWIONYCH ROZKŁADÓW</h3> <span class="stat-badge">
<span>LICZBA</span>
<div class="info-stats" v-if="store.dispatcherStatsData._count._all"> <span>{{ store.dispatcherStatsData._count._all }}</span>
<span class="stat-badge"> </span>
<span>LICZBA</span> <span class="stat-badge">
<span>{{ store.dispatcherStatsData._count._all }}</span> <span>SUMA (KM)</span>
</span> <span>{{ store.dispatcherStatsData._sum.routeDistance.toFixed(2) }}km</span>
<span class="stat-badge"> </span>
<span>SUMA (KM)</span> <span class="stat-badge">
<span>{{ store.dispatcherStatsData._sum.routeDistance.toFixed(2) }}km</span> <span>NAJDŁUŻSZY</span>
</span> <span>{{ store.dispatcherStatsData._max.routeDistance.toFixed(2) }}km</span>
<span class="stat-badge"> </span>
<span>NAJDŁUŻSZY</span> <span class="stat-badge">
<span>{{ store.dispatcherStatsData._max.routeDistance.toFixed(2) }}km</span> <span>ŚREDNIO</span>
</span> <span>{{ store.dispatcherStatsData._avg.routeDistance.toFixed(2) }}km</span>
<span class="stat-badge"> </span>
<span>ŚREDNIO</span>
<span>{{ store.dispatcherStatsData._avg.routeDistance.toFixed(2) }}km</span>
</span>
</div>
<h3>OSTATNIE WYSTAWIONE ROZKŁADY</h3>
<div class="last-timetables">
<div class="timetable-row" v-for="timetable in timetables" :key="timetable.id">
#{{ timetable.timetableId }} |
<b>{{ timetable.trainCategoryCode }} {{ timetable.trainNo }}</b> |
{{ timetable.driverName }} ({{ timetable.routeDistance }}km)
<div>{{ timetable.route.replace('|', ' > ') }}</div>
</div>
</div>
</div>
</div> </div>
</div> </span>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { useMainStore } from '../../store/mainStore'; import { useMainStore } from '../../store/mainStore';
import Loading from '../Global/Loading.vue';
import { API } from '../../typings/api';
import http from '../../http';
export default defineComponent({ export default defineComponent({
name: 'journal-dispatcher-stats', name: 'journal-dispatcher-stats',
components: { Loading },
setup() { setup() {
const store = useMainStore(); const store = useMainStore();
@@ -66,96 +53,10 @@ export default defineComponent({
return { return {
store store
}; };
},
data() {
return {
cardVisible: false,
lastDispatcherName: '',
timetables: [] as API.TimetableHistory.Response
};
},
methods: {
toggleCard() {
if (!this.store.dispatcherStatsName) return;
this.cardVisible = !this.cardVisible;
if (this.cardVisible) this.fetchDispatcherStats();
},
async fetchDispatcherStats() {
if (this.lastDispatcherName != this.store.dispatcherStatsName) {
this.store.dispatcherStatsData = undefined;
}
const statsData: API.DispatcherStats.Response = await (
await http.get('api/getDispatcherInfo?name=${this.store.dispatcherStatsName}')
).data;
const timetables: API.TimetableHistory.Response = await (
await http.get('api/getTimetables?authorName=${this.store.dispatcherStatsName}')
).data;
this.timetables = timetables;
this.store.dispatcherStatsData = statsData;
this.lastDispatcherName = this.store.dispatcherStatsName;
}
} }
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../../styles/responsive.scss'; @import '../../styles/JournalStats.scss';
@import '../../styles/variables.scss';
.stats_container {
position: relative;
}
.stats_card {
position: absolute;
z-index: 999;
top: 120%;
right: 0;
width: 500px;
max-width: 97vw;
min-height: 100px;
overflow: auto;
border-radius: 1em 0 1em 1em;
background-color: #222222f1;
box-shadow: 0 3px 10px 5px #131313;
padding: 1em 0.5em;
}
.last-timetables {
max-height: 400px;
margin: 0.5em 0;
}
.timetable-row {
width: 95%;
margin: 0.5em auto;
padding: 0.5em;
background-color: #4d4d4d;
}
h2.card-title {
font-size: 1.8em;
}
h3 {
margin-top: 1em;
}
h2,
h3 {
text-align: center;
}
.last-timetables {
overflow-y: auto;
}
</style> </style>
@@ -1,9 +1,12 @@
<template> <template>
<div class="journal-stats" v-if="store.driverStatsData"> <div class="journal-stats driver" v-if="store.driverStatsData">
<span> <span>
<h3> <h3>
{{ $t('journal.stats-title') }} <i18n-t keypath="journal.driver-stats-title">
<span class="text--primary">{{ store.driverStatsName.toUpperCase() }}</span> <template #name>
<span class="text--primary">{{ store.driverStatsName.toUpperCase() }}</span>
</template>
</i18n-t>
</h3> </h3>
<hr class="header-separator" /> <hr class="header-separator" />
@@ -114,7 +114,6 @@ import { defineComponent, inject, PropType } from 'vue';
import keyMixin from '../../mixins/keyMixin'; import keyMixin from '../../mixins/keyMixin';
import { useMainStore } from '../../store/mainStore'; import { useMainStore } from '../../store/mainStore';
import { Journal } from './typings'; import { Journal } from './typings';
import { API } from '../../typings/api';
import { Status } from '../../typings/common'; import { Status } from '../../typings/common';
import http from '../../http'; import http from '../../http';
@@ -181,10 +180,6 @@ export default defineComponent({
}, },
watch: { watch: {
async 'store.driverStatsName'() {
await this.fetchDriverStats();
},
async 'searchersValues.search-driver'(value: string | undefined) { async 'searchersValues.search-driver'(value: string | undefined) {
clearTimeout(this.searchTimeout); clearTimeout(this.searchTimeout);
@@ -203,29 +198,6 @@ export default defineComponent({
}, },
methods: { methods: {
async fetchDriverStats() {
this.store.driverStatsData = undefined;
if (!this.store.driverStatsName) {
this.store.driverStatsStatus = Status.Data.Initialized;
return;
}
try {
this.store.driverStatsStatus = Status.Data.Loading;
const statsData: API.DriverStats.Response = await (
await http.get(`api/getDriverInfo?name=${this.store.driverStatsName}`)
).data;
this.store.driverStatsData = statsData;
this.store.driverStatsStatus = Status.Data.Loaded;
} catch (error) {
this.store.driverStatsStatus = Status.Data.Error;
console.error('Ups! Wystąpił błąd przy próbie pobrania statystyk maszynisty! :/');
}
},
refreshData() { refreshData() {
this.$emit('onRefreshData'); this.$emit('onRefreshData');
}, },
+59 -12
View File
@@ -47,6 +47,9 @@ import { Journal } from './typings';
import JournalDailyStats from './JournalDailyStats.vue'; import JournalDailyStats from './JournalDailyStats.vue';
import JournalDispatcherStats from './JournalDispatcherStats.vue'; import JournalDispatcherStats from './JournalDispatcherStats.vue';
import JournalDriverStats from './JournalDriverStats.vue'; import JournalDriverStats from './JournalDriverStats.vue';
import { Status } from '../../typings/common';
import http from '../../http';
import { API } from '../../typings/api';
export default defineComponent({ export default defineComponent({
components: { JournalDailyStats, JournalDriverStats, JournalDispatcherStats }, components: { JournalDailyStats, JournalDriverStats, JournalDispatcherStats },
@@ -63,24 +66,68 @@ export default defineComponent({
currentStatsTab: null as Journal.StatsTab | null currentStatsTab: null as Journal.StatsTab | null
}; };
}, },
mounted() {
// const storedTab = StorageManager.getStringValue('journalStatsTab'); watch: {
// if (storedTab && storedTab !== '' && this.statsButtons.some((b) => b.tab == storedTab)) async 'mainStore.driverStatsName'(val) {
// this.currentStatsTab = storedTab as Journal.StatsTab; await this.fetchDriverStats();
},
async 'mainStore.dispatcherStatsName'() {
await this.fetchDispatcherStats();
}
}, },
// watch: {
// 'mainStore.driverStatsData'(newData, prevData) {
// this.currentStatsTab =
// JSON.stringify(prevData) !== JSON.stringify(newData) && newData !== undefined
// ? Journal.StatsTab.DRIVER_STATS
// : this.currentStatsTab;
// }
// },
methods: { methods: {
onTabButtonClick(tab: Journal.StatsTab) { onTabButtonClick(tab: Journal.StatsTab) {
this.currentStatsTab = tab == this.currentStatsTab ? null : tab; this.currentStatsTab = tab == this.currentStatsTab ? null : tab;
StorageManager.setStringValue('journalStatsTab', this.currentStatsTab ?? ''); StorageManager.setStringValue('journalStatsTab', this.currentStatsTab ?? '');
},
async fetchDriverStats() {
if (!this.mainStore.driverStatsName) {
this.mainStore.driverStatsData = undefined;
this.mainStore.driverStatsStatus = Status.Data.Initialized;
return;
}
try {
this.mainStore.driverStatsStatus = Status.Data.Loading;
const statsData: API.DriverStats.Response = await (
await http.get(`api/getDriverInfo?name=${this.mainStore.driverStatsName}`)
).data;
this.mainStore.driverStatsData = statsData;
this.mainStore.driverStatsStatus = Status.Data.Loaded;
} catch (error) {
this.mainStore.driverStatsData = undefined;
this.mainStore.driverStatsStatus = Status.Data.Error;
console.error('Ups! Wystąpił błąd przy próbie pobrania statystyk maszynisty! :/');
}
},
async fetchDispatcherStats() {
if (!this.mainStore.dispatcherStatsName) {
this.mainStore.dispatcherStatsData = undefined;
return;
}
try {
const statsData: API.DispatcherStats.Response = await (
await http.get('api/getDispatcherInfo', {
params: {
name: this.mainStore.dispatcherStatsName
}
})
).data;
this.mainStore.dispatcherStatsData = statsData;
} catch (error) {
this.mainStore.dispatcherStatsData = undefined;
console.error('Ups! Wystąpił błąd przy próbie pobrania statystyk dyżurnego! :/');
}
} }
} }
}); });
+6 -5
View File
@@ -347,8 +347,6 @@
"last-seen-at": "Last seen at", "last-seen-at": "Last seen at",
"currently-at": "Currently at", "currently-at": "Currently at",
"stats-title": "DRIVING STATISTICS OF",
"stats-timetables": "TIMETABLES", "stats-timetables": "TIMETABLES",
"stats-longest-timetable": "LONGEST TIMETABLE", "stats-longest-timetable": "LONGEST TIMETABLE",
"stats-avg-timetable": "AVERAGE TIMETABLE LENGTH", "stats-avg-timetable": "AVERAGE TIMETABLE LENGTH",
@@ -365,13 +363,16 @@
"timetable-count": "timetable | timetables", "timetable-count": "timetable | timetables",
"daily-stats-title": "DAILY STATS", "daily-stats-button": "DAILY STATS",
"daily-stats-title": "STATS OF THE DAY",
"daily-stats-info": "Today's statistics are unavailable yet!", "daily-stats-info": "Today's statistics are unavailable yet!",
"driver-stats-title": "DRIVER STATS", "driver-stats-button": "DRIVER STATS",
"driver-stats-title": "{name}'s DRIVER STATS",
"driver-stats-info": "Enter a proper nickname into filters [F] to see user's driving statistics!", "driver-stats-info": "Enter a proper nickname into filters [F] to see user's driving statistics!",
"dispatcher-stats-title": "DISPATCHER STATS", "dispatcher-stats-button": "DISPATCHER STATS",
"dispatcher-stats-title": "{name}'s DISPATCHER STATS",
"dispatcher-stats-info": "Enter a proper nickname into filters [F] to see user's dispatcher statistics!", "dispatcher-stats-info": "Enter a proper nickname into filters [F] to see user's dispatcher statistics!",
"stats-loading": "Fetching statistics...", "stats-loading": "Fetching statistics...",
+6 -4
View File
@@ -326,8 +326,6 @@
"load-data": "Pobierz dalszą historię...", "load-data": "Pobierz dalszą historię...",
"stats-title": "STATYSTYKI MASZYNISTY",
"last-seen-at": "Ostatnio widziany na: ", "last-seen-at": "Ostatnio widziany na: ",
"currently-at": "Obecnie na scenerii: ", "currently-at": "Obecnie na scenerii: ",
@@ -346,13 +344,17 @@
"timetable-count": "rozkład jazdy | rozkładów jazdy", "timetable-count": "rozkład jazdy | rozkładów jazdy",
"daily-stats-button": "STATYSTYKI DNIA",
"daily-stats-title": "STATYSTYKI DNIA", "daily-stats-title": "STATYSTYKI DNIA",
"daily-stats-info": "Dzisiejsze statystyki nie są jeszcze dostępne!", "daily-stats-info": "Dzisiejsze statystyki nie są jeszcze dostępne!",
"driver-stats-title": "STAT. MASZYNISTY", "driver-stats-button": "STAT. MASZYNISTY",
"driver-stats-title": "STATYSTYKI MASZYNISTY {name}",
"driver-stats-info": "Wpisz nazwę użytkownika w filtrach [F], aby zobaczyć jego statystyki maszynisty!", "driver-stats-info": "Wpisz nazwę użytkownika w filtrach [F], aby zobaczyć jego statystyki maszynisty!",
"dispatcher-stats-title": "STATYSTYKI DYŻURNEGO", "dispatcher-stats-button": "STATYSTYKI DYŻURNEGO",
"dispatcher-stats-title": "STATYSTYKI DYŻURNEGO {name}",
"dispatcher-stats-info": "Wpisz nazwę użytkownika w filtrach [F], aby zobaczyć jego statystyki dyżurnego!", "dispatcher-stats-info": "Wpisz nazwę użytkownika w filtrach [F], aby zobaczyć jego statystyki dyżurnego!",
"stats-loading": "Pobieranie statystyk...", "stats-loading": "Pobieranie statystyk...",
+6 -5
View File
@@ -52,9 +52,9 @@ import JournalStats from '../components/JournalView/JournalStats.vue';
const statsButtons: Journal.StatsButton[] = [ const statsButtons: Journal.StatsButton[] = [
{ {
tab: Journal.StatsTab.DISPATCHER_STATS, tab: Journal.StatsTab.DISPATCHER_STATS,
localeKey: 'journal.dispatcher-stats-title', localeKey: 'journal.dispatcher-stats-button',
iconName: 'user', iconName: 'user',
disabled: false disabled: true
} }
]; ];
@@ -140,9 +140,10 @@ export default defineComponent({
}, },
'mainStore.dispatcherStatsData'(stats) { 'mainStore.dispatcherStatsData'(stats) {
// console.log(stats); console.log('dispatcher stats', stats);
// this.statsButtons.find((sb) => sb.tab == Journal.StatsTab.DRIVER_STATS)!.disabled =
// driverStats === undefined; this.statsButtons.find((sb) => sb.tab == Journal.StatsTab.DISPATCHER_STATS)!.disabled =
stats === undefined;
} }
}, },
+2 -2
View File
@@ -146,13 +146,13 @@ export default defineComponent({
statsButtons: [ statsButtons: [
{ {
tab: Journal.StatsTab.DAILY_STATS, tab: Journal.StatsTab.DAILY_STATS,
localeKey: 'journal.daily-stats-title', localeKey: 'journal.daily-stats-button',
iconName: 'stats', iconName: 'stats',
disabled: false disabled: false
}, },
{ {
tab: Journal.StatsTab.DRIVER_STATS, tab: Journal.StatsTab.DRIVER_STATS,
localeKey: 'journal.driver-stats-title', localeKey: 'journal.driver-stats-button',
iconName: 'user', iconName: 'user',
disabled: true disabled: true
} }