poprawki dziennika rj / dr

This commit is contained in:
2023-06-30 20:50:03 +02:00
parent 72ff857fff
commit 1b85cc5f58
9 changed files with 216 additions and 167 deletions
+1 -1
View File
@@ -49,7 +49,7 @@ let data = reactive({
{ {
name: 'driver', name: 'driver',
titlePath: 'journal.driver-stats-title', titlePath: 'journal.driver-stats-title',
inactive: true, // inactive: true,
}, },
] as { name: TStatTab; titlePath: string; inactive?: boolean }[], ] as { name: TStatTab; titlePath: string; inactive?: boolean }[],
}); });
@@ -1,10 +1,10 @@
<template> <template>
<transition-group class="journal-list" tag="ul" name="list-anim"> <transition-group class="journal-list" tag="ul" name="list-anim">
<li <li
v-for="{ timetable, stockHistoryComp, stops, ...item } in computedTimetableHistory" v-for="{ timetable, stockHistoryComp, stops, showExtraInfo, ...item } in computedTimetableHistory"
class="journal_item" class="journal_item"
:key="timetable.id" :key="timetable.id"
@click="item.showExtra.value = !item.showExtra.value" @click="showExtraInfo.value = !showExtraInfo.value"
> >
<div class="journal_item-info"> <div class="journal_item-info">
<div class="info-general"> <div class="info-general">
@@ -43,7 +43,7 @@
<span class="general-time"> <span class="general-time">
<b class="info-date">{{ localeDay(timetable.beginDate, $i18n.locale) }}</b> <b class="info-date">{{ localeDay(timetable.beginDate, $i18n.locale) }}</b>
<b <b
class="info-status" class="info-badge"
:class="{ :class="{
fulfilled: timetable.fulfilled, fulfilled: timetable.fulfilled,
terminated: timetable.terminated && !timetable.fulfilled, terminated: timetable.terminated && !timetable.fulfilled,
@@ -67,45 +67,28 @@
<hr /> <hr />
<!-- Spis postojów -->
<div class="stop-list"> <div class="stop-list">
<span class="stop-list-item" v-for="(stop, i) in stops" :data-confirmed="stop.confirmed"> <span
<span v-if="i > 0">&nbsp;&gt;&nbsp;</span> v-for="(stop, i) in stops.filter((_, i) => (!showExtraInfo.value ? i == 0 || i == stops.length - 1 : true))"
class="stop-list-item"
<span>{{ stop.stopName }}</span> :key="stop.stopName"
:data-confirmed="stop.confirmed"
<span v-if="stop.scheduledArrivalDate || stop.scheduledDepartureDate"> >
<span>&nbsp;&lpar;</span> <span v-if="i > 0">
<span v-if="stop.scheduledArrivalDate" &gt;
>p. <span v-if="!showExtraInfo.value && i == 1 && stops.length > 2">
<s ... (+{{ stops.length - 2 }}) &gt;
class="text--grayed"
v-if="stop.realArrivalDate && stop.scheduledArrivalDate != stop.realArrivalDate && stop.confirmed"
>{{ stop.scheduledArrivalDate }}</s
>
{{ stop.realArrivalDate || stop.scheduledArrivalDate }}
</span> </span>
<span v-if="stop.scheduledArrivalDate && stop.scheduledDepartureDate">
/ <span v-if="stop.stopTime">{{ stop.stopTime }}{{ stop.stopType }} / </span>
</span>
<span v-if="stop.scheduledDepartureDate"
>o.
<s
class="text--grayed"
v-if="
stop.realDepartureDate && stop.scheduledDepartureDate != stop.realDepartureDate && stop.confirmed
"
>
{{ stop.scheduledDepartureDate }}
</s>
{{ stop.realDepartureDate || stop.scheduledDepartureDate }}</span
>
<span>&rpar;</span>
</span> </span>
<span class="stop-name">{{ stop.stopName }}</span>
<span v-html="stop.html"></span>
</span> </span>
</div> </div>
<!-- Status RJ --> <!-- Status RJ -->
<div style="margin: 0.5em 0"> <div class="info-status" style="margin: 0.5em 0">
<span> <span>
<b>{{ $t('journal.route-length') }}</b> <b>{{ $t('journal.route-length') }}</b>
{{ !timetable.fulfilled ? timetable.currentDistance + ' /' : '' }} {{ !timetable.fulfilled ? timetable.currentDistance + ' /' : '' }}
@@ -122,12 +105,24 @@
<b> <b>
{{ $t(`journal.${timetable.terminated ? 'last-seen-at' : 'currently-at'}`) }} {{ $t(`journal.${timetable.terminated ? 'last-seen-at' : 'currently-at'}`) }}
{{ timetable.currentSceneryName.replace(/.[a-zA-Z0-9]+.sc/, '') }} {{ timetable.currentSceneryName.replace(/.[a-zA-Z0-9]+.sc/, '') }}
<span v-if="timetable.currentLocation.toString()">&lpar;</span>
<span v-if="timetable.currentLocation[1]">
{{ $t('journal.timetable-location-route') }} {{ timetable.currentLocation[1] }}
</span>
<span v-else-if="timetable.currentLocation[0]">
{{ $t('journal.timetable-location-signal') }} {{ timetable.currentLocation[0] }}
</span>
<span v-if="timetable.currentLocation.toString()">&rpar;</span>
</b> </b>
</span> </span>
</div> </div>
<!-- Nick dyżurnego --> <!-- Info o autorze RJ -->
<div v-if="timetable.authorName"> <div class="info-author" v-if="timetable.authorName">
<b class="text--grayed">{{ $t('journal.dispatcher-name') }}&nbsp;</b> <b class="text--grayed">{{ $t('journal.dispatcher-name') }}&nbsp;</b>
<router-link class="dispatcher-link" :to="`/journal/dispatchers?dispatcherName=${timetable.authorName}`"> <router-link class="dispatcher-link" :to="`/journal/dispatchers?dispatcherName=${timetable.authorName}`">
<b>{{ timetable.authorName }}</b> <b>{{ timetable.authorName }}</b>
@@ -144,11 +139,11 @@
<button class="btn--option btn--show"> <button class="btn--option btn--show">
{{ $t('journal.stock-info') }} {{ $t('journal.stock-info') }}
<img :src="getIcon(`arrow-${item.showExtra.value ? 'asc' : 'desc'}`)" alt="Arrow" /> <img :src="getIcon(`arrow-${showExtraInfo.value ? 'asc' : 'desc'}`)" alt="Arrow" />
</button> </button>
<!-- Dodatkowe informacje --> <!-- Dodatkowe informacje -->
<div class="info-extended" v-if="timetable.stockString && timetable.stockMass && item.showExtra.value"> <div class="info-extended" v-if="timetable.stockString && timetable.stockMass && showExtraInfo.value">
<hr /> <hr />
<div class="stock-specs"> <div class="stock-specs">
@@ -180,6 +175,7 @@
</span> </span>
</div> </div>
<!-- Historia zmian w składzie -->
<div class="stock-history" v-if="stockHistoryComp.length > 1"> <div class="stock-history" v-if="stockHistoryComp.length > 1">
<button <button
class="btn--action" class="btn--action"
@@ -252,70 +248,66 @@ export default defineComponent({
}; };
}), }),
stops: timetable.sceneriesString.split('%').map((stopName, i, arr) => { showExtraInfo: ref(false),
/* Internal error with scheduledBeginDate & scheduledEndDate being mixed up with respectively stops: this.getTimetableStops(timetable),
beginDate and endDate, kurwa mać */
const scheduledArrivalDateString = timetable.checkpointArrivalsScheduled?.at(i);
const scheduledDepartureDateString = timetable.checkpointDeparturesScheduled?.at(i);
const arrivalDateString = timetable.checkpointArrivals?.at(i);
const departureDateString = timetable.checkpointDepartures?.at(i);
if (i == 0)
return {
stopName,
scheduledArrivalDate: null,
realArrivalDate: null,
scheduledDepartureDate: this.localeTime(
scheduledDepartureDateString || timetable.beginDate,
this.$i18n.locale
),
realDepartureDate: this.localeTime(
departureDateString || timetable.scheduledBeginDate,
this.$i18n.locale
),
confirmed: i < timetable.confirmedStopsCount,
};
if (i == arr.length - 1)
return {
stopName,
scheduledArrivalDate: this.localeTime(scheduledArrivalDateString || timetable.endDate, this.$i18n.locale),
realArrivalDate: this.localeTime(arrivalDateString || timetable.scheduledEndDate, this.$i18n.locale),
scheduledDepartureDate: null,
realDepartureDate: null,
confirmed: timetable.fulfilled,
};
const stopInfo = timetable.checkpointStopTypes?.at(i)?.split(',');
return {
stopName,
realArrivalDate: arrivalDateString ? this.localeTime(arrivalDateString, this.$i18n.locale) : null,
scheduledArrivalDate: scheduledArrivalDateString
? this.localeTime(scheduledArrivalDateString, this.$i18n.locale)
: null,
realDepartureDate: departureDateString ? this.localeTime(departureDateString, this.$i18n.locale) : null,
scheduledDepartureDate: scheduledDepartureDateString
? this.localeTime(scheduledDepartureDateString, this.$i18n.locale)
: null,
stopTime: Number(stopInfo?.at(0)) || null,
stopType: stopInfo?.at(1) || null,
confirmed: i < timetable.confirmedStopsCount,
};
}),
showExtra: ref(false),
currentHistoryIndex: ref(0), currentHistoryIndex: ref(0),
})); }));
}, },
}, },
methods: { methods: {
getTimetableStops(timetable: TimetableHistory) {
const stopNames = timetable.sceneriesString.split('%');
const beginDateHTML = ` (o. ${
timetable.beginDate != timetable.scheduledBeginDate
? `<s class="text--grayed">${this.localeTime(timetable.beginDate, this.$i18n.locale)}</s>`
: ''
} <span>${this.localeTime(timetable.scheduledBeginDate, this.$i18n.locale)}</span>)`;
const endDateHTML = ` (p. ${
timetable.endDate != timetable.scheduledEndDate && timetable.fulfilled
? `<s class="text--grayed">${this.localeTime(timetable.endDate, this.$i18n.locale)}</s>`
: ''
} <span>${this.localeTime(timetable.scheduledEndDate, this.$i18n.locale)}</span>)`;
return stopNames.map((stopName, i) => {
const confirmed = i < timetable.confirmedStopsCount;
if (i == 0) return { stopName, html: beginDateHTML, confirmed };
if (i == stopNames.length - 1) return { stopName, html: endDateHTML, confirmed };
const departureDateScheduled = this.stringToDate(timetable.checkpointDeparturesScheduled?.at(i));
const departureDateReal = this.stringToDate(timetable.checkpointDepartures?.at(i));
const arrivalDateScheduled = this.stringToDate(timetable.checkpointArrivalsScheduled?.at(i));
const arrivalDateReal = this.stringToDate(timetable.checkpointArrivals?.at(i));
// const arrivalDelay =
// arrivalDateReal && arrivalDateScheduled ? arrivalDateReal.getTime() - arrivalDateScheduled.getTime() : 0;
// const departureDelay =
// departureDateReal && departureDateScheduled
// ? departureDateReal.getTime() - departureDateScheduled.getTime()
// : 0;
const arrivalHTML =
(arrivalDateReal && arrivalDateScheduled && arrivalDateReal?.getTime() != arrivalDateScheduled?.getTime()
? `<s class="text--grayed">${this.parseDateToTimeString(arrivalDateScheduled)}</s> `
: '') + this.parseDateToTimeString(arrivalDateReal || arrivalDateScheduled);
const departureHTML =
(departureDateReal &&
departureDateScheduled &&
departureDateReal?.getTime() != departureDateScheduled?.getTime()
? `<s class="text--grayed">${this.parseDateToTimeString(departureDateScheduled)}</s> `
: '') + this.parseDateToTimeString(departureDateReal || departureDateScheduled);
let html = `${arrivalHTML}${departureHTML ? ` / ${departureHTML}` : ''}`;
if (html) html = ` (${html})`;
return { stopName, html, confirmed };
});
},
showTimetable(timetable: TimetableHistory) { showTimetable(timetable: TimetableHistory) {
if (!timetable) return; if (!timetable) return;
if (timetable.terminated) return; if (timetable.terminated) return;
@@ -351,7 +343,7 @@ hr {
margin-right: 0.5em; margin-right: 0.5em;
} }
&-status { &-badge {
padding: 0.05em 0.35em; padding: 0.05em 0.35em;
color: black; color: black;
@@ -448,10 +440,18 @@ ul.stock-list {
} }
.stop-list { .stop-list {
display: flex;
flex-wrap: wrap;
gap: 0.25em;
color: #adadad; color: #adadad;
&-item[data-confirmed='true'] { &-item[data-confirmed='true'] {
color: #a3eba3; color: #a3eba3;
.stop-name {
font-weight: bold;
}
} }
} }
@@ -467,17 +467,10 @@ ul.stock-list {
} }
@include smallScreen { @include smallScreen {
.info-general { .journal_item-info {
flex-direction: column;
}
.info-extended {
text-align: center; text-align: center;
} }
.general-train {
justify-content: center;
}
.info-route { .info-route {
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -487,10 +480,9 @@ ul.stock-list {
margin: 1em auto 0 auto; margin: 1em auto 0 auto;
} }
.stock-specs { .info-general,
justify-content: center; .general-train,
} .stock-specs,
.stock-history { .stock-history {
justify-content: center; justify-content: center;
} }
+9 -3
View File
@@ -274,6 +274,7 @@
"title": "DISPATCHER HISTORY", "title": "DISPATCHER HISTORY",
"loading": "Loading dispatcher history data...", "loading": "Loading dispatcher history data...",
"no-history": "No dispatcher history found!", "no-history": "No dispatcher history found!",
"data-refreshed-at": "Data refreshed at",
"section-timetables": "TIMETABLES", "section-timetables": "TIMETABLES",
"section-dispatchers": "DISPATCHERS", "section-dispatchers": "DISPATCHERS",
@@ -291,8 +292,10 @@
"online-since": "ONLINE SINCE", "online-since": "ONLINE SINCE",
"duty-lasted": "The duty lasted", "duty-lasted": "The duty lasted",
"minutes": "{minutes} mins",
"hours": "{hours}h {minutes} mins", "hours": "{value} hour | {value} hours",
"minutes": "{value} min | {value} mins",
"seconds": "{value} s",
"stock-info": "EXTRA INFO", "stock-info": "EXTRA INFO",
"stock-length": "Length", "stock-length": "Length",
@@ -329,7 +332,10 @@
"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!",
"stats-loading": "Fetching statistics...", "stats-loading": "Fetching statistics...",
"stats-error": "Oops! An unexpected error occurred while trying to fetch statistics! :/" "stats-error": "Oops! An unexpected error occurred while trying to fetch statistics! :/",
"timetable-location-signal": "signal:",
"timetable-location-route": "route:"
}, },
"scenery": { "scenery": {
"users": "PLAYERS ONLINE", "users": "PLAYERS ONLINE",
+8 -3
View File
@@ -279,6 +279,7 @@
"title": "HISTORIA DYŻURÓW", "title": "HISTORIA DYŻURÓW",
"loading": "Ładowanie historii dyżurów...", "loading": "Ładowanie historii dyżurów...",
"no-history": "Brak historii dyżurów dla tej scenerii!", "no-history": "Brak historii dyżurów dla tej scenerii!",
"data-refreshed-at": "Dane odświeżone o",
"section-timetables": "ROZKŁADY JAZDY", "section-timetables": "ROZKŁADY JAZDY",
"section-dispatchers": "DYŻURNI", "section-dispatchers": "DYŻURNI",
@@ -288,8 +289,9 @@
"online-since": "ONLINE OD", "online-since": "ONLINE OD",
"duty-lasted": "Dyżur trwał", "duty-lasted": "Dyżur trwał",
"minutes": "{minutes} min.", "hours": "{value} godz.",
"hours": "{hours} godz. {minutes} min.", "minutes": "{value} min.",
"seconds": "{value} sek.",
"route-length": "Kilometraż:", "route-length": "Kilometraż:",
"station-count": "Stacje:", "station-count": "Stacje:",
@@ -333,7 +335,10 @@
"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!",
"stats-loading": "Pobieranie statystyk...", "stats-loading": "Pobieranie statystyk...",
"stats-error": "Ups! Wystąpił błąd podczas próby pobrania statystyk! :/" "stats-error": "Ups! Wystąpił błąd podczas próby pobrania statystyk! :/",
"timetable-location-signal": "semafor:",
"timetable-location-route": "szlak:"
}, },
"scenery": { "scenery": {
"users": "GRACZE ONLINE", "users": "GRACZE ONLINE",
+24 -4
View File
@@ -28,6 +28,19 @@ export default defineComponent({
}); });
}, },
stringToDate(dateString?: string) {
return dateString ? new Date(dateString) : null;
},
parseDateToTimeString(date: Date | null) {
return (
date?.toLocaleTimeString('pl-PL', {
hour: '2-digit',
minute: '2-digit',
}) || ''
);
},
timestampToString(timestamp: number | null) { timestampToString(timestamp: number | null) {
return timestamp return timestamp
? new Date(timestamp).toLocaleTimeString('pl-PL', { ? new Date(timestamp).toLocaleTimeString('pl-PL', {
@@ -37,14 +50,21 @@ export default defineComponent({
: ''; : '';
}, },
calculateDuration(timestampMs: number) { calculateDuration(timestampMs: number, showSeconds = false) {
const secondsTotal = Math.floor(timestampMs / 1000);
const minsTotal = Math.round(timestampMs / 60000); const minsTotal = Math.round(timestampMs / 60000);
const hoursTotal = Math.floor(minsTotal / 60); const hoursTotal = Math.floor(minsTotal / 60);
const minsInHour = minsTotal % 60; const minsInHour = minsTotal % 60;
return minsTotal > 60 return minsTotal >= 60
? this.$t('journal.hours', { hours: hoursTotal, minutes: minsInHour }) ? `${this.$t('journal.hours', { value: hoursTotal }, hoursTotal)} ${this.$t(
: this.$t('journal.minutes', { minutes: minsTotal }); 'journal.minutes',
{ value: minsInHour },
minsInHour
)}`
: showSeconds && secondsTotal <= 60
? this.$t('journal.seconds', { value: secondsTotal }, secondsTotal)
: this.$t('journal.minutes', { value: minsTotal }, minsTotal);
}, },
}, },
}); });
@@ -16,6 +16,7 @@ export interface TimetableHistory {
twr: number; twr: number;
skr: number; skr: number;
sceneriesString: string; sceneriesString: string;
currentLocation: string[];
routeDistance: number; routeDistance: number;
currentDistance: number; currentDistance: number;
+13
View File
@@ -23,6 +23,15 @@
padding: 1em 0; padding: 1em 0;
} }
.journal_refreshed-date {
background-color: #333;
color: #ddd;
text-align: end;
padding: 0.25em;
margin: 0.5em 0;
}
.journal_warning { .journal_warning {
text-align: center; text-align: center;
font-size: 1.3em; font-size: 1.3em;
@@ -71,6 +80,10 @@
justify-content: center; justify-content: center;
flex-wrap: wrap; flex-wrap: wrap;
} }
.journal_refreshed-date {
text-align: center;
}
} }
@media (orientation: landscape) { @media (orientation: landscape) {
+6
View File
@@ -13,6 +13,10 @@
optionsType="dispatchers" optionsType="dispatchers"
/> />
<div class="journal_refreshed-date" v-if="dataRefreshedAt">
{{ $t('journal.data-refreshed-at') }}: {{ dataRefreshedAt.toLocaleString($i18n.locale) }}
</div>
<div class="list_wrapper" @scroll="handleScroll"> <div class="list_wrapper" @scroll="handleScroll">
<transition name="status-anim" mode="out-in"> <transition name="status-anim" mode="out-in">
<div :key="dataStatus"> <div :key="dataStatus">
@@ -104,6 +108,7 @@ export default defineComponent({
data: () => ({ data: () => ({
currentQuery: '', currentQuery: '',
currentQueryArray: [] as string[], currentQueryArray: [] as string[],
dataRefreshedAt: null as Date | null,
scrollDataLoaded: true, scrollDataLoaded: true,
scrollNoMoreData: false, scrollNoMoreData: false,
@@ -273,6 +278,7 @@ export default defineComponent({
? this.historyList[0].dispatcherName ? this.historyList[0].dispatcherName
: ''; : '';
this.dataRefreshedAt = new Date();
this.dataStatus = DataStatus.Loaded; this.dataStatus = DataStatus.Loaded;
} catch (error) { } catch (error) {
this.dataStatus = DataStatus.Error; this.dataStatus = DataStatus.Error;
+6
View File
@@ -16,6 +16,10 @@
<JournalStats /> <JournalStats />
<div class="journal_refreshed-date" v-if="dataRefreshedAt">
{{ $t('journal.data-refreshed-at') }}: {{ dataRefreshedAt.toLocaleString($i18n.locale) }}
</div>
<div class="list_wrapper" @scroll="handleScroll"> <div class="list_wrapper" @scroll="handleScroll">
<transition name="status-anim" mode="out-in"> <transition name="status-anim" mode="out-in">
<div :key="dataStatus"> <div :key="dataStatus">
@@ -101,6 +105,7 @@ export default defineComponent({
data: () => ({ data: () => ({
currentQueryParams: {} as TimetablesQueryParams, currentQueryParams: {} as TimetablesQueryParams,
dataRefreshedAt: null as Date | null,
scrollDataLoaded: true, scrollDataLoaded: true,
scrollNoMoreData: false, scrollNoMoreData: false,
@@ -326,6 +331,7 @@ export default defineComponent({
: ''; : '';
this.dataStatus = DataStatus.Loaded; this.dataStatus = DataStatus.Loaded;
this.dataRefreshedAt = new Date();
} catch (error) { } catch (error) {
this.dataStatus = DataStatus.Error; this.dataStatus = DataStatus.Error;
this.dataErrorMessage = 'Ups! Coś poszło nie tak!'; this.dataErrorMessage = 'Ups! Coś poszło nie tak!';