odświeżony wygląd dziennika RJ

This commit is contained in:
2023-08-30 20:31:40 +02:00
parent 25735c5e6e
commit 4537341a57
6 changed files with 126 additions and 84 deletions
+62
View File
@@ -0,0 +1,62 @@
<template>
<div class="progress-bar">
<span class="bar-bg"></span>
<span class="bar-fg" :style="{ width: `${~~progressPercent}%`, backgroundColor: bgColor }"></span>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
props: {
progressPercent: {
type: Number,
required: true,
},
progressType: {
type: String,
required: false,
},
},
computed: {
bgColor() {
switch (this.progressType) {
case 'abandoned':
return 'salmon';
default:
return 'springgreen';
}
},
},
});
</script>
<style lang="scss" scoped>
.progress-bar {
position: relative;
width: 6em;
height: 1em;
margin: 0.5em 0;
.bar-fg,
.bar-bg {
position: absolute;
height: 1em;
width: 100%;
left: 0;
}
.bar-fg {
background-color: springgreen;
}
.bar-bg {
background-color: #5b5b5b;
}
}
</style>
@@ -41,7 +41,14 @@
</span> </span>
<span class="general-time"> <span class="general-time">
<b class="info-date">{{ localeDay(timetable.beginDate, $i18n.locale) }}</b> <b class="info-date"
>{{
new Date(timetable.createdAt).getTime() - new Date(timetable.beginDate).getTime() < 0
? localeDateTime(timetable.createdAt, $i18n.locale)
: localeDateTime(timetable.beginDate, $i18n.locale)
}}
</b>
<b <b
class="info-badge" class="info-badge"
:class="{ :class="{
@@ -68,7 +75,7 @@
<hr /> <hr />
<!-- Spis postojów --> <!-- Spis postojów -->
<div class="stop-list"> <div class="stop-list" v-if="showExtraInfo.value == true">
<span <span
v-for="(stop, i) in stops.filter((_, i) => (!showExtraInfo.value ? i == 0 || i == stops.length - 1 : true))" v-for="(stop, i) in stops.filter((_, i) => (!showExtraInfo.value ? i == 0 || i == stops.length - 1 : true))"
class="stop-list-item" class="stop-list-item"
@@ -89,19 +96,20 @@
<!-- Status RJ --> <!-- Status RJ -->
<div class="info-status" style="margin: 0.5em 0"> <div class="info-status" style="margin: 0.5em 0">
<span> <ProgressBar
<b>{{ $t('journal.route-length') }}</b> :progressPercent="(timetable.confirmedStopsCount / timetable.allStopsCount) * 100"
{{ !timetable.fulfilled ? timetable.currentDistance + ' /' : '' }} :progressType="!timetable.fulfilled && timetable.terminated ? 'abandoned' : ''"
{{ timetable.routeDistance }} km />
<span :style="{ color: timetable.terminated && timetable.fulfilled ? 'lightgreen' : '' }">
<span>
{{ timetable.currentDistance + ' km' }}
</span>
<span> / </span>
<span>{{ timetable.routeDistance }} km</span>
</span> </span>
&bull;
<span> <span class="text--grayed" v-if="timetable.currentSceneryName">
<b>{{ $t('journal.station-count') }}</b>
{{ timetable.confirmedStopsCount }} /
{{ timetable.allStopsCount }}
</span>
<span class="text--grayed" v-if="!timetable.fulfilled && timetable.currentSceneryName">
&bull;
<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/, '') }}
@@ -121,22 +129,6 @@
</span> </span>
</div> </div>
<!-- Info o autorze RJ -->
<div class="info-author" v-if="timetable.authorName">
<b class="text--grayed">{{ $t('journal.dispatcher-name') }}&nbsp;</b>
<router-link class="dispatcher-link" :to="`/journal/dispatchers?dispatcherName=${timetable.authorName}`">
<b>{{ timetable.authorName }}</b>
</router-link>
<span class="text--grayed">
({{
(new Date(timetable.createdAt).getTime() - new Date(timetable.beginDate).getTime() < 0
? new Date(timetable.createdAt)
: new Date(timetable.beginDate)
).toLocaleString($i18n.locale, { timeStyle: 'short', dateStyle: 'full' })
}})
</span>
</div>
<button class="btn--option btn--show"> <button class="btn--option btn--show">
{{ $t('journal.stock-info') }} {{ $t('journal.stock-info') }}
<img :src="getIcon(`arrow-${showExtraInfo.value ? 'asc' : 'desc'}`)" alt="Arrow" /> <img :src="getIcon(`arrow-${showExtraInfo.value ? 'asc' : 'desc'}`)" alt="Arrow" />
@@ -146,11 +138,19 @@
<div class="info-extended" v-if="timetable.stockString && timetable.stockMass && showExtraInfo.value"> <div class="info-extended" v-if="timetable.stockString && timetable.stockMass && showExtraInfo.value">
<hr /> <hr />
<div class="stock-specs">
<span class="badge specs-badge">
<span>{{ $t('journal.dispatcher-name') }}</span>
<span>{{ timetable.authorName }}</span>
</span>
</div>
<div class="stock-specs"> <div class="stock-specs">
<span class="badge specs-badge"> <span class="badge specs-badge">
<span>{{ $t('journal.stock-max-speed') }}</span> <span>{{ $t('journal.stock-max-speed') }}</span>
<span>{{ timetable.maxSpeed }}km/h</span> <span>{{ timetable.maxSpeed }}km/h</span>
</span> </span>
<span class="badge specs-badge"> <span class="badge specs-badge">
<span>{{ $t('journal.stock-length') }}</span> <span>{{ $t('journal.stock-length') }}</span>
<span> <span>
@@ -161,6 +161,7 @@
}}m }}m
</span> </span>
</span> </span>
<span class="badge specs-badge"> <span class="badge specs-badge">
<span>{{ $t('journal.stock-mass') }}</span> <span>{{ $t('journal.stock-mass') }}</span>
<span> <span>
@@ -216,6 +217,7 @@ import imageMixin from '../../mixins/imageMixin';
import modalTrainMixin from '../../mixins/modalTrainMixin'; import modalTrainMixin from '../../mixins/modalTrainMixin';
import styleMixin from '../../mixins/styleMixin'; import styleMixin from '../../mixins/styleMixin';
import { TimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData'; import { TimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
import ProgressBar from '../Global/ProgressBar.vue';
export default defineComponent({ export default defineComponent({
props: { props: {
@@ -224,9 +226,7 @@ export default defineComponent({
required: true, required: true,
}, },
}, },
mixins: [dateMixin, imageMixin, modalTrainMixin, styleMixin], mixins: [dateMixin, imageMixin, modalTrainMixin, styleMixin],
computed: { computed: {
computedTimetableHistory() { computedTimetableHistory() {
return this.timetableHistory.map((timetable) => ({ return this.timetableHistory.map((timetable) => ({
@@ -236,7 +236,6 @@ export default defineComponent({
.reverse() .reverse()
.map((h) => { .map((h) => {
const historyData = h.split('@'); const historyData = h.split('@');
return { return {
updatedAt: new Date(Number(historyData[0])).toLocaleTimeString(this.$i18n.locale, { updatedAt: new Date(Number(historyData[0])).toLocaleTimeString(this.$i18n.locale, {
hour: '2-digit', hour: '2-digit',
@@ -247,14 +246,12 @@ export default defineComponent({
stockLength: Number(historyData[3]) || undefined, stockLength: Number(historyData[3]) || undefined,
}; };
}), }),
showExtraInfo: ref(false), showExtraInfo: ref(false),
stops: this.getTimetableStops(timetable), stops: this.getTimetableStops(timetable),
currentHistoryIndex: ref(0), currentHistoryIndex: ref(0),
})); }));
}, },
}, },
methods: { methods: {
getTimetableStops(timetable: TimetableHistory) { getTimetableStops(timetable: TimetableHistory) {
const stopNames = timetable.sceneriesString.split('%'); const stopNames = timetable.sceneriesString.split('%');
@@ -273,6 +270,7 @@ export default defineComponent({
return stopNames.map((stopName, i) => { return stopNames.map((stopName, i) => {
const confirmed = i < timetable.confirmedStopsCount; const confirmed = i < timetable.confirmedStopsCount;
if (i == 0) return { stopName, html: beginDateHTML, confirmed }; if (i == 0) return { stopName, html: beginDateHTML, confirmed };
if (i == stopNames.length - 1) return { stopName, html: endDateHTML, confirmed }; if (i == stopNames.length - 1) return { stopName, html: endDateHTML, confirmed };
@@ -281,14 +279,6 @@ export default defineComponent({
const arrivalDateScheduled = this.stringToDate(timetable.checkpointArrivalsScheduled?.at(i)); const arrivalDateScheduled = this.stringToDate(timetable.checkpointArrivalsScheduled?.at(i));
const arrivalDateReal = this.stringToDate(timetable.checkpointArrivals?.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 = const arrivalHTML =
(arrivalDateReal && arrivalDateScheduled && arrivalDateReal?.getTime() != arrivalDateScheduled?.getTime() (arrivalDateReal && arrivalDateScheduled && arrivalDateReal?.getTime() != arrivalDateScheduled?.getTime()
? `<s class="text--grayed">${this.parseDateToTimeString(arrivalDateScheduled)}</s> ` ? `<s class="text--grayed">${this.parseDateToTimeString(arrivalDateScheduled)}</s> `
@@ -302,24 +292,22 @@ export default defineComponent({
: '') + this.parseDateToTimeString(departureDateReal || departureDateScheduled); : '') + this.parseDateToTimeString(departureDateReal || departureDateScheduled);
let html = `${arrivalHTML}${departureHTML ? ` / ${departureHTML}` : ''}`; let html = `${arrivalHTML}${departureHTML ? ` / ${departureHTML}` : ''}`;
if (html) html = ` (${html})`;
if (html) html = ` (${html})`;
return { stopName, html, confirmed }; return { stopName, html, confirmed };
}); });
}, },
showTimetable(timetable: TimetableHistory) { showTimetable(timetable: TimetableHistory) {
if (!timetable) return; if (!timetable) return;
if (timetable.terminated) return; if (timetable.terminated) return;
this.selectModalTrain(timetable.driverName + timetable.trainNo.toString()); this.selectModalTrain(timetable.driverName + timetable.trainNo.toString());
}, },
onImageError(e: Event) { onImageError(e: Event) {
const imageEl = e.target as HTMLImageElement; const imageEl = e.target as HTMLImageElement;
imageEl.src = this.getImage('unknown.png'); imageEl.src = this.getImage('unknown.png');
}, },
}, },
components: { ProgressBar },
}); });
</script> </script>
@@ -377,6 +365,13 @@ hr {
&-extended { &-extended {
margin-top: 0.5em; margin-top: 0.5em;
} }
&-status {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0.5em;
}
} }
.general-train { .general-train {
@@ -421,11 +416,10 @@ ul.stock-list {
} }
} }
// badge.scss
.badges { .badges {
display: flex; display: flex;
gap: 0.25em; gap: 0.25em;
// badge.scss
} }
.stock-history { .stock-history {
@@ -440,14 +434,14 @@ ul.stock-list {
} }
.stop-list { .stop-list {
display: flex; word-wrap: break-word;
flex-wrap: wrap;
gap: 0.25em; gap: 0.25em;
font-size: 0.9em;
color: #adadad; color: #adadad;
&-item[data-confirmed='true'] { &-item[data-confirmed='true'] {
color: #a3eba3; color: lightgreen;
.stop-name { .stop-name {
font-weight: bold; font-weight: bold;
@@ -457,7 +451,6 @@ ul.stock-list {
.btn--show { .btn--show {
display: flex; display: flex;
margin-top: 1em;
font-weight: bold; font-weight: bold;
padding: 0.2em 0.45em; padding: 0.2em 0.45em;
@@ -476,6 +469,10 @@ ul.stock-list {
justify-content: center; justify-content: center;
} }
.info-status {
justify-content: center;
}
.btn--show { .btn--show {
margin: 1em auto 0 auto; margin: 1em auto 0 auto;
} }
+5 -29
View File
@@ -41,13 +41,14 @@
</div> </div>
<div class="timetable_progress" style="margin-top: 0.5em" v-if="train.timetableData"> <div class="timetable_progress" style="margin-top: 0.5em" v-if="train.timetableData">
<span class="timetable_progress-bar"> <!-- <span class="timetable_progress-bar">
<span class="bar-bg"></span> <span class="bar-bg"></span>
<span <span
class="bar-fg" class="bar-fg"
:style="{ width: `${Math.floor(confirmedPercentage(train.timetableData.followingStops))}%` }" :style="{ width: `${Math.floor(confirmedPercentage(train.timetableData.followingStops))}%` }"
></span> ></span>
</span> </span> -->
<ProgressBar :progressPercent="confirmedPercentage(train.timetableData.followingStops)" />
<span class="timetable_progress-distance"> <span class="timetable_progress-distance">
&nbsp; {{ currentDistance(train.timetableData.followingStops) }} km / &nbsp; {{ currentDistance(train.timetableData.followingStops) }} km /
@@ -96,6 +97,7 @@ import imageMixin from '../../mixins/imageMixin';
import styleMixin from '../../mixins/styleMixin'; import styleMixin from '../../mixins/styleMixin';
import trainInfoMixin from '../../mixins/trainInfoMixin'; import trainInfoMixin from '../../mixins/trainInfoMixin';
import Train from '../../scripts/interfaces/Train'; import Train from '../../scripts/interfaces/Train';
import ProgressBar from '../Global/ProgressBar.vue';
export default defineComponent({ export default defineComponent({
props: { props: {
@@ -103,14 +105,13 @@ export default defineComponent({
type: Object as () => Train, type: Object as () => Train,
required: true, required: true,
}, },
extended: { extended: {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
}, },
mixins: [trainInfoMixin, imageMixin, styleMixin], mixins: [trainInfoMixin, imageMixin, styleMixin],
components: { ProgressBar },
}); });
</script> </script>
@@ -206,31 +207,6 @@ export default defineComponent({
flex-wrap: wrap; flex-wrap: wrap;
} }
.timetable_progress-bar {
position: relative;
width: 6em;
height: 1em;
margin: 0.5em 0;
.bar-fg,
.bar-bg {
position: absolute;
height: 1em;
width: 100%;
left: 0;
}
.bar-fg {
background-color: springgreen;
}
.bar-bg {
background-color: #5b5b5b;
}
}
.timetable_progress-distance { .timetable_progress-distance {
margin-right: 0.25em; margin-right: 0.25em;
} }
+1 -1
View File
@@ -284,7 +284,7 @@
"route-length": "Route length:", "route-length": "Route length:",
"station-count": "Stations:", "station-count": "Stations:",
"dispatcher-name": "Created by", "dispatcher-name": "Author",
"timetable-day": "Timetable created at", "timetable-day": "Timetable created at",
"timetable-active": "ACTIVE", "timetable-active": "ACTIVE",
"timetable-fulfilled": "FULFILLED", "timetable-fulfilled": "FULFILLED",
+1 -1
View File
@@ -295,7 +295,7 @@
"route-length": "Kilometraż:", "route-length": "Kilometraż:",
"station-count": "Stacje:", "station-count": "Stacje:",
"dispatcher-name": "Wystawiony przez dyżurnego", "dispatcher-name": "Autor",
"timetable-day": "Rozkład z dnia", "timetable-day": "Rozkład z dnia",
"timetable-active": "AKTYWNY", "timetable-active": "AKTYWNY",
"timetable-fulfilled": "WYPEŁNIONY", "timetable-fulfilled": "WYPEŁNIONY",
+7
View File
@@ -21,6 +21,13 @@ export default defineComponent({
}); });
}, },
localeDateTime(dateString: string, locale: string) {
return new Date(dateString).toLocaleString(locale == 'pl' ? 'pl-PL' : 'en-GB', {
timeStyle: 'short',
dateStyle: 'medium'
});
},
localeTime(dateString: string, locale: string) { localeTime(dateString: string, locale: string) {
return new Date(dateString).toLocaleTimeString(locale == 'pl' ? 'pl-PL' : 'en-GB', { return new Date(dateString).toLocaleTimeString(locale == 'pl' ? 'pl-PL' : 'en-GB', {
hour: '2-digit', hour: '2-digit',