Migracja na Vite

This commit is contained in:
2022-07-16 16:12:31 +02:00
parent fc56c38c45
commit 46e700583d
63 changed files with 4269 additions and 23282 deletions
+16 -25
View File
@@ -12,16 +12,16 @@
<div class="header_container">
<div class="header_icons">
<span class="icons-top">
<img :src="icons.pl" alt="icon-pl" @click="changeLang('en')" v-if="currentLang == 'pl'" />
<img :src="icons.en" alt="icon-en" @click="changeLang('pl')" v-else />
<img :src="getIcon('pl')" alt="icon-pl" @click="changeLang('en')" v-if="currentLang == 'pl'" />
<img :src="getIcon('en', 'jpg')" alt="icon-en" @click="changeLang('pl')" v-else />
</span>
<span class="icons-bottom">
<a href="https://www.paypal.com/paypalme/spythere" target="_blank">
<img :src="icons.dollar" alt="icon paypal" />
<img :src="getIcon('dollar')" alt="icon paypal" />
</a>
<a href="https://discord.gg/x2mpNN3svk" target="_blank">
<img :src="icons.discord" alt="icon discord" />
<img :src="getIcon('discord', 'png')" alt="icon discord" />
</a>
</span>
</div>
@@ -29,18 +29,18 @@
<div class="header_body">
<status-indicator />
<span class="header_brand">
<img :src="brand_logo" alt="Stacjownik" />
<img :src="getImage('stacjownik-header-logo.svg')" alt="Stacjownik" />
</span>
<span class="header_info">
<Clock />
<div class="info_counter">
<img src="@/assets/icon-dispatcher.svg" alt="icon dispatcher" />
<img :src="getIcon('dispatcher')" alt="icon dispatcher" />
<span class="text--primary">{{ onlineDispatchers.length }}</span>
<span class="text--grayed"> / </span>
<span class="text--primary">{{ trainList.length }}</span>
<img src="@/assets/icon-train.svg" alt="icon train" />
<img :src="getIcon('train')" alt="icon train" />
</div>
<span class="info_region">
@@ -55,7 +55,7 @@
/
<router-link class="route" active-class="route-active" to="/trains">{{ $t('app.trains') }}</router-link>
/
<router-link class="route" active-class="route-active" to="/journal">
<router-link class="route" active-class="route-active" to="/journal/timetables">
{{ $t('app.journal') }}
</router-link>
</span>
@@ -84,17 +84,18 @@
<script lang="ts">
import { computed, defineComponent, provide, ref } from 'vue';
import Clock from '@/components/App/Clock.vue';
import StorageManager from '@/scripts/managers/storageManager';
import Clock from './components/App/Clock.vue';
import packageInfo from '.././package.json';
import options from '@/data/options.json';
import options from './data/options.json';
import StatusIndicator from '@/components/App/StatusIndicator.vue';
import SelectBox from '@/components/Global/SelectBox.vue';
import StatusIndicator from './components/App/StatusIndicator.vue';
import SelectBox from './components/Global/SelectBox.vue';
import { useStore } from './store/store';
import UpdateModal from './components/App/UpdateModal.vue';
import TrainModal from './components/Global/TrainModal.vue';
import StorageManager from './scripts/managers/storageManager';
import imageMixin from './mixins/imageMixin';
export default defineComponent({
components: {
@@ -105,6 +106,8 @@ export default defineComponent({
TrainModal,
},
mixins: [imageMixin],
setup() {
const store = useStore();
store.connectToAPI();
@@ -151,18 +154,6 @@ export default defineComponent({
currentLang: 'pl',
releaseURL: '',
brand_logo: require('@/assets/stacjownik-header-logo.svg'),
icons: {
en: require('@/assets/icon-en.jpg'),
pl: require('@/assets/icon-pl.svg'),
error: require('@/assets/icon-error.svg'),
dollar: require('@/assets/icon-dollar.svg'),
dispatcher: require('@/assets/icon-dispatcher.svg'),
train: require('@/assets/icon-train.svg'),
discord: require('@/assets/icon-discord.png'),
},
}),
created() {
+1 -1
View File
@@ -3,7 +3,7 @@
</template>
<script lang="ts">
import { defineComponent } from "@vue/runtime-core";
import { defineComponent } from "vue";
export default defineComponent({
props: ["message"],
+5 -8
View File
@@ -161,18 +161,15 @@
</template>
<script lang="ts">
import { DataStatus } from '@/scripts/enums/DataStatus';
import { StoreData } from '@/scripts/interfaces/StoreData';
import { useStore } from '@/store/store';
import { StoreState } from '@/store/storeTypes';
import { computed, defineComponent, watch } from 'vue';
import { defineComponent } from 'vue';
import { DataStatus } from '../../scripts/enums/DataStatus';
import { useStore } from '../../store/store';
import { StoreState } from '../../store/storeTypes';
export default defineComponent({
data() {
return {
icons: {
statusIndicator: require('@/assets/signal-status-indicator.svg'),
},
tooltipActive: false,
indicator: {
status: DataStatus.Loading,
+8 -10
View File
@@ -2,7 +2,7 @@
<transition name="modal-anim">
<section class="update-modal card" v-if="releaseData && modalOpen">
<h2 class="modal_header text--primary">
<img :src="icons.logo" alt="stacjownik logo" />
<img :src="getImage('stacjownik-header-logo.svg')" alt="stacjownik logo" />
{{ releaseData.tag_name }}
</h2>
@@ -30,17 +30,19 @@
<script lang="ts">
import axios from 'axios';
import { defineComponent } from 'vue';
import packageInfo from '../../../package.json';
import imageMixin from '../../mixins/imageMixin';
import { ReleaseAPIData } from '../../scripts/interfaces/github_api/ReleaseAPIData';
import StorageManager from '../../scripts/managers/storageManager';
import { useStore } from '../../store/store';
import { ReleaseAPIData } from '@/scripts/interfaces/github_api/ReleaseAPIData';
import { defineComponent } from '@vue/runtime-core';
import StorageManager from '@/scripts/managers/storageManager';
import { useStore } from '@/store/store';
const GH_LASTEST_RELEASE_URL = 'https://api.github.com/repos/Spythere/stacjownik/releases/latest';
export default defineComponent({
mixins: [imageMixin],
mounted() {
this.fetchReleases();
},
@@ -50,10 +52,6 @@ export default defineComponent({
modalOpen: false,
releaseData: null as ReleaseAPIData | null,
icons: {
logo: require('@/assets/stacjownik-header-logo.svg'),
},
};
},
+5 -5
View File
@@ -9,7 +9,7 @@
<img
class="search-exit"
:src="exitIcon"
:src="getIcon('exit')"
alt="exit-icon"
@click="clearValue"
/>
@@ -18,11 +18,11 @@
<script lang="ts">
import { defineComponent, ref, watch } from "vue";
import imageMixin from "../../mixins/imageMixin";
export default defineComponent({
data: () => ({
exitIcon: require("@/assets/icon-exit.svg"),
}),
mixins: [imageMixin],
emits: ["update:searchedValue", "clearValue"],
props: {
searchedValue: {
@@ -59,7 +59,7 @@ export default defineComponent({
emit("clearValue");
};
const updateValue = (e) => {
const updateValue = (e: any) => {
if (!props.updateOnInput && e.keyCode == 13)
emit("update:searchedValue", compSearchedValue.value);
};
+5 -8
View File
@@ -1,5 +1,5 @@
<template>
<div class="select-box" >
<div class="select-box">
<div class="select-box_content">
<button class="selected" @click="toggleBox">
<span class="text--primary">{{ prefix }}</span>
@@ -24,13 +24,14 @@
</div>
<div class="arrow">
<img :src="listOpen ? ascIcon : descIcon" alt="arrow-icon" />
<img :src="listOpen ? getIcon('arrow-asc') : getIcon('arrow-desc')" alt="arrow-icon" />
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, Ref, ref } from '@vue/runtime-core';
import { defineComponent, Ref, ref, computed } from 'vue';
import imageMixin from '../../mixins/imageMixin';
interface Item {
id: string;
@@ -40,6 +41,7 @@ interface Item {
export default defineComponent({
emits: ['selected'],
mixins: [imageMixin],
props: {
itemList: {
@@ -58,11 +60,6 @@ export default defineComponent({
},
},
data: () => ({
ascIcon: require('@/assets/icon-arrow-asc.svg'),
descIcon: require('@/assets/icon-arrow-desc.svg'),
}),
setup(props) {
let listRef: Ref<Element | null> = ref(null);
let buttonRef: Ref<HTMLButtonElement | null> = ref(null);
+2 -2
View File
@@ -47,9 +47,9 @@
</template>
<script lang="ts">
import dateMixin from '@/mixins/dateMixin';
import TrainStop from '@/scripts/interfaces/TrainStop';
import { defineComponent } from 'vue';
import dateMixin from '../../mixins/dateMixin';
import TrainStop from '../../scripts/interfaces/TrainStop';
export default defineComponent({
mixins: [dateMixin],
+5 -8
View File
@@ -3,7 +3,7 @@
<div class="modal_background" @click="closeModal"></div>
<div class="modal_content" ref="content" tabindex="0">
<button class="btn exit" @click="closeModal">
<img :src="icons.exit" alt="close card" />
<img :src="getIcon('exit')" alt="close card" />
</button>
<TrainInfo :train="store.chosenModalTrain" :extended="false" ref="trainInfo" />
@@ -13,23 +13,20 @@
</template>
<script lang="ts">
import trainInfoMixin from '@/mixins/trainInfoMixin';
import { useStore } from '@/store/store';
import { defineComponent } from 'vue';
import imageMixin from '../../mixins/imageMixin';
import trainInfoMixin from '../../mixins/trainInfoMixin';
import { useStore } from '../../store/store';
import TrainInfo from '../TrainsView/TrainInfo.vue';
import TrainSchedule from '../TrainsView/TrainSchedule.vue';
export default defineComponent({
components: { TrainInfo, TrainSchedule },
mixins: [trainInfoMixin],
mixins: [trainInfoMixin, imageMixin],
data() {
return {
isTopBarVisible: false,
icons: {
exit: require('@/assets/icon-exit.svg'),
},
};
},
@@ -48,12 +48,13 @@
</template>
<script lang="ts">
import { DispatcherStatsAPIData } from '@/scripts/interfaces/api/DispatcherStatsAPIData';
import { TimetableHistory } from '@/scripts/interfaces/api/TimetablesAPIData';
import { URLs } from '@/scripts/utils/apiURLs';
import { useStore } from '@/store/store';
import axios from 'axios';
import { computed, defineComponent } from 'vue';
import { DispatcherStatsAPIData } from '../../scripts/interfaces/api/DispatcherStatsAPIData';
import { TimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
import { URLs } from '../../scripts/utils/apiURLs';
import { useStore } from '../../store/store';
import Loading from '../Global/Loading.vue';
export default defineComponent({
+5 -4
View File
@@ -51,12 +51,13 @@
</template>
<script lang="ts">
import { DriverStatsAPIData } from '@/scripts/interfaces/api/DriverStatsAPIData';
import { TimetableHistory } from '@/scripts/interfaces/api/TimetablesAPIData';
import { URLs } from '@/scripts/utils/apiURLs';
import { useStore } from '@/store/store';
import axios from 'axios';
import { defineComponent } from 'vue';
import { DriverStatsAPIData } from '../../scripts/interfaces/api/DriverStatsAPIData';
import { TimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
import { URLs } from '../../scripts/utils/apiURLs';
import { useStore } from '../../store/store';
export default defineComponent({
emits: ['closeCard'],
@@ -82,21 +82,18 @@
import { computed, defineComponent, JournalFilter, provide, reactive, Ref, ref } from 'vue';
import axios from 'axios';
import SearchBox from '@/components/Global/SearchBox.vue';
import dateMixin from '@/mixins/dateMixin';
import { DataStatus } from '@/scripts/enums/DataStatus';
import ActionButton from '../../components/Global/ActionButton.vue';
import JournalOptions from '../../components/JournalView/JournalOptions.vue';
import DispatcherStats from '../../components/JournalView/DispatcherStats.vue';
import SearchBox from '../Global/SearchBox.vue';
import ActionButton from '@/components/Global/ActionButton.vue';
import JournalOptions from '@/components/JournalView/JournalOptions.vue';
import DispatcherStats from '@/components/JournalView/DispatcherStats.vue';
import { URLs } from '@/scripts/utils/apiURLs';
import { useStore } from '@/store/store';
import Loading from '../Global/Loading.vue';
import { URLs } from '../../scripts/utils/apiURLs';
import dateMixin from '../../mixins/dateMixin';
import { DataStatus } from '../../scripts/enums/DataStatus';
import { useStore } from '../../store/store';
const PROD_MODE = process.env.VUE_APP_JORUNAL_DISPATCHERS_DEV != '1' || process.env.NODE_ENV === 'production';
const DISPATCHERS_API_URL = (PROD_MODE ? `${URLs.stacjownikAPI}/api` : 'http://localhost:3001/api') + '/getDispatchers';
const DISPATCHERS_API_URL = `${URLs.stacjownikAPI}/api/getDispatchers`;
interface DispatcherHistoryItem {
id: string;
@@ -139,10 +136,6 @@ export default defineComponent({
},
data: () => ({
icons: {
arrow: require('@/assets/icon-arrow-asc.svg'),
},
currentQuery: '',
scrollDataLoaded: true,
scrollNoMoreData: false,
@@ -20,7 +20,7 @@
@keydown.enter="onInputSearch"
/>
<img class="search-exit" :src="exitIcon" alt="exit-icon" @click="onInputClear(propName)" />
<img class="search-exit" :src="getIcon('exit')" alt="exit-icon" @click="onInputClear(propName)" />
</div>
<!-- <div class="search-box">
<input
@@ -67,12 +67,15 @@
<script lang="ts">
import { defineComponent, inject, JournalFilter, PropType } from 'vue';
import imageMixin from '../../mixins/imageMixin';
import ActionButton from '../Global/ActionButton.vue';
import SelectBox from '../Global/SelectBox.vue';
export default defineComponent({
components: { SelectBox, ActionButton },
emits: ['onSorterChange', 'onInputChange', 'onFilterChange'],
mixins: [imageMixin],
props: {
sorterOptionIds: {
type: Array as PropType<Array<string>>,
@@ -85,9 +88,6 @@ export default defineComponent({
},
},
data: () => ({
exitIcon: require('@/assets/icon-exit.svg'),
}),
setup() {
return {
@@ -150,34 +150,26 @@
import { computed, defineComponent, JournalFilter, provide, reactive, Ref, ref } from 'vue';
import axios from 'axios';
import SearchBox from '@/components/Global/SearchBox.vue';
import dateMixin from '@/mixins/dateMixin';
import { DataStatus } from '@/scripts/enums/DataStatus';
import ActionButton from '@/components/Global/ActionButton.vue';
import JournalOptions from '@/components/JournalView/JournalOptions.vue';
import { URLs } from '@/scripts/utils/apiURLs';
import { journalTimetableFilters } from '@/data/journalFilters';
import { JournalFilterType } from '@/scripts/enums/JournalFilterType';
import routerMixin from '@/mixins/routerMixin';
import { useStore } from '@/store/store';
import DriverStats from './DriverStats.vue';
import { TimetableHistory } from '@/scripts/interfaces/api/TimetablesAPIData';
import Loading from '../Global/Loading.vue';
import { journalTimetableFilters } from '../../data/journalFilters';
import dateMixin from '../../mixins/dateMixin';
import routerMixin from '../../mixins/routerMixin';
import { DataStatus } from '../../scripts/enums/DataStatus';
import { JournalFilterType } from '../../scripts/enums/JournalFilterType';
import { TimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
import { URLs } from '../../scripts/utils/apiURLs';
import { useStore } from '../../store/store';
import JournalOptions from './JournalOptions.vue';
const PROD_MODE = process.env.VUE_APP_JOURNAL_TIMETABLES_DEV != '1' || process.env.NODE_ENV === 'production';
const TIMETABLES_API_URL = PROD_MODE
? `${URLs.stacjownikAPI}/api/getTimetables`
: 'http://localhost:3001/api/getTimetables';
const TIMETABLES_API_URL = `${URLs.stacjownikAPI}/api/getTimetables`;
type JournalTimetableSearcher = {
[key in 'search-driver' | 'search-train']: string;
};
export default defineComponent({
components: { SearchBox, ActionButton, JournalOptions, DriverStats, Loading },
components: { DriverStats, Loading, JournalOptions },
mixins: [dateMixin, routerMixin],
name: 'JournalTimetables',
@@ -189,10 +181,6 @@ export default defineComponent({
},
data: () => ({
icons: {
arrow: require('@/assets/icon-arrow-asc.svg'),
},
currentQuery: '',
scrollDataLoaded: true,
scrollNoMoreData: false,
@@ -31,13 +31,14 @@
</template>
<script lang="ts">
import dateMixin from '@/mixins/dateMixin';
import { DataStatus } from '@/scripts/enums/DataStatus';
import { DispatcherHistory } from '@/scripts/interfaces/api/DispatchersAPIData';
import Station from '@/scripts/interfaces/Station';
import { URLs } from '@/scripts/utils/apiURLs';
import axios from 'axios';
import { defineComponent, PropType } from 'vue';
import dateMixin from '../../mixins/dateMixin';
import { DataStatus } from '../../scripts/enums/DataStatus';
import { DispatcherHistory } from '../../scripts/interfaces/api/DispatchersAPIData';
import Station from '../../scripts/interfaces/Station';
import { URLs } from '../../scripts/utils/apiURLs';
import Loading from '../Global/Loading.vue';
export default defineComponent({
+1 -1
View File
@@ -10,8 +10,8 @@
<script lang="ts">
import { defineComponent } from 'vue';
import Station from '../../scripts/interfaces/Station';
import Station from '@/scripts/interfaces/Station';
export default defineComponent({
props: {
+1 -1
View File
@@ -70,8 +70,8 @@ import SceneryInfoStats from './SceneryInfo/SceneryInfoStats.vue';
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 Station from '@/scripts/interfaces/Station';
export default defineComponent({
components: {
@@ -13,7 +13,7 @@
</router-link>
<span class="dispatcher_likes text--primary">
<img :src="icons.like" alt="icon-like" />
<img :src="getIcon('like')" alt="icon-like" />
<span>{{ station.onlineInfo?.dispatcherRate || '0' }}</span>
</span>
</div>
@@ -35,14 +35,14 @@
<script lang="ts">
import { defineComponent } from 'vue';
import styleMixin from '@/mixins/styleMixin';
import Station from '@/scripts/interfaces/Station';
import dateMixin from '@/mixins/dateMixin';
import routerMixin from '@/mixins/routerMixin';
import dateMixin from '../../../mixins/dateMixin';
import imageMixin from '../../../mixins/imageMixin';
import routerMixin from '../../../mixins/routerMixin';
import styleMixin from '../../../mixins/styleMixin';
import Station from '../../../scripts/interfaces/Station';
export default defineComponent({
mixins: [styleMixin, dateMixin, routerMixin],
mixins: [styleMixin, dateMixin, routerMixin, imageMixin],
props: {
station: {
type: Object as () => Station,
@@ -54,13 +54,6 @@ export default defineComponent({
default: -1,
},
},
data: () => ({
icons: {
spawn: require('@/assets/icon-spawn.svg'),
like: require('@/assets/icon-like.svg'),
},
}),
});
</script>
@@ -20,7 +20,7 @@
<img
v-if="station.generalInfo?.SUP"
class="icon-info"
:src="require(`@/assets/icon-SUP.svg`)"
:src="getIcon('SUP')"
alt="SUP (RASP-UZK)"
:title="$t('desc.SUP')"
/>
@@ -28,7 +28,7 @@
<img
v-if="station.generalInfo?.signalType"
class="icon-info"
:src="require(`@/assets/icon-${station.generalInfo.signalType}.svg`)"
:src="getIcon(station.generalInfo.signalType)"
:alt="station.generalInfo.signalType"
:title="$t('desc.signals-type') + $t(`signals.${station.generalInfo.signalType}`)"
/>
@@ -36,7 +36,7 @@
<img
v-if="station.generalInfo?.availability == 'nonPublic'"
class="icon-info"
:src="icons.lock"
:src="getIcon('lock')"
alt="Non-public scenery"
:title="$t('desc.non-public')"
/>
@@ -44,7 +44,7 @@
<img
v-if="station.generalInfo?.availability == 'unavailable'"
class="icon-info"
:src="icons.unavailable"
:src="getIcon('unavailable')"
alt="Unavailable scenery"
:title="$t('desc.unavailable')"
/>
@@ -52,7 +52,7 @@
<img
v-if="station.generalInfo?.availability == 'abandoned'"
class="icon-info"
:src="icons.abandoned"
:src="getIcon('abandoned')"
alt="Abandoned scenery"
:title="$t('desc.abandoned')"
/>
@@ -60,7 +60,7 @@
<img
v-if="station.generalInfo?.lines"
class="icon-info"
:src="icons.real"
:src="getIcon('real')"
alt="real scenery"
:title="`${$t('desc.real')} ${station.generalInfo.lines}`"
/>
@@ -68,7 +68,7 @@
<img
v-if="!station.generalInfo"
class="icon-info"
:src="icons.unknown"
:src="getImage('unknown.png')"
alt="icon-unknown"
:title="$t('desc.unknown')"
/>
@@ -77,31 +77,19 @@
<script lang="ts">
import { defineComponent } from 'vue';
import stationInfoMixin from '@/mixins/stationInfoMixin';
import Station from '@/scripts/interfaces/Station';
import styleMixin from '@/mixins/styleMixin';
import imageMixin from '../../../mixins/imageMixin';
import stationInfoMixin from '../../../mixins/stationInfoMixin';
import styleMixin from '../../../mixins/styleMixin';
import Station from '../../../scripts/interfaces/Station';
export default defineComponent({
mixins: [stationInfoMixin, styleMixin],
mixins: [stationInfoMixin, styleMixin, imageMixin],
props: {
station: {
type: Object as () => Station,
default: {},
},
},
data: () => ({
icons: {
td2: require('@/assets/icon-td2.svg'),
lock: require('@/assets/icon-lock.svg'),
unavailable: require('@/assets/icon-unavailable.svg'),
unknown: require('@/assets/icon-unknown.svg'),
abandoned: require('@/assets/icon-abandoned.svg'),
real: require('@/assets/icon-real.svg'),
},
}),
});
</script>
@@ -130,3 +118,4 @@ export default defineComponent({
}
}
</style>
@@ -57,8 +57,8 @@
</template>
<script lang="ts">
import Station from '@/scripts/interfaces/Station';
import { defineComponent } from 'vue';
import Station from '../../../scripts/interfaces/Station';
export default defineComponent({
props: {
@@ -1,7 +1,7 @@
<template>
<section class="info-spawn-list">
<h3 class="spawn-header section-header">
<img :src="icons.spawn" alt="icon-spawn" />
<img :src="getIcon('spawn')" alt="icon-spawn" />
&nbsp;{{ $t('scenery.spawns') }} &nbsp;
<span class="text--primary">{{ station.onlineInfo?.spawns.length || '0' }}</span>
</h3>
@@ -24,22 +24,19 @@
</template>
<script lang="ts">
import Station from '@/scripts/interfaces/Station';
import { defineComponent } from 'vue';
import imageMixin from '../../../mixins/imageMixin';
import Station from '../../../scripts/interfaces/Station';
export default defineComponent({
mixins: [imageMixin],
props: {
station: {
type: Object as () => Station,
default: {},
},
},
data: () => ({
icons: {
spawn: require('@/assets/icon-spawn.svg'),
},
}),
});
</script>
@@ -1,24 +1,24 @@
<template>
<section class="info-stats" :class="!station.onlineInfo ? 'no-stats' : ''">
<span class="likes">
<img :src="icons.like" alt="icon-like" />
<img :src="getIcon('like')" alt="icon-like" />
<span>{{ station.onlineInfo?.dispatcherRate || '0' }}</span>
</span>
<span class="users">
<img :src="icons.user" alt="icon-user" />
<img :src="getIcon('user')" alt="icon-user" />
<span>{{ station.onlineInfo?.currentUsers || '0' }}</span>
/
<span>{{ station.onlineInfo?.maxUsers || '0' }}</span>
</span>
<span class="spawns">
<img :src="icons.spawn" alt="icon-spawn" />
<img :src="getIcon('spawn')" alt="icon-spawn" />
<span>{{ station.onlineInfo?.spawns.length || '0' }}</span>
</span>
<span class="schedules">
<img :src="icons.timetable" alt="icon-timetable" />
<img :src="getIcon('timetable')" alt="icon-timetable" />
<span>
<span style="color: #eee">{{ station.onlineInfo?.scheduledTrains?.length || '0' }}</span>
/
@@ -32,25 +32,17 @@
<script lang="ts">
import { defineComponent } from 'vue';
import Station from '@/scripts/interfaces/Station';
import imageMixin from '../../../mixins/imageMixin';
import Station from '../../../scripts/interfaces/Station';
export default defineComponent({
mixins: [imageMixin],
props: {
station: {
type: Object as () => Station,
default: {},
},
},
data: () => ({
icons: {
like: require('@/assets/icon-like.svg'),
timetable: require('@/assets/icon-timetable.svg'),
user: require('@/assets/icon-user.svg'),
spawn: require('@/assets/icon-spawn.svg'),
},
}),
});
</script>
@@ -83,7 +75,7 @@ export default defineComponent({
}
span > img {
width: 1.2em;
width: 1.2em;
margin-right: 0.5em;
}
}
@@ -1,7 +1,7 @@
<template>
<section class="info-user-list">
<h3 class="user-header section-header">
<img :src="icons.user" alt="icon-user" />
<img :src="getIcon('user')" alt="icon-user" />
&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>
@@ -27,13 +27,15 @@
</template>
<script lang="ts">
import routerMixin from '@/mixins/routerMixin';
import Station from '@/scripts/interfaces/Station';
import { useStore } from '@/store/store';
import { computed, defineComponent } from 'vue';
import imageMixin from '../../../mixins/imageMixin';
import routerMixin from '../../../mixins/routerMixin';
import Station from '../../../scripts/interfaces/Station';
import { useStore } from '../../../store/store';
export default defineComponent({
mixins: [routerMixin],
mixins: [routerMixin, imageMixin],
props: {
station: {
@@ -65,12 +67,6 @@ export default defineComponent({
return { computedStationTrains, store };
},
data: () => ({
icons: {
user: require('@/assets/icon-user.svg'),
},
}),
methods: {
selectTrain(trainId: string) {
this.store.chosenModalTrain = this.store.trainList.find((train) => train.trainId == trainId);
+10 -12
View File
@@ -2,7 +2,7 @@
<section class="scenery-timetable">
<div class="timetable-header">
<h3>
<img :src="icons.timetable" alt="icon-timetable" />&nbsp;
<img :src="getIcon('timetable')" alt="icon-timetable" />&nbsp;
<span>{{ $t('scenery.timetables') }}</span>
&nbsp;
<span class="text--primary">{{ station.onlineInfo?.scheduledTrains?.length || '0' }}</span>
@@ -51,7 +51,7 @@
{{ scheduledTrain.trainNo }}
<span class="g-tooltip" v-if="scheduledTrain.stopInfo.comments">
<img :src="icons.warning" />
<img :src="getIcon('warning')" />
<span class="content" v-html="scheduledTrain.stopInfo.comments"> </span>
</span>
</span>
@@ -153,22 +153,24 @@
</template>
<script lang="ts">
import Station from '@/scripts/interfaces/Station';
import SelectBox from '../Global/SelectBox.vue';
import { computed, defineComponent, PropType, ref } from '@vue/runtime-core';
import { useRoute } from 'vue-router';
import dateMixin from '@/mixins/dateMixin';
import routerMixin from '@/mixins/routerMixin';
import { useStore } from '@/store/store';
import Loading from '../Global/Loading.vue';
import TrainModal from '../Global/TrainModal.vue';
import dateMixin from '../../mixins/dateMixin';
import routerMixin from '../../mixins/routerMixin';
import Station from '../../scripts/interfaces/Station';
import { useStore } from '../../store/store';
import imageMixin from '../../mixins/imageMixin';
export default defineComponent({
name: 'SceneryTimetable',
components: { SelectBox, Loading, TrainModal },
mixins: [dateMixin, routerMixin],
mixins: [dateMixin, routerMixin, imageMixin],
props: {
station: {
@@ -178,12 +180,8 @@ export default defineComponent({
},
data: () => ({
viewIcon: require('@/assets/icon-view.svg'),
listOpen: false,
icons: {
warning: require('@/assets/icon-warning.svg'),
timetable: require('@/assets/icon-timetable.svg'),
},
}),
setup(props) {
@@ -33,13 +33,14 @@
</template>
<script lang="ts">
import dateMixin from '@/mixins/dateMixin';
import { DataStatus } from '@/scripts/enums/DataStatus';
import { SceneryTimetableHistory, TimetableHistory } from '@/scripts/interfaces/api/TimetablesAPIData';
import Station from '@/scripts/interfaces/Station';
import { URLs } from '@/scripts/utils/apiURLs';
import axios from 'axios';
import { defineComponent, PropType } from 'vue';
import dateMixin from '../../mixins/dateMixin';
import { DataStatus } from '../../scripts/enums/DataStatus';
import { TimetableHistory, SceneryTimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
import Station from '../../scripts/interfaces/Station';
import { URLs } from '../../scripts/utils/apiURLs';
import Loading from '../Global/Loading.vue';
export default defineComponent({
@@ -2,7 +2,7 @@
<section class="filter-card" v-click-outside="closeCard">
<div class="card_btn">
<button class="btn btn--option" @click="toggleCard">
<img class="button_icon" :src="filterIcon" alt="icon-filter" />
<img class="button_icon" :src="getIcon('filter2')" alt="icon-filter" />
{{ $t('options.filters') }}
</button>
</div>
@@ -91,21 +91,22 @@
</template>
<script lang="ts">
import { defineComponent, inject } from '@vue/runtime-core';
import inputData from '@/data/options.json';
import { defineComponent, inject } from 'vue';
import inputData from '../../data/options.json';
import imageMixin from '../../mixins/imageMixin';
import StorageManager from '../../scripts/managers/storageManager';
import { useStore } from '../../store/store';
import StorageManager from '@/scripts/managers/storageManager';
import ActionButton from '../Global/ActionButton.vue';
import FilterOption from './FilterOption.vue';
import { useStore } from '@/store/store';
export default defineComponent({
components: { ActionButton, FilterOption },
emits: ['changeFilterValue', 'invertFilters', 'resetFilters'],
mixins: [imageMixin],
data: () => ({
filterIcon: require('@/assets/icon-filter2.svg'),
inputs: { ...inputData },
saveOptions: false,
@@ -165,7 +166,7 @@ export default defineComponent({
handleAuthorsInput(e: Event) {
clearTimeout(this.delayInputTimer);
this.delayInputTimer = setTimeout(() => {
this.delayInputTimer = window.setTimeout(() => {
this.handleInput(e);
}, 400);
},
@@ -200,7 +201,7 @@ export default defineComponent({
this.$emit('invertFilters');
},
saveFilters(change: { value }) {
saveFilters(change: { value: any }) {
this.saveOptions = change.value;
if (!this.saveOptions) {
+20 -34
View File
@@ -15,7 +15,7 @@
<img
class="sort-icon"
v-if="sorterActive.index == i"
:src="sorterActive.dir == 1 ? ascIcon : descIcon"
:src="sorterActive.dir == 1 ? getIcon('arrow-asc') : getIcon('arrow-desc')"
alt="sort icon"
/>
</span>
@@ -23,12 +23,12 @@
<th v-for="(id, i) in headIconsIds" :key="id" @click="() => changeSorter(i + 7)">
<span class="header_wrapper">
<img :src="require(`@/assets/icon-${id}.svg`)" :alt="id" :title="$t(`sceneries.${id}s`)" />
<img :src="getIcon(id)" :alt="id" :title="$t(`sceneries.${id}s`)" />
<img
class="sort-icon"
v-if="sorterActive.index == i + 7"
:src="sorterActive.dir == 1 ? ascIcon : descIcon"
:src="sorterActive.dir == 1 ? getIcon('arrow-asc') : getIcon('arrow-desc')"
alt="sort icon"
/>
</span>
@@ -67,15 +67,15 @@
</span>
<span v-else-if="station.generalInfo.availability == 'abandoned'">
<img :src="abandonedIcon" alt="non-public" :title="$t('desc.abandoned')" />
<img :src="getIcon('abandoned')" alt="non-public" :title="$t('desc.abandoned')" />
</span>
<span v-else-if="station.generalInfo.availability == 'nonPublic'">
<img :src="lockIcon" alt="non-public" :title="$t('desc.non-public')" />
<img :src="getIcon('lock')" alt="non-public" :title="$t('desc.non-public')" />
</span>
<span v-else>
<img :src="unavailableIcon" alt="unavailable" :title="$t('desc.unavailable')" />
<img :src="getIcon('unavailable')" alt="unavailable" :title="$t('desc.unavailable')" />
</span>
</span>
@@ -154,7 +154,7 @@
<img
class="icon-info"
v-if="station.generalInfo.SUP"
:src="require(`@/assets/icon-SUP.svg`)"
:src="getIcon('SUP')"
alt="SUP (RASP-UZK)"
:title="$t('desc.SUP')"
/>
@@ -164,7 +164,7 @@
<img
class="icon-info"
v-if="station.generalInfo.signalType"
:src="require(`@/assets/icon-${station.generalInfo.signalType}.svg`)"
:src="getIcon(station.generalInfo.signalType)"
:alt="station.generalInfo.signalType"
:title="$t('desc.signals-type') + $t(`signals.${station.generalInfo.signalType}`)"
/>
@@ -174,7 +174,7 @@
<img
class="icon-info"
v-if="station.generalInfo && station.generalInfo.routes.sblRouteNames.length > 0"
:src="SBLIcon"
:src="getIcon('SBL')"
alt="SBL"
:title="$t('desc.SBL') + `${station.generalInfo.routes.sblRouteNames.join(',')}`"
/>
@@ -182,7 +182,7 @@
</td>
<td class="station_info" v-else>
<img class="icon-info" :src="unknownIcon" alt="icon-unknown" :title="$t('desc.unknown')" />
<img class="icon-info" :src="getImage('unknown.png')" alt="icon-unknown" :title="$t('desc.unknown')" />
</td>
<td class="station_users" :class="{ inactive: !station.onlineInfo }">
@@ -222,16 +222,15 @@
</template>
<script lang="ts">
import styleMixin from '@/mixins/styleMixin';
import dateMixin from '@/mixins/dateMixin';
import stationInfoMixin from '@/mixins/stationInfoMixin';
import returnBtnMixin from '@/mixins/returnBtnMixin';
import { DataStatus } from '@/scripts/enums/DataStatus';
import { computed, ComputedRef, defineComponent } from '@vue/runtime-core';
import Station from '@/scripts/interfaces/Station';
import { StoreData } from '@/scripts/interfaces/StoreData';
import { useStore } from '@/store/store';
import { defineComponent, computed } from 'vue';
import dateMixin from '../../mixins/dateMixin';
import imageMixin from '../../mixins/imageMixin';
import returnBtnMixin from '../../mixins/returnBtnMixin';
import stationInfoMixin from '../../mixins/stationInfoMixin';
import styleMixin from '../../mixins/styleMixin';
import { DataStatus } from '../../scripts/enums/DataStatus';
import Station from '../../scripts/interfaces/Station';
import { useStore } from '../../store/store';
import Loading from '../Global/Loading.vue';
export default defineComponent({
@@ -250,21 +249,8 @@ export default defineComponent({
setFocusedStation: { type: Function, required: true },
changeSorter: { type: Function, required: true },
},
mixins: [styleMixin, dateMixin, stationInfoMixin, returnBtnMixin],
mixins: [styleMixin, dateMixin, stationInfoMixin, returnBtnMixin, imageMixin],
data: () => ({
likeIcon: require('@/assets/icon-like.svg'),
spawnIcon: require('@/assets/icon-spawn.svg'),
timetableIcon: require('@/assets/icon-timetable.svg'),
userIcon: require('@/assets/icon-user.svg'),
trainIcon: require('@/assets/icon-train.svg'),
SBLIcon: require('@/assets/icon-SBL.svg'),
SUPIcon: require('@/assets/icon-SUP.svg'),
lockIcon: require('@/assets/icon-lock.svg'),
unavailableIcon: require('@/assets/icon-unavailable.svg'),
unknownIcon: require('@/assets/icon-unknown.svg'),
abandonedIcon: require('@/assets/icon-abandoned.svg'),
ascIcon: require('@/assets/icon-arrow-asc.svg'),
descIcon: require('@/assets/icon-arrow-desc.svg'),
headIds: ['station', 'min-lvl', 'status', 'dispatcher', 'dispatcher-lvl', 'routes', 'general'],
headIconsIds: ['user', 'spawn', 'timetable'],
lastSelectedStationName: '',
+7 -14
View File
@@ -20,7 +20,7 @@
<img
v-if="getSceneriesWithComments(train.timetableData).length > 0"
class="image-warning"
:src="icons.warning"
:src="getIcon('warning')"
:title="`${$t('trains.timetable-comments')} (${getSceneriesWithComments(train.timetableData)})`"
/>
</div>
@@ -59,7 +59,7 @@
</div>
<div class="driver_position text--grayed" style="margin-top: 0.25em">
{{ displayTrainPosition(train) }}
{{ displayTrainPosition(train) }}
</div>
</section>
@@ -79,7 +79,7 @@
<div>
<span v-for="(stat, i) in STATS.main" :key="stat.name">
<span v-if="i > 0"> &bull; </span>
<span>{{ `${~~(train[stat.name] * (stat.multiplier || 1))}${stat.unit}` }} </span>
<span>{{ `${~~((train as any)[stat.name] * (stat.multiplier || 1))}${stat.unit}` }} </span>
</span>
</div>
</section>
@@ -87,9 +87,10 @@
</template>
<script lang="ts">
import trainInfoMixin from '@/mixins/trainInfoMixin';
import Train from '@/scripts/interfaces/Train';
import { defineComponent } from 'vue';
import imageMixin from '../../mixins/imageMixin';
import trainInfoMixin from '../../mixins/trainInfoMixin';
import Train from '../../scripts/interfaces/Train';
export default defineComponent({
props: {
@@ -104,13 +105,7 @@ export default defineComponent({
},
},
mixins: [trainInfoMixin],
data: () => ({
icons: {
warning: require('@/assets/icon-warning.svg'),
},
}),
mixins: [trainInfoMixin, imageMixin],
});
</script>
@@ -165,7 +160,6 @@ export default defineComponent({
.train-status-badges {
display: flex;
flex-wrap: wrap;
}
.train-badge {
@@ -204,7 +198,6 @@ export default defineComponent({
display: flex;
align-items: center;
flex-wrap: wrap;
}
.timetable_progress-bar {
+4 -6
View File
@@ -15,13 +15,13 @@
<div class="search-box">
<input class="search-input" v-model="searchedTrain" :placeholder="$t('trains.search-train')" />
<img class="search-exit" :src="exitIcon" alt="exit-icon" @click="() => (searchedTrain = '')" />
<img class="search-exit" :src="getIcon('exit')" alt="exit-icon" @click="() => (searchedTrain = '')" />
</div>
<div class="search-box">
<input class="search-input" v-model="searchedDriver" :placeholder="$t('trains.search-driver')" />
<img class="search-exit" :src="exitIcon" alt="exit-icon" @click="() => (searchedDriver = '')" />
<img class="search-exit" :src="getIcon('exit')" alt="exit-icon" @click="() => (searchedDriver = '')" />
</div>
</div>
</div>
@@ -58,15 +58,13 @@
<script lang="ts">
import { computed, defineComponent, inject, TrainFilter } from 'vue';
import { useI18n } from 'vue-i18n';
import imageMixin from '../../mixins/imageMixin';
import SelectBox from '../Global/SelectBox.vue';
export default defineComponent({
components: { SelectBox },
emits: ['changeSearchedTrain', 'changeSearchedDriver', 'changeSorter'],
data: () => ({
exitIcon: require('@/assets/icon-exit.svg'),
}),
mixins: [imageMixin],
setup() {
const { t } = useI18n();
+9 -12
View File
@@ -2,7 +2,7 @@
<section class="filter-card" v-click-outside="closeCard">
<div class="card_btn">
<action-button @click="toggleCard">
<img class="button_icon" :src="filterIcon" alt="icon-filter" />
<img class="button_icon" :src="getIcon('filter2')" alt="icon-filter" />
<p>{{ $t('options.filters') }}</p>
</action-button>
</div>
@@ -26,13 +26,13 @@
<div class="search-box">
<input class="search-input" v-model="searchedTrain" :placeholder="$t('trains.search-train')" />
<img class="search-exit" :src="exitIcon" alt="exit-icon" @click="() => (searchedTrain = '')" />
<img class="search-exit" :src="getIcon('exit')" alt="exit-icon" @click="() => (searchedTrain = '')" />
</div>
<div class="search-box">
<input class="search-input" v-model="searchedDriver" :placeholder="$t('trains.search-driver')" />
<img class="search-exit" :src="exitIcon" alt="exit-icon" @click="() => (searchedDriver = '')" />
<img class="search-exit" :src="getIcon('exit')" alt="exit-icon" @click="() => (searchedDriver = '')" />
</div>
</div>
</div>
@@ -50,24 +50,21 @@
</template>
<script lang="ts">
import { defineComponent, inject } from '@vue/runtime-core';
import inputData from "../../data/options.json";
import inputData from '@/data/options.json';
import ActionButton from '@/components/Global/ActionButton.vue';
import { sorterOptions } from '@/data/trainOptions';
import { TrainFilter, computed } from 'vue';
import { TrainFilter, computed, defineComponent, inject } from 'vue';
import { useI18n } from 'vue-i18n';
import SelectBox from '../Global/SelectBox.vue';
import ActionButton from '../Global/ActionButton.vue';
import { sorterOptions } from '../../data/trainOptions';
import imageMixin from "../../mixins/imageMixin";
export default defineComponent({
components: { ActionButton, SelectBox },
emits: ['changeFilterValue', 'invertFilters', 'resetFilters'],
mixins: [imageMixin],
data: () => ({
filterIcon: require('@/assets/icon-filter2.svg'),
exitIcon: require('@/assets/icon-exit.svg'),
inputs: { ...inputData },
}),
+6 -11
View File
@@ -83,10 +83,11 @@
<script lang="ts">
import { computed, defineComponent, PropType } from '@vue/runtime-core';
import dateMixin from '@/mixins/dateMixin';
import TrainStop from '@/scripts/interfaces/TrainStop';
import dateMixin from '../../mixins/dateMixin';
import imageMixin from '../../mixins/imageMixin';
import Train from '../../scripts/interfaces/Train';
import TrainStop from '../../scripts/interfaces/TrainStop';
import StopDate from '../Global/StopDate.vue';
import Train from '@/scripts/interfaces/Train';
export default defineComponent({
components: { StopDate },
@@ -97,16 +98,10 @@ export default defineComponent({
},
},
mixins: [dateMixin],
mixins: [dateMixin, imageMixin],
emits: ['click'],
data: () => ({
icons: {
warning: require('@/assets/icon-warning.svg'),
},
}),
setup(props) {
return {
lastConfirmed: computed(() => {
@@ -154,7 +149,7 @@ export default defineComponent({
onImageError(e: Event) {
const imageEl = e.target as HTMLImageElement;
imageEl.src = require('@/assets/unknown.png');
imageEl.src = this.getImage('unknown.png');
},
},
});
+36 -72
View File
@@ -1,29 +1,27 @@
<template>
<div class="train-stats" v-click-outside="closeStats">
<action-button class="stats_button" @click="toggleStatsOpen">
<img :src="statsIcon" :alt="$t('trains.stats')" />
<p>{{ $t("trains.stats") }}</p>
<img :src="getIcon('stats')" :alt="$t('trains.stats')" />
<p>{{ $t('trains.stats') }}</p>
</action-button>
<transition name="stats-anim" class="stats_wrapper" tag="div">
<div class="stats-body" v-if="trainStatsOpen">
<h2 class="stats-header">
<img :src="statsIcon" :alt="$t('trains.stats')" />
{{ $t("trains.stats") }}
<img :src="getIcon('stats')" :alt="$t('trains.stats')" />
{{ $t('trains.stats') }}
</h2>
<div class="stats-speed">
<div class="title stats-title">
{{ $t("trains.stats-speed") }}
</div>
<div class="stats-content">
{{ speedStats.min }} | {{ speedStats.avg }} | {{ speedStats.max }}
{{ $t('trains.stats-speed') }}
</div>
<div class="stats-content">{{ speedStats.min }} | {{ speedStats.avg }} | {{ speedStats.max }}</div>
</div>
<div class="stats-length">
<div class="title stats-title">
{{ $t("trains.stats-length") }}
{{ $t('trains.stats-length') }}
</div>
<div class="stats-content">
{{ timetableStats.min }} | {{ timetableStats.avg }} |
@@ -33,15 +31,11 @@
<div class="stats-categories">
<div class="title stats-title">
{{ $t("trains.stats-categories") }}
{{ $t('trains.stats-categories') }}
</div>
<div class="category-list">
<span
class="category"
v-for="[key, value] of categoryList"
:key="key"
>
<span class="category" v-for="[key, value] of categoryList" :key="key">
<span class="category-type">{{ key }}</span>
<span class="category-count">{{ value }}</span>
</span>
@@ -49,28 +43,22 @@
<div class="special-list">
<span class="special twr">
<span class="special-type">{{
$t("trains.stats-special-twr")
}}</span>
<span class="special-type">{{ $t('trains.stats-special-twr') }}</span>
<span class="special-count">{{ specialTrainCount[0] }}</span>
</span>
<span class="special skr">
<span class="special-type">{{
$t("trains.stats-special-skr")
}}</span>
<span class="special-type">{{ $t('trains.stats-special-skr') }}</span>
<span class="special-count">{{ specialTrainCount[1] }}</span>
</span>
</div>
</div>
<div class="stats-locos">
<div class="title stats-title">{{ $t("trains.stats-locos") }}</div>
<div class="title stats-title">{{ $t('trains.stats-locos') }}</div>
<div class="loco-list stats-content">
<div class="loco-item" v-for="(loco, i) in locoList" :key="i">
{{ loco[0] }} | {{ loco[1] }}
</div>
<div class="loco-item" v-for="(loco, i) in locoList" :key="i">{{ loco[0] }} | {{ loco[1] }}</div>
</div>
</div>
</div>
@@ -79,13 +67,15 @@
</template>
<script lang="ts">
import ActionButton from "@/components/Global/ActionButton.vue";
import Train from "@/scripts/interfaces/Train";
import { computed, defineComponent, inject } from "@vue/runtime-core";
import { defineComponent, computed, inject } from 'vue';
import imageMixin from '../../mixins/imageMixin';
import Train from '../../scripts/interfaces/Train';
import ActionButton from '../Global/ActionButton.vue';
export default defineComponent({
components: { ActionButton },
mixins: [imageMixin],
props: {
trains: {
type: Array as () => Train[],
@@ -95,7 +85,6 @@ export default defineComponent({
data: () => ({
trainStatsOpen: false,
statsIcon: require("@/assets/icon-stats.svg"),
}),
methods: {
@@ -110,14 +99,11 @@ export default defineComponent({
setup(props) {
const speedStats = computed(() => {
if (props.trains.length == 0) return { avg: "0", min: "0", max: "0" };
if (props.trains.length == 0) return { avg: '0', min: '0', max: '0' };
const trainList = props.trains.filter((train) => train.timetableData);
const avg = (
trainList.reduce((acc, train) => acc + train.speed, 0) /
trainList.length
).toFixed(2);
const avg = (trainList.reduce((acc, train) => acc + train.speed, 0) / trainList.length).toFixed(2);
const minMaxSpeed = trainList.reduce((acc, train) => {
if (!train.timetableData) return acc;
@@ -136,32 +122,21 @@ export default defineComponent({
});
const timetableStats = computed(() => {
if (props.trains.length == 0) return { avg: "0", min: "0", max: "0" };
if (props.trains.length == 0) return { avg: '0', min: '0', max: '0' };
const activeTrainsLength = props.trains.filter(
(train) => train.timetableData
).length;
const activeTrainsLength = props.trains.filter((train) => train.timetableData).length;
const avg = (
props.trains.reduce(
(acc, train) =>
train.timetableData ? acc + train.timetableData.routeDistance : acc,
0
) / activeTrainsLength
props.trains.reduce((acc, train) => (train.timetableData ? acc + train.timetableData.routeDistance : acc), 0) /
activeTrainsLength
).toFixed(2);
const minMaxDistance = props.trains.reduce((acc, train) => {
if (!train.timetableData) return acc;
acc[0] =
!acc[0] || train.timetableData.routeDistance < acc[0]
? train.timetableData.routeDistance
: acc[0];
acc[0] = !acc[0] || train.timetableData.routeDistance < acc[0] ? train.timetableData.routeDistance : acc[0];
acc[1] =
!acc[1] || train.timetableData.routeDistance > acc[1]
? train.timetableData.routeDistance
: acc[1];
acc[1] = !acc[1] || train.timetableData.routeDistance > acc[1] ? train.timetableData.routeDistance : acc[1];
return acc;
}, [] as any);
@@ -178,9 +153,7 @@ export default defineComponent({
acc.set(
train.timetableData.category,
acc.get(train.timetableData.category)
? acc.get(train.timetableData.category) + 1
: 1
acc.get(train.timetableData.category) ? acc.get(train.timetableData.category) + 1 : 1
);
return acc;
@@ -193,35 +166,26 @@ export default defineComponent({
const map: Map<string, number> = props.trains.reduce((acc, train) => {
if (!train.timetableData || !train.locoType) return acc;
acc.set(
train.locoType,
acc.get(train.locoType) ? acc.get(train.locoType) + 1 : 1
);
acc.set(train.locoType, acc.get(train.locoType) ? acc.get(train.locoType) + 1 : 1);
return acc;
}, new Map());
const sorted = [...map.entries()]
.sort((a, b) => b[1] - a[1])
.filter((v, i) => i < 3);
const sorted = [...map.entries()].sort((a, b) => b[1] - a[1]).filter((v, i) => i < 3);
return sorted;
});
const specialTrainCount = computed(() => {
const twrList = props.trains.filter(
(train) => train.timetableData && train.timetableData.TWR
);
const twrList = props.trains.filter((train) => train.timetableData && train.timetableData.TWR);
const skrList = props.trains.filter(
(train) => train.timetableData && train.timetableData.SKR
);
const skrList = props.trains.filter((train) => train.timetableData && train.timetableData.SKR);
return [twrList.length, skrList.length];
});
/* Inject list from TrainsView for category filter */
const chosenTrainCategories = inject("chosenTrainCategories") as string[];
const chosenTrainCategories = inject('chosenTrainCategories') as string[];
return {
speedStats,
@@ -229,14 +193,14 @@ export default defineComponent({
categoryList,
locoList,
specialTrainCount,
chosenTrainCategories
chosenTrainCategories,
};
},
});
</script>
<style lang="scss" scoped>
@import "../../styles/responsive";
@import '../../styles/responsive';
.stats-anim {
&-enter-active,
@@ -370,4 +334,4 @@ export default defineComponent({
justify-content: center;
}
}
</style>
</style>
+6 -26
View File
@@ -1,9 +1,5 @@
<template>
<div class="train-table">
<button class="return-btn" @click="scrollToTop" v-if="showReturnButton">
<img :src="icons.arrowAsc" alt="return arrow" />
</button>
<transition name="anim" mode="out-in">
<div :key="store.dataStatuses.trains">
<Loading v-if="trains.length == 0 && store.dataStatuses.trains == 0" />
@@ -29,19 +25,14 @@
</template>
<script lang="ts">
import { computed, defineComponent, inject, Ref } from '@vue/runtime-core';
import defaultVehicleIconsJSON from '@/data/defaultVehicleIcons.json';
import Train from '@/scripts/interfaces/Train';
import TrainSchedule from '@/components/TrainsView/TrainSchedule.vue';
import TrainInfo from '@/components/TrainsView/TrainInfo.vue';
import returnBtnMixin from '@/mixins/returnBtnMixin';
import { useStore } from '@/store/store';
import { defineComponent, inject, Ref, computed } from 'vue';
import returnBtnMixin from '../../mixins/returnBtnMixin';
import Train from '../../scripts/interfaces/Train';
import { useStore } from '../../store/store';
import Loading from '../Global/Loading.vue';
import TrainModal from '../Global/TrainModal.vue';
import TrainInfo from './TrainInfo.vue';
import TrainSchedule from './TrainSchedule.vue';
export default defineComponent({
components: {
@@ -60,17 +51,6 @@ export default defineComponent({
},
},
data: () => ({
defaultLocoImage: require('@/assets/unknown.png'),
icons: {
arrowAsc: require('@/assets/icon-arrow-asc.svg'),
arrowDesc: require('@/assets/icon-arrow-desc.svg'),
},
defaultVehicleIcons: defaultVehicleIconsJSON,
}),
setup(props) {
const store = useStore();
+1 -1
View File
@@ -1,5 +1,5 @@
import { JournalFilterType } from "@/scripts/enums/JournalFilterType";
import { JournalFilter } from "vue";
import { JournalFilterType } from "../scripts/enums/JournalFilterType";
export const journalTimetableFilters: JournalFilter[] = [
{
+1 -1
View File
@@ -1,5 +1,5 @@
import { TrainFilterType } from "@/scripts/enums/TrainFilterType";
import { TrainFilter } from "vue";
import { TrainFilterType } from "../scripts/enums/TrainFilterType";
export const trainFilters: TrainFilter[] = [
{
+2 -3
View File
@@ -2,12 +2,11 @@ import { createApp, Directive, ref } from 'vue';
import App from './App.vue';
import router from './router';
import enLang from '@/locales/en.json';
import plLang from '@/locales/pl.json';
import enLang from './locales/en.json';
import plLang from './locales/pl.json';
import { createI18n } from 'vue-i18n';
import { createPinia } from 'pinia';
import './registerServiceWorker'
const i18n = createI18n({
locale: 'pl',
+13
View File
@@ -0,0 +1,13 @@
import { defineComponent } from 'vue';
export default defineComponent({
methods: {
getIcon(name: string, ext = 'svg') {
return new URL(`../assets/icon-${name}.${ext}`, import.meta.url).href;
},
getImage(name: string) {
return new URL(`../assets/${name}`, import.meta.url).href;
}
},
});
+26 -23
View File
@@ -1,31 +1,34 @@
import { defineComponent, h } from "vue";
import { defineComponent, h } from 'vue';
import imageMixin from './imageMixin';
export default defineComponent({
data() {
return {
icons: {
arrow: require('@/assets/icon-arrow-asc.svg'),
},
mixins: [imageMixin],
showReturnButton: false
}
data() {
return {
icons: {
arrow: this.getIcon('arrow-asc'),
},
showReturnButton: false,
};
},
methods: {
scrollToTop() {
window.scrollTo({ top: 0 });
},
methods: {
scrollToTop() {
window.scrollTo({ top: 0 });
},
handleScroll() {
this.showReturnButton = window.scrollY > window.innerHeight * 0.35;
}
handleScroll() {
this.showReturnButton = window.scrollY > window.innerHeight * 0.35;
},
},
activated() {
window.addEventListener('scroll', this.handleScroll);
},
activated() {
window.addEventListener('scroll', this.handleScroll);
},
deactivated() {
window.removeEventListener('scroll', this.handleScroll);
},
})
deactivated() {
window.removeEventListener('scroll', this.handleScroll);
},
});
+6 -3
View File
@@ -1,8 +1,11 @@
import Train from '@/scripts/interfaces/Train';
import TrainStop from '@/scripts/interfaces/TrainStop';
import { defineComponent } from 'vue';
import Train from '../scripts/interfaces/Train';
import TrainStop from '../scripts/interfaces/TrainStop';
import imageMixin from './imageMixin';
export default defineComponent({
mixins: [imageMixin],
data: () => ({
STATS: {
main: [
@@ -134,7 +137,7 @@ export default defineComponent({
onImageError(e: Event) {
const imageEl = e.target as HTMLImageElement;
imageEl.src = require('@/assets/unknown.png');
imageEl.src = this.getImage('unknown.png');
},
},
});
-31
View File
@@ -1,31 +0,0 @@
/* eslint-disable no-console */
import { register } from 'register-service-worker'
// if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready () {
console.log('SW gotowy')
},
registered () {
console.log('SW: zarejestrowano')
},
cached () {
console.log('SW: cached')
},
updatefound () {
console.log('SW: nowa aktualizacja wykryta')
},
updated () {
console.log('SW: nowe dane, potrzebne odświeżenie strony!');
window.location.reload();
},
offline () {
console.log('SW: tryb offline')
},
error (error) {
console.error('SW: wystąpił błąd - ', error)
}
})
// }
+10 -7
View File
@@ -1,42 +1,45 @@
import JournalDispatchersVue from '@/components/JournalView/JournalDispatchers.vue';
import JournalTimetablesVue from '@/components/JournalView/JournalTimetables.vue';
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import JournalDispatchersVue from '../components/JournalView/JournalDispatchers.vue';
import JournalTimetablesVue from '../components/JournalView/JournalTimetables.vue';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'StationsView',
component: () => import('@/views/StationsView.vue'),
component: () => import('../views/StationsView.vue'),
},
{
path: '/trains',
name: 'TrainsView',
component: () => import('@/views/TrainsView.vue'),
component: () => import('../views/TrainsView.vue'),
props: (route) => ({ train: route.query.train, driver: route.query.driver }),
},
{
path: '/scenery',
name: 'SceneryView',
component: () => import('@/views/SceneryView.vue'),
component: () => import('../views/SceneryView.vue'),
props: true,
},
{
path: '/journal',
name: 'JournalView',
component: () => import('@/views/JournalView.vue'),
component: () => import('../views/JournalView.vue'),
children: [
{
path: '',
redirect: '/journal/timetables',
name: 'JournalTimetables',
component: JournalTimetablesVue,
alias: '/timetables',
},
{
path: 'dispatchers',
name: 'JournalDispatchers',
component: JournalDispatchersVue,
props: (route) => ({ sceneryName: route.query.sceneryName, dispatcherName: route.query.dispatcherName }),
},
{
path: 'timetables',
name: 'JournalTimetables',
component: JournalTimetablesVue,
props: (route) => ({
trainNo: route.query.trainNo,
+2 -2
View File
@@ -1,5 +1,5 @@
import Station from '@/scripts/interfaces/Station';
import Filter from '@/scripts/interfaces/Filter';
import Filter from '../interfaces/Filter';
import Station from '../interfaces/Station';
import StorageManager from './storageManager';
const sortStations = (a: Station, b: Station, sorter: { index: number; dir: number }) => {
+1 -1
View File
@@ -1,5 +1,5 @@
export const URLs = {
stacjownikAPI: process.env.VUE_APP_API_DEV != 1 ? 'https://stacjownik.eu-4.evennode.com' : 'http://localhost:3000',
stacjownikAPI: import.meta.env.VITE_APP_API_DEV ? 'https://stacjownik.eu-4.evennode.com' : 'http://localhost:3000',
stacjownikAPIDev: 'localhost:3000',
// trains: "https://api.td2.info.pl:9640/?method=getTrainsOnline",
// getTimetableURL: (trainNo: string | number, region = "eu") => `https://api.td2.info.pl:9640/?method=readFromSWDR&value=getTimetable%3B${trainNo}%3B${region}`
-6
View File
@@ -1,6 +0,0 @@
/* eslint-disable */
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
+25 -20
View File
@@ -1,20 +1,20 @@
import { DataStatus } from '@/scripts/enums/DataStatus';
import StationAPIData from '@/scripts/interfaces/api/StationAPIData';
import ScheduledTrain from '@/scripts/interfaces/ScheduledTrain';
import Station from '@/scripts/interfaces/Station';
import StationRoutes from '@/scripts/interfaces/StationRoutes';
import Train from '@/scripts/interfaces/Train';
import { URLs } from '@/scripts/utils/apiURLs';
import {
getLocoURL,
getScheduledTrain,
getStatusID,
getStatusTimestamp,
parseSpawns,
} from '@/scripts/utils/storeUtils';
import axios from 'axios';
import { defineStore } from 'pinia';
import { io } from 'socket.io-client';
import { DataStatus } from '../scripts/enums/DataStatus';
import StationAPIData from '../scripts/interfaces/api/StationAPIData';
import ScheduledTrain from '../scripts/interfaces/ScheduledTrain';
import Station from '../scripts/interfaces/Station';
import StationRoutes from '../scripts/interfaces/StationRoutes';
import Train from '../scripts/interfaces/Train';
import { URLs } from '../scripts/utils/apiURLs';
import {
getLocoURL,
getStatusTimestamp,
getStatusID,
getScheduledTrain,
parseSpawns,
} from '../scripts/utils/storeUtils';
import { APIData, StationJSONData, StoreState } from './storeTypes';
export const useStore = defineStore('store', {
@@ -58,7 +58,7 @@ export const useStore = defineStore('store', {
setTrainsOnlineData() {
const { trains } = this.apiData;
if (!trains) return [];
if (!trains) return [];
this.trainList = trains
.filter(
@@ -73,7 +73,7 @@ export const useStore = defineStore('store', {
return {
trainId: train.driverName + train.trainNo.toString(),
trainNo: train.trainNo,
mass: train.mass,
length: train.length,
@@ -204,7 +204,12 @@ export const useStore = defineStore('store', {
(train) =>
train?.region === this.region.id && train.online && train.currentStationName === stationAPIData.stationName
)
.map((train) => ({ driverName: train.driverName, driverId: train.driverId, trainNo: train.trainNo, trainId: train.trainId }));
.map((train) => ({
driverName: train.driverName,
driverId: train.driverId,
trainNo: train.trainNo,
trainId: train.trainId,
}));
},
setStationsOnlineInfo() {
@@ -338,7 +343,7 @@ export const useStore = defineStore('store', {
transports: ['websocket', 'polling'],
rememberUpgrade: true,
reconnection: true,
timeout: 10000
timeout: 10000,
});
socket.on('connect_error', (err) => {
@@ -381,13 +386,13 @@ export const useStore = defineStore('store', {
return;
}
this.dataStatuses.sceneries = DataStatus.Loaded;
this.dataStatuses.trains = !this.apiData.trains ? DataStatus.Warning : DataStatus.Loaded;
this.dataStatuses.dispatchers = !this.apiData.dispatchers ? DataStatus.Warning : DataStatus.Loaded;
this.setTrainsOnlineData();
this.setStationsOnlineInfo();
},
},
});
+8 -7
View File
@@ -1,11 +1,12 @@
import { DataStatus } from '@/scripts/enums/DataStatus';
import { DispatcherStatsAPIData } from '@/scripts/interfaces/api/DispatcherStatsAPIData';
import { DriverStatsAPIData } from '@/scripts/interfaces/api/DriverStatsAPIData';
import StationAPIData from '@/scripts/interfaces/api/StationAPIData';
import TrainAPIData from '@/scripts/interfaces/api/TrainAPIData';
import Station from '@/scripts/interfaces/Station';
import Train from '@/scripts/interfaces/Train';
import { Socket } from 'socket.io-client';
import { DataStatus } from '../scripts/enums/DataStatus';
import { DispatcherStatsAPIData } from '../scripts/interfaces/api/DispatcherStatsAPIData';
import { DriverStatsAPIData } from '../scripts/interfaces/api/DriverStatsAPIData';
import StationAPIData from '../scripts/interfaces/api/StationAPIData';
import TrainAPIData from '../scripts/interfaces/api/TrainAPIData';
import Station from '../scripts/interfaces/Station';
import Train from '../scripts/interfaces/Train';
export type Availability = 'default' | 'unavailable' | 'nonPublic' | 'abandoned' | 'nonDefault';
+5 -7
View File
@@ -1,21 +1,19 @@
<template>
<div class="error-view">
<div class="container">
<img :src="icons.error" alt="error" />
<img :src="getIcon('error')" alt="error" />
<div class="desc">Z powodu błędu w zapisywaniu rozkładów jazdy w tej zakładce można do odwołania nacieszyć się animacją sygnału S1a. Jak naprawię to będzie :)</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from '@vue/runtime-core';
import { defineComponent } from "vue";
import imageMixin from "../mixins/imageMixin";
export default defineComponent({
data: () => ({
icons: {
error: require('@/assets/icon-error.svg'),
},
}),
mixins: [imageMixin]
});
</script>
+3 -4
View File
@@ -21,13 +21,12 @@
</template>
<script lang="ts">
import JournalTimetables from '@/components/JournalView/JournalTimetables.vue';
import { defineComponent, ref } from 'vue';
import JournalDispatchers from '@/components/JournalView/JournalDispatchers.vue';
import JournalDispatchers from '../components/JournalView/JournalDispatchers.vue';
import JournalTimetables from '../components/JournalView/JournalTimetables.vue';
export default defineComponent({
components: { JournalTimetables, JournalDispatchers },
components: { JournalDispatchers, JournalTimetables },
setup() {
const journalTypeChosen = ref('journalTimetables');
+14 -36
View File
@@ -12,7 +12,7 @@
<div class="scenery-left">
<div class="scenery-actions">
<button v-if="!timetableOnly" class="back-btn btn" :title="$t('scenery.return-btn')" @click="navigateTo('/')">
<img :src="icons.back" alt="Back to scenery" />
<img :src="getImage('back')" alt="Back to scenery" />
</button>
</div>
@@ -41,19 +41,17 @@
</template>
<script lang="ts">
import SceneryInfo from '@/components/SceneryView/SceneryInfo.vue';
import SceneryTimetable from '@/components/SceneryView/SceneryTimetable.vue';
import SceneryTimetablesHistory from '../components/SceneryView/SceneryTimetablesHistory.vue';
import SceneryDispatchersHistory from '@/components/SceneryView/SceneryDispatchersHistory.vue';
import SceneryHeader from '@/components/SceneryView/SceneryHeader.vue';
import ActionButton from '@/components/Global/ActionButton.vue';
import { computed, defineComponent, ref } from '@vue/runtime-core';
import { computed, defineComponent } from 'vue';
import { useRoute } from 'vue-router';
import { useStore } from '@/store/store';
import routerMixin from '@/mixins/routerMixin';
import routerMixin from '../mixins/routerMixin';
import { useStore } from '../store/store';
import SceneryInfo from '../components/SceneryView/SceneryInfo.vue';
import SceneryHeader from '../components/SceneryView/SceneryHeader.vue';
import SceneryTimetable from '../components/SceneryView/SceneryTimetable.vue';
import SceneryTimetablesHistory from '../components/SceneryView/SceneryTimetablesHistory.vue';
import SceneryDispatchersHistory from '../components/SceneryView/SceneryDispatchersHistory.vue';
import ActionButton from '../components/Global/ActionButton.vue';
import imageMixin from '../mixins/imageMixin';
enum SceneryViewMode {
'TIMETABLES_ACTIVE',
@@ -70,15 +68,8 @@ export default defineComponent({
SceneryTimetablesHistory,
SceneryDispatchersHistory,
},
mixins: [routerMixin],
mixins: [routerMixin, imageMixin],
data: () => ({
icons: {
user: require('@/assets/icon-user.svg'),
back: require('@/assets/icon-back.svg'),
},
viewModes: [
{
id: 'scenery.option-active-timetables',
@@ -93,32 +84,22 @@ export default defineComponent({
component: 'SceneryDispatchersHistory',
},
],
sceneryViewMode: SceneryViewMode,
selectedCheckpoint: '',
currentViewCompontent: 'SceneryTimetable',
onlineFrom: -1,
}),
activated() {
this.loadSelectedCheckpoint();
},
setup() {
const route = useRoute();
const store = useStore();
const timetableOnly = computed(() => (route.query['timetable_only'] == '1' ? true : false));
const isComponentVisible = computed(() => route.path === '/scenery');
const stationInfo = computed(() => {
return store.stationList.find((station) => station.name === route.query.station?.toString().replace(/_/g, ' '));
});
return {
timetableOnly,
isComponentVisible,
@@ -126,19 +107,15 @@ export default defineComponent({
store,
};
},
methods: {
setViewMode(componentName: string) {
this.currentViewCompontent = componentName;
},
loadSelectedCheckpoint() {
if (!this.stationInfo?.generalInfo?.checkpoints) return;
if (this.stationInfo.generalInfo.checkpoints.length == 0) return;
this.selectedCheckpoint = this.stationInfo.generalInfo.checkpoints[0].checkpointName;
},
selectCheckpoint(cp: { checkpointName: string }) {
this.selectedCheckpoint = cp.checkpointName;
},
@@ -290,7 +267,8 @@ button.back-btn {
}
@include smallScreen {
.scenery-left, .scenery-right {
.scenery-left,
.scenery-right {
max-height: 100vh;
}
}
+10 -15
View File
@@ -3,7 +3,7 @@
<div class="wrapper">
<div class="body">
<div class="options-bar">
<FilterCard
<StationFilterCard
:showCard="filterCardOpen"
:exit="closeCard"
@changeFilterValue="changeFilterValue"
@@ -25,30 +25,25 @@
</template>
<script lang="ts">
import Station from '@/scripts/interfaces/Station';
import StorageManager from '@/scripts/managers/storageManager';
import StationFilterManager from '@/scripts/managers/stationFilterManager';
import inputData from '@/data/options.json';
import StationTable from '@/components/StationsView/StationTable.vue';
import FilterCard from '@/components/StationsView/StationFilterCard.vue';
import SelectBox from '@/components/Global/SelectBox.vue';
import inputData from '../data/options.json';
import { computed, ComputedRef, defineComponent, reactive } from 'vue';
import { useStore } from '@/store/store';
import { useStore } from '../store/store';
import StationFilterManager from '../scripts/managers/stationFilterManager';
import Station from '../scripts/interfaces/Station';
import StorageManager from '../scripts/managers/storageManager';
import StationTable from '../components/StationsView/StationTable.vue';
import StationFilterCard from '../components/StationsView/StationFilterCard.vue';
import SelectBox from '../components/Global/SelectBox.vue';
export default defineComponent({
components: {
StationTable,
FilterCard,
StationFilterCard,
SelectBox,
},
data: () => ({
trainIcon: require('@/assets/icon-train.svg'),
timetableIcon: require('@/assets/icon-timetable.svg'),
dolarIcon: require('@/assets/icon-dolar.svg'),
filterCardOpen: false,
modalHidden: true,
STORAGE_KEY: 'options_saved',
+8 -11
View File
@@ -11,16 +11,14 @@
</template>
<script lang="ts">
import { computed, ComputedRef, defineComponent, PropType, provide, reactive, ref, TrainFilter } from 'vue';
import { filteredTrainList } from '@/scripts/managers/trainFilterManager';
import { trainFilters } from '@/data/trainOptions';
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/store';
import { computed, ComputedRef, defineComponent, provide, reactive, ref, TrainFilter } from 'vue';
import TrainOptions from '../components/TrainsView/TrainOptions.vue';
import TrainStats from '../components/TrainsView/TrainStats.vue';
import TrainTable from '../components/TrainsView/TrainTable.vue';
import { trainFilters } from '../data/trainOptions';
import Train from '../scripts/interfaces/Train';
import { filteredTrainList } from '../scripts/managers/trainFilterManager';
import { useStore } from '../store/store';
export default defineComponent({
components: {
@@ -42,7 +40,6 @@ export default defineComponent({
},
data: () => ({
statsIcon: require('@/assets/icon-stats.svg'),
trainStatsOpen: false,
}),
+19
View File
@@ -0,0 +1,19 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
interface ImportMetaEnv {
readonly VITE_APP_API_DEV: number;
readonly VITE_APP_WS_DEV: number;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}