mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 21:38:13 +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="details-body" v-if="showExtraInfo">
|
||||||
<div class="g-separator"></div>
|
<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>
|
<div class="g-separator"></div>
|
||||||
|
|
||||||
<b>{{ $t('journal.stock-dangers') }}:</b>
|
<div class="timetable-specs">
|
||||||
|
<span class="badge specs-badge" v-if="timetableDetails.authorName">
|
||||||
<ul>
|
<span>{{ $t('journal.dispatcher-name') }}</span>
|
||||||
<li v-if="timetable.twr">
|
<span>{{ timetableDetails.authorName }}</span>
|
||||||
<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>
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="badge specs-badge" v-if="timetable.stockMass">
|
<span class="badge specs-badge" v-if="timetableDetails.trainMaxSpeed">
|
||||||
<span>{{ $t('journal.stock-mass') }}</span>
|
<span>{{ $t('journal.stock-timetable-speed') }}</span>
|
||||||
<span>
|
<span> {{ timetableDetails.trainMaxSpeed }}km/h </span>
|
||||||
{{
|
</span>
|
||||||
Math.floor(
|
|
||||||
(currentHistoryIndex == 0
|
<span class="badge specs-badge" v-if="timetableDetails.maxSpeed">
|
||||||
? timetable.stockMass
|
<span>{{ $t('journal.stock-max-speed') }}</span>
|
||||||
: stockHistory[currentHistoryIndex].stockMass || timetable.stockMass) / 1000
|
<span>{{ timetableDetails.maxSpeed }}km/h</span>
|
||||||
)
|
|
||||||
}}t
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stock-history">
|
<div class="stock-dangers" v-if="timetableDetails.warningNotes">
|
||||||
<button class="btn btn--action" @click="copyStockToClipboard()">
|
<div class="g-separator"></div>
|
||||||
<i class="fa-regular fa-copy"></i> {{ $t('journal.stock-copy') }}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
<b>{{ $t('journal.stock-dangers') }}:</b>
|
||||||
v-for="(sh, i) in stockHistory"
|
|
||||||
:key="i"
|
<ul>
|
||||||
class="btn--action"
|
<li v-if="timetableDetails.twr">
|
||||||
:data-checked="i == currentHistoryIndex"
|
<b class="text--primary">{{ $t('warnings.TWR') }} (TWR)</b>
|
||||||
@click.stop="currentHistoryIndex = i"
|
</li>
|
||||||
>
|
|
||||||
{{ sh.updatedAt }}
|
<li v-if="timetableDetails.skr">
|
||||||
</button>
|
<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>
|
||||||
|
|
||||||
<div v-if="timetable.stockString" style="margin-top: 1em">
|
<!-- Historia zmian w składzie -->
|
||||||
<StockList
|
<div v-if="timetableDetails.stockString || stockHistory.length != 0">
|
||||||
:trainStockList="
|
<div class="g-separator"></div>
|
||||||
(currentHistoryIndex == 0
|
|
||||||
? timetable.stockString
|
<b>{{ $t('journal.stock-preview') }}:</b>
|
||||||
: stockHistory[currentHistoryIndex].stockString
|
|
||||||
).split(';')
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { PropType, defineComponent } from 'vue';
|
import { computed, defineComponent, onActivated, onMounted, ref, watch } from 'vue';
|
||||||
import StockList from '../../Global/StockList.vue';
|
|
||||||
import { API } from '../../../typings/api';
|
|
||||||
import { RouteLocationRaw } from 'vue-router';
|
import { RouteLocationRaw } from 'vue-router';
|
||||||
import EntryStops from './EntryStops.vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
export default defineComponent({
|
import StockList from '../../Global/StockList.vue';
|
||||||
components: { StockList, EntryStops },
|
import EntryStops from './EntryStops.vue';
|
||||||
|
import { API } from '../../../typings/api';
|
||||||
|
import { useApiStore } from '../../../store/apiStore';
|
||||||
|
|
||||||
emits: ['toggleExtraInfo'],
|
const i18n = useI18n();
|
||||||
|
const apiStore = useApiStore();
|
||||||
|
|
||||||
props: {
|
const props = defineProps({
|
||||||
showExtraInfo: {
|
showExtraInfo: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true
|
||||||
},
|
|
||||||
timetable: {
|
|
||||||
type: Object as PropType<API.TimetableHistory.Data>,
|
|
||||||
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 {
|
timetableId: {
|
||||||
if (this.timetable.terminated) return null;
|
type: Number,
|
||||||
return {
|
required: true
|
||||||
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'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -299,7 +333,7 @@ hr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include responsive.smallScreen{
|
@include responsive.smallScreen {
|
||||||
.timetable-specs {
|
.timetable-specs {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
props: {
|
props: {
|
||||||
timetable: {
|
timetable: {
|
||||||
type: Object as PropType<API.TimetableHistory.Data>,
|
type: Object as PropType<API.TimetableHistory.DataShort>,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export default defineComponent({
|
|||||||
components: { ProgressBar },
|
components: { ProgressBar },
|
||||||
props: {
|
props: {
|
||||||
timetable: {
|
timetable: {
|
||||||
type: Object as PropType<API.TimetableHistory.Data>,
|
type: Object as PropType<API.TimetableHistory.DataShort>,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<!-- Extra -->
|
<!-- Extra -->
|
||||||
<EntryDetails
|
<EntryDetails
|
||||||
:timetable="timetableEntry"
|
:timetable-id="timetableEntry.id"
|
||||||
:show-extra-info="showExtraInfo"
|
:show-extra-info="showExtraInfo"
|
||||||
@toggle-extra-info="toggleExtraInfo"
|
@toggle-extra-info="toggleExtraInfo"
|
||||||
/>
|
/>
|
||||||
@@ -28,7 +28,6 @@
|
|||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import { API } from '../../../typings/api';
|
import { API } from '../../../typings/api';
|
||||||
import { useApiStore } from '../../../store/apiStore';
|
import { useApiStore } from '../../../store/apiStore';
|
||||||
import { Journal } from '../typings';
|
|
||||||
|
|
||||||
import trainCategoryMixin from '../../../mixins/trainCategoryMixin';
|
import trainCategoryMixin from '../../../mixins/trainCategoryMixin';
|
||||||
import dateMixin from '../../../mixins/dateMixin';
|
import dateMixin from '../../../mixins/dateMixin';
|
||||||
@@ -41,7 +40,7 @@ import EntryDetails from './EntryDetails.vue';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
timetableEntry: {
|
timetableEntry: {
|
||||||
type: Object as PropType<API.TimetableHistory.Data>,
|
type: Object as PropType<API.TimetableHistory.DataShort>,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
showExtraInfo: {
|
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: {
|
methods: {
|
||||||
toggleExtraInfo() {
|
toggleExtraInfo() {
|
||||||
this.$emit('toggleShowExtraInfo');
|
this.$emit('toggleShowExtraInfo');
|
||||||
@@ -145,7 +79,7 @@ export default defineComponent({
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include responsive.smallScreen{
|
@include responsive.smallScreen {
|
||||||
.entry-route {
|
.entry-route {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
props: {
|
props: {
|
||||||
timetableHistory: {
|
timetableHistory: {
|
||||||
type: Array as PropType<API.TimetableHistory.Response>,
|
type: Array as PropType<API.TimetableHistory.ResponseShort>,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
scrollNoMoreData: {
|
scrollNoMoreData: {
|
||||||
|
|||||||
+72
-28
@@ -1,3 +1,4 @@
|
|||||||
|
import { Journal } from '../components/JournalView/typings';
|
||||||
import { Status, Vehicle, VehicleGroup } from './common';
|
import { Status, Vehicle, VehicleGroup } from './common';
|
||||||
|
|
||||||
export enum APIDataStatus {
|
export enum APIDataStatus {
|
||||||
@@ -225,35 +226,40 @@ export namespace API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export namespace TimetableHistory {
|
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;
|
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 {
|
export interface DataShort {
|
||||||
@@ -261,6 +267,7 @@ export namespace API {
|
|||||||
createdAt: string;
|
createdAt: string;
|
||||||
trainNo: number;
|
trainNo: number;
|
||||||
trainCategoryCode: string;
|
trainCategoryCode: string;
|
||||||
|
timetableId: number;
|
||||||
|
|
||||||
driverId: number;
|
driverId: number;
|
||||||
driverName: string;
|
driverName: string;
|
||||||
@@ -280,6 +287,9 @@ export namespace API {
|
|||||||
allStopsCount: number;
|
allStopsCount: number;
|
||||||
|
|
||||||
beginDate: string;
|
beginDate: string;
|
||||||
|
endDate: string;
|
||||||
|
scheduledBeginDate: string;
|
||||||
|
scheduledEndDate: string;
|
||||||
|
|
||||||
terminated: boolean;
|
terminated: boolean;
|
||||||
fulfilled: boolean;
|
fulfilled: boolean;
|
||||||
@@ -293,8 +303,42 @@ export namespace API {
|
|||||||
hasExtraDeliveries: boolean;
|
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 Response = Data[];
|
||||||
export type ResponseShort = DataShort[];
|
export type ResponseShort = DataShort[];
|
||||||
|
export type ResponseDetailsOnly = DataDetailsOnly[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace DailyStats {
|
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({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
JournalOptions,
|
JournalOptions,
|
||||||
@@ -170,7 +140,7 @@ export default defineComponent({
|
|||||||
mainStore: useMainStore(),
|
mainStore: useMainStore(),
|
||||||
apiStore: useApiStore(),
|
apiStore: useApiStore(),
|
||||||
|
|
||||||
currentQueryParams: {} as TimetablesQueryParams,
|
currentQueryParams: {} as API.TimetableHistory.QueryParams,
|
||||||
dataRefreshedAt: null as Date | null,
|
dataRefreshedAt: null as Date | null,
|
||||||
|
|
||||||
scrollDataLoaded: true,
|
scrollDataLoaded: true,
|
||||||
@@ -180,7 +150,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
currentOptionsActive: false,
|
currentOptionsActive: false,
|
||||||
|
|
||||||
timetableHistory: [] as API.TimetableHistory.Response,
|
timetableHistory: [] as API.TimetableHistory.ResponseShort,
|
||||||
|
|
||||||
dataStatus: Status.Data.Loading
|
dataStatus: Status.Data.Loading
|
||||||
}),
|
}),
|
||||||
@@ -230,7 +200,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
currentQueryParams(q: TimetablesQueryParams) {
|
currentQueryParams(q: API.TimetableHistory.QueryParams) {
|
||||||
this.currentOptionsActive = Object.values(q).some((v) => v !== undefined);
|
this.currentOptionsActive = Object.values(q).some((v) => v !== undefined);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -328,7 +298,7 @@ export default defineComponent({
|
|||||||
dateToISO = dateTo.toISOString();
|
dateToISO = dateTo.toISOString();
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryParams: TimetablesQueryParams = {};
|
const queryParams: API.TimetableHistory.QueryParams = {};
|
||||||
|
|
||||||
this.filterList
|
this.filterList
|
||||||
.filter((f) => f.isActive)
|
.filter((f) => f.isActive)
|
||||||
@@ -395,6 +365,7 @@ export default defineComponent({
|
|||||||
queryParams['terminatingAt'] = terminatingAt;
|
queryParams['terminatingAt'] = terminatingAt;
|
||||||
queryParams['via'] = via;
|
queryParams['via'] = via;
|
||||||
queryParams['categoryCode'] = categoryCode;
|
queryParams['categoryCode'] = categoryCode;
|
||||||
|
queryParams['returnType'] = 'short';
|
||||||
|
|
||||||
queryParams['issuedFrom'] = issuedFrom;
|
queryParams['issuedFrom'] = issuedFrom;
|
||||||
queryParams['sortBy'] =
|
queryParams['sortBy'] =
|
||||||
@@ -406,7 +377,7 @@ export default defineComponent({
|
|||||||
this.currentQueryParams = queryParams;
|
this.currentQueryParams = queryParams;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const responseData: API.TimetableHistory.Response = await (
|
const responseData: API.TimetableHistory.ResponseShort = await (
|
||||||
await this.apiStore.client!.get('api/getTimetables', {
|
await this.apiStore.client!.get('api/getTimetables', {
|
||||||
params: this.currentQueryParams
|
params: this.currentQueryParams
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user