mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 13:28:11 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b01d3e894b | |||
| 13dc6a0e32 | |||
| 96714550d0 | |||
| 2b6c751f55 | |||
| 08d3a2a03a | |||
| a79ca78781 | |||
| e08333dba1 | |||
| 8705dd1df5 | |||
| 7b4da9d422 | |||
| e51b2fe2f3 | |||
| f8b4ce103f | |||
| e82b4b8817 | |||
| 36e9df82b0 | |||
| cbce9af00b |
+25
-11
@@ -1,11 +1,14 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="pl">
|
<html lang="pl">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||||
|
|
||||||
<meta name="keywords" content="Stacjownik, TD2, Train Driver 2, stacjownik-td2, stacjownik, td2.info.pl" />
|
<meta
|
||||||
|
name="keywords"
|
||||||
|
content="Stacjownik, TD2, Train Driver 2, stacjownik-td2, stacjownik, td2.info.pl"
|
||||||
|
/>
|
||||||
<meta name="description" content="Pomocnik maszynisty i dyżurnego symulatora Train Driver 2" />
|
<meta name="description" content="Pomocnik maszynisty i dyżurnego symulatora Train Driver 2" />
|
||||||
|
|
||||||
<title>Stacjownik</title>
|
<title>Stacjownik</title>
|
||||||
@@ -18,10 +21,6 @@
|
|||||||
<meta name="msapplication-TileColor" content="#da532c" />
|
<meta name="msapplication-TileColor" content="#da532c" />
|
||||||
<meta name="theme-color" content="#222222" />
|
<meta name="theme-color" content="#222222" />
|
||||||
|
|
||||||
<link rel="icon" href="favicon-64.png" sizes="64x64" type="image/png" />
|
|
||||||
<link rel="icon" href="favicon-62.png" sizes="62x62" type="image/png" />
|
|
||||||
<link rel="icon" href="favicon-32.png" sizes="32x32" type="image/png" />
|
|
||||||
<link rel="icon" href="favicon-16.png" sizes="16x16" type="image/png" />
|
|
||||||
<link rel="icon" href="favicon.ico" />
|
<link rel="icon" href="favicon.ico" />
|
||||||
|
|
||||||
<!-- Static OpenGraph meta -->
|
<!-- Static OpenGraph meta -->
|
||||||
@@ -29,18 +28,33 @@
|
|||||||
<meta property="og:url" content="https://stacjownik-td2.web.app/" />
|
<meta property="og:url" content="https://stacjownik-td2.web.app/" />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:title" content="Stacjownik" />
|
<meta property="og:title" content="Stacjownik" />
|
||||||
<meta property="og:description" content="Pomocnik maszynisty i dyżurnego symulatora Train Driver 2" />
|
<meta
|
||||||
<meta property="og:image" content="https://raw.githubusercontent.com/Spythere/api/main/thumbnails/stacjownik.jpg" />
|
property="og:description"
|
||||||
|
content="Pomocnik maszynisty i dyżurnego symulatora Train Driver 2"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:image"
|
||||||
|
content="https://raw.githubusercontent.com/Spythere/api/main/thumbnails/stacjownik.jpg"
|
||||||
|
/>
|
||||||
<meta property="og:image:width" content="1200" />
|
<meta property="og:image:width" content="1200" />
|
||||||
<meta property="og:image:height" content="630" />
|
<meta property="og:image:height" content="630" />
|
||||||
<meta property="og:site_name" content="Stacjownik" />
|
<meta property="og:site_name" content="Stacjownik" />
|
||||||
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta name="twitter:title" content="Stacjownik" />
|
<meta name="twitter:title" content="Stacjownik" />
|
||||||
<meta name="twitter:description" content="Pomocnik maszynisty i dyżurnego symulatora Train Driver 2" />
|
<meta
|
||||||
<meta name="twitter:image" content="https://raw.githubusercontent.com/Spythere/api/main/thumbnails/stacjownik.jpg" />
|
name="twitter:description"
|
||||||
|
content="Pomocnik maszynisty i dyżurnego symulatora Train Driver 2"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
name="twitter:image"
|
||||||
|
content="https://raw.githubusercontent.com/Spythere/api/main/thumbnails/stacjownik.jpg"
|
||||||
|
/>
|
||||||
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Quicksand:wght@500;700&display=swap" rel="stylesheet" />
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Quicksand:wght@500;700&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "stacjownik",
|
"name": "stacjownik",
|
||||||
"version": "1.18.2",
|
"version": "1.18.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
+8
-15
@@ -56,24 +56,17 @@
|
|||||||
|
|
||||||
// CONTAINER
|
// CONTAINER
|
||||||
.app_container {
|
.app_container {
|
||||||
display: flex;
|
// display: flex;
|
||||||
flex-flow: column;
|
// flex-flow: column;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto 1fr auto;
|
||||||
|
grid-template-columns: 100%;
|
||||||
|
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
header {
|
.app_main {
|
||||||
flex: 0 0 auto;
|
padding: 0 0.5em;
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
|
|
||||||
padding: 0 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
flex: 0 1 0.2em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.warning {
|
.warning {
|
||||||
|
|||||||
+6
-9
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<main class="app_main">
|
<main class="app_main">
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<keep-alive exclude="JournalView">
|
<keep-alive exclude="JournalView,SceneryView">
|
||||||
<component :is="Component" :key="$route.name" />
|
<component :is="Component" :key="$route.name" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</router-view>
|
</router-view>
|
||||||
@@ -39,12 +39,12 @@ import Clock from './components/App/Clock.vue';
|
|||||||
import packageInfo from '.././package.json';
|
import packageInfo from '.././package.json';
|
||||||
import { regions } from './data/options.json';
|
import { regions } from './data/options.json';
|
||||||
|
|
||||||
import { useStore } from './store/store';
|
import { useStore } from './store/mainStore';
|
||||||
import StatusIndicator from './components/App/StatusIndicator.vue';
|
import StatusIndicator from './components/App/StatusIndicator.vue';
|
||||||
import TrainModal from './components/Global/TrainModal.vue';
|
import TrainModal from './components/Global/TrainModal.vue';
|
||||||
import StorageManager from './scripts/managers/storageManager';
|
|
||||||
import AppHeader from './components/App/AppHeader.vue';
|
import AppHeader from './components/App/AppHeader.vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import StorageManager from './managers/storageManager';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@@ -72,12 +72,9 @@ export default defineComponent({
|
|||||||
window.addEventListener('offline', () => {
|
window.addEventListener('offline', () => {
|
||||||
this.store.isOffline = true;
|
this.store.isOffline = true;
|
||||||
|
|
||||||
this.store.apiData = {
|
this.store.activeData.activeSceneries = [];
|
||||||
stations: [],
|
this.store.activeData.trains = [];
|
||||||
dispatchers: [],
|
this.store.activeData.connectedSocketCount = 0;
|
||||||
trains: [],
|
|
||||||
connectedSocketCount: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
this.store.setStatuses();
|
this.store.setStatuses();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
import StatusIndicator from './StatusIndicator.vue';
|
import StatusIndicator from './StatusIndicator.vue';
|
||||||
import Clock from './Clock.vue';
|
import Clock from './Clock.vue';
|
||||||
import RegionDropdown from '../Global/RegionDropdown.vue';
|
import RegionDropdown from '../Global/RegionDropdown.vue';
|
||||||
@@ -96,11 +96,13 @@ export default defineComponent({
|
|||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
onlineTrainsCount() {
|
onlineTrainsCount() {
|
||||||
return this.store.trainList.filter((train) => train.online).length;
|
return this.store.trainList.filter((train) => train.region == this.store.region.id).length;
|
||||||
},
|
},
|
||||||
|
|
||||||
onlineDispatchersCount() {
|
onlineDispatchersCount() {
|
||||||
return this.store.onlineSceneryList.length;
|
return this.store.onlineSceneryList.filter(
|
||||||
|
(scenery) => scenery.region == this.store.region.id
|
||||||
|
).length;
|
||||||
},
|
},
|
||||||
|
|
||||||
factorU() {
|
factorU() {
|
||||||
|
|||||||
@@ -194,9 +194,9 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { DataStatus } from '../../scripts/enums/DataStatus';
|
import { StoreState } from '../../store/typings';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
import { StoreState } from '../../scripts/interfaces/store/storeTypes';
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
@@ -204,7 +204,7 @@ export default defineComponent({
|
|||||||
tooltipActive: false,
|
tooltipActive: false,
|
||||||
indicator: {
|
indicator: {
|
||||||
offline: false,
|
offline: false,
|
||||||
status: DataStatus.Loading,
|
status: Status.Data.Loading,
|
||||||
message: 'data-status.S3'
|
message: 'data-status.S3'
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.setSignalStatus(DataStatus.Loading);
|
this.setSignalStatus(Status.Data.Loading);
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
@@ -240,44 +240,44 @@ export default defineComponent({
|
|||||||
const dispatcherDataStatus = statuses.dispatchers;
|
const dispatcherDataStatus = statuses.dispatchers;
|
||||||
|
|
||||||
if (this.store.isOffline) {
|
if (this.store.isOffline) {
|
||||||
this.setSignalStatus(DataStatus.Initialized);
|
this.setSignalStatus(Status.Data.Initialized);
|
||||||
this.indicator.status = DataStatus.Initialized;
|
this.indicator.status = Status.Data.Initialized;
|
||||||
this.indicator.message = 'data-status.S1-offline';
|
this.indicator.message = 'data-status.S1-offline';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connectionStatus == DataStatus.Error) {
|
if (connectionStatus == Status.Data.Error) {
|
||||||
this.setSignalStatus(connectionStatus);
|
this.setSignalStatus(connectionStatus);
|
||||||
this.indicator.status = connectionStatus;
|
this.indicator.status = connectionStatus;
|
||||||
this.indicator.message = 'data-status.S1a-connection';
|
this.indicator.message = 'data-status.S1a-connection';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sceneryDataStatus == DataStatus.Error) {
|
if (sceneryDataStatus == Status.Data.Error) {
|
||||||
this.setSignalStatus(sceneryDataStatus);
|
this.setSignalStatus(sceneryDataStatus);
|
||||||
this.indicator.status = sceneryDataStatus;
|
this.indicator.status = sceneryDataStatus;
|
||||||
this.indicator.message = 'data-status.S1a-sceneries';
|
this.indicator.message = 'data-status.S1a-sceneries';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trainsDataStatus == DataStatus.Warning) {
|
if (trainsDataStatus == Status.Data.Warning) {
|
||||||
this.setSignalStatus(trainsDataStatus);
|
this.setSignalStatus(trainsDataStatus);
|
||||||
this.indicator.status = trainsDataStatus;
|
this.indicator.status = trainsDataStatus;
|
||||||
this.indicator.message = 'data-status.S5-trains';
|
this.indicator.message = 'data-status.S5-trains';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dispatcherDataStatus == DataStatus.Warning) {
|
if (dispatcherDataStatus == Status.Data.Warning) {
|
||||||
this.setSignalStatus(dispatcherDataStatus);
|
this.setSignalStatus(dispatcherDataStatus);
|
||||||
this.indicator.status = dispatcherDataStatus;
|
this.indicator.status = dispatcherDataStatus;
|
||||||
this.indicator.message = 'data-status.S5-dispatchers';
|
this.indicator.message = 'data-status.S5-dispatchers';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sceneryDataStatus == DataStatus.Loaded) {
|
if (sceneryDataStatus == Status.Data.Loaded) {
|
||||||
this.setSignalStatus(DataStatus.Loaded);
|
this.setSignalStatus(Status.Data.Loaded);
|
||||||
|
|
||||||
this.indicator.status = DataStatus.Loaded;
|
this.indicator.status = Status.Data.Loaded;
|
||||||
this.indicator.message = 'data-status.S2';
|
this.indicator.message = 'data-status.S2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -285,31 +285,31 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
setSignalStatus(status: DataStatus) {
|
setSignalStatus(status: Status.Data) {
|
||||||
this.greenLight = false;
|
this.greenLight = false;
|
||||||
this.greenBlinkLight = false;
|
this.greenBlinkLight = false;
|
||||||
this.redTopLight = false;
|
this.redTopLight = false;
|
||||||
this.orangeLight = false;
|
this.orangeLight = false;
|
||||||
this.redBottomLight = false;
|
this.redBottomLight = false;
|
||||||
|
|
||||||
if (status == DataStatus.Initialized) {
|
if (status == Status.Data.Initialized) {
|
||||||
this.redTopLight = true;
|
this.redTopLight = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == DataStatus.Loaded) {
|
if (status == Status.Data.Loaded) {
|
||||||
this.greenLight = true;
|
this.greenLight = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == DataStatus.Warning) {
|
if (status == Status.Data.Warning) {
|
||||||
this.orangeLight = true;
|
this.orangeLight = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == DataStatus.Error) {
|
if (status == Status.Data.Error) {
|
||||||
this.redTopLight = true;
|
this.redTopLight = true;
|
||||||
this.redBottomLight = true;
|
this.redBottomLight = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == DataStatus.Loading) {
|
if (status == Status.Data.Loading) {
|
||||||
this.greenBlinkLight = true;
|
this.greenBlinkLight = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, Ref, ref } from 'vue';
|
import { defineComponent, Ref, ref } from 'vue';
|
||||||
import { useStore } from '../../store/store';
|
|
||||||
import { regions as regionsJSON } from '../../data/options.json';
|
import { regions as regionsJSON } from '../../data/options.json';
|
||||||
|
import { useStore } from '../../store/mainStore';
|
||||||
|
|
||||||
interface Item {
|
interface Item {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -67,16 +67,15 @@ export default defineComponent({
|
|||||||
selectedItem() {
|
selectedItem() {
|
||||||
return this.regionList[this.selectedItemIndex] || null;
|
return this.regionList[this.selectedItemIndex] || null;
|
||||||
},
|
},
|
||||||
|
|
||||||
regionList() {
|
regionList() {
|
||||||
return regionsJSON.map((region) => {
|
return regionsJSON.map((region) => {
|
||||||
const regionStationCount =
|
const regionStationCount = this.store.onlineSceneryList.filter(
|
||||||
this.store.apiData.stations?.filter(
|
(scenery) => scenery.region == region.id
|
||||||
(station) => station.region == region.id && station.isOnline
|
).length;
|
||||||
).length || 0;
|
|
||||||
|
|
||||||
const regionTrainCount =
|
const regionTrainCount =
|
||||||
this.store.apiData.trains?.filter((train) => train.region == region.id && train.online)
|
this.store.trainList.filter((train) => train.region == region.id).length || 0;
|
||||||
.length || 0;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: region.id,
|
id: region.id,
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="status-badge" :class="statusID" v-if="isOnline">
|
<span class="status-badge" :class="statusName" v-if="isOnline">
|
||||||
{{ $t(`status.${statusID}`) }}
|
{{ $t(`status.${statusName}`) }}
|
||||||
{{ statusID == 'online' ? timestampToString(statusTimestamp!) : '' }}
|
{{
|
||||||
|
statusName == 'online' && dispatcherStatus && dispatcherStatus > 5
|
||||||
|
? timestampToString(dispatcherStatus)
|
||||||
|
: ''
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="status-badge free" v-else>
|
<span class="status-badge free" v-else>
|
||||||
@@ -10,22 +14,56 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
statusID: {
|
dispatcherStatus: {
|
||||||
type: String
|
type: Number as PropType<Status.ActiveDispatcher | number>
|
||||||
},
|
|
||||||
statusTimestamp: {
|
|
||||||
type: Number
|
|
||||||
},
|
},
|
||||||
isOnline: {
|
isOnline: {
|
||||||
type: Boolean
|
type: Boolean
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixins: [dateMixin]
|
mixins: [dateMixin],
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
statusName() {
|
||||||
|
if (this.dispatcherStatus === undefined) return 'free';
|
||||||
|
|
||||||
|
switch (this.dispatcherStatus) {
|
||||||
|
case Status.ActiveDispatcher.AFK:
|
||||||
|
return 'afk';
|
||||||
|
|
||||||
|
case Status.ActiveDispatcher.NO_LIMIT:
|
||||||
|
return 'no-limit';
|
||||||
|
|
||||||
|
case Status.ActiveDispatcher.ENDING:
|
||||||
|
return 'ending';
|
||||||
|
|
||||||
|
case Status.ActiveDispatcher.INVALID:
|
||||||
|
return 'invalid';
|
||||||
|
|
||||||
|
case Status.ActiveDispatcher.NOT_LOGGED_IN:
|
||||||
|
return 'not-signed';
|
||||||
|
|
||||||
|
case Status.ActiveDispatcher.NO_SPACE:
|
||||||
|
return 'no-space';
|
||||||
|
|
||||||
|
case Status.ActiveDispatcher.UNAVAILABLE:
|
||||||
|
return 'unavailable';
|
||||||
|
|
||||||
|
case Status.ActiveDispatcher.UNKNOWN:
|
||||||
|
return 'unknown';
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (this.dispatcherStatus >= Date.now() + 25500000) return 'no-limit';
|
||||||
|
return 'online';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -34,10 +72,10 @@ $free: #8a8a8a;
|
|||||||
$ending: #e6c300;
|
$ending: #e6c300;
|
||||||
$no-limit: #117fc9;
|
$no-limit: #117fc9;
|
||||||
$unav: #ff3d5d;
|
$unav: #ff3d5d;
|
||||||
$brb: #e6a100;
|
$afk: #e6a100;
|
||||||
$no-space: #222;
|
$no-space: #222;
|
||||||
$online: #09a116;
|
$online: #09a116;
|
||||||
$unknown: rgb(185, 60, 60);
|
$unknown: #b93c3c;
|
||||||
|
|
||||||
.status-badge {
|
.status-badge {
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
@@ -69,8 +107,8 @@ $unknown: rgb(185, 60, 60);
|
|||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.brb {
|
&.afk {
|
||||||
background-color: $brb;
|
background-color: $afk;
|
||||||
color: black;
|
color: black;
|
||||||
font-size: 0.95em;
|
font-size: 0.95em;
|
||||||
}
|
}
|
||||||
@@ -82,7 +120,8 @@ $unknown: rgb(185, 60, 60);
|
|||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.unknown {
|
&.unknown,
|
||||||
|
&.invalid {
|
||||||
background-color: $unknown;
|
background-color: $unknown;
|
||||||
font-size: 0.95em;
|
font-size: 0.95em;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,8 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
import { RollingStockInfo } from '../../scripts/interfaces/github_api/StockInfoGithubData';
|
import { API } from '../../typings/api';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -71,7 +71,7 @@ export default defineComponent({
|
|||||||
onImageError(event: Event, stockName: string) {
|
onImageError(event: Event, stockName: string) {
|
||||||
const fallbackName =
|
const fallbackName =
|
||||||
Object.keys(this.store.rollingStockData!.info).find((type) => {
|
Object.keys(this.store.rollingStockData!.info).find((type) => {
|
||||||
return this.store.rollingStockData!.info[type as keyof RollingStockInfo].find(
|
return this.store.rollingStockData!.info[type as keyof API.RollingStock.Info].find(
|
||||||
(v) => v[0] === stockName.split(':')[0]
|
(v) => v[0] === stockName.split(':')[0]
|
||||||
);
|
);
|
||||||
}) || 'vehicle-unknown';
|
}) || 'vehicle-unknown';
|
||||||
|
|||||||
@@ -51,16 +51,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import TrainStop from '../../scripts/interfaces/TrainStop';
|
import { TrainStop } from '../../store/typings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [dateMixin],
|
mixins: [dateMixin],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
stop: {
|
stop: {
|
||||||
type: Object as () => TrainStop,
|
type: Object as PropType<TrainStop>,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
||||||
import trainInfoMixin from '../../mixins/trainInfoMixin';
|
import trainInfoMixin from '../../mixins/trainInfoMixin';
|
||||||
import { useStore } from '../../store/store';
|
|
||||||
import TrainInfo from '../TrainsView/TrainInfo.vue';
|
import TrainInfo from '../TrainsView/TrainInfo.vue';
|
||||||
import TrainSchedule from '../TrainsView/TrainSchedule.vue';
|
import TrainSchedule from '../TrainsView/TrainSchedule.vue';
|
||||||
|
|
||||||
@@ -30,14 +29,6 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
|
||||||
const store = useStore();
|
|
||||||
|
|
||||||
return {
|
|
||||||
store
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
activated() {
|
activated() {
|
||||||
const contentEl = this.$refs['content'] as HTMLElement;
|
const contentEl = this.$refs['content'] as HTMLElement;
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
import { RollingStockInfo } from '../../scripts/interfaces/github_api/StockInfoGithubData';
|
import { API } from '../../typings/api';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -54,7 +54,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
Object.keys(this.store.rollingStockData.info).find((type) => {
|
Object.keys(this.store.rollingStockData.info).find((type) => {
|
||||||
return this.store.rollingStockData?.info[type as keyof RollingStockInfo].find(
|
return this.store.rollingStockData?.info[type as keyof API.RollingStock.Info].find(
|
||||||
(v) => v[0] === this.name.split(':')[0]
|
(v) => v[0] === this.name.split(':')[0]
|
||||||
);
|
);
|
||||||
}) || 'vehicle-unknown'
|
}) || 'vehicle-unknown'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="daily-stats">
|
<section class="daily-stats">
|
||||||
<span :data-active="statsStatus">
|
<span :data-active="statsStatus">
|
||||||
<b v-if="statsStatus == DataStatus.Loading">
|
<b v-if="statsStatus == Status.Data.Loading">
|
||||||
{{ $t('app.loading') }}
|
{{ $t('app.loading') }}
|
||||||
</b>
|
</b>
|
||||||
|
|
||||||
@@ -32,24 +32,26 @@
|
|||||||
</i18n-t>
|
</i18n-t>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="stats.timetableId">
|
<div v-if="stats.maxTimetable">
|
||||||
•
|
•
|
||||||
<i18n-t keypath="journal.timetable-stats-longest">
|
<i18n-t keypath="journal.timetable-stats-longest">
|
||||||
<template #id>
|
<template #id>
|
||||||
<router-link :to="`/journal/timetables?timetableId=${stats.timetableId}`">
|
<router-link :to="`/journal/timetables?timetableId=${stats.maxTimetable.id}`">
|
||||||
<b>{{ stats.timetableId }}</b>
|
<b>{{ stats.maxTimetable.id }}</b>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
<template #author>
|
<template #author>
|
||||||
<router-link :to="`/journal/dispatchers?dispatcherName=${stats.timetableAuthor}`">
|
<router-link
|
||||||
<b>{{ stats.timetableAuthor }}</b>
|
:to="`/journal/dispatchers?dispatcherName=${stats.maxTimetable.authorName}`"
|
||||||
|
>
|
||||||
|
<b>{{ stats.maxTimetable.authorName }}</b>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
<template #driver>
|
<template #driver>
|
||||||
<b class="text--primary">{{ stats.timetableDriver }}</b>
|
<b class="text--primary">{{ stats.maxTimetable.driverName }}</b>
|
||||||
</template>
|
</template>
|
||||||
<template #distance>
|
<template #distance>
|
||||||
<b class="text--primary">{{ stats.timetableRouteDistance }} km</b>
|
<b class="text--primary">{{ stats.maxTimetable.routeDistance }} km</b>
|
||||||
</template>
|
</template>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
</div>
|
</div>
|
||||||
@@ -134,12 +136,10 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import { DataStatus } from '../../scripts/enums/DataStatus';
|
|
||||||
import {
|
|
||||||
ITimetablesDailyStats,
|
|
||||||
ITimetablesDailyStatsResponse
|
|
||||||
} from '../../scripts/interfaces/api/StatsAPIData';
|
|
||||||
import { URLs } from '../../scripts/utils/apiURLs';
|
import { URLs } from '../../scripts/utils/apiURLs';
|
||||||
|
import { API } from '../../typings/api';
|
||||||
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [dateMixin],
|
mixins: [dateMixin],
|
||||||
@@ -147,22 +147,11 @@ export default defineComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
DataStatus,
|
Status,
|
||||||
statsStatus: DataStatus.Loading,
|
statsStatus: Status.Data.Loading,
|
||||||
intervalId: -1,
|
intervalId: -1,
|
||||||
|
|
||||||
stats: {
|
stats: {} as API.DailyStats.Response
|
||||||
totalTimetables: 0,
|
|
||||||
distanceSum: 0,
|
|
||||||
distanceAvg: 0,
|
|
||||||
timetableAuthor: '',
|
|
||||||
timetableDriver: '',
|
|
||||||
timetableId: 0,
|
|
||||||
timetableRouteDistance: 0,
|
|
||||||
longestDuties: [],
|
|
||||||
mostActiveDrivers: [],
|
|
||||||
mostActiveDispatchers: []
|
|
||||||
} as ITimetablesDailyStats
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -187,28 +176,30 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
async fetchDailyTimetableStats() {
|
async fetchDailyTimetableStats() {
|
||||||
try {
|
try {
|
||||||
const res: ITimetablesDailyStatsResponse = await (
|
const res: API.DailyStats.Response = await (
|
||||||
await axios.get(`${URLs.stacjownikAPI}/api/getDailyTimetableStats`)
|
await axios.get(`${URLs.stacjownikAPI}/api/getDailyTimetableStats`)
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
this.stats = {
|
// this.stats = {
|
||||||
totalTimetables: res.totalTimetables,
|
// totalTimetables: res.totalTimetables,
|
||||||
distanceSum: res.distanceSum,
|
// distanceSum: res.distanceSum,
|
||||||
distanceAvg: res.distanceAvg,
|
// distanceAvg: res.distanceAvg,
|
||||||
timetableAuthor: res.maxTimetable?.authorName || '',
|
// // timetableAuthor: res.maxTimetable?.authorName || '',
|
||||||
timetableDriver: res.maxTimetable?.driverName || '',
|
// // timetableDriver: res.maxTimetable?.driverName || '',
|
||||||
timetableId: res.maxTimetable?.id || 0,
|
// // timetableId: res.maxTimetable?.id || 0,
|
||||||
timetableRouteDistance: res.maxTimetable?.routeDistance || 0,
|
// // timetableRouteDistance: res.maxTimetable?.routeDistance || 0,
|
||||||
|
|
||||||
mostActiveDispatchers: res.mostActiveDispatchers,
|
// mostActiveDispatchers: res.mostActiveDispatchers,
|
||||||
mostActiveDrivers: res.mostActiveDrivers,
|
// mostActiveDrivers: res.mostActiveDrivers,
|
||||||
longestDuties: res.longestDuties
|
// longestDuties: res.longestDuties
|
||||||
};
|
// };
|
||||||
|
|
||||||
this.statsStatus = DataStatus.Loaded;
|
this.stats = res;
|
||||||
|
|
||||||
|
this.statsStatus = Status.Data.Loaded;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ups! Wystąpił błąd podczas pobierania statystyk rozkładów jazdy...');
|
console.error('Ups! Wystąpił błąd podczas pobierania statystyk rozkładów jazdy...');
|
||||||
this.statsStatus = DataStatus.Error;
|
this.statsStatus = Status.Data.Error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -52,11 +52,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { DispatcherStatsAPIData } from '../../scripts/interfaces/api/DispatcherStatsAPIData';
|
|
||||||
import { TimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
|
|
||||||
import { URLs } from '../../scripts/utils/apiURLs';
|
import { URLs } from '../../scripts/utils/apiURLs';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
|
import { API } from '../../typings/api';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { Loading },
|
components: { Loading },
|
||||||
@@ -73,7 +72,7 @@ export default defineComponent({
|
|||||||
return {
|
return {
|
||||||
cardVisible: false,
|
cardVisible: false,
|
||||||
lastDispatcherName: '',
|
lastDispatcherName: '',
|
||||||
timetables: [] as TimetableHistory[]
|
timetables: [] as API.TimetableHistory.Response
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -90,13 +89,13 @@ export default defineComponent({
|
|||||||
this.store.dispatcherStatsData = undefined;
|
this.store.dispatcherStatsData = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const statsData: DispatcherStatsAPIData = await (
|
const statsData: API.DispatcherStats.Response = await (
|
||||||
await axios.get(
|
await axios.get(
|
||||||
`${URLs.stacjownikAPI}/api/getDispatcherInfo?name=${this.store.dispatcherStatsName}`
|
`${URLs.stacjownikAPI}/api/getDispatcherInfo?name=${this.store.dispatcherStatsName}`
|
||||||
)
|
)
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
const timetables: TimetableHistory[] = await (
|
const timetables: API.TimetableHistory.Response = await (
|
||||||
await axios.get(
|
await axios.get(
|
||||||
`${URLs.stacjownikAPI}/api/getTimetables?authorName=${this.store.dispatcherStatsName}`
|
`${URLs.stacjownikAPI}/api/getTimetables?authorName=${this.store.dispatcherStatsName}`
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
{{ $t('app.offline') }}
|
{{ $t('app.offline') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Loading v-else-if="dataStatus == DataStatus.Loading" />
|
<Loading v-else-if="dataStatus == Status.Data.Loading" />
|
||||||
|
|
||||||
<div v-else-if="dataStatus == DataStatus.Error" class="journal_warning error">
|
<div v-else-if="dataStatus == Status.Data.Error" class="journal_warning error">
|
||||||
{{ $t('app.error') }}
|
{{ $t('app.error') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -114,13 +114,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import { DispatcherHistory } from '../../scripts/interfaces/api/DispatchersAPIData';
|
|
||||||
import styleMixin from '../../mixins/styleMixin';
|
import styleMixin from '../../mixins/styleMixin';
|
||||||
import { DataStatus } from '../../scripts/enums/DataStatus';
|
import { useStore } from '../../store/mainStore';
|
||||||
import { useStore } from '../../store/store';
|
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
import { regions } from '../../data/options.json';
|
import { regions } from '../../data/options.json';
|
||||||
import AddDataButton from '../Global/AddDataButton.vue';
|
import AddDataButton from '../Global/AddDataButton.vue';
|
||||||
|
import { API } from '../../typings/api';
|
||||||
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { Loading, AddDataButton },
|
components: { Loading, AddDataButton },
|
||||||
@@ -129,7 +129,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
props: {
|
props: {
|
||||||
dispatcherHistory: {
|
dispatcherHistory: {
|
||||||
type: Array as PropType<DispatcherHistory[]>,
|
type: Array as PropType<API.DispatcherHistory.Response>,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
scrollNoMoreData: {
|
scrollNoMoreData: {
|
||||||
@@ -142,13 +142,13 @@ export default defineComponent({
|
|||||||
type: Function as PropType<() => void>
|
type: Function as PropType<() => void>
|
||||||
},
|
},
|
||||||
dataStatus: {
|
dataStatus: {
|
||||||
type: Number as PropType<DataStatus>
|
type: Number as PropType<Status.Data>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
DataStatus,
|
Status,
|
||||||
store: useStore(),
|
store: useStore(),
|
||||||
regions
|
regions
|
||||||
};
|
};
|
||||||
@@ -166,7 +166,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
[] as (DispatcherHistory | string)[]
|
[] as (API.DispatcherHistory.Data | string)[]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -43,10 +43,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<b v-else-if="store.driverStatsStatus == DataStatus.Loading">{{
|
<b v-else-if="store.driverStatsStatus == Status.Data.Loading">{{
|
||||||
$t('journal.stats-loading')
|
$t('journal.stats-loading')
|
||||||
}}</b>
|
}}</b>
|
||||||
<b v-else-if="store.driverStatsStatus == DataStatus.Error">
|
<b v-else-if="store.driverStatsStatus == Status.Data.Error">
|
||||||
{{ $t('journal.stats-error ') }}
|
{{ $t('journal.stats-error ') }}
|
||||||
</b>
|
</b>
|
||||||
<b v-else>{{ $t('journal.driver-stats-info') }}</b>
|
<b v-else>{{ $t('journal.driver-stats-info') }}</b>
|
||||||
@@ -55,14 +55,14 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { DataStatus } from '../../scripts/enums/DataStatus';
|
import { useStore } from '../../store/mainStore';
|
||||||
import { useStore } from '../../store/store';
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
store: useStore(),
|
||||||
DataStatus
|
Status: Status
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -113,12 +113,11 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { defineComponent, inject, PropType } from 'vue';
|
import { defineComponent, inject, PropType } from 'vue';
|
||||||
import keyMixin from '../../mixins/keyMixin';
|
import keyMixin from '../../mixins/keyMixin';
|
||||||
import { DataStatus } from '../../scripts/enums/DataStatus';
|
|
||||||
import { DriverStatsAPIData } from '../../scripts/interfaces/api/DriverStatsAPIData';
|
|
||||||
import { URLs } from '../../scripts/utils/apiURLs';
|
import { URLs } from '../../scripts/utils/apiURLs';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
import { JournalFilterSection } from '../../scripts/enums/JournalFilterType';
|
import { Journal } from './typings';
|
||||||
import { JournalFilter } from '../../scripts/types/JournalTimetablesTypes';
|
import { API } from '../../typings/api';
|
||||||
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
emits: ['onSearchConfirm', 'onOptionsReset', 'onRefreshData'],
|
emits: ['onSearchConfirm', 'onOptionsReset', 'onRefreshData'],
|
||||||
@@ -131,13 +130,13 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
filters: {
|
filters: {
|
||||||
type: Array as PropType<JournalFilter[]>,
|
type: Array as PropType<Journal.TimetableFilter[]>,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
|
|
||||||
dataStatus: {
|
dataStatus: {
|
||||||
type: Number as PropType<DataStatus>,
|
type: Number as PropType<Status.Data>,
|
||||||
default: DataStatus.Initialized
|
default: -1
|
||||||
},
|
},
|
||||||
|
|
||||||
currentOptionsActive: {
|
currentOptionsActive: {
|
||||||
@@ -154,7 +153,6 @@ export default defineComponent({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showOptions: false,
|
showOptions: false,
|
||||||
JournalFilterSection,
|
|
||||||
|
|
||||||
driverSuggestions: [] as string[],
|
driverSuggestions: [] as string[],
|
||||||
dispatcherSuggestions: [] as string[],
|
dispatcherSuggestions: [] as string[],
|
||||||
@@ -162,7 +160,7 @@ export default defineComponent({
|
|||||||
searchTimeout: 0,
|
searchTimeout: 0,
|
||||||
store: useStore(),
|
store: useStore(),
|
||||||
|
|
||||||
DataStatus
|
JournalFilterSection: Journal.FilterSection
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -170,7 +168,7 @@ export default defineComponent({
|
|||||||
return {
|
return {
|
||||||
searchersValues: inject('searchersValues') as { [key: string]: string },
|
searchersValues: inject('searchersValues') as { [key: string]: string },
|
||||||
sorterActive: inject('sorterActive') as { id: string | number; dir: number },
|
sorterActive: inject('sorterActive') as { id: string | number; dir: number },
|
||||||
filterList: inject('filterList') as JournalFilter[] | undefined
|
filterList: inject('filterList') as Journal.TimetableFilter[] | undefined
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -212,23 +210,23 @@ export default defineComponent({
|
|||||||
this.store.driverStatsData = undefined;
|
this.store.driverStatsData = undefined;
|
||||||
|
|
||||||
if (!this.store.driverStatsName) {
|
if (!this.store.driverStatsName) {
|
||||||
this.store.driverStatsStatus = DataStatus.Initialized;
|
this.store.driverStatsStatus = Status.Data.Initialized;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.store.driverStatsStatus = DataStatus.Loading;
|
this.store.driverStatsStatus = Status.Data.Loading;
|
||||||
|
|
||||||
const statsData: DriverStatsAPIData = await (
|
const statsData: API.DriverStats.Response = await (
|
||||||
await axios.get(
|
await axios.get(
|
||||||
`${URLs.stacjownikAPI}/api/getDriverInfo?name=${this.store.driverStatsName}`
|
`${URLs.stacjownikAPI}/api/getDriverInfo?name=${this.store.driverStatsName}`
|
||||||
)
|
)
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
this.store.driverStatsData = statsData;
|
this.store.driverStatsData = statsData;
|
||||||
this.store.driverStatsStatus = DataStatus.Loaded;
|
this.store.driverStatsStatus = Status.Data.Loaded;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.store.driverStatsStatus = DataStatus.Error;
|
this.store.driverStatsStatus = Status.Data.Error;
|
||||||
console.error('Ups! Wystąpił błąd przy próbie pobrania statystyk maszynisty! :/');
|
console.error('Ups! Wystąpił błąd przy próbie pobrania statystyk maszynisty! :/');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -270,7 +268,7 @@ export default defineComponent({
|
|||||||
this.$emit('onSearchConfirm');
|
this.$emit('onSearchConfirm');
|
||||||
},
|
},
|
||||||
|
|
||||||
onFilterChange(filter: JournalFilter) {
|
onFilterChange(filter: Journal.TimetableFilter) {
|
||||||
// this.journalFilterActive = filter;
|
// this.journalFilterActive = filter;
|
||||||
this.filterList
|
this.filterList
|
||||||
?.filter((f) => f.filterSection === filter.filterSection)
|
?.filter((f) => f.filterSection === filter.filterSection)
|
||||||
|
|||||||
@@ -29,10 +29,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, reactive, Ref, ref, watch } from 'vue';
|
import { computed, onMounted, reactive, Ref, ref, watch } from 'vue';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
import JournalDailyStats from './DailyStats.vue';
|
import JournalDailyStats from './DailyStats.vue';
|
||||||
import JournalDriverStats from './JournalDriverStats.vue';
|
import JournalDriverStats from './JournalDriverStats.vue';
|
||||||
import StorageManager from '../../scripts/managers/storageManager';
|
import StorageManager from '../../managers/storageManager';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
type TStatTab = 'daily' | 'driver';
|
type TStatTab = 'daily' | 'driver';
|
||||||
@@ -60,7 +60,8 @@ let data = reactive({
|
|||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
function onTabButtonClick(tab: TStatTab) {
|
function onTabButtonClick(tab: TStatTab) {
|
||||||
if (lastClickedTab.value == tab || !lastClickedTab.value || !areStatsOpen.value) areStatsOpen.value = !areStatsOpen.value;
|
if (lastClickedTab.value == tab || !lastClickedTab.value || !areStatsOpen.value)
|
||||||
|
areStatsOpen.value = !areStatsOpen.value;
|
||||||
|
|
||||||
if (tab == 'daily') {
|
if (tab == 'daily') {
|
||||||
StorageManager.setBooleanValue('dailyStatsOpen', areStatsOpen.value);
|
StorageManager.setBooleanValue('dailyStatsOpen', areStatsOpen.value);
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
{{ $t('app.offline') }}
|
{{ $t('app.offline') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Loading v-else-if="dataStatus == DataStatus.Loading" />
|
<Loading v-else-if="dataStatus == Status.Data.Loading" />
|
||||||
|
|
||||||
<div v-else-if="dataStatus == DataStatus.Error" class="journal_warning error">
|
<div v-else-if="dataStatus == Status.Data.Error" class="journal_warning error">
|
||||||
{{ $t('app.error') }}
|
{{ $t('app.error') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -38,20 +38,20 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import { DataStatus } from '../../../scripts/enums/DataStatus';
|
|
||||||
import { TimetableHistory } from '../../../scripts/interfaces/api/TimetablesAPIData';
|
|
||||||
import { useStore } from '../../../store/store';
|
|
||||||
|
|
||||||
import Loading from '../../Global/Loading.vue';
|
import Loading from '../../Global/Loading.vue';
|
||||||
import AddDataButton from '../../Global/AddDataButton.vue';
|
import AddDataButton from '../../Global/AddDataButton.vue';
|
||||||
import TimetableHistoryList from './TimetableHistoryList.vue';
|
import TimetableHistoryList from './TimetableHistoryList.vue';
|
||||||
|
import { useStore } from '../../../store/mainStore';
|
||||||
|
import { Status } from '../../../typings/common';
|
||||||
|
import { API } from '../../../typings/api';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { Loading, AddDataButton, TimetableHistoryList },
|
components: { Loading, AddDataButton, TimetableHistoryList },
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
timetableHistory: {
|
timetableHistory: {
|
||||||
type: Array as PropType<TimetableHistory[]>,
|
type: Array as PropType<API.TimetableHistory.Response>,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
scrollNoMoreData: {
|
scrollNoMoreData: {
|
||||||
@@ -64,13 +64,13 @@ export default defineComponent({
|
|||||||
type: Function as PropType<() => void>
|
type: Function as PropType<() => void>
|
||||||
},
|
},
|
||||||
dataStatus: {
|
dataStatus: {
|
||||||
type: Number as PropType<DataStatus>
|
type: Number as PropType<Status.Data>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
DataStatus,
|
Status,
|
||||||
store: useStore()
|
store: useStore()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,8 +77,8 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import { TimetableHistory } from '../../../scripts/interfaces/api/TimetablesAPIData';
|
|
||||||
import StockList from '../../Global/StockList.vue';
|
import StockList from '../../Global/StockList.vue';
|
||||||
|
import { API } from '../../../typings/api';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { StockList },
|
components: { StockList },
|
||||||
@@ -88,7 +88,7 @@ export default defineComponent({
|
|||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
timetable: {
|
timetable: {
|
||||||
type: Object as PropType<TimetableHistory>,
|
type: Object as PropType<API.TimetableHistory.Data>,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -62,24 +62,24 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import { TimetableHistory } from '../../../scripts/interfaces/api/TimetablesAPIData';
|
|
||||||
|
|
||||||
import dateMixin from '../../../mixins/dateMixin';
|
import dateMixin from '../../../mixins/dateMixin';
|
||||||
import modalTrainMixin from '../../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../../mixins/modalTrainMixin';
|
||||||
import styleMixin from '../../../mixins/styleMixin';
|
import styleMixin from '../../../mixins/styleMixin';
|
||||||
|
import { API } from '../../../typings/api';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [dateMixin, modalTrainMixin, styleMixin],
|
mixins: [dateMixin, modalTrainMixin, styleMixin],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
timetable: {
|
timetable: {
|
||||||
type: Object as PropType<TimetableHistory>,
|
type: Object as PropType<API.TimetableHistory.Data>,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
showTimetable(timetable: TimetableHistory, target: EventTarget | null) {
|
showTimetable(timetable: API.TimetableHistory.Data, target: EventTarget | null) {
|
||||||
if (timetable?.terminated) return;
|
if (timetable?.terminated) return;
|
||||||
|
|
||||||
this.selectModalTrain(timetable.driverName + timetable.trainNo.toString(), target);
|
this.selectModalTrain(timetable.driverName + timetable.trainNo.toString(), target);
|
||||||
|
|||||||
@@ -38,17 +38,17 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PropType, defineComponent, ref } from 'vue';
|
import { PropType, defineComponent, ref } from 'vue';
|
||||||
import { TimetableHistory } from '../../../scripts/interfaces/api/TimetablesAPIData';
|
|
||||||
|
|
||||||
import TimetableGeneral from './TimetableGeneral.vue';
|
import TimetableGeneral from './TimetableGeneral.vue';
|
||||||
import TimetableStops from './TimetableStops.vue';
|
import TimetableStops from './TimetableStops.vue';
|
||||||
import TimetableStatus from './TimetableStatus.vue';
|
import TimetableStatus from './TimetableStatus.vue';
|
||||||
import TimetableExtra from './TimetableExtra.vue';
|
import TimetableExtra from './TimetableExtra.vue';
|
||||||
|
import { API } from '../../../typings/api';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
timetableHistory: {
|
timetableHistory: {
|
||||||
type: Array as PropType<TimetableHistory[]>,
|
type: Array as PropType<API.TimetableHistory.Response>,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -44,14 +44,14 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import { TimetableHistory } from '../../../scripts/interfaces/api/TimetablesAPIData';
|
|
||||||
import ProgressBar from '../../Global/ProgressBar.vue';
|
import ProgressBar from '../../Global/ProgressBar.vue';
|
||||||
|
import { API } from '../../../typings/api';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { ProgressBar },
|
components: { ProgressBar },
|
||||||
props: {
|
props: {
|
||||||
timetable: {
|
timetable: {
|
||||||
type: Object as PropType<TimetableHistory>,
|
type: Object as PropType<API.TimetableHistory.Data>,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import dateMixin from '../../../mixins/dateMixin';
|
import dateMixin from '../../../mixins/dateMixin';
|
||||||
|
import { API } from '../../../typings/api';
|
||||||
import { TimetableHistory } from '../../../scripts/interfaces/api/TimetablesAPIData';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [dateMixin],
|
mixins: [dateMixin],
|
||||||
@@ -37,7 +36,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
timetable: {
|
timetable: {
|
||||||
type: Object as PropType<TimetableHistory>,
|
type: Object as PropType<API.TimetableHistory.Data>,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
export namespace Journal {
|
||||||
|
export type DispatcherSearcher = {
|
||||||
|
[key in 'search-dispatcher' | 'search-station' | 'search-date']: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface DispatcherSorter {
|
||||||
|
id: 'timestampFrom' | 'duration';
|
||||||
|
dir: -1 | 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TimetableSearchKey =
|
||||||
|
| 'search-driver'
|
||||||
|
| 'search-train'
|
||||||
|
| 'search-date'
|
||||||
|
| 'search-dispatcher'
|
||||||
|
| 'search-issuedFrom';
|
||||||
|
|
||||||
|
export type TimetableSearchType = {
|
||||||
|
[key in TimetableSearchKey]: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const enum TimetableFilterId {
|
||||||
|
ACTIVE = 'active',
|
||||||
|
FULFILLED = 'fulfilled',
|
||||||
|
ABANDONED = 'abandoned',
|
||||||
|
ALL = 'all',
|
||||||
|
TWR = 'twr',
|
||||||
|
SKR = 'skr',
|
||||||
|
TWR_SKR = 'twr-skr'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum FilterSection {
|
||||||
|
TIMETABLE_STATUS = 'timetable-status',
|
||||||
|
TWRSKR = 'twrskr'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TimetableFilter {
|
||||||
|
id: TimetableFilterId;
|
||||||
|
filterSection: string;
|
||||||
|
isActive: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TimetableSorterKey = 'timetableId' | 'beginDate' | 'distance' | 'total-stops';
|
||||||
|
|
||||||
|
export interface TimetableSorter {
|
||||||
|
id: TimetableSorterKey;
|
||||||
|
dir: 'asc' | 'desc';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -69,14 +69,14 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
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 Station from '../../scripts/interfaces/Station';
|
||||||
import { URLs } from '../../scripts/utils/apiURLs';
|
import { URLs } from '../../scripts/utils/apiURLs';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
import styleMixin from '../../mixins/styleMixin';
|
import styleMixin from '../../mixins/styleMixin';
|
||||||
import listObserverMixin from '../../mixins/listObserverMixin';
|
import listObserverMixin from '../../mixins/listObserverMixin';
|
||||||
import { OnlineScenery } from '../../scripts/interfaces/store/storeTypes';
|
import { OnlineScenery } from '../../store/typings';
|
||||||
|
import { API } from '../../typings/api';
|
||||||
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SceneryDispatchersHistory',
|
name: 'SceneryDispatchersHistory',
|
||||||
@@ -95,9 +95,9 @@ export default defineComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
historyList: [] as DispatcherHistory[],
|
historyList: [] as API.DispatcherHistory.Response,
|
||||||
dataStatus: DataStatus.Loading,
|
dataStatus: Status.Data.Loading,
|
||||||
DataStatus
|
DataStatus: Status.Data
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -109,17 +109,22 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async fetchAPIData(countFrom = 0, countLimit = 30): Promise<DispatcherHistory[] | null> {
|
async fetchAPIData(
|
||||||
|
countFrom = 0,
|
||||||
|
countLimit = 30
|
||||||
|
): Promise<API.DispatcherHistory.Response | null> {
|
||||||
try {
|
try {
|
||||||
this.dataStatus = DataStatus.Loading;
|
this.dataStatus = Status.Data.Loading;
|
||||||
|
|
||||||
const requestString = `${URLs.stacjownikAPI}/api/getDispatchers?stationName=${this.station.name}&countFrom=${countFrom}&countLimit=${countLimit}`;
|
const requestString = `${URLs.stacjownikAPI}/api/getDispatchers?stationName=${this.station.name}&countFrom=${countFrom}&countLimit=${countLimit}`;
|
||||||
const historyAPIData: DispatcherHistory[] = await (await axios.get(requestString)).data;
|
const historyAPIData: API.DispatcherHistory.Response = await (
|
||||||
|
await axios.get(requestString)
|
||||||
|
).data;
|
||||||
|
|
||||||
this.dataStatus = DataStatus.Loaded;
|
this.dataStatus = Status.Data.Loaded;
|
||||||
return historyAPIData;
|
return historyAPIData;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.dataStatus = DataStatus.Error;
|
this.dataStatus = Status.Data.Error;
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -153,3 +158,4 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
../../store/storeTypes
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import Station from '../../scripts/interfaces/Station';
|
import Station from '../../scripts/interfaces/Station';
|
||||||
import { OnlineScenery } from '../../scripts/interfaces/store/storeTypes';
|
import { OnlineScenery } from '../../store/typings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -58,3 +58,4 @@ export default defineComponent({
|
|||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
../../store/storeTypes
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ import SceneryInfoUserList from './SceneryInfo/SceneryInfoUserList.vue';
|
|||||||
import SceneryInfoSpawnList from './SceneryInfo/SceneryInfoSpawnList.vue';
|
import SceneryInfoSpawnList from './SceneryInfo/SceneryInfoSpawnList.vue';
|
||||||
import SceneryInfoRoutes from './SceneryInfo/SceneryInfoRoutes.vue';
|
import SceneryInfoRoutes from './SceneryInfo/SceneryInfoRoutes.vue';
|
||||||
import Station from '../../scripts/interfaces/Station';
|
import Station from '../../scripts/interfaces/Station';
|
||||||
import { OnlineScenery } from '../../scripts/interfaces/store/storeTypes';
|
import { OnlineScenery } from '../../store/typings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@@ -110,7 +110,7 @@ export default defineComponent({
|
|||||||
type: Object as PropType<OnlineScenery>,
|
type: Object as PropType<OnlineScenery>,
|
||||||
required: false
|
required: false
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<StationStatusBadge
|
<StationStatusBadge
|
||||||
:statusID="onlineScenery?.statusID"
|
|
||||||
:isOnline="onlineScenery ? true : false"
|
:isOnline="onlineScenery ? true : false"
|
||||||
:statusTimestamp="onlineScenery?.statusTimestamp"
|
:dispatcherStatus="onlineScenery?.dispatcherStatus"
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
@@ -35,7 +34,7 @@ import dateMixin from '../../../mixins/dateMixin';
|
|||||||
import routerMixin from '../../../mixins/routerMixin';
|
import routerMixin from '../../../mixins/routerMixin';
|
||||||
import styleMixin from '../../../mixins/styleMixin';
|
import styleMixin from '../../../mixins/styleMixin';
|
||||||
import StationStatusBadge from '../../Global/StationStatusBadge.vue';
|
import StationStatusBadge from '../../Global/StationStatusBadge.vue';
|
||||||
import { OnlineScenery } from '../../../scripts/interfaces/store/storeTypes';
|
import { OnlineScenery } from '../../../store/typings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [styleMixin, dateMixin, routerMixin],
|
mixins: [styleMixin, dateMixin, routerMixin],
|
||||||
|
|||||||
@@ -7,7 +7,11 @@
|
|||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<transition-group name="spawns-anim" tag="ul">
|
<transition-group name="spawns-anim" tag="ul">
|
||||||
<li class="badge spawn badge-none" v-if="!onlineScenery || onlineScenery.spawns.length == 0" key="no-spawns">
|
<li
|
||||||
|
class="badge spawn badge-none"
|
||||||
|
v-if="!onlineScenery || onlineScenery.spawns.length == 0"
|
||||||
|
key="no-spawns"
|
||||||
|
>
|
||||||
{{ $t('scenery.no-spawns') }}
|
{{ $t('scenery.no-spawns') }}
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -26,7 +30,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import { OnlineScenery } from '../../../scripts/interfaces/store/storeTypes';
|
import { OnlineScenery } from '../../../store/typings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import modalTrainMixin from '../../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../../mixins/modalTrainMixin';
|
||||||
import routerMixin from '../../../mixins/routerMixin';
|
import routerMixin from '../../../mixins/routerMixin';
|
||||||
import { OnlineScenery } from '../../../scripts/interfaces/store/storeTypes';
|
import { OnlineScenery } from '../../../store/typings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [routerMixin, modalTrainMixin],
|
mixins: [routerMixin, modalTrainMixin],
|
||||||
|
|||||||
@@ -185,10 +185,10 @@ import Loading from '../Global/Loading.vue';
|
|||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import routerMixin from '../../mixins/routerMixin';
|
import routerMixin from '../../mixins/routerMixin';
|
||||||
import Station from '../../scripts/interfaces/Station';
|
import Station from '../../scripts/interfaces/Station';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
||||||
import ScheduledTrainStatus from './ScheduledTrainStatus.vue';
|
import ScheduledTrainStatus from './ScheduledTrainStatus.vue';
|
||||||
import { OnlineScenery } from '../../scripts/interfaces/store/storeTypes';
|
import { OnlineScenery } from '../../store/typings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SceneryTimetable',
|
name: 'SceneryTimetable',
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<!-- WIP -->
|
||||||
|
<!-- <div class="top-filters">
|
||||||
|
<button class="btn btn--option">ROZPOCZYNA BIEG</button>
|
||||||
|
|
||||||
|
<button class="btn btn--option">PRZEZ</button>
|
||||||
|
|
||||||
|
<button class="btn btn--option">KOŃCZY BIEG</button>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
<section class="scenery-table-section">
|
<section class="scenery-table-section">
|
||||||
<Loading v-if="dataStatus != DataStatus.Loaded" />
|
<Loading v-if="dataStatus != DataStatus.Loaded" />
|
||||||
|
|
||||||
<div class="no-history" v-else-if="historyList.length == 0">
|
<div class="no-history" v-else-if="historyList.length == 0">
|
||||||
{{ $t('scenery.history-list-empty') }}
|
{{ $t('scenery.history-list-empty') }}
|
||||||
</div>
|
</div>
|
||||||
@@ -18,9 +28,9 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="historyItem in historyList" :key="historyItem.id">
|
<tr v-for="historyItem in historyList" :key="historyItem.id">
|
||||||
<td>
|
<td>
|
||||||
<router-link :to="`/journal/timetables?timetableId=${historyItem.id}`"
|
<router-link :to="`/journal/timetables?timetableId=${historyItem.id}`">
|
||||||
>#{{ historyItem.id }}</router-link
|
#{{ historyItem.id }}
|
||||||
>
|
</router-link>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<b class="text--primary">{{ historyItem.trainCategoryCode }}</b> <br />
|
<b class="text--primary">{{ historyItem.trainCategoryCode }}</b> <br />
|
||||||
@@ -56,16 +66,14 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
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 Station from '../../scripts/interfaces/Station';
|
||||||
import { URLs } from '../../scripts/utils/apiURLs';
|
import { URLs } from '../../scripts/utils/apiURLs';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
import listObserverMixin from '../../mixins/listObserverMixin';
|
import listObserverMixin from '../../mixins/listObserverMixin';
|
||||||
import { OnlineScenery } from '../../scripts/interfaces/store/storeTypes';
|
import { OnlineScenery } from '../../store/typings';
|
||||||
|
import { API } from '../../typings/api';
|
||||||
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SceneryTimetablesHistory',
|
name: 'SceneryTimetablesHistory',
|
||||||
@@ -83,28 +91,28 @@ export default defineComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
historyList: [] as TimetableHistory[],
|
historyList: [] as API.TimetableHistory.Response,
|
||||||
dataStatus: DataStatus.Loading,
|
dataStatus: Status.Data.Loading,
|
||||||
DataStatus
|
DataStatus: Status.Data
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
async activated() {
|
async activated() {
|
||||||
const fetchedHistory = await this.fetchAPIData();
|
this.fetchAPIData();
|
||||||
if (fetchedHistory) this.historyList = fetchedHistory.timetables;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async fetchAPIData(countFrom = 0, countLimit = 15): Promise<SceneryTimetableHistory | null> {
|
async fetchAPIData(countFrom = 0, countLimit = 15) {
|
||||||
try {
|
try {
|
||||||
const requestString = `${URLs.stacjownikAPI}/api/getIssuedTimetables?name=${this.station.name}&countFrom=${countFrom}&countLimit=${countLimit}`;
|
const requestString = `${URLs.stacjownikAPI}/api/getTimetables?issuedFrom=${this.station.name}&countFrom=${countFrom}&countLimit=${countLimit}`;
|
||||||
const historyAPIData: SceneryTimetableHistory = await (await axios.get(requestString)).data;
|
|
||||||
|
|
||||||
this.dataStatus = DataStatus.Loaded;
|
const response: API.TimetableHistory.Response = await (await axios.get(requestString)).data;
|
||||||
return historyAPIData;
|
|
||||||
|
this.historyList = response;
|
||||||
|
|
||||||
|
this.dataStatus = Status.Data.Loaded;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -119,4 +127,14 @@ export default defineComponent({
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../styles/responsive.scss';
|
@import '../../styles/responsive.scss';
|
||||||
@import '../../styles/sceneryViewTables.scss';
|
@import '../../styles/sceneryViewTables.scss';
|
||||||
|
|
||||||
|
.top-filters {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import { ScheduledTrain, StopStatus } from '../../scripts/interfaces/ScheduledTrain';
|
import { ScheduledTrain, StopStatus } from '../../store/typings';
|
||||||
|
|
||||||
interface ScheduledTrainComp extends ScheduledTrain {
|
interface ScheduledTrainComp extends ScheduledTrain {
|
||||||
stopStatusIndicator: string;
|
stopStatusIndicator: string;
|
||||||
@@ -42,7 +42,7 @@ export default defineComponent({
|
|||||||
stopStatusIndicator = '';
|
stopStatusIndicator = '';
|
||||||
|
|
||||||
switch (stopStatus) {
|
switch (stopStatus) {
|
||||||
case StopStatus.arriving:
|
case StopStatus.ARRIVING:
|
||||||
stopStatusIndicator = `${this.$t('timetables.from')}: ${prevDepartureIndicator}`;
|
stopStatusIndicator = `${this.$t('timetables.from')}: ${prevDepartureIndicator}`;
|
||||||
stopStatusDescription = this.$t('timetables.desc-arriving', {
|
stopStatusDescription = this.$t('timetables.desc-arriving', {
|
||||||
prevStationName,
|
prevStationName,
|
||||||
@@ -50,8 +50,8 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StopStatus.online:
|
case StopStatus.ONLINE:
|
||||||
case StopStatus.stopped:
|
case StopStatus.STOPPED:
|
||||||
stopStatusIndicator = nextArrivalLine
|
stopStatusIndicator = nextArrivalLine
|
||||||
? `${this.$t('timetables.to')}: ${nextArrivalIndicator}`
|
? `${this.$t('timetables.to')}: ${nextArrivalIndicator}`
|
||||||
: `${this.$t('timetables.desc-end')}`;
|
: `${this.$t('timetables.desc-end')}`;
|
||||||
@@ -60,7 +60,7 @@ export default defineComponent({
|
|||||||
: '';
|
: '';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StopStatus.departed:
|
case StopStatus.DEPARTED:
|
||||||
stopStatusIndicator = `${this.$t('timetables.to')}: ${nextArrivalIndicator}`;
|
stopStatusIndicator = `${this.$t('timetables.to')}: ${nextArrivalIndicator}`;
|
||||||
stopStatusDescription = this.$t('timetables.desc-departed', {
|
stopStatusDescription = this.$t('timetables.desc-departed', {
|
||||||
nextStationName,
|
nextStationName,
|
||||||
@@ -68,7 +68,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StopStatus['departed-away']:
|
case StopStatus.DEPARTED_AWAY:
|
||||||
stopStatusIndicator = `${this.$t('timetables.to')}: ${nextArrivalIndicator}`;
|
stopStatusIndicator = `${this.$t('timetables.to')}: ${nextArrivalIndicator}`;
|
||||||
stopStatusDescription = this.$t('timetables.desc-departed-away', {
|
stopStatusDescription = this.$t('timetables.desc-departed-away', {
|
||||||
nextStationName,
|
nextStationName,
|
||||||
@@ -76,7 +76,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StopStatus.terminated:
|
case StopStatus.TERMINATED:
|
||||||
stopStatusIndicator = `X ${this.$t('timetables.desc-terminated')}`;
|
stopStatusIndicator = `X ${this.$t('timetables.desc-terminated')}`;
|
||||||
stopStatusDescription = this.$t('timetables.desc-terminated');
|
stopStatusDescription = this.$t('timetables.desc-terminated');
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -138,11 +138,11 @@
|
|||||||
import { defineComponent, inject } from 'vue';
|
import { defineComponent, inject } from 'vue';
|
||||||
import keyMixin from '../../mixins/keyMixin';
|
import keyMixin from '../../mixins/keyMixin';
|
||||||
import routerMixin from '../../mixins/routerMixin';
|
import routerMixin from '../../mixins/routerMixin';
|
||||||
import StorageManager from '../../scripts/managers/storageManager';
|
|
||||||
import { useStationFiltersStore } from '../../store/stationFiltersStore';
|
import { useStationFiltersStore } from '../../store/stationFiltersStore';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
|
|
||||||
import FilterOption from './FilterOption.vue';
|
import FilterOption from './FilterOption.vue';
|
||||||
|
import StorageManager from '../../managers/storageManager';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { FilterOption },
|
components: { FilterOption },
|
||||||
|
|||||||
@@ -108,9 +108,8 @@
|
|||||||
|
|
||||||
<td class="station_status">
|
<td class="station_status">
|
||||||
<StationStatusBadge
|
<StationStatusBadge
|
||||||
:statusID="station.onlineInfo?.statusID"
|
|
||||||
:isOnline="station.onlineInfo ? true : false"
|
:isOnline="station.onlineInfo ? true : false"
|
||||||
:statusTimestamp="station.onlineInfo?.statusTimestamp"
|
:dispatcherStatus="station.onlineInfo?.dispatcherStatus"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
@@ -280,13 +279,13 @@ import { defineComponent, computed, PropType } from 'vue';
|
|||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import stationInfoMixin from '../../mixins/stationInfoMixin';
|
import stationInfoMixin from '../../mixins/stationInfoMixin';
|
||||||
import styleMixin from '../../mixins/styleMixin';
|
import styleMixin from '../../mixins/styleMixin';
|
||||||
import { DataStatus } from '../../scripts/enums/DataStatus';
|
|
||||||
import Station from '../../scripts/interfaces/Station';
|
import Station from '../../scripts/interfaces/Station';
|
||||||
import { useStationFiltersStore } from '../../store/stationFiltersStore';
|
import { useStationFiltersStore } from '../../store/stationFiltersStore';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
import { HeadIdsTypes, headIconsIds, headIds } from '../../scripts/data/stationHeaderNames';
|
import { HeadIdsTypes, headIconsIds, headIds } from '../../scripts/data/stationHeaderNames';
|
||||||
import StationStatusBadge from '../Global/StationStatusBadge.vue';
|
import StationStatusBadge from '../Global/StationStatusBadge.vue';
|
||||||
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -316,8 +315,9 @@ export default defineComponent({
|
|||||||
const stationFiltersStore = useStationFiltersStore();
|
const stationFiltersStore = useStationFiltersStore();
|
||||||
|
|
||||||
const isDataLoaded = computed(() => {
|
const isDataLoaded = computed(() => {
|
||||||
return store.dataStatuses.sceneries != DataStatus.Loading;
|
return store.dataStatuses.sceneries != Status.Data.Loading;
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isDataLoaded,
|
isDataLoaded,
|
||||||
stationFiltersStore
|
stationFiltersStore
|
||||||
@@ -388,7 +388,8 @@ section.station_table {
|
|||||||
table {
|
table {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
min-width: 1350px;
|
// min-width: 1350px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
@include smallScreen() {
|
@include smallScreen() {
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
export default interface Filter {
|
export interface FilterOption {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
value: boolean;
|
||||||
|
defaultValue: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Filter {
|
||||||
[key: string]: boolean | number | string;
|
[key: string]: boolean | number | string;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
notDefault: boolean;
|
notDefault: boolean;
|
||||||
@@ -1,22 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="train-info">
|
<div class="train-info">
|
||||||
<section class="train-route">
|
<section class="train-general">
|
||||||
<div class="train_general">
|
<div class="general-info">
|
||||||
<b class="warning-timeout" v-if="train.isTimeout" :title="$t('trains.timeout')">?</b>
|
<b class="warning-timeout" v-if="train.isTimeout" :title="$t('trains.timeout')">?</b>
|
||||||
<span class="timetable-id" v-if="train.timetableData"
|
<span class="timetable-id" v-if="train.timetableData">
|
||||||
>#{{ train.timetableData.timetableId }}</span
|
#{{ train.timetableData.timetableId }}
|
||||||
>
|
</span>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
class="timetable_warnings"
|
class="timetable-warnings"
|
||||||
v-if="train.timetableData?.TWR || train.timetableData?.SKR"
|
v-if="train.timetableData?.TWR || train.timetableData?.SKR"
|
||||||
>
|
>
|
||||||
<span class="train-badge twr" v-if="train.timetableData?.TWR" :title="$t('general.TWR')"
|
<span class="train-badge twr" v-if="train.timetableData?.TWR" :title="$t('general.TWR')">
|
||||||
>TWR</span
|
TWR
|
||||||
>
|
</span>
|
||||||
<span class="train-badge skr" v-if="train.timetableData?.SKR" :title="$t('general.SKR')"
|
<span class="train-badge skr" v-if="train.timetableData?.SKR" :title="$t('general.SKR')">
|
||||||
>SKR</span
|
SKR
|
||||||
>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<strong>
|
<strong>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
<span>{{ train.driverName }}</span>
|
<span>{{ train.driverName }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="timetable_route" v-if="train.timetableData">
|
<div class="general-timetable" v-if="train.timetableData">
|
||||||
<strong>{{ train.timetableData.route.replace('|', ' - ') }}</strong>
|
<strong>{{ train.timetableData.route.replace('|', ' - ') }}</strong>
|
||||||
<img
|
<img
|
||||||
v-if="getSceneriesWithComments(train.timetableData).length > 0"
|
v-if="getSceneriesWithComments(train.timetableData).length > 0"
|
||||||
@@ -49,27 +49,30 @@
|
|||||||
|
|
||||||
<hr style="margin: 0.25em 0" />
|
<hr style="margin: 0.25em 0" />
|
||||||
|
|
||||||
<div class="timetable_stops" v-if="train.timetableData">
|
<div class="general-stops" v-if="train.timetableData">
|
||||||
<span v-if="train.timetableData.followingStops.length > 2">
|
<span v-if="train.timetableData.followingStops.length > 2">
|
||||||
{{ $t('trains.via-title') }}
|
{{ $t('trains.via-title') }}
|
||||||
<span v-html="displayStopList(train.timetableData.followingStops)"></span>
|
<span v-html="displayStopList(train.timetableData.followingStops)"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="timetable_progress" style="margin-top: 0.5em" v-if="train.timetableData">
|
<div class="general-status">
|
||||||
<ProgressBar :progressPercent="confirmedPercentage(train.timetableData.followingStops)" />
|
<div class="timetable-progress" v-if="train.timetableData">
|
||||||
|
<ProgressBar :progressPercent="confirmedPercentage(train.timetableData.followingStops)" />
|
||||||
|
|
||||||
<span class="timetable_progress-distance">
|
<span class="progress-distance">
|
||||||
{{ currentDistance(train.timetableData.followingStops) }} km /
|
{{ currentDistance(train.timetableData.followingStops) }} km /
|
||||||
<span class="text--primary"> {{ train.timetableData.routeDistance }} km </span>
|
<span class="text--primary"> {{ train.timetableData.routeDistance }} km </span>
|
||||||
|
|
|
|
||||||
<span v-html="currentDelay(train.timetableData.followingStops)"></span>
|
<span v-html="currentDelay(train.timetableData.followingStops)"></span>
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="train-status-badges">
|
<div class="status-badges">
|
||||||
<div v-if="!train.currentStationHash" class="train-badge offline">
|
<div v-if="!train.currentStationHash" class="train-badge offline">
|
||||||
{{ $t('trains.scenery-offline') }}
|
{{ $t('trains.scenery-offline') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!train.online" class="train-badge offline">
|
<div v-if="!train.online" class="train-badge offline">
|
||||||
Offline {{ lastSeenMessage(train.lastSeen) }}
|
Offline {{ lastSeenMessage(train.lastSeen) }}
|
||||||
</div>
|
</div>
|
||||||
@@ -181,11 +184,17 @@ export default defineComponent({
|
|||||||
padding: 0 0.25em;
|
padding: 0 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timetable_stops {
|
.train-general {
|
||||||
font-size: 0.75em;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.train_general {
|
.general-stops {
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.general-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -193,55 +202,41 @@ export default defineComponent({
|
|||||||
gap: 0.25em;
|
gap: 0.25em;
|
||||||
margin-right: 1.5em;
|
margin-right: 1.5em;
|
||||||
}
|
}
|
||||||
.train-status-badges {
|
.general-status {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badges {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
gap: 0.25em;
|
gap: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.train-driver {
|
.general-timetable {
|
||||||
&.supporter {
|
|
||||||
color: orange;
|
|
||||||
text-shadow: orange 0 0 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.timetable_route {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
margin-top: 0.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.timetable_warnings {
|
.timetable-warnings {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.25em;
|
gap: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timetable_progress {
|
.timetable-progress {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timetable_progress-distance {
|
.progress-distance {
|
||||||
margin-right: 0.25em;
|
margin-right: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
font-size: 0.9em;
|
|
||||||
|
|
||||||
margin-top: 1em;
|
|
||||||
|
|
||||||
img {
|
|
||||||
margin-right: 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include smallScreen() {
|
@include smallScreen() {
|
||||||
.train-info {
|
.train-info {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
@@ -251,23 +246,13 @@ export default defineComponent({
|
|||||||
font-size: 1.15em;
|
font-size: 1.15em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.train-stats {
|
.general-info,
|
||||||
font-size: 1.1em;
|
.general-status,
|
||||||
}
|
.general-timetable {
|
||||||
|
|
||||||
.train_general {
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.train-status-badges {
|
.timetable-progress {
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timetable_route {
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timetable_progress {
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,11 @@
|
|||||||
v-model="searchedTrain"
|
v-model="searchedTrain"
|
||||||
/>
|
/>
|
||||||
<button class="search-exit">
|
<button class="search-exit">
|
||||||
<img src="/images/icon-exit.svg" alt="Trains search clear icon" @click="onInputClear('train')" />
|
<img
|
||||||
|
src="/images/icon-exit.svg"
|
||||||
|
alt="Trains search clear icon"
|
||||||
|
@click="onInputClear('train')"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -36,7 +40,11 @@
|
|||||||
v-model="searchedDriver"
|
v-model="searchedDriver"
|
||||||
/>
|
/>
|
||||||
<button class="search-exit">
|
<button class="search-exit">
|
||||||
<img src="/images/icon-exit.svg" alt="Driver search clear icon" @click="onInputClear('driver')" />
|
<img
|
||||||
|
src="/images/icon-exit.svg"
|
||||||
|
alt="Driver search clear icon"
|
||||||
|
@click="onInputClear('driver')"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -87,8 +95,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, inject, PropType } from 'vue';
|
import { defineComponent, inject, PropType } from 'vue';
|
||||||
import keyMixin from '../../mixins/keyMixin';
|
import keyMixin from '../../mixins/keyMixin';
|
||||||
import { TrainFilterSection } from '../../scripts/enums/TrainFilterType';
|
import { TrainFilter, TrainFilterSection } from './typings';
|
||||||
import { TrainFilter } from '../../scripts/interfaces/Trains/TrainFilter';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [keyMixin],
|
mixins: [keyMixin],
|
||||||
@@ -152,9 +159,6 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onFilterChange(filter: TrainFilter) {
|
onFilterChange(filter: TrainFilter) {
|
||||||
// if (this.lastSelectedFilter?.id === filter.id)
|
|
||||||
// this.trainFilterList.forEach((tf) => (tf.isActive = filter.id === tf.id));
|
|
||||||
|
|
||||||
filter.isActive = !filter.isActive;
|
filter.isActive = !filter.isActive;
|
||||||
this.lastSelectedFilter = filter;
|
this.lastSelectedFilter = filter;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -72,10 +72,10 @@
|
|||||||
import { computed, defineComponent, PropType } from 'vue';
|
import { computed, defineComponent, PropType } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import Train from '../../scripts/interfaces/Train';
|
import Train from '../../scripts/interfaces/Train';
|
||||||
import TrainStop from '../../scripts/interfaces/TrainStop';
|
import { useStore } from '../../store/mainStore';
|
||||||
import { useStore } from '../../store/store';
|
|
||||||
import StopDate from '../Global/StopDate.vue';
|
import StopDate from '../Global/StopDate.vue';
|
||||||
import StockList from '../Global/StockList.vue';
|
import StockList from '../Global/StockList.vue';
|
||||||
|
import { TrainStop } from '../../store/typings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { StopDate, StockList },
|
components: { StopDate, StockList },
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="train-table">
|
<transition name="status-anim" mode="out-in" tag="div" class="train-table">
|
||||||
<transition name="anim" mode="out-in">
|
<div :key="store.dataStatuses.trains">
|
||||||
<div :key="store.dataStatuses.trains">
|
<div class="table-info" key="offline" v-if="store.isOffline">
|
||||||
<div class="table-info" v-if="store.isOffline">
|
{{ $t('app.offline') }}
|
||||||
{{ $t('app.offline') }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Loading v-else-if="trains.length == 0 && store.dataStatuses.trains == 0" />
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="table-info no-trains"
|
|
||||||
v-else-if="trains.length == 0 && store.dataStatuses.trains != 0"
|
|
||||||
>
|
|
||||||
{{ $t('trains.no-trains') }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<transition-group name="list-anim" tag="ul" class="train-list" v-else>
|
|
||||||
<li
|
|
||||||
class="train-row"
|
|
||||||
v-for="train in currentTrains"
|
|
||||||
:key="train.trainId"
|
|
||||||
tabindex="0"
|
|
||||||
@click.stop="selectModalTrain(train.trainId, $event.currentTarget)"
|
|
||||||
@keydown.enter="selectModalTrain(train.trainId, $event.currentTarget)"
|
|
||||||
>
|
|
||||||
<TrainInfo :train="train" />
|
|
||||||
</li>
|
|
||||||
</transition-group>
|
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
|
||||||
</div>
|
<Loading v-else-if="trains.length == 0 && store.dataStatuses.trains == 0" key="loading" />
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="table-info"
|
||||||
|
key="no-trains"
|
||||||
|
v-else-if="trains.length == 0 && store.dataStatuses.trains != 0"
|
||||||
|
>
|
||||||
|
{{ $t('trains.no-trains') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<transition-group name="list-anim" tag="ul">
|
||||||
|
<li
|
||||||
|
class="train-row"
|
||||||
|
v-for="train in trains"
|
||||||
|
:key="train.trainId"
|
||||||
|
tabindex="0"
|
||||||
|
@click.stop="selectModalTrain(train.trainId, $event.currentTarget)"
|
||||||
|
@keydown.enter="selectModalTrain(train.trainId, $event.currentTarget)"
|
||||||
|
>
|
||||||
|
<TrainInfo :train="train" />
|
||||||
|
</li>
|
||||||
|
</transition-group>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, inject, PropType, Ref } from 'vue';
|
import { defineComponent, inject, PropType, Ref } from 'vue';
|
||||||
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
||||||
import Train from '../../scripts/interfaces/Train';
|
import Train from '../../scripts/interfaces/Train';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/mainStore';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
import TrainInfo from './TrainInfo.vue';
|
import TrainInfo from './TrainInfo.vue';
|
||||||
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { Loading, TrainInfo },
|
components: { Loading, TrainInfo },
|
||||||
@@ -56,14 +56,10 @@ export default defineComponent({
|
|||||||
const store = useStore();
|
const store = useStore();
|
||||||
const searchedTrain = inject('searchedTrain') as Ref<string>;
|
const searchedTrain = inject('searchedTrain') as Ref<string>;
|
||||||
const searchedDriver = inject('searchedDriver') as Ref<string>;
|
const searchedDriver = inject('searchedDriver') as Ref<string>;
|
||||||
const currentTrains = computed(() => {
|
|
||||||
return props.trains;
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
searchedTrain,
|
searchedTrain,
|
||||||
searchedDriver,
|
searchedDriver,
|
||||||
currentTrains,
|
|
||||||
store,
|
store,
|
||||||
sorterActive: inject('sorterActive') as {
|
sorterActive: inject('sorterActive') as {
|
||||||
id: string | number;
|
id: string | number;
|
||||||
@@ -72,6 +68,17 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
dataStatus() {
|
||||||
|
if (this.store.isOffline) return Status.Data.Offline;
|
||||||
|
|
||||||
|
if (this.trains.length == 0 && this.store.dataStatuses.trains == Status.Data.Loading)
|
||||||
|
return Status.Data.Loading;
|
||||||
|
|
||||||
|
return Status.Data.Loaded;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
activated() {
|
activated() {
|
||||||
const query = this.$route.query;
|
const query = this.$route.query;
|
||||||
if (query.trainNo && query.driverName) {
|
if (query.trainNo && query.driverName) {
|
||||||
@@ -89,19 +96,13 @@ export default defineComponent({
|
|||||||
@import '../../styles/responsive.scss';
|
@import '../../styles/responsive.scss';
|
||||||
@import '../../styles/animations.scss';
|
@import '../../styles/animations.scss';
|
||||||
|
|
||||||
.anim {
|
.train-table {
|
||||||
&-enter-from,
|
position: relative;
|
||||||
&-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-enter-active {
|
height: 90vh;
|
||||||
transition: all 100ms ease-out;
|
min-height: 550px;
|
||||||
}
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
&-leave-active {
|
|
||||||
transition: all 100ms ease-out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-info {
|
.table-info {
|
||||||
@@ -114,96 +115,11 @@ export default defineComponent({
|
|||||||
background: #1a1a1a;
|
background: #1a1a1a;
|
||||||
}
|
}
|
||||||
|
|
||||||
img.train-image {
|
li.train-row {
|
||||||
width: 12em;
|
background-color: var(--clr-secondary);
|
||||||
}
|
margin-bottom: 1em;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
.traffic-warning {
|
cursor: pointer;
|
||||||
padding: 1em 0;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
background: var(--clr-warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeouts-warning {
|
|
||||||
background-color: #333;
|
|
||||||
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.05em;
|
|
||||||
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.warning-timeout {
|
|
||||||
background-color: #be3728;
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
width: 1.25em;
|
|
||||||
height: 1.25em;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.train {
|
|
||||||
&-list {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
@include smallScreen() {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-row {
|
|
||||||
background-color: var(--clr-secondary);
|
|
||||||
margin-bottom: 1em;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
&_cars {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.paginator {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
&_item {
|
|
||||||
padding: 0.25em 0.5em;
|
|
||||||
margin: 0 0.5em;
|
|
||||||
outline: 2px solid salmon;
|
|
||||||
|
|
||||||
min-width: 30px;
|
|
||||||
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&.page-number {
|
|
||||||
font-weight: bold;
|
|
||||||
color: gold;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.disabled {
|
|
||||||
outline: 2px solid lightgray;
|
|
||||||
color: lightgray;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: 2px solid white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include smallScreen() {
|
|
||||||
.info-bottom {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,63 +1,93 @@
|
|||||||
import { TrainFilterSection, TrainFilterType } from '../../scripts/enums/TrainFilterType';
|
export enum TrainFilterSection {
|
||||||
import { TrainFilter } from '../../scripts/interfaces/Trains/TrainFilter';
|
TRAIN_TYPE = 'TRAIN_TYPE',
|
||||||
|
TIMETABLE_TYPE = 'TIMETABLE_TYPE',
|
||||||
|
COMMENTS = 'COMMENTS',
|
||||||
|
TIMETABLE = 'TIMETABLE'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const enum TrainFilterId {
|
||||||
|
noComments = 'noComments',
|
||||||
|
withComments = 'withComments',
|
||||||
|
|
||||||
|
twr = 'twr',
|
||||||
|
skr = 'skr',
|
||||||
|
common = 'common',
|
||||||
|
|
||||||
|
passenger = 'passenger',
|
||||||
|
freight = 'freight',
|
||||||
|
other = 'other',
|
||||||
|
noTimetable = 'noTimetable',
|
||||||
|
withTimetable = 'withTimetable'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TrainFilter {
|
||||||
|
id: TrainFilterId;
|
||||||
|
section: TrainFilterSection;
|
||||||
|
isActive: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TrainSorter {
|
||||||
|
id: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
export const trainFilters: TrainFilter[] = [
|
export const trainFilters: TrainFilter[] = [
|
||||||
{
|
{
|
||||||
id: TrainFilterType.twr,
|
id: TrainFilterId.twr,
|
||||||
section: TrainFilterSection.TRAIN_TYPE,
|
section: TrainFilterSection.TRAIN_TYPE,
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.skr,
|
id: TrainFilterId.skr,
|
||||||
section: TrainFilterSection.TRAIN_TYPE,
|
section: TrainFilterSection.TRAIN_TYPE,
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.common,
|
id: TrainFilterId.common,
|
||||||
section: TrainFilterSection.TRAIN_TYPE,
|
section: TrainFilterSection.TRAIN_TYPE,
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: TrainFilterType.passenger,
|
id: TrainFilterId.passenger,
|
||||||
section: TrainFilterSection.TIMETABLE_TYPE,
|
section: TrainFilterSection.TIMETABLE_TYPE,
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.freight,
|
id: TrainFilterId.freight,
|
||||||
section: TrainFilterSection.TIMETABLE_TYPE,
|
section: TrainFilterSection.TIMETABLE_TYPE,
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.other,
|
id: TrainFilterId.other,
|
||||||
section: TrainFilterSection.TIMETABLE_TYPE,
|
section: TrainFilterSection.TIMETABLE_TYPE,
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: TrainFilterType.withComments,
|
id: TrainFilterId.withComments,
|
||||||
section: TrainFilterSection.COMMENTS,
|
section: TrainFilterSection.COMMENTS,
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.noComments,
|
id: TrainFilterId.noComments,
|
||||||
section: TrainFilterSection.COMMENTS,
|
section: TrainFilterSection.COMMENTS,
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: TrainFilterType.withTimetable,
|
id: TrainFilterId.withTimetable,
|
||||||
section: TrainFilterSection.TIMETABLE,
|
section: TrainFilterSection.TIMETABLE,
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.noTimetable,
|
id: TrainFilterId.noTimetable,
|
||||||
section: TrainFilterSection.TIMETABLE,
|
section: TrainFilterSection.TIMETABLE,
|
||||||
isActive: true
|
isActive: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export const sorterOptions = [
|
export const sorterOptions: TrainSorter[] = [
|
||||||
{
|
{
|
||||||
id: 'distance',
|
id: 'distance',
|
||||||
value: 'kilometraż'
|
value: 'kilometraż'
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import { JournalFilterSection, JournalFilterType } from '../../scripts/enums/JournalFilterType';
|
|
||||||
import { JournalFilter } from '../../scripts/types/JournalTimetablesTypes';
|
|
||||||
|
|
||||||
export const journalTimetableFilters: JournalFilter[] = [
|
|
||||||
{
|
|
||||||
id: JournalFilterType.ALL,
|
|
||||||
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
|
||||||
isActive: true
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
id: JournalFilterType.ACTIVE,
|
|
||||||
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
|
||||||
isActive: false
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
id: JournalFilterType.FULFILLED,
|
|
||||||
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
|
||||||
isActive: false
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
id: JournalFilterType.ABANDONED,
|
|
||||||
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
|
||||||
isActive: false
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
id: JournalFilterType.TWR_SKR,
|
|
||||||
filterSection: JournalFilterSection.TWRSKR,
|
|
||||||
isActive: true
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
id: JournalFilterType.TWR,
|
|
||||||
filterSection: JournalFilterSection.TWRSKR,
|
|
||||||
isActive: false
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
id: JournalFilterType.SKR,
|
|
||||||
filterSection: JournalFilterSection.TWRSKR,
|
|
||||||
isActive: false
|
|
||||||
}
|
|
||||||
];
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
[
|
|
||||||
"EP07-356",
|
|
||||||
"EP07-356",
|
|
||||||
"EP07-356",
|
|
||||||
"ET41-074",
|
|
||||||
"2EN57-694+716rb",
|
|
||||||
"EU07E-083",
|
|
||||||
"EN57-716rb",
|
|
||||||
"EN57-716rb",
|
|
||||||
"EN57-716rb",
|
|
||||||
"EN57-038rb",
|
|
||||||
"EN57-038rb",
|
|
||||||
"SM42-329_PLREG",
|
|
||||||
"2EN57-038+1715rb",
|
|
||||||
"EN57-1953rb",
|
|
||||||
"EN57-1953rb",
|
|
||||||
"SM42-1121",
|
|
||||||
"SM42-091",
|
|
||||||
"SM42-404",
|
|
||||||
"SM42-404",
|
|
||||||
"EN57-1914rb",
|
|
||||||
"EN57-961rb"
|
|
||||||
]
|
|
||||||
+1438
-13428
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -78,8 +78,9 @@
|
|||||||
"not-signed": "NOT SIGNED IN",
|
"not-signed": "NOT SIGNED IN",
|
||||||
"no-limit": "NO LIMIT",
|
"no-limit": "NO LIMIT",
|
||||||
"unavailable": "UNAVAILABLE",
|
"unavailable": "UNAVAILABLE",
|
||||||
"brb": "AFK",
|
"afk": "AFK",
|
||||||
"no-space": "NO SPACE",
|
"no-space": "NO SPACE",
|
||||||
|
"invalid": "INVALID HASH",
|
||||||
"unknown": "UNKNOWN"
|
"unknown": "UNKNOWN"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
|||||||
+2
-1
@@ -66,8 +66,9 @@
|
|||||||
"not-signed": "NIEZALOGOWANY",
|
"not-signed": "NIEZALOGOWANY",
|
||||||
"no-limit": "BEZ LIMITU",
|
"no-limit": "BEZ LIMITU",
|
||||||
"unavailable": "NIEDOSTĘPNY",
|
"unavailable": "NIEDOSTĘPNY",
|
||||||
"brb": "Z/W",
|
"afk": "Z/W",
|
||||||
"no-space": "BRAK MIEJSCA",
|
"no-space": "BRAK MIEJSCA",
|
||||||
|
"invalid": "NIEWPISANY",
|
||||||
"unknown": "NIEZNANY"
|
"unknown": "NIEZNANY"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { TrainFilter } from '../interfaces/Trains/TrainFilter';
|
import { TrainFilter, TrainFilterId } from '../components/TrainsView/typings';
|
||||||
import { TrainFilterType } from '../enums/TrainFilterType';
|
import Train from '../scripts/interfaces/Train';
|
||||||
import Train from '../interfaces/Train';
|
import { TrainStop } from '../store/typings';
|
||||||
import TrainStop from '../interfaces/TrainStop';
|
|
||||||
|
|
||||||
function confirmedPercentage(stops: TrainStop[] | undefined) {
|
function confirmedPercentage(stops: TrainStop[] | undefined) {
|
||||||
if (!stops) return -1;
|
if (!stops) return -1;
|
||||||
@@ -32,34 +31,34 @@ function filterTrainList(
|
|||||||
if (f.isActive) return true;
|
if (f.isActive) return true;
|
||||||
|
|
||||||
switch (f.id) {
|
switch (f.id) {
|
||||||
case TrainFilterType.noTimetable:
|
case TrainFilterId.noTimetable:
|
||||||
return train.timetableData;
|
return train.timetableData;
|
||||||
|
|
||||||
case TrainFilterType.withTimetable:
|
case TrainFilterId.withTimetable:
|
||||||
return !train.timetableData;
|
return !train.timetableData;
|
||||||
|
|
||||||
case TrainFilterType.withComments:
|
case TrainFilterId.withComments:
|
||||||
return !train.timetableData?.followingStops.some((stop) => stop.comments);
|
return !train.timetableData?.followingStops.some((stop) => stop.comments);
|
||||||
|
|
||||||
case TrainFilterType.noComments:
|
case TrainFilterId.noComments:
|
||||||
return train.timetableData?.followingStops.some((stop) => stop.comments);
|
return train.timetableData?.followingStops.some((stop) => stop.comments);
|
||||||
|
|
||||||
case TrainFilterType.twr:
|
case TrainFilterId.twr:
|
||||||
return !train.timetableData?.TWR;
|
return !train.timetableData?.TWR;
|
||||||
|
|
||||||
case TrainFilterType.skr:
|
case TrainFilterId.skr:
|
||||||
return !train.timetableData?.SKR;
|
return !train.timetableData?.SKR;
|
||||||
|
|
||||||
case TrainFilterType.common:
|
case TrainFilterId.common:
|
||||||
return train.timetableData?.SKR || train.timetableData?.TWR;
|
return train.timetableData?.SKR || train.timetableData?.TWR;
|
||||||
|
|
||||||
case TrainFilterType.passenger:
|
case TrainFilterId.passenger:
|
||||||
return !/^[AMRE]\D{2}$/.test(train.timetableData?.category || '');
|
return !/^[AMRE]\D{2}$/.test(train.timetableData?.category || '');
|
||||||
|
|
||||||
case TrainFilterType.freight:
|
case TrainFilterId.freight:
|
||||||
return !train.timetableData?.category.startsWith('T');
|
return !train.timetableData?.category.startsWith('T');
|
||||||
|
|
||||||
case TrainFilterType.other:
|
case TrainFilterId.other:
|
||||||
return !/^[PXZL]\D{2}$/.test(train.timetableData?.category || '');
|
return !/^[PXZL]\D{2}$/.test(train.timetableData?.category || '');
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -72,7 +71,6 @@ function filterTrainList(
|
|||||||
(searchedDriver.length > 0
|
(searchedDriver.length > 0
|
||||||
? train.driverName.toLowerCase().startsWith(searchedDriver.toLowerCase())
|
? train.driverName.toLowerCase().startsWith(searchedDriver.toLowerCase())
|
||||||
: true) &&
|
: true) &&
|
||||||
(!train.timetableData ? train.online : train.timetableData) &&
|
|
||||||
isFiltered
|
isFiltered
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../store/store';
|
import { useStore } from '../store/mainStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import Train from '../scripts/interfaces/Train';
|
import Train from '../scripts/interfaces/Train';
|
||||||
import TrainStop from '../scripts/interfaces/TrainStop';
|
import { TrainStop } from '../store/typings';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data: () => ({
|
data: () => ({
|
||||||
|
|||||||
+2
-1
@@ -61,7 +61,8 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
scrollBehavior(to, from, savedPosition) {
|
scrollBehavior(to, from, savedPosition) {
|
||||||
if (to.name == 'SceneryView' && from.name) return { el: `.app_main` };
|
if (to.name == 'SceneryView' && from.name && from.query['view'] === undefined)
|
||||||
|
return { el: `.app_main` };
|
||||||
|
|
||||||
if (savedPosition) return savedPosition;
|
if (savedPosition) return savedPosition;
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
import Filter from '../../interfaces/Filter';
|
|
||||||
|
|
||||||
export const filterInitStates: Filter = {
|
|
||||||
default: false,
|
|
||||||
notDefault: false,
|
|
||||||
real: false,
|
|
||||||
fictional: false,
|
|
||||||
SPK: false,
|
|
||||||
SCS: false,
|
|
||||||
SPE: false,
|
|
||||||
SUP: false,
|
|
||||||
noSUP: false,
|
|
||||||
ręczne: false,
|
|
||||||
'ręczne+SPK': false,
|
|
||||||
'ręczne+SCS': false,
|
|
||||||
mechaniczne: false,
|
|
||||||
'mechaniczne+SPK': false,
|
|
||||||
'mechaniczne+SCS': false,
|
|
||||||
współczesna: false,
|
|
||||||
kształtowa: false,
|
|
||||||
historyczna: false,
|
|
||||||
mieszana: false,
|
|
||||||
SBL: false,
|
|
||||||
PBL: false,
|
|
||||||
minLevel: 0,
|
|
||||||
maxLevel: 20,
|
|
||||||
minOneWayCatenary: 0,
|
|
||||||
minOneWay: 0,
|
|
||||||
minTwoWayCatenary: 0,
|
|
||||||
minTwoWay: 0,
|
|
||||||
'include-selected': false,
|
|
||||||
'no-1track': false,
|
|
||||||
'no-2track': false,
|
|
||||||
free: true,
|
|
||||||
occupied: false,
|
|
||||||
ending: false,
|
|
||||||
nonPublic: false,
|
|
||||||
unavailable: true,
|
|
||||||
abandoned: true,
|
|
||||||
afkStatus: false,
|
|
||||||
endingStatus: false,
|
|
||||||
noSpaceStatus: false,
|
|
||||||
unavailableStatus: false,
|
|
||||||
unsignedStatus: false,
|
|
||||||
|
|
||||||
authors: '',
|
|
||||||
|
|
||||||
onlineFromHours: 0
|
|
||||||
};
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
export enum DataStatus {
|
|
||||||
Initialized = -1,
|
|
||||||
Loading = 0,
|
|
||||||
Error = 1,
|
|
||||||
Loaded = 2,
|
|
||||||
Warning = 3
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
export enum DispatcherStatusID {
|
|
||||||
Unknown = 'unknown',
|
|
||||||
Outdated = 'outdated',
|
|
||||||
Unauthorized = 'not-signed',
|
|
||||||
OnlineNoLimit = 'no-limit',
|
|
||||||
Afk = 'brb',
|
|
||||||
Ending = 'ending',
|
|
||||||
NoSpace = 'no-space',
|
|
||||||
Unavailable = 'unavailable',
|
|
||||||
OnlineWithHours = 'online'
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
export const enum JournalFilterType {
|
|
||||||
ACTIVE = 'active',
|
|
||||||
FULFILLED = 'fulfilled',
|
|
||||||
ABANDONED = 'abandoned',
|
|
||||||
ALL = 'all',
|
|
||||||
TWR = 'twr',
|
|
||||||
SKR = 'skr',
|
|
||||||
TWR_SKR = 'twr-skr'
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum JournalFilterSection {
|
|
||||||
TIMETABLE_STATUS = 'timetable-status',
|
|
||||||
TWRSKR = 'twrskr'
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
export enum TrainFilterSection {
|
|
||||||
TRAIN_TYPE = 'TRAIN_TYPE',
|
|
||||||
TIMETABLE_TYPE = 'TIMETABLE_TYPE',
|
|
||||||
COMMENTS = 'COMMENTS',
|
|
||||||
TIMETABLE = 'TIMETABLE'
|
|
||||||
}
|
|
||||||
|
|
||||||
export const enum TrainFilterType {
|
|
||||||
noComments = 'noComments',
|
|
||||||
withComments = 'withComments',
|
|
||||||
|
|
||||||
twr = 'twr',
|
|
||||||
skr = 'skr',
|
|
||||||
common = 'common',
|
|
||||||
|
|
||||||
passenger = 'passenger',
|
|
||||||
freight = 'freight',
|
|
||||||
other = 'other',
|
|
||||||
noTimetable = 'noTimetable',
|
|
||||||
withTimetable = 'withTimetable'
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
export default interface FilterOption {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
value: boolean;
|
|
||||||
defaultValue: boolean;
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
interface Scenery {
|
|
||||||
stationName: string;
|
|
||||||
stationURL: string;
|
|
||||||
stationLines: string;
|
|
||||||
stationProject: string;
|
|
||||||
|
|
||||||
reqLevel: string;
|
|
||||||
supportersOnly: string;
|
|
||||||
signalType: string;
|
|
||||||
controlType: string;
|
|
||||||
SBL: string;
|
|
||||||
twoWayBlock: string;
|
|
||||||
|
|
||||||
routesOneWayCatenary: number;
|
|
||||||
routesOneWayOther: number;
|
|
||||||
routesTwoWayCatenary: number;
|
|
||||||
routesToWayOther: number;
|
|
||||||
|
|
||||||
default: boolean;
|
|
||||||
nonPublic: boolean;
|
|
||||||
unavailable: boolean;
|
|
||||||
hasData: boolean;
|
|
||||||
|
|
||||||
stops: string[];
|
|
||||||
checkpoints: string[];
|
|
||||||
|
|
||||||
currentDispatcher: string;
|
|
||||||
currentDispatcherId: number;
|
|
||||||
currentDispatcherFrom: number;
|
|
||||||
dispatcherHistory: {
|
|
||||||
dispatcherName: string;
|
|
||||||
dispatcherId: number;
|
|
||||||
dispatcherFrom: number;
|
|
||||||
dispatcherTo: number;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Scenery;
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import TrainStop from './TrainStop';
|
|
||||||
|
|
||||||
export enum StopStatus {
|
|
||||||
'arriving' = 'arriving',
|
|
||||||
'departed' = 'departed',
|
|
||||||
'departed-away' = 'departed-away',
|
|
||||||
'online' = 'online',
|
|
||||||
'stopped' = 'stopped',
|
|
||||||
'terminated' = 'terminated'
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ScheduledTrain {
|
|
||||||
checkpointName: string;
|
|
||||||
|
|
||||||
trainId: string;
|
|
||||||
trainNo: number;
|
|
||||||
|
|
||||||
driverName: string;
|
|
||||||
driverId: number;
|
|
||||||
currentStationName: string;
|
|
||||||
currentStationHash: string;
|
|
||||||
category: string;
|
|
||||||
stopInfo: TrainStop;
|
|
||||||
|
|
||||||
terminatesAt: string;
|
|
||||||
beginsAt: string;
|
|
||||||
|
|
||||||
prevStationName: string;
|
|
||||||
nextStationName: string;
|
|
||||||
|
|
||||||
arrivingLine: string | null;
|
|
||||||
departureLine: string | null;
|
|
||||||
|
|
||||||
prevDepartureLine: string | null;
|
|
||||||
nextArrivalLine: string | null;
|
|
||||||
|
|
||||||
signal: string;
|
|
||||||
connectedTrack: string;
|
|
||||||
|
|
||||||
stopLabel: string;
|
|
||||||
stopStatus: StopStatus;
|
|
||||||
stopStatusID: number;
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Availability, OnlineScenery } from './store/storeTypes';
|
import { Availability, OnlineScenery, ScheduledTrain } from '../../store/typings';
|
||||||
import { ScheduledTrain } from './ScheduledTrain';
|
|
||||||
import StationRoutes from './StationRoutes';
|
import StationRoutes from './StationRoutes';
|
||||||
|
|
||||||
export default interface Station {
|
export default interface Station {
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
import { DataStatus } from '../enums/DataStatus';
|
|
||||||
import Station from './Station';
|
|
||||||
import Train from './Train';
|
|
||||||
|
|
||||||
export interface StoreData {
|
|
||||||
stationList: Station[];
|
|
||||||
trainList: Train[];
|
|
||||||
dispatcherCount: number;
|
|
||||||
|
|
||||||
sceneryDataStatus: DataStatus;
|
|
||||||
dispatcherDataStatus: DataStatus;
|
|
||||||
trainsDataStatus: DataStatus;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import TrainStop from './TrainStop';
|
|
||||||
|
|
||||||
export default interface Timetable {
|
|
||||||
trainNo: number;
|
|
||||||
|
|
||||||
success: boolean;
|
|
||||||
|
|
||||||
data?: {
|
|
||||||
trainNo: number;
|
|
||||||
driverName: string;
|
|
||||||
driverId: number;
|
|
||||||
currentStationName: string;
|
|
||||||
currentStationHash: string;
|
|
||||||
timetableId: number;
|
|
||||||
category: string;
|
|
||||||
route: string;
|
|
||||||
TWR: boolean;
|
|
||||||
SKR: boolean;
|
|
||||||
routeDistance: number;
|
|
||||||
followingStops: TrainStop[];
|
|
||||||
followingSceneries: string[];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import TrainStop from './TrainStop';
|
import { TrainStop } from '../../store/typings';
|
||||||
|
|
||||||
export default interface Train {
|
export default interface Train {
|
||||||
trainId: string;
|
trainId: string;
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
export default interface TrainStop {
|
|
||||||
stopName: string;
|
|
||||||
stopNameRAW: string;
|
|
||||||
stopType: string;
|
|
||||||
stopDistance: number;
|
|
||||||
mainStop: boolean;
|
|
||||||
|
|
||||||
arrivalLine: string | null;
|
|
||||||
// arrivalTimeString: string | null;
|
|
||||||
arrivalTimestamp: number;
|
|
||||||
// arrivalRealTimeString: string | null;
|
|
||||||
arrivalRealTimestamp: number;
|
|
||||||
arrivalDelay: number;
|
|
||||||
|
|
||||||
departureLine: string | null;
|
|
||||||
// departureTimeString: string | null;
|
|
||||||
departureTimestamp: number;
|
|
||||||
// departureRealTimeString: string | null;
|
|
||||||
departureRealTimestamp: number;
|
|
||||||
departureDelay: number;
|
|
||||||
pointId: number;
|
|
||||||
|
|
||||||
comments?: any;
|
|
||||||
|
|
||||||
beginsHere: boolean;
|
|
||||||
terminatesHere: boolean;
|
|
||||||
confirmed: boolean;
|
|
||||||
stopped: boolean;
|
|
||||||
stopTime: number | null;
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import { TrainFilterSection, TrainFilterType } from '../../enums/TrainFilterType';
|
|
||||||
|
|
||||||
export interface TrainFilter {
|
|
||||||
id: TrainFilterType;
|
|
||||||
section: TrainFilterSection;
|
|
||||||
isActive: boolean;
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
export interface Sum {
|
|
||||||
routeDistance: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Max {
|
|
||||||
routeDistance: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Min {
|
|
||||||
routeDistance: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Avg {
|
|
||||||
routeDistance: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Count {
|
|
||||||
_all: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DispatcherStatsAPIData {
|
|
||||||
_sum: Sum;
|
|
||||||
_max: Max;
|
|
||||||
_min: Min;
|
|
||||||
_avg: Avg;
|
|
||||||
_count: Count;
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
export interface DispatcherHistory {
|
|
||||||
id: string;
|
|
||||||
|
|
||||||
currentDuration: number;
|
|
||||||
dispatcherId: number;
|
|
||||||
dispatcherName: string;
|
|
||||||
dispatcherLevel: number | null;
|
|
||||||
dispatcherRate: number;
|
|
||||||
dispatcherIsSupporter: boolean;
|
|
||||||
dispatcherStatus?: number;
|
|
||||||
isOnline: boolean;
|
|
||||||
lastOnlineTimestamp: number;
|
|
||||||
region: string;
|
|
||||||
stationHash: string;
|
|
||||||
stationName: string;
|
|
||||||
timestampFrom: number;
|
|
||||||
timestampTo?: number;
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
export interface Sum {
|
|
||||||
routeDistance: number;
|
|
||||||
confirmedStopsCount: number;
|
|
||||||
allStopsCount: number;
|
|
||||||
currentDistance: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Count {
|
|
||||||
fulfilled: number;
|
|
||||||
terminated: number;
|
|
||||||
_all: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Max {
|
|
||||||
routeDistance: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Avg {
|
|
||||||
routeDistance: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DriverStatsAPIData {
|
|
||||||
_sum: Sum;
|
|
||||||
_count: Count;
|
|
||||||
_max: Max;
|
|
||||||
_avg: Avg;
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
export default interface StationAPIData {
|
|
||||||
dispatcherId: number;
|
|
||||||
dispatcherName: string;
|
|
||||||
dispatcherIsSupporter: boolean;
|
|
||||||
stationName: string;
|
|
||||||
stationHash: string;
|
|
||||||
region: string;
|
|
||||||
maxUsers: number;
|
|
||||||
currentUsers: number;
|
|
||||||
spawn: number;
|
|
||||||
lastSeen: number;
|
|
||||||
dispatcherExp: number;
|
|
||||||
nameFromHeader: string;
|
|
||||||
spawnString: string | null;
|
|
||||||
networkConnectionString: string;
|
|
||||||
isOnline: number;
|
|
||||||
dispatcherRate: number;
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import { TimetableHistory } from './TimetablesAPIData';
|
|
||||||
|
|
||||||
export interface ITimetablesDailyStats {
|
|
||||||
totalTimetables: number;
|
|
||||||
distanceSum: number;
|
|
||||||
distanceAvg: number;
|
|
||||||
|
|
||||||
timetableId: number;
|
|
||||||
timetableAuthor: string;
|
|
||||||
timetableDriver: string;
|
|
||||||
timetableRouteDistance: number;
|
|
||||||
|
|
||||||
mostActiveDispatchers: {
|
|
||||||
name: string;
|
|
||||||
count: number;
|
|
||||||
}[];
|
|
||||||
|
|
||||||
mostActiveDrivers: {
|
|
||||||
name: string;
|
|
||||||
distance: number;
|
|
||||||
}[];
|
|
||||||
|
|
||||||
longestDuties: {
|
|
||||||
name: string;
|
|
||||||
duration: number;
|
|
||||||
station: string;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ITimetablesDailyStatsResponse {
|
|
||||||
totalTimetables: number;
|
|
||||||
distanceSum: number;
|
|
||||||
distanceAvg: number;
|
|
||||||
maxTimetable: TimetableHistory | null;
|
|
||||||
|
|
||||||
mostActiveDispatchers: {
|
|
||||||
name: string;
|
|
||||||
count: number;
|
|
||||||
}[];
|
|
||||||
|
|
||||||
mostActiveDrivers: {
|
|
||||||
name: string;
|
|
||||||
distance: number;
|
|
||||||
}[];
|
|
||||||
|
|
||||||
longestDuties: {
|
|
||||||
name: string;
|
|
||||||
duration: number;
|
|
||||||
station: string;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
export interface TimetableHistory {
|
|
||||||
id: number;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
|
|
||||||
timetableId: number;
|
|
||||||
trainNo: number;
|
|
||||||
trainCategoryCode: string;
|
|
||||||
|
|
||||||
driverId: number;
|
|
||||||
driverName: string;
|
|
||||||
driverLevel: number | null;
|
|
||||||
driverIsSupporter: boolean;
|
|
||||||
|
|
||||||
route: string;
|
|
||||||
twr: number;
|
|
||||||
skr: number;
|
|
||||||
sceneriesString: string;
|
|
||||||
currentLocation: string[];
|
|
||||||
|
|
||||||
routeDistance: number;
|
|
||||||
currentDistance: number;
|
|
||||||
|
|
||||||
confirmedStopsCount: number;
|
|
||||||
allStopsCount: number;
|
|
||||||
|
|
||||||
beginDate: string;
|
|
||||||
endDate: string;
|
|
||||||
|
|
||||||
scheduledBeginDate: string;
|
|
||||||
scheduledEndDate: string;
|
|
||||||
|
|
||||||
terminated: boolean;
|
|
||||||
fulfilled: boolean;
|
|
||||||
|
|
||||||
authorName?: string;
|
|
||||||
authorId?: number;
|
|
||||||
|
|
||||||
stopsString?: string;
|
|
||||||
|
|
||||||
stockString?: string;
|
|
||||||
stockHistory: string[];
|
|
||||||
|
|
||||||
stockMass?: number;
|
|
||||||
stockLength?: number;
|
|
||||||
maxSpeed?: number;
|
|
||||||
|
|
||||||
hashesString?: string;
|
|
||||||
currentSceneryName?: string;
|
|
||||||
currentSceneryHash?: string;
|
|
||||||
|
|
||||||
routeSceneries?: string;
|
|
||||||
|
|
||||||
checkpointArrivals?: string[];
|
|
||||||
checkpointDepartures?: string[];
|
|
||||||
|
|
||||||
checkpointArrivalsScheduled?: string[];
|
|
||||||
checkpointDeparturesScheduled?: string[];
|
|
||||||
|
|
||||||
checkpointStopTypes?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SceneryTimetableHistory {
|
|
||||||
timetables: TimetableHistory[];
|
|
||||||
// totalCount: number;
|
|
||||||
// sceneryName: string;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { JournalTimetableSorter } from '../../types/JournalTimetablesTypes';
|
|
||||||
|
|
||||||
export interface TimetablesQueryParams {
|
|
||||||
driverName?: string;
|
|
||||||
trainNo?: string;
|
|
||||||
timetableId?: string;
|
|
||||||
|
|
||||||
authorName?: string;
|
|
||||||
timestampFrom?: number;
|
|
||||||
timestampTo?: number;
|
|
||||||
issuedFrom?: string;
|
|
||||||
|
|
||||||
countFrom?: number;
|
|
||||||
countLimit?: number;
|
|
||||||
|
|
||||||
fulfilled?: number;
|
|
||||||
terminated?: number;
|
|
||||||
|
|
||||||
twr?: number;
|
|
||||||
skr?: number;
|
|
||||||
|
|
||||||
sortBy?: JournalTimetableSorter['id'];
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
export interface TimetableStop {
|
|
||||||
stopName: string;
|
|
||||||
stopNameRAW: string;
|
|
||||||
stopType: string;
|
|
||||||
stopDistance: number;
|
|
||||||
pointId: number;
|
|
||||||
|
|
||||||
mainStop: boolean;
|
|
||||||
|
|
||||||
arrivalLine: string;
|
|
||||||
arrivalTimestamp: number;
|
|
||||||
arrivalRealTimestamp: number;
|
|
||||||
arrivalDelay: number;
|
|
||||||
|
|
||||||
departureLine: string;
|
|
||||||
departureTimestamp: number;
|
|
||||||
departureRealTimestamp: number;
|
|
||||||
departureDelay: number;
|
|
||||||
|
|
||||||
comments?: any;
|
|
||||||
|
|
||||||
beginsHere: boolean;
|
|
||||||
terminatesHere: boolean;
|
|
||||||
confirmed: boolean;
|
|
||||||
stopped: boolean;
|
|
||||||
stopTime: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TrainTimetable {
|
|
||||||
timetableId: number;
|
|
||||||
category: string;
|
|
||||||
route: string;
|
|
||||||
|
|
||||||
stopList: TimetableStop[];
|
|
||||||
|
|
||||||
TWR: boolean;
|
|
||||||
SKR: boolean;
|
|
||||||
sceneries: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TrainAPIData {
|
|
||||||
trainNo: number;
|
|
||||||
|
|
||||||
mass: number;
|
|
||||||
length: number;
|
|
||||||
speed: number;
|
|
||||||
stockString: string;
|
|
||||||
|
|
||||||
signal: string;
|
|
||||||
distance: number;
|
|
||||||
connectedTrack: string;
|
|
||||||
|
|
||||||
driverName: string;
|
|
||||||
driverId: number;
|
|
||||||
driverIsSupporter: boolean;
|
|
||||||
driverLevel?: number;
|
|
||||||
|
|
||||||
currentStationName: string;
|
|
||||||
currentStationHash: string;
|
|
||||||
|
|
||||||
online: boolean;
|
|
||||||
lastSeen: number;
|
|
||||||
|
|
||||||
region: string;
|
|
||||||
isTimeout: boolean;
|
|
||||||
|
|
||||||
timetable?: TrainTimetable;
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
export interface Author {
|
|
||||||
login: string;
|
|
||||||
id: number;
|
|
||||||
node_id: string;
|
|
||||||
avatar_url: string;
|
|
||||||
gravatar_id: string;
|
|
||||||
url: string;
|
|
||||||
html_url: string;
|
|
||||||
followers_url: string;
|
|
||||||
following_url: string;
|
|
||||||
gists_url: string;
|
|
||||||
starred_url: string;
|
|
||||||
subscriptions_url: string;
|
|
||||||
organizations_url: string;
|
|
||||||
repos_url: string;
|
|
||||||
events_url: string;
|
|
||||||
received_events_url: string;
|
|
||||||
type: string;
|
|
||||||
site_admin: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReleaseAPIData {
|
|
||||||
url: string;
|
|
||||||
assets_url: string;
|
|
||||||
upload_url: string;
|
|
||||||
html_url: string;
|
|
||||||
id: number;
|
|
||||||
author: Author;
|
|
||||||
node_id: string;
|
|
||||||
tag_name: string;
|
|
||||||
target_commitish: string;
|
|
||||||
name: string;
|
|
||||||
draft: boolean;
|
|
||||||
prerelease: boolean;
|
|
||||||
created_at: Date;
|
|
||||||
published_at: Date;
|
|
||||||
assets: any[];
|
|
||||||
tarball_url: string;
|
|
||||||
zipball_url: string;
|
|
||||||
body: string;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
export interface RollingStockGithubData {
|
|
||||||
usage: Record<string, string>;
|
|
||||||
info: RollingStockInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RollingStockInfo {
|
|
||||||
'loco-e': [string, string, string, string, boolean][];
|
|
||||||
'loco-s': [string, string, string, string, boolean][];
|
|
||||||
'loco-szt': [string, string, string, string, boolean][];
|
|
||||||
'loco-ezt': [string, string, string, string, boolean][];
|
|
||||||
'car-passenger': [string, string, boolean, boolean, string][];
|
|
||||||
'car-cargo': [string, string, boolean, boolean, string][];
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
import { Socket } from 'socket.io-client';
|
|
||||||
import { DataStatus } from '../../enums/DataStatus';
|
|
||||||
import StationAPIData from '../api/StationAPIData';
|
|
||||||
import { TrainAPIData } from '../api/TrainAPIData';
|
|
||||||
import { DispatcherStatsAPIData } from '../api/DispatcherStatsAPIData';
|
|
||||||
import { DriverStatsAPIData } from '../api/DriverStatsAPIData';
|
|
||||||
import { RollingStockGithubData } from '../github_api/StockInfoGithubData';
|
|
||||||
import Station from '../Station';
|
|
||||||
import { ScheduledTrain } from '../ScheduledTrain';
|
|
||||||
import { DispatcherStatusID } from '../../enums/DispatcherStatus';
|
|
||||||
|
|
||||||
export type Availability = 'default' | 'unavailable' | 'nonPublic' | 'abandoned' | 'nonDefault';
|
|
||||||
|
|
||||||
export interface StoreState {
|
|
||||||
stationList: Station[];
|
|
||||||
apiData: APIData;
|
|
||||||
rollingStockData?: RollingStockGithubData;
|
|
||||||
|
|
||||||
lastDispatcherStatuses: { hash: string; statusTimestamp: number; statusID: DispatcherStatusID }[];
|
|
||||||
|
|
||||||
sceneryData: any[][];
|
|
||||||
|
|
||||||
region: { id: string; value: string };
|
|
||||||
trainCount: number;
|
|
||||||
stationCount: number;
|
|
||||||
|
|
||||||
webSocket?: Socket;
|
|
||||||
isOffline: boolean;
|
|
||||||
|
|
||||||
dispatcherStatsName: string;
|
|
||||||
dispatcherStatsData?: DispatcherStatsAPIData;
|
|
||||||
|
|
||||||
driverStatsName: string;
|
|
||||||
driverStatsData?: DriverStatsAPIData;
|
|
||||||
driverStatsStatus: DataStatus;
|
|
||||||
|
|
||||||
chosenModalTrainId?: string;
|
|
||||||
|
|
||||||
currentStatsTab: 'daily' | 'driver' | null;
|
|
||||||
|
|
||||||
dataStatuses: {
|
|
||||||
connection: DataStatus;
|
|
||||||
sceneries: DataStatus;
|
|
||||||
timetables: DataStatus;
|
|
||||||
dispatchers: DataStatus;
|
|
||||||
trains: DataStatus;
|
|
||||||
};
|
|
||||||
|
|
||||||
listenerLaunched: boolean;
|
|
||||||
blockScroll: boolean;
|
|
||||||
modalLastClickedTarget: EventTarget | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface APIData {
|
|
||||||
stations?: StationAPIData[];
|
|
||||||
dispatchers?: string[][];
|
|
||||||
trains?: TrainAPIData[];
|
|
||||||
connectedSocketCount: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StationRoutesInfo {
|
|
||||||
routeName: string;
|
|
||||||
isElectric: boolean;
|
|
||||||
isInternal: boolean;
|
|
||||||
isRouteSBL: boolean;
|
|
||||||
routeLength: number;
|
|
||||||
routeSpeed: number;
|
|
||||||
routeTracks: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StationJSONData {
|
|
||||||
name: string;
|
|
||||||
abbr: string;
|
|
||||||
url: string;
|
|
||||||
lines: string;
|
|
||||||
project: string;
|
|
||||||
projectUrl: string;
|
|
||||||
|
|
||||||
reqLevel: number;
|
|
||||||
|
|
||||||
signalType: string;
|
|
||||||
controlType: string;
|
|
||||||
|
|
||||||
SUP: boolean;
|
|
||||||
|
|
||||||
// routes: string;
|
|
||||||
routesInfo: StationRoutesInfo[];
|
|
||||||
|
|
||||||
checkpoints: string | null;
|
|
||||||
authors?: string;
|
|
||||||
|
|
||||||
availability: Availability;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StationTrain {
|
|
||||||
driverName: string;
|
|
||||||
driverId: number;
|
|
||||||
trainNo: number;
|
|
||||||
trainId: string;
|
|
||||||
stopStatus: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OnlineScenery {
|
|
||||||
name: string;
|
|
||||||
hash: string;
|
|
||||||
region: string;
|
|
||||||
maxUsers: number;
|
|
||||||
currentUsers: number;
|
|
||||||
spawns: { spawnName: string; spawnLength: number; isElectrified: boolean }[];
|
|
||||||
dispatcherName: string;
|
|
||||||
dispatcherRate: number;
|
|
||||||
dispatcherId: number;
|
|
||||||
dispatcherExp: number;
|
|
||||||
dispatcherIsSupporter: boolean;
|
|
||||||
|
|
||||||
statusTimestamp: number;
|
|
||||||
statusID: DispatcherStatusID;
|
|
||||||
|
|
||||||
isOnline: boolean;
|
|
||||||
|
|
||||||
stationTrains?: StationTrain[];
|
|
||||||
scheduledTrains?: ScheduledTrain[];
|
|
||||||
|
|
||||||
scheduledTrainCount: {
|
|
||||||
all: number;
|
|
||||||
confirmed: number;
|
|
||||||
unconfirmed: number;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
export type JournalDispatcherSearcher = {
|
|
||||||
[key in 'search-dispatcher' | 'search-station' | 'search-date']: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface JournalDispatcherSorter {
|
|
||||||
id: 'timestampFrom' | 'duration';
|
|
||||||
dir: -1 | 1;
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import { JournalFilterType } from '../../scripts/enums/JournalFilterType';
|
|
||||||
|
|
||||||
export type JournalTimetableSearchKey =
|
|
||||||
| 'search-driver'
|
|
||||||
| 'search-train'
|
|
||||||
| 'search-date'
|
|
||||||
| 'search-dispatcher'
|
|
||||||
| 'search-issuedFrom';
|
|
||||||
|
|
||||||
export type JournalTimetableSorterKey = 'timetableId' | 'beginDate' | 'distance' | 'total-stops';
|
|
||||||
|
|
||||||
export type JournalTimetableSearchType = {
|
|
||||||
[key in JournalTimetableSearchKey]: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface JournalFilter {
|
|
||||||
id: JournalFilterType;
|
|
||||||
filterSection: string;
|
|
||||||
isActive: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface JournalTimetableSorter {
|
|
||||||
id: JournalTimetableSorterKey;
|
|
||||||
dir: 'asc' | 'desc';
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { Filter } from '../../components/StationsView/typings';
|
||||||
|
import { Status } from '../../typings/common';
|
||||||
import { HeadIdsTypes } from '../data/stationHeaderNames';
|
import { HeadIdsTypes } from '../data/stationHeaderNames';
|
||||||
import { DispatcherStatusID } from '../enums/DispatcherStatus';
|
|
||||||
import Filter from '../interfaces/Filter';
|
|
||||||
import Station from '../interfaces/Station';
|
import Station from '../interfaces/Station';
|
||||||
|
|
||||||
export const sortStations = (
|
export const sortStations = (
|
||||||
@@ -19,7 +19,7 @@ export const sortStations = (
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'status':
|
case 'status':
|
||||||
diff = (a.onlineInfo?.statusTimestamp || 0) - (b.onlineInfo?.statusTimestamp || 0);
|
diff = (a.onlineInfo?.dispatcherStatus || 0) - (b.onlineInfo?.dispatcherStatus || 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'dispatcher':
|
case 'dispatcher':
|
||||||
@@ -81,27 +81,28 @@ export const filterStations = (station: Station, filters: Filter) => {
|
|||||||
if (!station.onlineInfo && filters['free']) return false;
|
if (!station.onlineInfo && filters['free']) return false;
|
||||||
|
|
||||||
if (station.onlineInfo) {
|
if (station.onlineInfo) {
|
||||||
const { statusID, statusTimestamp } = station.onlineInfo;
|
const { dispatcherStatus } = station.onlineInfo;
|
||||||
|
|
||||||
const isEnding = statusID == DispatcherStatusID.Ending && filters['endingStatus'];
|
const isEnding = dispatcherStatus == Status.ActiveDispatcher.ENDING && filters['endingStatus'];
|
||||||
|
|
||||||
const isNotSigned =
|
const isNotSigned =
|
||||||
(statusID == 'not-signed' || statusID == 'unavailable') && filters['unavailableStatus'];
|
(dispatcherStatus == Status.ActiveDispatcher.NOT_LOGGED_IN ||
|
||||||
|
dispatcherStatus == Status.ActiveDispatcher.UNAVAILABLE) &&
|
||||||
|
filters['unavailableStatus'];
|
||||||
|
|
||||||
const isAFK = statusID == 'brb' && filters['afkStatus'];
|
const isAFK = dispatcherStatus == Status.ActiveDispatcher.AFK && filters['afkStatus'];
|
||||||
|
|
||||||
const isNoSpace = statusID == 'no-space' && filters['noSpaceStatus'];
|
const isNoSpace =
|
||||||
|
dispatcherStatus == Status.ActiveDispatcher.NO_SPACE && filters['noSpaceStatus'];
|
||||||
|
|
||||||
const isOccupied = station.onlineInfo && filters['occupied'];
|
const isOccupied = station.onlineInfo && filters['occupied'];
|
||||||
|
|
||||||
const isOnlineInBounds =
|
if (isEnding || isNotSigned || isAFK || isNoSpace || isOccupied) return false;
|
||||||
(filters['onlineFromHours'] < 8 &&
|
|
||||||
statusTimestamp > 0 &&
|
|
||||||
statusTimestamp <= Date.now() + filters['onlineFromHours'] * 3600000) ||
|
|
||||||
(filters['onlineFromHours'] > 0 && statusTimestamp <= 0) ||
|
|
||||||
(filters['onlineFromHours'] == 8 && statusID != 'no-limit');
|
|
||||||
|
|
||||||
if (isEnding || isOnlineInBounds || isNotSigned || isAFK || isNoSpace || isOccupied)
|
if (
|
||||||
|
filters['onlineFromHours'] > 0 &&
|
||||||
|
dispatcherStatus <= Date.now() + filters['onlineFromHours'] * 3600000
|
||||||
|
)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,25 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { io } from 'socket.io-client';
|
import { io } from 'socket.io-client';
|
||||||
import { DataStatus } from '../scripts/enums/DataStatus';
|
|
||||||
import StationRoutes from '../scripts/interfaces/StationRoutes';
|
import StationRoutes from '../scripts/interfaces/StationRoutes';
|
||||||
import Train from '../scripts/interfaces/Train';
|
import Train from '../scripts/interfaces/Train';
|
||||||
import { URLs } from '../scripts/utils/apiURLs';
|
import { URLs } from '../scripts/utils/apiURLs';
|
||||||
import {
|
import { parseSpawns, getScheduledTrains, getStationTrains } from './utils';
|
||||||
getDispatcherStatus,
|
|
||||||
parseSpawns,
|
|
||||||
getScheduledTrains,
|
|
||||||
getStationTrains
|
|
||||||
} from '../scripts/utils/storeUtils';
|
|
||||||
|
|
||||||
import {
|
import { OnlineScenery, ScheduledTrain, StationJSONData, StoreState } from './typings';
|
||||||
APIData,
|
|
||||||
OnlineScenery,
|
|
||||||
StationJSONData,
|
|
||||||
StoreState
|
|
||||||
} from '../scripts/interfaces/store/storeTypes';
|
|
||||||
|
|
||||||
import packageInfo from '../../package.json';
|
import packageInfo from '../../package.json';
|
||||||
import { RollingStockGithubData } from '../scripts/interfaces/github_api/StockInfoGithubData';
|
import { Websocket, API } from '../typings/api';
|
||||||
import { ScheduledTrain } from '../scripts/interfaces/ScheduledTrain';
|
import { Status } from '../typings/common';
|
||||||
import { DispatcherStatusID } from '../scripts/enums/DispatcherStatus';
|
|
||||||
|
|
||||||
export const useStore = defineStore('store', {
|
export const useStore = defineStore('store', {
|
||||||
state: () =>
|
state: () =>
|
||||||
({
|
({
|
||||||
apiData: {} as unknown,
|
activeData: {} as unknown,
|
||||||
rollingStockData: undefined,
|
rollingStockData: undefined,
|
||||||
|
|
||||||
stationList: [],
|
stationList: [],
|
||||||
|
regionOnlineCounters: [],
|
||||||
|
|
||||||
routesList: [],
|
routesList: [],
|
||||||
|
|
||||||
@@ -50,16 +39,16 @@ export const useStore = defineStore('store', {
|
|||||||
|
|
||||||
driverStatsName: '',
|
driverStatsName: '',
|
||||||
driverStatsData: undefined,
|
driverStatsData: undefined,
|
||||||
driverStatsStatus: DataStatus.Initialized,
|
driverStatsStatus: Status.Data.Initialized,
|
||||||
|
|
||||||
chosenModalTrainId: undefined,
|
chosenModalTrainId: undefined,
|
||||||
|
|
||||||
dataStatuses: {
|
dataStatuses: {
|
||||||
connection: DataStatus.Loading,
|
connection: Status.Data.Loading,
|
||||||
sceneries: DataStatus.Loading,
|
sceneries: Status.Data.Loading,
|
||||||
timetables: DataStatus.Loading,
|
timetables: Status.Data.Loading,
|
||||||
dispatchers: DataStatus.Loading,
|
dispatchers: Status.Data.Loading,
|
||||||
trains: DataStatus.Loading
|
trains: Status.Data.Loading
|
||||||
},
|
},
|
||||||
|
|
||||||
currentStatsTab: null,
|
currentStatsTab: null,
|
||||||
@@ -71,12 +60,8 @@ export const useStore = defineStore('store', {
|
|||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
trainList(): Train[] {
|
trainList(): Train[] {
|
||||||
return (this.apiData?.trains ?? [])
|
return (this.activeData?.trains ?? [])
|
||||||
.filter(
|
.filter((train) => train.timetable || train.online)
|
||||||
(train) =>
|
|
||||||
train.region === this.region.id &&
|
|
||||||
(train.online || train.timetable || train.lastSeen > Date.now() - 180000)
|
|
||||||
)
|
|
||||||
.map((train) => {
|
.map((train) => {
|
||||||
const stock = train.stockString.split(';');
|
const stock = train.stockString.split(';');
|
||||||
const locoType = stock ? stock[0] : train.stockString;
|
const locoType = stock ? stock[0] : train.stockString;
|
||||||
@@ -127,75 +112,59 @@ export const useStore = defineStore('store', {
|
|||||||
|
|
||||||
onlineSceneryList(state): OnlineScenery[] {
|
onlineSceneryList(state): OnlineScenery[] {
|
||||||
if (state.isOffline) return [];
|
if (state.isOffline) return [];
|
||||||
if (!state.apiData?.stations) return [];
|
if (!state.activeData?.activeSceneries) return [];
|
||||||
|
|
||||||
return (
|
return state.activeData?.activeSceneries.reduce((list, scenery) => {
|
||||||
state.apiData?.stations
|
if (scenery.isOnline !== 1 && Date.now() - scenery.lastSeen > 1000 * 60 * 2) return list;
|
||||||
// ?.filter((apiStation) => apiStation.region == state.region.id)
|
if (scenery.dispatcherStatus == Status.ActiveDispatcher.UNKNOWN) return list;
|
||||||
.reduce((list, apiStation) => {
|
|
||||||
if (apiStation.region != state.region.id) return list;
|
|
||||||
|
|
||||||
if (apiStation.isOnline !== 1 && Date.now() - apiStation.lastSeen > 1000 * 60 * 3)
|
const station = this.stationList.find((s) => s.name === scenery.stationName);
|
||||||
return list;
|
|
||||||
|
|
||||||
const dispatcherStatus = getDispatcherStatus(state as StoreState, apiStation);
|
const scheduledTrains = getScheduledTrains(this.trainList, scenery, station?.generalInfo);
|
||||||
|
|
||||||
if (dispatcherStatus.statusID == DispatcherStatusID.Unknown) return list;
|
const stationTrains = getStationTrains(
|
||||||
|
this.trainList,
|
||||||
|
scheduledTrains,
|
||||||
|
this.region.id,
|
||||||
|
scenery
|
||||||
|
);
|
||||||
|
|
||||||
const station = this.stationList.find((s) => s.name === apiStation.stationName);
|
// Remove checkpoint duplicates
|
||||||
|
const uniqueScheduledTrains = scheduledTrains.reduce(
|
||||||
|
(uniqueList, sTrain) =>
|
||||||
|
uniqueList.find((v) => v.trainId === sTrain.trainId)
|
||||||
|
? uniqueList
|
||||||
|
: [...uniqueList, sTrain],
|
||||||
|
[] as ScheduledTrain[]
|
||||||
|
);
|
||||||
|
|
||||||
const scheduledTrains = getScheduledTrains(
|
list.push({
|
||||||
this.trainList,
|
name: scenery.stationName,
|
||||||
apiStation,
|
hash: scenery.stationHash,
|
||||||
station?.generalInfo
|
region: scenery.region,
|
||||||
);
|
maxUsers: scenery.maxUsers,
|
||||||
|
currentUsers: scenery.currentUsers,
|
||||||
|
spawns: parseSpawns(scenery.spawnString),
|
||||||
|
dispatcherName: scenery.dispatcherName,
|
||||||
|
dispatcherRate: scenery.dispatcherRate,
|
||||||
|
dispatcherId: scenery.dispatcherId,
|
||||||
|
dispatcherExp: scenery.dispatcherExp,
|
||||||
|
dispatcherIsSupporter: scenery.dispatcherIsSupporter,
|
||||||
|
scheduledTrains: scheduledTrains,
|
||||||
|
stationTrains: stationTrains,
|
||||||
|
dispatcherStatus: scenery.dispatcherStatus,
|
||||||
|
|
||||||
const stationTrains = getStationTrains(
|
isOnline: scenery.isOnline == 1,
|
||||||
this.trainList,
|
|
||||||
scheduledTrains,
|
|
||||||
this.region.id,
|
|
||||||
apiStation
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove checkpoint duplicates
|
scheduledTrainCount: {
|
||||||
const uniqueScheduledTrains = scheduledTrains.reduce(
|
all: uniqueScheduledTrains.length,
|
||||||
(uniqueList, sTrain) =>
|
confirmed: uniqueScheduledTrains.filter((train) => train.stopInfo.confirmed).length,
|
||||||
uniqueList.find((v) => v.trainId === sTrain.trainId)
|
unconfirmed: uniqueScheduledTrains.filter((train) => !train.stopInfo.confirmed).length
|
||||||
? uniqueList
|
}
|
||||||
: [...uniqueList, sTrain],
|
});
|
||||||
[] as ScheduledTrain[]
|
|
||||||
);
|
|
||||||
|
|
||||||
list.push({
|
return list;
|
||||||
name: apiStation.stationName,
|
}, [] as OnlineScenery[]);
|
||||||
hash: apiStation.stationHash,
|
|
||||||
region: apiStation.region,
|
|
||||||
maxUsers: apiStation.maxUsers,
|
|
||||||
currentUsers: apiStation.currentUsers,
|
|
||||||
spawns: parseSpawns(apiStation.spawnString),
|
|
||||||
dispatcherName: apiStation.dispatcherName,
|
|
||||||
dispatcherRate: apiStation.dispatcherRate,
|
|
||||||
dispatcherId: apiStation.dispatcherId,
|
|
||||||
dispatcherExp: apiStation.dispatcherExp,
|
|
||||||
dispatcherIsSupporter: apiStation.dispatcherIsSupporter,
|
|
||||||
scheduledTrains: scheduledTrains,
|
|
||||||
stationTrains: stationTrains,
|
|
||||||
statusTimestamp: dispatcherStatus.statusTimestamp,
|
|
||||||
statusID: dispatcherStatus.statusID,
|
|
||||||
|
|
||||||
isOnline: apiStation.isOnline == 1,
|
|
||||||
|
|
||||||
scheduledTrainCount: {
|
|
||||||
all: uniqueScheduledTrains.length,
|
|
||||||
confirmed: uniqueScheduledTrains.filter((train) => train.stopInfo.confirmed).length,
|
|
||||||
unconfirmed: uniqueScheduledTrains.filter((train) => !train.stopInfo.confirmed)
|
|
||||||
.length
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}, [] as OnlineScenery[])
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@@ -205,7 +174,7 @@ export const useStore = defineStore('store', {
|
|||||||
).data;
|
).data;
|
||||||
|
|
||||||
if (!sceneryData) {
|
if (!sceneryData) {
|
||||||
this.dataStatuses.sceneries = DataStatus.Error;
|
this.dataStatuses.sceneries = Status.Data.Error;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,8 +232,8 @@ export const useStore = defineStore('store', {
|
|||||||
async connectToWebsocket() {
|
async connectToWebsocket() {
|
||||||
if (import.meta.env.VITE_APP_WS_DEV === '1') {
|
if (import.meta.env.VITE_APP_WS_DEV === '1') {
|
||||||
const mockWebsocketData = await import('../data/mockWebsocketData.json');
|
const mockWebsocketData = await import('../data/mockWebsocketData.json');
|
||||||
this.dataStatuses.connection = DataStatus.Loaded;
|
this.dataStatuses.connection = Status.Data.Loaded;
|
||||||
this.apiData = mockWebsocketData as any;
|
this.activeData = mockWebsocketData as any;
|
||||||
this.setStatuses();
|
this.setStatuses();
|
||||||
|
|
||||||
console.warn('Stacjownik działa w trybie mockowania danych z WS');
|
console.warn('Stacjownik działa w trybie mockowania danych z WS');
|
||||||
@@ -281,18 +250,19 @@ export const useStore = defineStore('store', {
|
|||||||
socket.emit('CONNECTION', { version: packageInfo.version });
|
socket.emit('CONNECTION', { version: packageInfo.version });
|
||||||
|
|
||||||
socket.on('connect_error', () => {
|
socket.on('connect_error', () => {
|
||||||
this.dataStatuses.connection = DataStatus.Error;
|
this.dataStatuses.connection = Status.Data.Error;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('UPDATE', (data: APIData) => {
|
socket.on('UPDATE', (data: Websocket.ActiveData) => {
|
||||||
this.apiData = data;
|
this.activeData = data;
|
||||||
this.dataStatuses.connection = DataStatus.Loaded;
|
this.dataStatuses.connection = Status.Data.Loaded;
|
||||||
|
|
||||||
this.setStatuses();
|
this.setStatuses();
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.emit('FETCH_DATA', { version: packageInfo.version }, (data: APIData) => {
|
socket.emit('FETCH_DATA', { version: packageInfo.version }, (data: Websocket.ActiveData) => {
|
||||||
this.dataStatuses.connection = DataStatus.Loaded;
|
this.dataStatuses.connection = Status.Data.Loaded;
|
||||||
this.apiData = data;
|
this.activeData = data;
|
||||||
this.setStatuses();
|
this.setStatuses();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -312,7 +282,7 @@ export const useStore = defineStore('store', {
|
|||||||
async fetchStockInfoData() {
|
async fetchStockInfoData() {
|
||||||
try {
|
try {
|
||||||
this.rollingStockData = (
|
this.rollingStockData = (
|
||||||
await axios.get<RollingStockGithubData>(
|
await axios.get<API.RollingStock.Response>(
|
||||||
'https://raw.githubusercontent.com/Spythere/api/main/td2/data/stockInfo.json'
|
'https://raw.githubusercontent.com/Spythere/api/main/td2/data/stockInfo.json'
|
||||||
)
|
)
|
||||||
).data;
|
).data;
|
||||||
@@ -322,19 +292,17 @@ export const useStore = defineStore('store', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async setStatuses() {
|
async setStatuses() {
|
||||||
if (!this.apiData.stations) {
|
if (!this.activeData.activeSceneries) {
|
||||||
this.dataStatuses.sceneries = DataStatus.Error;
|
this.dataStatuses.sceneries = Status.Data.Error;
|
||||||
this.dataStatuses.trains = DataStatus.Error;
|
this.dataStatuses.trains = Status.Data.Error;
|
||||||
this.dataStatuses.dispatchers = DataStatus.Error;
|
this.dataStatuses.dispatchers = Status.Data.Error;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dataStatuses.sceneries = DataStatus.Loaded;
|
this.dataStatuses.sceneries = Status.Data.Loaded;
|
||||||
this.dataStatuses.trains = !this.apiData.trains ? DataStatus.Warning : DataStatus.Loaded;
|
this.dataStatuses.trains = !this.activeData.trains ? Status.Data.Warning : Status.Data.Loaded;
|
||||||
this.dataStatuses.dispatchers = !this.apiData.dispatchers
|
this.dataStatuses.dispatchers = Status.Data.Loaded;
|
||||||
? DataStatus.Warning
|
|
||||||
: DataStatus.Loaded;
|
|
||||||
|
|
||||||
// if (this.apiData.dispatchers != null) this.lastDispatcherStatuses = prevDispatcherStatuses;
|
// if (this.apiData.dispatchers != null) this.lastDispatcherStatuses = prevDispatcherStatuses;
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,58 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import inputData from '../data/options.json';
|
import inputData from '../data/options.json';
|
||||||
import StorageManager from '../scripts/managers/storageManager';
|
import { useStore } from './mainStore';
|
||||||
import { useStore } from './store';
|
|
||||||
import { filterInitStates } from '../scripts/constants/stores/initFilterStates';
|
|
||||||
import { filterStations, sortStations } from '../scripts/utils/filterUtils';
|
import { filterStations, sortStations } from '../scripts/utils/filterUtils';
|
||||||
import { HeadIdsTypes } from '../scripts/data/stationHeaderNames';
|
import { HeadIdsTypes } from '../scripts/data/stationHeaderNames';
|
||||||
|
import StorageManager from '../managers/storageManager';
|
||||||
|
import { Filter } from '../components/StationsView/typings';
|
||||||
|
|
||||||
|
const filterInitStates: Filter = {
|
||||||
|
default: false,
|
||||||
|
notDefault: false,
|
||||||
|
real: false,
|
||||||
|
fictional: false,
|
||||||
|
SPK: false,
|
||||||
|
SCS: false,
|
||||||
|
SPE: false,
|
||||||
|
SUP: false,
|
||||||
|
noSUP: false,
|
||||||
|
ręczne: false,
|
||||||
|
'ręczne+SPK': false,
|
||||||
|
'ręczne+SCS': false,
|
||||||
|
mechaniczne: false,
|
||||||
|
'mechaniczne+SPK': false,
|
||||||
|
'mechaniczne+SCS': false,
|
||||||
|
współczesna: false,
|
||||||
|
kształtowa: false,
|
||||||
|
historyczna: false,
|
||||||
|
mieszana: false,
|
||||||
|
SBL: false,
|
||||||
|
PBL: false,
|
||||||
|
minLevel: 0,
|
||||||
|
maxLevel: 20,
|
||||||
|
minOneWayCatenary: 0,
|
||||||
|
minOneWay: 0,
|
||||||
|
minTwoWayCatenary: 0,
|
||||||
|
minTwoWay: 0,
|
||||||
|
'include-selected': false,
|
||||||
|
'no-1track': false,
|
||||||
|
'no-2track': false,
|
||||||
|
free: true,
|
||||||
|
occupied: false,
|
||||||
|
ending: false,
|
||||||
|
nonPublic: false,
|
||||||
|
unavailable: true,
|
||||||
|
abandoned: true,
|
||||||
|
afkStatus: false,
|
||||||
|
endingStatus: false,
|
||||||
|
noSpaceStatus: false,
|
||||||
|
unavailableStatus: false,
|
||||||
|
unsignedStatus: false,
|
||||||
|
|
||||||
|
authors: '',
|
||||||
|
|
||||||
|
onlineFromHours: 0
|
||||||
|
};
|
||||||
|
|
||||||
export const useStationFiltersStore = defineStore('stationFiltersStore', {
|
export const useStationFiltersStore = defineStore('stationFiltersStore', {
|
||||||
state() {
|
state() {
|
||||||
@@ -26,7 +74,9 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', {
|
|||||||
return store.stationList
|
return store.stationList
|
||||||
.map((station) => ({
|
.map((station) => ({
|
||||||
...station,
|
...station,
|
||||||
onlineInfo: store.onlineSceneryList.find((os) => os.name == station.name)
|
onlineInfo: store.onlineSceneryList.find(
|
||||||
|
(os) => os.name == station.name && os.region == store.region.id
|
||||||
|
)
|
||||||
}))
|
}))
|
||||||
.filter((station) => filterStations(station, state.filters))
|
.filter((station) => filterStations(station, state.filters))
|
||||||
.sort((a, b) => sortStations(a, b, state.sorterActive));
|
.sort((a, b) => sortStations(a, b, state.sorterActive));
|
||||||
|
|||||||
@@ -0,0 +1,196 @@
|
|||||||
|
import { Socket } from 'socket.io-client';
|
||||||
|
import Station from '../scripts/interfaces/Station';
|
||||||
|
import { API, Websocket } from '../typings/api';
|
||||||
|
import { Status } from '../typings/common';
|
||||||
|
|
||||||
|
export type Availability = 'default' | 'unavailable' | 'nonPublic' | 'abandoned' | 'nonDefault';
|
||||||
|
|
||||||
|
export interface RegionCounters {
|
||||||
|
stationCount: number;
|
||||||
|
trainsCount: number;
|
||||||
|
timetablesCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StoreState {
|
||||||
|
stationList: Station[];
|
||||||
|
activeData: Websocket.ActiveData;
|
||||||
|
rollingStockData?: API.RollingStock.Response;
|
||||||
|
|
||||||
|
regionOnlineCounters: RegionCounters[];
|
||||||
|
|
||||||
|
lastDispatcherStatuses: {
|
||||||
|
hash: string;
|
||||||
|
statusTimestamp: number;
|
||||||
|
statusID: Status.ActiveDispatcher;
|
||||||
|
}[];
|
||||||
|
|
||||||
|
sceneryData: any[][];
|
||||||
|
|
||||||
|
region: { id: string; value: string };
|
||||||
|
trainCount: number;
|
||||||
|
stationCount: number;
|
||||||
|
|
||||||
|
webSocket?: Socket;
|
||||||
|
isOffline: boolean;
|
||||||
|
|
||||||
|
dispatcherStatsName: string;
|
||||||
|
dispatcherStatsData?: API.DispatcherStats.Response;
|
||||||
|
|
||||||
|
driverStatsName: string;
|
||||||
|
driverStatsData?: API.DriverStats.Response;
|
||||||
|
driverStatsStatus: Status.Data;
|
||||||
|
|
||||||
|
chosenModalTrainId?: string;
|
||||||
|
|
||||||
|
currentStatsTab: 'daily' | 'driver' | null;
|
||||||
|
|
||||||
|
dataStatuses: {
|
||||||
|
connection: Status.Data;
|
||||||
|
sceneries: Status.Data;
|
||||||
|
timetables: Status.Data;
|
||||||
|
dispatchers: Status.Data;
|
||||||
|
trains: Status.Data;
|
||||||
|
};
|
||||||
|
|
||||||
|
listenerLaunched: boolean;
|
||||||
|
blockScroll: boolean;
|
||||||
|
modalLastClickedTarget: EventTarget | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StationRoutesInfo {
|
||||||
|
routeName: string;
|
||||||
|
isElectric: boolean;
|
||||||
|
isInternal: boolean;
|
||||||
|
isRouteSBL: boolean;
|
||||||
|
routeLength: number;
|
||||||
|
routeSpeed: number;
|
||||||
|
routeTracks: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StationJSONData {
|
||||||
|
name: string;
|
||||||
|
abbr: string;
|
||||||
|
url: string;
|
||||||
|
lines: string;
|
||||||
|
project: string;
|
||||||
|
projectUrl: string;
|
||||||
|
|
||||||
|
reqLevel: number;
|
||||||
|
|
||||||
|
signalType: string;
|
||||||
|
controlType: string;
|
||||||
|
|
||||||
|
SUP: boolean;
|
||||||
|
|
||||||
|
// routes: string;
|
||||||
|
routesInfo: StationRoutesInfo[];
|
||||||
|
|
||||||
|
checkpoints: string | null;
|
||||||
|
authors?: string;
|
||||||
|
|
||||||
|
availability: Availability;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OnlineScenery {
|
||||||
|
name: string;
|
||||||
|
hash: string;
|
||||||
|
region: string;
|
||||||
|
maxUsers: number;
|
||||||
|
currentUsers: number;
|
||||||
|
spawns: { spawnName: string; spawnLength: number; isElectrified: boolean }[];
|
||||||
|
dispatcherName: string;
|
||||||
|
dispatcherRate: number;
|
||||||
|
dispatcherId: number;
|
||||||
|
dispatcherExp: number;
|
||||||
|
dispatcherIsSupporter: boolean;
|
||||||
|
|
||||||
|
dispatcherStatus: Status.ActiveDispatcher | number;
|
||||||
|
|
||||||
|
isOnline: boolean;
|
||||||
|
|
||||||
|
stationTrains?: StationTrain[];
|
||||||
|
scheduledTrains?: ScheduledTrain[];
|
||||||
|
|
||||||
|
scheduledTrainCount: {
|
||||||
|
all: number;
|
||||||
|
confirmed: number;
|
||||||
|
unconfirmed: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StationTrain {
|
||||||
|
driverName: string;
|
||||||
|
driverId: number;
|
||||||
|
trainNo: number;
|
||||||
|
trainId: string;
|
||||||
|
stopStatus: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScheduledTrain {
|
||||||
|
checkpointName: string;
|
||||||
|
|
||||||
|
trainId: string;
|
||||||
|
trainNo: number;
|
||||||
|
|
||||||
|
driverName: string;
|
||||||
|
driverId: number;
|
||||||
|
currentStationName: string;
|
||||||
|
currentStationHash: string;
|
||||||
|
category: string;
|
||||||
|
stopInfo: TrainStop;
|
||||||
|
|
||||||
|
terminatesAt: string;
|
||||||
|
beginsAt: string;
|
||||||
|
|
||||||
|
prevStationName: string;
|
||||||
|
nextStationName: string;
|
||||||
|
|
||||||
|
arrivingLine: string | null;
|
||||||
|
departureLine: string | null;
|
||||||
|
|
||||||
|
prevDepartureLine: string | null;
|
||||||
|
nextArrivalLine: string | null;
|
||||||
|
|
||||||
|
signal: string;
|
||||||
|
connectedTrack: string;
|
||||||
|
|
||||||
|
stopLabel: string;
|
||||||
|
stopStatus: StopStatus;
|
||||||
|
stopStatusID: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum StopStatus {
|
||||||
|
ARRIVING = 'arriving',
|
||||||
|
DEPARTED = 'departed',
|
||||||
|
DEPARTED_AWAY = 'departed-away',
|
||||||
|
ONLINE = 'online',
|
||||||
|
STOPPED = 'stopped',
|
||||||
|
TERMINATED = 'terminated'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TrainStop {
|
||||||
|
stopName: string;
|
||||||
|
stopNameRAW: string;
|
||||||
|
stopType: string;
|
||||||
|
stopDistance: number;
|
||||||
|
mainStop: boolean;
|
||||||
|
|
||||||
|
arrivalLine: string | null;
|
||||||
|
arrivalTimestamp: number;
|
||||||
|
arrivalRealTimestamp: number;
|
||||||
|
arrivalDelay: number;
|
||||||
|
|
||||||
|
departureLine: string | null;
|
||||||
|
departureTimestamp: number;
|
||||||
|
departureRealTimestamp: number;
|
||||||
|
departureDelay: number;
|
||||||
|
pointId: number;
|
||||||
|
|
||||||
|
comments?: any;
|
||||||
|
|
||||||
|
beginsHere: boolean;
|
||||||
|
terminatesHere: boolean;
|
||||||
|
confirmed: boolean;
|
||||||
|
stopped: boolean;
|
||||||
|
stopTime: number | null;
|
||||||
|
}
|
||||||
@@ -1,52 +1,15 @@
|
|||||||
import { DispatcherStatusID } from '../enums/DispatcherStatus';
|
import Station from '../scripts/interfaces/Station';
|
||||||
import { ScheduledTrain, StopStatus } from '../interfaces/ScheduledTrain';
|
import Train from '../scripts/interfaces/Train';
|
||||||
import Station from '../interfaces/Station';
|
import { API } from '../typings/api';
|
||||||
import Train from '../interfaces/Train';
|
import { ScheduledTrain, StationTrain, StopStatus, TrainStop } from './typings';
|
||||||
import TrainStop from '../interfaces/TrainStop';
|
|
||||||
import StationAPIData from '../interfaces/api/StationAPIData';
|
|
||||||
import { StationTrain, StoreState } from '../interfaces/store/storeTypes';
|
|
||||||
|
|
||||||
export const getLocoURL = (locoType: string): string =>
|
export function getLocoURL(locoType: string): string {
|
||||||
`https://rj.td2.info.pl/dist/img/thumbnails/${
|
return `https://rj.td2.info.pl/dist/img/thumbnails/${
|
||||||
locoType.includes('EN') ? locoType + 'rb' : locoType
|
locoType.includes('EN') ? locoType + 'rb' : locoType
|
||||||
}.png`;
|
}.png`;
|
||||||
|
}
|
||||||
|
|
||||||
export const getStatusID = (
|
export function getStatusTimestamp(stationStatus: any): number {
|
||||||
stationStatus: any[] | undefined,
|
|
||||||
isSWDROnline: boolean
|
|
||||||
): DispatcherStatusID => {
|
|
||||||
if (isSWDROnline && !stationStatus) return DispatcherStatusID.Unauthorized;
|
|
||||||
if (!stationStatus) return DispatcherStatusID.Unknown;
|
|
||||||
|
|
||||||
// if (stationStatus == -1) return DispatcherStatusID.Unauthorized;
|
|
||||||
|
|
||||||
const statusCode = stationStatus[2];
|
|
||||||
const statusTimestamp = stationStatus[3];
|
|
||||||
|
|
||||||
switch (statusCode) {
|
|
||||||
case 0:
|
|
||||||
if (statusTimestamp - Date.now() > 21000000) return DispatcherStatusID.OnlineNoLimit;
|
|
||||||
|
|
||||||
return DispatcherStatusID.OnlineWithHours;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
return DispatcherStatusID.Afk;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
if (statusTimestamp == 0) return DispatcherStatusID.Ending;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
return DispatcherStatusID.NoSpace;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DispatcherStatusID.Unavailable;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getStatusTimestamp = (stationStatus: any): number => {
|
|
||||||
if (!stationStatus) return -2;
|
if (!stationStatus) return -2;
|
||||||
|
|
||||||
const statusCode = stationStatus[2];
|
const statusCode = stationStatus[2];
|
||||||
@@ -67,9 +30,9 @@ export const getStatusTimestamp = (stationStatus: any): number => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
};
|
}
|
||||||
|
|
||||||
export const parseSpawns = (spawnString: string | null) => {
|
export function parseSpawns(spawnString: string | null) {
|
||||||
if (!spawnString) return [];
|
if (!spawnString) return [];
|
||||||
if (spawnString === 'NO_SPAWN') return [];
|
if (spawnString === 'NO_SPAWN') return [];
|
||||||
|
|
||||||
@@ -81,47 +44,49 @@ export const parseSpawns = (spawnString: string | null) => {
|
|||||||
|
|
||||||
return { spawnName, spawnLength, isElectrified };
|
return { spawnName, spawnLength, isElectrified };
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
export const getTimestamp = (date: string | null): number => (date ? new Date(date).getTime() : 0);
|
export function getTimestamp(date: string | null): number {
|
||||||
|
return date ? new Date(date).getTime() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
export const getTrainStopStatus = (
|
export function getTrainStopStatus(
|
||||||
stopInfo: TrainStop,
|
stopInfo: TrainStop,
|
||||||
currentStationName: string,
|
currentStationName: string,
|
||||||
sceneryName: string
|
sceneryName: string
|
||||||
) => {
|
) {
|
||||||
let stopStatus = StopStatus['arriving'],
|
let stopStatus = StopStatus.ARRIVING,
|
||||||
stopLabel = '',
|
stopLabel = '',
|
||||||
stopStatusID = -1;
|
stopStatusID = -1;
|
||||||
|
|
||||||
if (stopInfo.terminatesHere && stopInfo.confirmed) {
|
if (stopInfo.terminatesHere && stopInfo.confirmed) {
|
||||||
stopStatus = StopStatus['terminated'];
|
stopStatus = StopStatus.TERMINATED;
|
||||||
stopLabel = 'Skończył bieg';
|
stopLabel = 'Skończył bieg';
|
||||||
stopStatusID = 5;
|
stopStatusID = 5;
|
||||||
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName == sceneryName) {
|
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName == sceneryName) {
|
||||||
stopStatus = StopStatus['departed'];
|
stopStatus = StopStatus.DEPARTED;
|
||||||
stopLabel = 'Odprawiony';
|
stopLabel = 'Odprawiony';
|
||||||
stopStatusID = 2;
|
stopStatusID = 2;
|
||||||
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName != sceneryName) {
|
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName != sceneryName) {
|
||||||
stopStatus = StopStatus['departed-away'];
|
stopStatus = StopStatus.DEPARTED_AWAY;
|
||||||
stopLabel = 'Odjechał';
|
stopLabel = 'Odjechał';
|
||||||
stopStatusID = 4;
|
stopStatusID = 4;
|
||||||
} else if (currentStationName == sceneryName && !stopInfo.stopped) {
|
} else if (currentStationName == sceneryName && !stopInfo.stopped) {
|
||||||
stopStatus = StopStatus['online'];
|
stopStatus = StopStatus.ONLINE;
|
||||||
stopLabel = 'Na stacji';
|
stopLabel = 'Na stacji';
|
||||||
stopStatusID = 0;
|
stopStatusID = 0;
|
||||||
} else if (currentStationName == sceneryName && stopInfo.stopped) {
|
} else if (currentStationName == sceneryName && stopInfo.stopped) {
|
||||||
stopStatus = StopStatus['stopped'];
|
stopStatus = StopStatus.STOPPED;
|
||||||
stopLabel = 'Postój';
|
stopLabel = 'Postój';
|
||||||
stopStatusID = 1;
|
stopStatusID = 1;
|
||||||
} else if (currentStationName != sceneryName) {
|
} else if (currentStationName != sceneryName) {
|
||||||
stopStatus = StopStatus['arriving'];
|
stopStatus = StopStatus.ARRIVING;
|
||||||
stopLabel = 'W drodze';
|
stopLabel = 'W drodze';
|
||||||
stopStatusID = 3;
|
stopStatusID = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { stopStatus, stopLabel, stopStatusID };
|
return { stopStatus, stopLabel, stopStatusID };
|
||||||
};
|
}
|
||||||
|
|
||||||
export function getCheckpointTrain(
|
export function getCheckpointTrain(
|
||||||
train: Train,
|
train: Train,
|
||||||
@@ -218,40 +183,12 @@ export function getCheckpointTrain(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDispatcherStatus(state: StoreState, onlineStationData: StationAPIData) {
|
|
||||||
const { dispatchers } = state.apiData;
|
|
||||||
|
|
||||||
const prevDispatcherStatus = state.lastDispatcherStatuses.find(
|
|
||||||
(dispatcher) => dispatcher.hash === onlineStationData.stationHash
|
|
||||||
);
|
|
||||||
|
|
||||||
const stationStatus = dispatchers?.find(
|
|
||||||
(status: string[]) => status[0] == onlineStationData.stationHash && status[1] == state.region.id
|
|
||||||
);
|
|
||||||
|
|
||||||
const statusTimestamp =
|
|
||||||
prevDispatcherStatus && !dispatchers
|
|
||||||
? prevDispatcherStatus.statusTimestamp
|
|
||||||
: getStatusTimestamp(stationStatus);
|
|
||||||
|
|
||||||
const statusID =
|
|
||||||
prevDispatcherStatus && !dispatchers
|
|
||||||
? prevDispatcherStatus.statusID
|
|
||||||
: getStatusID(stationStatus, onlineStationData.isOnline === 1);
|
|
||||||
|
|
||||||
return {
|
|
||||||
hash: onlineStationData.stationHash,
|
|
||||||
statusID,
|
|
||||||
statusTimestamp
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getScheduledTrains(
|
export function getScheduledTrains(
|
||||||
trainList: Train[],
|
trainList: Train[],
|
||||||
stationAPIData: StationAPIData,
|
sceneryData: API.ActiveSceneries.Data,
|
||||||
stationGeneralInfo: Station['generalInfo']
|
stationGeneralInfo: Station['generalInfo']
|
||||||
): ScheduledTrain[] {
|
): ScheduledTrain[] {
|
||||||
const stationName = stationAPIData.stationName.toLocaleLowerCase();
|
const stationNameLower = sceneryData.stationName.toLocaleLowerCase();
|
||||||
|
|
||||||
stationGeneralInfo?.checkpoints.forEach((cp) => (cp.scheduledTrains.length = 0));
|
stationGeneralInfo?.checkpoints.forEach((cp) => (cp.scheduledTrains.length = 0));
|
||||||
|
|
||||||
@@ -259,17 +196,17 @@ export function getScheduledTrains(
|
|||||||
if (!train.timetableData) return acc;
|
if (!train.timetableData) return acc;
|
||||||
|
|
||||||
const timetable = train.timetableData;
|
const timetable = train.timetableData;
|
||||||
if (!timetable.sceneries.includes(stationAPIData.stationHash)) return acc;
|
if (!timetable.sceneries.includes(sceneryData.stationHash)) return acc;
|
||||||
|
|
||||||
const stopInfoIndex = timetable.followingStops.findIndex((stop) => {
|
const stopInfoIndex = timetable.followingStops.findIndex((stop) => {
|
||||||
const stopName = stop.stopNameRAW.toLowerCase();
|
const stopNameLower = stop.stopNameRAW.toLocaleLowerCase();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
stationName == stopName ||
|
stationNameLower == stopNameLower ||
|
||||||
(!/(po\.|podg\.)/.test(stopName) && stopName.includes(stationName)) ||
|
(!/(po\.|podg\.)/.test(stopNameLower) && stopNameLower.includes(stationNameLower)) ||
|
||||||
(!/(po\.|podg\.)/.test(stationName) && stationName.includes(stopName)) ||
|
(!/(po\.|podg\.)/.test(stationNameLower) && stationNameLower.includes(stopNameLower)) ||
|
||||||
(stopName.split(', podg.')[0] !== undefined &&
|
(stopNameLower.split(', podg.')[0] !== undefined &&
|
||||||
stationName.startsWith(stopName.split(', podg.')[0]))
|
stationNameLower.startsWith(stopNameLower.split(', podg.')[0]))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -277,12 +214,12 @@ export function getScheduledTrains(
|
|||||||
|
|
||||||
if (stopInfoIndex != -1) {
|
if (stopInfoIndex != -1) {
|
||||||
checkpointScheduledTrains.push(
|
checkpointScheduledTrains.push(
|
||||||
getCheckpointTrain(train, stopInfoIndex, stationAPIData.stationName)
|
getCheckpointTrain(train, stopInfoIndex, sceneryData.stationName)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
stationGeneralInfo?.checkpoints?.forEach((checkpoint) => {
|
stationGeneralInfo?.checkpoints?.forEach((checkpoint) => {
|
||||||
if (checkpoint.checkpointName.toLocaleLowerCase() == stationName) return;
|
// if (checkpoint.checkpointName.toLocaleLowerCase() == stationNameLower) return;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
checkpointScheduledTrains.findIndex(
|
checkpointScheduledTrains.findIndex(
|
||||||
@@ -298,9 +235,7 @@ export function getScheduledTrains(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (index > -1)
|
if (index > -1)
|
||||||
checkpointScheduledTrains.push(
|
checkpointScheduledTrains.push(getCheckpointTrain(train, index, sceneryData.stationName));
|
||||||
getCheckpointTrain(train, index, stationAPIData.stationName)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
acc.push(...checkpointScheduledTrains);
|
acc.push(...checkpointScheduledTrains);
|
||||||
@@ -312,14 +247,14 @@ export function getStationTrains(
|
|||||||
trainList: Train[],
|
trainList: Train[],
|
||||||
scheduledTrainList: ScheduledTrain[],
|
scheduledTrainList: ScheduledTrain[],
|
||||||
region: string,
|
region: string,
|
||||||
apiStation: StationAPIData
|
sceneryData: API.ActiveSceneries.Data
|
||||||
): StationTrain[] {
|
): StationTrain[] {
|
||||||
return trainList
|
return trainList
|
||||||
.filter(
|
.filter(
|
||||||
(train) =>
|
(train) =>
|
||||||
train?.region === region &&
|
train?.region === region &&
|
||||||
train.online &&
|
train.online &&
|
||||||
train.currentStationName === apiStation.stationName
|
train.currentStationName === sceneryData.stationName
|
||||||
)
|
)
|
||||||
.map((train) => ({
|
.map((train) => ({
|
||||||
driverName: train.driverName,
|
driverName: train.driverName,
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
.filters-options {
|
.filters-options {
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions-bar {
|
.actions-bar {
|
||||||
@@ -57,7 +58,7 @@ h1.option-title {
|
|||||||
background-color: $bgCol;
|
background-color: $bgCol;
|
||||||
box-shadow: 0 5px 10px 2px #0f0f0f;
|
box-shadow: 0 5px 10px 2px #0f0f0f;
|
||||||
|
|
||||||
width: 97%;
|
width: 100%;
|
||||||
max-width: 550px;
|
max-width: 550px;
|
||||||
|
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
|
|||||||
@@ -0,0 +1,331 @@
|
|||||||
|
import { Status } from './common';
|
||||||
|
|
||||||
|
export namespace API {
|
||||||
|
export namespace DispatcherHistory {
|
||||||
|
export type Response = Data[];
|
||||||
|
|
||||||
|
export interface Data {
|
||||||
|
id: string;
|
||||||
|
currentDuration: number;
|
||||||
|
dispatcherId: number;
|
||||||
|
dispatcherName: string;
|
||||||
|
dispatcherLevel: number | null;
|
||||||
|
dispatcherRate: number;
|
||||||
|
dispatcherIsSupporter: boolean;
|
||||||
|
dispatcherStatus?: number;
|
||||||
|
isOnline: boolean;
|
||||||
|
lastOnlineTimestamp: number;
|
||||||
|
region: string;
|
||||||
|
stationHash: string;
|
||||||
|
stationName: string;
|
||||||
|
timestampFrom: number;
|
||||||
|
timestampTo?: number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace DispatcherStats {
|
||||||
|
export interface DistanceStat {
|
||||||
|
routeDistance: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Count {
|
||||||
|
_all: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Response {
|
||||||
|
_sum: DistanceStat;
|
||||||
|
_max: DistanceStat;
|
||||||
|
_min: DistanceStat;
|
||||||
|
_avg: DistanceStat;
|
||||||
|
_count: Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace DriverStats {
|
||||||
|
export interface SumStats {
|
||||||
|
routeDistance: number;
|
||||||
|
confirmedStopsCount: number;
|
||||||
|
allStopsCount: number;
|
||||||
|
currentDistance: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CountStats {
|
||||||
|
fulfilled: number;
|
||||||
|
terminated: number;
|
||||||
|
_all: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MaxStats {
|
||||||
|
routeDistance: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AvdStats {
|
||||||
|
routeDistance: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Response {
|
||||||
|
_sum: SumStats;
|
||||||
|
_count: CountStats;
|
||||||
|
_max: MaxStats;
|
||||||
|
_avg: AvdStats;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace ActiveSceneries {
|
||||||
|
export interface Data {
|
||||||
|
dispatcherId: number;
|
||||||
|
dispatcherName: string;
|
||||||
|
dispatcherIsSupporter: boolean;
|
||||||
|
stationName: string;
|
||||||
|
stationHash: string;
|
||||||
|
region: string;
|
||||||
|
maxUsers: number;
|
||||||
|
currentUsers: number;
|
||||||
|
spawn: number;
|
||||||
|
lastSeen: number;
|
||||||
|
dispatcherExp: number;
|
||||||
|
nameFromHeader: string;
|
||||||
|
spawnString: string | null;
|
||||||
|
networkConnectionString: string;
|
||||||
|
isOnline: number;
|
||||||
|
dispatcherRate: number;
|
||||||
|
dispatcherStatus: Status.ActiveDispatcher | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Response = Data[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace ActiveTrains {
|
||||||
|
export type Response = Data[];
|
||||||
|
|
||||||
|
export interface Data {
|
||||||
|
trainNo: number;
|
||||||
|
|
||||||
|
mass: number;
|
||||||
|
length: number;
|
||||||
|
speed: number;
|
||||||
|
stockString: string;
|
||||||
|
|
||||||
|
signal: string;
|
||||||
|
distance: number;
|
||||||
|
connectedTrack: string;
|
||||||
|
|
||||||
|
driverName: string;
|
||||||
|
driverId: number;
|
||||||
|
driverIsSupporter: boolean;
|
||||||
|
driverLevel?: number;
|
||||||
|
|
||||||
|
currentStationName: string;
|
||||||
|
currentStationHash: string;
|
||||||
|
|
||||||
|
online: boolean;
|
||||||
|
lastSeen: number;
|
||||||
|
|
||||||
|
region: string;
|
||||||
|
isTimeout: boolean;
|
||||||
|
|
||||||
|
timetable?: Timetable;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TimetableStop {
|
||||||
|
stopName: string;
|
||||||
|
stopNameRAW: string;
|
||||||
|
stopType: string;
|
||||||
|
stopDistance: number;
|
||||||
|
pointId: number;
|
||||||
|
|
||||||
|
mainStop: boolean;
|
||||||
|
|
||||||
|
arrivalLine: string;
|
||||||
|
arrivalTimestamp: number;
|
||||||
|
arrivalRealTimestamp: number;
|
||||||
|
arrivalDelay: number;
|
||||||
|
|
||||||
|
departureLine: string;
|
||||||
|
departureTimestamp: number;
|
||||||
|
departureRealTimestamp: number;
|
||||||
|
departureDelay: number;
|
||||||
|
|
||||||
|
comments?: any;
|
||||||
|
|
||||||
|
beginsHere: boolean;
|
||||||
|
terminatesHere: boolean;
|
||||||
|
confirmed: boolean;
|
||||||
|
stopped: boolean;
|
||||||
|
stopTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Timetable {
|
||||||
|
timetableId: number;
|
||||||
|
category: string;
|
||||||
|
route: string;
|
||||||
|
|
||||||
|
stopList: TimetableStop[];
|
||||||
|
|
||||||
|
TWR: boolean;
|
||||||
|
SKR: boolean;
|
||||||
|
sceneries: string[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace TimetableHistory {
|
||||||
|
export interface Data {
|
||||||
|
id: number;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
|
||||||
|
timetableId: number;
|
||||||
|
trainNo: number;
|
||||||
|
trainCategoryCode: string;
|
||||||
|
|
||||||
|
driverId: number;
|
||||||
|
driverName: string;
|
||||||
|
driverLevel: number | null;
|
||||||
|
driverIsSupporter: boolean;
|
||||||
|
|
||||||
|
route: string;
|
||||||
|
twr: number;
|
||||||
|
skr: number;
|
||||||
|
sceneriesString: string;
|
||||||
|
currentLocation: string[];
|
||||||
|
|
||||||
|
routeDistance: number;
|
||||||
|
currentDistance: number;
|
||||||
|
|
||||||
|
confirmedStopsCount: number;
|
||||||
|
allStopsCount: number;
|
||||||
|
|
||||||
|
beginDate: string;
|
||||||
|
endDate: string;
|
||||||
|
|
||||||
|
scheduledBeginDate: string;
|
||||||
|
scheduledEndDate: string;
|
||||||
|
|
||||||
|
terminated: boolean;
|
||||||
|
fulfilled: boolean;
|
||||||
|
|
||||||
|
authorName?: string;
|
||||||
|
authorId?: number;
|
||||||
|
|
||||||
|
stopsString?: string;
|
||||||
|
|
||||||
|
stockString?: string;
|
||||||
|
stockHistory: string[];
|
||||||
|
|
||||||
|
stockMass?: number;
|
||||||
|
stockLength?: number;
|
||||||
|
maxSpeed?: number;
|
||||||
|
|
||||||
|
hashesString?: string;
|
||||||
|
currentSceneryName?: string;
|
||||||
|
currentSceneryHash?: string;
|
||||||
|
|
||||||
|
routeSceneries?: string;
|
||||||
|
|
||||||
|
checkpointArrivals?: string[];
|
||||||
|
checkpointDepartures?: string[];
|
||||||
|
|
||||||
|
checkpointArrivalsScheduled?: string[];
|
||||||
|
checkpointDeparturesScheduled?: string[];
|
||||||
|
|
||||||
|
checkpointStopTypes?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Response = Data[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace RollingStock {
|
||||||
|
export interface Response {
|
||||||
|
usage: Record<string, string>;
|
||||||
|
info: Info;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Info {
|
||||||
|
'loco-e': [string, string, string, string, boolean][];
|
||||||
|
'loco-s': [string, string, string, string, boolean][];
|
||||||
|
'loco-szt': [string, string, string, string, boolean][];
|
||||||
|
'loco-ezt': [string, string, string, string, boolean][];
|
||||||
|
'car-passenger': [string, string, boolean, boolean, string][];
|
||||||
|
'car-cargo': [string, string, boolean, boolean, string][];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace DailyStats {
|
||||||
|
export interface Response {
|
||||||
|
totalTimetables: number;
|
||||||
|
distanceSum: number;
|
||||||
|
distanceAvg: number;
|
||||||
|
maxTimetable: API.TimetableHistory.Data | null;
|
||||||
|
|
||||||
|
mostActiveDispatchers: {
|
||||||
|
name: string;
|
||||||
|
count: number;
|
||||||
|
}[];
|
||||||
|
|
||||||
|
mostActiveDrivers: {
|
||||||
|
name: string;
|
||||||
|
distance: number;
|
||||||
|
}[];
|
||||||
|
|
||||||
|
longestDuties: {
|
||||||
|
name: string;
|
||||||
|
duration: number;
|
||||||
|
station: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace Websocket {
|
||||||
|
export interface ActiveData {
|
||||||
|
activeSceneries?: API.ActiveSceneries.Response;
|
||||||
|
trains?: API.ActiveTrains.Response;
|
||||||
|
connectedSocketCount: number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace GithubAPI {
|
||||||
|
export namespace Release {
|
||||||
|
export interface Author {
|
||||||
|
login: string;
|
||||||
|
id: number;
|
||||||
|
node_id: string;
|
||||||
|
avatar_url: string;
|
||||||
|
gravatar_id: string;
|
||||||
|
url: string;
|
||||||
|
html_url: string;
|
||||||
|
followers_url: string;
|
||||||
|
following_url: string;
|
||||||
|
gists_url: string;
|
||||||
|
starred_url: string;
|
||||||
|
subscriptions_url: string;
|
||||||
|
organizations_url: string;
|
||||||
|
repos_url: string;
|
||||||
|
events_url: string;
|
||||||
|
received_events_url: string;
|
||||||
|
type: string;
|
||||||
|
site_admin: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Response {
|
||||||
|
url: string;
|
||||||
|
assets_url: string;
|
||||||
|
upload_url: string;
|
||||||
|
html_url: string;
|
||||||
|
id: number;
|
||||||
|
author: Author;
|
||||||
|
node_id: string;
|
||||||
|
tag_name: string;
|
||||||
|
target_commitish: string;
|
||||||
|
name: string;
|
||||||
|
draft: boolean;
|
||||||
|
prerelease: boolean;
|
||||||
|
created_at: Date;
|
||||||
|
published_at: Date;
|
||||||
|
assets: any[];
|
||||||
|
tarball_url: string;
|
||||||
|
zipball_url: string;
|
||||||
|
body: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
export namespace Status {
|
||||||
|
export enum ActiveDispatcher {
|
||||||
|
INVALID = -2,
|
||||||
|
UNKNOWN = -1,
|
||||||
|
NO_LIMIT = 0,
|
||||||
|
AFK = 1,
|
||||||
|
ENDING = 2,
|
||||||
|
NO_SPACE = 3,
|
||||||
|
UNAVAILABLE = 4,
|
||||||
|
NOT_LOGGED_IN = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Data {
|
||||||
|
Offline = 2,
|
||||||
|
Initialized = -1,
|
||||||
|
Loading = 0,
|
||||||
|
Error = 1,
|
||||||
|
Loaded = 2,
|
||||||
|
Warning = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,16 +36,14 @@ import axios from 'axios';
|
|||||||
|
|
||||||
import JournalOptions from '../components/JournalView/JournalOptions.vue';
|
import JournalOptions from '../components/JournalView/JournalOptions.vue';
|
||||||
import { URLs } from '../scripts/utils/apiURLs';
|
import { URLs } from '../scripts/utils/apiURLs';
|
||||||
import { DataStatus } from '../scripts/enums/DataStatus';
|
import { useStore } from '../store/mainStore';
|
||||||
import { useStore } from '../store/store';
|
|
||||||
import JournalDispatchersList from '../components/JournalView/JournalDispatchersList.vue';
|
import JournalDispatchersList from '../components/JournalView/JournalDispatchersList.vue';
|
||||||
import {
|
|
||||||
JournalDispatcherSearcher,
|
|
||||||
JournalDispatcherSorter
|
|
||||||
} from '../scripts/types/JournalDispatcherTypes';
|
|
||||||
import { DispatcherHistory } from '../scripts/interfaces/api/DispatchersAPIData';
|
|
||||||
import JournalHeader from '../components/JournalView/JournalHeader.vue';
|
import JournalHeader from '../components/JournalView/JournalHeader.vue';
|
||||||
import { LocationQuery } from 'vue-router';
|
import { LocationQuery } from 'vue-router';
|
||||||
|
import { Journal } from '../components/JournalView/typings';
|
||||||
|
import { API } from '../typings/api';
|
||||||
|
import { Status } from '../typings/common';
|
||||||
|
|
||||||
const DISPATCHERS_API_URL = `${URLs.stacjownikAPI}/api/getDispatchers`;
|
const DISPATCHERS_API_URL = `${URLs.stacjownikAPI}/api/getDispatchers`;
|
||||||
|
|
||||||
@@ -81,21 +79,20 @@ export default defineComponent({
|
|||||||
statsCardOpen: false,
|
statsCardOpen: false,
|
||||||
currentOptionsActive: false,
|
currentOptionsActive: false,
|
||||||
|
|
||||||
dataStatus: DataStatus.Loading,
|
dataStatus: Status.Data.Loading,
|
||||||
DataStatus,
|
|
||||||
|
|
||||||
historyList: [] as DispatcherHistory[]
|
historyList: [] as API.DispatcherHistory.Response
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const sorterActive: JournalDispatcherSorter = reactive({ id: 'timestampFrom', dir: -1 });
|
const sorterActive: Journal.DispatcherSorter = reactive({ id: 'timestampFrom', dir: -1 });
|
||||||
const journalFilterActive = ref({});
|
const journalFilterActive = ref({});
|
||||||
|
|
||||||
const searchersValues = reactive({
|
const searchersValues = reactive({
|
||||||
'search-dispatcher': '',
|
'search-dispatcher': '',
|
||||||
'search-station': '',
|
'search-station': '',
|
||||||
'search-date': ''
|
'search-date': ''
|
||||||
} as JournalDispatcherSearcher);
|
} as Journal.DispatcherSearcher);
|
||||||
|
|
||||||
const countFromIndex = ref(0);
|
const countFromIndex = ref(0);
|
||||||
const countLimit = 15;
|
const countLimit = 15;
|
||||||
@@ -153,7 +150,7 @@ export default defineComponent({
|
|||||||
const scrollTop = listElement.scrollTop;
|
const scrollTop = listElement.scrollTop;
|
||||||
const elementHeight = listElement.scrollHeight - listElement.offsetHeight;
|
const elementHeight = listElement.scrollHeight - listElement.offsetHeight;
|
||||||
|
|
||||||
if (!this.scrollDataLoaded || this.scrollNoMoreData || this.dataStatus != DataStatus.Loaded)
|
if (!this.scrollDataLoaded || this.scrollNoMoreData || this.dataStatus != Status.Data.Loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (scrollTop > elementHeight * 0.85) this.addHistoryData();
|
if (scrollTop > elementHeight * 0.85) this.addHistoryData();
|
||||||
@@ -185,7 +182,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
this.countFromIndex = this.historyList.length;
|
this.countFromIndex = this.historyList.length;
|
||||||
|
|
||||||
const responseData: DispatcherHistory[] = await (
|
const responseData: API.DispatcherHistory.Response = await (
|
||||||
await axios.get(
|
await axios.get(
|
||||||
`${DISPATCHERS_API_URL}?${this.currentQuery}&countFrom=${this.countFromIndex}`
|
`${DISPATCHERS_API_URL}?${this.currentQuery}&countFrom=${this.countFromIndex}`
|
||||||
)
|
)
|
||||||
@@ -226,20 +223,20 @@ export default defineComponent({
|
|||||||
|
|
||||||
queries.push('countLimit=30');
|
queries.push('countLimit=30');
|
||||||
|
|
||||||
if (this.currentQuery != queries.join('&')) this.dataStatus = DataStatus.Loading;
|
if (this.currentQuery != queries.join('&')) this.dataStatus = Status.Data.Loading;
|
||||||
|
|
||||||
this.currentQuery = queries.join('&');
|
this.currentQuery = queries.join('&');
|
||||||
this.currentQueryArray = queries;
|
this.currentQueryArray = queries;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (reset) this.dataStatus = DataStatus.Loading;
|
if (reset) this.dataStatus = Status.Data.Loading;
|
||||||
|
|
||||||
const responseData: DispatcherHistory[] = await (
|
const responseData: API.DispatcherHistory.Response = await (
|
||||||
await axios.get(`${DISPATCHERS_API_URL}?${this.currentQuery}`)
|
await axios.get(`${DISPATCHERS_API_URL}?${this.currentQuery}`)
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
if (!responseData) {
|
if (!responseData) {
|
||||||
this.dataStatus = DataStatus.Error;
|
this.dataStatus = Status.Data.Error;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,9 +252,9 @@ export default defineComponent({
|
|||||||
: '';
|
: '';
|
||||||
|
|
||||||
this.dataRefreshedAt = new Date();
|
this.dataRefreshedAt = new Date();
|
||||||
this.dataStatus = DataStatus.Loaded;
|
this.dataStatus = Status.Data.Loaded;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.dataStatus = DataStatus.Error;
|
this.dataStatus = Status.Data.Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scrollNoMoreData = false;
|
this.scrollNoMoreData = false;
|
||||||
|
|||||||
@@ -45,24 +45,84 @@ import JournalOptions from '../components/JournalView/JournalOptions.vue';
|
|||||||
import JournalStats from '../components/JournalView/JournalStats.vue';
|
import JournalStats from '../components/JournalView/JournalStats.vue';
|
||||||
import JournalHeader from '../components/JournalView/JournalHeader.vue';
|
import JournalHeader from '../components/JournalView/JournalHeader.vue';
|
||||||
|
|
||||||
import { DataStatus } from '../scripts/enums/DataStatus';
|
|
||||||
import { TimetableHistory } from '../scripts/interfaces/api/TimetablesAPIData';
|
|
||||||
import { URLs } from '../scripts/utils/apiURLs';
|
import { URLs } from '../scripts/utils/apiURLs';
|
||||||
import { useStore } from '../store/store';
|
import { useStore } from '../store/mainStore';
|
||||||
|
|
||||||
import { LocationQuery } from 'vue-router';
|
import { LocationQuery } from 'vue-router';
|
||||||
import { TimetablesQueryParams } from '../scripts/interfaces/api/TimetablesQueryParams';
|
|
||||||
import { JournalFilterType } from '../scripts/enums/JournalFilterType';
|
|
||||||
import {
|
|
||||||
JournalFilter,
|
|
||||||
JournalTimetableSearchType,
|
|
||||||
JournalTimetableSorter
|
|
||||||
} from '../scripts/types/JournalTimetablesTypes';
|
|
||||||
import { journalTimetableFilters } from '../constants/Journal/JournalTimetablesConsts';
|
|
||||||
import JournalTimetablesList from '../components/JournalView/JournalTimetables/JournalTimetablesList.vue';
|
import JournalTimetablesList from '../components/JournalView/JournalTimetables/JournalTimetablesList.vue';
|
||||||
|
import { Journal } from '../components/JournalView/typings';
|
||||||
|
import { Status } from '../typings/common';
|
||||||
|
import { API } from '../typings/api';
|
||||||
|
|
||||||
const TIMETABLES_API_URL = `${URLs.stacjownikAPI}/api/getTimetables`;
|
const TIMETABLES_API_URL = `${URLs.stacjownikAPI}/api/getTimetables`;
|
||||||
|
|
||||||
|
export const journalTimetableFilters: Journal.TimetableFilter[] = [
|
||||||
|
{
|
||||||
|
id: Journal.TimetableFilterId.ALL,
|
||||||
|
filterSection: Journal.FilterSection.TIMETABLE_STATUS,
|
||||||
|
isActive: true
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: Journal.TimetableFilterId.ACTIVE,
|
||||||
|
filterSection: Journal.FilterSection.TIMETABLE_STATUS,
|
||||||
|
isActive: false
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: Journal.TimetableFilterId.FULFILLED,
|
||||||
|
filterSection: Journal.FilterSection.TIMETABLE_STATUS,
|
||||||
|
isActive: false
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: Journal.TimetableFilterId.ABANDONED,
|
||||||
|
filterSection: Journal.FilterSection.TIMETABLE_STATUS,
|
||||||
|
isActive: false
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: Journal.TimetableFilterId.TWR_SKR,
|
||||||
|
filterSection: Journal.FilterSection.TWRSKR,
|
||||||
|
isActive: true
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: Journal.TimetableFilterId.TWR,
|
||||||
|
filterSection: Journal.FilterSection.TWRSKR,
|
||||||
|
isActive: false
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: Journal.TimetableFilterId.SKR,
|
||||||
|
filterSection: Journal.FilterSection.TWRSKR,
|
||||||
|
isActive: false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
interface TimetablesQueryParams {
|
||||||
|
driverName?: string;
|
||||||
|
trainNo?: string;
|
||||||
|
timetableId?: string;
|
||||||
|
|
||||||
|
authorName?: string;
|
||||||
|
timestampFrom?: number;
|
||||||
|
timestampTo?: number;
|
||||||
|
issuedFrom?: string;
|
||||||
|
|
||||||
|
countFrom?: number;
|
||||||
|
countLimit?: number;
|
||||||
|
|
||||||
|
fulfilled?: number;
|
||||||
|
terminated?: number;
|
||||||
|
|
||||||
|
twr?: number;
|
||||||
|
skr?: number;
|
||||||
|
|
||||||
|
sortBy?: Journal.TimetableSorter['id'];
|
||||||
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
JournalOptions,
|
JournalOptions,
|
||||||
@@ -91,22 +151,20 @@ export default defineComponent({
|
|||||||
statsCardOpen: false,
|
statsCardOpen: false,
|
||||||
currentOptionsActive: false,
|
currentOptionsActive: false,
|
||||||
|
|
||||||
timetableHistory: [] as TimetableHistory[],
|
timetableHistory: [] as API.TimetableHistory.Response,
|
||||||
journalTimetableFilters,
|
journalTimetableFilters,
|
||||||
|
|
||||||
dataStatus: DataStatus.Loading,
|
dataStatus: Status.Data.Loading,
|
||||||
dataErrorMessage: '',
|
dataErrorMessage: ''
|
||||||
|
|
||||||
DataStatus
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const sorterActive: JournalTimetableSorter = reactive({ id: 'timetableId', dir: 'desc' });
|
const sorterActive: Journal.TimetableSorter = reactive({ id: 'timetableId', dir: 'desc' });
|
||||||
// const journalFilterActive = ref(journalTimetableFilters[0]);
|
// const journalFilterActive = ref(journalTimetableFilters[0]);
|
||||||
const initFilters: readonly JournalFilter[] = JSON.parse(
|
const initFilters: readonly Journal.TimetableFilter[] = JSON.parse(
|
||||||
JSON.stringify(journalTimetableFilters)
|
JSON.stringify(journalTimetableFilters)
|
||||||
);
|
);
|
||||||
const filterList: JournalFilter[] = reactive(JSON.parse(JSON.stringify(initFilters)));
|
const filterList: Journal.TimetableFilter[] = reactive(JSON.parse(JSON.stringify(initFilters)));
|
||||||
|
|
||||||
const searchersValues = reactive({
|
const searchersValues = reactive({
|
||||||
'search-train': '',
|
'search-train': '',
|
||||||
@@ -114,7 +172,7 @@ export default defineComponent({
|
|||||||
'search-dispatcher': '',
|
'search-dispatcher': '',
|
||||||
'search-issuedFrom': '',
|
'search-issuedFrom': '',
|
||||||
'search-date': ''
|
'search-date': ''
|
||||||
} as JournalTimetableSearchType);
|
} as Journal.TimetableSearchType);
|
||||||
|
|
||||||
const countFromIndex = ref(0);
|
const countFromIndex = ref(0);
|
||||||
const countLimit = 15;
|
const countLimit = 15;
|
||||||
@@ -163,7 +221,7 @@ export default defineComponent({
|
|||||||
const scrollTop = listElement.scrollTop;
|
const scrollTop = listElement.scrollTop;
|
||||||
const elementHeight = listElement.scrollHeight - listElement.offsetHeight;
|
const elementHeight = listElement.scrollHeight - listElement.offsetHeight;
|
||||||
|
|
||||||
if (!this.scrollDataLoaded || this.scrollNoMoreData || this.dataStatus != DataStatus.Loaded)
|
if (!this.scrollDataLoaded || this.scrollNoMoreData || this.dataStatus != Status.Data.Loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (scrollTop > elementHeight * 0.85) this.addHistoryData();
|
if (scrollTop > elementHeight * 0.85) this.addHistoryData();
|
||||||
@@ -213,7 +271,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
this.currentQueryParams['countFrom'] = this.timetableHistory.length;
|
this.currentQueryParams['countFrom'] = this.timetableHistory.length;
|
||||||
|
|
||||||
const responseData: TimetableHistory[] = await (
|
const responseData: API.TimetableHistory.Response = await (
|
||||||
await axios.get(`${TIMETABLES_API_URL}`, {
|
await axios.get(`${TIMETABLES_API_URL}`, {
|
||||||
params: { ...this.currentQueryParams }
|
params: { ...this.currentQueryParams }
|
||||||
})
|
})
|
||||||
@@ -248,37 +306,37 @@ export default defineComponent({
|
|||||||
.filter((f) => f.isActive)
|
.filter((f) => f.isActive)
|
||||||
.forEach((f) => {
|
.forEach((f) => {
|
||||||
switch (f.id) {
|
switch (f.id) {
|
||||||
case JournalFilterType.ABANDONED:
|
case Journal.TimetableFilterId.ABANDONED:
|
||||||
queryParams['fulfilled'] = 0;
|
queryParams['fulfilled'] = 0;
|
||||||
queryParams['terminated'] = 1;
|
queryParams['terminated'] = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JournalFilterType.ACTIVE:
|
case Journal.TimetableFilterId.ACTIVE:
|
||||||
queryParams['fulfilled'] = undefined;
|
queryParams['fulfilled'] = undefined;
|
||||||
queryParams['terminated'] = 0;
|
queryParams['terminated'] = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JournalFilterType.FULFILLED:
|
case Journal.TimetableFilterId.FULFILLED:
|
||||||
queryParams['terminated'] = undefined;
|
queryParams['terminated'] = undefined;
|
||||||
queryParams['fulfilled'] = 1;
|
queryParams['fulfilled'] = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JournalFilterType.ALL:
|
case Journal.TimetableFilterId.ALL:
|
||||||
queryParams['terminated'] = undefined;
|
queryParams['terminated'] = undefined;
|
||||||
queryParams['fulfilled'] = undefined;
|
queryParams['fulfilled'] = undefined;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JournalFilterType.TWR_SKR:
|
case Journal.TimetableFilterId.TWR_SKR:
|
||||||
queryParams['twr'] = undefined;
|
queryParams['twr'] = undefined;
|
||||||
queryParams['skr'] = undefined;
|
queryParams['skr'] = undefined;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JournalFilterType.TWR:
|
case Journal.TimetableFilterId.TWR:
|
||||||
queryParams['twr'] = 1;
|
queryParams['twr'] = 1;
|
||||||
queryParams['skr'] = undefined;
|
queryParams['skr'] = undefined;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JournalFilterType.SKR:
|
case Journal.TimetableFilterId.SKR:
|
||||||
queryParams['twr'] = undefined;
|
queryParams['twr'] = undefined;
|
||||||
queryParams['skr'] = 1;
|
queryParams['skr'] = 1;
|
||||||
break;
|
break;
|
||||||
@@ -301,19 +359,19 @@ export default defineComponent({
|
|||||||
this.sorterActive.id != 'timetableId' ? this.sorterActive.id : undefined;
|
this.sorterActive.id != 'timetableId' ? this.sorterActive.id : undefined;
|
||||||
|
|
||||||
if (JSON.stringify(this.currentQueryParams) != JSON.stringify(queryParams))
|
if (JSON.stringify(this.currentQueryParams) != JSON.stringify(queryParams))
|
||||||
this.dataStatus = DataStatus.Loading;
|
this.dataStatus = Status.Data.Loading;
|
||||||
|
|
||||||
this.currentQueryParams = queryParams;
|
this.currentQueryParams = queryParams;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const responseData: TimetableHistory[] = await (
|
const responseData: API.TimetableHistory.Response = await (
|
||||||
await axios.get(`${TIMETABLES_API_URL}`, {
|
await axios.get(`${TIMETABLES_API_URL}`, {
|
||||||
params: this.currentQueryParams
|
params: this.currentQueryParams
|
||||||
})
|
})
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
if (!responseData) {
|
if (!responseData) {
|
||||||
this.dataStatus = DataStatus.Error;
|
this.dataStatus = Status.Data.Error;
|
||||||
this.dataErrorMessage = 'Brak danych!';
|
this.dataErrorMessage = 'Brak danych!';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -329,10 +387,10 @@ export default defineComponent({
|
|||||||
? this.timetableHistory[0].driverName
|
? this.timetableHistory[0].driverName
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
this.dataStatus = DataStatus.Loaded;
|
this.dataStatus = Status.Data.Loaded;
|
||||||
this.dataRefreshedAt = new Date();
|
this.dataRefreshedAt = new Date();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.dataStatus = DataStatus.Error;
|
this.dataStatus = Status.Data.Error;
|
||||||
this.dataErrorMessage = 'Ups! Coś poszło nie tak!';
|
this.dataErrorMessage = 'Ups! Coś poszło nie tak!';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
:key="i"
|
:key="i"
|
||||||
class="btn btn--option"
|
class="btn btn--option"
|
||||||
@click="setViewMode(viewMode.component)"
|
@click="setViewMode(viewMode.component)"
|
||||||
:data-checked="currentViewCompontent == viewMode.component"
|
:data-checked="currentMode == viewMode.component"
|
||||||
>
|
>
|
||||||
{{ $t(viewMode.id) }}
|
{{ $t(viewMode.id) }}
|
||||||
</button>
|
</button>
|
||||||
@@ -35,10 +35,10 @@
|
|||||||
|
|
||||||
<keep-alive>
|
<keep-alive>
|
||||||
<component
|
<component
|
||||||
:is="currentViewCompontent"
|
:is="currentMode"
|
||||||
:onlineScenery="onlineSceneryInfo"
|
:onlineScenery="onlineSceneryInfo"
|
||||||
:station="stationInfo"
|
:station="stationInfo"
|
||||||
:key="currentViewCompontent"
|
:key="currentMode"
|
||||||
></component>
|
></component>
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</div>
|
</div>
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import routerMixin from '../mixins/routerMixin';
|
import routerMixin from '../mixins/routerMixin';
|
||||||
import { useStore } from '../store/store';
|
import { useStore } from '../store/mainStore';
|
||||||
|
|
||||||
import SceneryInfo from '../components/SceneryView/SceneryInfo.vue';
|
import SceneryInfo from '../components/SceneryView/SceneryInfo.vue';
|
||||||
import SceneryHeader from '../components/SceneryView/SceneryHeader.vue';
|
import SceneryHeader from '../components/SceneryView/SceneryHeader.vue';
|
||||||
@@ -66,6 +66,8 @@ enum SceneryViewMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
name: 'SceneryView',
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
SceneryInfo,
|
SceneryInfo,
|
||||||
SceneryTimetable,
|
SceneryTimetable,
|
||||||
@@ -111,9 +113,9 @@ export default defineComponent({
|
|||||||
onlineFrom: -1
|
onlineFrom: -1
|
||||||
}),
|
}),
|
||||||
|
|
||||||
activated() {
|
// activated() {
|
||||||
this.loadSelectedCheckpoint();
|
// this.loadSelectedCheckpoint();
|
||||||
},
|
// },
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -126,6 +128,10 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
currentMode() {
|
||||||
|
return this.$route.query.view?.toString() ?? 'SceneryTimetable';
|
||||||
|
},
|
||||||
|
|
||||||
stationInfo() {
|
stationInfo() {
|
||||||
return this.store.stationList.find(
|
return this.store.stationList.find(
|
||||||
(station) => station.name === this.station?.toString().replace(/_/g, ' ')
|
(station) => station.name === this.station?.toString().replace(/_/g, ' ')
|
||||||
@@ -134,14 +140,22 @@ export default defineComponent({
|
|||||||
|
|
||||||
onlineSceneryInfo() {
|
onlineSceneryInfo() {
|
||||||
return this.store.onlineSceneryList.find(
|
return this.store.onlineSceneryList.find(
|
||||||
(scenery) => scenery.name === this.station?.toString().replace(/_/g, ' ')
|
(scenery) =>
|
||||||
|
scenery.name === this.station?.toString().replace(/_/g, ' ') &&
|
||||||
|
scenery.region == this.store.region.id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
setViewMode(componentName: string) {
|
setViewMode(componentName: string) {
|
||||||
this.currentViewCompontent = componentName;
|
this.$router.push({
|
||||||
|
path: this.$route.path,
|
||||||
|
query: {
|
||||||
|
...this.$route.query,
|
||||||
|
view: componentName
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
loadSelectedCheckpoint() {
|
loadSelectedCheckpoint() {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { defineComponent } from 'vue';
|
|||||||
import StationTable from '../components/StationsView/StationTable.vue';
|
import StationTable from '../components/StationsView/StationTable.vue';
|
||||||
import StationFilterCard from '../components/StationsView/StationFilterCard.vue';
|
import StationFilterCard from '../components/StationsView/StationFilterCard.vue';
|
||||||
import { useStationFiltersStore } from '../store/stationFiltersStore';
|
import { useStationFiltersStore } from '../store/stationFiltersStore';
|
||||||
import { useStore } from '../store/store';
|
import { useStore } from '../store/mainStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@@ -38,7 +38,6 @@ export default defineComponent({
|
|||||||
store: useStore()
|
store: useStore()
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
computedStationList() {
|
computedStationList() {
|
||||||
return this.filterStore.filteredStationList;
|
return this.filterStore.filteredStationList;
|
||||||
|
|||||||
@@ -15,12 +15,11 @@
|
|||||||
import { computed, ComputedRef, defineComponent, provide, reactive, ref, watch } from 'vue';
|
import { computed, ComputedRef, defineComponent, provide, reactive, ref, watch } from 'vue';
|
||||||
import TrainOptions from '../components/TrainsView/TrainOptions.vue';
|
import TrainOptions from '../components/TrainsView/TrainOptions.vue';
|
||||||
import TrainTable from '../components/TrainsView/TrainTable.vue';
|
import TrainTable from '../components/TrainsView/TrainTable.vue';
|
||||||
import { trainFilters } from '../constants/Trains/TrainOptionsConsts';
|
|
||||||
import modalTrainMixin from '../mixins/modalTrainMixin';
|
import modalTrainMixin from '../mixins/modalTrainMixin';
|
||||||
import Train from '../scripts/interfaces/Train';
|
import Train from '../scripts/interfaces/Train';
|
||||||
import { filteredTrainList } from '../scripts/managers/trainFilterManager';
|
import { useStore } from '../store/mainStore';
|
||||||
import { useStore } from '../store/store';
|
import { TrainFilter, trainFilters } from '../components/TrainsView/typings';
|
||||||
import { TrainFilter } from '../scripts/interfaces/Trains/TrainFilter';
|
import { filteredTrainList } from '../managers/trainFilterManager';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@@ -70,7 +69,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const computedTrains: ComputedRef<Train[]> = computed(() => {
|
const computedTrains: ComputedRef<Train[]> = computed(() => {
|
||||||
return filteredTrainList(
|
return filteredTrainList(
|
||||||
store.trainList,
|
store.trainList.filter((train) => train.region == store.region.id),
|
||||||
searchedTrain.value,
|
searchedTrain.value,
|
||||||
searchedDriver.value,
|
searchedDriver.value,
|
||||||
sorterActive,
|
sorterActive,
|
||||||
@@ -83,7 +82,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
currentOptionsActive.value =
|
currentOptionsActive.value =
|
||||||
sT.length > 0 || sD.length > 0 || sA.id != 'routeDistance' || areFiltersActive;
|
sT.length > 0 || sD.length > 0 || sA.id != 'routeDistance' || areFiltersActive;
|
||||||
console.log(sA.id);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -115,7 +113,7 @@ export default defineComponent({
|
|||||||
@import '../styles/responsive.scss';
|
@import '../styles/responsive.scss';
|
||||||
|
|
||||||
.trains-view {
|
.trains-view {
|
||||||
min-height: 100%;
|
min-height: 600px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-10
@@ -10,19 +10,12 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"lib": [
|
|
||||||
"ESNext",
|
"lib": ["ESNext", "DOM"],
|
||||||
"DOM"
|
|
||||||
],
|
|
||||||
"types": ["vite/client", "vite-plugin-pwa/client"],
|
"types": ["vite/client", "vite-plugin-pwa/client"],
|
||||||
"skipLibCheck": true
|
"skipLibCheck": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||||
"src/**/*.ts",
|
|
||||||
"src/**/*.d.ts",
|
|
||||||
"src/**/*.tsx",
|
|
||||||
"src/**/*.vue"
|
|
||||||
],
|
|
||||||
"references": [
|
"references": [
|
||||||
{
|
{
|
||||||
"path": "./tsconfig.node.json"
|
"path": "./tsconfig.node.json"
|
||||||
|
|||||||
Reference in New Issue
Block a user