Files
stacjownik/src/views/TrainsView.vue
T

179 lines
4.3 KiB
Vue

<template>
<section class="trains-view">
<div class="wrapper">
<div class="options-bar">
<TrainStats :trains="trainList" :trainStatsOpen="trainStatsOpen" />
<TrainOptions
:queryTrain="train"
@changeSorter="changeSorter"
@changeSearchedTrain="changeSearchedTrain"
@changeSearchedDriver="changeSearchedDriver"
/>
</div>
<TrainTable :computedTrains="computedTrains" :queryTrain="train" />
</div>
</section>
</template>
<script lang="ts">
import { computed, ComputedRef, defineComponent, provide, reactive, ref } from "vue";
import { DataStatus } from "@/scripts/enums/DataStatus";
import Train from "@/scripts/interfaces/Train";
import TrainTable from "@/components/TrainsView/TrainTable.vue";
import TrainStats from "@/components/TrainsView/TrainStats.vue";
import TrainOptions from "@/components/TrainsView/TrainOptions.vue";
import { useStore } from "@/store";
import { GETTERS } from "@/constants/storeConstants";
const filteredTrainList = (
trainList: Train[],
searchedTrain: string,
searchedDriver: string,
sorterActive: { id: string; dir: number }
) => {
return trainList
.filter(
(train) =>
train.online &&
(searchedTrain.length > 0
? train.trainNo.toString().includes(searchedTrain)
: true) &&
(searchedDriver.length > 0
? train.driverName
.toLowerCase()
.includes(searchedDriver.toLowerCase())
: true)
)
.sort((a: Train, b: Train) => {
switch (sorterActive.id) {
case "mass":
if (a.mass > b.mass) return sorterActive.dir;
return -sorterActive.dir;
case "distance":
if (
(a.timetableData?.routeDistance || -1) >
(b.timetableData?.routeDistance || -1)
)
return sorterActive.dir;
return -sorterActive.dir;
case "speed":
if (a.speed > b.speed) return sorterActive.dir;
return -sorterActive.dir;
case "timetable":
if (a.trainNo > b.trainNo) return sorterActive.dir;
return -sorterActive.dir;
case "length":
if (a.length > b.length) return sorterActive.dir;
return -sorterActive.dir;
default:
break;
}
return 0;
});
};
export default defineComponent({
components: {
TrainTable,
TrainStats,
TrainOptions,
},
props: ["train"],
data: () => ({
statsIcon: require("@/assets/icon-stats.svg"),
trainStatsOpen: false,
queryTrain: "",
}),
setup() {
const store = useStore();
const trainList: ComputedRef<Train[]> = computed(
() => store.getters[GETTERS.trainList]
);
const timetableDataStatus: ComputedRef<DataStatus> = computed(
() => store.getters[GETTERS.timetableDataStatus]
);
const sorterActive = ref({ id: "distance", dir: -1 });
const searchedDriver = ref("");
const searchedTrain = ref("");
const computedTrains: ComputedRef<Train[]> = computed(() => {
if (timetableDataStatus.value != DataStatus.Loaded) return [];
return filteredTrainList(
trainList.value,
searchedTrain.value,
searchedDriver.value,
sorterActive.value
);
});
/* Provide list for TrainStats category filter */
const chosenTrainCategories = reactive([] as string[]);
provide('chosenTrainCategories', chosenTrainCategories);
return {
trainList,
computedTrains,
searchedTrain,
searchedDriver,
sorterActive,
chosenTrainCategories
};
},
methods: {
changeSearchedTrain(trainNo: string) {
this.searchedTrain = trainNo;
},
changeSearchedDriver(name: string) {
this.searchedDriver = name;
},
changeSorter(sorter: { id: string; dir: number }) {
this.sorterActive = sorter;
},
},
});
</script>
<style lang="scss" scoped>
@import "../styles/responsive.scss";
.trains-view {
min-height: 100%;
position: relative;
}
.wrapper {
margin: 1rem auto;
max-width: 1300px;
padding: 0 0.5em;
}
@include smallScreen {
.options-bar {
font-size: 1.25em;
}
}
</style>