rework reaktywności danych z API i WS

This commit is contained in:
2023-10-30 23:19:17 +01:00
parent 12ece46089
commit 8de03b9210
24 changed files with 501 additions and 446 deletions
@@ -76,6 +76,7 @@ import { URLs } from '../../scripts/utils/apiURLs';
import Loading from '../Global/Loading.vue';
import styleMixin from '../../mixins/styleMixin';
import listObserverMixin from '../../mixins/listObserverMixin';
import { OnlineScenery } from '../../scripts/interfaces/store/storeTypes';
export default defineComponent({
name: 'SceneryDispatchersHistory',
@@ -85,6 +86,10 @@ export default defineComponent({
station: {
type: Object as PropType<Station>,
required: true
},
onlineScenery: {
type: Object as PropType<OnlineScenery>,
required: false
}
},
+7 -1
View File
@@ -8,19 +8,25 @@
{{ $t('scenery.abbrev') }} <b>{{ station.generalInfo?.abbr }}</b>
</div>
<div class="scenery-hash" v-if="station.onlineInfo?.hash">#{{ station.onlineInfo.hash }}</div>
<div class="scenery-hash" v-if="onlineScenery?.hash">#{{ onlineScenery.hash }}</div>
</section>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue';
import Station from '../../scripts/interfaces/Station';
import { OnlineScenery } from '../../scripts/interfaces/store/storeTypes';
export default defineComponent({
props: {
station: {
type: Object as PropType<Station>,
required: true
},
onlineScenery: {
type: Object as PropType<OnlineScenery>,
required: false
}
}
});
+9 -9
View File
@@ -1,6 +1,6 @@
<template>
<div class="scenery-info">
<section v-if="!timetableOnly">
<section>
<div class="scenery-info-general" v-if="station.generalInfo">
<SceneryInfoIcons :station="station" />
@@ -68,14 +68,14 @@
<div style="margin: 2em 0; height: 2px; background-color: white"></div>
<!-- info dispatcher -->
<SceneryInfoDispatcher :station="station" :onlineFrom="onlineFrom" />
<SceneryInfoDispatcher :onlineScenery="onlineScenery" />
<div class="info-lists">
<!-- user list -->
<SceneryInfoUserList :station="station" />
<SceneryInfoUserList :onlineScenery="onlineScenery" />
<!-- spawn list -->
<SceneryInfoSpawnList :station="station" />
<SceneryInfoSpawnList :onlineScenery="onlineScenery" />
</div>
</section>
</div>
@@ -90,6 +90,7 @@ import SceneryInfoUserList from './SceneryInfo/SceneryInfoUserList.vue';
import SceneryInfoSpawnList from './SceneryInfo/SceneryInfoSpawnList.vue';
import SceneryInfoRoutes from './SceneryInfo/SceneryInfoRoutes.vue';
import Station from '../../scripts/interfaces/Station';
import { OnlineScenery } from '../../scripts/interfaces/store/storeTypes';
export default defineComponent({
components: {
@@ -105,12 +106,11 @@ export default defineComponent({
required: true
},
timetableOnly: Boolean
onlineScenery: {
type: Object as PropType<OnlineScenery>,
required: false
}
},
data: () => ({
onlineFrom: -1
})
});
</script>
@@ -1,35 +1,30 @@
<template>
<section class="info-dispatcher">
<div class="dispatcher" v-if="station.onlineInfo">
<div class="dispatcher" v-if="onlineScenery">
<span
class="dispatcher_level"
:style="
calculateExpStyle(
station.onlineInfo.dispatcherExp,
station.onlineInfo.dispatcherIsSupporter
)
"
:style="calculateExpStyle(onlineScenery.dispatcherExp, onlineScenery.dispatcherIsSupporter)"
>
{{ station.onlineInfo.dispatcherExp > 1 ? station.onlineInfo.dispatcherExp : 'L' }}
{{ onlineScenery.dispatcherExp > 1 ? onlineScenery.dispatcherExp : 'L' }}
</span>
<router-link
class="dispatcher_name"
:to="`/journal/dispatchers?dispatcherName=${station.onlineInfo.dispatcherName}`"
:to="`/journal/dispatchers?dispatcherName=${onlineScenery.dispatcherName}`"
>
{{ station.onlineInfo.dispatcherName }}
{{ onlineScenery.dispatcherName }}
</router-link>
<span class="dispatcher_likes text--primary">
<img src="/images/icon-like.svg" alt="Likes count icon" />
<span>{{ station.onlineInfo?.dispatcherRate || '0' }}</span>
<span>{{ onlineScenery?.dispatcherRate || '0' }}</span>
</span>
</div>
<StationStatusBadge
:statusID="station.onlineInfo?.statusID"
:isOnline="station.onlineInfo ? true : false"
:statusTimestamp="station.onlineInfo?.statusTimestamp"
:statusID="onlineScenery?.statusID"
:isOnline="onlineScenery ? true : false"
:statusTimestamp="onlineScenery?.statusTimestamp"
/>
</section>
</template>
@@ -39,19 +34,15 @@ import { PropType, defineComponent } from 'vue';
import dateMixin from '../../../mixins/dateMixin';
import routerMixin from '../../../mixins/routerMixin';
import styleMixin from '../../../mixins/styleMixin';
import Station from '../../../scripts/interfaces/Station';
import StationStatusBadge from '../../Global/StationStatusBadge.vue';
import { OnlineScenery } from '../../../scripts/interfaces/store/storeTypes';
export default defineComponent({
mixins: [styleMixin, dateMixin, routerMixin],
props: {
station: {
type: Object as PropType<Station>,
required: true
},
onlineFrom: {
type: Number,
default: -1
onlineScenery: {
type: Object as PropType<OnlineScenery>,
required: false
}
},
components: { StationStatusBadge }
@@ -3,14 +3,14 @@
<h3 class="spawn-header section-header">
<img src="/images/icon-spawn.svg" alt="Open spawns icon" />
&nbsp;{{ $t('scenery.spawns') }} &nbsp;
<span class="text--primary">{{ station.onlineInfo?.spawns.length || '0' }}</span>
<span class="text--primary">{{ onlineScenery?.spawns.length || '0' }}</span>
</h3>
<span v-if="station.onlineInfo">
<span v-if="onlineScenery">
<span
class="badge spawn"
v-for="(spawn, i) in sortedSpawns"
:key="spawn.spawnName + station.onlineInfo?.dispatcherName + i"
:key="spawn.spawnName + onlineScenery?.dispatcherName + i"
:data-electrified="spawn.isElectrified"
>
<span class="spawn_name">{{ spawn.spawnName }}</span>
@@ -18,9 +18,7 @@
</span>
</span>
<span
class="badge spawn badge-none"
v-if="!station.onlineInfo || station.onlineInfo.spawns.length == 0"
<span class="badge spawn badge-none" v-if="!onlineScenery || onlineScenery.spawns.length == 0"
>{{ $t('scenery.no-spawns') }}
</span>
</section>
@@ -28,21 +26,21 @@
<script lang="ts">
import { PropType, defineComponent } from 'vue';
import Station from '../../../scripts/interfaces/Station';
import { OnlineScenery } from '../../../scripts/interfaces/store/storeTypes';
export default defineComponent({
props: {
station: {
type: Object as PropType<Station>,
required: true
onlineScenery: {
type: Object as PropType<OnlineScenery>,
required: false
}
},
computed: {
sortedSpawns() {
if (!this.station.onlineInfo) return [];
if (!this.onlineScenery) return [];
return [...this.station.onlineInfo.spawns].sort((s1, s2) =>
return [...this.onlineScenery.spawns].sort((s1, s2) =>
s1.spawnLength < s2.spawnLength ? 1 : -1
);
}
@@ -3,12 +3,12 @@
<h3 class="user-header section-header">
<img src="/images/icon-user.svg" alt="Users icon" />
&nbsp;{{ $t('scenery.users') }} &nbsp;
<span class="text--primary">{{ station.onlineInfo?.currentUsers || '0' }}</span
>&nbsp;/&nbsp;<span class="text--primary">{{ station.onlineInfo?.maxUsers || '0' }}</span>
<span class="text--primary">{{ onlineScenery?.currentUsers || 0 }}</span
>&nbsp;/&nbsp;<span class="text--primary">{{ onlineScenery?.maxUsers || 0 }}</span>
</h3>
<div
v-for="train in computedStationTrains"
v-for="train in onlineScenery?.stationTrains"
class="badge user"
:class="train.stopStatus"
:key="train.trainId"
@@ -22,7 +22,7 @@
<div
class="badge user badge-none"
v-if="!computedStationTrains || computedStationTrains.length == 0"
v-if="!onlineScenery?.scheduledTrains || onlineScenery.scheduledTrains.length == 0"
>
{{ $t('scenery.no-users') }}
</div>
@@ -30,45 +30,19 @@
</template>
<script lang="ts">
import { PropType, computed, defineComponent } from 'vue';
import { PropType, defineComponent } from 'vue';
import modalTrainMixin from '../../../mixins/modalTrainMixin';
import routerMixin from '../../../mixins/routerMixin';
import Station from '../../../scripts/interfaces/Station';
import { useStore } from '../../../store/store';
import { OnlineScenery } from '../../../scripts/interfaces/store/storeTypes';
export default defineComponent({
mixins: [routerMixin, modalTrainMixin],
props: {
station: {
type: Object as PropType<Station>,
required: true
onlineScenery: {
type: Object as PropType<OnlineScenery>,
required: false
}
},
setup(props) {
const store = useStore();
const computedStationTrains = computed(() => {
if (!props.station) return [];
const station = props.station as Station;
if (!station.onlineInfo) return [];
if (!station.onlineInfo.stationTrains) return [];
return station.onlineInfo.stationTrains.map((train) => {
const scheduledTrainStatus = station.onlineInfo?.scheduledTrains?.find(
(st) => st.trainNo === train.trainNo
);
return {
...train,
stopStatus: scheduledTrainStatus?.stopStatus || 'no-timetable'
};
});
});
return { computedStationTrains, store };
}
});
</script>
+30 -48
View File
@@ -6,14 +6,12 @@
<span>{{ $t('scenery.timetables') }}</span>
<span>
<span class="text--primary">{{
station.onlineInfo?.scheduledTrains?.length || '0'
}}</span>
<span class="text--primary">{{ onlineScenery?.scheduledTrains?.length || '0' }}</span>
<span> / </span>
<span class="text--grayed">
{{
station.onlineInfo?.scheduledTrains?.filter((train) => train.stopInfo.confirmed)
.length || '0'
onlineScenery?.scheduledTrains?.filter((train) => train.stopInfo.confirmed).length ||
'0'
}}
</span>
</span>
@@ -59,7 +57,7 @@
<span
class="timetable-item empty"
v-else-if="computedScheduledTrains.length == 0 && !station.onlineInfo"
v-else-if="computedScheduledTrains.length == 0 && !onlineScenery"
>
{{ $t('scenery.offline') }}
</span>
@@ -186,6 +184,7 @@ import Station from '../../scripts/interfaces/Station';
import { useStore } from '../../store/store';
import modalTrainMixin from '../../mixins/modalTrainMixin';
import ScheduledTrainStatus from './ScheduledTrainStatus.vue';
import { OnlineScenery } from '../../scripts/interfaces/store/storeTypes';
export default defineComponent({
name: 'SceneryTimetable',
@@ -199,9 +198,9 @@ export default defineComponent({
type: Object as PropType<Station>,
required: true
},
timetableOnly: {
type: Boolean
onlineScenery: {
type: Object as PropType<OnlineScenery>,
required: false
}
},
@@ -229,36 +228,9 @@ export default defineComponent({
: props.station?.generalInfo?.checkpoints[0].checkpointName || null
);
const computedScheduledTrains = computed(() => {
if (!props.station) return [];
const station = props.station as Station;
let scheduledTrains =
station.generalInfo?.checkpoints.find((cp) => cp.checkpointName === chosenCheckpoint.value)
?.scheduledTrains ||
station.onlineInfo?.scheduledTrains ||
[];
if (!scheduledTrains) return [];
return (
scheduledTrains.sort((a, b) => {
if (a.stopStatusID > b.stopStatusID) return 1;
if (a.stopStatusID < b.stopStatusID) return -1;
if (a.stopInfo.arrivalTimestamp > b.stopInfo.arrivalTimestamp) return 1;
if (a.stopInfo.arrivalTimestamp < b.stopInfo.arrivalTimestamp) return -1;
return a.stopInfo.departureTimestamp > b.stopInfo.departureTimestamp ? 1 : -1;
}) || []
);
});
return {
currentURL,
chosenCheckpoint,
computedScheduledTrains,
store
};
},
@@ -269,27 +241,37 @@ export default defineComponent({
if (this.chosenCheckpoint) url += `&checkpoint=${this.chosenCheckpoint}`;
return url;
},
computedScheduledTrains() {
return (
this.onlineScenery?.scheduledTrains
?.filter(
(train) =>
train.checkpointName.toLocaleLowerCase() ==
(this.chosenCheckpoint || this.station.name).toLocaleLowerCase()
)
.sort((a, b) => {
if (a.stopStatusID > b.stopStatusID) return 1;
if (a.stopStatusID < b.stopStatusID) return -1;
if (a.stopInfo.arrivalTimestamp > b.stopInfo.arrivalTimestamp) return 1;
if (a.stopInfo.arrivalTimestamp < b.stopInfo.arrivalTimestamp) return -1;
return a.stopInfo.departureTimestamp > b.stopInfo.departureTimestamp ? 1 : -1;
}) || []
);
}
},
methods: {
loadSelectedOption() {
if (!this.station) return;
if (!this.station.generalInfo) return;
if (!this.station.generalInfo.checkpoints) return;
if (this.station.generalInfo.checkpoints.length == 0) return;
if (this.chosenCheckpoint != '') return;
this.chosenCheckpoint = this.station.generalInfo.checkpoints[0].checkpointName;
this.chosenCheckpoint =
this.station.generalInfo?.checkpoints[0]?.checkpointName || this.station.name;
},
setCheckpoint(cp: { checkpointName: string }) {
this.chosenCheckpoint = cp.checkpointName;
},
showTimetableOnlyView() {
this.$router.push(`${this.$route.fullPath}&timetableOnly=1`);
}
}
});
@@ -65,6 +65,7 @@ import Station from '../../scripts/interfaces/Station';
import { URLs } from '../../scripts/utils/apiURLs';
import Loading from '../Global/Loading.vue';
import listObserverMixin from '../../mixins/listObserverMixin';
import { OnlineScenery } from '../../scripts/interfaces/store/storeTypes';
export default defineComponent({
name: 'SceneryTimetablesHistory',
@@ -73,6 +74,10 @@ export default defineComponent({
station: {
type: Object as PropType<Station>,
required: true
},
onlineScenery: {
type: Object as PropType<OnlineScenery>,
required: false
}
},