mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 05:18:11 +00:00
Dodano informacje o poc. offline
This commit is contained in:
+7
-1
@@ -37,7 +37,7 @@
|
|||||||
<img src="@/assets/icon-dispatcher.svg" alt="icon dispatcher" />
|
<img src="@/assets/icon-dispatcher.svg" alt="icon dispatcher" />
|
||||||
<span class="text--primary">{{ onlineDispatchers.length }}</span>
|
<span class="text--primary">{{ onlineDispatchers.length }}</span>
|
||||||
<span class="text--grayed"> / </span>
|
<span class="text--grayed"> / </span>
|
||||||
<span class="text--primary">{{ store.trainList.length }}</span>
|
<span class="text--primary">{{ trainList.length }}</span>
|
||||||
<img src="@/assets/icon-train.svg" alt="icon train" />
|
<img src="@/assets/icon-train.svg" alt="icon train" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -125,6 +125,12 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
trainList() {
|
||||||
|
return this.store.trainList.filter(train => train.online);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
VERSION: packageInfo.version,
|
VERSION: packageInfo.version,
|
||||||
updateModalVisible: false,
|
updateModalVisible: false,
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
<h3 class="user-header section-header">
|
<h3 class="user-header section-header">
|
||||||
<img :src="icons.user" alt="icon-user" />
|
<img :src="icons.user" alt="icon-user" />
|
||||||
{{ $t('scenery.users') }}
|
{{ $t('scenery.users') }}
|
||||||
<span class="text--primary">{{ station.onlineInfo?.currentUsers || '0' }}</span> / <span class="text--primary">{{ station.onlineInfo?.maxUsers || '0' }}</span>
|
<span class="text--primary">{{ station.onlineInfo?.currentUsers || '0' }}</span
|
||||||
|
> / <span class="text--primary">{{ station.onlineInfo?.maxUsers || '0' }}</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -41,7 +42,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const computedStationTrains= computed(() => {
|
const computedStationTrains = computed(() => {
|
||||||
if (!props.station) return [];
|
if (!props.station) return [];
|
||||||
|
|
||||||
const station = props.station as Station;
|
const station = props.station as Station;
|
||||||
@@ -49,9 +50,7 @@ export default defineComponent({
|
|||||||
if (!station.onlineInfo.stationTrains) return [];
|
if (!station.onlineInfo.stationTrains) return [];
|
||||||
|
|
||||||
return station.onlineInfo.stationTrains.map((train) => {
|
return station.onlineInfo.stationTrains.map((train) => {
|
||||||
const scheduledTrainStatus = station.onlineInfo?.scheduledTrains?.find(
|
const scheduledTrainStatus = station.onlineInfo?.scheduledTrains?.find((st) => st.trainNo === train.trainNo);
|
||||||
(st) => st.trainNo === train.trainNo
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...train,
|
...train,
|
||||||
|
|||||||
@@ -61,6 +61,10 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!train.online" style="color: salmon">
|
||||||
|
Offline - {{ lastSeenMessage(train.lastSeen) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="driver_position text--grayed" style="margin-top: 0.25em">
|
<div class="driver_position text--grayed" style="margin-top: 0.25em">
|
||||||
<span v-if="train.currentStationHash">
|
<span v-if="train.currentStationHash">
|
||||||
{{ $t('trains.current-scenery') }} <span>{{ train['currentStationName'] }} </span>
|
{{ $t('trains.current-scenery') }} <span>{{ train['currentStationName'] }} </span>
|
||||||
|
|||||||
+5
-1
@@ -181,7 +181,11 @@
|
|||||||
"loco-diesel": "Diesel locomotive",
|
"loco-diesel": "Diesel locomotive",
|
||||||
"timetable-comments": "Exploitation comments available for this train",
|
"timetable-comments": "Exploitation comments available for this train",
|
||||||
"comment": "Exploitation comments for: ",
|
"comment": "Exploitation comments for: ",
|
||||||
"table-limit": "For performance reasons there's a limit of 10 trains shown at the same time."
|
"table-limit": "For performance reasons there's a limit of 10 trains shown at the same time.",
|
||||||
|
|
||||||
|
"last-seen-now": "last seen: just now",
|
||||||
|
"last-seen-min": "last seen: one minute ago",
|
||||||
|
"last-seen-ago": "last seen: {minutes} mins ago"
|
||||||
},
|
},
|
||||||
"journal": {
|
"journal": {
|
||||||
"title": "DISPATCHER HISTORY",
|
"title": "DISPATCHER HISTORY",
|
||||||
|
|||||||
+5
-2
@@ -161,7 +161,6 @@
|
|||||||
"filter-noTimetable": "bez RJ",
|
"filter-noTimetable": "bez RJ",
|
||||||
"filter-reset": "X RESETUJ",
|
"filter-reset": "X RESETUJ",
|
||||||
|
|
||||||
|
|
||||||
"sorter-prefix": "Sortuj: ",
|
"sorter-prefix": "Sortuj: ",
|
||||||
"search-train": "Numer pociągu",
|
"search-train": "Numer pociągu",
|
||||||
"search-driver": "Nick maszynisty",
|
"search-driver": "Nick maszynisty",
|
||||||
@@ -183,7 +182,11 @@
|
|||||||
"loco-diesel": "Spalinowóz",
|
"loco-diesel": "Spalinowóz",
|
||||||
"timetable-comments": "Pociąg z uwagami eksploatacyjnymi",
|
"timetable-comments": "Pociąg z uwagami eksploatacyjnymi",
|
||||||
"comment": "Uwagi eksploatacyjne dla: ",
|
"comment": "Uwagi eksploatacyjne dla: ",
|
||||||
"table-limit": "Dla płynności działania strony pokazanych jest tylko 10 pociągów zgodnie z wybranymi filtrami."
|
"table-limit": "Dla płynności działania strony pokazanych jest tylko 10 pociągów zgodnie z wybranymi filtrami.",
|
||||||
|
|
||||||
|
"last-seen-now": "ostatnio widziany: przed chwilą",
|
||||||
|
"last-seen-min": "ostatnio widziany: minutę temu",
|
||||||
|
"last-seen-ago": "ostatnio widziany: {minutes} min. temu"
|
||||||
},
|
},
|
||||||
"journal": {
|
"journal": {
|
||||||
"title": "HISTORIA DYŻURÓW",
|
"title": "HISTORIA DYŻURÓW",
|
||||||
|
|||||||
+115
-104
@@ -1,117 +1,128 @@
|
|||||||
import Train from "@/scripts/interfaces/Train";
|
import Train from '@/scripts/interfaces/Train';
|
||||||
import TrainStop from "@/scripts/interfaces/TrainStop";
|
import TrainStop from '@/scripts/interfaces/TrainStop';
|
||||||
import { defineComponent } from "vue";
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data: () => ({
|
data: () => ({
|
||||||
STATS: {
|
STATS: {
|
||||||
main: [
|
main: [
|
||||||
{
|
{
|
||||||
name: 'speed',
|
name: 'speed',
|
||||||
unit: 'km/h',
|
unit: 'km/h',
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'length',
|
|
||||||
unit: 'm',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'mass',
|
|
||||||
unit: 't',
|
|
||||||
multiplier: 0.001,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
position: [
|
|
||||||
{
|
|
||||||
name: 'scenery',
|
|
||||||
prop: 'currentStationName',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'route',
|
|
||||||
prop: 'connectedTrack',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'signal',
|
|
||||||
prop: 'signal',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'distance',
|
|
||||||
prop: 'distance',
|
|
||||||
unit: 'm',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
}),
|
{
|
||||||
|
name: 'length',
|
||||||
methods: {
|
unit: 'm',
|
||||||
displayStopList(stops: TrainStop[]): string | undefined {
|
|
||||||
if (!stops) return '';
|
|
||||||
|
|
||||||
return stops
|
|
||||||
.reduce((acc: string[], stop: TrainStop, i: number) => {
|
|
||||||
if (stop.stopType.includes('ph') && !stop.stopNameRAW.includes('po.'))
|
|
||||||
acc.push(`<strong style='color:${stop.confirmed ? 'springgreen' : 'white'}'>${stop.stopName}</strong>`);
|
|
||||||
else if (
|
|
||||||
i > 0 &&
|
|
||||||
i < stops.length - 1 &&
|
|
||||||
!stop.stopNameRAW.includes('po.') &&
|
|
||||||
!stop.stopNameRAW.includes('SBL')
|
|
||||||
)
|
|
||||||
acc.push(`<span style='color:${stop.confirmed ? 'springgreen' : 'lightgray'}'>${stop.stopName}</span>`);
|
|
||||||
return acc;
|
|
||||||
}, [])
|
|
||||||
.join(' > ');
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
currentDistance(stops: TrainStop[]) {
|
name: 'mass',
|
||||||
return stops.filter(stop => stop.confirmed).slice(-1)[0]?.stopDistance || 0;
|
unit: 't',
|
||||||
|
multiplier: 0.001,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
|
||||||
confirmedPercentage(stops: TrainStop[]) {
|
position: [
|
||||||
return Number(((stops.filter((stop) => stop.confirmed).length / stops.length) * 100).toFixed(0));
|
{
|
||||||
|
name: 'scenery',
|
||||||
|
prop: 'currentStationName',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
currentDelay(stops: TrainStop[]) {
|
name: 'route',
|
||||||
const delay =
|
prop: 'connectedTrack',
|
||||||
stops.find((stop, i) => (i == 0 && !stop.confirmed) || (i > 0 && stops[i - 1].confirmed && !stop.confirmed))
|
|
||||||
?.departureDelay || 0;
|
|
||||||
|
|
||||||
if (delay > 0) return `<span style='color: salmon'>${this.$t('trains.delayed')} ${delay} min</span>`;
|
|
||||||
else if (delay < 0) return `<span style='color: lightgreen'>${this.$t('trains.preponed')} ${delay} min</span>`;
|
|
||||||
else return this.$t('trains.on-time');
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
displayLocoInfo(locoType: string) {
|
name: 'signal',
|
||||||
if (locoType.includes('EN')) return `${this.$t('trains.EZT')}`;
|
prop: 'signal',
|
||||||
if (locoType.includes('SN')) return `${this.$t('trains.SZT')}`;
|
|
||||||
if (locoType.startsWith('E')) return `${this.$t('trains.loco-electric')}`;
|
|
||||||
if (locoType.startsWith('S')) return `${this.$t('trains.loco-diesel')}`;
|
|
||||||
|
|
||||||
return '';
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
getSceneriesWithComments(timetableData: Train['timetableData']) {
|
name: 'distance',
|
||||||
const commentList = timetableData?.followingStops.reduce((acc, stop, i) => {
|
prop: 'distance',
|
||||||
if (stop.comments) acc.push(stop.stopNameRAW);
|
unit: 'm',
|
||||||
|
|
||||||
return acc;
|
|
||||||
}, [] as string[]) || []
|
|
||||||
|
|
||||||
const moreCount = commentList.length - 10;
|
|
||||||
|
|
||||||
|
|
||||||
return commentList.slice(0, 10).join(", ") + (moreCount > 0 ? `... (+${moreCount})` : '');
|
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
displayDistance(distance: number) {
|
methods: {
|
||||||
if (distance < 1000) return `${distance}m`;
|
lastSeenMessage(timestamp: number) {
|
||||||
|
const diff = Date.now() - timestamp;
|
||||||
|
const diffMins = Math.floor(diff / 60000);
|
||||||
|
|
||||||
return `${(distance / 1000).toPrecision(2)}km`;
|
return diffMins < 1
|
||||||
},
|
? this.$t('trains.last-seen-now')
|
||||||
|
: diffMins < 2
|
||||||
|
? this.$t('trains.last-seen-min')
|
||||||
|
: this.$t('trains.last-seen-ago', { minutes: diffMins });
|
||||||
|
},
|
||||||
|
|
||||||
onImageError(e: Event) {
|
displayStopList(stops: TrainStop[]): string | undefined {
|
||||||
const imageEl = e.target as HTMLImageElement;
|
if (!stops) return '';
|
||||||
imageEl.src = require('@/assets/unknown.png');
|
|
||||||
}
|
return stops
|
||||||
}
|
.reduce((acc: string[], stop: TrainStop, i: number) => {
|
||||||
})
|
if (stop.stopType.includes('ph') && !stop.stopNameRAW.includes('po.'))
|
||||||
|
acc.push(`<strong style='color:${stop.confirmed ? 'springgreen' : 'white'}'>${stop.stopName}</strong>`);
|
||||||
|
else if (
|
||||||
|
i > 0 &&
|
||||||
|
i < stops.length - 1 &&
|
||||||
|
!stop.stopNameRAW.includes('po.') &&
|
||||||
|
!stop.stopNameRAW.includes('SBL')
|
||||||
|
)
|
||||||
|
acc.push(`<span style='color:${stop.confirmed ? 'springgreen' : 'lightgray'}'>${stop.stopName}</span>`);
|
||||||
|
return acc;
|
||||||
|
}, [])
|
||||||
|
.join(' > ');
|
||||||
|
},
|
||||||
|
|
||||||
|
currentDistance(stops: TrainStop[]) {
|
||||||
|
return stops.filter((stop) => stop.confirmed).slice(-1)[0]?.stopDistance || 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
confirmedPercentage(stops: TrainStop[]) {
|
||||||
|
return Number(((stops.filter((stop) => stop.confirmed).length / stops.length) * 100).toFixed(0));
|
||||||
|
},
|
||||||
|
|
||||||
|
currentDelay(stops: TrainStop[]) {
|
||||||
|
const delay =
|
||||||
|
stops.find((stop, i) => (i == 0 && !stop.confirmed) || (i > 0 && stops[i - 1].confirmed && !stop.confirmed))
|
||||||
|
?.departureDelay || 0;
|
||||||
|
|
||||||
|
if (delay > 0) return `<span style='color: salmon'>${this.$t('trains.delayed')} ${delay} min</span>`;
|
||||||
|
else if (delay < 0) return `<span style='color: lightgreen'>${this.$t('trains.preponed')} ${delay} min</span>`;
|
||||||
|
else return this.$t('trains.on-time');
|
||||||
|
},
|
||||||
|
|
||||||
|
displayLocoInfo(locoType: string) {
|
||||||
|
if (locoType.includes('EN')) return `${this.$t('trains.EZT')}`;
|
||||||
|
if (locoType.includes('SN')) return `${this.$t('trains.SZT')}`;
|
||||||
|
if (locoType.startsWith('E')) return `${this.$t('trains.loco-electric')}`;
|
||||||
|
if (locoType.startsWith('S')) return `${this.$t('trains.loco-diesel')}`;
|
||||||
|
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
|
||||||
|
getSceneriesWithComments(timetableData: Train['timetableData']) {
|
||||||
|
const commentList =
|
||||||
|
timetableData?.followingStops.reduce((acc, stop, i) => {
|
||||||
|
if (stop.comments) acc.push(stop.stopNameRAW);
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, [] as string[]) || [];
|
||||||
|
|
||||||
|
const moreCount = commentList.length - 10;
|
||||||
|
|
||||||
|
return commentList.slice(0, 10).join(', ') + (moreCount > 0 ? `... (+${moreCount})` : '');
|
||||||
|
},
|
||||||
|
|
||||||
|
displayDistance(distance: number) {
|
||||||
|
if (distance < 1000) return `${distance}m`;
|
||||||
|
|
||||||
|
return `${(distance / 1000).toPrecision(2)}km`;
|
||||||
|
},
|
||||||
|
|
||||||
|
onImageError(e: Event) {
|
||||||
|
const imageEl = e.target as HTMLImageElement;
|
||||||
|
imageEl.src = require('@/assets/unknown.png');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export default interface Train {
|
|||||||
locoURL: string;
|
locoURL: string;
|
||||||
locoType: string;
|
locoType: string;
|
||||||
online: boolean;
|
online: boolean;
|
||||||
|
lastSeen: number;
|
||||||
region: string;
|
region: string;
|
||||||
|
|
||||||
cars: string[];
|
cars: string[];
|
||||||
|
|||||||
+6
-6
@@ -1,11 +1,8 @@
|
|||||||
import { DataStatus } from '@/scripts/enums/DataStatus';
|
import { DataStatus } from '@/scripts/enums/DataStatus';
|
||||||
import { DispatcherStatsAPIData } from '@/scripts/interfaces/api/DispatcherStatsAPIData';
|
|
||||||
import StationAPIData from '@/scripts/interfaces/api/StationAPIData';
|
import StationAPIData from '@/scripts/interfaces/api/StationAPIData';
|
||||||
import TrainAPIData from '@/scripts/interfaces/api/TrainAPIData';
|
|
||||||
import ScheduledTrain from '@/scripts/interfaces/ScheduledTrain';
|
import ScheduledTrain from '@/scripts/interfaces/ScheduledTrain';
|
||||||
import Station from '@/scripts/interfaces/Station';
|
import Station from '@/scripts/interfaces/Station';
|
||||||
import StationRoutes from '@/scripts/interfaces/StationRoutes';
|
import StationRoutes from '@/scripts/interfaces/StationRoutes';
|
||||||
import { StoreData } from '@/scripts/interfaces/StoreData';
|
|
||||||
import Train from '@/scripts/interfaces/Train';
|
import Train from '@/scripts/interfaces/Train';
|
||||||
import { URLs } from '@/scripts/utils/apiURLs';
|
import { URLs } from '@/scripts/utils/apiURLs';
|
||||||
import {
|
import {
|
||||||
@@ -62,7 +59,10 @@ export const useStore = defineStore('store', {
|
|||||||
if (!trains) return [];
|
if (!trains) return [];
|
||||||
|
|
||||||
this.trainList = trains
|
this.trainList = trains
|
||||||
.filter((train) => train.region === this.region.id)
|
.filter(
|
||||||
|
(train) =>
|
||||||
|
train.region === this.region.id && (train.online || train.timetable || train.lastSeen > Date.now() - 180000)
|
||||||
|
)
|
||||||
.map((train) => {
|
.map((train) => {
|
||||||
const stock = train.stockString.split(';');
|
const stock = train.stockString.split(';');
|
||||||
const locoType = stock ? stock[0] : train.stockString;
|
const locoType = stock ? stock[0] : train.stockString;
|
||||||
@@ -88,6 +88,8 @@ export const useStore = defineStore('store', {
|
|||||||
locoURL: getLocoURL(locoType),
|
locoURL: getLocoURL(locoType),
|
||||||
cars: stock.slice(1),
|
cars: stock.slice(1),
|
||||||
|
|
||||||
|
lastSeen: train.lastSeen,
|
||||||
|
|
||||||
timetableData: timetable
|
timetableData: timetable
|
||||||
? {
|
? {
|
||||||
timetableId: timetable.timetableId,
|
timetableId: timetable.timetableId,
|
||||||
@@ -206,7 +208,6 @@ export const useStore = defineStore('store', {
|
|||||||
const prevDispatcherStatuses: StoreState['lastDispatcherStatuses'] = [];
|
const prevDispatcherStatuses: StoreState['lastDispatcherStatuses'] = [];
|
||||||
|
|
||||||
this.apiData.stations?.forEach((stationAPIData) => {
|
this.apiData.stations?.forEach((stationAPIData) => {
|
||||||
|
|
||||||
if (stationAPIData.region !== this.region.id || !stationAPIData.isOnline) return;
|
if (stationAPIData.region !== this.region.id || !stationAPIData.isOnline) return;
|
||||||
const station = this.stationList.find((s) => s.name === stationAPIData.stationName);
|
const station = this.stationList.find((s) => s.name === stationAPIData.stationName);
|
||||||
|
|
||||||
@@ -345,7 +346,6 @@ export const useStore = defineStore('store', {
|
|||||||
this.setOnlineData();
|
this.setOnlineData();
|
||||||
|
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.emit('FETCH_DATA', {}, (data: APIData) => {
|
socket.emit('FETCH_DATA', {}, (data: APIData) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user