mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 05:18:11 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 57e88b9abc | |||
| 44ebf53798 | |||
| 145dc72b6b | |||
| b7f3761940 | |||
| ea7c49dfb3 | |||
| 5d6785813a | |||
| a0054aed14 | |||
| 471e6f5216 | |||
| a617eef00e | |||
| 38e700ecd6 | |||
| da1be0e10a | |||
| f49bb12948 | |||
| 02673a3d70 | |||
| 4ddc7345df | |||
| 5d822684c0 | |||
| 69fa15c70a | |||
| 9192067388 | |||
| 2b41e5b857 | |||
| 674680ff14 | |||
| 475bd2ff10 | |||
| 074d1eb155 | |||
| 378393de89 | |||
| 03e61083a7 | |||
| 0b746fce8c | |||
| 5883e710be | |||
| 3d0695a17b | |||
| 4adb76eeb0 | |||
| 4c41076519 | |||
| 77f61d17fd | |||
| 032a84cbcf |
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "stacjownik",
|
"name": "stacjownik",
|
||||||
"version": "1.13.0",
|
"version": "1.15.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ footer.app_footer {
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 1.1em;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|
||||||
background: #111;
|
background: #111;
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
<a href="https://td2.info.pl/profile/?u=20777" target="_blank">Spythere</a>
|
<a href="https://td2.info.pl/profile/?u=20777" target="_blank">Spythere</a>
|
||||||
{{ new Date().getUTCFullYear() }} |
|
{{ new Date().getUTCFullYear() }} |
|
||||||
<a :href="releaseURL" target="_blank">v{{ VERSION }}{{ isOnProductionHost ? '' : 'dev' }}</a>
|
<a :href="releaseURL" target="_blank">v{{ VERSION }}{{ isOnProductionHost ? '' : 'dev' }}</a>
|
||||||
|
<br />
|
||||||
|
<a href="https://discord.gg/x2mpNN3svk"><img :src="getIcon('discord', 'png')" alt=""> <b>{{ $t('footer.discord') }}</b></a>
|
||||||
|
|
||||||
<div style="display: none">∫ ukryta taktyczna całka do programowania w HTMLu</div>
|
<div style="display: none">∫ ukryta taktyczna całka do programowania w HTMLu</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M23.75 3.75H22.5V1.25H20V3.75H10V1.25H7.5V3.75H6.25C4.875 3.75 3.75 4.875 3.75 6.25V23.75C3.75 25.125 4.875 26.25 6.25 26.25H23.75C25.125 26.25 26.25 25.125 26.25 23.75V6.25C26.25 4.875 25.125 3.75 23.75 3.75ZM23.75 23.75H6.25V11.25H23.75V23.75ZM6.25 8.75V6.25H23.75V8.75H6.25ZM8.75 13.75H21.25V16.25H8.75V13.75ZM8.75 18.75H17.5V21.25H8.75V18.75Z" fill="#F2E147"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 477 B |
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M23.75 3.75H22.5V1.25H20V3.75H10V1.25H7.5V3.75H6.25C4.875 3.75 3.75 4.875 3.75 6.25V23.75C3.75 25.125 4.875 26.25 6.25 26.25H23.75C25.125 26.25 26.25 25.125 26.25 23.75V6.25C26.25 4.875 25.125 3.75 23.75 3.75ZM23.75 23.75H6.25V11.25H23.75V23.75ZM6.25 8.75V6.25H23.75V8.75H6.25ZM8.75 13.75H21.25V16.25H8.75V13.75ZM8.75 18.75H17.5V21.25H8.75V18.75Z" fill="#66FF6C"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 477 B |
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M23.75 3.75H22.5V1.25H20V3.75H10V1.25H7.5V3.75H6.25C4.875 3.75 3.75 4.875 3.75 6.25V23.75C3.75 25.125 4.875 26.25 6.25 26.25H23.75C25.125 26.25 26.25 25.125 26.25 23.75V6.25C26.25 4.875 25.125 3.75 23.75 3.75ZM23.75 23.75H6.25V11.25H23.75V23.75ZM6.25 8.75V6.25H23.75V8.75H6.25ZM8.75 13.75H21.25V16.25H8.75V13.75ZM8.75 18.75H17.5V21.25H8.75V18.75Z" fill="#898989"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 477 B |
@@ -6,16 +6,6 @@
|
|||||||
<img :src="getIcon('pl')" alt="icon-pl" @click="changeLang('en')" v-if="currentLang == 'pl'" />
|
<img :src="getIcon('pl')" alt="icon-pl" @click="changeLang('en')" v-if="currentLang == 'pl'" />
|
||||||
<img :src="getIcon('en', 'jpg')" alt="icon-en" @click="changeLang('pl')" v-else />
|
<img :src="getIcon('en', 'jpg')" alt="icon-en" @click="changeLang('pl')" v-else />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="icons-bottom">
|
|
||||||
<a href="https://www.paypal.com/paypalme/spythere" target="_blank">
|
|
||||||
<img :src="getIcon('dollar')" alt="icon paypal" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="https://discord.gg/x2mpNN3svk" target="_blank">
|
|
||||||
<img :src="getIcon('discord', 'png')" alt="icon discord" />
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="header_body">
|
<div class="header_body">
|
||||||
@@ -33,6 +23,12 @@
|
|||||||
<div class="info_counter">
|
<div class="info_counter">
|
||||||
<img :src="getIcon('dispatcher')" alt="icon dispatcher" />
|
<img :src="getIcon('dispatcher')" alt="icon dispatcher" />
|
||||||
<span class="text--primary">{{ onlineDispatchersCount }}</span>
|
<span class="text--primary">{{ onlineDispatchersCount }}</span>
|
||||||
|
|
||||||
|
<!-- <span class="g-tooltip">
|
||||||
|
<b class="text--primary">{{ factorU }}U</b>
|
||||||
|
<div class="content">Test</div>
|
||||||
|
</span> -->
|
||||||
|
|
||||||
<span class="text--grayed"> / </span>
|
<span class="text--grayed"> / </span>
|
||||||
<span class="text--primary">{{ onlineTrainsCount }}</span>
|
<span class="text--primary">{{ onlineTrainsCount }}</span>
|
||||||
<img :src="getIcon('train')" alt="icon train" />
|
<img :src="getIcon('train')" alt="icon train" />
|
||||||
@@ -98,11 +94,17 @@ export default defineComponent({
|
|||||||
onlineTrainsCount() {
|
onlineTrainsCount() {
|
||||||
return this.store.trainList.filter((train) => train.online).length;
|
return this.store.trainList.filter((train) => train.online).length;
|
||||||
},
|
},
|
||||||
|
|
||||||
onlineDispatchersCount() {
|
onlineDispatchersCount() {
|
||||||
return this.store.stationList.filter(
|
return this.store.stationList.filter(
|
||||||
(station) => station.onlineInfo && station.onlineInfo.region == this.store.region.id
|
(station) => station.onlineInfo && station.onlineInfo.region == this.store.region.id
|
||||||
).length;
|
).length;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
factorU() {
|
||||||
|
return this.onlineDispatchersCount == 0 ? '-' : (this.onlineTrainsCount / this.onlineDispatchersCount).toFixed(2);
|
||||||
|
},
|
||||||
|
|
||||||
computedRegions() {
|
computedRegions() {
|
||||||
return options.regions.map((region) => {
|
return options.regions.map((region) => {
|
||||||
const regionStationCount =
|
const regionStationCount =
|
||||||
@@ -135,22 +137,20 @@ export default defineComponent({
|
|||||||
|
|
||||||
.header {
|
.header {
|
||||||
&_body {
|
&_body {
|
||||||
max-width: 21em;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
max-width: 20em;
|
||||||
@include smallScreen {
|
|
||||||
max-width: 18em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&_container {
|
&_container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
position: relative;
|
|
||||||
|
|
||||||
width: 1350px;
|
|
||||||
padding: 0.5em 0.3em 0 0.3em;
|
|
||||||
border-radius: 0 0 1em 1em;
|
border-radius: 0 0 1em 1em;
|
||||||
|
|
||||||
|
@include smallScreen {
|
||||||
|
position: relative;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&_brand {
|
&_brand {
|
||||||
@@ -158,6 +158,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,9 +166,7 @@ export default defineComponent({
|
|||||||
&_info {
|
&_info {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr 1fr;
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
max-width: 100%;
|
font-size: 1.15em;
|
||||||
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&_links {
|
&_links {
|
||||||
@@ -184,58 +183,21 @@ export default defineComponent({
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
display: flex;
|
padding: 0.5em;
|
||||||
flex-direction: column;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: flex-end;
|
|
||||||
padding: 0.5em 0.5em;
|
|
||||||
|
|
||||||
@include smallScreen() {
|
@include smallScreen {
|
||||||
right: auto;
|
transform: translateX(85%);
|
||||||
left: 0.75em;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ICONS
|
// ICONS
|
||||||
.icons {
|
.icons-top {
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&-top {
|
|
||||||
img {
|
img {
|
||||||
width: 2.5em;
|
width: 2.5em;
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-bottom {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
a {
|
|
||||||
margin-left: 0.6em;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 1.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include smallScreen() {
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
a {
|
|
||||||
margin: 0.25em 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// COUNTER
|
// COUNTER
|
||||||
|
|||||||
@@ -164,7 +164,7 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { DataStatus } from '../../scripts/enums/DataStatus';
|
import { DataStatus } from '../../scripts/enums/DataStatus';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/store';
|
||||||
import { StoreState } from '../../store/storeTypes';
|
import { StoreState } from '../../scripts/interfaces/store/storeTypes';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
@@ -303,9 +303,11 @@ export default defineComponent({
|
|||||||
|
|
||||||
.status-indicator {
|
.status-indicator {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 110%;
|
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
|
|
||||||
|
transform: translateX(1.5em);
|
||||||
}
|
}
|
||||||
|
|
||||||
.indicator {
|
.indicator {
|
||||||
@@ -330,7 +332,7 @@ export default defineComponent({
|
|||||||
background-color: #171717;
|
background-color: #171717;
|
||||||
border-radius: 0.75em;
|
border-radius: 0.75em;
|
||||||
|
|
||||||
min-width: 13em;
|
width: 13em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
overflow: none;
|
overflow: none;
|
||||||
|
|
||||||
@@ -354,22 +356,16 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include midScreen() {
|
@include midScreen() {
|
||||||
left: 50%;
|
left: auto;
|
||||||
top: 100%;
|
right: 200%;
|
||||||
|
|
||||||
transform: translate(-50%, 0);
|
|
||||||
margin-left: 0;
|
|
||||||
margin-top: 0.75em;
|
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
border-left: 10px solid transparent;
|
|
||||||
border-right: 10px solid transparent;
|
border-right: 10px solid transparent;
|
||||||
border-bottom: 10px solid #171717;
|
border-left: 12px solid #171717;
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
|
||||||
top: 0;
|
transform: translate(100%, -50%);
|
||||||
left: 50%;
|
|
||||||
|
|
||||||
transform: translate(-50%, -100%);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,3 +375,4 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
<div class="select-box_content">
|
<div class="select-box_content">
|
||||||
<button class="selected" @click="toggleBox">
|
<button class="selected" @click="toggleBox">
|
||||||
<span>{{ computedSelectedItem.selectedValue || computedSelectedItem.value }}</span>
|
<span>{{ computedSelectedItem.selectedValue || computedSelectedItem.value }}</span>
|
||||||
|
|
||||||
|
<div class="arrow">
|
||||||
|
<img :src="listOpen ? getIcon('arrow-asc') : getIcon('arrow-desc')" alt="arrow-icon" />
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<ul class="options" :ref="(el) => (listRef = el as Element)">
|
<ul class="options" :ref="(el) => (listRef = el as Element)">
|
||||||
@@ -21,10 +25,6 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="arrow">
|
|
||||||
<img :src="listOpen ? getIcon('arrow-asc') : getIcon('arrow-desc')" alt="arrow-icon" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -129,46 +129,22 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.select-box {
|
.select-box {
|
||||||
position: relative;
|
display: flex;
|
||||||
width: auto;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow {
|
.arrow {
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
right: 0;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
img {
|
img {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
width: 1.35em;
|
width: 1.35em;
|
||||||
}
|
}
|
||||||
|
|
||||||
transform: translateY(-50%);
|
|
||||||
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button.selected {
|
button.selected {
|
||||||
background-color: transparent;
|
|
||||||
color: paleturquoise;
|
color: paleturquoise;
|
||||||
|
|
||||||
font-size: 1em;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
padding: 0.1em 0.5em;
|
padding: 0.1em 0.5em;
|
||||||
margin-right: 2em;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
background-color: #262626;
|
background-color: #262626;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition-group class="journal-list" tag="ul" name="list-anim">
|
<transition-group class="journal-list" tag="ul" name="list-anim">
|
||||||
<li
|
<li
|
||||||
v-for="{ timetable, sceneryList, ...item } in computedTimetableHistory"
|
v-for="{ timetable, sceneryList, stockHistoryComp, ...item } in computedTimetableHistory"
|
||||||
class="journal_item"
|
class="journal_item"
|
||||||
:key="timetable.id"
|
:key="timetable.id"
|
||||||
@click="item.showExtra.value = !item.showExtra.value"
|
@click="item.showExtra.value = !item.showExtra.value"
|
||||||
@@ -16,6 +16,12 @@
|
|||||||
style="cursor: pointer"
|
style="cursor: pointer"
|
||||||
>
|
>
|
||||||
<span class="text--grayed">#{{ timetable.id }}</span>
|
<span class="text--grayed">#{{ timetable.id }}</span>
|
||||||
|
|
||||||
|
<span class="badges" v-if="timetable.skr || timetable.twr">
|
||||||
|
<span class="train-badge twr" v-if="timetable.twr" :title="$t('general.TWR')">TWR</span>
|
||||||
|
<span class="train-badge skr" v-if="timetable.skr" :title="$t('general.SKR')">SKR</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
<strong class="text--primary">
|
<strong class="text--primary">
|
||||||
{{ timetable.trainCategoryCode }}
|
{{ timetable.trainCategoryCode }}
|
||||||
@@ -129,24 +135,58 @@
|
|||||||
<img :src="getIcon(`arrow-${item.showExtra.value ? 'asc' : 'desc'}`)" alt="Arrow" />
|
<img :src="getIcon(`arrow-${item.showExtra.value ? 'asc' : 'desc'}`)" alt="Arrow" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="info-extended" v-if="timetable.stockString && item.showExtra.value">
|
<!-- Dodatkowe informacje -->
|
||||||
|
<div class="info-extended" v-if="timetable.stockString && timetable.stockMass && item.showExtra.value">
|
||||||
<hr />
|
<hr />
|
||||||
<div>
|
|
||||||
<span class="badge info-badge">
|
<div class="stock-specs">
|
||||||
|
<span class="badge specs-badge">
|
||||||
<span>{{ $t('journal.stock-max-speed') }}</span>
|
<span>{{ $t('journal.stock-max-speed') }}</span>
|
||||||
<span>{{ timetable.maxSpeed }}km/h</span>
|
<span>{{ timetable.maxSpeed }}km/h</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="badge info-badge">
|
<span class="badge specs-badge">
|
||||||
<span>{{ $t('journal.stock-length') }}</span>
|
<span>{{ $t('journal.stock-length') }}</span>
|
||||||
<span>{{ timetable.stockLength }}m</span>
|
<span>
|
||||||
|
{{
|
||||||
|
item.currentHistoryIndex.value == 0
|
||||||
|
? timetable.stockLength
|
||||||
|
: stockHistoryComp[item.currentHistoryIndex.value].stockLength || timetable.stockLength
|
||||||
|
}}m
|
||||||
</span>
|
</span>
|
||||||
<span class="badge info-badge">
|
</span>
|
||||||
|
<span class="badge specs-badge">
|
||||||
<span>{{ $t('journal.stock-mass') }}</span>
|
<span>{{ $t('journal.stock-mass') }}</span>
|
||||||
<span>{{ Math.floor(timetable.stockMass! / 1000) }}t</span>
|
<span>
|
||||||
|
{{
|
||||||
|
Math.floor(
|
||||||
|
(item.currentHistoryIndex.value == 0
|
||||||
|
? timetable.stockMass!
|
||||||
|
: stockHistoryComp[item.currentHistoryIndex.value].stockMass || timetable.stockMass) / 1000
|
||||||
|
)
|
||||||
|
}}t
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="stock-history" v-if="stockHistoryComp.length > 1">
|
||||||
|
<button
|
||||||
|
class="btn--action"
|
||||||
|
v-for="(sh, i) in stockHistoryComp"
|
||||||
|
:data-checked="i == item.currentHistoryIndex.value"
|
||||||
|
@click.stop="item.currentHistoryIndex.value = i"
|
||||||
|
>
|
||||||
|
{{ sh.updatedAt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ul class="stock-list">
|
<ul class="stock-list">
|
||||||
<li v-for="(car, i) in timetable.stockString.split(';')" :key="i">
|
<li
|
||||||
|
v-for="(car, i) in (item.currentHistoryIndex.value == 0
|
||||||
|
? timetable.stockString
|
||||||
|
: stockHistoryComp[item.currentHistoryIndex.value].stockString
|
||||||
|
).split(';')"
|
||||||
|
:key="i"
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
@error="onImageError"
|
@error="onImageError"
|
||||||
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${car.split(':')[0]}.png`"
|
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${car.split(':')[0]}.png`"
|
||||||
@@ -168,7 +208,6 @@ import imageMixin from '../../mixins/imageMixin';
|
|||||||
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
||||||
import styleMixin from '../../mixins/styleMixin';
|
import styleMixin from '../../mixins/styleMixin';
|
||||||
import { TimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
|
import { TimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
|
||||||
import { TimetableStop } from '../../scripts/interfaces/api/TrainAPIData';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -185,7 +224,24 @@ export default defineComponent({
|
|||||||
return this.timetableHistory.map((timetable) => ({
|
return this.timetableHistory.map((timetable) => ({
|
||||||
timetable,
|
timetable,
|
||||||
sceneryList: this.getSceneryList(timetable),
|
sceneryList: this.getSceneryList(timetable),
|
||||||
|
stockHistoryComp: timetable.stockHistory
|
||||||
|
.slice()
|
||||||
|
.reverse()
|
||||||
|
.map((h) => {
|
||||||
|
const historyData = h.split('@');
|
||||||
|
|
||||||
|
return {
|
||||||
|
updatedAt: new Date(Number(historyData[0])).toLocaleTimeString(this.$i18n.locale, {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
}),
|
||||||
|
stockString: historyData[1],
|
||||||
|
stockMass: Number(historyData[2]) || undefined,
|
||||||
|
stockLength: Number(historyData[3]) || undefined,
|
||||||
|
};
|
||||||
|
}),
|
||||||
showExtra: ref(false),
|
showExtra: ref(false),
|
||||||
|
currentHistoryIndex: ref(0),
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -292,6 +348,7 @@ hr {
|
|||||||
|
|
||||||
.general-train {
|
.general-train {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.25em;
|
gap: 0.25em;
|
||||||
}
|
}
|
||||||
@@ -308,6 +365,45 @@ ul.stock-list {
|
|||||||
color: #aaa;
|
color: #aaa;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
li > img {
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
max-height: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.stock-specs {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
|
||||||
|
.specs-badge {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
span:last-child {
|
||||||
|
color: black;
|
||||||
|
background-color: $accentCol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.badges {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.25em;
|
||||||
|
|
||||||
|
// badge.scss
|
||||||
|
}
|
||||||
|
|
||||||
|
.stock-history {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5em;
|
||||||
|
margin-top: 1em;
|
||||||
|
|
||||||
|
button[data-checked='true'] {
|
||||||
|
color: $accentCol;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.scenery-list {
|
.scenery-list {
|
||||||
@@ -328,13 +424,6 @@ ul.stock-list {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-badge {
|
|
||||||
span:last-child {
|
|
||||||
color: black;
|
|
||||||
background-color: $accentCol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include smallScreen {
|
@include smallScreen {
|
||||||
.info-general {
|
.info-general {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -343,6 +432,10 @@ ul.stock-list {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.general-train {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.info-route {
|
.info-route {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -351,5 +444,13 @@ ul.stock-list {
|
|||||||
.btn--show {
|
.btn--show {
|
||||||
margin: 1em auto 0 auto;
|
margin: 1em auto 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stock-specs {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stock-history {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
{{ station.name }}
|
{{ station.name }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<div class="scenery-abbrev">{{ $t('scenery.abbrev') }} <b>{{ station.generalInfo?.abbr }}</b></div>
|
||||||
|
|
||||||
<div class="scenery-hash" v-if="station.onlineInfo?.hash">#{{ station.onlineInfo.hash }}</div>
|
<div class="scenery-hash" v-if="station.onlineInfo?.hash">#{{ station.onlineInfo.hash }}</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
@@ -28,16 +30,20 @@ export default defineComponent({
|
|||||||
|
|
||||||
.scenery-name {
|
.scenery-name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
font-size: 3em;
|
font-size: 3em;
|
||||||
|
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scenery-abbrev {
|
||||||
|
font-size: 1.3em;
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
.scenery-hash {
|
.scenery-hash {
|
||||||
|
margin-top: 0.5em;
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,9 @@
|
|||||||
style="color: salmon; text-decoration: underline; font-weight: bold"
|
style="color: salmon; text-decoration: underline; font-weight: bold"
|
||||||
:href="station.generalInfo.projectUrl"
|
:href="station.generalInfo.projectUrl"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{ station.generalInfo.project }}</a
|
|
||||||
>
|
>
|
||||||
|
{{ station.generalInfo.project }}
|
||||||
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,15 @@
|
|||||||
<table v-else-if="sceneryHistoryList.length">
|
<table v-else-if="sceneryHistoryList.length">
|
||||||
<thead>
|
<thead>
|
||||||
<th>{{ $t('scenery.timetables-history-id') }}</th>
|
<th>{{ $t('scenery.timetables-history-id') }}</th>
|
||||||
<th>{{ $t('scenery.timetables-history-number')}}</th>
|
<th>{{ $t('scenery.timetables-history-number') }}</th>
|
||||||
<th>{{ $t('scenery.timetables-history-route')}}</th>
|
<th>{{ $t('scenery.timetables-history-route') }}</th>
|
||||||
<th>{{ $t('scenery.timetables-history-driver')}}</th>
|
<th>{{ $t('scenery.timetables-history-driver') }}</th>
|
||||||
<th>{{ $t('scenery.timetables-history-author')}}</th>
|
<th>{{ $t('scenery.timetables-history-author') }}</th>
|
||||||
<th>{{ $t('scenery.timetables-history-date')}}</th>
|
<th>{{ $t('scenery.timetables-history-date') }}</th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="historyItem in sceneryHistoryList" @click="test">
|
<tr v-for="historyItem in sceneryHistoryList">
|
||||||
<td>
|
<td>
|
||||||
<router-link :to="`/journal/timetables?timetableId=${historyItem.id}`">#{{ historyItem.id }}</router-link>
|
<router-link :to="`/journal/timetables?timetableId=${historyItem.id}`">#{{ historyItem.id }}</router-link>
|
||||||
</td>
|
</td>
|
||||||
@@ -40,31 +40,6 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div class="list-warning" v-else>{{ $t('scenery.history-list-empty') }}</div>
|
<div class="list-warning" v-else>{{ $t('scenery.history-list-empty') }}</div>
|
||||||
|
|
||||||
<!-- <ul class="history-list" v-else>
|
|
||||||
<li class="list-item" v-for="historyItem in sceneryHistoryList">
|
|
||||||
<div>
|
|
||||||
<b>{{ localeDay(historyItem.beginDate, $i18n.locale) }}</b>
|
|
||||||
{{ localeTime(historyItem.beginDate, $i18n.locale) }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<router-link :to="`/journal/timetables?timetableId=${historyItem.id}`">
|
|
||||||
<span class="text--grayed"> #{{ historyItem.id }} </span>
|
|
||||||
<b class="text--primary"> {{ historyItem.trainCategoryCode }} {{ historyItem.trainNo }}</b>
|
|
||||||
<div>{{ historyItem.driverName }}</div>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>{{ historyItem.route.replace('|', ' -> ') }}</div>
|
|
||||||
<div>
|
|
||||||
{{ $t('scenery.timetable-author-title') }}:
|
|
||||||
<b v-if="historyItem.authorName">{{ historyItem.authorName }}</b>
|
|
||||||
<i v-else>{{ $t('scenery.timetable-author-unknown') }}</i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul> -->
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -99,19 +74,15 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
async fetchAPIData(countFrom = 0, countLimit = 15) {
|
async fetchAPIData(countFrom = 0, countLimit = 15) {
|
||||||
try {
|
try {
|
||||||
const requestString = `${URLs.stacjownikAPI}/api/getSceneryTimetables?name=${this.station.name}&countFrom=${countFrom}&countLimit=${countLimit}`;
|
const requestString = `${URLs.stacjownikAPI}/api/getIssuedTimetables?name=${this.station.name}&countFrom=${countFrom}&countLimit=${countLimit}`;
|
||||||
const historyAPIData: SceneryTimetableHistory = await (await axios.get(requestString)).data;
|
const historyAPIData: SceneryTimetableHistory = await (await axios.get(requestString)).data;
|
||||||
|
|
||||||
this.sceneryHistoryList = historyAPIData.sceneryTimetables;
|
this.sceneryHistoryList = historyAPIData.timetables;
|
||||||
this.dataStatus = DataStatus.Loaded;
|
this.dataStatus = DataStatus.Loaded;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
test() {
|
|
||||||
console.log('test');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
components: { Loading },
|
components: { Loading },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,47 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="general-status">
|
<div class="general-status">
|
||||||
<span :class="scheduledTrain.stopStatus">
|
<span :class="computedScheduledTrain.stopStatus" :title="computedScheduledTrain.stopStatusDescription">
|
||||||
<span v-if="scheduledTrain.stopStatus == 'arriving'">
|
{{ computedScheduledTrain.stopStatusIndicator }}
|
||||||
<span v-if="scheduledTrain.prevDepartureLine">({{ scheduledTrain.prevDepartureLine }})</span>
|
|
||||||
{{ scheduledTrain.prevStationName }}
|
|
||||||
><span v-if="scheduledTrain.nextArrivalLine"> ({{ scheduledTrain.nextArrivalLine }}) </span>
|
|
||||||
{{ scheduledTrain.nextStationName || '---' }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="scheduledTrain.stopStatus == 'departed'">
|
|
||||||
>> <span v-if="scheduledTrain.nextArrivalLine"> ({{ scheduledTrain.nextArrivalLine }}) </span>
|
|
||||||
{{ scheduledTrain.nextStationName }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="scheduledTrain.stopStatus == 'departed-away'">
|
|
||||||
>>>
|
|
||||||
<span v-if="scheduledTrain.nextArrivalLine"> ({{ scheduledTrain.nextArrivalLine }}) </span>
|
|
||||||
{{ scheduledTrain.nextStationName }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="scheduledTrain.stopStatus == 'online'">
|
|
||||||
>
|
|
||||||
<span v-if="scheduledTrain.nextArrivalLine">
|
|
||||||
({{ scheduledTrain.nextArrivalLine }}) {{ scheduledTrain.nextStationName }}
|
|
||||||
</span>
|
|
||||||
<span v-else-if="!scheduledTrain.nextStationName">{{ $t('timetables.end') }}</span>
|
|
||||||
<span v-else>{{ scheduledTrain.nextStationName }}</span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="scheduledTrain.stopStatus == 'stopped'">
|
|
||||||
>
|
|
||||||
<span v-if="scheduledTrain.nextArrivalLine"> ({{ scheduledTrain.nextArrivalLine }}) </span>
|
|
||||||
{{ scheduledTrain.nextStationName }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="scheduledTrain.stopStatus == 'terminated'">X {{ $t('timetables.terminated') }}</span>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import ScheduledTrain from '../../scripts/interfaces/ScheduledTrain';
|
import { ScheduledTrain, StopStatus } from '../../scripts/interfaces/ScheduledTrain';
|
||||||
|
|
||||||
|
interface ScheduledTrainComp extends ScheduledTrain {
|
||||||
|
stopStatusIndicator: string;
|
||||||
|
stopStatusDescription: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -50,6 +22,58 @@ export default defineComponent({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
computedScheduledTrain(): ScheduledTrainComp {
|
||||||
|
const { prevDepartureLine, prevStationName, stopStatus, nextArrivalLine, nextStationName } = this.scheduledTrain;
|
||||||
|
|
||||||
|
const prevDepartureIndicator = prevDepartureLine ? `(${prevDepartureLine}) ${prevStationName}` : '---';
|
||||||
|
const nextArrivalIndicator = nextArrivalLine ? `(${nextArrivalLine}) ${nextStationName}` : '---';
|
||||||
|
|
||||||
|
let stopStatusDescription = '',
|
||||||
|
stopStatusIndicator = '';
|
||||||
|
|
||||||
|
switch (stopStatus) {
|
||||||
|
case StopStatus.arriving:
|
||||||
|
stopStatusIndicator = `${this.$t('timetables.from')}: ${prevDepartureIndicator}`;
|
||||||
|
stopStatusDescription = this.$t('timetables.desc-arriving', { prevStationName, prevDepartureLine });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StopStatus.online:
|
||||||
|
case StopStatus.stopped:
|
||||||
|
stopStatusIndicator = nextArrivalLine
|
||||||
|
? `${this.$t('timetables.to')}: ${nextArrivalIndicator}`
|
||||||
|
: `${this.$t('timetables.desc-end')}`;
|
||||||
|
stopStatusDescription = nextArrivalLine
|
||||||
|
? this.$t(`timetables.desc-${stopStatus}`, { nextStationName, nextArrivalLine })
|
||||||
|
: '';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StopStatus.departed:
|
||||||
|
stopStatusIndicator = `${this.$t('timetables.to')}: ${nextArrivalIndicator}`;
|
||||||
|
stopStatusDescription = this.$t('timetables.desc-departed', { nextStationName, nextArrivalLine });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StopStatus['departed-away']:
|
||||||
|
stopStatusIndicator = `${this.$t('timetables.to')}: ${nextArrivalIndicator}`;
|
||||||
|
stopStatusDescription = this.$t('timetables.desc-departed-away', { nextStationName, nextArrivalLine });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StopStatus.terminated:
|
||||||
|
stopStatusIndicator = `X ${this.$t('timetables.desc-terminated')}`;
|
||||||
|
stopStatusDescription = this.$t('timetables.desc-terminated');
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...this.scheduledTrain,
|
||||||
|
stopStatusDescription,
|
||||||
|
stopStatusIndicator,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -86,3 +110,4 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,6 @@ export default defineComponent({
|
|||||||
handleDbClick(e: Event) {
|
handleDbClick(e: Event) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
|
||||||
const lastClicked = this.filterStore.lastClickedFilterId == this.option.id;
|
|
||||||
console.log(this.filterStore.lastClickedFilterId);
|
|
||||||
this.filterStore.lastClickedFilterId = this.option.id;
|
this.filterStore.lastClickedFilterId = this.option.id;
|
||||||
this.option.value = true;
|
this.option.value = true;
|
||||||
|
|
||||||
@@ -96,51 +93,8 @@ button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&[data-selected='true'] {
|
&[data-selected='true'] {
|
||||||
// &.reality {
|
|
||||||
// background-color: $realityCol;
|
|
||||||
// box-shadow: 0 0 6px 1px $realityCol;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &.access {
|
|
||||||
// background-color: $accessCol;
|
|
||||||
// box-shadow: 0 0 6px 1px $accessCol;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &.control {
|
|
||||||
// background-color: $controlCol;
|
|
||||||
// box-shadow: 0 0 6px 1px $controlCol;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &.signals {
|
|
||||||
// background-color: $signalCol;
|
|
||||||
// box-shadow: 0 0 6px 1px $signalCol;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &.routes {
|
|
||||||
// background-color: $routesCol;
|
|
||||||
// box-shadow: 0 0 6px 1px $routesCol;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &.status {
|
|
||||||
// background-color: $statusCol;
|
|
||||||
// box-shadow: 0 0 6px 1px $statusCol;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &.save {
|
|
||||||
// background-color: $saveCol;
|
|
||||||
// box-shadow: 0 0 6px 1px $saveCol;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &.troll {
|
|
||||||
// background-color: firebrick;
|
|
||||||
// box-shadow: 0 0 6px 1px firebrick;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// & {
|
|
||||||
background-color: forestgreen;
|
background-color: forestgreen;
|
||||||
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -128,7 +128,6 @@ import { useStore } from '../../store/store';
|
|||||||
|
|
||||||
import ActionButton from '../Global/ActionButton.vue';
|
import ActionButton from '../Global/ActionButton.vue';
|
||||||
import FilterOption from './FilterOption.vue';
|
import FilterOption from './FilterOption.vue';
|
||||||
import { filterInitStates } from '../../store/constants/initFilterStates';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { ActionButton, FilterOption },
|
components: { ActionButton, FilterOption },
|
||||||
|
|||||||
@@ -8,26 +8,36 @@
|
|||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th v-for="(id, i) in headIds" :key="id" @click="() => changeSorter(i)">
|
<th
|
||||||
|
v-for="(headerName, i) in headIds"
|
||||||
|
:key="headerName"
|
||||||
|
@click="changeSorter(headerName)"
|
||||||
|
class="header-text"
|
||||||
|
>
|
||||||
<span class="header_wrapper">
|
<span class="header_wrapper">
|
||||||
<div v-html="$t(`sceneries.${id}`)"></div>
|
<div v-html="$t(`sceneries.${headerName}`)"></div>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
class="sort-icon"
|
class="sort-icon"
|
||||||
v-if="sorterActive.index == i"
|
v-if="sorterActive.headerName == headerName"
|
||||||
:src="sorterActive.dir == 1 ? getIcon('arrow-asc') : getIcon('arrow-desc')"
|
:src="sorterActive.dir == 1 ? getIcon('arrow-asc') : getIcon('arrow-desc')"
|
||||||
alt="sort icon"
|
alt="sort icon"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
<th v-for="(id, i) in headIconsIds" :key="id" @click="() => changeSorter(i + 7)">
|
<th
|
||||||
|
v-for="(headerName, i) in headIconsIds"
|
||||||
|
:key="headerName"
|
||||||
|
@click="changeSorter(headerName)"
|
||||||
|
class="header-image"
|
||||||
|
>
|
||||||
<span class="header_wrapper">
|
<span class="header_wrapper">
|
||||||
<img :src="getIcon(id)" :alt="id" :title="$t(`sceneries.${id}s`)" />
|
<img :src="getIcon(headerName)" :alt="headerName" :title="$t(`sceneries.${headerName}`)" />
|
||||||
|
|
||||||
<img
|
<img
|
||||||
class="sort-icon"
|
class="sort-icon"
|
||||||
v-if="sorterActive.index == i + 7"
|
v-if="sorterActive.headerName == headerName"
|
||||||
:src="sorterActive.dir == 1 ? getIcon('arrow-asc') : getIcon('arrow-desc')"
|
:src="sorterActive.dir == 1 ? getIcon('arrow-asc') : getIcon('arrow-desc')"
|
||||||
alt="sort icon"
|
alt="sort icon"
|
||||||
/>
|
/>
|
||||||
@@ -190,25 +200,31 @@
|
|||||||
|
|
||||||
<td class="station_users" :class="{ inactive: !station.onlineInfo }">
|
<td class="station_users" :class="{ inactive: !station.onlineInfo }">
|
||||||
<span>
|
<span>
|
||||||
<span class="highlight">{{ station.onlineInfo?.currentUsers || '0' }}</span>
|
<span class="highlight">{{ station.onlineInfo?.currentUsers || 0 }}</span>
|
||||||
/
|
/
|
||||||
<span>{{ station.onlineInfo?.maxUsers || '0' }}</span>
|
<span class="highlight">{{ station.onlineInfo?.maxUsers || 0 }}</span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="station_spawns" :class="{ inactive: !station.onlineInfo }">
|
<td class="station_spawns" :class="{ inactive: !station.onlineInfo }">
|
||||||
<span class="highlight">{{ station.onlineInfo?.spawns.length || '0' }}</span>
|
<span>{{ station.onlineInfo?.spawns.length || 0 }}</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="station_schedules" :class="{ inactive: !station.onlineInfo }">
|
<td class="station_schedules" style="width: 30px" :class="{ inactive: !station.onlineInfo }">
|
||||||
<span>
|
|
||||||
<span class="highlight">
|
<span class="highlight">
|
||||||
{{ station.onlineInfo?.scheduledTrains?.length || '0' }}
|
{{ station.onlineInfo?.scheduledTrains?.length || 0 }}
|
||||||
</span>
|
</span>
|
||||||
/
|
</td>
|
||||||
<span style="color: #bbb">
|
|
||||||
{{ station.onlineInfo?.scheduledTrains?.filter((train) => train.stopInfo.confirmed).length || '0' }}
|
<td class="station_schedules" style="width: 30px" :class="{ inactive: !station.onlineInfo }">
|
||||||
|
<span style="color: #ccc">
|
||||||
|
{{ station.onlineInfo?.scheduledTrains?.filter((train) => !train.stopInfo.confirmed).length || 0 }}
|
||||||
</span>
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="station_schedules" style="width: 30px" :class="{ inactive: !station.onlineInfo }">
|
||||||
|
<span style="color: #66ff6c">
|
||||||
|
{{ station.onlineInfo?.scheduledTrains?.filter((train) => train.stopInfo.confirmed).length || 0 }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -236,6 +252,7 @@ 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/store';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
|
import { HeadIdsTypes, headIconsIds, headIds } from '../../scripts/data/stationHeaderNames';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -249,8 +266,8 @@ export default defineComponent({
|
|||||||
mixins: [styleMixin, dateMixin, stationInfoMixin, returnBtnMixin, imageMixin],
|
mixins: [styleMixin, dateMixin, stationInfoMixin, returnBtnMixin, imageMixin],
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
headIds: ['station', 'min-lvl', 'status', 'dispatcher', 'dispatcher-lvl', 'routes', 'general'],
|
headIconsIds,
|
||||||
headIconsIds: ['user', 'spawn', 'timetable'],
|
headIds,
|
||||||
lastSelectedStationName: '',
|
lastSelectedStationName: '',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@@ -291,8 +308,10 @@ export default defineComponent({
|
|||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
},
|
},
|
||||||
|
|
||||||
changeSorter(i: number) {
|
changeSorter(headerName: HeadIdsTypes) {
|
||||||
this.stationFiltersStore.changeSorter(i);
|
if (headerName == 'general' || headerName == 'routes') return;
|
||||||
|
|
||||||
|
this.stationFiltersStore.changeSorter(headerName);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -349,9 +368,15 @@ table {
|
|||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
||||||
min-width: 75px;
|
&.header-text {
|
||||||
|
min-width: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
padding: 0.5em;
|
&.header-image {
|
||||||
|
min-width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
padding: 0.5em 0.25em;
|
||||||
background-color: $bgCol;
|
background-color: $bgCol;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<span class="timetable-id" v-if="train.timetableData">#{{ train.timetableData.timetableId }}</span>
|
<span class="timetable-id" v-if="train.timetableData">#{{ train.timetableData.timetableId }}</span>
|
||||||
|
|
||||||
<span class="timetable_warnings" v-if="train.timetableData?.TWR || train.timetableData?.SKR">
|
<span class="timetable_warnings" v-if="train.timetableData?.TWR || train.timetableData?.SKR">
|
||||||
<span class="train-badge twr" v-if="train.timetableData?.TWR">TWR</span>
|
<span class="train-badge twr" v-if="train.timetableData?.TWR" :title="$t('general.TWR')">TWR</span>
|
||||||
<span class="train-badge skr" v-if="train.timetableData?.SKR">SKR</span>
|
<span class="train-badge skr" v-if="train.timetableData?.SKR" :title="$t('general.SKR')">SKR</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<strong>
|
<strong>
|
||||||
@@ -118,7 +118,6 @@ export default defineComponent({
|
|||||||
@import '../../styles/responsive.scss';
|
@import '../../styles/responsive.scss';
|
||||||
@import '../../styles/badge.scss';
|
@import '../../styles/badge.scss';
|
||||||
|
|
||||||
|
|
||||||
.image-warning {
|
.image-warning {
|
||||||
height: 1em;
|
height: 1em;
|
||||||
|
|
||||||
@@ -182,26 +181,6 @@ export default defineComponent({
|
|||||||
gap: 0.25em;
|
gap: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.train-badge {
|
|
||||||
padding: 0.1em 0.2em;
|
|
||||||
border-radius: 0.2em;
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
font-size: 0.9em;
|
|
||||||
|
|
||||||
&.twr {
|
|
||||||
background-color: var(--clr-twr);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.skr {
|
|
||||||
background-color: var(--clr-skr);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.offline {
|
|
||||||
background-color: #9c362b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.train-driver {
|
.train-driver {
|
||||||
&.supporter {
|
&.supporter {
|
||||||
color: orange;
|
color: orange;
|
||||||
@@ -218,9 +197,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
.timetable_warnings {
|
.timetable_warnings {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.2em;
|
gap: 0.25em;
|
||||||
|
|
||||||
color: black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.timetable_progress {
|
.timetable_progress {
|
||||||
|
|||||||
@@ -202,7 +202,6 @@ ul.stock-list {
|
|||||||
|
|
||||||
img {
|
img {
|
||||||
max-height: 60px;
|
max-height: 60px;
|
||||||
max-width: 320px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+26
-6
@@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"general": {
|
"general": {
|
||||||
"and": " and ",
|
"and": " and ",
|
||||||
"refresh": "REFRESH"
|
"refresh": "REFRESH",
|
||||||
|
"TWR": "High risk freight train",
|
||||||
|
"SKR": "Train with exceeded gauge"
|
||||||
},
|
},
|
||||||
"app": {
|
"app": {
|
||||||
"sceneries": "SCENERIES",
|
"sceneries": "SCENERIES",
|
||||||
@@ -15,6 +17,9 @@
|
|||||||
"migration-confirm": "Roger that!",
|
"migration-confirm": "Roger that!",
|
||||||
"offline": "App is in the offline mode!"
|
"offline": "App is in the offline mode!"
|
||||||
},
|
},
|
||||||
|
"footer": {
|
||||||
|
"discord": "Stacjownik Discord server"
|
||||||
|
},
|
||||||
"update": {
|
"update": {
|
||||||
"title": "New version of the app is available!",
|
"title": "New version of the app is available!",
|
||||||
"paragraph1": "Enjoy the application and may the green signal be with you!",
|
"paragraph1": "Enjoy the application and may the green signal be with you!",
|
||||||
@@ -208,9 +213,11 @@
|
|||||||
"dispatcher-lvl": "Dispatcher\nlevel",
|
"dispatcher-lvl": "Dispatcher\nlevel",
|
||||||
"routes": "Routes\ndouble / single",
|
"routes": "Routes\ndouble / single",
|
||||||
"general": "General info",
|
"general": "General info",
|
||||||
"users": "Drivers online",
|
"user": "Drivers online",
|
||||||
"spawns": "Spawns online",
|
"spawn": "Spawns online",
|
||||||
"timetables": "Active timetables",
|
"timetableAll": "Active timetables",
|
||||||
|
"timetableConfirmed": "Confirmed timetables",
|
||||||
|
"timetableUnconfirmed": "Unconfirmed timetables",
|
||||||
"no-stations": "No stations to show here!",
|
"no-stations": "No stations to show here!",
|
||||||
"scenery-search": "Search for scenery..."
|
"scenery-search": "Search for scenery..."
|
||||||
},
|
},
|
||||||
@@ -284,7 +291,7 @@
|
|||||||
"stock-info": "EXTRA INFO",
|
"stock-info": "EXTRA INFO",
|
||||||
"stock-length": "Length",
|
"stock-length": "Length",
|
||||||
"stock-mass": "Mass",
|
"stock-mass": "Mass",
|
||||||
"stock-max-speed": "Maximum registered speed",
|
"stock-max-speed": "Max. speed",
|
||||||
|
|
||||||
"load-data": "Load further data...",
|
"load-data": "Load further data...",
|
||||||
|
|
||||||
@@ -328,6 +335,7 @@
|
|||||||
"history-btn": "View the dispatcher history",
|
"history-btn": "View the dispatcher history",
|
||||||
"info-btn": "Return to the scenery view",
|
"info-btn": "Return to the scenery view",
|
||||||
"authors-title": "Scenery author | Scenery authors",
|
"authors-title": "Scenery author | Scenery authors",
|
||||||
|
"abbrev": "Station symbol:",
|
||||||
"lines-title": "Real lines",
|
"lines-title": "Real lines",
|
||||||
"project-title": "Project name",
|
"project-title": "Project name",
|
||||||
"one-way-routes": "One way routes",
|
"one-way-routes": "One way routes",
|
||||||
@@ -368,7 +376,19 @@
|
|||||||
"end": "Timetable terminates here",
|
"end": "Timetable terminates here",
|
||||||
"terminated": "Timetable terminated",
|
"terminated": "Timetable terminated",
|
||||||
"begins": "BEGINS HERE",
|
"begins": "BEGINS HERE",
|
||||||
"terminates": "TERMINATES\nHERE"
|
"terminates": "TERMINATES\nHERE",
|
||||||
|
|
||||||
|
"from": "FROM",
|
||||||
|
"to": "TO",
|
||||||
|
|
||||||
|
"desc-arriving": "The train is not here yet. It's going to come from: {prevStationName} (szlak {prevDepartureLine})",
|
||||||
|
"desc-online": "The train is at the station. It's going to leave to: {nextStationName} (szlak {nextArrivalLine})",
|
||||||
|
"desc-stopped": "The train is at the station and is stopped. It's going to leave towards: {nextStationName} (szlak {nextArrivalLine})",
|
||||||
|
"desc-next-arrival": "Leaves towards: {nextStationName} (szlak {nextArrivalLine})",
|
||||||
|
"desc-departed": "The train is at the station and it's been departed. Leaves towards: {nextStationName} (szlak {nextArrivalLine})",
|
||||||
|
"desc-departed-away": "The train has been departed to: {nextStationName} (szlak {nextArrivalLine})",
|
||||||
|
"desc-end": "The train terminates here",
|
||||||
|
"desc-terminated": "The train has been terminated"
|
||||||
},
|
},
|
||||||
"history": {
|
"history": {
|
||||||
"title": "TIMETABLE JOURNAL",
|
"title": "TIMETABLE JOURNAL",
|
||||||
|
|||||||
+27
-8
@@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"general": {
|
"general": {
|
||||||
"and": " oraz ",
|
"and": " oraz ",
|
||||||
"refresh": "ODŚWIEŻ"
|
"refresh": "ODŚWIEŻ",
|
||||||
|
"TWR": "Towar niebezpieczny wysokiego ryzyka",
|
||||||
|
"SKR": "Przekroczona skrajnia"
|
||||||
},
|
},
|
||||||
"app": {
|
"app": {
|
||||||
"sceneries": "SCENERIE",
|
"sceneries": "SCENERIE",
|
||||||
@@ -15,7 +17,9 @@
|
|||||||
"migration-confirm": "Przyjąłem!",
|
"migration-confirm": "Przyjąłem!",
|
||||||
"offline": "Aplikacja w trybie offline!"
|
"offline": "Aplikacja w trybie offline!"
|
||||||
},
|
},
|
||||||
|
"footer": {
|
||||||
|
"discord": "Serwer Discord Stacjownika"
|
||||||
|
},
|
||||||
"update": {
|
"update": {
|
||||||
"title": "Nowa wersja Stacjownika jest dostępna!",
|
"title": "Nowa wersja Stacjownika jest dostępna!",
|
||||||
"paragraph1": "Miłego korzystania z aplikacji i niech S2 będzie z wami!",
|
"paragraph1": "Miłego korzystania z aplikacji i niech S2 będzie z wami!",
|
||||||
@@ -23,7 +27,6 @@
|
|||||||
"confirm-button": "ZAKTUALIZUJ",
|
"confirm-button": "ZAKTUALIZUJ",
|
||||||
"later-button": "PÓŹNIEJ"
|
"later-button": "PÓŹNIEJ"
|
||||||
},
|
},
|
||||||
|
|
||||||
"data-status": {
|
"data-status": {
|
||||||
"S1-offline": "<b>Sygnał S1</b> <br> Aplikacja działa w trybie offline!",
|
"S1-offline": "<b>Sygnał S1</b> <br> Aplikacja działa w trybie offline!",
|
||||||
"S1a-connection": "<b>Sygnał S1a</b> <br> Błąd podczas próby połączenia się z API Stacjownika!",
|
"S1a-connection": "<b>Sygnał S1a</b> <br> Błąd podczas próby połączenia się z API Stacjownika!",
|
||||||
@@ -207,15 +210,18 @@
|
|||||||
},
|
},
|
||||||
"sceneries": {
|
"sceneries": {
|
||||||
"station": "Stacja",
|
"station": "Stacja",
|
||||||
|
"abbr": "Skrót\nposterunku",
|
||||||
"min-lvl": "Min. poziom\ndyżurnego",
|
"min-lvl": "Min. poziom\ndyżurnego",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
"dispatcher": "Dyżurny",
|
"dispatcher": "Dyżurny",
|
||||||
"dispatcher-lvl": "Poziom\ndyżurnego",
|
"dispatcher-lvl": "Poziom\ndyżurnego",
|
||||||
"routes": "Szlaki\n2tor / 1tor",
|
"routes": "Szlaki\n2tor / 1tor",
|
||||||
"general": "Informacje\nogólne",
|
"general": "Informacje\nogólne",
|
||||||
"users": "Maszyniści online",
|
"user": "Maszyniści online",
|
||||||
"spawns": "Otwarte spawny",
|
"spawn": "Otwarte spawny",
|
||||||
"timetables": "Aktywne rozkłady jazdy",
|
"timetableAll": "Aktywne rozkłady jazdy",
|
||||||
|
"timetableConfirmed": "Zatwierdzone rozkłady jazdy",
|
||||||
|
"timetableUnconfirmed": "Niezatwierdzone rozkłady jazdy",
|
||||||
"no-stations": "Brak stacji do wyświetlenia!",
|
"no-stations": "Brak stacji do wyświetlenia!",
|
||||||
"scenery-search": "Wyszukaj scenerię..."
|
"scenery-search": "Wyszukaj scenerię..."
|
||||||
},
|
},
|
||||||
@@ -290,7 +296,7 @@
|
|||||||
"stock-info": "DODATKOWE INFORMACJE",
|
"stock-info": "DODATKOWE INFORMACJE",
|
||||||
"stock-length": "Długość",
|
"stock-length": "Długość",
|
||||||
"stock-mass": "Masa",
|
"stock-mass": "Masa",
|
||||||
"stock-max-speed": "Maks. zarejestrowana prędkość",
|
"stock-max-speed": "Prędkość maks.",
|
||||||
|
|
||||||
"load-data": "Pobierz dalszą historię...",
|
"load-data": "Pobierz dalszą historię...",
|
||||||
|
|
||||||
@@ -334,6 +340,7 @@
|
|||||||
"history-btn": "Przejdź do widoku historii dyżurnych ruchu",
|
"history-btn": "Przejdź do widoku historii dyżurnych ruchu",
|
||||||
"info-btn": "Wróć do widoku scenerii",
|
"info-btn": "Wróć do widoku scenerii",
|
||||||
"authors-title": "Autor scenerii | Autorzy scenerii",
|
"authors-title": "Autor scenerii | Autorzy scenerii",
|
||||||
|
"abbrev": "Skrót posterunku:",
|
||||||
"lines-title": "Rzeczywiste linie",
|
"lines-title": "Rzeczywiste linie",
|
||||||
"project-title": "Projekt",
|
"project-title": "Projekt",
|
||||||
"one-way-routes": "Szlaki jednotorowe",
|
"one-way-routes": "Szlaki jednotorowe",
|
||||||
@@ -374,7 +381,19 @@
|
|||||||
"end": "Koniec rozkładu jazdy",
|
"end": "Koniec rozkładu jazdy",
|
||||||
"terminated": "Rozkład jazdy zakończony",
|
"terminated": "Rozkład jazdy zakończony",
|
||||||
"begins": "ROZPOCZYNA\nBIEG",
|
"begins": "ROZPOCZYNA\nBIEG",
|
||||||
"terminates": "KOŃCZY BIEG"
|
"terminates": "KOŃCZY BIEG",
|
||||||
|
|
||||||
|
"from": "Z",
|
||||||
|
"to": "DO",
|
||||||
|
|
||||||
|
"desc-arriving": "Pociągu nie ma jeszcze na tej scenerii. Przyjedzie z: {prevStationName} (szlak {prevDepartureLine})",
|
||||||
|
"desc-online": "Pociąg jest na tej scenerii. Odjedzie do: {nextStationName} (szlak {nextArrivalLine})",
|
||||||
|
"desc-stopped": "Pociąg jest na tej scenerii i odbywa postój. Odjedzie do: {nextStationName} (szlak {nextArrivalLine})",
|
||||||
|
"desc-next-arrival": "Odjeżdża do: {nextStationName} (szlak {nextArrivalLine})",
|
||||||
|
"desc-departed": "Pociąg jest na tej scenerii i został odprawiony. Odjeżdża do: {nextStationName} (szlak {nextArrivalLine})",
|
||||||
|
"desc-departed-away": "Pociąg został odprawiony i odjechał do: {nextStationName} (szlak {nextArrivalLine})",
|
||||||
|
"desc-end": "Pociąg kończy bieg",
|
||||||
|
"desc-terminated": "Pociąg skończył bieg"
|
||||||
},
|
},
|
||||||
"history": {
|
"history": {
|
||||||
"title": "DZIENNIK ROZKŁADÓW JAZDY"
|
"title": "DZIENNIK ROZKŁADÓW JAZDY"
|
||||||
|
|||||||
-10
@@ -7,7 +7,6 @@ import plLang from './locales/pl.json';
|
|||||||
|
|
||||||
import { createI18n } from 'vue-i18n';
|
import { createI18n } from 'vue-i18n';
|
||||||
import { createPinia } from 'pinia';
|
import { createPinia } from 'pinia';
|
||||||
import { registerSW } from 'virtual:pwa-register';
|
|
||||||
|
|
||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
locale: 'pl',
|
locale: 'pl',
|
||||||
@@ -21,15 +20,6 @@ const i18n = createI18n({
|
|||||||
enableLegacy: false,
|
enableLegacy: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
registerSW({
|
|
||||||
onRegistered(r) {
|
|
||||||
r &&
|
|
||||||
setInterval(() => {
|
|
||||||
r.update();
|
|
||||||
}, 60 * 60 * 1000);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const clickOutsideDirective: Directive = {
|
const clickOutsideDirective: Directive = {
|
||||||
mounted(el, binding) {
|
mounted(el, binding) {
|
||||||
el.clickOutsideEvent = (event: Event) => {
|
el.clickOutsideEvent = (event: Event) => {
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export const headIds = ['station', 'min-lvl', 'status', 'dispatcher', 'dispatcher-lvl', 'routes', 'general'] as const;
|
||||||
|
|
||||||
|
export const headIconsIds = ['user', 'spawn', 'timetableAll', 'timetableUnconfirmed', 'timetableConfirmed'] as const;
|
||||||
|
|
||||||
|
export type HeadIdsTypes = typeof headIds[number] | typeof headIconsIds[number];
|
||||||
@@ -1,6 +1,15 @@
|
|||||||
import TrainStop from "./TrainStop";
|
import TrainStop from './TrainStop';
|
||||||
|
|
||||||
export default interface ScheduledTrain {
|
export enum StopStatus {
|
||||||
|
'arriving' = 'arriving',
|
||||||
|
'departed' = 'departed',
|
||||||
|
'departed-away' = 'departed-away',
|
||||||
|
'online' = 'online',
|
||||||
|
'stopped' = 'stopped',
|
||||||
|
'terminated' = 'terminated',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScheduledTrain {
|
||||||
trainId: string;
|
trainId: string;
|
||||||
trainNo: number;
|
trainNo: number;
|
||||||
|
|
||||||
@@ -27,6 +36,6 @@ export default interface ScheduledTrain {
|
|||||||
connectedTrack: string;
|
connectedTrack: string;
|
||||||
|
|
||||||
stopLabel: string;
|
stopLabel: string;
|
||||||
stopStatus: string;
|
stopStatus: StopStatus;
|
||||||
stopStatusID: number;
|
stopStatusID: number;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Availability } from '../../store/storeTypes';
|
import { Availability } from './store/storeTypes';
|
||||||
import ScheduledTrain from './ScheduledTrain';
|
import {ScheduledTrain} from './ScheduledTrain';
|
||||||
import StationRoutes from './StationRoutes';
|
import StationRoutes from './StationRoutes';
|
||||||
|
|
||||||
export default interface Station {
|
export default interface Station {
|
||||||
@@ -8,10 +8,12 @@ export default interface Station {
|
|||||||
generalInfo?: {
|
generalInfo?: {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
|
abbr: string;
|
||||||
|
|
||||||
reqLevel: number;
|
reqLevel: number;
|
||||||
// supportersOnly: boolean;
|
// supportersOnly: boolean;
|
||||||
|
|
||||||
|
|
||||||
lines: string;
|
lines: string;
|
||||||
project: string;
|
project: string;
|
||||||
projectUrl?: string;
|
projectUrl?: string;
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ export interface TimetableHistory {
|
|||||||
stopsString?: string;
|
stopsString?: string;
|
||||||
|
|
||||||
stockString?: string;
|
stockString?: string;
|
||||||
|
stockHistory: string[];
|
||||||
|
|
||||||
stockMass?: number;
|
stockMass?: number;
|
||||||
stockLength?: number;
|
stockLength?: number;
|
||||||
maxSpeed?: number;
|
maxSpeed?: number;
|
||||||
@@ -45,10 +47,12 @@ export interface TimetableHistory {
|
|||||||
hashesString?: string;
|
hashesString?: string;
|
||||||
currentSceneryName?: string;
|
currentSceneryName?: string;
|
||||||
currentSceneryHash?: string;
|
currentSceneryHash?: string;
|
||||||
|
|
||||||
|
routeSceneries?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SceneryTimetableHistory {
|
export interface SceneryTimetableHistory {
|
||||||
sceneryTimetables: TimetableHistory[];
|
timetables: TimetableHistory[];
|
||||||
totalCount: number;
|
// totalCount: number;
|
||||||
sceneryName: string;
|
// sceneryName: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Socket } from 'socket.io-client';
|
import { Socket } from 'socket.io-client';
|
||||||
import { DataStatus } from '../scripts/enums/DataStatus';
|
import { DataStatus } from '../../enums/DataStatus';
|
||||||
import StationAPIData from '../scripts/interfaces/api/StationAPIData';
|
import StationAPIData from '../api/StationAPIData';
|
||||||
import { TrainAPIData } from '../scripts/interfaces/api/TrainAPIData';
|
import { TrainAPIData } from '../api/TrainAPIData';
|
||||||
import Station from '../scripts/interfaces/Station';
|
import Station from '../Station';
|
||||||
import Train from '../scripts/interfaces/Train';
|
import Train from '../Train';
|
||||||
import { DispatcherStatsAPIData } from '../scripts/interfaces/api/DispatcherStatsAPIData';
|
import { DispatcherStatsAPIData } from '../api/DispatcherStatsAPIData';
|
||||||
import { DriverStatsAPIData } from '../scripts/interfaces/api/DriverStatsAPIData';
|
import { DriverStatsAPIData } from '../api/DriverStatsAPIData';
|
||||||
|
|
||||||
export type Availability = 'default' | 'unavailable' | 'nonPublic' | 'abandoned' | 'nonDefault';
|
export type Availability = 'default' | 'unavailable' | 'nonPublic' | 'abandoned' | 'nonDefault';
|
||||||
|
|
||||||
@@ -55,8 +55,19 @@ export interface APIData {
|
|||||||
connectedSocketCount: number;
|
connectedSocketCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StationRoutesInfo {
|
||||||
|
routeName: string;
|
||||||
|
isElectric: boolean;
|
||||||
|
isInternal: boolean;
|
||||||
|
isRouteSBL: boolean;
|
||||||
|
routeLength: number;
|
||||||
|
routeSpeed: number;
|
||||||
|
routeTracks: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface StationJSONData {
|
export interface StationJSONData {
|
||||||
name: string;
|
name: string;
|
||||||
|
abbr: string;
|
||||||
url: string;
|
url: string;
|
||||||
lines: string;
|
lines: string;
|
||||||
project: string;
|
project: string;
|
||||||
@@ -69,7 +80,8 @@ export interface StationJSONData {
|
|||||||
|
|
||||||
SUP: boolean;
|
SUP: boolean;
|
||||||
|
|
||||||
routes: string;
|
// routes: string;
|
||||||
|
routesInfo: StationRoutesInfo[];
|
||||||
|
|
||||||
checkpoints: string | null;
|
checkpoints: string | null;
|
||||||
authors?: string;
|
authors?: string;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
export const URLs = {
|
export const URLs = {
|
||||||
stacjownikAPI:
|
stacjownikAPI:
|
||||||
import.meta.env.VITE_APP_API_DEV == 1 && !import.meta.env.PROD
|
import.meta.env.VITE_APP_API_DEV == 1 && !import.meta.env.PROD
|
||||||
? 'http://localhost:3000'
|
? 'http://localhost:3001'
|
||||||
: 'https://spythere.pl',
|
: 'https://spythere.pl',
|
||||||
stacjownikAPIDev: 'localhost:3000',
|
stacjownikAPIDev: 'localhost:3000',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import ScheduledTrain from '../interfaces/ScheduledTrain';
|
import { ScheduledTrain, StopStatus } from '../interfaces/ScheduledTrain';
|
||||||
import Train from '../interfaces/Train';
|
import Train from '../interfaces/Train';
|
||||||
import TrainStop from '../interfaces/TrainStop';
|
import TrainStop from '../interfaces/TrainStop';
|
||||||
|
|
||||||
@@ -74,32 +74,32 @@ export const parseSpawns = (spawnString: string) => {
|
|||||||
export const getTimestamp = (date: string | null): number => (date ? new Date(date).getTime() : 0);
|
export const getTimestamp = (date: string | null): number => (date ? new Date(date).getTime() : 0);
|
||||||
|
|
||||||
export const getTrainStopStatus = (stopInfo: TrainStop, currentStationName: string, stationName: string) => {
|
export const getTrainStopStatus = (stopInfo: TrainStop, currentStationName: string, stationName: string) => {
|
||||||
let stopStatus = '',
|
let stopStatus = StopStatus['arriving'],
|
||||||
stopLabel = '',
|
stopLabel = '',
|
||||||
stopStatusID = -1;
|
stopStatusID = -1;
|
||||||
|
|
||||||
if (stopInfo.terminatesHere && stopInfo.confirmed) {
|
if (stopInfo.terminatesHere && stopInfo.confirmed) {
|
||||||
stopStatus = 'terminated';
|
stopStatus = StopStatus['terminated'];
|
||||||
stopLabel = 'Skończył bieg';
|
stopLabel = 'Skończył bieg';
|
||||||
stopStatusID = 5;
|
stopStatusID = 5;
|
||||||
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName == stationName) {
|
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName == stationName) {
|
||||||
stopStatus = 'departed';
|
stopStatus = StopStatus['departed'];
|
||||||
stopLabel = 'Odprawiony';
|
stopLabel = 'Odprawiony';
|
||||||
stopStatusID = 2;
|
stopStatusID = 2;
|
||||||
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName != stationName) {
|
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName != stationName) {
|
||||||
stopStatus = 'departed-away';
|
stopStatus = StopStatus['departed-away'];
|
||||||
stopLabel = 'Odjechał';
|
stopLabel = 'Odjechał';
|
||||||
stopStatusID = 4;
|
stopStatusID = 4;
|
||||||
} else if (currentStationName == stationName && !stopInfo.stopped) {
|
} else if (currentStationName == stationName && !stopInfo.stopped) {
|
||||||
stopStatus = 'online';
|
stopStatus = StopStatus['online'];
|
||||||
stopLabel = 'Na stacji';
|
stopLabel = 'Na stacji';
|
||||||
stopStatusID = 0;
|
stopStatusID = 0;
|
||||||
} else if (currentStationName == stationName && stopInfo.stopped) {
|
} else if (currentStationName == stationName && stopInfo.stopped) {
|
||||||
stopStatus = 'stopped';
|
stopStatus = StopStatus['stopped'];
|
||||||
stopLabel = 'Postój';
|
stopLabel = 'Postój';
|
||||||
stopStatusID = 1;
|
stopStatusID = 1;
|
||||||
} else if (currentStationName != stationName) {
|
} else if (currentStationName != stationName) {
|
||||||
stopStatus = 'arriving';
|
stopStatus = StopStatus['arriving'];
|
||||||
stopLabel = 'W drodze';
|
stopLabel = 'W drodze';
|
||||||
stopStatusID = 3;
|
stopStatusID = 3;
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ export function getScheduledTrain(train: Train, trainStopIndex: number, stationN
|
|||||||
|
|
||||||
for (let i = trainStopIndex - 1; i >= 0; i--) {
|
for (let i = trainStopIndex - 1; i >= 0; i--) {
|
||||||
if (/strong|podg/g.test(followingStops[i].stopName)) {
|
if (/strong|podg/g.test(followingStops[i].stopName)) {
|
||||||
prevStationName = followingStops[i].stopNameRAW.replace(/,.*/g,"");
|
prevStationName = followingStops[i].stopNameRAW.replace(/,.*/g, '');
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ export function getScheduledTrain(train: Train, trainStopIndex: number, stationN
|
|||||||
|
|
||||||
for (let i = trainStopIndex + 1; i < followingStops.length; i++) {
|
for (let i = trainStopIndex + 1; i < followingStops.length; i++) {
|
||||||
if (/strong|podg/g.test(followingStops[i].stopName)) {
|
if (/strong|podg/g.test(followingStops[i].stopName)) {
|
||||||
nextStationName = followingStops[i].stopNameRAW.replace(/,.*/g,"");
|
nextStationName = followingStops[i].stopNameRAW.replace(/,.*/g, '');
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,6 @@ export function getScheduledTrain(train: Train, trainStopIndex: number, stationN
|
|||||||
signal: train.signal,
|
signal: train.signal,
|
||||||
connectedTrack: train.connectedTrack,
|
connectedTrack: train.connectedTrack,
|
||||||
|
|
||||||
|
|
||||||
driverName: train.driverName,
|
driverName: train.driverName,
|
||||||
driverId: train.driverId,
|
driverId: train.driverId,
|
||||||
currentStationName: train.currentStationName,
|
currentStationName: train.currentStationName,
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import inputData from '../data/options.json';
|
import inputData from '../data/options.json';
|
||||||
import Filter from '../scripts/interfaces/Filter';
|
|
||||||
import Station from '../scripts/interfaces/Station';
|
import Station from '../scripts/interfaces/Station';
|
||||||
import StorageManager from '../scripts/managers/storageManager';
|
import StorageManager from '../scripts/managers/storageManager';
|
||||||
import { useStore } from './store';
|
import { useStore } from './store';
|
||||||
import { filterInitStates } from './constants/initFilterStates';
|
import { filterInitStates } from './constants/initFilterStates';
|
||||||
import { filterStations, sortStations } from './utils/filterUtils';
|
import { filterStations, sortStations } from './utils/filterUtils';
|
||||||
|
import { HeadIdsTypes } from '../scripts/data/stationHeaderNames';
|
||||||
|
|
||||||
export const useStationFiltersStore = defineStore('stationFiltersStore', {
|
export const useStationFiltersStore = defineStore('stationFiltersStore', {
|
||||||
state() {
|
state() {
|
||||||
return {
|
return {
|
||||||
inputs: inputData,
|
inputs: inputData,
|
||||||
filters: { ...filterInitStates },
|
filters: { ...filterInitStates },
|
||||||
sorterActive: { index: 0, dir: 1 },
|
sorterActive: { headerName: 'station' as HeadIdsTypes, dir: 1 },
|
||||||
store: useStore(),
|
store: useStore(),
|
||||||
lastClickedFilterId: '',
|
lastClickedFilterId: '',
|
||||||
};
|
};
|
||||||
@@ -89,13 +89,11 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
changeSorter(index: number) {
|
changeSorter(headerName: HeadIdsTypes) {
|
||||||
if (index > 4 && index < 7) return;
|
if (headerName == this.sorterActive.headerName) this.sorterActive.dir = -1 * this.sorterActive.dir;
|
||||||
|
|
||||||
if (index == this.sorterActive.index) this.sorterActive.dir = -1 * this.sorterActive.dir;
|
|
||||||
else this.sorterActive.dir = 1;
|
else this.sorterActive.dir = 1;
|
||||||
|
|
||||||
this.sorterActive.index = index;
|
this.sorterActive.headerName = headerName;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
+19
-37
@@ -3,7 +3,7 @@ import { defineStore } from 'pinia';
|
|||||||
import { io } from 'socket.io-client';
|
import { io } from 'socket.io-client';
|
||||||
import { DataStatus } from '../scripts/enums/DataStatus';
|
import { DataStatus } from '../scripts/enums/DataStatus';
|
||||||
import StationAPIData from '../scripts/interfaces/api/StationAPIData';
|
import StationAPIData from '../scripts/interfaces/api/StationAPIData';
|
||||||
import ScheduledTrain from '../scripts/interfaces/ScheduledTrain';
|
import { ScheduledTrain } from '../scripts/interfaces/ScheduledTrain';
|
||||||
import Station from '../scripts/interfaces/Station';
|
import Station from '../scripts/interfaces/Station';
|
||||||
import StationRoutes from '../scripts/interfaces/StationRoutes';
|
import StationRoutes from '../scripts/interfaces/StationRoutes';
|
||||||
import Train from '../scripts/interfaces/Train';
|
import Train from '../scripts/interfaces/Train';
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
getScheduledTrain,
|
getScheduledTrain,
|
||||||
parseSpawns,
|
parseSpawns,
|
||||||
} from '../scripts/utils/storeUtils';
|
} from '../scripts/utils/storeUtils';
|
||||||
import { APIData, StationJSONData, StoreState } from './storeTypes';
|
import { APIData, StationJSONData, StoreState } from '../scripts/interfaces/store/storeTypes';
|
||||||
|
|
||||||
export const useStore = defineStore('store', {
|
export const useStore = defineStore('store', {
|
||||||
state: () =>
|
state: () =>
|
||||||
@@ -303,44 +303,26 @@ export const useStore = defineStore('store', {
|
|||||||
...scenery,
|
...scenery,
|
||||||
authors: scenery.authors?.split(',').map((a) => a.trim()),
|
authors: scenery.authors?.split(',').map((a) => a.trim()),
|
||||||
routes:
|
routes:
|
||||||
scenery.routes
|
scenery.routesInfo.reduce(
|
||||||
?.split(';')
|
(acc, route) => {
|
||||||
.filter((routeString) => routeString)
|
const propName: keyof StationRoutes = `${route.routeTracks == 2 ? 'twoWay' : 'oneWay'}${
|
||||||
.reduce(
|
route.isElectric ? '' : 'No'
|
||||||
(acc, routeString) => {
|
}CatenaryRouteNames`;
|
||||||
const specs1 = routeString.split('_')[0];
|
|
||||||
const isInternal = specs1.startsWith('!');
|
|
||||||
const name = isInternal ? specs1.replace('!', '') : specs1;
|
|
||||||
|
|
||||||
const specs2 = routeString.split('_')[1].split('');
|
acc[route.routeTracks == 2 ? 'twoWay' : 'oneWay'].push({
|
||||||
const twoWay = specs2[0] == '2';
|
name: route.routeName,
|
||||||
const catenary = specs2[1] == 'E';
|
SBL: route.isRouteSBL,
|
||||||
const SBL = specs2[2] == 'S';
|
TWB: false,
|
||||||
const TWB = specs2[3] ? true : false;
|
catenary: route.isElectric,
|
||||||
const speed = Number(routeString.split(':')[1]) || 0;
|
isInternal: route.isInternal,
|
||||||
const length = Number(routeString.split(':')[2]) || 0;
|
tracks: route.routeTracks,
|
||||||
|
length: route.routeLength,
|
||||||
const propName = twoWay
|
speed: route.routeSpeed,
|
||||||
? catenary
|
|
||||||
? 'twoWayCatenaryRouteNames'
|
|
||||||
: 'twoWayNoCatenaryRouteNames'
|
|
||||||
: catenary
|
|
||||||
? 'oneWayCatenaryRouteNames'
|
|
||||||
: 'oneWayNoCatenaryRouteNames';
|
|
||||||
|
|
||||||
acc[twoWay ? 'twoWay' : 'oneWay'].push({
|
|
||||||
name,
|
|
||||||
SBL,
|
|
||||||
TWB,
|
|
||||||
catenary,
|
|
||||||
isInternal,
|
|
||||||
tracks: twoWay ? 2 : 1,
|
|
||||||
length,
|
|
||||||
speed,
|
|
||||||
});
|
});
|
||||||
if (!isInternal) acc[propName].push(name);
|
|
||||||
|
|
||||||
if (SBL) acc['sblRouteNames'].push(name);
|
if (!route.isInternal) acc[propName].push(route.routeName);
|
||||||
|
|
||||||
|
if (route.isRouteSBL) acc['sblRouteNames'].push(route.routeName);
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,57 +1,72 @@
|
|||||||
|
import { HeadIdsTypes } from '../../scripts/data/stationHeaderNames';
|
||||||
import Filter from '../../scripts/interfaces/Filter';
|
import Filter from '../../scripts/interfaces/Filter';
|
||||||
import Station from '../../scripts/interfaces/Station';
|
import Station from '../../scripts/interfaces/Station';
|
||||||
|
|
||||||
export const sortStations = (a: Station, b: Station, sorter: { index: number; dir: number }) => {
|
export const sortStations = (a: Station, b: Station, sorter: { headerName: HeadIdsTypes; dir: number }) => {
|
||||||
switch (sorter.index) {
|
let diff = 0;
|
||||||
case 0:
|
|
||||||
|
switch (sorter.headerName) {
|
||||||
|
case 'station':
|
||||||
return sorter.dir == 1 ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name);
|
return sorter.dir == 1 ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name);
|
||||||
|
|
||||||
case 1:
|
case 'min-lvl':
|
||||||
if ((a.generalInfo?.reqLevel || 0) > (b.generalInfo?.reqLevel || 0)) return sorter.dir;
|
diff = (a.generalInfo?.reqLevel || 0) - (b.generalInfo?.reqLevel || 0);
|
||||||
if ((a.generalInfo?.reqLevel || 0) < (b.generalInfo?.reqLevel || 0)) return -sorter.dir;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 'status':
|
||||||
if ((a.onlineInfo?.statusTimestamp || 0) > (b.onlineInfo?.statusTimestamp || 0)) return sorter.dir;
|
diff = (a.onlineInfo?.statusTimestamp || 0) - (b.onlineInfo?.statusTimestamp || 0);
|
||||||
if ((a.onlineInfo?.statusTimestamp || 0) < (b.onlineInfo?.statusTimestamp || 0)) return -sorter.dir;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 'dispatcher':
|
||||||
if ((a.onlineInfo?.dispatcherName.toLowerCase() || '') > (b.onlineInfo?.dispatcherName.toLowerCase() || ''))
|
if ((a.onlineInfo?.dispatcherName.toLowerCase() || '') > (b.onlineInfo?.dispatcherName.toLowerCase() || ''))
|
||||||
return sorter.dir;
|
return sorter.dir;
|
||||||
if ((a.onlineInfo?.dispatcherName.toLowerCase() || '') < (b.onlineInfo?.dispatcherName.toLowerCase() || ''))
|
if ((a.onlineInfo?.dispatcherName.toLowerCase() || '') < (b.onlineInfo?.dispatcherName.toLowerCase() || ''))
|
||||||
return -sorter.dir;
|
return -sorter.dir;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 'dispatcher-lvl':
|
||||||
if ((a.onlineInfo?.dispatcherExp || 0) > (b.onlineInfo?.dispatcherExp || 0)) return sorter.dir;
|
diff = (a.onlineInfo?.dispatcherExp || 0) - (b.onlineInfo?.dispatcherExp || 0);
|
||||||
if ((a.onlineInfo?.dispatcherExp || 0) < (b.onlineInfo?.dispatcherExp || 0)) return -sorter.dir;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 'user':
|
||||||
if ((a.onlineInfo?.currentUsers || 0) > (b.onlineInfo?.currentUsers || 0)) return sorter.dir;
|
diff = (b.onlineInfo ? b.onlineInfo.currentUsers : -1) - (a.onlineInfo ? a.onlineInfo.currentUsers : -1);
|
||||||
if ((a.onlineInfo?.currentUsers || 0) < (b.onlineInfo?.currentUsers || 0)) return -sorter.dir;
|
|
||||||
|
|
||||||
if ((a.onlineInfo?.maxUsers || 0) > (b.onlineInfo?.maxUsers || 0)) return sorter.dir;
|
|
||||||
if ((a.onlineInfo?.maxUsers || 0) < (b.onlineInfo?.maxUsers || 0)) return -sorter.dir;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 'spawn':
|
||||||
if ((a.onlineInfo?.spawns.length || 0) > (b.onlineInfo?.spawns.length || 0)) return sorter.dir;
|
diff = (a.onlineInfo ? a.onlineInfo.spawns.length : -1) - (b.onlineInfo ? b.onlineInfo.spawns.length : -1);
|
||||||
if ((a.onlineInfo?.spawns.length || 0) < (b.onlineInfo?.spawns.length || 0)) return -sorter.dir;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case 'timetableConfirmed':
|
||||||
if ((a.onlineInfo?.scheduledTrains?.length || 0) > (b.onlineInfo?.scheduledTrains?.length || 0))
|
diff =
|
||||||
return sorter.dir;
|
(a.onlineInfo?.scheduledTrains
|
||||||
if ((a.onlineInfo?.scheduledTrains?.length || 0) < (b.onlineInfo?.scheduledTrains?.length || 0))
|
? a.onlineInfo.scheduledTrains.filter((train) => train.stopInfo.confirmed).length
|
||||||
return -sorter.dir;
|
: -1) -
|
||||||
|
(b.onlineInfo?.scheduledTrains
|
||||||
|
? b.onlineInfo.scheduledTrains.filter((train) => train.stopInfo.confirmed).length
|
||||||
|
: -1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'timetableUnconfirmed':
|
||||||
|
diff =
|
||||||
|
(a.onlineInfo?.scheduledTrains
|
||||||
|
? a.onlineInfo.scheduledTrains.filter((train) => !train.stopInfo.confirmed).length
|
||||||
|
: -1) -
|
||||||
|
(b.onlineInfo?.scheduledTrains
|
||||||
|
? b.onlineInfo.scheduledTrains.filter((train) => !train.stopInfo.confirmed).length
|
||||||
|
: -1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'timetableAll':
|
||||||
|
diff =
|
||||||
|
(a.onlineInfo?.scheduledTrains ? a.onlineInfo.scheduledTrains.length : -1) -
|
||||||
|
(b.onlineInfo?.scheduledTrains ? b.onlineInfo.scheduledTrains.length : -1);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (diff != 0) return Math.sign(diff) * sorter.dir;
|
||||||
return a.name.localeCompare(b.name);
|
return a.name.localeCompare(b.name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+24
-2
@@ -4,12 +4,11 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
background: #585858;
|
|
||||||
|
|
||||||
margin: 0.25em;
|
margin: 0.25em;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
background: #585858;
|
||||||
padding: 0.2em 0.4em;
|
padding: 0.2em 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,3 +55,26 @@
|
|||||||
background-color: forestgreen;
|
background-color: forestgreen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.train-badge {
|
||||||
|
padding: 0.1em 0.2em;
|
||||||
|
border-radius: 0.2em;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
font-size: 0.9em;
|
||||||
|
|
||||||
|
&.twr {
|
||||||
|
background-color: var(--clr-twr);
|
||||||
|
box-shadow: 0 0 5px 1px var(--clr-twr);
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.skr {
|
||||||
|
background-color: var(--clr-skr);
|
||||||
|
box-shadow: 0 0 5px 1px var(--clr-skr);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.offline {
|
||||||
|
background-color: #be3728;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -52,17 +52,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.filterStore.setupFilters();
|
this.filterStore.setupFilters();
|
||||||
// this.filterStore.inputs.options.forEach((option) => {
|
|
||||||
// const value = StorageManager.getBooleanValue(option.name);
|
|
||||||
// option.value = value;
|
|
||||||
// this.filterStore.changeFilterValue({ name: option.name, value: value });
|
|
||||||
// });
|
|
||||||
|
|
||||||
// this.filterStore.inputs.sliders.forEach((slider) => {
|
|
||||||
// const value = StorageManager.getNumericValue(slider.name);
|
|
||||||
// slider.value = value;
|
|
||||||
// this.filterStore.changeFilterValue({ name: slider.name, value: value });
|
|
||||||
// });
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ export default defineConfig({
|
|||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
VitePWA({
|
VitePWA({
|
||||||
registerType: 'prompt',
|
registerType: 'autoUpdate',
|
||||||
|
|
||||||
workbox: {
|
workbox: {
|
||||||
globPatterns: ['**/*.{js,css,html,png,svg,jpg}'],
|
globPatterns: ['**/*.{js,css,html,png,svg,jpg}'],
|
||||||
|
|||||||
Reference in New Issue
Block a user