mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 13:28:11 +00:00
refactor(journal): fetching heavy timetable details separately on demand
This commit is contained in:
@@ -19,209 +19,243 @@
|
||||
<div class="details-body" v-if="showExtraInfo">
|
||||
<div class="g-separator"></div>
|
||||
|
||||
<EntryStops :timetable="timetable" />
|
||||
<div v-if="timetableDetails">
|
||||
<EntryStops :timetable="timetableDetails" />
|
||||
|
||||
<div class="g-separator"></div>
|
||||
|
||||
<div class="timetable-specs">
|
||||
<span class="badge specs-badge" v-if="timetable.authorName">
|
||||
<span>{{ $t('journal.dispatcher-name') }}</span>
|
||||
<span>{{ timetable.authorName }}</span>
|
||||
</span>
|
||||
|
||||
<span class="badge specs-badge" v-if="timetable.trainMaxSpeed">
|
||||
<span>{{ $t('journal.stock-timetable-speed') }}</span>
|
||||
<span> {{ timetable.trainMaxSpeed }}km/h </span>
|
||||
</span>
|
||||
|
||||
<span class="badge specs-badge" v-if="timetable.maxSpeed">
|
||||
<span>{{ $t('journal.stock-max-speed') }}</span>
|
||||
<span>{{ timetable.maxSpeed }}km/h</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="stock-dangers" v-if="timetable.warningNotes">
|
||||
<div class="g-separator"></div>
|
||||
|
||||
<b>{{ $t('journal.stock-dangers') }}:</b>
|
||||
|
||||
<ul>
|
||||
<li v-if="timetable.twr">
|
||||
<b class="text--primary">{{ $t('warnings.TWR') }} (TWR)</b>
|
||||
</li>
|
||||
|
||||
<li v-if="timetable.skr">
|
||||
<b class="text--primary">{{ $t('warnings.SKR') }}</b>
|
||||
</li>
|
||||
|
||||
<li v-if="timetable.hasDangerousCargo">
|
||||
<b class="text--primary">{{ $t('warnings.TN') }}</b>
|
||||
</li>
|
||||
|
||||
<li v-if="timetable.hasExtraDeliveries">
|
||||
<b class="text--primary">{{ $t('warnings.PN') }}</b>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="dangers-notes" v-if="timetable.warningNotes">
|
||||
<h4>{{ $t('warnings.header-title') }}</h4>
|
||||
<p>
|
||||
<i>{{ timetable.warningNotes }}</i>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Historia zmian w składzie -->
|
||||
<div v-if="timetable.stockString || stockHistory.length != 0">
|
||||
<div class="g-separator"></div>
|
||||
|
||||
<b>{{ $t('journal.stock-preview') }}:</b>
|
||||
|
||||
<div class="stock-specs" style="margin-top: 0.5em">
|
||||
<span class="badge specs-badge" v-if="timetable.stockLength">
|
||||
<span>{{ $t('journal.stock-length') }}</span>
|
||||
<span>
|
||||
{{
|
||||
currentHistoryIndex == 0
|
||||
? timetable.stockLength
|
||||
: stockHistory[currentHistoryIndex].stockLength || timetable.stockLength
|
||||
}}m
|
||||
</span>
|
||||
<div class="timetable-specs">
|
||||
<span class="badge specs-badge" v-if="timetableDetails.authorName">
|
||||
<span>{{ $t('journal.dispatcher-name') }}</span>
|
||||
<span>{{ timetableDetails.authorName }}</span>
|
||||
</span>
|
||||
|
||||
<span class="badge specs-badge" v-if="timetable.stockMass">
|
||||
<span>{{ $t('journal.stock-mass') }}</span>
|
||||
<span>
|
||||
{{
|
||||
Math.floor(
|
||||
(currentHistoryIndex == 0
|
||||
? timetable.stockMass
|
||||
: stockHistory[currentHistoryIndex].stockMass || timetable.stockMass) / 1000
|
||||
)
|
||||
}}t
|
||||
</span>
|
||||
<span class="badge specs-badge" v-if="timetableDetails.trainMaxSpeed">
|
||||
<span>{{ $t('journal.stock-timetable-speed') }}</span>
|
||||
<span> {{ timetableDetails.trainMaxSpeed }}km/h </span>
|
||||
</span>
|
||||
|
||||
<span class="badge specs-badge" v-if="timetableDetails.maxSpeed">
|
||||
<span>{{ $t('journal.stock-max-speed') }}</span>
|
||||
<span>{{ timetableDetails.maxSpeed }}km/h</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="stock-history">
|
||||
<button class="btn btn--action" @click="copyStockToClipboard()">
|
||||
<i class="fa-regular fa-copy"></i> {{ $t('journal.stock-copy') }}
|
||||
</button>
|
||||
<div class="stock-dangers" v-if="timetableDetails.warningNotes">
|
||||
<div class="g-separator"></div>
|
||||
|
||||
<button
|
||||
v-for="(sh, i) in stockHistory"
|
||||
:key="i"
|
||||
class="btn--action"
|
||||
:data-checked="i == currentHistoryIndex"
|
||||
@click.stop="currentHistoryIndex = i"
|
||||
>
|
||||
{{ sh.updatedAt }}
|
||||
</button>
|
||||
<b>{{ $t('journal.stock-dangers') }}:</b>
|
||||
|
||||
<ul>
|
||||
<li v-if="timetableDetails.twr">
|
||||
<b class="text--primary">{{ $t('warnings.TWR') }} (TWR)</b>
|
||||
</li>
|
||||
|
||||
<li v-if="timetableDetails.skr">
|
||||
<b class="text--primary">{{ $t('warnings.SKR') }}</b>
|
||||
</li>
|
||||
|
||||
<li v-if="timetableDetails.hasDangerousCargo">
|
||||
<b class="text--primary">{{ $t('warnings.TN') }}</b>
|
||||
</li>
|
||||
|
||||
<li v-if="timetableDetails.hasExtraDeliveries">
|
||||
<b class="text--primary">{{ $t('warnings.PN') }}</b>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="dangers-notes" v-if="timetableDetails.warningNotes">
|
||||
<h4>{{ $t('warnings.header-title') }}</h4>
|
||||
<p>
|
||||
<i>{{ timetableDetails.warningNotes }}</i>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="timetable.stockString" style="margin-top: 1em">
|
||||
<StockList
|
||||
:trainStockList="
|
||||
(currentHistoryIndex == 0
|
||||
? timetable.stockString
|
||||
: stockHistory[currentHistoryIndex].stockString
|
||||
).split(';')
|
||||
"
|
||||
/>
|
||||
<!-- Historia zmian w składzie -->
|
||||
<div v-if="timetableDetails.stockString || stockHistory.length != 0">
|
||||
<div class="g-separator"></div>
|
||||
|
||||
<b>{{ $t('journal.stock-preview') }}:</b>
|
||||
|
||||
<div class="stock-specs" style="margin-top: 0.5em">
|
||||
<span class="badge specs-badge" v-if="timetableDetails.stockLength">
|
||||
<span>{{ $t('journal.stock-length') }}</span>
|
||||
<span>
|
||||
{{
|
||||
currentHistoryIndex == 0
|
||||
? timetableDetails.stockLength
|
||||
: stockHistory[currentHistoryIndex].stockLength || timetableDetails.stockLength
|
||||
}}m
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span class="badge specs-badge" v-if="timetableDetails.stockMass">
|
||||
<span>{{ $t('journal.stock-mass') }}</span>
|
||||
<span>
|
||||
{{
|
||||
Math.floor(
|
||||
(currentHistoryIndex == 0
|
||||
? timetableDetails.stockMass
|
||||
: stockHistory[currentHistoryIndex].stockMass || timetableDetails.stockMass) /
|
||||
1000
|
||||
)
|
||||
}}t
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="stock-history">
|
||||
<button class="btn btn--action" @click="copyStockToClipboard()">
|
||||
<i class="fa-regular fa-copy"></i> {{ $t('journal.stock-copy') }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
v-for="(sh, i) in stockHistory"
|
||||
:key="i"
|
||||
class="btn--action"
|
||||
:data-checked="i == currentHistoryIndex"
|
||||
@click.stop="currentHistoryIndex = i"
|
||||
>
|
||||
{{ sh.updatedAt }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="timetableDetails.stockString" style="margin-top: 1em">
|
||||
<StockList
|
||||
:trainStockList="
|
||||
(currentHistoryIndex == 0
|
||||
? timetableDetails.stockString
|
||||
: stockHistory[currentHistoryIndex].stockString
|
||||
).split(';')
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { PropType, defineComponent } from 'vue';
|
||||
import StockList from '../../Global/StockList.vue';
|
||||
import { API } from '../../../typings/api';
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineComponent, onActivated, onMounted, ref, watch } from 'vue';
|
||||
import { RouteLocationRaw } from 'vue-router';
|
||||
import EntryStops from './EntryStops.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
export default defineComponent({
|
||||
components: { StockList, EntryStops },
|
||||
import StockList from '../../Global/StockList.vue';
|
||||
import EntryStops from './EntryStops.vue';
|
||||
import { API } from '../../../typings/api';
|
||||
import { useApiStore } from '../../../store/apiStore';
|
||||
|
||||
emits: ['toggleExtraInfo'],
|
||||
const i18n = useI18n();
|
||||
const apiStore = useApiStore();
|
||||
|
||||
props: {
|
||||
showExtraInfo: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
timetable: {
|
||||
type: Object as PropType<API.TimetableHistory.Data>,
|
||||
required: true
|
||||
}
|
||||
const props = defineProps({
|
||||
showExtraInfo: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentHistoryIndex: 0,
|
||||
i18n: useI18n()
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
stockHistory() {
|
||||
return this.timetable.stockHistory
|
||||
.slice()
|
||||
.reverse()
|
||||
.map((h) => {
|
||||
const historyData = h.split('@');
|
||||
return {
|
||||
updatedAt: new Date(Number(historyData[0])).toLocaleTimeString(this.$i18n.locale, {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
}),
|
||||
stockString: historyData[1],
|
||||
stockMass: Number(historyData[2]) || undefined,
|
||||
stockLength: Number(historyData[3]) || undefined
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
driverRouteLocation(): RouteLocationRaw | null {
|
||||
if (this.timetable.terminated) return null;
|
||||
return {
|
||||
name: 'DriverView',
|
||||
query: {
|
||||
trainId: `${this.timetable.driverId}|${this.timetable.trainNo}|eu`
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onImageError(e: Event) {
|
||||
const imageEl = e.target as HTMLImageElement;
|
||||
imageEl.src = '/images/icon-unknown.png';
|
||||
},
|
||||
|
||||
toggleExtraInfo() {
|
||||
this.$emit('toggleExtraInfo', this.timetable.id);
|
||||
},
|
||||
|
||||
copyStockToClipboard() {
|
||||
const currentStockString =
|
||||
this.stockHistory[this.currentHistoryIndex]?.stockString ?? this.timetable.stockString;
|
||||
|
||||
if (!currentStockString) {
|
||||
alert(this.i18n.t('journal.stock-clipboard-failure'));
|
||||
return;
|
||||
}
|
||||
|
||||
navigator.clipboard
|
||||
.writeText(currentStockString)
|
||||
.then(() => {
|
||||
prompt(this.i18n.t('journal.stock-clipboard-success'), currentStockString);
|
||||
})
|
||||
.catch(() => {
|
||||
alert(this.i18n.t('journal.stock-clipboard-failure'));
|
||||
});
|
||||
}
|
||||
timetableId: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const emits = defineEmits(['toggleExtraInfo']);
|
||||
const currentHistoryIndex = ref(0);
|
||||
|
||||
const timetableDetails = ref<API.TimetableHistory.Data | null>(null);
|
||||
|
||||
watch(
|
||||
computed(() => props.showExtraInfo),
|
||||
(state) => {
|
||||
if (state == true) {
|
||||
fetchTimetableDetails();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const stockHistory = computed(() => {
|
||||
return (
|
||||
timetableDetails.value?.stockHistory
|
||||
.slice()
|
||||
.reverse()
|
||||
.map((h) => {
|
||||
const historyData = h.split('@');
|
||||
return {
|
||||
updatedAt: new Date(Number(historyData[0])).toLocaleTimeString(i18n.locale.value, {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
}),
|
||||
stockString: historyData[1],
|
||||
stockMass: Number(historyData[2]) || undefined,
|
||||
stockLength: Number(historyData[3]) || undefined
|
||||
};
|
||||
}) ?? []
|
||||
);
|
||||
});
|
||||
|
||||
const driverRouteLocation = computed<RouteLocationRaw | null>(() => {
|
||||
if (!timetableDetails.value || timetableDetails.value.terminated) return null;
|
||||
|
||||
return {
|
||||
name: 'DriverView',
|
||||
query: {
|
||||
trainId: `${timetableDetails.value.driverId}|${timetableDetails.value.trainNo}|eu`
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
async function fetchTimetableDetails() {
|
||||
try {
|
||||
const responseData = await apiStore.client!.get<API.TimetableHistory.Response>(
|
||||
'api/getTimetables',
|
||||
{
|
||||
params: {
|
||||
timetableId: props.timetableId,
|
||||
returnType: 'detailed'
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (!responseData || responseData.data.length != 1) {
|
||||
timetableDetails.value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
timetableDetails.value = responseData.data[0];
|
||||
} catch (error) {
|
||||
// this.dataStatus = Status.Data.Error;
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleExtraInfo() {
|
||||
emits('toggleExtraInfo', props.timetableId);
|
||||
}
|
||||
|
||||
function copyStockToClipboard() {
|
||||
if (!timetableDetails.value) return;
|
||||
|
||||
const currentStockString =
|
||||
stockHistory.value[currentHistoryIndex.value]?.stockString ??
|
||||
timetableDetails.value.stockString;
|
||||
|
||||
if (!currentStockString) {
|
||||
alert(i18n.t('journal.stock-clipboard-failure'));
|
||||
return;
|
||||
}
|
||||
|
||||
navigator.clipboard
|
||||
.writeText(currentStockString)
|
||||
.then(() => {
|
||||
prompt(i18n.t('journal.stock-clipboard-success'), currentStockString);
|
||||
})
|
||||
.catch(() => {
|
||||
alert(i18n.t('journal.stock-clipboard-failure'));
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -299,7 +333,7 @@ hr {
|
||||
}
|
||||
}
|
||||
|
||||
@include responsive.smallScreen{
|
||||
@include responsive.smallScreen {
|
||||
.timetable-specs {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ export default defineComponent({
|
||||
|
||||
props: {
|
||||
timetable: {
|
||||
type: Object as PropType<API.TimetableHistory.Data>,
|
||||
type: Object as PropType<API.TimetableHistory.DataShort>,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ export default defineComponent({
|
||||
components: { ProgressBar },
|
||||
props: {
|
||||
timetable: {
|
||||
type: Object as PropType<API.TimetableHistory.Data>,
|
||||
type: Object as PropType<API.TimetableHistory.DataShort>,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<!-- Extra -->
|
||||
<EntryDetails
|
||||
:timetable="timetableEntry"
|
||||
:timetable-id="timetableEntry.id"
|
||||
:show-extra-info="showExtraInfo"
|
||||
@toggle-extra-info="toggleExtraInfo"
|
||||
/>
|
||||
@@ -28,7 +28,6 @@
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import { API } from '../../../typings/api';
|
||||
import { useApiStore } from '../../../store/apiStore';
|
||||
import { Journal } from '../typings';
|
||||
|
||||
import trainCategoryMixin from '../../../mixins/trainCategoryMixin';
|
||||
import dateMixin from '../../../mixins/dateMixin';
|
||||
@@ -41,7 +40,7 @@ import EntryDetails from './EntryDetails.vue';
|
||||
export default defineComponent({
|
||||
props: {
|
||||
timetableEntry: {
|
||||
type: Object as PropType<API.TimetableHistory.Data>,
|
||||
type: Object as PropType<API.TimetableHistory.DataShort>,
|
||||
required: true
|
||||
},
|
||||
showExtraInfo: {
|
||||
@@ -60,71 +59,6 @@ export default defineComponent({
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
timetablePathDetails() {
|
||||
if (!this.timetableEntry.path || this.timetableEntry.path == '') return null;
|
||||
|
||||
return this.timetableEntry.path.split(';').map((pathEl, i) => {
|
||||
const [arrival, name, departure] = pathEl.split(',');
|
||||
const sceneryName = name.split(' ').slice(0, -1).join(' ');
|
||||
const sceneryHash = name.split(' ').pop()?.replace('.sc', '') ?? '';
|
||||
|
||||
return {
|
||||
arrival,
|
||||
sceneryName,
|
||||
sceneryHash,
|
||||
departure,
|
||||
isVisited: this.timetableEntry.visitedSceneries?.includes(sceneryHash) ?? false
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
timetableStops(): Journal.TimetableStopDetails[] {
|
||||
const timetableEntry = this.timetableEntry;
|
||||
|
||||
const stopNames = timetableEntry.sceneriesString.split('%');
|
||||
|
||||
return stopNames.reduce<Journal.TimetableStopDetails[]>((acc, stopName, i, arr) => {
|
||||
const arrivalDate =
|
||||
i == arr.length - 1
|
||||
? (timetableEntry.checkpointArrivals.at(i) ?? timetableEntry.endDate)
|
||||
: timetableEntry.checkpointArrivals.at(i);
|
||||
|
||||
const scheduledArrivalDate =
|
||||
i == arr.length - 1
|
||||
? (timetableEntry.checkpointArrivalsScheduled.at(i) ?? timetableEntry.scheduledEndDate)
|
||||
: timetableEntry.checkpointArrivalsScheduled.at(i);
|
||||
|
||||
const departureDate =
|
||||
i == 0
|
||||
? (timetableEntry.checkpointDepartures.at(i) ?? timetableEntry.beginDate)
|
||||
: timetableEntry.checkpointDepartures.at(i);
|
||||
|
||||
const scheduledDepartureDate =
|
||||
i == 0
|
||||
? (timetableEntry.checkpointDeparturesScheduled.at(i) ??
|
||||
timetableEntry.scheduledBeginDate)
|
||||
: timetableEntry.checkpointDeparturesScheduled.at(i);
|
||||
|
||||
const stopTime = Number(timetableEntry.checkpointStopTypes.at(i)?.split(',')[0]) || 0;
|
||||
const stopType = timetableEntry.checkpointStopTypes.at(i)?.split(',')[1] || '';
|
||||
|
||||
acc.push({
|
||||
stopName,
|
||||
arrivalTimestamp: this.dateStringToTimestamp(arrivalDate),
|
||||
scheduledArrivalTimestamp: this.dateStringToTimestamp(scheduledArrivalDate),
|
||||
departureTimestamp: this.dateStringToTimestamp(departureDate),
|
||||
scheduledDepartureTimestamp: this.dateStringToTimestamp(scheduledDepartureDate),
|
||||
stopTime,
|
||||
stopType,
|
||||
isConfirmed: i < timetableEntry.confirmedStopsCount
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleExtraInfo() {
|
||||
this.$emit('toggleShowExtraInfo');
|
||||
@@ -145,7 +79,7 @@ export default defineComponent({
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@include responsive.smallScreen{
|
||||
@include responsive.smallScreen {
|
||||
.entry-route {
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
|
||||
@@ -61,7 +61,7 @@ export default defineComponent({
|
||||
|
||||
props: {
|
||||
timetableHistory: {
|
||||
type: Array as PropType<API.TimetableHistory.Response>,
|
||||
type: Array as PropType<API.TimetableHistory.ResponseShort>,
|
||||
required: true
|
||||
},
|
||||
scrollNoMoreData: {
|
||||
|
||||
+72
-28
@@ -1,3 +1,4 @@
|
||||
import { Journal } from '../components/JournalView/typings';
|
||||
import { Status, Vehicle, VehicleGroup } from './common';
|
||||
|
||||
export enum APIDataStatus {
|
||||
@@ -225,35 +226,40 @@ export namespace API {
|
||||
}
|
||||
|
||||
export namespace TimetableHistory {
|
||||
export interface Data extends DataShort {
|
||||
export interface QueryParams {
|
||||
driverName?: string;
|
||||
trainNo?: string;
|
||||
timetableId?: string;
|
||||
categoryCode?: string;
|
||||
|
||||
authorName?: string;
|
||||
|
||||
dateFrom?: string;
|
||||
dateTo?: string;
|
||||
|
||||
issuedFrom?: string;
|
||||
terminatingAt?: string;
|
||||
via?: string;
|
||||
includesScenery?: string;
|
||||
|
||||
countFrom?: number;
|
||||
countLimit?: number;
|
||||
|
||||
fulfilled?: number;
|
||||
terminated?: number;
|
||||
|
||||
twr?: number;
|
||||
skr?: number;
|
||||
pn?: number;
|
||||
tn?: number;
|
||||
|
||||
returnType?: 'all' | 'short' | 'detailed';
|
||||
|
||||
sortBy?: Journal.TimetableSorter['id'];
|
||||
}
|
||||
|
||||
export interface Data extends DataShort, DataDetailsOnly {
|
||||
updatedAt: string;
|
||||
|
||||
timetableId: number;
|
||||
sceneriesString: string;
|
||||
endDate: string;
|
||||
|
||||
scheduledBeginDate: string;
|
||||
scheduledEndDate: string;
|
||||
|
||||
stockString?: string;
|
||||
stockHistory: string[];
|
||||
|
||||
stockMass?: number;
|
||||
stockLength?: number;
|
||||
maxSpeed?: number;
|
||||
|
||||
routeSceneries: string;
|
||||
checkpointArrivals: string[];
|
||||
checkpointDepartures: string[];
|
||||
checkpointArrivalsScheduled: string[];
|
||||
checkpointDeparturesScheduled: string[];
|
||||
checkpointStopTypes: string[];
|
||||
checkpointComments: string[];
|
||||
visitedSceneries: string[];
|
||||
sceneryNames: string[];
|
||||
path: string;
|
||||
warningNotes: string | null;
|
||||
trainMaxSpeed?: number;
|
||||
}
|
||||
|
||||
export interface DataShort {
|
||||
@@ -261,6 +267,7 @@ export namespace API {
|
||||
createdAt: string;
|
||||
trainNo: number;
|
||||
trainCategoryCode: string;
|
||||
timetableId: number;
|
||||
|
||||
driverId: number;
|
||||
driverName: string;
|
||||
@@ -280,6 +287,9 @@ export namespace API {
|
||||
allStopsCount: number;
|
||||
|
||||
beginDate: string;
|
||||
endDate: string;
|
||||
scheduledBeginDate: string;
|
||||
scheduledEndDate: string;
|
||||
|
||||
terminated: boolean;
|
||||
fulfilled: boolean;
|
||||
@@ -293,8 +303,42 @@ export namespace API {
|
||||
hasExtraDeliveries: boolean;
|
||||
}
|
||||
|
||||
export interface DataDetailsOnly {
|
||||
id: number;
|
||||
timetableId: number;
|
||||
|
||||
sceneriesString: string;
|
||||
stockString?: string;
|
||||
stockHistory: string[];
|
||||
|
||||
stockMass?: number;
|
||||
stockLength?: number;
|
||||
maxSpeed?: number;
|
||||
trainMaxSpeed?: number;
|
||||
|
||||
routeSceneries: string;
|
||||
checkpointArrivals: string[];
|
||||
checkpointDepartures: string[];
|
||||
checkpointArrivalsScheduled: string[];
|
||||
checkpointDeparturesScheduled: string[];
|
||||
checkpointStopTypes: string[];
|
||||
checkpointComments: string[];
|
||||
visitedSceneries: string[];
|
||||
sceneryNames: string[];
|
||||
|
||||
path: string;
|
||||
warningNotes: string | null;
|
||||
|
||||
authorId?: number;
|
||||
authorName?: string;
|
||||
driverId: number;
|
||||
driverName: string;
|
||||
driverLanguageId: number | null;
|
||||
}
|
||||
|
||||
export type Response = Data[];
|
||||
export type ResponseShort = DataShort[];
|
||||
export type ResponseDetailsOnly = DataDetailsOnly[];
|
||||
}
|
||||
|
||||
export namespace DailyStats {
|
||||
|
||||
@@ -118,36 +118,6 @@ export const journalTimetableFilters: Journal.TimetableFilter[] = [
|
||||
}
|
||||
];
|
||||
|
||||
interface TimetablesQueryParams {
|
||||
driverName?: string;
|
||||
trainNo?: string;
|
||||
timetableId?: string;
|
||||
categoryCode?: string;
|
||||
|
||||
authorName?: string;
|
||||
|
||||
dateFrom?: string;
|
||||
dateTo?: string;
|
||||
|
||||
issuedFrom?: string;
|
||||
terminatingAt?: string;
|
||||
via?: string;
|
||||
includesScenery?: string;
|
||||
|
||||
countFrom?: number;
|
||||
countLimit?: number;
|
||||
|
||||
fulfilled?: number;
|
||||
terminated?: number;
|
||||
|
||||
twr?: number;
|
||||
skr?: number;
|
||||
pn?: number;
|
||||
tn?: number;
|
||||
|
||||
sortBy?: Journal.TimetableSorter['id'];
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
JournalOptions,
|
||||
@@ -170,7 +140,7 @@ export default defineComponent({
|
||||
mainStore: useMainStore(),
|
||||
apiStore: useApiStore(),
|
||||
|
||||
currentQueryParams: {} as TimetablesQueryParams,
|
||||
currentQueryParams: {} as API.TimetableHistory.QueryParams,
|
||||
dataRefreshedAt: null as Date | null,
|
||||
|
||||
scrollDataLoaded: true,
|
||||
@@ -180,7 +150,7 @@ export default defineComponent({
|
||||
|
||||
currentOptionsActive: false,
|
||||
|
||||
timetableHistory: [] as API.TimetableHistory.Response,
|
||||
timetableHistory: [] as API.TimetableHistory.ResponseShort,
|
||||
|
||||
dataStatus: Status.Data.Loading
|
||||
}),
|
||||
@@ -230,7 +200,7 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
watch: {
|
||||
currentQueryParams(q: TimetablesQueryParams) {
|
||||
currentQueryParams(q: API.TimetableHistory.QueryParams) {
|
||||
this.currentOptionsActive = Object.values(q).some((v) => v !== undefined);
|
||||
}
|
||||
},
|
||||
@@ -328,7 +298,7 @@ export default defineComponent({
|
||||
dateToISO = dateTo.toISOString();
|
||||
}
|
||||
|
||||
const queryParams: TimetablesQueryParams = {};
|
||||
const queryParams: API.TimetableHistory.QueryParams = {};
|
||||
|
||||
this.filterList
|
||||
.filter((f) => f.isActive)
|
||||
@@ -395,6 +365,7 @@ export default defineComponent({
|
||||
queryParams['terminatingAt'] = terminatingAt;
|
||||
queryParams['via'] = via;
|
||||
queryParams['categoryCode'] = categoryCode;
|
||||
queryParams['returnType'] = 'short';
|
||||
|
||||
queryParams['issuedFrom'] = issuedFrom;
|
||||
queryParams['sortBy'] =
|
||||
@@ -406,7 +377,7 @@ export default defineComponent({
|
||||
this.currentQueryParams = queryParams;
|
||||
|
||||
try {
|
||||
const responseData: API.TimetableHistory.Response = await (
|
||||
const responseData: API.TimetableHistory.ResponseShort = await (
|
||||
await this.apiStore.client!.get('api/getTimetables', {
|
||||
params: this.currentQueryParams
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user