feat: journal timetable view mode

This commit is contained in:
2025-04-25 02:14:45 +02:00
parent 3b68056acc
commit 17d5574d0c
15 changed files with 628 additions and 224 deletions
+85 -5
View File
@@ -1,8 +1,19 @@
import type { AxiosInstance } from 'axios';
import axios from 'axios';
import { defineStore } from 'pinia';
import { DataStatus, type ActiveDataResponse, type SceneriesDataResponse } from '../types/api.types';
import type { ActiveData, SceneryData } from '../types/common.types';
import {
DataStatus,
type ActiveDataResponse,
type SceneriesDataResponse,
type JournalTimetablesShortResponse
} from '../types/api.types';
import type {
ActiveData,
JournalTimetableDetailed,
JournalTimetableShort,
SceneryData
} from '../types/common.types';
import { useGlobalStore } from './global.store';
export const useApiStore = defineStore('api', {
state() {
@@ -11,11 +22,13 @@ export const useApiStore = defineStore('api', {
activeData: null as ActiveData | null,
sceneryData: null as SceneryData[] | null,
journalTimetablesData: null as JournalTimetableShort[] | null,
outdatedTimerId: -1,
isActiveDataOutdated: false,
activeDataStatus: DataStatus.LOADING,
journalDataStatus: DataStatus.SUCCESS
};
},
@@ -37,13 +50,12 @@ export const useApiStore = defineStore('api', {
}
this.client = axios.create({
baseURL,
baseURL
});
this.fetchSceneriesData();
await this.fetchActiveData();
setInterval(() => {
this.fetchActiveData();
}, 25000);
@@ -76,5 +88,73 @@ export const useApiStore = defineStore('api', {
console.error(error);
}
},
},
async fetchJournalTimetables(searchValue: string) {
// if (searchValue.trim().length == 0) {
// this.journalDataStatus = DataStatus.SUCCESS;
// this.journalTimetablesData = null;
// return;
// }
let searchObj: Record<string, any> = {};
const searchParams = searchValue.split(' ');
searchParams.forEach((param) => {
const [key, value] = param.split(':');
if (key == 'nick') searchObj['driverName'] = value;
else if (key == 'date') {
let dateFromStr = new Date(value).toISOString();
let dateTo = new Date(dateFromStr);
dateTo.setDate(dateTo.getDate() + 1);
searchObj['dateFrom'] = dateFromStr;
searchObj['dateTo'] = dateTo.toISOString();
} else if (key == 'from') searchObj['issuedFrom'] = value.replace(/_/g, ' ');
else if (key == 'to') searchObj['terminatingAt'] = value.replace(/_/g, ' ');
});
searchObj['hasStopsDetails'] = 1;
searchObj['returnType'] = 'short';
try {
this.journalDataStatus = DataStatus.LOADING;
const response = (
await this.client!.get<JournalTimetablesShortResponse>('/api/getTimetables', {
params: searchObj
})
).data;
this.journalDataStatus = DataStatus.SUCCESS;
this.journalTimetablesData = response;
} catch (error) {
this.journalDataStatus = DataStatus.ERROR;
this.journalTimetablesData = null;
console.error(error);
}
},
async fetchJournalTimetableDetails(id: number) {
const globalStore = useGlobalStore();
try {
const response = (
await this.client!.get<JournalTimetableDetailed[]>('/api/getTimetables', {
params: {
timetableId: id,
hasStopsDetails: 1
}
})
).data;
if (response.length > 0) globalStore.selectedJournalTimetable = response[0];
} catch (error) {
globalStore.selectedJournalTimetable = null;
console.error(error);
}
}
}
});
+56 -13
View File
@@ -1,6 +1,12 @@
import { defineStore } from 'pinia';
import { useApiStore } from './api.store';
import type { ActiveTrain, TimetableData, ViewMode } from '../types/common.types';
import type {
ActiveTrain,
JournalTimetableDetailed,
JournalTimetableShort,
TimetableData,
ViewMode
} from '../types/common.types';
import { unitNameCorrections } from '../utils/trainUtils';
export const useGlobalStore = defineStore('global', {
@@ -11,6 +17,8 @@ export const useGlobalStore = defineStore('global', {
selectedTrainId: null as string | null,
selectedActiveTrain: null as ActiveTrain | null,
selectedStorageTimetable: null as TimetableData | null,
selectedJournalTimetable: null as JournalTimetableDetailed | null,
storageTimetables: {} as Record<number, TimetableData>,
timetableWarnings: [] as string[],
@@ -18,9 +26,10 @@ export const useGlobalStore = defineStore('global', {
generatedDate: null as Date | null,
generatedMs: 0,
timetableSearch: '',
localTimetableSearch: '',
journalTimetableSearch: '',
showSettings: false,
showSettings: false
}),
getters: {
activeTimetableTrains() {
@@ -28,7 +37,9 @@ export const useGlobalStore = defineStore('global', {
if (!apiStore.activeData) return [];
return apiStore.activeData.trains.filter((train) => train.timetable).sort((t1, t2) => t1.driverName.localeCompare(t2.driverName, 'pl-PL'));
return apiStore.activeData.trains
.filter((train) => train.timetable)
.sort((t1, t2) => t1.driverName.localeCompare(t2.driverName, 'pl-PL'));
},
currentTimetableData(): TimetableData | null {
@@ -52,12 +63,14 @@ export const useGlobalStore = defineStore('global', {
trainMaxSpeed: selectedTrain.timetable.trainMaxSpeed,
timetableId: selectedTrain.timetable.timetableId,
stopListString: selectedTrain.timetable.stopList
.filter((stop) => stop.mainStop || (/^podg|po|pe$/.test(stop.stopNameRAW)))
.filter((stop) => stop.mainStop || /^podg|po|pe$/.test(stop.stopNameRAW))
.map(
(stop) =>
`${stop.arrivalLine ?? ''};${stop.arrivalTimestamp};${stop.stopNameRAW};${stop.stopTime ? stop.stopTime + '_' + stop.stopType : ''};${
stop.mainStop
};${stop.stopDistance};${stop.departureTimestamp};${stop.departureLine ?? ''}`
`${stop.arrivalLine ?? ''};${stop.arrivalTimestamp};${stop.stopNameRAW};${
stop.stopTime ? stop.stopTime + '_' + stop.stopType : ''
};${stop.mainStop};${stop.stopDistance};${stop.departureTimestamp};${
stop.departureLine ?? ''
}`
)
.join('~~'),
headUnits: selectedTrain.stockString
@@ -68,13 +81,43 @@ export const useGlobalStore = defineStore('global', {
const unitName = s.slice(0, s.indexOf('-'));
return unitNameCorrections[unitName] ?? unitName;
}),
})
};
} else if (this.viewMode == 'journal') {
const selectedTimetable = this.selectedJournalTimetable;
if (!selectedTimetable || !selectedTimetable.stopListString) return null;
return {
journalCreatedAt: new Date(selectedTimetable.createdAt).getTime(),
trainNo: selectedTimetable.trainNo,
mass: selectedTimetable.stockMass,
length: selectedTimetable.stockLength,
driverId: selectedTimetable.driverId,
driverName: selectedTimetable.driverName,
category: selectedTimetable.trainCategoryCode,
hasDangerousCargo: selectedTimetable.hasDangerousCargo,
hasExtraDeliveries: selectedTimetable.hasExtraDeliveries,
warningNotes: selectedTimetable.warningNotes,
path: selectedTimetable.path,
route: selectedTimetable.route,
trainMaxSpeed: selectedTimetable.trainMaxSpeed,
timetableId: selectedTimetable.id,
stopListString: selectedTimetable.stopListString,
headUnits: selectedTimetable.stockString
.split(';')
.slice(0, 3)
.filter((s, i) => i == 0 || /-\d+$/.test(s))
.map((s) => {
const unitName = s.slice(0, s.indexOf('-'));
return unitNameCorrections[unitName] ?? unitName;
})
};
} else {
const selectedStorageTimetable = this.selectedStorageTimetable;
return selectedStorageTimetable;
return this.selectedStorageTimetable;
}
},
}
},
actions: {},
actions: {}
});