mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 05:18:11 +00:00
Statystyki DR (wip)
This commit is contained in:
@@ -1,64 +1,51 @@
|
||||
<template>
|
||||
<div class="stats_container" v-click-outside="() => (cardVisible = false)">
|
||||
<button class="stats_button" @click="toggleCard">
|
||||
Statystyki dyżurnego {{ store.dispatcherStatsName }}
|
||||
</button>
|
||||
<div
|
||||
class="journal-stats dispatcher"
|
||||
v-if="store.dispatcherStatsName && store.dispatcherStatsData"
|
||||
>
|
||||
<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">
|
||||
<div>
|
||||
<Loading v-if="!store.dispatcherStatsData" />
|
||||
<span v-else>
|
||||
<h3>
|
||||
<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">
|
||||
Ten dyżurny nie ma jeszcze szczegółowych statystyk!
|
||||
</div>
|
||||
<hr class="header-separator" />
|
||||
|
||||
<div v-else>
|
||||
<h3>STATYSTYKI WYSTAWIONYCH ROZKŁADÓW</h3>
|
||||
|
||||
<div class="info-stats" v-if="store.dispatcherStatsData._count._all">
|
||||
<span class="stat-badge">
|
||||
<span>LICZBA</span>
|
||||
<span>{{ store.dispatcherStatsData._count._all }}</span>
|
||||
</span>
|
||||
<span class="stat-badge">
|
||||
<span>SUMA (KM)</span>
|
||||
<span>{{ store.dispatcherStatsData._sum.routeDistance.toFixed(2) }}km</span>
|
||||
</span>
|
||||
<span class="stat-badge">
|
||||
<span>NAJDŁUŻSZY</span>
|
||||
<span>{{ store.dispatcherStatsData._max.routeDistance.toFixed(2) }}km</span>
|
||||
</span>
|
||||
<span class="stat-badge">
|
||||
<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 class="info-stats" v-if="store.dispatcherStatsData._count._all">
|
||||
<span class="stat-badge">
|
||||
<span>LICZBA</span>
|
||||
<span>{{ store.dispatcherStatsData._count._all }}</span>
|
||||
</span>
|
||||
<span class="stat-badge">
|
||||
<span>SUMA (KM)</span>
|
||||
<span>{{ store.dispatcherStatsData._sum.routeDistance.toFixed(2) }}km</span>
|
||||
</span>
|
||||
<span class="stat-badge">
|
||||
<span>NAJDŁUŻSZY</span>
|
||||
<span>{{ store.dispatcherStatsData._max.routeDistance.toFixed(2) }}km</span>
|
||||
</span>
|
||||
<span class="stat-badge">
|
||||
<span>ŚREDNIO</span>
|
||||
<span>{{ store.dispatcherStatsData._avg.routeDistance.toFixed(2) }}km</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { useMainStore } from '../../store/mainStore';
|
||||
import Loading from '../Global/Loading.vue';
|
||||
import { API } from '../../typings/api';
|
||||
import http from '../../http';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'journal-dispatcher-stats',
|
||||
components: { Loading },
|
||||
|
||||
setup() {
|
||||
const store = useMainStore();
|
||||
@@ -66,96 +53,10 @@ export default defineComponent({
|
||||
return {
|
||||
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>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../../styles/responsive.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;
|
||||
}
|
||||
@import '../../styles/JournalStats.scss';
|
||||
</style>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<template>
|
||||
<div class="journal-stats" v-if="store.driverStatsData">
|
||||
<div class="journal-stats driver" v-if="store.driverStatsData">
|
||||
<span>
|
||||
<h3>
|
||||
{{ $t('journal.stats-title') }}
|
||||
<span class="text--primary">{{ store.driverStatsName.toUpperCase() }}</span>
|
||||
<i18n-t keypath="journal.driver-stats-title">
|
||||
<template #name>
|
||||
<span class="text--primary">{{ store.driverStatsName.toUpperCase() }}</span>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</h3>
|
||||
|
||||
<hr class="header-separator" />
|
||||
|
||||
@@ -114,7 +114,6 @@ import { defineComponent, inject, PropType } from 'vue';
|
||||
import keyMixin from '../../mixins/keyMixin';
|
||||
import { useMainStore } from '../../store/mainStore';
|
||||
import { Journal } from './typings';
|
||||
import { API } from '../../typings/api';
|
||||
import { Status } from '../../typings/common';
|
||||
import http from '../../http';
|
||||
|
||||
@@ -181,10 +180,6 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
watch: {
|
||||
async 'store.driverStatsName'() {
|
||||
await this.fetchDriverStats();
|
||||
},
|
||||
|
||||
async 'searchersValues.search-driver'(value: string | undefined) {
|
||||
clearTimeout(this.searchTimeout);
|
||||
|
||||
@@ -203,29 +198,6 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
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() {
|
||||
this.$emit('onRefreshData');
|
||||
},
|
||||
|
||||
@@ -47,6 +47,9 @@ import { Journal } from './typings';
|
||||
import JournalDailyStats from './JournalDailyStats.vue';
|
||||
import JournalDispatcherStats from './JournalDispatcherStats.vue';
|
||||
import JournalDriverStats from './JournalDriverStats.vue';
|
||||
import { Status } from '../../typings/common';
|
||||
import http from '../../http';
|
||||
import { API } from '../../typings/api';
|
||||
|
||||
export default defineComponent({
|
||||
components: { JournalDailyStats, JournalDriverStats, JournalDispatcherStats },
|
||||
@@ -63,24 +66,68 @@ export default defineComponent({
|
||||
currentStatsTab: null as Journal.StatsTab | null
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
// const storedTab = StorageManager.getStringValue('journalStatsTab');
|
||||
// if (storedTab && storedTab !== '' && this.statsButtons.some((b) => b.tab == storedTab))
|
||||
// this.currentStatsTab = storedTab as Journal.StatsTab;
|
||||
|
||||
watch: {
|
||||
async 'mainStore.driverStatsName'(val) {
|
||||
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: {
|
||||
onTabButtonClick(tab: Journal.StatsTab) {
|
||||
this.currentStatsTab = tab == this.currentStatsTab ? null : tab;
|
||||
|
||||
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
@@ -347,8 +347,6 @@
|
||||
"last-seen-at": "Last seen at",
|
||||
"currently-at": "Currently at",
|
||||
|
||||
"stats-title": "DRIVING STATISTICS OF",
|
||||
|
||||
"stats-timetables": "TIMETABLES",
|
||||
"stats-longest-timetable": "LONGEST TIMETABLE",
|
||||
"stats-avg-timetable": "AVERAGE TIMETABLE LENGTH",
|
||||
@@ -365,13 +363,16 @@
|
||||
|
||||
"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!",
|
||||
|
||||
"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!",
|
||||
|
||||
"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!",
|
||||
|
||||
"stats-loading": "Fetching statistics...",
|
||||
|
||||
+6
-4
@@ -326,8 +326,6 @@
|
||||
|
||||
"load-data": "Pobierz dalszą historię...",
|
||||
|
||||
"stats-title": "STATYSTYKI MASZYNISTY",
|
||||
|
||||
"last-seen-at": "Ostatnio widziany na: ",
|
||||
"currently-at": "Obecnie na scenerii: ",
|
||||
|
||||
@@ -346,13 +344,17 @@
|
||||
|
||||
"timetable-count": "rozkład jazdy | rozkładów jazdy",
|
||||
|
||||
"daily-stats-button": "STATYSTYKI DNIA",
|
||||
"daily-stats-title": "STATYSTYKI DNIA",
|
||||
|
||||
"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!",
|
||||
|
||||
"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!",
|
||||
|
||||
"stats-loading": "Pobieranie statystyk...",
|
||||
|
||||
@@ -52,9 +52,9 @@ import JournalStats from '../components/JournalView/JournalStats.vue';
|
||||
const statsButtons: Journal.StatsButton[] = [
|
||||
{
|
||||
tab: Journal.StatsTab.DISPATCHER_STATS,
|
||||
localeKey: 'journal.dispatcher-stats-title',
|
||||
localeKey: 'journal.dispatcher-stats-button',
|
||||
iconName: 'user',
|
||||
disabled: false
|
||||
disabled: true
|
||||
}
|
||||
];
|
||||
|
||||
@@ -140,9 +140,10 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
'mainStore.dispatcherStatsData'(stats) {
|
||||
// console.log(stats);
|
||||
// this.statsButtons.find((sb) => sb.tab == Journal.StatsTab.DRIVER_STATS)!.disabled =
|
||||
// driverStats === undefined;
|
||||
console.log('dispatcher stats', stats);
|
||||
|
||||
this.statsButtons.find((sb) => sb.tab == Journal.StatsTab.DISPATCHER_STATS)!.disabled =
|
||||
stats === undefined;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -146,13 +146,13 @@ export default defineComponent({
|
||||
statsButtons: [
|
||||
{
|
||||
tab: Journal.StatsTab.DAILY_STATS,
|
||||
localeKey: 'journal.daily-stats-title',
|
||||
localeKey: 'journal.daily-stats-button',
|
||||
iconName: 'stats',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
tab: Journal.StatsTab.DRIVER_STATS,
|
||||
localeKey: 'journal.driver-stats-title',
|
||||
localeKey: 'journal.driver-stats-button',
|
||||
iconName: 'user',
|
||||
disabled: true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user