mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-02 21:08:12 +00:00
format & lint
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
/* eslint-env node */
|
||||||
|
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
extends: [
|
||||||
|
'plugin:vue/vue3-essential',
|
||||||
|
'eslint:recommended',
|
||||||
|
'@vue/eslint-config-typescript',
|
||||||
|
'@vue/eslint-config-prettier/skip-formatting'
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'vue/multi-word-component-names': 'off'
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 'latest'
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/prettierrc",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 100,
|
||||||
|
"trailingComma": "none"
|
||||||
|
}
|
||||||
Generated
+22
@@ -24,6 +24,7 @@
|
|||||||
"@vite-pwa/assets-generator": "^0.0.10",
|
"@vite-pwa/assets-generator": "^0.0.10",
|
||||||
"@vitejs/plugin-vue": "^4.3.4",
|
"@vitejs/plugin-vue": "^4.3.4",
|
||||||
"axios": "^1.5.0",
|
"axios": "^1.5.0",
|
||||||
|
"prettier": "^3.0.3",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"vite": "^4.4.9",
|
"vite": "^4.4.9",
|
||||||
"vite-plugin-pwa": "^0.16.5",
|
"vite-plugin-pwa": "^0.16.5",
|
||||||
@@ -5440,6 +5441,21 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prettier": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"prettier": "bin/prettier.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pretty-bytes": {
|
"node_modules/pretty-bytes": {
|
||||||
"version": "6.1.1",
|
"version": "6.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
|
||||||
@@ -10873,6 +10889,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"prettier": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"pretty-bytes": {
|
"pretty-bytes": {
|
||||||
"version": "6.1.1",
|
"version": "6.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
|
||||||
|
|||||||
+12
-2
@@ -6,7 +6,10 @@
|
|||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vue-tsc --noEmit && vite build",
|
"build": "vue-tsc --noEmit && vite build",
|
||||||
"deploy": "yarn build && firebase deploy --only hosting",
|
"deploy": "yarn build && firebase deploy --only hosting",
|
||||||
"preview": "yarn build && vite preview"
|
"preview": "yarn build && vite preview",
|
||||||
|
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false",
|
||||||
|
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
||||||
|
"format": "prettier --write src/"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.32.2",
|
"core-js": "^3.32.2",
|
||||||
@@ -25,10 +28,17 @@
|
|||||||
"@vite-pwa/assets-generator": "^0.0.10",
|
"@vite-pwa/assets-generator": "^0.0.10",
|
||||||
"@vitejs/plugin-vue": "^4.3.4",
|
"@vitejs/plugin-vue": "^4.3.4",
|
||||||
"axios": "^1.5.0",
|
"axios": "^1.5.0",
|
||||||
|
"prettier": "^3.0.3",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"vite": "^4.4.9",
|
"vite": "^4.4.9",
|
||||||
"vite-plugin-pwa": "^0.16.5",
|
"vite-plugin-pwa": "^0.16.5",
|
||||||
"vue-tsc": "^1.8.11"
|
"vue-tsc": "^1.8.11",
|
||||||
|
"@vue/eslint-config-prettier": "^8.0.0",
|
||||||
|
"@vue/eslint-config-typescript": "^12.0.0",
|
||||||
|
"@vue/tsconfig": "^0.4.0",
|
||||||
|
"eslint": "^8.49.0",
|
||||||
|
"eslint-plugin-vue": "^9.17.0",
|
||||||
|
"@rushstack/eslint-patch": "^1.3.3"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
|
|||||||
+14
-16
@@ -6,8 +6,6 @@
|
|||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
|
|
||||||
<UpdatePrompt />
|
|
||||||
|
|
||||||
<AppHeader :current-lang="currentLang" @change-lang="changeLang" />
|
<AppHeader :current-lang="currentLang" @change-lang="changeLang" />
|
||||||
|
|
||||||
<main class="app_main">
|
<main class="app_main">
|
||||||
@@ -24,7 +22,9 @@
|
|||||||
{{ 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 />
|
<br />
|
||||||
<a href="https://discord.gg/x2mpNN3svk"><img :src="getIcon('discord', 'png')" alt=""> <b>{{ $t('footer.discord') }}</b></a>
|
<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>
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, KeepAlive, provide, ref, watch } from 'vue';
|
import { computed, defineComponent, provide, ref, watch } from 'vue';
|
||||||
|
|
||||||
import Clock from './components/App/Clock.vue';
|
import Clock from './components/App/Clock.vue';
|
||||||
|
|
||||||
@@ -46,9 +46,6 @@ import StorageManager from './scripts/managers/storageManager';
|
|||||||
import imageMixin from './mixins/imageMixin';
|
import imageMixin from './mixins/imageMixin';
|
||||||
import AppHeader from './components/App/AppHeader.vue';
|
import AppHeader from './components/App/AppHeader.vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import UpdatePrompt from './components/App/UpdatePrompt.vue';
|
|
||||||
import { VERSION } from 'vue-i18n';
|
|
||||||
import { RouterView } from 'vue-router';
|
|
||||||
import useCustomSW from './mixins/useCustomSW';
|
import useCustomSW from './mixins/useCustomSW';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -57,8 +54,7 @@ export default defineComponent({
|
|||||||
StatusIndicator,
|
StatusIndicator,
|
||||||
SelectBox,
|
SelectBox,
|
||||||
TrainModal,
|
TrainModal,
|
||||||
AppHeader,
|
AppHeader
|
||||||
UpdatePrompt,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [imageMixin],
|
mixins: [imageMixin],
|
||||||
@@ -67,7 +63,7 @@ export default defineComponent({
|
|||||||
const store = useStore();
|
const store = useStore();
|
||||||
store.connectToAPI();
|
store.connectToAPI();
|
||||||
|
|
||||||
const { offlineReady } = useCustomSW();
|
useCustomSW();
|
||||||
|
|
||||||
const isFilterCardVisible = ref(false);
|
const isFilterCardVisible = ref(false);
|
||||||
|
|
||||||
@@ -77,10 +73,12 @@ export default defineComponent({
|
|||||||
store,
|
store,
|
||||||
isFilterCardVisible,
|
isFilterCardVisible,
|
||||||
onlineDispatchers: computed(() =>
|
onlineDispatchers: computed(() =>
|
||||||
store.stationList.filter((station) => station.onlineInfo && station.onlineInfo.region == store.region.id)
|
store.stationList.filter(
|
||||||
|
(station) => station.onlineInfo && station.onlineInfo.region == store.region.id
|
||||||
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
dispatcherDataStatus: store.dataStatuses.dispatchers,
|
dispatcherDataStatus: store.dataStatuses.dispatchers
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -89,7 +87,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
currentLang: 'pl',
|
currentLang: 'pl',
|
||||||
releaseURL: '',
|
releaseURL: '',
|
||||||
isOnProductionHost: location.hostname == 'stacjownik-td2.web.app',
|
isOnProductionHost: location.hostname == 'stacjownik-td2.web.app'
|
||||||
}),
|
}),
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
@@ -104,7 +102,7 @@ export default defineComponent({
|
|||||||
stations: [],
|
stations: [],
|
||||||
dispatchers: [],
|
dispatchers: [],
|
||||||
trains: [],
|
trains: [],
|
||||||
connectedSocketCount: 0,
|
connectedSocketCount: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
this.store.setOnlineData();
|
this.store.setOnlineData();
|
||||||
@@ -170,8 +168,8 @@ export default defineComponent({
|
|||||||
this.changeLang('en');
|
this.changeLang('en');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,12 @@
|
|||||||
<div class="header_container">
|
<div class="header_container">
|
||||||
<div class="header_icons">
|
<div class="header_icons">
|
||||||
<span class="icons-top">
|
<span class="icons-top">
|
||||||
<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>
|
||||||
</div>
|
</div>
|
||||||
@@ -44,7 +49,9 @@
|
|||||||
{{ $t('app.sceneries') }}
|
{{ $t('app.sceneries') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
/
|
/
|
||||||
<router-link class="route" active-class="route-active" to="/trains">{{ $t('app.trains') }}</router-link>
|
<router-link class="route" active-class="route-active" to="/trains">{{
|
||||||
|
$t('app.trains')
|
||||||
|
}}</router-link>
|
||||||
/
|
/
|
||||||
<router-link
|
<router-link
|
||||||
class="route"
|
class="route"
|
||||||
@@ -74,12 +81,12 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
currentLang: {
|
currentLang: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
store: useStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -88,7 +95,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
changeLang(lang: string) {
|
changeLang(lang: string) {
|
||||||
this.$emit('changeLang', lang);
|
this.$emit('changeLang', lang);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
onlineTrainsCount() {
|
onlineTrainsCount() {
|
||||||
@@ -102,24 +109,29 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
factorU() {
|
factorU() {
|
||||||
return this.onlineDispatchersCount == 0 ? '-' : (this.onlineTrainsCount / this.onlineDispatchersCount).toFixed(2);
|
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 =
|
||||||
this.store.apiData.stations?.filter((station) => station.region == region.id && station.isOnline).length || 0;
|
this.store.apiData.stations?.filter(
|
||||||
|
(station) => station.region == region.id && station.isOnline
|
||||||
|
).length || 0;
|
||||||
const regionTrainCount =
|
const regionTrainCount =
|
||||||
this.store.apiData.trains?.filter((train) => train.region == region.id && train.online).length || 0;
|
this.store.apiData.trains?.filter((train) => train.region == region.id && train.online)
|
||||||
|
.length || 0;
|
||||||
return {
|
return {
|
||||||
id: region.id,
|
id: region.id,
|
||||||
value: `${region.value} <div class='text--grayed'>${regionStationCount} / ${regionTrainCount}</div>`,
|
value: `${region.value} <div class='text--grayed'>${regionStationCount} / ${regionTrainCount}</div>`,
|
||||||
selectedValue: region.value,
|
selectedValue: region.value
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
components: { SelectBox, StatusIndicator, Clock },
|
components: { SelectBox, StatusIndicator, Clock }
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -2,32 +2,33 @@
|
|||||||
<div class="clock">{{ computedDate }}</div>
|
<div class="clock">{{ computedDate }}</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, ref } from "vue";
|
import { computed, defineComponent, ref } from 'vue';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "clock",
|
name: 'VueClock',
|
||||||
data: () => ({
|
data: () => ({
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now()
|
||||||
}),
|
}),
|
||||||
setup() {
|
setup() {
|
||||||
let timestamp = ref(Date.now());
|
let timestamp = ref(Date.now());
|
||||||
|
|
||||||
const computedDate = computed(() => new Date(timestamp.value).toLocaleString("pl-PL", {
|
const computedDate = computed(() =>
|
||||||
hour: "2-digit",
|
new Date(timestamp.value).toLocaleString('pl-PL', {
|
||||||
minute: "2-digit",
|
hour: '2-digit',
|
||||||
second: "2-digit",
|
minute: '2-digit',
|
||||||
}));
|
second: '2-digit'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
setInterval(() => (timestamp.value = Date.now()), 1000);
|
setInterval(() => (timestamp.value = Date.now()), 1000);
|
||||||
|
|
||||||
return { computedDate }
|
return { computedDate };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "../../styles/responsive.scss";
|
@import '../../styles/responsive.scss';
|
||||||
|
|
||||||
.clock {
|
.clock {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -43,7 +43,13 @@
|
|||||||
<g v-if="greenBlinkLight" filter="url(#filter0_d_843_28)">
|
<g v-if="greenBlinkLight" filter="url(#filter0_d_843_28)">
|
||||||
<circle cx="15" cy="17" r="7" fill="#00FF0A" />
|
<circle cx="15" cy="17" r="7" fill="#00FF0A" />
|
||||||
|
|
||||||
<animate attributeType="XML" attributeName="opacity" values="1;0;1" dur="1s" repeatCount="indefinite" />
|
<animate
|
||||||
|
attributeType="XML"
|
||||||
|
attributeName="opacity"
|
||||||
|
values="1;0;1"
|
||||||
|
dur="1s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
/>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g v-if="redTopLight" filter="url(#filter1_d_843_28)">
|
<g v-if="redTopLight" filter="url(#filter1_d_843_28)">
|
||||||
@@ -56,7 +62,13 @@
|
|||||||
<g v-if="redBottomLight" filter="url(#filter3_d_843_28)">
|
<g v-if="redBottomLight" filter="url(#filter3_d_843_28)">
|
||||||
<circle cx="15" cy="74" r="7" fill="#F40000" />
|
<circle cx="15" cy="74" r="7" fill="#F40000" />
|
||||||
|
|
||||||
<animate attributeType="XML" attributeName="opacity" values="1;0;1" dur="1s" repeatCount="indefinite" />
|
<animate
|
||||||
|
attributeType="XML"
|
||||||
|
attributeName="opacity"
|
||||||
|
values="1;0;1"
|
||||||
|
dur="1s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
/>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
@@ -82,7 +94,12 @@
|
|||||||
<feComposite in2="hardAlpha" operator="out" />
|
<feComposite in2="hardAlpha" operator="out" />
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 1 0 0 0 0 0.04 0 0 0 1 0" />
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 1 0 0 0 0 0.04 0 0 0 1 0" />
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_843_28" />
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_843_28" />
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_843_28" result="shape" />
|
<feBlend
|
||||||
|
mode="normal"
|
||||||
|
in="SourceGraphic"
|
||||||
|
in2="effect1_dropShadow_843_28"
|
||||||
|
result="shape"
|
||||||
|
/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter
|
<filter
|
||||||
id="filter1_d_843_28"
|
id="filter1_d_843_28"
|
||||||
@@ -104,7 +121,12 @@
|
|||||||
<feGaussianBlur stdDeviation="2.5" />
|
<feGaussianBlur stdDeviation="2.5" />
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0.770833 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" />
|
<feColorMatrix type="matrix" values="0 0 0 0 0.770833 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" />
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_843_28" />
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_843_28" />
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_843_28" result="shape" />
|
<feBlend
|
||||||
|
mode="normal"
|
||||||
|
in="SourceGraphic"
|
||||||
|
in2="effect1_dropShadow_843_28"
|
||||||
|
result="shape"
|
||||||
|
/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter
|
<filter
|
||||||
id="filter2_d_843_28"
|
id="filter2_d_843_28"
|
||||||
@@ -126,7 +148,12 @@
|
|||||||
<feGaussianBlur stdDeviation="2.5" />
|
<feGaussianBlur stdDeviation="2.5" />
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 0.72 0 0 0 0 0 0 0 0 1 0" />
|
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 0.72 0 0 0 0 0 0 0 0 1 0" />
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_843_28" />
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_843_28" />
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_843_28" result="shape" />
|
<feBlend
|
||||||
|
mode="normal"
|
||||||
|
in="SourceGraphic"
|
||||||
|
in2="effect1_dropShadow_843_28"
|
||||||
|
result="shape"
|
||||||
|
/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter
|
<filter
|
||||||
id="filter3_d_843_28"
|
id="filter3_d_843_28"
|
||||||
@@ -148,7 +175,12 @@
|
|||||||
<feGaussianBlur stdDeviation="2.5" />
|
<feGaussianBlur stdDeviation="2.5" />
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0.770833 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" />
|
<feColorMatrix type="matrix" values="0 0 0 0 0.770833 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" />
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_843_28" />
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_843_28" />
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_843_28" result="shape" />
|
<feBlend
|
||||||
|
mode="normal"
|
||||||
|
in="SourceGraphic"
|
||||||
|
in2="effect1_dropShadow_843_28"
|
||||||
|
result="shape"
|
||||||
|
/>
|
||||||
</filter>
|
</filter>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
@@ -173,14 +205,14 @@ export default defineComponent({
|
|||||||
indicator: {
|
indicator: {
|
||||||
offline: false,
|
offline: false,
|
||||||
status: DataStatus.Loading,
|
status: DataStatus.Loading,
|
||||||
message: 'data-status.S3',
|
message: 'data-status.S3'
|
||||||
},
|
},
|
||||||
|
|
||||||
greenLight: false,
|
greenLight: false,
|
||||||
greenBlinkLight: false,
|
greenBlinkLight: false,
|
||||||
redTopLight: false,
|
redTopLight: false,
|
||||||
orangeLight: false,
|
orangeLight: false,
|
||||||
redBottomLight: false,
|
redBottomLight: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -193,7 +225,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
dataStatus: store.dataStatuses,
|
dataStatus: store.dataStatuses,
|
||||||
store,
|
store
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -248,8 +280,8 @@ export default defineComponent({
|
|||||||
this.indicator.status = DataStatus.Loaded;
|
this.indicator.status = DataStatus.Loaded;
|
||||||
this.indicator.message = 'data-status.S2';
|
this.indicator.message = 'data-status.S2';
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -280,8 +312,8 @@ export default defineComponent({
|
|||||||
if (status == DataStatus.Loading) {
|
if (status == DataStatus.Loading) {
|
||||||
this.greenBlinkLight = true;
|
this.greenBlinkLight = true;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -375,4 +407,3 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -1,168 +0,0 @@
|
|||||||
<template>
|
|
||||||
<transition name="modal-anim">
|
|
||||||
<section class="update-modal card" v-if="releaseData && modalOpen">
|
|
||||||
<h2 class="modal_header text--primary">
|
|
||||||
<img :src="getImage('stacjownik-header-logo.svg')" alt="stacjownik logo" />
|
|
||||||
|
|
||||||
{{ releaseData.tag_name }}
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div class="horizontal"></div>
|
|
||||||
|
|
||||||
<div class="modal_content">
|
|
||||||
<h3>{{ $t('update.title') }}</h3>
|
|
||||||
<a :href="releaseData.html_url" target="_blank">{{ $t('update.release-link') }}</a>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<p>{{ $t('update.paragraph1') }}</p>
|
|
||||||
|
|
||||||
<!-- <div class="modal_changelog" v-html="markdownReleaseBody"></div> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal_actions">
|
|
||||||
<button class="btn btn--option" @click="modalOpen = false">{{ $t('update.confirm-button') }}</button>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</transition>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import axios from 'axios';
|
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
import packageInfo from '../../../package.json';
|
|
||||||
import imageMixin from '../../mixins/imageMixin';
|
|
||||||
import { ReleaseAPIData } from '../../scripts/interfaces/github_api/ReleaseAPIData';
|
|
||||||
import StorageManager from '../../scripts/managers/storageManager';
|
|
||||||
import { useStore } from '../../store/store';
|
|
||||||
|
|
||||||
|
|
||||||
const GH_LASTEST_RELEASE_URL = 'https://api.github.com/repos/Spythere/stacjownik/releases/latest';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
mixins: [imageMixin],
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
this.fetchReleases();
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
modalOpen: false,
|
|
||||||
|
|
||||||
releaseData: null as ReleaseAPIData | null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
store: useStore()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
async fetchReleases() {
|
|
||||||
const storedVersion = StorageManager.getStringValue('appVersion');
|
|
||||||
const appVersion = packageInfo.version;
|
|
||||||
|
|
||||||
// Zmiana
|
|
||||||
if (appVersion != storedVersion) {
|
|
||||||
StorageManager.setStringValue('appVersion', appVersion);
|
|
||||||
|
|
||||||
// Znajdź changelog na GitHubie, jeśli jest pokaż modal
|
|
||||||
try {
|
|
||||||
const releaseData: ReleaseAPIData = await (await axios.get(GH_LASTEST_RELEASE_URL)).data;
|
|
||||||
if (!releaseData) return;
|
|
||||||
|
|
||||||
const lastReleaseVersion = releaseData.tag_name.slice(1);
|
|
||||||
|
|
||||||
if (lastReleaseVersion == appVersion) {
|
|
||||||
this.releaseData = releaseData;
|
|
||||||
this.modalOpen = true;
|
|
||||||
|
|
||||||
StorageManager.setStringValue('releaseURL', releaseData.html_url);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Wystąpił błąd podczas pobierania danych z API GitHuba: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import '../../styles/card.scss';
|
|
||||||
@import '../../styles/responsive.scss';
|
|
||||||
|
|
||||||
|
|
||||||
.modal-anim {
|
|
||||||
&-enter-active,
|
|
||||||
&-leave-active {
|
|
||||||
transition: all $animDuration $animType;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-enter-from,
|
|
||||||
&-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translate(-50%, -50%) scale(0.45);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.update-modal {
|
|
||||||
text-align: center;
|
|
||||||
background-color: var(--clr-secondary);
|
|
||||||
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.horizontal {
|
|
||||||
margin: 1em 0;
|
|
||||||
|
|
||||||
height: 2px;
|
|
||||||
width: 100%;
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal_header {
|
|
||||||
font-size: 1.6em;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 50%;
|
|
||||||
vertical-align: text-top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal_content {
|
|
||||||
font-size: 1.1em;
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal_actions {
|
|
||||||
margin-top: 2em;
|
|
||||||
|
|
||||||
button {
|
|
||||||
color: white;
|
|
||||||
padding: 0.5em;
|
|
||||||
font-size: 1.2em;
|
|
||||||
|
|
||||||
background-color: black;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal_changelog {
|
|
||||||
font-size: 0.8em;
|
|
||||||
margin-top: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include smallScreen {
|
|
||||||
.update-modal {
|
|
||||||
height: auto;
|
|
||||||
max-width: 95%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="update-prompt">
|
|
||||||
<transition name="prompt-anim">
|
|
||||||
<div class="prompt_content" v-if="!hidePrompt && needRefresh">
|
|
||||||
<div>{{ $t('update.title') }}</div>
|
|
||||||
|
|
||||||
<div class="prompt_actions">
|
|
||||||
<button class="btn btn--filled" @click="updateServiceWorker(true)">{{ $t('update.confirm-button') }}</button>
|
|
||||||
<button class="btn btn--filled" @click="hidePrompt = true">{{ $t('update.later-button') }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import useCustomSW from '../../mixins/useCustomSW';
|
|
||||||
|
|
||||||
const hidePrompt = ref(false);
|
|
||||||
const { needRefresh, updateServiceWorker } = useCustomSW();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import '../../styles/variables.scss';
|
|
||||||
|
|
||||||
.update-prompt {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prompt_content {
|
|
||||||
margin: 1em;
|
|
||||||
padding: 1em;
|
|
||||||
|
|
||||||
font-weight: bold;
|
|
||||||
background-color: black;
|
|
||||||
|
|
||||||
box-shadow: 0 0 10px 1px $accentCol;
|
|
||||||
border-radius: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prompt_actions {
|
|
||||||
display: flex;
|
|
||||||
margin-top: 1em;
|
|
||||||
gap: 0.5em;
|
|
||||||
|
|
||||||
button {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animation
|
|
||||||
.prompt-anim {
|
|
||||||
&-enter-active,
|
|
||||||
&-leave-active {
|
|
||||||
transition: all 120ms ease-in;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
&-enter-from,
|
|
||||||
&-leave-to {
|
|
||||||
transform: translateY(100%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
@@ -7,14 +7,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from "vue";
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({});
|
export default defineComponent({});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "../../styles/variables";
|
@import '../../styles/variables';
|
||||||
@import "../../styles/responsive";
|
@import '../../styles/responsive';
|
||||||
|
|
||||||
.button_content {
|
.button_content {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -15,18 +15,18 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
scrollNoMoreData: {
|
scrollNoMoreData: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
scrollDataLoaded: {
|
scrollDataLoaded: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
list: {
|
list: {
|
||||||
type: Array as PropType<any[]>,
|
type: Array as PropType<any[]>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
emits: ['addHistoryData'],
|
emits: ['addHistoryData'],
|
||||||
@@ -34,8 +34,8 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
addHistoryData() {
|
addHistoryData() {
|
||||||
this.$emit('addHistoryData');
|
this.$emit('addHistoryData');
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { defineComponent } from 'vue';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
return {};
|
return {};
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="progress-bar">
|
<div class="progress-bar">
|
||||||
<span class="bar-bg"></span>
|
<span class="bar-bg"></span>
|
||||||
<span class="bar-fg" :style="{ width: `${~~progressPercent}%`, backgroundColor: bgColor }"></span>
|
<span
|
||||||
|
class="bar-fg"
|
||||||
|
:style="{ width: `${~~progressPercent}%`, backgroundColor: bgColor }"
|
||||||
|
></span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -12,12 +15,12 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
progressPercent: {
|
progressPercent: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
progressType: {
|
progressType: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
@@ -29,8 +32,8 @@ export default defineComponent({
|
|||||||
default:
|
default:
|
||||||
return 'springgreen';
|
return 'springgreen';
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -7,39 +7,34 @@
|
|||||||
@keypress="updateValue"
|
@keypress="updateValue"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<img
|
<img class="search-exit" :src="getIcon('exit')" alt="exit-icon" @click="clearSearchValue" />
|
||||||
class="search-exit"
|
|
||||||
:src="getIcon('exit')"
|
|
||||||
alt="exit-icon"
|
|
||||||
@click="clearValue"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref, watch } from "vue";
|
import { defineComponent, ref, watch } from 'vue';
|
||||||
import imageMixin from "../../mixins/imageMixin";
|
import imageMixin from '../../mixins/imageMixin';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [imageMixin],
|
mixins: [imageMixin],
|
||||||
|
|
||||||
emits: ["update:searchedValue", "clearValue"],
|
emits: ['update:searchedValue', 'clearValue'],
|
||||||
props: {
|
props: {
|
||||||
searchedValue: {
|
searchedValue: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
updateOnInput: {
|
updateOnInput: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true
|
||||||
},
|
},
|
||||||
titleToTranslate: {
|
titleToTranslate: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
clearValue: {
|
clearValue: {
|
||||||
type: Function,
|
type: Function
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
@@ -49,32 +44,32 @@ export default defineComponent({
|
|||||||
watch(
|
watch(
|
||||||
() => compSearchedValue.value,
|
() => compSearchedValue.value,
|
||||||
(value) => {
|
(value) => {
|
||||||
emit("update:searchedValue", value);
|
emit('update:searchedValue', value);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearValue = () => {
|
const clearSearchValue = () => {
|
||||||
compSearchedValue.value = "";
|
compSearchedValue.value = '';
|
||||||
emit("clearValue");
|
emit('clearValue');
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateValue = (e: any) => {
|
const updateValue = (e: any) => {
|
||||||
if (!props.updateOnInput && e.keyCode == 13)
|
if (!props.updateOnInput && e.keyCode == 13)
|
||||||
emit("update:searchedValue", compSearchedValue.value);
|
emit('update:searchedValue', compSearchedValue.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compSearchedValue,
|
compSearchedValue,
|
||||||
updateValue,
|
updateValue,
|
||||||
clearValue,
|
clearSearchValue
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "../../styles/responsive";
|
@import '../../styles/responsive';
|
||||||
|
|
||||||
.search {
|
.search {
|
||||||
&-box {
|
&-box {
|
||||||
|
|||||||
@@ -19,7 +19,11 @@
|
|||||||
>
|
>
|
||||||
<label :for="item.id" v-if="listOpen">
|
<label :for="item.id" v-if="listOpen">
|
||||||
<input type="button" :id="item.id" name="select-box" @click="selectOption(item)" />
|
<input type="button" :id="item.id" name="select-box" @click="selectOption(item)" />
|
||||||
<span :style="computedSelectedItem.id == item.id ? 'color: gold;' : ''" v-html="item.value"> </span>
|
<span
|
||||||
|
:style="computedSelectedItem.id == item.id ? 'color: gold;' : ''"
|
||||||
|
v-html="item.value"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</transition>
|
</transition>
|
||||||
</li>
|
</li>
|
||||||
@@ -45,18 +49,18 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
itemList: {
|
itemList: {
|
||||||
type: Array as () => Item[],
|
type: Array as () => Item[],
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
defaultItemIndex: {
|
defaultItemIndex: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0,
|
default: 0
|
||||||
},
|
},
|
||||||
|
|
||||||
prefix: {
|
prefix: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: ''
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
@@ -69,7 +73,10 @@ export default defineComponent({
|
|||||||
let selectedItem: Ref<Item> = ref(props.itemList[props.defaultItemIndex]);
|
let selectedItem: Ref<Item> = ref(props.itemList[props.defaultItemIndex]);
|
||||||
|
|
||||||
const computedSelectedItem = computed(() => {
|
const computedSelectedItem = computed(() => {
|
||||||
return props.itemList.find((item) => item.id === selectedItem.value.id) || props.itemList[props.defaultItemIndex];
|
return (
|
||||||
|
props.itemList.find((item) => item.id === selectedItem.value.id) ||
|
||||||
|
props.itemList[props.defaultItemIndex]
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -78,7 +85,7 @@ export default defineComponent({
|
|||||||
selectedItem,
|
selectedItem,
|
||||||
listRef,
|
listRef,
|
||||||
buttonRef,
|
buttonRef,
|
||||||
activeEl,
|
activeEl
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -99,8 +106,8 @@ export default defineComponent({
|
|||||||
clickedOutside() {
|
clickedOutside() {
|
||||||
this.listOpen = false;
|
this.listOpen = false;
|
||||||
this.buttonRef?.blur();
|
this.buttonRef?.blur();
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -16,16 +16,16 @@ import dateMixin from '../../mixins/dateMixin';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
statusID: {
|
statusID: {
|
||||||
type: String,
|
type: String
|
||||||
},
|
},
|
||||||
statusTimestamp: {
|
statusTimestamp: {
|
||||||
type: Number,
|
type: Number
|
||||||
},
|
},
|
||||||
isOnline: {
|
isOnline: {
|
||||||
type: Boolean,
|
type: Boolean
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mixins: [dateMixin],
|
mixins: [dateMixin]
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="stock-list">
|
<div class="stock-list">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(stockName, i) in trainStockList">
|
<li v-for="(stockName, i) in trainStockList" :key="i">
|
||||||
<p>{{ stockName.split(':')[0].split('_').splice(0, 2).join(' ') }} {{ stockName.split(':')[1] }}</p>
|
<p>
|
||||||
|
{{ stockName.split(':')[0].split('_').splice(0, 2).join(' ') }}
|
||||||
|
{{ stockName.split(':')[1] }}
|
||||||
|
</p>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
<img
|
<img
|
||||||
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stockName.split(':')[0]}${/^EN/.test(stockName) ? 'rb' : ''}.png`"
|
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stockName.split(':')[0]}${
|
||||||
|
/^EN/.test(stockName) ? 'rb' : ''
|
||||||
|
}.png`"
|
||||||
@error="onImageError($event, stockName)"
|
@error="onImageError($event, stockName)"
|
||||||
width="400"
|
width="400"
|
||||||
height="60"
|
height="60"
|
||||||
@@ -15,21 +20,27 @@
|
|||||||
<img
|
<img
|
||||||
v-if="/^(EN|2EN)/.test(stockName)"
|
v-if="/^(EN|2EN)/.test(stockName)"
|
||||||
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stockName.split(':')[0]}s.png`"
|
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stockName.split(':')[0]}s.png`"
|
||||||
@error="(event) => ((event.target as HTMLImageElement).src = '/images/icon-loco-ezt-s.png')"
|
@error="
|
||||||
|
(event) => ((event.target as HTMLImageElement).src = '/images/icon-loco-ezt-s.png')
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
class="train-thumbnail"
|
class="train-thumbnail"
|
||||||
v-if="/^EN71/.test(stockName)"
|
v-if="/^EN71/.test(stockName)"
|
||||||
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stockName.split(':')[0]}s.png`"
|
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stockName.split(':')[0]}s.png`"
|
||||||
@error="(event) => ((event.target as HTMLImageElement).src = '/images/icon-loco-ezt-s.png')"
|
@error="
|
||||||
|
(event) => ((event.target as HTMLImageElement).src = '/images/icon-loco-ezt-s.png')
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
class="train-thumbnail"
|
class="train-thumbnail"
|
||||||
v-if="/^(EN|2EN)/.test(stockName)"
|
v-if="/^(EN|2EN)/.test(stockName)"
|
||||||
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stockName.split(':')[0]}ra.png`"
|
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stockName.split(':')[0]}ra.png`"
|
||||||
@error="(event) => ((event.target as HTMLImageElement).src = '/images/icon-loco-ezt-ra.png')"
|
@error="
|
||||||
|
(event) => ((event.target as HTMLImageElement).src = '/images/icon-loco-ezt-ra.png')
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
@@ -49,13 +60,13 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
trainStockList: {
|
trainStockList: {
|
||||||
type: Array as PropType<string[]>,
|
type: Array as PropType<string[]>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
store: useStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -63,12 +74,14 @@ 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((v) => v[0] === stockName.split(':')[0]);
|
return this.store.rollingStockData!.info[type as keyof RollingStockInfo].find(
|
||||||
|
(v) => v[0] === stockName.split(':')[0]
|
||||||
|
);
|
||||||
}) || 'vehicle-unknown';
|
}) || 'vehicle-unknown';
|
||||||
|
|
||||||
(event.target as HTMLImageElement).src = `/images/icon-${fallbackName}.png`;
|
(event.target as HTMLImageElement).src = `/images/icon-${fallbackName}.png`;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
:class="{
|
:class="{
|
||||||
delayed: stop.arrivalDelay > 0 && (stop.confirmed || stop.stopped),
|
delayed: stop.arrivalDelay > 0 && (stop.confirmed || stop.stopped),
|
||||||
preponed: stop.arrivalDelay < 0 && (stop.confirmed || stop.stopped),
|
preponed: stop.arrivalDelay < 0 && (stop.confirmed || stop.stopped),
|
||||||
'on-time': stop.arrivalDelay == 0 && stop.confirmed,
|
'on-time': stop.arrivalDelay == 0 && stop.confirmed
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<span v-if="stop.arrivalDelay != 0 && (stop.confirmed || stop.stopped)">
|
<span v-if="stop.arrivalDelay != 0 && (stop.confirmed || stop.stopped)">
|
||||||
@@ -20,7 +20,11 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="date stop" v-if="stop.stopTime || stop.stopped" :class="stop.stopType.replace(', ', '-')">
|
<span
|
||||||
|
class="date stop"
|
||||||
|
v-if="stop.stopTime || stop.stopped"
|
||||||
|
:class="stop.stopType.replace(', ', '-')"
|
||||||
|
>
|
||||||
{{ stop.stopTime }} {{ stop.stopType == '' ? 'pt' : stop.stopType }}
|
{{ stop.stopTime }} {{ stop.stopType == '' ? 'pt' : stop.stopType }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -29,7 +33,7 @@
|
|||||||
v-if="!stop.terminatesHere && (stop.stopTime != 0 || stop.stopped)"
|
v-if="!stop.terminatesHere && (stop.stopTime != 0 || stop.stopped)"
|
||||||
:class="{
|
:class="{
|
||||||
delayed: stop.departureDelay > 0 && stop.confirmed,
|
delayed: stop.departureDelay > 0 && stop.confirmed,
|
||||||
preponed: stop.departureDelay < 0 && stop.confirmed,
|
preponed: stop.departureDelay < 0 && stop.confirmed
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<span v-if="stop.departureDelay != 0 && stop.confirmed">
|
<span v-if="stop.departureDelay != 0 && stop.confirmed">
|
||||||
@@ -57,13 +61,13 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
stop: {
|
stop: {
|
||||||
type: Object as () => TrainStop,
|
type: Object as () => TrainStop,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return {};
|
return {};
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isTopBarVisible: false,
|
isTopBarVisible: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ export default defineComponent({
|
|||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
store,
|
store
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -49,12 +49,14 @@ export default defineComponent({
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
handleContentScroll(e: Event) {
|
handleContentScroll(e: Event) {
|
||||||
const trainInfoCompHeight: number = (this.$refs['trainInfo'] as any).$el.getBoundingClientRect().height;
|
const trainInfoCompHeight: number = (
|
||||||
|
this.$refs['trainInfo'] as any
|
||||||
|
).$el.getBoundingClientRect().height;
|
||||||
|
|
||||||
const posTop = (e.target as HTMLElement).scrollTop;
|
const posTop = (e.target as HTMLElement).scrollTop;
|
||||||
this.isTopBarVisible = posTop > trainInfoCompHeight;
|
this.isTopBarVisible = posTop > trainInfoCompHeight;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -144,7 +146,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include smallScreen {
|
@include smallScreen {
|
||||||
|
|
||||||
.modal_content {
|
.modal_content {
|
||||||
max-height: 85vh;
|
max-height: 85vh;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
<img
|
<img
|
||||||
class="train-thumbnail"
|
class="train-thumbnail"
|
||||||
v-else
|
v-else
|
||||||
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${name.split(':')[0]}${stockType == 'loco-ezt' ? 'rb' : ''}.png`"
|
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${name.split(':')[0]}${
|
||||||
|
stockType == 'loco-ezt' ? 'rb' : ''
|
||||||
|
}.png`"
|
||||||
@error="onImageError"
|
@error="onImageError"
|
||||||
@load="onImageLoad"
|
@load="onImageLoad"
|
||||||
width="220"
|
width="220"
|
||||||
@@ -14,7 +16,6 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import imageMixin from '../../mixins/imageMixin';
|
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/store';
|
||||||
import { RollingStockInfo } from '../../scripts/interfaces/github_api/StockInfoGithubData';
|
import { RollingStockInfo } from '../../scripts/interfaces/github_api/StockInfoGithubData';
|
||||||
|
|
||||||
@@ -22,20 +23,20 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
onlyFirstSegment: {
|
onlyFirstSegment: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
store: useStore(),
|
||||||
isNotFound: false,
|
isNotFound: false,
|
||||||
isLoaded: false,
|
isLoaded: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -53,10 +54,12 @@ 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((v) => v[0] === this.name.split(':')[0]);
|
return this.store.rollingStockData?.info[type as keyof RollingStockInfo].find(
|
||||||
|
(v) => v[0] === this.name.split(':')[0]
|
||||||
|
);
|
||||||
}) || 'vehicle-unknown'
|
}) || 'vehicle-unknown'
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -68,8 +71,8 @@ export default defineComponent({
|
|||||||
onImageLoad() {
|
onImageLoad() {
|
||||||
this.isNotFound = false;
|
this.isNotFound = false;
|
||||||
this.isLoaded = true;
|
this.isLoaded = true;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -54,42 +54,42 @@
|
|||||||
</i18n-t>
|
</i18n-t>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="firstPlaceDispatchers.length == 1">
|
<div v-if="topDispatchers.length == 1">
|
||||||
•
|
•
|
||||||
<i18n-t keypath="journal.timetable-stats-most-active-dr">
|
<i18n-t keypath="journal.timetable-stats-most-active-dr">
|
||||||
<template #dispatcher>
|
<template #dispatcher>
|
||||||
<router-link :to="`/journal/dispatchers?dispatcherName=${firstPlaceDispatchers[0].name}`">
|
<router-link :to="`/journal/dispatchers?dispatcherName=${topDispatchers[0].name}`">
|
||||||
<b>{{ firstPlaceDispatchers[0].name }}</b>
|
<b>{{ topDispatchers[0].name }}</b>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
<template #count>
|
<template #count>
|
||||||
<b class="text--primary">
|
<b class="text--primary">
|
||||||
{{ firstPlaceDispatchers[0].count }}
|
{{ topDispatchers[0].count }}
|
||||||
{{ $t('journal.timetable-count', firstPlaceDispatchers[0].count) }}
|
{{ $t('journal.timetable-count', topDispatchers[0].count) }}
|
||||||
</b>
|
</b>
|
||||||
</template>
|
</template>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="firstPlaceDispatchers.length > 1">
|
<div v-if="topDispatchers.length > 1">
|
||||||
•
|
•
|
||||||
<i18n-t keypath="journal.timetable-stats-most-active-dr-many">
|
<i18n-t keypath="journal.timetable-stats-most-active-dr-many">
|
||||||
<template #dispatchers>
|
<template #dispatchers>
|
||||||
<span v-for="(disp, i) in firstPlaceDispatchers">
|
<span v-for="(disp, i) in topDispatchers" :key="i">
|
||||||
<span v-if="i == firstPlaceDispatchers.length - 1"> {{ $t('general.and') }} </span>
|
<span v-if="i == topDispatchers.length - 1"> {{ $t('general.and') }} </span>
|
||||||
|
|
||||||
<router-link :to="`/journal/dispatchers?dispatcherName=${disp.name}`">
|
<router-link :to="`/journal/dispatchers?dispatcherName=${disp.name}`">
|
||||||
<b>{{ disp.name }}</b>
|
<b>{{ disp.name }}</b>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<span v-if="i < firstPlaceDispatchers.length - 2">, </span>
|
<span v-if="i < topDispatchers.length - 2">, </span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #count>
|
<template #count>
|
||||||
<b class="text--primary">
|
<b class="text--primary">
|
||||||
{{ firstPlaceDispatchers[0].count }}
|
{{ topDispatchers[0].count }}
|
||||||
{{ $t('journal.timetable-count', firstPlaceDispatchers[0].count) }}
|
{{ $t('journal.timetable-count', topDispatchers[0].count) }}
|
||||||
</b>
|
</b>
|
||||||
</template>
|
</template>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
@@ -99,7 +99,9 @@
|
|||||||
•
|
•
|
||||||
<i18n-t keypath="journal.timetable-stats-longest-duties">
|
<i18n-t keypath="journal.timetable-stats-longest-duties">
|
||||||
<template #dispatcher>
|
<template #dispatcher>
|
||||||
<router-link :to="`/journal/dispatchers?dispatcherName=${stats.longestDuties[0].name}`">
|
<router-link
|
||||||
|
:to="`/journal/dispatchers?dispatcherName=${stats.longestDuties[0].name}`"
|
||||||
|
>
|
||||||
<b>{{ stats.longestDuties[0].name }}</b>
|
<b>{{ stats.longestDuties[0].name }}</b>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
@@ -133,7 +135,10 @@ 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 { DataStatus } from '../../scripts/enums/DataStatus';
|
||||||
import { ITimetablesDailyStats, ITimetablesDailyStatsResponse } from '../../scripts/interfaces/api/StatsAPIData';
|
import {
|
||||||
|
ITimetablesDailyStats,
|
||||||
|
ITimetablesDailyStatsResponse
|
||||||
|
} from '../../scripts/interfaces/api/StatsAPIData';
|
||||||
import { URLs } from '../../scripts/utils/apiURLs';
|
import { URLs } from '../../scripts/utils/apiURLs';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -156,8 +161,8 @@ export default defineComponent({
|
|||||||
timetableRouteDistance: 0,
|
timetableRouteDistance: 0,
|
||||||
longestDuties: [],
|
longestDuties: [],
|
||||||
mostActiveDrivers: [],
|
mostActiveDrivers: [],
|
||||||
mostActiveDispatchers: [],
|
mostActiveDispatchers: []
|
||||||
} as ITimetablesDailyStats,
|
} as ITimetablesDailyStats
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -171,12 +176,12 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
firstPlaceDispatchers() {
|
topDispatchers() {
|
||||||
if (this.stats.mostActiveDispatchers.length == 0) return [];
|
if (this.stats.mostActiveDispatchers.length == 0) return [];
|
||||||
const maxCount = this.stats.mostActiveDispatchers[0].count;
|
const maxCount = this.stats.mostActiveDispatchers[0].count;
|
||||||
|
|
||||||
return this.stats.mostActiveDispatchers.filter((disp) => disp.count === maxCount);
|
return this.stats.mostActiveDispatchers.filter((disp) => disp.count === maxCount);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -197,7 +202,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
mostActiveDispatchers: res.mostActiveDispatchers,
|
mostActiveDispatchers: res.mostActiveDispatchers,
|
||||||
mostActiveDrivers: res.mostActiveDrivers,
|
mostActiveDrivers: res.mostActiveDrivers,
|
||||||
longestDuties: res.longestDuties,
|
longestDuties: res.longestDuties
|
||||||
};
|
};
|
||||||
|
|
||||||
this.statsStatus = DataStatus.Loaded;
|
this.statsStatus = DataStatus.Loaded;
|
||||||
@@ -218,8 +223,8 @@ export default defineComponent({
|
|||||||
stopFetchingDailyStats() {
|
stopFetchingDailyStats() {
|
||||||
clearInterval(this.intervalId);
|
clearInterval(this.intervalId);
|
||||||
this.intervalId = -1;
|
this.intervalId = -1;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -247,4 +252,3 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,9 @@
|
|||||||
|
|
||||||
<h3>OSTATNIE WYSTAWIONE ROZKŁADY</h3>
|
<h3>OSTATNIE WYSTAWIONE ROZKŁADY</h3>
|
||||||
<div class="last-timetables">
|
<div class="last-timetables">
|
||||||
<div class="timetable-row" v-for="timetable in timetables">
|
<div class="timetable-row" v-for="timetable in timetables" :key="timetable.id">
|
||||||
#{{ timetable.timetableId }} | <b>{{ timetable.trainCategoryCode }} {{ timetable.trainNo }}</b> |
|
#{{ timetable.timetableId }} |
|
||||||
|
<b>{{ timetable.trainCategoryCode }} {{ timetable.trainNo }}</b> |
|
||||||
{{ timetable.driverName }} ({{ timetable.routeDistance }}km)
|
{{ timetable.driverName }} ({{ timetable.routeDistance }}km)
|
||||||
<div>{{ timetable.route.replace('|', ' > ') }}</div>
|
<div>{{ timetable.route.replace('|', ' > ') }}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -49,9 +50,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { computed, defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { DispatcherStatsAPIData } from '../../scripts/interfaces/api/DispatcherStatsAPIData';
|
import { DispatcherStatsAPIData } from '../../scripts/interfaces/api/DispatcherStatsAPIData';
|
||||||
import { TimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
|
import { TimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
|
||||||
import { URLs } from '../../scripts/utils/apiURLs';
|
import { URLs } from '../../scripts/utils/apiURLs';
|
||||||
@@ -64,15 +64,8 @@ export default defineComponent({
|
|||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
const statsData2 = computed(async () => {
|
|
||||||
return await (
|
|
||||||
await axios.get(`${URLs.stacjownikAPI}/api/getDispatcherInfo?name=${store.dispatcherStatsName}`)
|
|
||||||
).data;
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
store,
|
store
|
||||||
statsData2,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -80,7 +73,7 @@ export default defineComponent({
|
|||||||
return {
|
return {
|
||||||
cardVisible: false,
|
cardVisible: false,
|
||||||
lastDispatcherName: '',
|
lastDispatcherName: '',
|
||||||
timetables: [] as TimetableHistory[],
|
timetables: [] as TimetableHistory[]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -98,18 +91,22 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const statsData: DispatcherStatsAPIData = await (
|
const statsData: DispatcherStatsAPIData = await (
|
||||||
await axios.get(`${URLs.stacjownikAPI}/api/getDispatcherInfo?name=${this.store.dispatcherStatsName}`)
|
await axios.get(
|
||||||
|
`${URLs.stacjownikAPI}/api/getDispatcherInfo?name=${this.store.dispatcherStatsName}`
|
||||||
|
)
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
const timetables: TimetableHistory[] = await (
|
const timetables: TimetableHistory[] = await (
|
||||||
await axios.get(`${URLs.stacjownikAPI}/api/getTimetables?authorName=${this.store.dispatcherStatsName}`)
|
await axios.get(
|
||||||
|
`${URLs.stacjownikAPI}/api/getTimetables?authorName=${this.store.dispatcherStatsName}`
|
||||||
|
)
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
this.timetables = timetables;
|
this.timetables = timetables;
|
||||||
this.store.dispatcherStatsData = statsData;
|
this.store.dispatcherStatsData = statsData;
|
||||||
this.lastDispatcherName = this.store.dispatcherStatsName;
|
this.lastDispatcherName = this.store.dispatcherStatsName;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -163,11 +160,7 @@ h3 {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.last-timetables {
|
.last-timetables {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -32,13 +32,17 @@
|
|||||||
<transition-group name="list-anim">
|
<transition-group name="list-anim">
|
||||||
<tr v-for="historyItem in dispatcherHistory" :key="historyItem.id">
|
<tr v-for="historyItem in dispatcherHistory" :key="historyItem.id">
|
||||||
<td>
|
<td>
|
||||||
<router-link :to="`/journal/dispatchers?sceneryName=${historyItem.stationName}`">
|
<router-link
|
||||||
|
:to="`/journal/dispatchers?sceneryName=${historyItem.stationName}`"
|
||||||
|
>
|
||||||
<b>{{ historyItem.stationName }}</b>
|
<b>{{ historyItem.stationName }}</b>
|
||||||
</router-link>
|
</router-link>
|
||||||
</td>
|
</td>
|
||||||
<td>#{{ historyItem.stationHash }}</td>
|
<td>#{{ historyItem.stationHash }}</td>
|
||||||
<td>
|
<td>
|
||||||
<router-link :to="`/journal/dispatchers?dispatcherName=${historyItem.dispatcherName}`">
|
<router-link
|
||||||
|
:to="`/journal/dispatchers?dispatcherName=${historyItem.dispatcherName}`"
|
||||||
|
>
|
||||||
<b>{{ historyItem.dispatcherName }}</b>
|
<b>{{ historyItem.dispatcherName }}</b>
|
||||||
</router-link>
|
</router-link>
|
||||||
</td>
|
</td>
|
||||||
@@ -46,7 +50,12 @@
|
|||||||
<b
|
<b
|
||||||
v-if="historyItem.dispatcherLevel !== null"
|
v-if="historyItem.dispatcherLevel !== null"
|
||||||
class="level-badge dispatcher"
|
class="level-badge dispatcher"
|
||||||
:style="calculateExpStyle(historyItem.dispatcherLevel, historyItem.dispatcherIsSupporter)"
|
:style="
|
||||||
|
calculateExpStyle(
|
||||||
|
historyItem.dispatcherLevel,
|
||||||
|
historyItem.dispatcherIsSupporter
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ historyItem.dispatcherLevel >= 2 ? historyItem.dispatcherLevel : 'L' }}
|
{{ historyItem.dispatcherLevel >= 2 ? historyItem.dispatcherLevel : 'L' }}
|
||||||
</b>
|
</b>
|
||||||
@@ -122,27 +131,27 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
dispatcherHistory: {
|
dispatcherHistory: {
|
||||||
type: Array as PropType<DispatcherHistory[]>,
|
type: Array as PropType<DispatcherHistory[]>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
scrollNoMoreData: {
|
scrollNoMoreData: {
|
||||||
type: Boolean,
|
type: Boolean
|
||||||
},
|
},
|
||||||
scrollDataLoaded: {
|
scrollDataLoaded: {
|
||||||
type: Boolean,
|
type: Boolean
|
||||||
},
|
},
|
||||||
addHistoryData: {
|
addHistoryData: {
|
||||||
type: Function as PropType<() => void>,
|
type: Function as PropType<() => void>
|
||||||
},
|
},
|
||||||
dataStatus: {
|
dataStatus: {
|
||||||
type: Number as PropType<DataStatus>,
|
type: Number as PropType<DataStatus>
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
DataStatus,
|
DataStatus,
|
||||||
store: useStore(),
|
store: useStore(),
|
||||||
regions,
|
regions
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -150,13 +159,17 @@ export default defineComponent({
|
|||||||
computedDispatcherHistory() {
|
computedDispatcherHistory() {
|
||||||
console.log(this.dispatcherHistory.length);
|
console.log(this.dispatcherHistory.length);
|
||||||
|
|
||||||
return this.dispatcherHistory.reduce((acc, historyItem, i) => {
|
return this.dispatcherHistory.reduce(
|
||||||
if (this.isAnotherDay(i - 1, i)) acc.push(new Date(historyItem.timestampFrom).toLocaleDateString('pl-PL'));
|
(acc, historyItem, i) => {
|
||||||
acc.push(historyItem);
|
if (this.isAnotherDay(i - 1, i))
|
||||||
|
acc.push(new Date(historyItem.timestampFrom).toLocaleDateString('pl-PL'));
|
||||||
|
acc.push(historyItem);
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
}, [] as (DispatcherHistory | string)[]);
|
},
|
||||||
},
|
[] as (DispatcherHistory | string)[]
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -173,8 +186,8 @@ export default defineComponent({
|
|||||||
new Date(this.dispatcherHistory[prevIndex].timestampFrom).getDate() !=
|
new Date(this.dispatcherHistory[prevIndex].timestampFrom).getDate() !=
|
||||||
new Date(this.dispatcherHistory[currIndex].timestampFrom).getDate()
|
new Date(this.dispatcherHistory[currIndex].timestampFrom).getDate()
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,17 @@
|
|||||||
<div class="journal-stats">
|
<div class="journal-stats">
|
||||||
<span v-if="store.driverStatsData">
|
<span v-if="store.driverStatsData">
|
||||||
<h3>
|
<h3>
|
||||||
{{ $t('journal.stats-title') }} <span class="text--primary">{{ store.driverStatsName.toUpperCase() }}</span>
|
{{ $t('journal.stats-title') }}
|
||||||
|
<span class="text--primary">{{ store.driverStatsName.toUpperCase() }}</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div class="info-stats">
|
<div class="info-stats">
|
||||||
<span class="stat-badge">
|
<span class="stat-badge">
|
||||||
<span>{{ $t('journal.stats-timetables') }}</span>
|
<span>{{ $t('journal.stats-timetables') }}</span>
|
||||||
<span>{{ store.driverStatsData._count.fulfilled }} / {{ store.driverStatsData._count._all }}</span>
|
<span
|
||||||
|
>{{ store.driverStatsData._count.fulfilled }} /
|
||||||
|
{{ store.driverStatsData._count._all }}</span
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="stat-badge">
|
<span class="stat-badge">
|
||||||
@@ -39,7 +43,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<b v-else-if="store.driverStatsStatus == DataStatus.Loading">{{ $t('journal.stats-loading') }}</b>
|
<b v-else-if="store.driverStatsStatus == DataStatus.Loading">{{
|
||||||
|
$t('journal.stats-loading')
|
||||||
|
}}</b>
|
||||||
<b v-else-if="store.driverStatsStatus == DataStatus.Error">
|
<b v-else-if="store.driverStatsStatus == DataStatus.Error">
|
||||||
{{ $t('journal.stats-error ') }}
|
{{ $t('journal.stats-error ') }}
|
||||||
</b>
|
</b>
|
||||||
@@ -56,9 +62,9 @@ export default defineComponent({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
store: useStore(),
|
||||||
DataStatus,
|
DataStatus
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
<div class="bg" v-if="showOptions" @click="showOptions = false"></div>
|
<div class="bg" v-if="showOptions" @click="showOptions = false"></div>
|
||||||
|
|
||||||
<div class="actions-bar">
|
<div class="actions-bar">
|
||||||
<button class="filter-button btn--filled btn--image" @click="showOptions = !showOptions" ref="button">
|
<button
|
||||||
|
class="filter-button btn--filled btn--image"
|
||||||
|
@click="showOptions = !showOptions"
|
||||||
|
ref="button"
|
||||||
|
>
|
||||||
<img :src="getIcon('filter2')" alt="Open filters" />
|
<img :src="getIcon('filter2')" alt="Open filters" />
|
||||||
{{ $t('options.filters') }} [F]
|
{{ $t('options.filters') }} [F]
|
||||||
<span class="active-indicator" v-if="currentOptionsActive"></span>
|
<span class="active-indicator" v-if="currentOptionsActive"></span>
|
||||||
@@ -16,11 +20,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<datalist id="search-driver">
|
<datalist id="search-driver">
|
||||||
<option v-for="sugg in driverSuggestions" :value="sugg"></option>
|
<option v-for="(sugg, i) in driverSuggestions" :key="i" :value="sugg"></option>
|
||||||
</datalist>
|
</datalist>
|
||||||
|
|
||||||
<datalist id="search-dispatcher">
|
<datalist id="search-dispatcher">
|
||||||
<option v-for="sugg in dispatcherSuggestions" :value="sugg"></option>
|
<option v-for="(sugg, i) in dispatcherSuggestions" :key="i" :value="sugg"></option>
|
||||||
</datalist>
|
</datalist>
|
||||||
|
|
||||||
<transition name="options-anim">
|
<transition name="options-anim">
|
||||||
@@ -29,7 +33,9 @@
|
|||||||
<h1 class="option-title">{{ $t('options.search-title') }}</h1>
|
<h1 class="option-title">{{ $t('options.search-title') }}</h1>
|
||||||
<div class="search_content">
|
<div class="search_content">
|
||||||
<div class="search" v-for="(_, propName) in searchersValues" :key="propName">
|
<div class="search" v-for="(_, propName) in searchersValues" :key="propName">
|
||||||
<label v-if="propName == 'search-date'" for="date">{{ $t(`options.search-${optionsType}-date`) }}</label>
|
<label v-if="propName == 'search-date'" for="date">{{
|
||||||
|
$t(`options.search-${optionsType}-date`)
|
||||||
|
}}</label>
|
||||||
|
|
||||||
<div class="search-box">
|
<div class="search-box">
|
||||||
<input
|
<input
|
||||||
@@ -53,7 +59,7 @@
|
|||||||
|
|
||||||
<h1 class="option-title">{{ $t('options.sort-title') }}</h1>
|
<h1 class="option-title">{{ $t('options.sort-title') }}</h1>
|
||||||
<div class="options_sorters">
|
<div class="options_sorters">
|
||||||
<div v-for="opt in translatedSorterOptions">
|
<div v-for="opt in translatedSorterOptions" :key="opt.id">
|
||||||
<button
|
<button
|
||||||
class="sort-option btn--option"
|
class="sort-option btn--option"
|
||||||
:data-selected="opt.id == sorterActive.id"
|
:data-selected="opt.id == sorterActive.id"
|
||||||
@@ -67,12 +73,13 @@
|
|||||||
<h1 class="option-title" v-if="filters.length != 0">{{ $t('options.filter-title') }}</h1>
|
<h1 class="option-title" v-if="filters.length != 0">{{ $t('options.filter-title') }}</h1>
|
||||||
|
|
||||||
<div class="options_filter-sections" v-if="filters.length != 0 && filterList">
|
<div class="options_filter-sections" v-if="filters.length != 0 && filterList">
|
||||||
<section class="filter-section" v-for="section in JournalFilterSection">
|
<section class="filter-section" v-for="section in JournalFilterSection" :key="section">
|
||||||
<p>{{ $t(`options.filter-section-${section}`) }}</p>
|
<p>{{ $t(`options.filter-section-${section}`) }}</p>
|
||||||
|
|
||||||
<div class="options_filters">
|
<div class="options_filters">
|
||||||
<button
|
<button
|
||||||
v-for="filter in filterList.filter((f) => f.filterSection == section)"
|
v-for="filter in filterList.filter((f) => f.filterSection == section)"
|
||||||
|
:key="filter.id"
|
||||||
class="filter-option btn--option"
|
class="filter-option btn--option"
|
||||||
:class="{ checked: filter.isActive }"
|
:class="{ checked: filter.isActive }"
|
||||||
:id="filter.id"
|
:id="filter.id"
|
||||||
@@ -107,41 +114,38 @@ import { DataStatus } from '../../scripts/enums/DataStatus';
|
|||||||
import { DriverStatsAPIData } from '../../scripts/interfaces/api/DriverStatsAPIData';
|
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/store';
|
||||||
import ActionButton from '../Global/ActionButton.vue';
|
|
||||||
import SelectBox from '../Global/SelectBox.vue';
|
|
||||||
import { JournalFilterSection } from '../../scripts/enums/JournalFilterType';
|
import { JournalFilterSection } from '../../scripts/enums/JournalFilterType';
|
||||||
import { JournalFilter } from '../../scripts/types/JournalTimetablesTypes';
|
import { JournalFilter } from '../../scripts/types/JournalTimetablesTypes';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { SelectBox, ActionButton },
|
|
||||||
emits: ['onSearchConfirm', 'onOptionsReset', 'onRefreshData'],
|
emits: ['onSearchConfirm', 'onOptionsReset', 'onRefreshData'],
|
||||||
mixins: [imageMixin, keyMixin],
|
mixins: [imageMixin, keyMixin],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
sorterOptionIds: {
|
sorterOptionIds: {
|
||||||
type: Array as PropType<Array<string>>,
|
type: Array as PropType<Array<string>>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
filters: {
|
filters: {
|
||||||
type: Array as PropType<JournalFilter[]>,
|
type: Array as PropType<JournalFilter[]>,
|
||||||
default: [],
|
default: () => []
|
||||||
},
|
},
|
||||||
|
|
||||||
dataStatus: {
|
dataStatus: {
|
||||||
type: Number as PropType<DataStatus>,
|
type: Number as PropType<DataStatus>,
|
||||||
default: DataStatus.Initialized,
|
default: DataStatus.Initialized
|
||||||
},
|
},
|
||||||
|
|
||||||
currentOptionsActive: {
|
currentOptionsActive: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
optionsType: {
|
optionsType: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
@@ -155,7 +159,7 @@ export default defineComponent({
|
|||||||
searchTimeout: 0,
|
searchTimeout: 0,
|
||||||
store: useStore(),
|
store: useStore(),
|
||||||
|
|
||||||
DataStatus,
|
DataStatus
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -163,26 +167,21 @@ 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 },
|
||||||
// journalFilterActive: inject('journalFilterActive') as JournalFilter,
|
filterList: inject('filterList') as JournalFilter[] | undefined
|
||||||
filterList: inject('filterList') as JournalFilter[] | undefined,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
driverStatsName() {
|
|
||||||
return this.store.driverStatsName;
|
|
||||||
},
|
|
||||||
|
|
||||||
translatedSorterOptions() {
|
translatedSorterOptions() {
|
||||||
return this.$props.sorterOptionIds.map((id) => ({
|
return this.$props.sorterOptionIds.map((id) => ({
|
||||||
id,
|
id,
|
||||||
value: this.$t(`options.sort-${id}`),
|
value: this.$t(`options.sort-${id}`)
|
||||||
}));
|
}));
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
async driverStatsName(value: string) {
|
async driverStatsName() {
|
||||||
await this.fetchDriverStats();
|
await this.fetchDriverStats();
|
||||||
|
|
||||||
// if (value) this.store.currentStatsTab = 'driver';
|
// if (value) this.store.currentStatsTab = 'driver';
|
||||||
@@ -202,7 +201,7 @@ export default defineComponent({
|
|||||||
if (value.length < 3) return;
|
if (value.length < 3) return;
|
||||||
|
|
||||||
this.startSearchTimeout('dispatcher', value);
|
this.startSearchTimeout('dispatcher', value);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -218,7 +217,9 @@ export default defineComponent({
|
|||||||
this.store.driverStatsStatus = DataStatus.Loading;
|
this.store.driverStatsStatus = DataStatus.Loading;
|
||||||
|
|
||||||
const statsData: DriverStatsAPIData = await (
|
const statsData: DriverStatsAPIData = await (
|
||||||
await axios.get(`${URLs.stacjownikAPI}/api/getDriverInfo?name=${this.store.driverStatsName}`)
|
await axios.get(
|
||||||
|
`${URLs.stacjownikAPI}/api/getDriverInfo?name=${this.store.driverStatsName}`
|
||||||
|
)
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
this.store.driverStatsData = statsData;
|
this.store.driverStatsData = statsData;
|
||||||
@@ -268,7 +269,9 @@ export default defineComponent({
|
|||||||
|
|
||||||
onFilterChange(filter: JournalFilter) {
|
onFilterChange(filter: JournalFilter) {
|
||||||
// this.journalFilterActive = filter;
|
// this.journalFilterActive = filter;
|
||||||
this.filterList?.filter((f) => f.filterSection === filter.filterSection).forEach((f) => (f.isActive = false));
|
this.filterList
|
||||||
|
?.filter((f) => f.filterSection === filter.filterSection)
|
||||||
|
.forEach((f) => (f.isActive = false));
|
||||||
filter.isActive = true;
|
filter.isActive = true;
|
||||||
|
|
||||||
this.$emit('onSearchConfirm');
|
this.$emit('onSearchConfirm');
|
||||||
@@ -290,8 +293,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
onResetButtonClick() {
|
onResetButtonClick() {
|
||||||
this.$emit('onOptionsReset');
|
this.$emit('onOptionsReset');
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
<button
|
<button
|
||||||
v-for="tab in data.tabs"
|
v-for="tab in data.tabs"
|
||||||
|
:key="tab.name"
|
||||||
class="btn--filled"
|
class="btn--filled"
|
||||||
:data-selected="tab.name == store.currentStatsTab && areStatsOpen"
|
:data-selected="tab.name == store.currentStatsTab && areStatsOpen"
|
||||||
:data-inactive="tab.inactive"
|
:data-inactive="tab.inactive"
|
||||||
@@ -16,7 +17,10 @@
|
|||||||
|
|
||||||
<div class="stats-tab" v-show="areStatsOpen">
|
<div class="stats-tab" v-show="areStatsOpen">
|
||||||
<keep-alive>
|
<keep-alive>
|
||||||
<JournalDailyStats v-if="store.currentStatsTab == 'daily'" @toggleStatsOpen="toggleStatsOpen" />
|
<JournalDailyStats
|
||||||
|
v-if="store.currentStatsTab == 'daily'"
|
||||||
|
@toggleStatsOpen="toggleStatsOpen"
|
||||||
|
/>
|
||||||
<JournalDriverStats v-else-if="store.currentStatsTab == 'driver'" />
|
<JournalDriverStats v-else-if="store.currentStatsTab == 'driver'" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</div>
|
</div>
|
||||||
@@ -24,7 +28,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, KeepAlive, 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/store';
|
||||||
import JournalDailyStats from './DailyStats.vue';
|
import JournalDailyStats from './DailyStats.vue';
|
||||||
import JournalDriverStats from './JournalDriverStats.vue';
|
import JournalDriverStats from './JournalDriverStats.vue';
|
||||||
@@ -44,14 +48,14 @@ let data = reactive({
|
|||||||
tabs: [
|
tabs: [
|
||||||
{
|
{
|
||||||
name: 'daily',
|
name: 'daily',
|
||||||
titlePath: 'journal.daily-stats-title',
|
titlePath: 'journal.daily-stats-title'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'driver',
|
name: 'driver',
|
||||||
titlePath: 'journal.driver-stats-title',
|
titlePath: 'journal.driver-stats-title'
|
||||||
// inactive: true,
|
// inactive: true,
|
||||||
},
|
}
|
||||||
] as { name: TStatTab; titlePath: string; inactive?: boolean }[],
|
] as { name: TStatTab; titlePath: string; inactive?: boolean }[]
|
||||||
});
|
});
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
@@ -115,4 +119,3 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,9 @@
|
|||||||
</transition>
|
</transition>
|
||||||
|
|
||||||
<div class="journal_warning" v-if="scrollNoMoreData">{{ $t('journal.no-further-data') }}</div>
|
<div class="journal_warning" v-if="scrollNoMoreData">{{ $t('journal.no-further-data') }}</div>
|
||||||
<div class="journal_warning" v-else-if="!scrollDataLoaded">{{ $t('journal.loading-further-data') }}</div>
|
<div class="journal_warning" v-else-if="!scrollDataLoaded">
|
||||||
|
{{ $t('journal.loading-further-data') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -41,38 +43,37 @@ import { TimetableHistory } from '../../../scripts/interfaces/api/TimetablesAPID
|
|||||||
import { useStore } from '../../../store/store';
|
import { useStore } from '../../../store/store';
|
||||||
|
|
||||||
import Loading from '../../Global/Loading.vue';
|
import Loading from '../../Global/Loading.vue';
|
||||||
import ProgressBar from '../../Global/ProgressBar.vue';
|
|
||||||
import AddDataButton from '../../Global/AddDataButton.vue';
|
import AddDataButton from '../../Global/AddDataButton.vue';
|
||||||
import TimetableHistoryList from './TimetableHistoryList.vue';
|
import TimetableHistoryList from './TimetableHistoryList.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { ProgressBar, Loading, AddDataButton, TimetableHistoryList },
|
components: { Loading, AddDataButton, TimetableHistoryList },
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
timetableHistory: {
|
timetableHistory: {
|
||||||
type: Array as PropType<TimetableHistory[]>,
|
type: Array as PropType<TimetableHistory[]>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
scrollNoMoreData: {
|
scrollNoMoreData: {
|
||||||
type: Boolean,
|
type: Boolean
|
||||||
},
|
},
|
||||||
scrollDataLoaded: {
|
scrollDataLoaded: {
|
||||||
type: Boolean,
|
type: Boolean
|
||||||
},
|
},
|
||||||
addHistoryData: {
|
addHistoryData: {
|
||||||
type: Function as PropType<() => void>,
|
type: Function as PropType<() => void>
|
||||||
},
|
},
|
||||||
dataStatus: {
|
dataStatus: {
|
||||||
type: Number as PropType<DataStatus>,
|
type: Number as PropType<DataStatus>
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
DataStatus,
|
DataStatus,
|
||||||
store: useStore(),
|
store: useStore()
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,11 @@
|
|||||||
<span class="badge">
|
<span class="badge">
|
||||||
<span>{{ $t('journal.stock-length') }}</span>
|
<span>{{ $t('journal.stock-length') }}</span>
|
||||||
<span>
|
<span>
|
||||||
{{ currentHistoryIndex == 0 ? timetable.stockLength : stockHistory[currentHistoryIndex].stockLength || timetable.stockLength }}m
|
{{
|
||||||
|
currentHistoryIndex == 0
|
||||||
|
? timetable.stockLength
|
||||||
|
: stockHistory[currentHistoryIndex].stockLength || timetable.stockLength
|
||||||
|
}}m
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -26,7 +30,11 @@
|
|||||||
<span>{{ $t('journal.stock-mass') }}</span>
|
<span>{{ $t('journal.stock-mass') }}</span>
|
||||||
<span>
|
<span>
|
||||||
{{
|
{{
|
||||||
Math.floor((currentHistoryIndex == 0 ? timetable.stockMass! : stockHistory[currentHistoryIndex].stockMass || timetable.stockMass) / 1000)
|
Math.floor(
|
||||||
|
(currentHistoryIndex == 0
|
||||||
|
? timetable.stockMass!
|
||||||
|
: stockHistory[currentHistoryIndex].stockMass || timetable.stockMass) / 1000
|
||||||
|
)
|
||||||
}}t
|
}}t
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -34,13 +42,26 @@
|
|||||||
|
|
||||||
<!-- Historia zmian w składzie -->
|
<!-- Historia zmian w składzie -->
|
||||||
<div class="stock-history" v-if="stockHistory.length > 1">
|
<div class="stock-history" v-if="stockHistory.length > 1">
|
||||||
<button class="btn--action" v-for="(sh, i) in stockHistory" :data-checked="i == currentHistoryIndex" @click.stop="currentHistoryIndex = i">
|
<button
|
||||||
|
v-for="(sh, i) in stockHistory"
|
||||||
|
:key="i"
|
||||||
|
class="btn--action"
|
||||||
|
:data-checked="i == currentHistoryIndex"
|
||||||
|
@click.stop="currentHistoryIndex = i"
|
||||||
|
>
|
||||||
{{ sh.updatedAt }}
|
{{ sh.updatedAt }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <StockList :trainStockList="currentHistoryIndex == 0 ? timetable.stockString : stockHistory[currentHistoryIndex].stockString).split(';')" /> -->
|
<!-- <StockList :trainStockList="currentHistoryIndex == 0 ? timetable.stockString : stockHistory[currentHistoryIndex].stockString).split(';')" /> -->
|
||||||
<StockList :trainStockList="(currentHistoryIndex == 0 ? timetable.stockString : stockHistory[currentHistoryIndex].stockString).split(';') " />
|
<StockList
|
||||||
|
:trainStockList="
|
||||||
|
(currentHistoryIndex == 0
|
||||||
|
? timetable.stockString
|
||||||
|
: stockHistory[currentHistoryIndex].stockString
|
||||||
|
).split(';')
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- <ul class="stock-list">
|
<!-- <ul class="stock-list">
|
||||||
<li
|
<li
|
||||||
@@ -58,24 +79,24 @@
|
|||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import { TimetableHistory } from '../../../scripts/interfaces/api/TimetablesAPIData';
|
import { TimetableHistory } from '../../../scripts/interfaces/api/TimetablesAPIData';
|
||||||
import imageMixin from '../../../mixins/imageMixin';
|
import imageMixin from '../../../mixins/imageMixin';
|
||||||
import TrainThumbnail from '../../Global/TrainThumbnail.vue';
|
|
||||||
import StockList from '../../Global/StockList.vue';
|
import StockList from '../../Global/StockList.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [imageMixin],
|
mixins: [imageMixin],
|
||||||
|
components: { StockList },
|
||||||
props: {
|
props: {
|
||||||
showExtraInfo: {
|
showExtraInfo: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
timetable: {
|
timetable: {
|
||||||
type: Object as PropType<TimetableHistory>,
|
type: Object as PropType<TimetableHistory>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentHistoryIndex: 0,
|
currentHistoryIndex: 0
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -88,22 +109,21 @@ export default defineComponent({
|
|||||||
return {
|
return {
|
||||||
updatedAt: new Date(Number(historyData[0])).toLocaleTimeString(this.$i18n.locale, {
|
updatedAt: new Date(Number(historyData[0])).toLocaleTimeString(this.$i18n.locale, {
|
||||||
hour: '2-digit',
|
hour: '2-digit',
|
||||||
minute: '2-digit',
|
minute: '2-digit'
|
||||||
}),
|
}),
|
||||||
stockString: historyData[1],
|
stockString: historyData[1],
|
||||||
stockMass: Number(historyData[2]) || undefined,
|
stockMass: Number(historyData[2]) || undefined,
|
||||||
stockLength: Number(historyData[3]) || undefined,
|
stockLength: Number(historyData[3]) || undefined
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onImageError(e: Event) {
|
onImageError(e: Event) {
|
||||||
const imageEl = e.target as HTMLImageElement;
|
const imageEl = e.target as HTMLImageElement;
|
||||||
imageEl.src = this.getImage('unknown.png');
|
imageEl.src = this.getImage('unknown.png');
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
components: { TrainThumbnail, StockList },
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
:class="{
|
:class="{
|
||||||
fulfilled: timetable.fulfilled,
|
fulfilled: timetable.fulfilled,
|
||||||
terminated: timetable.terminated && !timetable.fulfilled,
|
terminated: timetable.terminated && !timetable.fulfilled,
|
||||||
active: !timetable.terminated,
|
active: !timetable.terminated
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
@@ -74,8 +74,8 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
timetable: {
|
timetable: {
|
||||||
type: Object as PropType<TimetableHistory>,
|
type: Object as PropType<TimetableHistory>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -83,8 +83,8 @@ export default defineComponent({
|
|||||||
if (timetable?.terminated) return;
|
if (timetable?.terminated) return;
|
||||||
|
|
||||||
this.selectModalTrain(timetable.driverName + timetable.trainNo.toString(), target);
|
this.selectModalTrain(timetable.driverName + timetable.trainNo.toString(), target);
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -48,19 +48,19 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
timetableHistory: {
|
timetableHistory: {
|
||||||
type: Array as PropType<TimetableHistory[]>,
|
type: Array as PropType<TimetableHistory[]>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
computedTimetableHistory() {
|
computedTimetableHistory() {
|
||||||
return this.timetableHistory.map((timetable) => ({
|
return this.timetableHistory.map((timetable) => ({
|
||||||
timetable,
|
timetable,
|
||||||
showExtraInfo: ref(false),
|
showExtraInfo: ref(false)
|
||||||
}));
|
}));
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {},
|
methods: {},
|
||||||
components: { TimetableGeneral, TimetableStops, TimetableStatus, TimetableExtra },
|
components: { TimetableGeneral, TimetableStops, TimetableStatus, TimetableExtra }
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,19 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
<span :style="{ color: timetable.fulfilled ? 'lightgreen' : timetable.terminated ? 'salmon' : '' }">
|
<span
|
||||||
|
:style="{
|
||||||
|
color: timetable.fulfilled ? 'lightgreen' : timetable.terminated ? 'salmon' : ''
|
||||||
|
}"
|
||||||
|
>
|
||||||
{{ timetable.currentDistance + ' km' }}
|
{{ timetable.currentDistance + ' km' }}
|
||||||
</span>
|
</span>
|
||||||
<span> / </span>
|
<span> / </span>
|
||||||
<span class="text--primary">{{ timetable.routeDistance }} km</span>
|
<span class="text--primary">{{ timetable.routeDistance }} km</span>
|
||||||
|
|
|
|
||||||
<span class="text--grayed">{{ timetable.confirmedStopsCount }}/{{ timetable.allStopsCount }}</span>
|
<span class="text--grayed"
|
||||||
|
>{{ timetable.confirmedStopsCount }}/{{ timetable.allStopsCount }}</span
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="text--grayed" v-if="timetable.currentSceneryName">
|
<span class="text--grayed" v-if="timetable.currentSceneryName">
|
||||||
@@ -46,9 +52,9 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
timetable: {
|
timetable: {
|
||||||
type: Object as PropType<TimetableHistory>,
|
type: Object as PropType<TimetableHistory>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
timetable: {
|
timetable: {
|
||||||
type: Object as PropType<TimetableHistory>,
|
type: Object as PropType<TimetableHistory>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
@@ -65,12 +65,18 @@ export default defineComponent({
|
|||||||
if (i == 0) return { stopName, html: beginDateHTML, confirmed };
|
if (i == 0) return { stopName, html: beginDateHTML, confirmed };
|
||||||
if (i == stopNames.length - 1) return { stopName, html: endDateHTML, confirmed };
|
if (i == stopNames.length - 1) return { stopName, html: endDateHTML, confirmed };
|
||||||
|
|
||||||
const departureDateScheduled = this.stringToDate(timetable.checkpointDeparturesScheduled?.at(i));
|
const departureDateScheduled = this.stringToDate(
|
||||||
|
timetable.checkpointDeparturesScheduled?.at(i)
|
||||||
|
);
|
||||||
const departureDateReal = this.stringToDate(timetable.checkpointDepartures?.at(i));
|
const departureDateReal = this.stringToDate(timetable.checkpointDepartures?.at(i));
|
||||||
const arrivalDateScheduled = this.stringToDate(timetable.checkpointArrivalsScheduled?.at(i));
|
const arrivalDateScheduled = this.stringToDate(
|
||||||
|
timetable.checkpointArrivalsScheduled?.at(i)
|
||||||
|
);
|
||||||
const arrivalDateReal = this.stringToDate(timetable.checkpointArrivals?.at(i));
|
const arrivalDateReal = this.stringToDate(timetable.checkpointArrivals?.at(i));
|
||||||
const arrivalHTML =
|
const arrivalHTML =
|
||||||
(arrivalDateReal && arrivalDateScheduled && arrivalDateReal?.getTime() != arrivalDateScheduled?.getTime()
|
(arrivalDateReal &&
|
||||||
|
arrivalDateScheduled &&
|
||||||
|
arrivalDateReal?.getTime() != arrivalDateScheduled?.getTime()
|
||||||
? `<s class="text--grayed">${this.parseDateToTimeString(arrivalDateScheduled)}</s> `
|
? `<s class="text--grayed">${this.parseDateToTimeString(arrivalDateScheduled)}</s> `
|
||||||
: '') + this.parseDateToTimeString(arrivalDateReal || arrivalDateScheduled);
|
: '') + this.parseDateToTimeString(arrivalDateReal || arrivalDateScheduled);
|
||||||
const departureHTML =
|
const departureHTML =
|
||||||
@@ -83,8 +89,8 @@ export default defineComponent({
|
|||||||
if (html) html = ` (${html})`;
|
if (html) html = ` (${html})`;
|
||||||
return { stopName, html, confirmed };
|
return { stopName, html, confirmed };
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="scenery-table-section">
|
<section class="scenery-table-section">
|
||||||
<Loading v-if="dataStatus != DataStatus.Loaded && historyList.length == 0" />
|
<Loading v-if="dataStatus != DataStatus.Loaded && historyList.length == 0" />
|
||||||
<div class="no-history" v-else-if="historyList.length == 0">{{ $t('scenery.history-list-empty') }}</div>
|
|
||||||
|
|
||||||
<table class="scenery-history-table" v-else="historyList.length">
|
<div class="no-history" v-else-if="historyList.length == 0">
|
||||||
|
{{ $t('scenery.history-list-empty') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="scenery-history-table" v-else>
|
||||||
<thead>
|
<thead>
|
||||||
<th>{{ $t('scenery.dispatchers-history-hash') }}</th>
|
<th>{{ $t('scenery.dispatchers-history-hash') }}</th>
|
||||||
<th>{{ $t('scenery.dispatchers-history-dispatcher') }}</th>
|
<th>{{ $t('scenery.dispatchers-history-dispatcher') }}</th>
|
||||||
@@ -13,7 +16,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="historyItem in historyList">
|
<tr v-for="historyItem in historyList" :key="historyItem.id">
|
||||||
<td>#{{ historyItem.stationHash }}</td>
|
<td>#{{ historyItem.stationHash }}</td>
|
||||||
<td>
|
<td>
|
||||||
<router-link :to="`/journal/dispatchers?dispatcherName=${historyItem.dispatcherName}`">
|
<router-link :to="`/journal/dispatchers?dispatcherName=${historyItem.dispatcherName}`">
|
||||||
@@ -24,7 +27,9 @@
|
|||||||
<b
|
<b
|
||||||
v-if="historyItem.dispatcherLevel !== null"
|
v-if="historyItem.dispatcherLevel !== null"
|
||||||
class="level-badge dispatcher"
|
class="level-badge dispatcher"
|
||||||
:style="calculateExpStyle(historyItem.dispatcherLevel, historyItem.dispatcherIsSupporter)"
|
:style="
|
||||||
|
calculateExpStyle(historyItem.dispatcherLevel, historyItem.dispatcherIsSupporter)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ historyItem.dispatcherLevel >= 2 ? historyItem.dispatcherLevel : 'L' }}
|
{{ historyItem.dispatcherLevel >= 2 ? historyItem.dispatcherLevel : 'L' }}
|
||||||
</b>
|
</b>
|
||||||
@@ -37,7 +42,9 @@
|
|||||||
<b>{{ $d(historyItem.timestampFrom) }}</b>
|
<b>{{ $d(historyItem.timestampFrom) }}</b>
|
||||||
|
|
||||||
{{ timestampToString(historyItem.timestampFrom) }}
|
{{ timestampToString(historyItem.timestampFrom) }}
|
||||||
- {{ timestampToString(historyItem.timestampTo) }} ({{ calculateDuration(historyItem.currentDuration) }})
|
- {{ timestampToString(historyItem.timestampTo) }} ({{
|
||||||
|
calculateDuration(historyItem.currentDuration)
|
||||||
|
}})
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dispatcher-online" v-else>
|
<div class="dispatcher-online" v-else>
|
||||||
@@ -73,18 +80,19 @@ import listObserverMixin from '../../mixins/listObserverMixin';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SceneryDispatchersHistory',
|
name: 'SceneryDispatchersHistory',
|
||||||
mixins: [dateMixin, styleMixin, listObserverMixin],
|
mixins: [dateMixin, styleMixin, listObserverMixin],
|
||||||
|
components: { Loading },
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as PropType<Station>,
|
type: Object as PropType<Station>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
historyList: [] as DispatcherHistory[],
|
historyList: [] as DispatcherHistory[],
|
||||||
dataStatus: DataStatus.Loading,
|
dataStatus: DataStatus.Loading,
|
||||||
DataStatus,
|
DataStatus
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -113,9 +121,8 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
navigateToHistory() {
|
navigateToHistory() {
|
||||||
this.$router.push(`/journal/dispatchers?sceneryName=${this.station.name}`);
|
this.$router.push(`/journal/dispatchers?sceneryName=${this.station.name}`);
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
components: { Loading },
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -13,16 +13,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import Station from '../../scripts/interfaces/Station';
|
import Station from '../../scripts/interfaces/Station';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as () => Station,
|
type: Object as PropType<Station>,
|
||||||
default: {},
|
required: true
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -52,4 +52,3 @@ export default defineComponent({
|
|||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -6,19 +6,29 @@
|
|||||||
|
|
||||||
<div class="scenery-general-list">
|
<div class="scenery-general-list">
|
||||||
<span>
|
<span>
|
||||||
<b>{{ $t('availability.title') }}:</b> {{ $t(`availability.${station.generalInfo.availability}`) }}
|
<b>{{ $t('availability.title') }}:</b>
|
||||||
|
{{ $t(`availability.${station.generalInfo.availability}`) }}
|
||||||
|
|
||||||
<span v-if="station.generalInfo.reqLevel > -1">
|
<span v-if="station.generalInfo.reqLevel > -1">
|
||||||
- {{ $t('scenery.req-level', { lvl: station.generalInfo.reqLevel }, station.generalInfo.reqLevel) }}
|
-
|
||||||
|
{{
|
||||||
|
$t(
|
||||||
|
'scenery.req-level',
|
||||||
|
{ lvl: station.generalInfo.reqLevel },
|
||||||
|
station.generalInfo.reqLevel
|
||||||
|
)
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
• <b>{{ $t('controls.title') }}:</b> {{ $t(`controls.${station.generalInfo.controlType}`) }}
|
• <b>{{ $t('controls.title') }}:</b>
|
||||||
|
{{ $t(`controls.${station.generalInfo.controlType}`) }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
• <b>{{ $t('signals.title') }}:</b> {{ $t(`signals.${station.generalInfo.signalType}`) }}
|
• <b>{{ $t('signals.title') }}:</b>
|
||||||
|
{{ $t(`signals.${station.generalInfo.signalType}`) }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span v-if="station.generalInfo.lines">
|
<span v-if="station.generalInfo.lines">
|
||||||
@@ -26,7 +36,11 @@
|
|||||||
</span>
|
</span>
|
||||||
<span v-if="station.generalInfo.project">
|
<span v-if="station.generalInfo.project">
|
||||||
• <b>{{ $t('scenery.project-title') }}: </b>
|
• <b>{{ $t('scenery.project-title') }}: </b>
|
||||||
<a style="color: salmon; text-decoration: underline; font-weight: bold" :href="station.generalInfo.projectUrl" target="_blank">
|
<a
|
||||||
|
style="color: salmon; text-decoration: underline; font-weight: bold"
|
||||||
|
:href="station.generalInfo.projectUrl"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
{{ station.generalInfo.project }}
|
{{ station.generalInfo.project }}
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
@@ -34,8 +48,19 @@
|
|||||||
|
|
||||||
<SceneryInfoRoutes :station="station" />
|
<SceneryInfoRoutes :station="station" />
|
||||||
|
|
||||||
<div class="scenery-authors" v-if="station.generalInfo.authors && station.generalInfo.authors.length > 0">
|
<div
|
||||||
<b> {{ $t('scenery.authors-title', { authors: station.generalInfo.authors.length }, station.generalInfo.authors.length) }}: </b>
|
class="scenery-authors"
|
||||||
|
v-if="station.generalInfo.authors && station.generalInfo.authors.length > 0"
|
||||||
|
>
|
||||||
|
<b>
|
||||||
|
{{
|
||||||
|
$t(
|
||||||
|
'scenery.authors-title',
|
||||||
|
{ authors: station.generalInfo.authors.length },
|
||||||
|
station.generalInfo.authors.length
|
||||||
|
)
|
||||||
|
}}:
|
||||||
|
</b>
|
||||||
{{ station.generalInfo.authors.join(', ') }}
|
{{ station.generalInfo.authors.join(', ') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -57,11 +82,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from '@vue/runtime-core';
|
import { PropType, defineComponent } from 'vue';
|
||||||
|
|
||||||
import SceneryInfoDispatcher from './SceneryInfo/SceneryInfoDispatcher.vue';
|
import SceneryInfoDispatcher from './SceneryInfo/SceneryInfoDispatcher.vue';
|
||||||
import SceneryInfoIcons from './SceneryInfo/SceneryInfoIcons.vue';
|
import SceneryInfoIcons from './SceneryInfo/SceneryInfoIcons.vue';
|
||||||
import SceneryInfoStats from './SceneryInfo/SceneryInfoStats.vue';
|
|
||||||
import SceneryInfoUserList from './SceneryInfo/SceneryInfoUserList.vue';
|
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';
|
||||||
@@ -71,23 +95,22 @@ export default defineComponent({
|
|||||||
components: {
|
components: {
|
||||||
SceneryInfoDispatcher,
|
SceneryInfoDispatcher,
|
||||||
SceneryInfoIcons,
|
SceneryInfoIcons,
|
||||||
SceneryInfoStats,
|
|
||||||
SceneryInfoUserList,
|
SceneryInfoUserList,
|
||||||
SceneryInfoSpawnList,
|
SceneryInfoSpawnList,
|
||||||
SceneryInfoRoutes,
|
SceneryInfoRoutes
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as () => Station,
|
type: Object as PropType<Station>,
|
||||||
default: {},
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
timetableOnly: Boolean,
|
timetableOnly: Boolean
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
onlineFrom: -1,
|
onlineFrom: -1
|
||||||
}),
|
})
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,12 @@
|
|||||||
<div class="dispatcher" v-if="station.onlineInfo">
|
<div class="dispatcher" v-if="station.onlineInfo">
|
||||||
<span
|
<span
|
||||||
class="dispatcher_level"
|
class="dispatcher_level"
|
||||||
:style="calculateExpStyle(station.onlineInfo.dispatcherExp, station.onlineInfo.dispatcherIsSupporter)"
|
:style="
|
||||||
|
calculateExpStyle(
|
||||||
|
station.onlineInfo.dispatcherExp,
|
||||||
|
station.onlineInfo.dispatcherIsSupporter
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ station.onlineInfo.dispatcherExp > 1 ? station.onlineInfo.dispatcherExp : 'L' }}
|
{{ station.onlineInfo.dispatcherExp > 1 ? station.onlineInfo.dispatcherExp : 'L' }}
|
||||||
</span>
|
</span>
|
||||||
@@ -30,7 +35,7 @@
|
|||||||
</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 imageMixin from '../../../mixins/imageMixin';
|
import imageMixin from '../../../mixins/imageMixin';
|
||||||
import routerMixin from '../../../mixins/routerMixin';
|
import routerMixin from '../../../mixins/routerMixin';
|
||||||
@@ -39,18 +44,18 @@ import Station from '../../../scripts/interfaces/Station';
|
|||||||
import StationStatusBadge from '../../Global/StationStatusBadge.vue';
|
import StationStatusBadge from '../../Global/StationStatusBadge.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [styleMixin, dateMixin, routerMixin, imageMixin],
|
mixins: [styleMixin, dateMixin, routerMixin, imageMixin],
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as () => Station,
|
type: Object as PropType<Station>,
|
||||||
default: {},
|
required: true
|
||||||
},
|
|
||||||
onlineFrom: {
|
|
||||||
type: Number,
|
|
||||||
default: -1,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
components: { StationStatusBadge }
|
onlineFrom: {
|
||||||
|
type: Number,
|
||||||
|
default: -1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: { StationStatusBadge }
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -98,4 +103,3 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import imageMixin from '../../../mixins/imageMixin';
|
import imageMixin from '../../../mixins/imageMixin';
|
||||||
import stationInfoMixin from '../../../mixins/stationInfoMixin';
|
import stationInfoMixin from '../../../mixins/stationInfoMixin';
|
||||||
import styleMixin from '../../../mixins/styleMixin';
|
import styleMixin from '../../../mixins/styleMixin';
|
||||||
@@ -86,10 +86,10 @@ export default defineComponent({
|
|||||||
mixins: [stationInfoMixin, styleMixin, imageMixin],
|
mixins: [stationInfoMixin, styleMixin, imageMixin],
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as () => Station,
|
type: Object as PropType<Station>,
|
||||||
default: {},
|
required: true
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -118,4 +118,3 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,14 @@
|
|||||||
<b>{{ $t('scenery.one-way-routes') }}</b>
|
<b>{{ $t('scenery.one-way-routes') }}</b>
|
||||||
|
|
||||||
<ul class="routes-list">
|
<ul class="routes-list">
|
||||||
<li v-for="route in station.generalInfo.routes.oneWay" @click="setActiveShowLength(route.name)">
|
<li
|
||||||
<span :class="{ 'no-catenary': !route.catenary, internal: route.isInternal }"> {{ route.name }}</span>
|
v-for="route in station.generalInfo.routes.oneWay"
|
||||||
|
:key="route.name"
|
||||||
|
@click="setActiveShowLength(route.name)"
|
||||||
|
>
|
||||||
|
<span :class="{ 'no-catenary': !route.catenary, internal: route.isInternal }">
|
||||||
|
{{ route.name }}</span
|
||||||
|
>
|
||||||
<span v-if="route.speed" class="speed">
|
<span v-if="route.speed" class="speed">
|
||||||
{{ activeShowLength.includes(route.name) ? route.length + 'm' : route.speed }}
|
{{ activeShowLength.includes(route.name) ? route.length + 'm' : route.speed }}
|
||||||
</span>
|
</span>
|
||||||
@@ -18,8 +24,14 @@
|
|||||||
<b>{{ $t('scenery.two-way-routes') }}</b>
|
<b>{{ $t('scenery.two-way-routes') }}</b>
|
||||||
|
|
||||||
<ul class="routes-list">
|
<ul class="routes-list">
|
||||||
<li v-for="(route, i) in station.generalInfo.routes.twoWay" @click="setActiveShowLength(route.name)">
|
<li
|
||||||
<span :class="{ 'no-catenary': !route.catenary, internal: route.isInternal }">{{ route.name }}</span>
|
v-for="route in station.generalInfo.routes.twoWay"
|
||||||
|
:key="route.name"
|
||||||
|
@click="setActiveShowLength(route.name)"
|
||||||
|
>
|
||||||
|
<span :class="{ 'no-catenary': !route.catenary, internal: route.isInternal }">{{
|
||||||
|
route.name
|
||||||
|
}}</span>
|
||||||
<span v-if="route.speed" class="speed">
|
<span v-if="route.speed" class="speed">
|
||||||
{{ activeShowLength.includes(route.name) ? route.length + 'm' : route.speed }}
|
{{ activeShowLength.includes(route.name) ? route.length + 'm' : route.speed }}
|
||||||
</span>
|
</span>
|
||||||
@@ -31,29 +43,30 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import Station from '../../../scripts/interfaces/Station';
|
import Station from '../../../scripts/interfaces/Station';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as () => Station,
|
type: Object as PropType<Station>,
|
||||||
default: {},
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
setActiveShowLength(name: string) {
|
setActiveShowLength(name: string) {
|
||||||
if (this.activeShowLength.includes(name)) this.activeShowLength.splice(this.activeShowLength.indexOf(name), 1);
|
if (this.activeShowLength.includes(name))
|
||||||
|
this.activeShowLength.splice(this.activeShowLength.indexOf(name), 1);
|
||||||
else this.activeShowLength.push(name);
|
else this.activeShowLength.push(name);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeShowLength: [] as string[],
|
activeShowLength: [] as string[]
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -18,14 +18,16 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="badge spawn badge-none" v-if="!station.onlineInfo || station.onlineInfo.spawns.length == 0"
|
<span
|
||||||
|
class="badge spawn badge-none"
|
||||||
|
v-if="!station.onlineInfo || station.onlineInfo.spawns.length == 0"
|
||||||
>{{ $t('scenery.no-spawns') }}
|
>{{ $t('scenery.no-spawns') }}
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import imageMixin from '../../../mixins/imageMixin';
|
import imageMixin from '../../../mixins/imageMixin';
|
||||||
import Station from '../../../scripts/interfaces/Station';
|
import Station from '../../../scripts/interfaces/Station';
|
||||||
|
|
||||||
@@ -34,16 +36,20 @@ export default defineComponent({
|
|||||||
|
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as () => Station,
|
type: Object as PropType<Station>,
|
||||||
default: {},
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
sortedSpawns() {
|
sortedSpawns() {
|
||||||
return this.station.onlineInfo?.spawns.sort((s1, s2) => (s1.spawnLength < s2.spawnLength ? 1 : -1));
|
if (!this.station.onlineInfo) return [];
|
||||||
},
|
|
||||||
},
|
return [...this.station.onlineInfo.spawns].sort((s1, s2) =>
|
||||||
|
s1.spawnLength < s2.spawnLength ? 1 : -1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,10 @@
|
|||||||
<span style="color: #eee">{{ station.onlineInfo?.scheduledTrains?.length || '0' }}</span>
|
<span style="color: #eee">{{ station.onlineInfo?.scheduledTrains?.length || '0' }}</span>
|
||||||
/
|
/
|
||||||
<span style="color: #bbb"
|
<span style="color: #bbb"
|
||||||
>{{ station.onlineInfo?.scheduledTrains?.filter((train) => train.stopInfo.confirmed).length || '0' }}
|
>{{
|
||||||
|
station.onlineInfo?.scheduledTrains?.filter((train) => train.stopInfo.confirmed)
|
||||||
|
.length || '0'
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -31,7 +34,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import imageMixin from '../../../mixins/imageMixin';
|
import imageMixin from '../../../mixins/imageMixin';
|
||||||
import Station from '../../../scripts/interfaces/Station';
|
import Station from '../../../scripts/interfaces/Station';
|
||||||
|
|
||||||
@@ -39,10 +42,10 @@ export default defineComponent({
|
|||||||
mixins: [imageMixin],
|
mixins: [imageMixin],
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as () => Station,
|
type: Object as PropType<Station>,
|
||||||
default: {},
|
required: true
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-for="(train, i) in computedStationTrains"
|
v-for="train in computedStationTrains"
|
||||||
class="badge user"
|
class="badge user"
|
||||||
:class="train.stopStatus"
|
:class="train.stopStatus"
|
||||||
:key="train.trainId"
|
:key="train.trainId"
|
||||||
@@ -20,14 +20,17 @@
|
|||||||
<span class="user_name">{{ train.driverName }}</span>
|
<span class="user_name">{{ train.driverName }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="badge user badge-none" v-if="!computedStationTrains || computedStationTrains.length == 0">
|
<div
|
||||||
|
class="badge user badge-none"
|
||||||
|
v-if="!computedStationTrains || computedStationTrains.length == 0"
|
||||||
|
>
|
||||||
{{ $t('scenery.no-users') }}
|
{{ $t('scenery.no-users') }}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent } from 'vue';
|
import { PropType, computed, defineComponent } from 'vue';
|
||||||
import imageMixin from '../../../mixins/imageMixin';
|
import imageMixin from '../../../mixins/imageMixin';
|
||||||
import modalTrainMixin from '../../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../../mixins/modalTrainMixin';
|
||||||
import routerMixin from '../../../mixins/routerMixin';
|
import routerMixin from '../../../mixins/routerMixin';
|
||||||
@@ -39,9 +42,9 @@ export default defineComponent({
|
|||||||
|
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as () => Station,
|
type: Object as PropType<Station>,
|
||||||
default: {},
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
@@ -55,17 +58,19 @@ export default defineComponent({
|
|||||||
if (!station.onlineInfo.stationTrains) return [];
|
if (!station.onlineInfo.stationTrains) return [];
|
||||||
|
|
||||||
return station.onlineInfo.stationTrains.map((train) => {
|
return station.onlineInfo.stationTrains.map((train) => {
|
||||||
const scheduledTrainStatus = station.onlineInfo?.scheduledTrains?.find((st) => st.trainNo === train.trainNo);
|
const scheduledTrainStatus = station.onlineInfo?.scheduledTrains?.find(
|
||||||
|
(st) => st.trainNo === train.trainNo
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...train,
|
...train,
|
||||||
stopStatus: scheduledTrainStatus?.stopStatus || 'no-timetable',
|
stopStatus: scheduledTrainStatus?.stopStatus || 'no-timetable'
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return { computedStationTrains, store };
|
return { computedStationTrains, store };
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,24 @@
|
|||||||
<span>{{ $t('scenery.timetables') }}</span>
|
<span>{{ $t('scenery.timetables') }}</span>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
<span class="text--primary">{{ station.onlineInfo?.scheduledTrains?.length || '0' }}</span>
|
<span class="text--primary">{{
|
||||||
|
station.onlineInfo?.scheduledTrains?.length || '0'
|
||||||
|
}}</span>
|
||||||
<span> / </span>
|
<span> / </span>
|
||||||
<span class="text--grayed">
|
<span class="text--grayed">
|
||||||
{{ station.onlineInfo?.scheduledTrains?.filter((train) => train.stopInfo.confirmed).length || '0' }}
|
{{
|
||||||
|
station.onlineInfo?.scheduledTrains?.filter((train) => train.stopInfo.confirmed)
|
||||||
|
.length || '0'
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="header_links">
|
<span class="header_links">
|
||||||
<a :href="`https://pragotron-td2.web.app/board?name=${station.name}`" target="_blank" :title="$t('scenery.pragotron-link')">
|
<a
|
||||||
|
:href="`https://pragotron-td2.web.app/board?name=${station.name}`"
|
||||||
|
target="_blank"
|
||||||
|
:title="$t('scenery.pragotron-link')"
|
||||||
|
>
|
||||||
<img :src="getIcon('pragotron')" alt="icon-pragotron" />
|
<img :src="getIcon('pragotron')" alt="icon-pragotron" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@@ -41,11 +50,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="timetable-list">
|
<div class="timetable-list">
|
||||||
<div style="padding-bottom: 5em" v-if="store.dataStatuses.trains == 0 && computedScheduledTrains.length == 0">
|
<div
|
||||||
|
style="padding-bottom: 5em"
|
||||||
|
v-if="store.dataStatuses.trains == 0 && computedScheduledTrains.length == 0"
|
||||||
|
>
|
||||||
<Loading />
|
<Loading />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="timetable-item empty" v-else-if="computedScheduledTrains.length == 0 && !station.onlineInfo">
|
<span
|
||||||
|
class="timetable-item empty"
|
||||||
|
v-else-if="computedScheduledTrains.length == 0 && !station.onlineInfo"
|
||||||
|
>
|
||||||
{{ $t('scenery.offline') }}
|
{{ $t('scenery.offline') }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -56,7 +71,7 @@
|
|||||||
<transition-group name="list-anim">
|
<transition-group name="list-anim">
|
||||||
<div
|
<div
|
||||||
class="timetable-item"
|
class="timetable-item"
|
||||||
v-for="(scheduledTrain, i) in computedScheduledTrains"
|
v-for="scheduledTrain in computedScheduledTrains"
|
||||||
:key="scheduledTrain.trainId"
|
:key="scheduledTrain.trainId"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@click.prevent.stop="selectModalTrain(scheduledTrain.trainId, $event.currentTarget)"
|
@click.prevent.stop="selectModalTrain(scheduledTrain.trainId, $event.currentTarget)"
|
||||||
@@ -98,12 +113,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div>
|
<div>
|
||||||
<s style="margin-right: 0.2em" class="text--grayed">{{ timestampToString(scheduledTrain.stopInfo.arrivalTimestamp) }}</s>
|
<s style="margin-right: 0.2em" class="text--grayed">{{
|
||||||
|
timestampToString(scheduledTrain.stopInfo.arrivalTimestamp)
|
||||||
|
}}</s>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
{{ timestampToString(scheduledTrain.stopInfo.arrivalRealTimestamp) }}
|
{{ timestampToString(scheduledTrain.stopInfo.arrivalRealTimestamp) }}
|
||||||
({{ scheduledTrain.stopInfo.arrivalDelay > 0 ? '+' : '' }}{{ scheduledTrain.stopInfo.arrivalDelay }})
|
({{ scheduledTrain.stopInfo.arrivalDelay > 0 ? '+' : ''
|
||||||
|
}}{{ scheduledTrain.stopInfo.arrivalDelay }})
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
@@ -116,7 +134,9 @@
|
|||||||
|
|
||||||
<span class="stop-time">
|
<span class="stop-time">
|
||||||
{{ scheduledTrain.stopInfo.stopTime || '' }}
|
{{ scheduledTrain.stopInfo.stopTime || '' }}
|
||||||
{{ scheduledTrain.stopInfo.stopTime ? scheduledTrain.stopInfo.stopType || 'pt' : '' }}
|
{{
|
||||||
|
scheduledTrain.stopInfo.stopTime ? scheduledTrain.stopInfo.stopType || 'pt' : ''
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="stop-connection">
|
<span class="stop-connection">
|
||||||
@@ -135,12 +155,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div>
|
<div>
|
||||||
<s style="margin-right: 0.2em" class="text--grayed">{{ timestampToString(scheduledTrain.stopInfo.departureTimestamp) }}</s>
|
<s style="margin-right: 0.2em" class="text--grayed">{{
|
||||||
|
timestampToString(scheduledTrain.stopInfo.departureTimestamp)
|
||||||
|
}}</s>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
{{ timestampToString(scheduledTrain.stopInfo.departureRealTimestamp) }}
|
{{ timestampToString(scheduledTrain.stopInfo.departureRealTimestamp) }}
|
||||||
({{ scheduledTrain.stopInfo.departureDelay > 0 ? '+' : '' }}{{ scheduledTrain.stopInfo.departureDelay }})
|
({{ scheduledTrain.stopInfo.departureDelay > 0 ? '+' : ''
|
||||||
|
}}{{ scheduledTrain.stopInfo.departureDelay }})
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
@@ -153,12 +176,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import SelectBox from '../Global/SelectBox.vue';
|
import { computed, defineComponent, PropType, ref } from 'vue';
|
||||||
import { computed, defineComponent, PropType, ref } from '@vue/runtime-core';
|
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
import TrainModal from '../Global/TrainModal.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';
|
||||||
@@ -170,23 +191,23 @@ import ScheduledTrainStatus from './ScheduledTrainStatus.vue';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SceneryTimetable',
|
name: 'SceneryTimetable',
|
||||||
|
|
||||||
components: { SelectBox, Loading, TrainModal, ScheduledTrainStatus },
|
components: { Loading, ScheduledTrainStatus },
|
||||||
|
|
||||||
mixins: [dateMixin, routerMixin, imageMixin, modalTrainMixin],
|
mixins: [dateMixin, routerMixin, imageMixin, modalTrainMixin],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as PropType<Station>,
|
type: Object as PropType<Station>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
timetableOnly: {
|
timetableOnly: {
|
||||||
type: Boolean,
|
type: Boolean
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
listOpen: false,
|
listOpen: false
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -204,7 +225,9 @@ export default defineComponent({
|
|||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
const chosenCheckpoint = ref(
|
const chosenCheckpoint = ref(
|
||||||
props.station?.generalInfo?.checkpoints?.length == 0 ? '' : props.station?.generalInfo?.checkpoints[0].checkpointName || null
|
props.station?.generalInfo?.checkpoints?.length == 0
|
||||||
|
? ''
|
||||||
|
: props.station?.generalInfo?.checkpoints[0].checkpointName || null
|
||||||
);
|
);
|
||||||
|
|
||||||
const computedScheduledTrains = computed(() => {
|
const computedScheduledTrains = computed(() => {
|
||||||
@@ -213,7 +236,8 @@ export default defineComponent({
|
|||||||
const station = props.station as Station;
|
const station = props.station as Station;
|
||||||
|
|
||||||
let scheduledTrains =
|
let scheduledTrains =
|
||||||
station.generalInfo?.checkpoints.find((cp) => cp.checkpointName === chosenCheckpoint.value)?.scheduledTrains ||
|
station.generalInfo?.checkpoints.find((cp) => cp.checkpointName === chosenCheckpoint.value)
|
||||||
|
?.scheduledTrains ||
|
||||||
station.onlineInfo?.scheduledTrains ||
|
station.onlineInfo?.scheduledTrains ||
|
||||||
[];
|
[];
|
||||||
|
|
||||||
@@ -236,7 +260,7 @@ export default defineComponent({
|
|||||||
currentURL,
|
currentURL,
|
||||||
chosenCheckpoint,
|
chosenCheckpoint,
|
||||||
computedScheduledTrains,
|
computedScheduledTrains,
|
||||||
store,
|
store
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -246,7 +270,7 @@ export default defineComponent({
|
|||||||
if (this.chosenCheckpoint) url += `&checkpoint=${this.chosenCheckpoint}`;
|
if (this.chosenCheckpoint) url += `&checkpoint=${this.chosenCheckpoint}`;
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -267,8 +291,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
showTimetableOnlyView() {
|
showTimetableOnlyView() {
|
||||||
this.$router.push(`${this.$route.fullPath}&timetableOnly=1`);
|
this.$router.push(`${this.$route.fullPath}&timetableOnly=1`);
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<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">{{ $t('scenery.history-list-empty') }}</div>
|
<div class="no-history" v-else-if="historyList.length == 0">
|
||||||
|
{{ $t('scenery.history-list-empty') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<table class="scenery-history-table" v-else>
|
<table class="scenery-history-table" v-else>
|
||||||
<thead>
|
<thead>
|
||||||
@@ -14,9 +16,11 @@
|
|||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="historyItem in historyList">
|
<tr v-for="historyItem in historyList" :key="historyItem.id">
|
||||||
<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>
|
||||||
<td>
|
<td>
|
||||||
<b class="text--primary">{{ historyItem.trainCategoryCode }}</b> <br />
|
<b class="text--primary">{{ historyItem.trainCategoryCode }}</b> <br />
|
||||||
@@ -53,7 +57,10 @@ 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 { DataStatus } from '../../scripts/enums/DataStatus';
|
||||||
import { TimetableHistory, SceneryTimetableHistory } from '../../scripts/interfaces/api/TimetablesAPIData';
|
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';
|
||||||
@@ -65,15 +72,15 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as PropType<Station>,
|
type: Object as PropType<Station>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
historyList: [] as TimetableHistory[],
|
historyList: [] as TimetableHistory[],
|
||||||
dataStatus: DataStatus.Loading,
|
dataStatus: DataStatus.Loading,
|
||||||
DataStatus,
|
DataStatus
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -98,9 +105,9 @@ export default defineComponent({
|
|||||||
|
|
||||||
navigateToHistory() {
|
navigateToHistory() {
|
||||||
this.$router.push(`/journal/timetables?issuedFrom=${this.station.name}`);
|
this.$router.push(`/journal/timetables?issuedFrom=${this.station.name}`);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
components: { Loading },
|
components: { Loading }
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="general-status">
|
<div class="general-status">
|
||||||
<span :class="computedScheduledTrain.stopStatus" :title="computedScheduledTrain.stopStatusDescription">
|
<span
|
||||||
|
:class="computedScheduledTrain.stopStatus"
|
||||||
|
:title="computedScheduledTrain.stopStatusDescription"
|
||||||
|
>
|
||||||
{{ computedScheduledTrain.stopStatusIndicator }}
|
{{ computedScheduledTrain.stopStatusIndicator }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -19,16 +22,21 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
scheduledTrain: {
|
scheduledTrain: {
|
||||||
type: Object as PropType<ScheduledTrain>,
|
type: Object as PropType<ScheduledTrain>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
computedScheduledTrain(): ScheduledTrainComp {
|
computedScheduledTrain(): ScheduledTrainComp {
|
||||||
const { prevDepartureLine, prevStationName, stopStatus, nextArrivalLine, nextStationName } = this.scheduledTrain;
|
const { prevDepartureLine, prevStationName, stopStatus, nextArrivalLine, nextStationName } =
|
||||||
|
this.scheduledTrain;
|
||||||
|
|
||||||
const prevDepartureIndicator = prevDepartureLine ? `(${prevDepartureLine}) ${prevStationName}` : '---';
|
const prevDepartureIndicator = prevDepartureLine
|
||||||
const nextArrivalIndicator = nextArrivalLine ? `(${nextArrivalLine}) ${nextStationName}` : '---';
|
? `(${prevDepartureLine}) ${prevStationName}`
|
||||||
|
: '---';
|
||||||
|
const nextArrivalIndicator = nextArrivalLine
|
||||||
|
? `(${nextArrivalLine}) ${nextStationName}`
|
||||||
|
: '---';
|
||||||
|
|
||||||
let stopStatusDescription = '',
|
let stopStatusDescription = '',
|
||||||
stopStatusIndicator = '';
|
stopStatusIndicator = '';
|
||||||
@@ -36,7 +44,10 @@ export default defineComponent({
|
|||||||
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', { prevStationName, prevDepartureLine });
|
stopStatusDescription = this.$t('timetables.desc-arriving', {
|
||||||
|
prevStationName,
|
||||||
|
prevDepartureLine
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StopStatus.online:
|
case StopStatus.online:
|
||||||
@@ -51,12 +62,18 @@ export default defineComponent({
|
|||||||
|
|
||||||
case StopStatus.departed:
|
case StopStatus.departed:
|
||||||
stopStatusIndicator = `${this.$t('timetables.to')}: ${nextArrivalIndicator}`;
|
stopStatusIndicator = `${this.$t('timetables.to')}: ${nextArrivalIndicator}`;
|
||||||
stopStatusDescription = this.$t('timetables.desc-departed', { nextStationName, nextArrivalLine });
|
stopStatusDescription = this.$t('timetables.desc-departed', {
|
||||||
|
nextStationName,
|
||||||
|
nextArrivalLine
|
||||||
|
});
|
||||||
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', { nextStationName, nextArrivalLine });
|
stopStatusDescription = this.$t('timetables.desc-departed-away', {
|
||||||
|
nextStationName,
|
||||||
|
nextArrivalLine
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StopStatus.terminated:
|
case StopStatus.terminated:
|
||||||
@@ -70,10 +87,10 @@ export default defineComponent({
|
|||||||
return {
|
return {
|
||||||
...this.scheduledTrain,
|
...this.scheduledTrain,
|
||||||
stopStatusDescription,
|
stopStatusDescription,
|
||||||
stopStatusIndicator,
|
stopStatusIndicator
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -110,4 +127,3 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<label @dblclick="handleDbClick">
|
<label @dblclick="handleDbClick">
|
||||||
<input v-model="option.value" type="checkbox" :class="option.section" :name="option.id" />
|
<input type="checkbox" :class="option.section" :name="option.id" />
|
||||||
<span>
|
<span>
|
||||||
{{ $t(`filters.${option.id}`) }}
|
{{ $t(`filters.${option.id}`) }}
|
||||||
</span>
|
</span>
|
||||||
@@ -23,20 +23,20 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
option: {
|
option: {
|
||||||
type: Object as () => FilterOption,
|
type: Object as () => FilterOption,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
filterStore: useStationFiltersStore(),
|
filterStore: useStationFiltersStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
'option.value'() {
|
'option.value'() {
|
||||||
this.filterStore.changeFilterValue(this.option.name, !this.option.value);
|
this.filterStore.changeFilterValue(this.option.name, !this.option.value);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -44,7 +44,7 @@ export default defineComponent({
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.filterStore.lastClickedFilterId = this.option.id;
|
this.filterStore.lastClickedFilterId = this.option.id;
|
||||||
this.option.value = true;
|
// this.option.value = true;
|
||||||
|
|
||||||
this.filterStore.inputs.options
|
this.filterStore.inputs.options
|
||||||
.filter((option) => {
|
.filter((option) => {
|
||||||
@@ -53,8 +53,8 @@ export default defineComponent({
|
|||||||
.forEach((option) => {
|
.forEach((option) => {
|
||||||
option.value = !this.option.value;
|
option.value = !this.option.value;
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -96,4 +96,3 @@ label {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,11 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<datalist id="sceneries">
|
<datalist id="sceneries">
|
||||||
<option v-for="scenery in sortedStationList" :value="scenery.name"></option>
|
<option
|
||||||
|
v-for="scenery in sortedStationList"
|
||||||
|
:key="scenery.name"
|
||||||
|
:value="scenery.name"
|
||||||
|
></option>
|
||||||
</datalist>
|
</datalist>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,7 +50,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
|
|
||||||
<div class="option-section" v-for="section in filterStore.inputs.optionSections">
|
<div
|
||||||
|
class="option-section"
|
||||||
|
v-for="section in filterStore.inputs.optionSections"
|
||||||
|
:key="section"
|
||||||
|
>
|
||||||
<h3 class="text--primary">
|
<h3 class="text--primary">
|
||||||
{{ $t(`filters.sections.${section}`) }}
|
{{ $t(`filters.sections.${section}`) }}
|
||||||
|
|
||||||
@@ -57,7 +65,9 @@
|
|||||||
|
|
||||||
<div class="section-inputs">
|
<div class="section-inputs">
|
||||||
<FilterOption
|
<FilterOption
|
||||||
v-for="(option, i) in filterStore.inputs.options.filter((o) => o.section == section)"
|
v-for="(option, i) in filterStore.inputs.options.filter(
|
||||||
|
(o) => o.section == section
|
||||||
|
)"
|
||||||
:option="option"
|
:option="option"
|
||||||
:key="i"
|
:key="i"
|
||||||
/>
|
/>
|
||||||
@@ -114,7 +124,12 @@
|
|||||||
|
|
||||||
<section class="card_actions">
|
<section class="card_actions">
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<button class="btn--action" style="width: 100%" @click="saveFilters" :data-selected="saveOptions">
|
<button
|
||||||
|
class="btn--action"
|
||||||
|
style="width: 100%"
|
||||||
|
@click="saveFilters"
|
||||||
|
:data-selected="saveOptions"
|
||||||
|
>
|
||||||
{{ $t('filters.save') }}
|
{{ $t('filters.save') }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -143,11 +158,10 @@ 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/store';
|
||||||
|
|
||||||
import ActionButton from '../Global/ActionButton.vue';
|
|
||||||
import FilterOption from './FilterOption.vue';
|
import FilterOption from './FilterOption.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { ActionButton, FilterOption },
|
components: { FilterOption },
|
||||||
mixins: [imageMixin, keyMixin, routerMixin],
|
mixins: [imageMixin, keyMixin, routerMixin],
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
@@ -160,7 +174,7 @@ export default defineComponent({
|
|||||||
currentRegion: { id: '', value: '' },
|
currentRegion: { id: '', value: '' },
|
||||||
|
|
||||||
delayInputTimer: -1,
|
delayInputTimer: -1,
|
||||||
chosenSearchScenery: '',
|
chosenSearchScenery: ''
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
@@ -171,7 +185,7 @@ export default defineComponent({
|
|||||||
return {
|
return {
|
||||||
isVisible,
|
isVisible,
|
||||||
store,
|
store,
|
||||||
filterStore,
|
filterStore
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -190,13 +204,15 @@ export default defineComponent({
|
|||||||
computed: {
|
computed: {
|
||||||
sortedStationList() {
|
sortedStationList() {
|
||||||
return this.store.stationList
|
return this.store.stationList
|
||||||
.filter((s) => s.name.toLocaleLowerCase().includes(this.chosenSearchScenery.toLocaleLowerCase()))
|
.filter((s) =>
|
||||||
|
s.name.toLocaleLowerCase().includes(this.chosenSearchScenery.toLocaleLowerCase())
|
||||||
|
)
|
||||||
.sort((s1, s2) => (s1.name > s2.name ? 1 : -1));
|
.sort((s1, s2) => (s1.name > s2.name ? 1 : -1));
|
||||||
},
|
},
|
||||||
|
|
||||||
currentOptionsActive() {
|
currentOptionsActive() {
|
||||||
return true;
|
return true;
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
@@ -213,7 +229,7 @@ export default defineComponent({
|
|||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (value) (this.$refs['cardEl'] as HTMLDivElement).focus();
|
if (value) (this.$refs['cardEl'] as HTMLDivElement).focus();
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -265,8 +281,12 @@ export default defineComponent({
|
|||||||
|
|
||||||
StorageManager.registerStorage(this.STORAGE_KEY);
|
StorageManager.registerStorage(this.STORAGE_KEY);
|
||||||
|
|
||||||
this.filterStore.inputs.options.forEach((option) => StorageManager.setBooleanValue(option.name, !option.value));
|
this.filterStore.inputs.options.forEach((option) =>
|
||||||
this.filterStore.inputs.sliders.forEach((slider) => StorageManager.setNumericValue(slider.name, slider.value));
|
StorageManager.setBooleanValue(option.name, !option.value)
|
||||||
|
);
|
||||||
|
this.filterStore.inputs.sliders.forEach((slider) =>
|
||||||
|
StorageManager.setNumericValue(slider.name, slider.value)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
resetFilters() {
|
resetFilters() {
|
||||||
@@ -283,8 +303,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
toggleCard() {
|
toggleCard() {
|
||||||
this.isVisible = !this.isVisible;
|
this.isVisible = !this.isVisible;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
v-for="(headerName, i) in headIds"
|
v-for="headerName in headIds"
|
||||||
:key="headerName"
|
:key="headerName"
|
||||||
@click="changeSorter(headerName)"
|
@click="changeSorter(headerName)"
|
||||||
class="header-text"
|
class="header-text"
|
||||||
@@ -23,13 +23,17 @@
|
|||||||
</th>
|
</th>
|
||||||
|
|
||||||
<th
|
<th
|
||||||
v-for="(headerName, i) in headIconsIds"
|
v-for="headerName in headIconsIds"
|
||||||
:key="headerName"
|
:key="headerName"
|
||||||
@click="changeSorter(headerName)"
|
@click="changeSorter(headerName)"
|
||||||
class="header-image"
|
class="header-image"
|
||||||
>
|
>
|
||||||
<span class="header_wrapper">
|
<span class="header_wrapper">
|
||||||
<img :src="getIcon(headerName)" :alt="headerName" :title="$t(`sceneries.${headerName}`)" />
|
<img
|
||||||
|
:src="getIcon(headerName)"
|
||||||
|
:alt="headerName"
|
||||||
|
:title="$t(`sceneries.${headerName}`)"
|
||||||
|
/>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
class="sort-icon"
|
class="sort-icon"
|
||||||
@@ -55,7 +59,9 @@
|
|||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<td class="station_name" :class="station.generalInfo?.availability">
|
<td class="station_name" :class="station.generalInfo?.availability">
|
||||||
<b v-if="station.generalInfo?.project" style="color: salmon">{{ station.generalInfo.project }}</b>
|
<b v-if="station.generalInfo?.project" style="color: salmon">{{
|
||||||
|
station.generalInfo.project
|
||||||
|
}}</b>
|
||||||
{{ station.name }}
|
{{ station.name }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
@@ -81,7 +87,11 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<img :src="getIcon('unavailable')" alt="unavailable" :title="$t('desc.unavailable')" />
|
<img
|
||||||
|
:src="getIcon('unavailable')"
|
||||||
|
alt="unavailable"
|
||||||
|
:title="$t('desc.unavailable')"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -103,7 +113,12 @@
|
|||||||
<td class="station_dispatcher-exp">
|
<td class="station_dispatcher-exp">
|
||||||
<span
|
<span
|
||||||
v-if="station.onlineInfo"
|
v-if="station.onlineInfo"
|
||||||
:style="calculateExpStyle(station.onlineInfo.dispatcherExp, station.onlineInfo.dispatcherIsSupporter)"
|
:style="
|
||||||
|
calculateExpStyle(
|
||||||
|
station.onlineInfo.dispatcherExp,
|
||||||
|
station.onlineInfo.dispatcherIsSupporter
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ 2 > station.onlineInfo.dispatcherExp ? 'L' : station.onlineInfo.dispatcherExp }}
|
{{ 2 > station.onlineInfo.dispatcherExp ? 'L' : station.onlineInfo.dispatcherExp }}
|
||||||
</span>
|
</span>
|
||||||
@@ -111,7 +126,10 @@
|
|||||||
|
|
||||||
<td class="station_tracks twoway">
|
<td class="station_tracks twoway">
|
||||||
<span
|
<span
|
||||||
v-if="station.generalInfo && station.generalInfo.routes.twoWayCatenaryRouteNames.length > 0"
|
v-if="
|
||||||
|
station.generalInfo &&
|
||||||
|
station.generalInfo.routes.twoWayCatenaryRouteNames.length > 0
|
||||||
|
"
|
||||||
class="track catenary"
|
class="track catenary"
|
||||||
:title="`Liczba zelektryfikowanych szlaków dwutorowych: ${station.generalInfo.routes.twoWayCatenaryRouteNames.length}`"
|
:title="`Liczba zelektryfikowanych szlaków dwutorowych: ${station.generalInfo.routes.twoWayCatenaryRouteNames.length}`"
|
||||||
>
|
>
|
||||||
@@ -119,7 +137,10 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
v-if="station.generalInfo && station.generalInfo.routes.twoWayNoCatenaryRouteNames.length > 0"
|
v-if="
|
||||||
|
station.generalInfo &&
|
||||||
|
station.generalInfo.routes.twoWayNoCatenaryRouteNames.length > 0
|
||||||
|
"
|
||||||
class="track no-catenary"
|
class="track no-catenary"
|
||||||
:title="`Liczba niezelektryfikowanych szlaków dwutorowych: ${station.generalInfo.routes.twoWayNoCatenaryRouteNames.length}`"
|
:title="`Liczba niezelektryfikowanych szlaków dwutorowych: ${station.generalInfo.routes.twoWayNoCatenaryRouteNames.length}`"
|
||||||
>
|
>
|
||||||
@@ -129,7 +150,10 @@
|
|||||||
<span class="separator"></span>
|
<span class="separator"></span>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
v-if="station.generalInfo && station.generalInfo.routes.oneWayCatenaryRouteNames.length > 0"
|
v-if="
|
||||||
|
station.generalInfo &&
|
||||||
|
station.generalInfo.routes.oneWayCatenaryRouteNames.length > 0
|
||||||
|
"
|
||||||
class="track catenary"
|
class="track catenary"
|
||||||
:title="`Liczba zelektryfikowanych szlaków jednotorowych: ${station.generalInfo.routes.oneWayCatenaryRouteNames.length}`"
|
:title="`Liczba zelektryfikowanych szlaków jednotorowych: ${station.generalInfo.routes.oneWayCatenaryRouteNames.length}`"
|
||||||
>
|
>
|
||||||
@@ -137,7 +161,10 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
v-if="station.generalInfo && station.generalInfo.routes.oneWayNoCatenaryRouteNames.length > 0"
|
v-if="
|
||||||
|
station.generalInfo &&
|
||||||
|
station.generalInfo.routes.oneWayNoCatenaryRouteNames.length > 0
|
||||||
|
"
|
||||||
class="track no-catenary"
|
class="track no-catenary"
|
||||||
:title="`Liczba niezelektryfikowanych szlaków jednotorowych: ${station.generalInfo.routes.oneWayNoCatenaryRouteNames.length}`"
|
:title="`Liczba niezelektryfikowanych szlaków jednotorowych: ${station.generalInfo.routes.oneWayNoCatenaryRouteNames.length}`"
|
||||||
>
|
>
|
||||||
@@ -186,7 +213,12 @@
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="station_info" v-else>
|
<td class="station_info" v-else>
|
||||||
<img class="icon-info" :src="getIcon('unknown')" alt="icon-unknown" :title="$t('desc.unknown')" />
|
<img
|
||||||
|
class="icon-info"
|
||||||
|
:src="getIcon('unknown')"
|
||||||
|
alt="icon-unknown"
|
||||||
|
:title="$t('desc.unknown')"
|
||||||
|
/>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="station_users" :class="{ inactive: !station.onlineInfo }">
|
<td class="station_users" :class="{ inactive: !station.onlineInfo }">
|
||||||
@@ -201,21 +233,39 @@
|
|||||||
<span>{{ station.onlineInfo?.spawns.length || 0 }}</span>
|
<span>{{ station.onlineInfo?.spawns.length || 0 }}</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="station_schedules" style="width: 30px" :class="{ inactive: !station.onlineInfo }">
|
<td
|
||||||
|
class="station_schedules"
|
||||||
|
style="width: 30px"
|
||||||
|
:class="{ inactive: !station.onlineInfo }"
|
||||||
|
>
|
||||||
<span class="highlight">
|
<span class="highlight">
|
||||||
{{ station.onlineInfo?.scheduledTrains?.length || 0 }}
|
{{ station.onlineInfo?.scheduledTrains?.length || 0 }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="station_schedules" style="width: 30px" :class="{ inactive: !station.onlineInfo }">
|
<td
|
||||||
|
class="station_schedules"
|
||||||
|
style="width: 30px"
|
||||||
|
:class="{ inactive: !station.onlineInfo }"
|
||||||
|
>
|
||||||
<span style="color: #ccc">
|
<span style="color: #ccc">
|
||||||
{{ station.onlineInfo?.scheduledTrains?.filter((train) => !train.stopInfo.confirmed).length || 0 }}
|
{{
|
||||||
|
station.onlineInfo?.scheduledTrains?.filter((train) => !train.stopInfo.confirmed)
|
||||||
|
.length || 0
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="station_schedules" style="width: 30px" :class="{ inactive: !station.onlineInfo }">
|
<td
|
||||||
|
class="station_schedules"
|
||||||
|
style="width: 30px"
|
||||||
|
:class="{ inactive: !station.onlineInfo }"
|
||||||
|
>
|
||||||
<span style="color: #66ff6c">
|
<span style="color: #66ff6c">
|
||||||
{{ station.onlineInfo?.scheduledTrains?.filter((train) => train.stopInfo.confirmed).length || 0 }}
|
{{
|
||||||
|
station.onlineInfo?.scheduledTrains?.filter((train) => train.stopInfo.confirmed)
|
||||||
|
.length || 0
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -250,8 +300,8 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
stations: {
|
stations: {
|
||||||
type: Array as () => Station[],
|
type: Array as () => Station[],
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
components: { Loading, StationStatusBadge },
|
components: { Loading, StationStatusBadge },
|
||||||
@@ -260,13 +310,13 @@ export default defineComponent({
|
|||||||
data: () => ({
|
data: () => ({
|
||||||
headIconsIds,
|
headIconsIds,
|
||||||
headIds,
|
headIds,
|
||||||
lastSelectedStationName: '',
|
lastSelectedStationName: ''
|
||||||
}),
|
}),
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
sorterActive() {
|
sorterActive() {
|
||||||
return this.stationFiltersStore.sorterActive;
|
return this.stationFiltersStore.sorterActive;
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
@@ -278,7 +328,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
isDataLoaded,
|
isDataLoaded,
|
||||||
stationFiltersStore,
|
stationFiltersStore
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -290,7 +340,7 @@ export default defineComponent({
|
|||||||
this.lastSelectedStationName = station.name;
|
this.lastSelectedStationName = station.name;
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: 'SceneryView',
|
name: 'SceneryView',
|
||||||
query: { station: station.name.replaceAll(' ', '_') },
|
query: { station: station.name.replaceAll(' ', '_') }
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -304,8 +354,8 @@ export default defineComponent({
|
|||||||
if (headerName == 'general' || headerName == 'routes') return;
|
if (headerName == 'general' || headerName == 'routes') return;
|
||||||
|
|
||||||
this.stationFiltersStore.changeSorter(headerName);
|
this.stationFiltersStore.changeSorter(headerName);
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,19 +3,33 @@
|
|||||||
<section class="train-route">
|
<section class="train-route">
|
||||||
<div class="train_general">
|
<div class="train_general">
|
||||||
<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">#{{ 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
|
||||||
<span class="train-badge twr" v-if="train.timetableData?.TWR" :title="$t('general.TWR')">TWR</span>
|
class="timetable_warnings"
|
||||||
<span class="train-badge skr" v-if="train.timetableData?.SKR" :title="$t('general.SKR')">SKR</span>
|
v-if="train.timetableData?.TWR || train.timetableData?.SKR"
|
||||||
|
>
|
||||||
|
<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" :title="$t('general.SKR')"
|
||||||
|
>SKR</span
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<strong>
|
<strong>
|
||||||
<span v-if="train.timetableData" class="text--primary">{{ train.timetableData.category }} </span>
|
<span v-if="train.timetableData" class="text--primary"
|
||||||
|
>{{ train.timetableData.category }} </span
|
||||||
|
>
|
||||||
<span class="train-number">{{ train.trainNo }}</span>
|
<span class="train-number">{{ train.trainNo }}</span>
|
||||||
</strong>
|
</strong>
|
||||||
<span>•</span>
|
<span>•</span>
|
||||||
<b class="level-badge driver" :style="calculateExpStyle(train.driverLevel, train.isSupporter)">
|
<b
|
||||||
|
class="level-badge driver"
|
||||||
|
:style="calculateExpStyle(train.driverLevel, train.isSupporter)"
|
||||||
|
>
|
||||||
{{ train.driverLevel < 2 ? 'L' : `${train.driverLevel}` }}
|
{{ train.driverLevel < 2 ? 'L' : `${train.driverLevel}` }}
|
||||||
</b>
|
</b>
|
||||||
<span>{{ train.driverName }}</span>
|
<span>{{ train.driverName }}</span>
|
||||||
@@ -27,7 +41,9 @@
|
|||||||
v-if="getSceneriesWithComments(train.timetableData).length > 0"
|
v-if="getSceneriesWithComments(train.timetableData).length > 0"
|
||||||
class="image-warning"
|
class="image-warning"
|
||||||
:src="getIcon('warning')"
|
:src="getIcon('warning')"
|
||||||
:title="`${$t('trains.timetable-comments')} (${getSceneriesWithComments(train.timetableData)})`"
|
:title="`${$t('trains.timetable-comments')} (${getSceneriesWithComments(
|
||||||
|
train.timetableData
|
||||||
|
)})`"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -51,8 +67,12 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="train-status-badges">
|
<div class="train-status-badges">
|
||||||
<div v-if="!train.currentStationHash" class="train-badge offline">{{ $t('trains.scenery-offline') }}</div>
|
<div v-if="!train.currentStationHash" class="train-badge offline">
|
||||||
<div v-if="!train.online" class="train-badge offline">Offline {{ lastSeenMessage(train.lastSeen) }}</div>
|
{{ $t('trains.scenery-offline') }}
|
||||||
|
</div>
|
||||||
|
<div v-if="!train.online" class="train-badge offline">
|
||||||
|
Offline {{ lastSeenMessage(train.lastSeen) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -75,7 +95,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<span v-for="(stat, i) in STATS.main" :key="stat.name">
|
<span v-for="(stat, i) in STATS.main" :key="stat.name">
|
||||||
<span v-if="i > 0"> • </span>
|
<span v-if="i > 0"> • </span>
|
||||||
<span>{{ `${~~((train as any)[stat.name] * (stat.multiplier || 1))}${stat.unit}` }} </span>
|
<span
|
||||||
|
>{{ `${~~((train as any)[stat.name] * (stat.multiplier || 1))}${stat.unit}` }}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -95,15 +117,15 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
train: {
|
train: {
|
||||||
type: Object as () => Train,
|
type: Object as () => Train,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
extended: {
|
extended: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mixins: [trainInfoMixin, imageMixin, styleMixin],
|
mixins: [trainInfoMixin, imageMixin, styleMixin],
|
||||||
components: { ProgressBar, TrainThumbnail },
|
components: { ProgressBar, TrainThumbnail }
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
<div class="options_sorters">
|
<div class="options_sorters">
|
||||||
<button
|
<button
|
||||||
v-for="opt in translatedSorterOptions"
|
v-for="opt in translatedSorterOptions"
|
||||||
|
:key="opt.id"
|
||||||
class="sort-option btn--option"
|
class="sort-option btn--option"
|
||||||
:data-selected="opt.id == sorterActive.id"
|
:data-selected="opt.id == sorterActive.id"
|
||||||
@click="onSorterChange(opt)"
|
@click="onSorterChange(opt)"
|
||||||
@@ -53,13 +54,16 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 class="option-title" v-if="trainFilterList.length != 0">{{ $t('options.filter-title') }}</h1>
|
<h1 class="option-title" v-if="trainFilterList.length != 0">
|
||||||
|
{{ $t('options.filter-title') }}
|
||||||
|
</h1>
|
||||||
|
|
||||||
<div class="options_filters">
|
<div class="options_filters">
|
||||||
<div v-for="section in Object.keys(TrainFilterSection)">
|
<div v-for="section in Object.keys(TrainFilterSection)" :key="section">
|
||||||
<button
|
<button
|
||||||
class="btn--option"
|
class="btn--option"
|
||||||
v-for="filter in trainFilterList.filter((f) => f.section == section)"
|
v-for="filter in trainFilterList.filter((f) => f.section == section)"
|
||||||
|
:key="filter.id"
|
||||||
:data-inactive="!filter.isActive"
|
:data-inactive="!filter.isActive"
|
||||||
@click="onFilterChange(filter)"
|
@click="onFilterChange(filter)"
|
||||||
>
|
>
|
||||||
@@ -70,7 +74,9 @@
|
|||||||
|
|
||||||
<div class="filter-actions">
|
<div class="filter-actions">
|
||||||
<div></div>
|
<div></div>
|
||||||
<button class="btn--action" @click="resetAllFilters">{{ $t('options.filter-reset') }}</button>
|
<button class="btn--action" @click="resetAllFilters">
|
||||||
|
{{ $t('options.filter-reset') }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -82,32 +88,29 @@
|
|||||||
import { defineComponent, inject, PropType } from 'vue';
|
import { defineComponent, inject, PropType } from 'vue';
|
||||||
import imageMixin from '../../mixins/imageMixin';
|
import imageMixin from '../../mixins/imageMixin';
|
||||||
import keyMixin from '../../mixins/keyMixin';
|
import keyMixin from '../../mixins/keyMixin';
|
||||||
import ActionButton from '../Global/ActionButton.vue';
|
|
||||||
import SelectBox from '../Global/SelectBox.vue';
|
|
||||||
import { TrainFilterSection } from '../../scripts/enums/TrainFilterType';
|
import { TrainFilterSection } from '../../scripts/enums/TrainFilterType';
|
||||||
import { TrainFilter } from '../../scripts/interfaces/Trains/TrainFilter';
|
import { TrainFilter } from '../../scripts/interfaces/Trains/TrainFilter';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { SelectBox, ActionButton },
|
|
||||||
mixins: [imageMixin, keyMixin],
|
mixins: [imageMixin, keyMixin],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
sorterOptionIds: {
|
sorterOptionIds: {
|
||||||
type: Array as PropType<Array<string>>,
|
type: Array as PropType<Array<string>>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
currentOptionsActive: {
|
currentOptionsActive: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showOptions: false,
|
showOptions: false,
|
||||||
lastSelectedFilter: null as TrainFilter | null,
|
lastSelectedFilter: null as TrainFilter | null,
|
||||||
TrainFilterSection,
|
TrainFilterSection
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -117,7 +120,7 @@ export default defineComponent({
|
|||||||
searchedDriver: inject('searchedDriver') as string,
|
searchedDriver: inject('searchedDriver') as string,
|
||||||
|
|
||||||
sorterActive: inject('sorterActive') as { id: string | number; dir: number },
|
sorterActive: inject('sorterActive') as { id: string | number; dir: number },
|
||||||
trainFilterList: inject('filterList') as TrainFilter[],
|
trainFilterList: inject('filterList') as TrainFilter[]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -125,9 +128,9 @@ export default defineComponent({
|
|||||||
translatedSorterOptions() {
|
translatedSorterOptions() {
|
||||||
return this.$props.sorterOptionIds.map((id) => ({
|
return this.$props.sorterOptionIds.map((id) => ({
|
||||||
id,
|
id,
|
||||||
value: this.$t(`options.sort-${id}`),
|
value: this.$t(`options.sort-${id}`)
|
||||||
}));
|
}));
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -172,8 +175,8 @@ export default defineComponent({
|
|||||||
onInputClear(id: 'driver' | 'train') {
|
onInputClear(id: 'driver' | 'train') {
|
||||||
if (id == 'driver') this.searchedDriver = '';
|
if (id == 'driver') this.searchedDriver = '';
|
||||||
if (id == 'train') this.searchedTrain = '';
|
if (id == 'train') this.searchedTrain = '';
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,12 @@
|
|||||||
|
|
||||||
<div class="schedule-wrapper" v-if="train.timetableData">
|
<div class="schedule-wrapper" v-if="train.timetableData">
|
||||||
<ul class="stop_list">
|
<ul class="stop_list">
|
||||||
<li v-for="(stop, i) in train.timetableData.followingStops" :key="i" class="stop" :class="addClasses(stop, i)">
|
<li
|
||||||
|
v-for="(stop, i) in train.timetableData.followingStops"
|
||||||
|
:key="i"
|
||||||
|
class="stop"
|
||||||
|
:class="addClasses(stop, i)"
|
||||||
|
>
|
||||||
<span class="stop_info">
|
<span class="stop_info">
|
||||||
<div class="indicator"></div>
|
<div class="indicator"></div>
|
||||||
|
|
||||||
@@ -37,7 +42,12 @@
|
|||||||
<b>{{ stop.stopNameRAW }} </b>: <span v-html="stop.comments"></span>
|
<b>{{ stop.stopNameRAW }} </b>: <span v-html="stop.comments"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span v-if="stop.departureLine == train.timetableData!.followingStops[i + 1].arrivalLine && !/sbl/gi.test(stop.departureLine!)">
|
<span
|
||||||
|
v-if="
|
||||||
|
stop.departureLine == train.timetableData!.followingStops[i + 1].arrivalLine &&
|
||||||
|
!/sbl/gi.test(stop.departureLine!)
|
||||||
|
"
|
||||||
|
>
|
||||||
{{ stop.departureLine }}
|
{{ stop.departureLine }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -59,23 +69,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, PropType } from '@vue/runtime-core';
|
import { computed, defineComponent, PropType } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import imageMixin from '../../mixins/imageMixin';
|
import imageMixin from '../../mixins/imageMixin';
|
||||||
import Train from '../../scripts/interfaces/Train';
|
import Train from '../../scripts/interfaces/Train';
|
||||||
import TrainStop from '../../scripts/interfaces/TrainStop';
|
import TrainStop from '../../scripts/interfaces/TrainStop';
|
||||||
import { useStore } from '../../store/store';
|
import { useStore } from '../../store/store';
|
||||||
import StopDate from '../Global/StopDate.vue';
|
import StopDate from '../Global/StopDate.vue';
|
||||||
import TrainThumbnail from '../Global/TrainThumbnail.vue';
|
|
||||||
import StockList from '../Global/StockList.vue';
|
import StockList from '../Global/StockList.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { StopDate, TrainThumbnail, StockList },
|
components: { StopDate, StockList },
|
||||||
props: {
|
props: {
|
||||||
train: {
|
train: {
|
||||||
type: Object as PropType<Train>,
|
type: Object as PropType<Train>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [dateMixin, imageMixin],
|
mixins: [dateMixin, imageMixin],
|
||||||
@@ -97,15 +106,21 @@ export default defineComponent({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const activeMinorStopList: number[] = [];
|
const activeMinorStopList: number[] = [];
|
||||||
if (lastMajorConfirmed + 1 >= props.train.timetableData!.followingStops.length) return activeMinorStopList;
|
if (lastMajorConfirmed + 1 >= props.train.timetableData!.followingStops.length)
|
||||||
|
return activeMinorStopList;
|
||||||
|
|
||||||
for (let i = lastMajorConfirmed + 1; i < props.train.timetableData!.followingStops.length; i++) {
|
for (
|
||||||
if (/po\.|sbl/gi.test(props.train.timetableData!.followingStops[i].stopNameRAW)) activeMinorStopList.push(i);
|
let i = lastMajorConfirmed + 1;
|
||||||
|
i < props.train.timetableData!.followingStops.length;
|
||||||
|
i++
|
||||||
|
) {
|
||||||
|
if (/po\.|sbl/gi.test(props.train.timetableData!.followingStops[i].stopNameRAW))
|
||||||
|
activeMinorStopList.push(i);
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return activeMinorStopList;
|
return activeMinorStopList;
|
||||||
}),
|
})
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -122,17 +137,18 @@ export default defineComponent({
|
|||||||
end: stop.terminatesHere,
|
end: stop.terminatesHere,
|
||||||
delayed: stop.departureDelay > 0,
|
delayed: stop.departureDelay > 0,
|
||||||
sbl: /sbl/gi.test(stop.stopName),
|
sbl: /sbl/gi.test(stop.stopName),
|
||||||
[stop.stopType.replaceAll(', ', '-')]: stop.stopType.match(new RegExp('ph|pm|pt')) && !stop.confirmed && !stop.beginsHere,
|
[stop.stopType.replaceAll(', ', '-')]:
|
||||||
|
stop.stopType.match(new RegExp('ph|pm|pt')) && !stop.confirmed && !stop.beginsHere,
|
||||||
'minor-stop-active': this.activeMinorStops.includes(index),
|
'minor-stop-active': this.activeMinorStops.includes(index),
|
||||||
'last-confirmed': index == this.lastConfirmed && !stop.terminatesHere,
|
'last-confirmed': index == this.lastConfirmed && !stop.terminatesHere
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
onImageError(e: Event) {
|
onImageError(e: Event) {
|
||||||
const imageEl = e.target as HTMLImageElement;
|
const imageEl = e.target as HTMLImageElement;
|
||||||
imageEl.src = this.getImage('unknown.png');
|
imageEl.src = this.getImage('unknown.png');
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,10 @@
|
|||||||
|
|
||||||
<Loading v-else-if="trains.length == 0 && store.dataStatuses.trains == 0" />
|
<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">
|
<div
|
||||||
|
class="table-info no-trains"
|
||||||
|
v-else-if="trains.length == 0 && store.dataStatuses.trains != 0"
|
||||||
|
>
|
||||||
{{ $t('trains.no-trains') }}
|
{{ $t('trains.no-trains') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -44,8 +47,8 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
trains: {
|
trains: {
|
||||||
type: Array as PropType<Train[]>,
|
type: Array as PropType<Train[]>,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [returnBtnMixin, modalTrainMixin],
|
mixins: [returnBtnMixin, modalTrainMixin],
|
||||||
@@ -66,7 +69,7 @@ export default defineComponent({
|
|||||||
sorterActive: inject('sorterActive') as {
|
sorterActive: inject('sorterActive') as {
|
||||||
id: string | number;
|
id: string | number;
|
||||||
dir: number;
|
dir: number;
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -79,7 +82,7 @@ export default defineComponent({
|
|||||||
this.selectModalTrain(query.driverName! + query.trainNo!.toString());
|
this.selectModalTrain(query.driverName! + query.trainNo!.toString());
|
||||||
}, 20);
|
}, 20);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -5,42 +5,42 @@ export const journalTimetableFilters: JournalFilter[] = [
|
|||||||
{
|
{
|
||||||
id: JournalFilterType.ALL,
|
id: JournalFilterType.ALL,
|
||||||
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: JournalFilterType.ACTIVE,
|
id: JournalFilterType.ACTIVE,
|
||||||
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
||||||
isActive: false,
|
isActive: false
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: JournalFilterType.FULFILLED,
|
id: JournalFilterType.FULFILLED,
|
||||||
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
||||||
isActive: false,
|
isActive: false
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: JournalFilterType.ABANDONED,
|
id: JournalFilterType.ABANDONED,
|
||||||
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
filterSection: JournalFilterSection.TIMETABLE_STATUS,
|
||||||
isActive: false,
|
isActive: false
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: JournalFilterType.TWR_SKR,
|
id: JournalFilterType.TWR_SKR,
|
||||||
filterSection: JournalFilterSection.TWRSKR,
|
filterSection: JournalFilterSection.TWRSKR,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: JournalFilterType.TWR,
|
id: JournalFilterType.TWR,
|
||||||
filterSection: JournalFilterSection.TWRSKR,
|
filterSection: JournalFilterSection.TWRSKR,
|
||||||
isActive: false,
|
isActive: false
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: JournalFilterType.SKR,
|
id: JournalFilterType.SKR,
|
||||||
filterSection: JournalFilterSection.TWRSKR,
|
filterSection: JournalFilterSection.TWRSKR,
|
||||||
isActive: false,
|
isActive: false
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -5,85 +5,85 @@ export const trainFilters: TrainFilter[] = [
|
|||||||
{
|
{
|
||||||
id: TrainFilterType.twr,
|
id: TrainFilterType.twr,
|
||||||
section: TrainFilterSection.TRAIN_TYPE,
|
section: TrainFilterSection.TRAIN_TYPE,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.skr,
|
id: TrainFilterType.skr,
|
||||||
section: TrainFilterSection.TRAIN_TYPE,
|
section: TrainFilterSection.TRAIN_TYPE,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.common,
|
id: TrainFilterType.common,
|
||||||
section: TrainFilterSection.TRAIN_TYPE,
|
section: TrainFilterSection.TRAIN_TYPE,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: TrainFilterType.passenger,
|
id: TrainFilterType.passenger,
|
||||||
section: TrainFilterSection.TIMETABLE_TYPE,
|
section: TrainFilterSection.TIMETABLE_TYPE,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.freight,
|
id: TrainFilterType.freight,
|
||||||
section: TrainFilterSection.TIMETABLE_TYPE,
|
section: TrainFilterSection.TIMETABLE_TYPE,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.other,
|
id: TrainFilterType.other,
|
||||||
section: TrainFilterSection.TIMETABLE_TYPE,
|
section: TrainFilterSection.TIMETABLE_TYPE,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: TrainFilterType.withComments,
|
id: TrainFilterType.withComments,
|
||||||
section: TrainFilterSection.COMMENTS,
|
section: TrainFilterSection.COMMENTS,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.noComments,
|
id: TrainFilterType.noComments,
|
||||||
section: TrainFilterSection.COMMENTS,
|
section: TrainFilterSection.COMMENTS,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: TrainFilterType.withTimetable,
|
id: TrainFilterType.withTimetable,
|
||||||
section: TrainFilterSection.TIMETABLE,
|
section: TrainFilterSection.TIMETABLE,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TrainFilterType.noTimetable,
|
id: TrainFilterType.noTimetable,
|
||||||
section: TrainFilterSection.TIMETABLE,
|
section: TrainFilterSection.TIMETABLE,
|
||||||
isActive: true,
|
isActive: true
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export const sorterOptions = [
|
export const sorterOptions = [
|
||||||
{
|
{
|
||||||
id: 'distance',
|
id: 'distance',
|
||||||
value: 'kilometraż',
|
value: 'kilometraż'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'id',
|
id: 'id',
|
||||||
value: 'id rozkładu',
|
value: 'id rozkładu'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'progress',
|
id: 'progress',
|
||||||
value: 'przebyta trasa',
|
value: 'przebyta trasa'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'delay',
|
id: 'delay',
|
||||||
value: 'opóźnienie',
|
value: 'opóźnienie'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'mass',
|
id: 'mass',
|
||||||
value: 'masa',
|
value: 'masa'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'speed',
|
id: 'speed',
|
||||||
value: 'prędkość',
|
value: 'prędkość'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'length',
|
id: 'length',
|
||||||
value: 'długość',
|
value: 'długość'
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1 +1,23 @@
|
|||||||
["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"]
|
[
|
||||||
|
"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"
|
||||||
|
]
|
||||||
|
|||||||
@@ -2650,7 +2650,16 @@
|
|||||||
],
|
],
|
||||||
"route": "DOBRZYNIEC|CZERMIN",
|
"route": "DOBRZYNIEC|CZERMIN",
|
||||||
"timetableId": 441366,
|
"timetableId": 441366,
|
||||||
"sceneries": ["2ce4e4b8", "e89b093c", "7fc24616", "9e8e828e", "a08efab9", "32d49e1d", "89fcee89", "beca9dd8"]
|
"sceneries": [
|
||||||
|
"2ce4e4b8",
|
||||||
|
"e89b093c",
|
||||||
|
"7fc24616",
|
||||||
|
"9e8e828e",
|
||||||
|
"a08efab9",
|
||||||
|
"32d49e1d",
|
||||||
|
"89fcee89",
|
||||||
|
"beca9dd8"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -4624,7 +4633,18 @@
|
|||||||
],
|
],
|
||||||
"route": "CZERMIN|Zakopane",
|
"route": "CZERMIN|Zakopane",
|
||||||
"timetableId": 441329,
|
"timetableId": 441329,
|
||||||
"sceneries": ["2a60af79", "9e8e828e", "89fcee89", "32d49e1d", "e89b093c", "d60a1f02", "4e0599d3", "beca9dd8", "b7fea344", "2ce4e4b8"]
|
"sceneries": [
|
||||||
|
"2a60af79",
|
||||||
|
"9e8e828e",
|
||||||
|
"89fcee89",
|
||||||
|
"32d49e1d",
|
||||||
|
"e89b093c",
|
||||||
|
"d60a1f02",
|
||||||
|
"4e0599d3",
|
||||||
|
"beca9dd8",
|
||||||
|
"b7fea344",
|
||||||
|
"2ce4e4b8"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -4940,7 +4960,15 @@
|
|||||||
],
|
],
|
||||||
"route": "Suszec Kopalnia|Wielichowo Główne gt",
|
"route": "Suszec Kopalnia|Wielichowo Główne gt",
|
||||||
"timetableId": 441331,
|
"timetableId": 441331,
|
||||||
"sceneries": ["a07a1966", "70717e39", "9e8e828e", "d60a1f02", "89fcee89", "beca9dd8", "8ce88788"]
|
"sceneries": [
|
||||||
|
"a07a1966",
|
||||||
|
"70717e39",
|
||||||
|
"9e8e828e",
|
||||||
|
"d60a1f02",
|
||||||
|
"89fcee89",
|
||||||
|
"beca9dd8",
|
||||||
|
"8ce88788"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -6620,7 +6648,15 @@
|
|||||||
],
|
],
|
||||||
"route": "ŁAPANÓW|LISKÓW",
|
"route": "ŁAPANÓW|LISKÓW",
|
||||||
"timetableId": 441339,
|
"timetableId": 441339,
|
||||||
"sceneries": ["e2517545", "8052a490", "1800a035", "f58b0066", "beca9dd8", "a07a1966", "9e8e828e"]
|
"sceneries": [
|
||||||
|
"e2517545",
|
||||||
|
"8052a490",
|
||||||
|
"1800a035",
|
||||||
|
"f58b0066",
|
||||||
|
"beca9dd8",
|
||||||
|
"a07a1966",
|
||||||
|
"9e8e828e"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -8902,7 +8938,15 @@
|
|||||||
],
|
],
|
||||||
"route": "ŁAPANÓW|GRABÓW",
|
"route": "ŁAPANÓW|GRABÓW",
|
||||||
"timetableId": 441348,
|
"timetableId": 441348,
|
||||||
"sceneries": ["e3222787", "2ce4e4b8", "db41867c", "f58b0066", "b7fea344", "073ff753", "9e8e828e"]
|
"sceneries": [
|
||||||
|
"e3222787",
|
||||||
|
"2ce4e4b8",
|
||||||
|
"db41867c",
|
||||||
|
"f58b0066",
|
||||||
|
"b7fea344",
|
||||||
|
"073ff753",
|
||||||
|
"9e8e828e"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -9686,7 +9730,16 @@
|
|||||||
],
|
],
|
||||||
"route": "KRNÓW|ORNIKI",
|
"route": "KRNÓW|ORNIKI",
|
||||||
"timetableId": 441355,
|
"timetableId": 441355,
|
||||||
"sceneries": ["4590c058", "f58b0066", "2ce4e4b8", "b0eecdb9", "5186fd9c", "e3222787", "5d22ada6", "03cd8e91"]
|
"sceneries": [
|
||||||
|
"4590c058",
|
||||||
|
"f58b0066",
|
||||||
|
"2ce4e4b8",
|
||||||
|
"b0eecdb9",
|
||||||
|
"5186fd9c",
|
||||||
|
"e3222787",
|
||||||
|
"5d22ada6",
|
||||||
|
"03cd8e91"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-1
@@ -1,5 +1,14 @@
|
|||||||
{
|
{
|
||||||
"optionSections": ["reality", "package-access", "access", "control", "addons", "blockades", "signals", "status"],
|
"optionSections": [
|
||||||
|
"reality",
|
||||||
|
"package-access",
|
||||||
|
"access",
|
||||||
|
"control",
|
||||||
|
"addons",
|
||||||
|
"blockades",
|
||||||
|
"signals",
|
||||||
|
"status"
|
||||||
|
],
|
||||||
|
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,434 @@
|
|||||||
|
{
|
||||||
|
"general": {
|
||||||
|
"and": " oraz ",
|
||||||
|
"refresh": "ODŚWIEŻ",
|
||||||
|
"TWR": "Towar niebezpieczny wysokiego ryzyka",
|
||||||
|
"SKR": "Przekroczona skrajnia"
|
||||||
|
},
|
||||||
|
"app": {
|
||||||
|
"sceneries": "SCENERIE",
|
||||||
|
"trains": "POCIĄGI",
|
||||||
|
"journal": "DZIENNIK",
|
||||||
|
"loading": "Pobieranie danych...",
|
||||||
|
"support": "Wspomóż projekt",
|
||||||
|
"error": "Wystąpił problem z załadowaniem danych!",
|
||||||
|
"no-result": "Brak wyników o podanych kryteriach!",
|
||||||
|
"migration-warning": "Usługi Stacjownika będą niedostępne w godzinach 1:00-3:00 2 czerwca 2022r. z powodu migracji hostingów API!",
|
||||||
|
"migration-confirm": "Przyjąłem!",
|
||||||
|
"offline": "Aplikacja w trybie offline!"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"discord": "Serwer Discord Stacjownika"
|
||||||
|
},
|
||||||
|
"update": {
|
||||||
|
"title": "Nowa wersja Stacjownika jest dostępna!",
|
||||||
|
"paragraph1": "Miłego korzystania z aplikacji i niech S2 będzie z wami!",
|
||||||
|
"release-link": "Kliknij, aby przejrzeć listę zmian (GitHub)",
|
||||||
|
"confirm-button": "ZAKTUALIZUJ",
|
||||||
|
"later-button": "PÓŹNIEJ"
|
||||||
|
},
|
||||||
|
"data-status": {
|
||||||
|
"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-sceneries": "<b>Sygnał S1a</b> <br> Błąd podczas pobierania danych o sceneriach online!",
|
||||||
|
"S2": "<b>Sygnał S2</b> <br> Pomyślnie załadowano dane!",
|
||||||
|
"S3": "<b>Sygnał S3</b> <br> Pobieranie danych...",
|
||||||
|
"S5-timetables": "<b>Sygnał S5</b> <br> Rozkłady jazdy mogą być niekompletne!",
|
||||||
|
"S5-dispatchers": "<b>Sygnał S5</b> <br> Błąd podczas pobierania danych o statusach dyżurnych ruchu!",
|
||||||
|
"S5-trains": "<b>Sygnał S5</b> <br> Błąd podczas pobierania danych o pociągach online!"
|
||||||
|
},
|
||||||
|
"desc": {
|
||||||
|
"control-type": "Sterowanie: ",
|
||||||
|
"signals-type": "Sygnalizacja: ",
|
||||||
|
"SBL": "Sceneria posiada SBL na szlakach: ",
|
||||||
|
"SUP": "Wymaga programu SUP do kontroli systemu RASP-UZK",
|
||||||
|
"TWB-all": "Sceneria posiada blokadę dwukierunkową na wszystkich szlakach",
|
||||||
|
"TWB-routes": "Sceneria posiada blokadę dwukierunkową na szlakach: ",
|
||||||
|
"default": "Sceneria dostępna domyślnie w paczce z grą",
|
||||||
|
"non-public": "Sceneria niepubliczna",
|
||||||
|
"unavailable": "Sceneria niedostępna",
|
||||||
|
"unknown": "Nieznana sceneria",
|
||||||
|
"real": "Sceneria z realnymi liniami kolejowymi: ",
|
||||||
|
"abandoned": "Sceneria wycofana z rozgrywki"
|
||||||
|
},
|
||||||
|
"signals": {
|
||||||
|
"title": "Sygnalizacja",
|
||||||
|
"współczesna": "współczesna",
|
||||||
|
"mieszana": "mieszana",
|
||||||
|
"kształtowa": "kształtowa",
|
||||||
|
"historyczna": "historyczna"
|
||||||
|
},
|
||||||
|
"controls": {
|
||||||
|
"title": "Sterowanie",
|
||||||
|
"SPK": "SPK",
|
||||||
|
"SCS": "SCS",
|
||||||
|
"SCS-SPK": "SCS/SPK",
|
||||||
|
"SPE": "SPE",
|
||||||
|
"ręczne": "ręczne",
|
||||||
|
"ręczne+SPK": "ręczne z SPK",
|
||||||
|
"ręczne+SCS": "ręczne z SCS",
|
||||||
|
"mechaniczne": "mechaniczne",
|
||||||
|
"mechaniczne+SPK": "mechaniczne z SPK",
|
||||||
|
"mechaniczne+SCS": "mechaniczne z SCS"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"online": "DO ",
|
||||||
|
"free": "WOLNA",
|
||||||
|
"ending": "KOŃCZY",
|
||||||
|
"not-signed": "NIEZALOGOWANY",
|
||||||
|
"no-limit": "BEZ LIMITU",
|
||||||
|
"unavailable": "NIEDOSTĘPNY",
|
||||||
|
"brb": "Z/W",
|
||||||
|
"no-space": "BRAK MIEJSCA",
|
||||||
|
"unknown": "NIEZNANY"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"filters": "FILTRY",
|
||||||
|
"donate": "WESPRZYJ",
|
||||||
|
|
||||||
|
"search-button": "Szukaj",
|
||||||
|
"reset-button": "Zresetuj",
|
||||||
|
|
||||||
|
"sort-title": "SORTUJ WG:",
|
||||||
|
"filter-title": "FILTRUJ WG:",
|
||||||
|
"search-title": "SZUKAJ:",
|
||||||
|
|
||||||
|
"search-train-no": "Nr pociągu",
|
||||||
|
"search-train": "Nr pociągu / #",
|
||||||
|
"search-driver": "Nick maszynisty",
|
||||||
|
"search-dispatcher": "Nick dyżurnego",
|
||||||
|
"search-station": "Nazwa scenerii",
|
||||||
|
"search-author": "Nick autora rozkładu jazdy",
|
||||||
|
"search-issuedFrom": "Sceneria początkowa",
|
||||||
|
"search-timetables-date": "Data rozkładu jazdy (UTC+2 / CEST)",
|
||||||
|
"search-dispatchers-date": "Data służby (UTC+2 / CEST)",
|
||||||
|
"search-date": "Data (UTC+2 / CEST)",
|
||||||
|
|
||||||
|
"sort-routeDistance": "kilometraż",
|
||||||
|
"sort-allStopsCount": "stacje",
|
||||||
|
"sort-beginDate": "data",
|
||||||
|
"sort-timetableId": "ID rozkładu",
|
||||||
|
"sort-timestampFrom": "data",
|
||||||
|
"sort-duration": "czas dyżuru",
|
||||||
|
"sort-id": "id rozkładu",
|
||||||
|
|
||||||
|
"sort-mass": "masa",
|
||||||
|
"sort-speed": "prędkość",
|
||||||
|
"sort-length": "długość",
|
||||||
|
"sort-timetable": "nr pociągu",
|
||||||
|
"sort-progress": "przebyta trasa",
|
||||||
|
"sort-delay": "opóźnienie",
|
||||||
|
"sort-comments": "uwagi ekspl.",
|
||||||
|
|
||||||
|
"filter-withComments": "UWAGI EKSPLOATACYJNE",
|
||||||
|
"filter-noComments": "BEZ UWAG",
|
||||||
|
"filter-twr": "WYS. RYZYKA",
|
||||||
|
"filter-skr": "SKRAJNIA",
|
||||||
|
"filter-twr-skr": "WSZYSTKIE",
|
||||||
|
"filter-common": "ZWYKŁE",
|
||||||
|
"filter-passenger": "PASAŻERSKIE",
|
||||||
|
"filter-freight": "TOWAROWE",
|
||||||
|
"filter-other": "INNE",
|
||||||
|
"filter-noTimetable": "BEZ RJ",
|
||||||
|
"filter-withTimetable": "ROZKŁAD JAZDY",
|
||||||
|
|
||||||
|
"filter-reset": "ZRESETUJ FILTRY",
|
||||||
|
"filter-clear": "WYŁĄCZ FILTRY",
|
||||||
|
|
||||||
|
"filter-section-timetable-status": "STATUS ROZKŁADU JAZDY",
|
||||||
|
"filter-section-twrskr": "UWAGI",
|
||||||
|
|
||||||
|
"filter-all": "WSZYSTKIE",
|
||||||
|
"filter-abandoned": "PORZUCONE",
|
||||||
|
"filter-fulfilled": "WYPEŁNIONE",
|
||||||
|
"filter-active": "AKTYWNE"
|
||||||
|
},
|
||||||
|
"filters": {
|
||||||
|
"desc": " • Kliknięcie: zaznaczenie / odznaczenie filtru <br /> • Podwójne kliknięcie: odznaczenie reszty filtrów z <b class='text--primary'>grupy</b> <br /> • <span style='color: coral'>RESET</span>: zresetowanie filtrów z <b class='text--primary'>grupy</b>",
|
||||||
|
|
||||||
|
"sections": {
|
||||||
|
"quick": "SZYBKIE FILTRY",
|
||||||
|
"reality": "FIKCYJNOŚĆ SCENERII",
|
||||||
|
"package-access": "DOSTĘPNOŚĆ W PACZCE",
|
||||||
|
"access": "DOSTĘPNOŚĆ OGÓLNA",
|
||||||
|
"control": "TYP STEROWANIA",
|
||||||
|
"signals": "TYP SYGNALIZACJI",
|
||||||
|
"addons": "DODATKOWE PROGRAMY",
|
||||||
|
"blockades": "BLOKADY LINIOWE",
|
||||||
|
"status": "STATUS ONLINE"
|
||||||
|
},
|
||||||
|
|
||||||
|
"all-available": "WSZYSTKIE DOSTĘPNE",
|
||||||
|
"all-free": "WSZYSTKIE WOLNE",
|
||||||
|
|
||||||
|
"endingStatus": "KOŃCZY",
|
||||||
|
"afkStatus": "Z/W",
|
||||||
|
"noSpaceStatus": "BRAK MIEJSCA",
|
||||||
|
"unavailableStatus": "NIEDOSTĘPNY",
|
||||||
|
|
||||||
|
"title": "FILTRUJ STACJE",
|
||||||
|
"default": "DOMYŚLNA",
|
||||||
|
"not-default": "POZA PACZKĄ",
|
||||||
|
"real": "REALNA",
|
||||||
|
"fictional": "FIKCYJNA",
|
||||||
|
"unavailable": "NIEDOSTĘPNA",
|
||||||
|
"non-public": "NIEPUBLICZNA",
|
||||||
|
"abandoned": "WYCOFANA",
|
||||||
|
|
||||||
|
"SPK": "SPK",
|
||||||
|
"SPK-R": "SPK + RĘCZNE",
|
||||||
|
"SPK-M": "SPK + MECH.",
|
||||||
|
"SCS": "SCS",
|
||||||
|
"SCS-R": "SCS + RĘCZNE",
|
||||||
|
"SCS-M": "SCS + MECH.",
|
||||||
|
"SPE": "SPE",
|
||||||
|
"manual": "RĘCZNE",
|
||||||
|
|
||||||
|
"SUP": "SUP (RASP-UZK)",
|
||||||
|
"noSUP": "BEZ SUP",
|
||||||
|
|
||||||
|
"SBL": "SAMOCZYNNA",
|
||||||
|
"PBL": "PÓŁSAMOCZYNNA",
|
||||||
|
|
||||||
|
"mechanical": "MECHANICZNE",
|
||||||
|
"modern": "WSPÓŁCZESNA",
|
||||||
|
"semaphores": "KSZTAŁTOWA",
|
||||||
|
"mixed": "MIESZANA",
|
||||||
|
"historical": "HISTORYCZNA",
|
||||||
|
|
||||||
|
"free": "WOLNA",
|
||||||
|
"occupied": "ZAJĘTA",
|
||||||
|
|
||||||
|
"sliders": {
|
||||||
|
"min-lvl": "MIN. WYMAGANY POZIOM DYŻURNEGO",
|
||||||
|
"max-lvl": "MAKS. WYMAGANY POZIOM DYŻURNEGO",
|
||||||
|
"routes-1t-cat": "SZLAKI JEDNOTOROWE ZELEKTR. (MINIMUM)",
|
||||||
|
"routes-1t-other": "SZLAKI JEDNOTOROWE NIEZELEKTR. (MINIMUM)",
|
||||||
|
"routes-2t-cat": "SZLAKI DWUTOROWE ZELEKTR. (MINIMUM)",
|
||||||
|
"routes-2t-other": "SZLAKI DWUTOROWE NIEZELEKTR. (MINIMUM)"
|
||||||
|
},
|
||||||
|
|
||||||
|
"authors-search": "Szukaj autora (uwzględnia inne filtry)",
|
||||||
|
"minimum-hours-title": "POKAŻ TYLKO SCENERIE DOSTĘPNE MINIMUM DO:",
|
||||||
|
"now": "TERAZ",
|
||||||
|
"hour": " godz.",
|
||||||
|
"no-limit": "BEZ LIMITU",
|
||||||
|
"include-selected": "POKAŻ ZAZNACZONE",
|
||||||
|
"save": "ZAPAMIĘTAJ FILTRY",
|
||||||
|
"reset": "RESETUJ FILTRY",
|
||||||
|
"close": "ZAMKNIJ FILTRY"
|
||||||
|
},
|
||||||
|
"sceneries": {
|
||||||
|
"station": "Stacja",
|
||||||
|
"abbr": "Skrót\nposterunku",
|
||||||
|
"min-lvl": "Min. poziom\ndyżurnego",
|
||||||
|
"status": "Status",
|
||||||
|
"dispatcher": "Dyżurny",
|
||||||
|
"dispatcher-lvl": "Poziom\ndyżurnego",
|
||||||
|
"routes": "Szlaki\n2tor / 1tor",
|
||||||
|
"general": "Informacje\nogólne",
|
||||||
|
"user": "Maszyniści online",
|
||||||
|
"spawn": "Otwarte spawny",
|
||||||
|
"timetableAll": "Aktywne rozkłady jazdy",
|
||||||
|
"timetableConfirmed": "Zatwierdzone rozkłady jazdy",
|
||||||
|
"timetableUnconfirmed": "Niezatwierdzone rozkłady jazdy",
|
||||||
|
"no-stations": "Brak stacji do wyświetlenia!",
|
||||||
|
"scenery-search": "Wyszukaj scenerię..."
|
||||||
|
},
|
||||||
|
"trains": {
|
||||||
|
"no-trains": "Brak pociągów do wyświetlenia!",
|
||||||
|
"loading": "Pobieranie danych o pociągach...",
|
||||||
|
"offline": "Przejazd offline",
|
||||||
|
|
||||||
|
"stats": "STATYSTYKI RUCHU",
|
||||||
|
"stats-speed": "PRĘDKOŚCI POCIĄGÓW (MIN, ŚR, MAX) [km/h]",
|
||||||
|
"stats-length": "DŁUGOŚCI ROZKŁADÓW (MIN, ŚR, MAX) [km]",
|
||||||
|
"stats-categories": "KATEGORIE RJ",
|
||||||
|
"stats-special-twr": "WYSOKIEGO RYZYKA",
|
||||||
|
"stats-special-skr": "PRZEKROCZONA SKRAJNIA",
|
||||||
|
"stats-locos": "NAJCZĘSTSZE JEDNOSTKI",
|
||||||
|
|
||||||
|
"current-scenery": "na scenerii",
|
||||||
|
"current-signal": "przy semaforze",
|
||||||
|
"current-track": "na szlaku",
|
||||||
|
|
||||||
|
"delayed": "Opóźniony: ",
|
||||||
|
"preponed": "Przed czasem: ",
|
||||||
|
"on-time": "Planowo",
|
||||||
|
|
||||||
|
"route-progress": "Postęp: ",
|
||||||
|
|
||||||
|
"detailed-timetable": "Szczegółowy rozkład jazdy pociągu ",
|
||||||
|
"via-title": "Przez: ",
|
||||||
|
"no-timetable": "brak rozkładu jazdy",
|
||||||
|
"distance-exceeded": "Uwaga! Z powodu wewnętrznego błędu serwera TD2, rozkłady jazdy o kilometrażu powyżej 200km mogą być niepoprawne!",
|
||||||
|
"cars": "Wagony",
|
||||||
|
"EZT": "EZT",
|
||||||
|
"SZT": "SZT",
|
||||||
|
"loco-electric": "Elektrowóz",
|
||||||
|
"loco-diesel": "Spalinowóz",
|
||||||
|
"timetable-comments": "Pociąg z uwagami eksploatacyjnymi",
|
||||||
|
"comment": "Uwagi eksploatacyjne dla: ",
|
||||||
|
"table-limit": "Dla płynności działania strony pokazanych jest tylko 10 pociągów zgodnie z wybranymi filtrami.",
|
||||||
|
|
||||||
|
"last-seen-now": "od niedawna",
|
||||||
|
"last-seen-min": "od minuty",
|
||||||
|
"last-seen-ago": "od {minutes} minut",
|
||||||
|
|
||||||
|
"scenery-offline": "Przejazd offline",
|
||||||
|
|
||||||
|
"timeout": "Wystąpił problem z aktualizacją rozkładów jazdy z SWDR"
|
||||||
|
},
|
||||||
|
"journal": {
|
||||||
|
"title": "HISTORIA DYŻURÓW",
|
||||||
|
"loading": "Ładowanie historii dyżurów...",
|
||||||
|
"no-history": "Brak historii dyżurów dla tej scenerii!",
|
||||||
|
"data-refreshed-at": "Dane odświeżone o",
|
||||||
|
|
||||||
|
"section-timetables": "ROZKŁADY JAZDY",
|
||||||
|
"section-dispatchers": "DYŻURNI",
|
||||||
|
|
||||||
|
"no-further-data": "Brak dalszych wyników dla podanych parametrów",
|
||||||
|
"loading-further-data": "Ładowanie...",
|
||||||
|
|
||||||
|
"online-since": "ONLINE OD",
|
||||||
|
"duty-lasted": "Dyżur trwał",
|
||||||
|
"hours": "{value} godz.",
|
||||||
|
"minutes": "{value} min.",
|
||||||
|
"seconds": "{value} sek.",
|
||||||
|
|
||||||
|
"route-length": "Kilometraż:",
|
||||||
|
"station-count": "Stacje:",
|
||||||
|
"dispatcher-name": "Autor",
|
||||||
|
"timetable-day": "Rozkład z dnia",
|
||||||
|
"timetable-active": "AKTYWNY",
|
||||||
|
"timetable-fulfilled": "WYPEŁNIONY",
|
||||||
|
"timetable-abandoned": "PORZUCONY",
|
||||||
|
|
||||||
|
"stock-info": "DODATKOWE INFORMACJE",
|
||||||
|
"stock-length": "Długość",
|
||||||
|
"stock-mass": "Masa",
|
||||||
|
"stock-max-speed": "Prędkość maks.",
|
||||||
|
|
||||||
|
"load-data": "Pobierz dalszą historię...",
|
||||||
|
|
||||||
|
"stats-title": "STATYSTYKI MASZYNISTY",
|
||||||
|
|
||||||
|
"last-seen-at": "Ostatnio widziany na: ",
|
||||||
|
"currently-at": "Obecnie na scenerii: ",
|
||||||
|
|
||||||
|
"stats-timetables": "ROZKŁADY JAZDY",
|
||||||
|
"stats-longest-timetable": "NAJDŁUŻSZY RJ",
|
||||||
|
"stats-avg-timetable": "ŚREDNIA DŁUGOŚĆ RJ",
|
||||||
|
"stats-distance": "DYSTANS",
|
||||||
|
"stats-stations": "STACJE",
|
||||||
|
|
||||||
|
"timetable-stats-total": "Stworzone rozkłady jazdy: {count} (łączny dystans: {distance})",
|
||||||
|
"timetable-stats-longest": "Najdłuższy rozkład jazdy: #{id} (stworzony przez dyżurnego {author} dla maszynisty {driver} o dystansie {distance})",
|
||||||
|
"timetable-stats-most-active-dr": "Najaktywniejszy dyżurny: {dispatcher} (stworzył {count})",
|
||||||
|
"timetable-stats-most-active-dr-many": "Najaktywniejsi dyżurni: {dispatchers} (stworzyli po {count})",
|
||||||
|
"timetable-stats-most-active-driver": "Najaktywniejszy maszynista: {driver} (łączny przejechany dystans: {distance})",
|
||||||
|
"timetable-stats-longest-duties": "Najdłuższa służba: {dispatcher} na scenerii {station} (czas trwania: {duration})",
|
||||||
|
|
||||||
|
"timetable-count": "rozkład jazdy | rozkładów jazdy",
|
||||||
|
|
||||||
|
"daily-stats-title": "STATYSTYKI DNIA",
|
||||||
|
"daily-stats-info": "Dzisiejsze statystyki nie są jeszcze dostępne!",
|
||||||
|
|
||||||
|
"driver-stats-title": "STATYSTYKI GRACZA",
|
||||||
|
"driver-stats-info": "Wpisz nazwę użytkownika w filtrach [F], aby zobaczyć jego statystyki maszynisty!",
|
||||||
|
|
||||||
|
"stats-loading": "Pobieranie statystyk...",
|
||||||
|
"stats-error": "Ups! Wystąpił błąd podczas próby pobrania statystyk! :/",
|
||||||
|
|
||||||
|
"timetable-location-signal": "semafor:",
|
||||||
|
"timetable-location-route": "szlak:",
|
||||||
|
|
||||||
|
"history-name": "Sceneria",
|
||||||
|
"history-hash": "Hash",
|
||||||
|
"history-dispatcher": "Dyżurny",
|
||||||
|
"history-level": "Poziom",
|
||||||
|
"history-rate": "Ocena",
|
||||||
|
"history-region": "Region",
|
||||||
|
"history-date": "Data służby"
|
||||||
|
},
|
||||||
|
"scenery": {
|
||||||
|
"users": "GRACZE ONLINE",
|
||||||
|
"spawns": "OTWARTE SPAWNY",
|
||||||
|
"timetables": "AKTYWNE ROZKŁADY JAZDY",
|
||||||
|
"no-timetables": "Brak aktywnych rozkładów!",
|
||||||
|
"offline": "Sceneria jest offline",
|
||||||
|
"no-users": "BRAK AKTYWNYCH GRACZY",
|
||||||
|
"no-spawns": "BRAK OTWARTYCH SPAWNÓW",
|
||||||
|
"no-scenery": "Ups! Ta sceneria nie istnieje!",
|
||||||
|
"return-btn": "Wróć na stronę główną",
|
||||||
|
"history-btn": "Przejdź do widoku historii dyżurnych ruchu",
|
||||||
|
"info-btn": "Wróć do widoku scenerii",
|
||||||
|
"authors-title": "Autor scenerii | Autorzy scenerii",
|
||||||
|
"abbrev": "Skrót posterunku:",
|
||||||
|
"lines-title": "Rzeczywiste linie",
|
||||||
|
"project-title": "Projekt",
|
||||||
|
"one-way-routes": "Szlaki jednotorowe",
|
||||||
|
"two-way-routes": "Szlaki dwutorowe",
|
||||||
|
|
||||||
|
"option-active-timetables": "Aktywne rozkłady jazdy",
|
||||||
|
"option-timetables-history": "Historia rozkładów",
|
||||||
|
"option-dispatchers-history": "Historia dyżurów",
|
||||||
|
|
||||||
|
"timetable-author-title": "Wydany przez",
|
||||||
|
"timetable-author-unknown": "Autor nieznany",
|
||||||
|
|
||||||
|
"timetables-history-id": "ID",
|
||||||
|
"timetables-history-number": "Numer",
|
||||||
|
"timetables-history-route": "Trasa",
|
||||||
|
"timetables-history-driver": "Maszynista",
|
||||||
|
"timetables-history-author": "Autor RJ",
|
||||||
|
"timetables-history-date": "Data",
|
||||||
|
|
||||||
|
"dispatchers-history-hash": "Hash",
|
||||||
|
"dispatchers-history-dispatcher": "Dyżurny",
|
||||||
|
"dispatchers-history-level": "Poziom",
|
||||||
|
"dispatchers-history-rate": "Ocena",
|
||||||
|
"dispatchers-history-date": "Data służby",
|
||||||
|
|
||||||
|
"req-level": "ogólnodostępna | minimum {lvl} poziom dyżurnego | minimum {lvl} poziom dyżurnego",
|
||||||
|
"history-list-empty": "Brak historii dla tej scenerii!",
|
||||||
|
|
||||||
|
"forum-topic": "Oficjalny wątek scenerii {name}",
|
||||||
|
|
||||||
|
"pragotron-link": "Paletowa tablica informacyjna (beta)",
|
||||||
|
"tablice-link": "Tablica informacyjna zbiorcza (autorstwa Thundo)",
|
||||||
|
|
||||||
|
"bottom-info": "Pokaż pełną historię w zakładce Dziennika"
|
||||||
|
},
|
||||||
|
"availability": {
|
||||||
|
"title": "Dostępność",
|
||||||
|
"default": "w paczce",
|
||||||
|
"nonDefault": "poza paczką",
|
||||||
|
"unavailable": "niedostępna",
|
||||||
|
"nonPublic": "niepubliczna",
|
||||||
|
"abandoned": "wycofana"
|
||||||
|
},
|
||||||
|
"timetables": {
|
||||||
|
"timetable-only": "Wyodrębnij rozkłady jazdy",
|
||||||
|
"end": "Koniec rozkładu jazdy",
|
||||||
|
"terminated": "Rozkład jazdy zakończony",
|
||||||
|
"begins": "ROZPOCZYNA\nBIEG",
|
||||||
|
"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": {
|
||||||
|
"title": "DZIENNIK ROZKŁADÓW JAZDY"
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-27
@@ -10,23 +10,13 @@
|
|||||||
"trains": "POCIĄGI",
|
"trains": "POCIĄGI",
|
||||||
"journal": "DZIENNIK",
|
"journal": "DZIENNIK",
|
||||||
"loading": "Pobieranie danych...",
|
"loading": "Pobieranie danych...",
|
||||||
"support": "Wspomóż projekt",
|
|
||||||
"error": "Wystąpił problem z załadowaniem danych!",
|
"error": "Wystąpił problem z załadowaniem danych!",
|
||||||
"no-result": "Brak wyników o podanych kryteriach!",
|
"no-result": "Brak wyników o podanych kryteriach!",
|
||||||
"migration-warning": "Usługi Stacjownika będą niedostępne w godzinach 1:00-3:00 2 czerwca 2022r. z powodu migracji hostingów API!",
|
|
||||||
"migration-confirm": "Przyjąłem!",
|
|
||||||
"offline": "Aplikacja w trybie offline!"
|
"offline": "Aplikacja w trybie offline!"
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"discord": "Serwer Discord Stacjownika"
|
"discord": "Serwer Discord Stacjownika"
|
||||||
},
|
},
|
||||||
"update": {
|
|
||||||
"title": "Nowa wersja Stacjownika jest dostępna!",
|
|
||||||
"paragraph1": "Miłego korzystania z aplikacji i niech S2 będzie z wami!",
|
|
||||||
"release-link": "Kliknij, aby przejrzeć listę zmian (GitHub)",
|
|
||||||
"confirm-button": "ZAKTUALIZUJ",
|
|
||||||
"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!",
|
||||||
@@ -38,17 +28,15 @@
|
|||||||
"S5-trains": "<b>Sygnał S5</b> <br> Błąd podczas pobierania danych o pociągach online!"
|
"S5-trains": "<b>Sygnał S5</b> <br> Błąd podczas pobierania danych o pociągach online!"
|
||||||
},
|
},
|
||||||
"desc": {
|
"desc": {
|
||||||
"control-type": "Sterowanie: ",
|
"control-type": "Sterowanie:",
|
||||||
"signals-type": "Sygnalizacja: ",
|
"signals-type": "Sygnalizacja:",
|
||||||
"SBL": "Sceneria posiada SBL na szlakach: ",
|
"SBL": "Sceneria posiada SBL na szlakach:",
|
||||||
"SUP": "Wymaga programu SUP do kontroli systemu RASP-UZK",
|
"SUP": "Wymaga programu SUP do kontroli systemu RASP-UZK",
|
||||||
"TWB-all": "Sceneria posiada blokadę dwukierunkową na wszystkich szlakach",
|
|
||||||
"TWB-routes": "Sceneria posiada blokadę dwukierunkową na szlakach: ",
|
|
||||||
"default": "Sceneria dostępna domyślnie w paczce z grą",
|
"default": "Sceneria dostępna domyślnie w paczce z grą",
|
||||||
"non-public": "Sceneria niepubliczna",
|
"non-public": "Sceneria niepubliczna",
|
||||||
"unavailable": "Sceneria niedostępna",
|
"unavailable": "Sceneria niedostępna",
|
||||||
"unknown": "Nieznana sceneria",
|
"unknown": "Nieznana sceneria",
|
||||||
"real": "Sceneria z realnymi liniami kolejowymi: ",
|
"real": "Sceneria z realnymi liniami kolejowymi:",
|
||||||
"abandoned": "Sceneria wycofana z rozgrywki"
|
"abandoned": "Sceneria wycofana z rozgrywki"
|
||||||
},
|
},
|
||||||
"signals": {
|
"signals": {
|
||||||
@@ -240,14 +228,6 @@
|
|||||||
"loading": "Pobieranie danych o pociągach...",
|
"loading": "Pobieranie danych o pociągach...",
|
||||||
"offline": "Przejazd offline",
|
"offline": "Przejazd offline",
|
||||||
|
|
||||||
"stats": "STATYSTYKI RUCHU",
|
|
||||||
"stats-speed": "PRĘDKOŚCI POCIĄGÓW (MIN, ŚR, MAX) [km/h]",
|
|
||||||
"stats-length": "DŁUGOŚCI ROZKŁADÓW (MIN, ŚR, MAX) [km]",
|
|
||||||
"stats-categories": "KATEGORIE RJ",
|
|
||||||
"stats-special-twr": "WYSOKIEGO RYZYKA",
|
|
||||||
"stats-special-skr": "PRZEKROCZONA SKRAJNIA",
|
|
||||||
"stats-locos": "NAJCZĘSTSZE JEDNOSTKI",
|
|
||||||
|
|
||||||
"current-scenery": "na scenerii",
|
"current-scenery": "na scenerii",
|
||||||
"current-signal": "przy semaforze",
|
"current-signal": "przy semaforze",
|
||||||
"current-track": "na szlaku",
|
"current-track": "na szlaku",
|
||||||
@@ -261,7 +241,6 @@
|
|||||||
"detailed-timetable": "Szczegółowy rozkład jazdy pociągu ",
|
"detailed-timetable": "Szczegółowy rozkład jazdy pociągu ",
|
||||||
"via-title": "Przez: ",
|
"via-title": "Przez: ",
|
||||||
"no-timetable": "brak rozkładu jazdy",
|
"no-timetable": "brak rozkładu jazdy",
|
||||||
"distance-exceeded": "Uwaga! Z powodu wewnętrznego błędu serwera TD2, rozkłady jazdy o kilometrażu powyżej 200km mogą być niepoprawne!",
|
|
||||||
"cars": "Wagony",
|
"cars": "Wagony",
|
||||||
"EZT": "EZT",
|
"EZT": "EZT",
|
||||||
"SZT": "SZT",
|
"SZT": "SZT",
|
||||||
@@ -269,7 +248,6 @@
|
|||||||
"loco-diesel": "Spalinowóz",
|
"loco-diesel": "Spalinowóz",
|
||||||
"timetable-comments": "Pociąg z uwagami eksploatacyjnymi",
|
"timetable-comments": "Pociąg z uwagami eksploatacyjnymi",
|
||||||
"comment": "Uwagi eksploatacyjne dla: ",
|
"comment": "Uwagi eksploatacyjne dla: ",
|
||||||
"table-limit": "Dla płynności działania strony pokazanych jest tylko 10 pociągów zgodnie z wybranymi filtrami.",
|
|
||||||
|
|
||||||
"last-seen-now": "od niedawna",
|
"last-seen-now": "od niedawna",
|
||||||
"last-seen-min": "od minuty",
|
"last-seen-min": "od minuty",
|
||||||
@@ -339,7 +317,7 @@
|
|||||||
"driver-stats-info": "Wpisz nazwę użytkownika w filtrach [F], aby zobaczyć jego statystyki maszynisty!",
|
"driver-stats-info": "Wpisz nazwę użytkownika w filtrach [F], aby zobaczyć jego statystyki maszynisty!",
|
||||||
|
|
||||||
"stats-loading": "Pobieranie statystyk...",
|
"stats-loading": "Pobieranie statystyk...",
|
||||||
"stats-error": "Ups! Wystąpił błąd podczas próby pobrania statystyk! :/",
|
"stats-error": "Ups! Wystąpił błąd podczas próby pobrania statystyk!",
|
||||||
|
|
||||||
"timetable-location-signal": "semafor:",
|
"timetable-location-signal": "semafor:",
|
||||||
"timetable-location-route": "szlak:",
|
"timetable-location-route": "szlak:",
|
||||||
|
|||||||
+3
-3
@@ -15,9 +15,9 @@ const i18n = createI18n({
|
|||||||
fallbackLocale: 'pl',
|
fallbackLocale: 'pl',
|
||||||
messages: {
|
messages: {
|
||||||
en: enLang,
|
en: enLang,
|
||||||
pl: plLang,
|
pl: plLang
|
||||||
},
|
},
|
||||||
enableLegacy: false,
|
enableLegacy: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const clickOutsideDirective: Directive = {
|
const clickOutsideDirective: Directive = {
|
||||||
@@ -29,7 +29,7 @@ const clickOutsideDirective: Directive = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener('click', el.clickOutsideEvent);
|
document.addEventListener('click', el.clickOutsideEvent);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
createApp(App)
|
createApp(App)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default defineComponent({
|
|||||||
month: '2-digit',
|
month: '2-digit',
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
hour: '2-digit',
|
hour: '2-digit',
|
||||||
minute: '2-digit',
|
minute: '2-digit'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ export default defineComponent({
|
|||||||
return new Date(dateString).toLocaleDateString(locale == 'pl' ? 'pl-PL' : 'en-GB', {
|
return new Date(dateString).toLocaleDateString(locale == 'pl' ? 'pl-PL' : 'en-GB', {
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
month: '2-digit',
|
month: '2-digit',
|
||||||
year: 'numeric',
|
year: 'numeric'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ export default defineComponent({
|
|||||||
localeTime(dateString: string, locale: string) {
|
localeTime(dateString: string, locale: string) {
|
||||||
return new Date(dateString).toLocaleTimeString(locale == 'pl' ? 'pl-PL' : 'en-GB', {
|
return new Date(dateString).toLocaleTimeString(locale == 'pl' ? 'pl-PL' : 'en-GB', {
|
||||||
hour: '2-digit',
|
hour: '2-digit',
|
||||||
minute: '2-digit',
|
minute: '2-digit'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ export default defineComponent({
|
|||||||
return (
|
return (
|
||||||
date?.toLocaleTimeString('pl-PL', {
|
date?.toLocaleTimeString('pl-PL', {
|
||||||
hour: '2-digit',
|
hour: '2-digit',
|
||||||
minute: '2-digit',
|
minute: '2-digit'
|
||||||
}) || ''
|
}) || ''
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -52,7 +52,7 @@ export default defineComponent({
|
|||||||
return timestamp
|
return timestamp
|
||||||
? new Date(timestamp).toLocaleTimeString('pl-PL', {
|
? new Date(timestamp).toLocaleTimeString('pl-PL', {
|
||||||
hour: '2-digit',
|
hour: '2-digit',
|
||||||
minute: '2-digit',
|
minute: '2-digit'
|
||||||
})
|
})
|
||||||
: '';
|
: '';
|
||||||
},
|
},
|
||||||
@@ -72,6 +72,6 @@ export default defineComponent({
|
|||||||
: showSeconds && secondsTotal <= 60
|
: showSeconds && secondsTotal <= 60
|
||||||
? this.$t('journal.seconds', { value: secondsTotal }, secondsTotal)
|
? this.$t('journal.seconds', { value: secondsTotal }, secondsTotal)
|
||||||
: this.$t('journal.minutes', { value: minsTotal }, minsTotal);
|
: this.$t('journal.minutes', { value: minsTotal }, minsTotal);
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getImage(name: string) {
|
getImage(name: string) {
|
||||||
return new URL(`../assets/${name}`, import.meta.url).href;
|
return new URL(`../assets/${name}`, import.meta.url).href;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { defineComponent } from 'vue';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
preventKeyDown: false,
|
preventKeyDown: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -20,7 +20,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
handleKeyDown(e: KeyboardEvent) {
|
handleKeyDown(e: KeyboardEvent) {
|
||||||
if (!e.key) return;
|
if (!e.key) return;
|
||||||
if (e.key.toLowerCase() == 'f' && !this.preventKeyDown && !e.ctrlKey && !e.altKey) this.onKeyDownFunction();
|
if (e.key.toLowerCase() == 'f' && !this.preventKeyDown && !e.ctrlKey && !e.altKey)
|
||||||
},
|
this.onKeyDownFunction();
|
||||||
},
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,16 +3,19 @@ import { defineComponent } from 'vue';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data: () => ({
|
data: () => ({
|
||||||
observer: null as IntersectionObserver | null,
|
observer: null as IntersectionObserver | null,
|
||||||
observerTarget: null as Element | null,
|
observerTarget: null as Element | null
|
||||||
}),
|
}),
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
mountObserver(actionFunction: () => void, target: Element) {
|
mountObserver(actionFunction: () => void, target: Element) {
|
||||||
this.observer = new IntersectionObserver((entries) => {
|
this.observer = new IntersectionObserver(
|
||||||
console.log(entries);
|
(entries) => {
|
||||||
|
console.log(entries);
|
||||||
|
|
||||||
if (entries[0].intersectionRatio > 0.5) actionFunction();
|
if (entries[0].intersectionRatio > 0.5) actionFunction();
|
||||||
}, { threshold: 0.2 });
|
},
|
||||||
|
{ threshold: 0.2 }
|
||||||
|
);
|
||||||
|
|
||||||
this.observer.observe(target);
|
this.observer.observe(target);
|
||||||
},
|
},
|
||||||
@@ -21,6 +24,6 @@ export default defineComponent({
|
|||||||
if (!this.observerTarget) return;
|
if (!this.observerTarget) return;
|
||||||
|
|
||||||
this.observer?.unobserve(this.observerTarget);
|
this.observer?.unobserve(this.observerTarget);
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { Ref, defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../store/store';
|
import { useStore } from '../store/store';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
store: useStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
chosenTrain() {
|
chosenTrain() {
|
||||||
return this.store.trainList.find((train) => train.trainId == this.store.chosenModalTrainId);
|
return this.store.trainList.find((train) => train.trainId == this.store.chosenModalTrainId);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -28,6 +28,6 @@ export default defineComponent({
|
|||||||
(this.store.modalLastClickedTarget as any)?.focus();
|
(this.store.modalLastClickedTarget as any)?.focus();
|
||||||
document.body.classList.remove('no-scroll');
|
document.body.classList.remove('no-scroll');
|
||||||
}, 150);
|
}, 150);
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { defineComponent, h } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import imageMixin from './imageMixin';
|
import imageMixin from './imageMixin';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -7,10 +7,10 @@ export default defineComponent({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
icons: {
|
icons: {
|
||||||
arrow: this.getIcon('arrow-asc'),
|
arrow: this.getIcon('arrow-asc')
|
||||||
},
|
},
|
||||||
|
|
||||||
showReturnButton: false,
|
showReturnButton: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
handleScroll() {
|
handleScroll() {
|
||||||
this.showReturnButton = window.scrollY > window.innerHeight * 0.35;
|
this.showReturnButton = window.scrollY > window.innerHeight * 0.35;
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
activated() {
|
activated() {
|
||||||
@@ -30,5 +30,5 @@ export default defineComponent({
|
|||||||
|
|
||||||
deactivated() {
|
deactivated() {
|
||||||
window.removeEventListener('wheel', this.handleScroll);
|
window.removeEventListener('wheel', this.handleScroll);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,12 +2,11 @@ import { defineComponent } from 'vue';
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
navigateTo(path: string, query?: {}) {
|
navigateTo(path: string, query?: {}) {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path,
|
path,
|
||||||
query,
|
query
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,25 +1,24 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
methods: {
|
methods: {
|
||||||
getControlTypeAbbrev(controlType: string) {
|
getControlTypeAbbrev(controlType: string) {
|
||||||
switch (controlType) {
|
switch (controlType) {
|
||||||
case 'mechaniczne':
|
case 'mechaniczne':
|
||||||
return 'M';
|
return 'M';
|
||||||
case 'SCS-SPK':
|
case 'SCS-SPK':
|
||||||
return 'S/S';
|
return 'S/S';
|
||||||
case 'ręczne':
|
case 'ręczne':
|
||||||
return 'R';
|
return 'R';
|
||||||
case 'mechaniczne+SPK':
|
case 'mechaniczne+SPK':
|
||||||
return 'M';
|
return 'M';
|
||||||
case 'ręczne+SPK':
|
case 'ręczne+SPK':
|
||||||
return 'R';
|
return 'R';
|
||||||
case 'mechaniczne+SCS':
|
case 'mechaniczne+SCS':
|
||||||
return 'M';
|
return 'M';
|
||||||
default:
|
default:
|
||||||
return controlType;
|
return controlType;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import { defineComponent } from 'vue';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
methods: {
|
methods: {
|
||||||
calculateExpStyle(exp: number, isSupporter = false): string {
|
calculateExpStyle(exp: number, isSupporter = false): string {
|
||||||
const bgColor = exp > -1 ? (exp < 2 ? '#26B0D9' : `hsl(${-exp * 5 + 100}, 85%, 50%)`) : '#666';
|
const bgColor =
|
||||||
|
exp > -1 ? (exp < 2 ? '#26B0D9' : `hsl(${-exp * 5 + 100}, 85%, 50%)`) : '#666';
|
||||||
|
|
||||||
const fontColor = exp > 14 || exp == -1 ? 'white' : 'black';
|
const fontColor = exp > 14 || exp == -1 ? 'white' : 'black';
|
||||||
const boxShadow = isSupporter ? `box-shadow: 0 0 6px 2px ${bgColor};` : '';
|
const boxShadow = isSupporter ? `box-shadow: 0 0 6px 2px ${bgColor};` : '';
|
||||||
@@ -12,7 +13,8 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
calculateTextExpStyle(exp: number, isSupporter = false): string {
|
calculateTextExpStyle(exp: number, isSupporter = false): string {
|
||||||
const textColor = exp > -1 ? (exp < 2 ? '#26B0D9' : `hsl(${-exp * 5 + 100}, 75%, 50%)`) : '#666';
|
const textColor =
|
||||||
|
exp > -1 ? (exp < 2 ? '#26B0D9' : `hsl(${-exp * 5 + 100}, 75%, 50%)`) : '#666';
|
||||||
|
|
||||||
return `color: ${textColor}; ${isSupporter ? 'text-shadow: 0 0 6px ' + textColor : ''};`;
|
return `color: ${textColor}; ${isSupporter ? 'text-shadow: 0 0 6px ' + textColor : ''};`;
|
||||||
},
|
},
|
||||||
@@ -47,6 +49,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return className;
|
return className;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,39 +11,39 @@ export default defineComponent({
|
|||||||
main: [
|
main: [
|
||||||
{
|
{
|
||||||
name: 'speed',
|
name: 'speed',
|
||||||
unit: 'km/h',
|
unit: 'km/h'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'length',
|
name: 'length',
|
||||||
unit: 'm',
|
unit: 'm'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'mass',
|
name: 'mass',
|
||||||
unit: 't',
|
unit: 't',
|
||||||
multiplier: 0.001,
|
multiplier: 0.001
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
position: [
|
position: [
|
||||||
{
|
{
|
||||||
name: 'scenery',
|
name: 'scenery',
|
||||||
prop: 'currentStationName',
|
prop: 'currentStationName'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'route',
|
name: 'route',
|
||||||
prop: 'connectedTrack',
|
prop: 'connectedTrack'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'signal',
|
name: 'signal',
|
||||||
prop: 'signal',
|
prop: 'signal'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'distance',
|
name: 'distance',
|
||||||
prop: 'distance',
|
prop: 'distance',
|
||||||
unit: 'm',
|
unit: 'm'
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -64,11 +64,15 @@ export default defineComponent({
|
|||||||
positionString += this.$t('trains.current-scenery') + ' ';
|
positionString += this.$t('trains.current-scenery') + ' ';
|
||||||
|
|
||||||
if (train.currentStationHash) positionString += train.currentStationName + ' ';
|
if (train.currentStationHash) positionString += train.currentStationName + ' ';
|
||||||
else positionString += train['currentStationName'].replace(/.[a-zA-Z0-9]+.sc/, '') + ' (offline) ';
|
else
|
||||||
|
positionString +=
|
||||||
|
train['currentStationName'].replace(/.[a-zA-Z0-9]+.sc/, '') + ' (offline) ';
|
||||||
|
|
||||||
if (train.signal) positionString += this.$t('trains.current-signal') + ' ' + train.signal + ' ';
|
if (train.signal)
|
||||||
|
positionString += this.$t('trains.current-signal') + ' ' + train.signal + ' ';
|
||||||
|
|
||||||
if (train.connectedTrack) positionString += this.$t('trains.current-track') + ' ' + train.connectedTrack + ' ';
|
if (train.connectedTrack)
|
||||||
|
positionString += this.$t('trains.current-track') + ' ' + train.connectedTrack + ' ';
|
||||||
|
|
||||||
if (train.distance) positionString += `(${this.displayDistance(train.distance)})`;
|
if (train.distance) positionString += `(${this.displayDistance(train.distance)})`;
|
||||||
|
|
||||||
@@ -81,9 +85,17 @@ export default defineComponent({
|
|||||||
return stops
|
return stops
|
||||||
.reduce((acc: string[], stop: TrainStop, i: number) => {
|
.reduce((acc: string[], stop: TrainStop, i: number) => {
|
||||||
if (stop.stopType.includes('ph') && !stop.stopNameRAW.includes('po.'))
|
if (stop.stopType.includes('ph') && !stop.stopNameRAW.includes('po.'))
|
||||||
acc.push(`<strong style='color:${stop.confirmed ? 'springgreen' : 'white'}'>${stop.stopName}</strong>`);
|
acc.push(
|
||||||
|
`<strong style='color:${stop.confirmed ? 'springgreen' : 'white'}'>${
|
||||||
|
stop.stopName
|
||||||
|
}</strong>`
|
||||||
|
);
|
||||||
else if (i > 0 && i < stops.length - 1 && !/po\.|sbl/gi.test(stop.stopNameRAW))
|
else if (i > 0 && i < stops.length - 1 && !/po\.|sbl/gi.test(stop.stopNameRAW))
|
||||||
acc.push(`<span style='color:${stop.confirmed ? 'springgreen' : 'lightgray'}'>${stop.stopName}</span>`);
|
acc.push(
|
||||||
|
`<span style='color:${stop.confirmed ? 'springgreen' : 'lightgray'}'>${
|
||||||
|
stop.stopName
|
||||||
|
}</span>`
|
||||||
|
);
|
||||||
return acc;
|
return acc;
|
||||||
}, [])
|
}, [])
|
||||||
.join(' > ');
|
.join(' > ');
|
||||||
@@ -94,16 +106,22 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
confirmedPercentage(stops: TrainStop[]) {
|
confirmedPercentage(stops: TrainStop[]) {
|
||||||
return Number(((stops.filter((stop) => stop.confirmed).length / stops.length) * 100).toFixed(0));
|
return Number(
|
||||||
|
((stops.filter((stop) => stop.confirmed).length / stops.length) * 100).toFixed(0)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
currentDelay(stops: TrainStop[]) {
|
currentDelay(stops: TrainStop[]) {
|
||||||
const delay =
|
const delay =
|
||||||
stops.find((stop, i) => (i == 0 && !stop.confirmed) || (i > 0 && stops[i - 1].confirmed && !stop.confirmed))
|
stops.find(
|
||||||
?.departureDelay || 0;
|
(stop, i) =>
|
||||||
|
(i == 0 && !stop.confirmed) || (i > 0 && stops[i - 1].confirmed && !stop.confirmed)
|
||||||
|
)?.departureDelay || 0;
|
||||||
|
|
||||||
if (delay > 0) return `<span style='color: salmon'>${this.$t('trains.delayed')} ${delay} min</span>`;
|
if (delay > 0)
|
||||||
else if (delay < 0) return `<span style='color: lightgreen'>${this.$t('trains.preponed')} ${delay} min</span>`;
|
return `<span style='color: salmon'>${this.$t('trains.delayed')} ${delay} min</span>`;
|
||||||
|
else if (delay < 0)
|
||||||
|
return `<span style='color: lightgreen'>${this.$t('trains.preponed')} ${delay} min</span>`;
|
||||||
else return this.$t('trains.on-time');
|
else return this.$t('trains.on-time');
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -118,7 +136,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
getSceneriesWithComments(timetableData: Train['timetableData']) {
|
getSceneriesWithComments(timetableData: Train['timetableData']) {
|
||||||
const commentList =
|
const commentList =
|
||||||
timetableData?.followingStops.reduce((acc, stop, i) => {
|
timetableData?.followingStops.reduce((acc, stop) => {
|
||||||
if (stop.comments) acc.push(stop.stopNameRAW);
|
if (stop.comments) acc.push(stop.stopNameRAW);
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
@@ -138,6 +156,6 @@ export default defineComponent({
|
|||||||
onImageError(e: Event) {
|
onImageError(e: Event) {
|
||||||
const imageEl = e.target as HTMLImageElement;
|
const imageEl = e.target as HTMLImageElement;
|
||||||
imageEl.src = this.getImage('unknown.png');
|
imageEl.src = this.getImage('unknown.png');
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import { useRegisterSW } from 'virtual:pwa-register/vue';
|
|||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const { needRefresh, updateServiceWorker, offlineReady } = useRegisterSW({
|
const { needRefresh, updateServiceWorker, offlineReady } = useRegisterSW({
|
||||||
immediate: true,
|
immediate: true
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
needRefresh,
|
needRefresh,
|
||||||
updateServiceWorker,
|
updateServiceWorker,
|
||||||
offlineReady,
|
offlineReady
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
+16
-9
@@ -6,18 +6,22 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'StationsView',
|
name: 'StationsView',
|
||||||
component: () => import('../views/StationsView.vue'),
|
component: () => import('../views/StationsView.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/trains',
|
path: '/trains',
|
||||||
name: 'TrainsView',
|
name: 'TrainsView',
|
||||||
component: () => import('../views/TrainsView.vue'),
|
component: () => import('../views/TrainsView.vue'),
|
||||||
props: (route) => ({ train: route.query.train, driver: route.query.driver, trainId: route.query.trainId }),
|
props: (route) => ({
|
||||||
|
train: route.query.train,
|
||||||
|
driver: route.query.driver,
|
||||||
|
trainId: route.query.trainId
|
||||||
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/scenery',
|
path: '/scenery',
|
||||||
name: 'SceneryView',
|
name: 'SceneryView',
|
||||||
component: () => import('../views/SceneryView.vue'),
|
component: () => import('../views/SceneryView.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/journal',
|
path: '/journal',
|
||||||
@@ -30,19 +34,22 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
props: (route) => ({
|
props: (route) => ({
|
||||||
trainNo: route.query.trainNo,
|
trainNo: route.query.trainNo,
|
||||||
driverName: route.query.driverName,
|
driverName: route.query.driverName,
|
||||||
timetableId: route.query.timetableId,
|
timetableId: route.query.timetableId
|
||||||
}),
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/journal/dispatchers',
|
path: '/journal/dispatchers',
|
||||||
name: 'JournalDispatchers',
|
name: 'JournalDispatchers',
|
||||||
component: JournalDispatchersVue,
|
component: JournalDispatchersVue,
|
||||||
props: (route) => ({ sceneryName: route.query.sceneryName, dispatcherName: route.query.dispatcherName }),
|
props: (route) => ({
|
||||||
|
sceneryName: route.query.sceneryName,
|
||||||
|
dispatcherName: route.query.dispatcherName
|
||||||
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/:catchAll(.*)',
|
path: '/:catchAll(.*)',
|
||||||
redirect: '/',
|
redirect: '/'
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
@@ -52,7 +59,7 @@ const router = createRouter({
|
|||||||
// if (from.name == 'SceneryView' && to.name == 'StationsView') return { el: `.last-selected`, top: 20 };
|
// if (from.name == 'SceneryView' && to.name == 'StationsView') return { el: `.last-selected`, top: 20 };
|
||||||
},
|
},
|
||||||
history: createWebHistory(),
|
history: createWebHistory(),
|
||||||
routes,
|
routes
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import Filter from "../../interfaces/Filter";
|
import Filter from '../../interfaces/Filter';
|
||||||
|
|
||||||
export const filterInitStates: Filter = {
|
export const filterInitStates: Filter = {
|
||||||
default: false,
|
default: false,
|
||||||
@@ -45,5 +45,5 @@ export const filterInitStates: Filter = {
|
|||||||
|
|
||||||
authors: '',
|
authors: '',
|
||||||
|
|
||||||
onlineFromHours: 0,
|
onlineFromHours: 0
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
export const headIds = ['station', 'min-lvl', 'status', 'dispatcher', 'dispatcher-lvl', 'routes', 'general'] as const;
|
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 const headIconsIds = [
|
||||||
|
'user',
|
||||||
|
'spawn',
|
||||||
|
'timetableAll',
|
||||||
|
'timetableUnconfirmed',
|
||||||
|
'timetableConfirmed'
|
||||||
|
] as const;
|
||||||
|
|
||||||
export type HeadIdsTypes = typeof headIds[number] | typeof headIconsIds[number];
|
export type HeadIdsTypes = (typeof headIds)[number] | (typeof headIconsIds)[number];
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ export const enum JournalFilterType {
|
|||||||
ALL = 'all',
|
ALL = 'all',
|
||||||
TWR = 'twr',
|
TWR = 'twr',
|
||||||
SKR = 'skr',
|
SKR = 'skr',
|
||||||
TWR_SKR = 'twr-skr',
|
TWR_SKR = 'twr-skr'
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum JournalFilterSection {
|
export enum JournalFilterSection {
|
||||||
TIMETABLE_STATUS = 'timetable-status',
|
TIMETABLE_STATUS = 'timetable-status',
|
||||||
TWRSKR = 'twrskr',
|
TWRSKR = 'twrskr'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ export enum TrainFilterSection {
|
|||||||
TRAIN_TYPE = 'TRAIN_TYPE',
|
TRAIN_TYPE = 'TRAIN_TYPE',
|
||||||
TIMETABLE_TYPE = 'TIMETABLE_TYPE',
|
TIMETABLE_TYPE = 'TIMETABLE_TYPE',
|
||||||
COMMENTS = 'COMMENTS',
|
COMMENTS = 'COMMENTS',
|
||||||
TIMETABLE = 'TIMETABLE',
|
TIMETABLE = 'TIMETABLE'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum TrainFilterType {
|
export const enum TrainFilterType {
|
||||||
@@ -17,5 +17,5 @@ export const enum TrainFilterType {
|
|||||||
freight = 'freight',
|
freight = 'freight',
|
||||||
other = 'other',
|
other = 'other',
|
||||||
noTimetable = 'noTimetable',
|
noTimetable = 'noTimetable',
|
||||||
withTimetable = 'withTimetable',
|
withTimetable = 'withTimetable'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export default interface FilterOption {
|
export default interface FilterOption {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
value: boolean;
|
value: boolean;
|
||||||
defaultValue: boolean;
|
defaultValue: boolean;
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,12 @@ interface Scenery {
|
|||||||
currentDispatcher: string;
|
currentDispatcher: string;
|
||||||
currentDispatcherId: number;
|
currentDispatcherId: number;
|
||||||
currentDispatcherFrom: number;
|
currentDispatcherFrom: number;
|
||||||
dispatcherHistory: { dispatcherName: string; dispatcherId: number; dispatcherFrom: number; dispatcherTo: number }[];
|
dispatcherHistory: {
|
||||||
|
dispatcherName: string;
|
||||||
|
dispatcherId: number;
|
||||||
|
dispatcherFrom: number;
|
||||||
|
dispatcherTo: number;
|
||||||
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Scenery;
|
export default Scenery;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export enum StopStatus {
|
|||||||
'departed-away' = 'departed-away',
|
'departed-away' = 'departed-away',
|
||||||
'online' = 'online',
|
'online' = 'online',
|
||||||
'stopped' = 'stopped',
|
'stopped' = 'stopped',
|
||||||
'terminated' = 'terminated',
|
'terminated' = 'terminated'
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ScheduledTrain {
|
export interface ScheduledTrain {
|
||||||
|
|||||||
@@ -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 {
|
||||||
@@ -13,7 +13,6 @@ export default interface Station {
|
|||||||
reqLevel: number;
|
reqLevel: number;
|
||||||
// supportersOnly: boolean;
|
// supportersOnly: boolean;
|
||||||
|
|
||||||
|
|
||||||
lines: string;
|
lines: string;
|
||||||
project: string;
|
project: string;
|
||||||
projectUrl?: string;
|
projectUrl?: string;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import TrainStop from "./TrainStop";
|
import TrainStop from './TrainStop';
|
||||||
|
|
||||||
export default interface Timetable {
|
export default interface Timetable {
|
||||||
trainNo: number;
|
trainNo: number;
|
||||||
@@ -19,5 +19,5 @@ export default interface Timetable {
|
|||||||
routeDistance: number;
|
routeDistance: number;
|
||||||
followingStops: TrainStop[];
|
followingStops: TrainStop[];
|
||||||
followingSceneries: string[];
|
followingSceneries: string[];
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { TrainFilterSection, TrainFilterType } from '../../enums/TrainFilterType'
|
import { TrainFilterSection, TrainFilterType } from '../../enums/TrainFilterType';
|
||||||
|
|
||||||
export interface TrainFilter {
|
export interface TrainFilter {
|
||||||
id: TrainFilterType;
|
id: TrainFilterType;
|
||||||
|
|||||||
@@ -49,4 +49,3 @@ export interface ITimetablesDailyStatsResponse {
|
|||||||
station: string;
|
station: string;
|
||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,13 +13,20 @@ function currentDelay(stops: TrainStop[] | undefined) {
|
|||||||
if (!stops) return -Infinity;
|
if (!stops) return -Infinity;
|
||||||
|
|
||||||
const delay =
|
const delay =
|
||||||
stops.find((stop, i) => (i == 0 && !stop.confirmed) || (i > 0 && stops[i - 1].confirmed && !stop.confirmed))
|
stops.find(
|
||||||
?.departureDelay || 0;
|
(stop, i) =>
|
||||||
|
(i == 0 && !stop.confirmed) || (i > 0 && stops[i - 1].confirmed && !stop.confirmed)
|
||||||
|
)?.departureDelay || 0;
|
||||||
|
|
||||||
return delay;
|
return delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterTrainList(trainList: Train[], searchedTrain: string, searchedDriver: string, filters: TrainFilter[]) {
|
function filterTrainList(
|
||||||
|
trainList: Train[],
|
||||||
|
searchedTrain: string,
|
||||||
|
searchedDriver: string,
|
||||||
|
filters: TrainFilter[]
|
||||||
|
) {
|
||||||
return trainList.filter((train) => {
|
return trainList.filter((train) => {
|
||||||
const isFiltered = filters.every((f) => {
|
const isFiltered = filters.every((f) => {
|
||||||
if (f.isActive) return true;
|
if (f.isActive) return true;
|
||||||
@@ -62,7 +69,9 @@ function filterTrainList(trainList: Train[], searchedTrain: string, searchedDriv
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
(searchedTrain.length > 0 ? train.trainNo.toString().startsWith(searchedTrain) : true) &&
|
(searchedTrain.length > 0 ? train.trainNo.toString().startsWith(searchedTrain) : true) &&
|
||||||
(searchedDriver.length > 0 ? train.driverName.toLowerCase().startsWith(searchedDriver.toLowerCase()) : true) &&
|
(searchedDriver.length > 0
|
||||||
|
? train.driverName.toLowerCase().startsWith(searchedDriver.toLowerCase())
|
||||||
|
: true) &&
|
||||||
(!train.timetableData ? train.online : train.timetableData) &&
|
(!train.timetableData ? train.online : train.timetableData) &&
|
||||||
isFiltered
|
isFiltered
|
||||||
);
|
);
|
||||||
@@ -73,7 +82,8 @@ function sortTrainList(trainList: Train[], sorterActive: { id: string; dir: numb
|
|||||||
return trainList.sort((a: Train, b: Train) => {
|
return trainList.sort((a: Train, b: Train) => {
|
||||||
switch (sorterActive.id) {
|
switch (sorterActive.id) {
|
||||||
case 'id':
|
case 'id':
|
||||||
if ((a.timetableData?.timetableId || -1) > (b.timetableData?.timetableId || -1)) return sorterActive.dir;
|
if ((a.timetableData?.timetableId || -1) > (b.timetableData?.timetableId || -1))
|
||||||
|
return sorterActive.dir;
|
||||||
|
|
||||||
return -sorterActive.dir;
|
return -sorterActive.dir;
|
||||||
|
|
||||||
@@ -82,18 +92,25 @@ function sortTrainList(trainList: Train[], sorterActive: { id: string; dir: numb
|
|||||||
return -sorterActive.dir;
|
return -sorterActive.dir;
|
||||||
|
|
||||||
case 'routeDistance':
|
case 'routeDistance':
|
||||||
if ((a.timetableData?.routeDistance || -1) > (b.timetableData?.routeDistance || -1)) return sorterActive.dir;
|
if ((a.timetableData?.routeDistance || -1) > (b.timetableData?.routeDistance || -1))
|
||||||
|
return sorterActive.dir;
|
||||||
|
|
||||||
return -sorterActive.dir;
|
return -sorterActive.dir;
|
||||||
|
|
||||||
case 'progress':
|
case 'progress':
|
||||||
if (confirmedPercentage(a.timetableData?.followingStops) > confirmedPercentage(b.timetableData?.followingStops))
|
if (
|
||||||
|
confirmedPercentage(a.timetableData?.followingStops) >
|
||||||
|
confirmedPercentage(b.timetableData?.followingStops)
|
||||||
|
)
|
||||||
return sorterActive.dir;
|
return sorterActive.dir;
|
||||||
|
|
||||||
return -sorterActive.dir;
|
return -sorterActive.dir;
|
||||||
|
|
||||||
case 'delay':
|
case 'delay':
|
||||||
if (currentDelay(a.timetableData?.followingStops) > currentDelay(b.timetableData?.followingStops))
|
if (
|
||||||
|
currentDelay(a.timetableData?.followingStops) >
|
||||||
|
currentDelay(b.timetableData?.followingStops)
|
||||||
|
)
|
||||||
return sorterActive.dir;
|
return sorterActive.dir;
|
||||||
|
|
||||||
return -sorterActive.dir;
|
return -sorterActive.dir;
|
||||||
|
|||||||
@@ -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:3001'
|
? 'http://localhost:3001'
|
||||||
: 'https://stacjownik.spythere.pl',
|
: 'https://stacjownik.spythere.pl',
|
||||||
stacjownikAPIDev: 'localhost:3000',
|
stacjownikAPIDev: 'localhost:3000'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ import { HeadIdsTypes } from '../data/stationHeaderNames';
|
|||||||
import Filter from '../interfaces/Filter';
|
import Filter from '../interfaces/Filter';
|
||||||
import Station from '../interfaces/Station';
|
import Station from '../interfaces/Station';
|
||||||
|
|
||||||
export const sortStations = (a: Station, b: Station, sorter: { headerName: HeadIdsTypes; dir: number }) => {
|
export const sortStations = (
|
||||||
|
a: Station,
|
||||||
|
b: Station,
|
||||||
|
sorter: { headerName: HeadIdsTypes; dir: number }
|
||||||
|
) => {
|
||||||
let diff = 0;
|
let diff = 0;
|
||||||
|
|
||||||
switch (sorter.headerName) {
|
switch (sorter.headerName) {
|
||||||
@@ -18,9 +22,15 @@ export const sortStations = (a: Station, b: Station, sorter: { headerName: HeadI
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'dispatcher':
|
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;
|
||||||
|
|
||||||
@@ -29,11 +39,15 @@ export const sortStations = (a: Station, b: Station, sorter: { headerName: HeadI
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'user':
|
case 'user':
|
||||||
diff = (b.onlineInfo ? b.onlineInfo.currentUsers : -1) - (a.onlineInfo ? a.onlineInfo.currentUsers : -1);
|
diff =
|
||||||
|
(b.onlineInfo ? b.onlineInfo.currentUsers : -1) -
|
||||||
|
(a.onlineInfo ? a.onlineInfo.currentUsers : -1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'spawn':
|
case 'spawn':
|
||||||
diff = (a.onlineInfo ? a.onlineInfo.spawns.length : -1) - (b.onlineInfo ? b.onlineInfo.spawns.length : -1);
|
diff =
|
||||||
|
(a.onlineInfo ? a.onlineInfo.spawns.length : -1) -
|
||||||
|
(b.onlineInfo ? b.onlineInfo.spawns.length : -1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'timetableConfirmed':
|
case 'timetableConfirmed':
|
||||||
@@ -77,7 +91,8 @@ export const filterStations = (station: Station, filters: Filter) => {
|
|||||||
const { statusID, statusTimestamp } = station.onlineInfo;
|
const { statusID, statusTimestamp } = station.onlineInfo;
|
||||||
|
|
||||||
const isEnding = statusID == 'ending' && filters['endingStatus'];
|
const isEnding = statusID == 'ending' && filters['endingStatus'];
|
||||||
const isNotSigned = (statusID == 'not-signed' || statusID == 'unavailable') && filters['unavailableStatus'];
|
const isNotSigned =
|
||||||
|
(statusID == 'not-signed' || statusID == 'unavailable') && filters['unavailableStatus'];
|
||||||
const isAFK = statusID == 'brb' && filters['afkStatus'];
|
const isAFK = statusID == 'brb' && filters['afkStatus'];
|
||||||
const isNoSpace = statusID == 'no-space' && filters['noSpaceStatus'];
|
const isNoSpace = statusID == 'no-space' && filters['noSpaceStatus'];
|
||||||
const isOccupied = station.onlineInfo && filters['occupied'];
|
const isOccupied = station.onlineInfo && filters['occupied'];
|
||||||
@@ -89,15 +104,22 @@ export const filterStations = (station: Station, filters: Filter) => {
|
|||||||
(filters['onlineFromHours'] > 0 && statusTimestamp <= 0) ||
|
(filters['onlineFromHours'] > 0 && statusTimestamp <= 0) ||
|
||||||
(filters['onlineFromHours'] == 8 && statusID != 'no-limit');
|
(filters['onlineFromHours'] == 8 && statusID != 'no-limit');
|
||||||
|
|
||||||
if (isEnding || isOnlineInBounds || isNotSigned || isAFK || isNoSpace || isOccupied) return false;
|
if (isEnding || isOnlineInBounds || isNotSigned || isAFK || isNoSpace || isOccupied)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((station.generalInfo?.availability == 'nonPublic' || !station.generalInfo) && filters['nonPublic']) return false;
|
if (
|
||||||
|
(station.generalInfo?.availability == 'nonPublic' || !station.generalInfo) &&
|
||||||
|
filters['nonPublic']
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (station.generalInfo) {
|
if (station.generalInfo) {
|
||||||
const { routes, availability, controlType, lines, reqLevel, signalType, SUP, authors } = station.generalInfo;
|
const { routes, availability, controlType, lines, reqLevel, signalType, SUP, authors } =
|
||||||
|
station.generalInfo;
|
||||||
|
|
||||||
if (availability == 'unavailable' && filters['unavailable'] && !station.onlineInfo) return false;
|
if (availability == 'unavailable' && filters['unavailable'] && !station.onlineInfo)
|
||||||
|
return false;
|
||||||
if (availability == 'abandoned' && filters['abandoned'] && !station.onlineInfo) return false;
|
if (availability == 'abandoned' && filters['abandoned'] && !station.onlineInfo) return false;
|
||||||
if (availability == 'default' && filters['default']) return false;
|
if (availability == 'default' && filters['default']) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ 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';
|
||||||
|
|
||||||
export const getLocoURL = (locoType: string): string => `https://rj.td2.info.pl/dist/img/thumbnails/${locoType.includes('EN') ? locoType + 'rb' : locoType}.png`;
|
export const getLocoURL = (locoType: string): string =>
|
||||||
|
`https://rj.td2.info.pl/dist/img/thumbnails/${
|
||||||
|
locoType.includes('EN') ? locoType + 'rb' : locoType
|
||||||
|
}.png`;
|
||||||
|
|
||||||
export const getStatusID = (stationStatus: any): string => {
|
export const getStatusID = (stationStatus: any): string => {
|
||||||
if (!stationStatus) return 'unknown';
|
if (!stationStatus) return 'unknown';
|
||||||
@@ -73,7 +76,11 @@ export const parseSpawns = (spawnString: string | null) => {
|
|||||||
|
|
||||||
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 = StopStatus['arriving'],
|
let stopStatus = StopStatus['arriving'],
|
||||||
stopLabel = '',
|
stopLabel = '',
|
||||||
stopStatusID = -1;
|
stopStatusID = -1;
|
||||||
@@ -107,7 +114,11 @@ export const getTrainStopStatus = (stopInfo: TrainStop, currentStationName: stri
|
|||||||
return { stopStatus, stopLabel, stopStatusID };
|
return { stopStatus, stopLabel, stopStatusID };
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getScheduledTrain(train: Train, trainStopIndex: number, stationName: string): ScheduledTrain {
|
export function getScheduledTrain(
|
||||||
|
train: Train,
|
||||||
|
trainStopIndex: number,
|
||||||
|
stationName: string
|
||||||
|
): ScheduledTrain {
|
||||||
const timetable = train.timetableData!;
|
const timetable = train.timetableData!;
|
||||||
const followingStops = timetable.followingStops;
|
const followingStops = timetable.followingStops;
|
||||||
const trainStop = followingStops[trainStopIndex];
|
const trainStop = followingStops[trainStopIndex];
|
||||||
@@ -192,6 +203,6 @@ export function getScheduledTrain(train: Train, trainStopIndex: number, stationN
|
|||||||
departureLine,
|
departureLine,
|
||||||
|
|
||||||
nextArrivalLine,
|
nextArrivalLine,
|
||||||
prevDepartureLine,
|
prevDepartureLine
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', {
|
|||||||
filters: { ...filterInitStates },
|
filters: { ...filterInitStates },
|
||||||
sorterActive: { headerName: 'station' as HeadIdsTypes, dir: 1 },
|
sorterActive: { headerName: 'station' as HeadIdsTypes, dir: 1 },
|
||||||
store: useStore(),
|
store: useStore(),
|
||||||
lastClickedFilterId: '',
|
lastClickedFilterId: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
areFiltersAtDefault(state) {
|
areFiltersAtDefault(state) {
|
||||||
return Object.keys(state.filters).every((f) => state.filters[f] === filterInitStates[f]);
|
return Object.keys(state.filters).every((f) => state.filters[f] === filterInitStates[f]);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@@ -58,26 +58,6 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Quick actions (TODO)
|
|
||||||
handleQuickAction(actionName: string) {
|
|
||||||
// switch (actionName) {
|
|
||||||
// case 'all-available':
|
|
||||||
// this.resetFilters();
|
|
||||||
// this.inputs.options
|
|
||||||
// .filter((option) => /^(free|non-public)/.test(option.id))
|
|
||||||
// .forEach((option) => (option.value = !option.defaultValue));
|
|
||||||
// break;
|
|
||||||
// case 'all-free':
|
|
||||||
// this.resetFilters();
|
|
||||||
// this.inputs.options
|
|
||||||
// .filter((option) => /^(free|occupied)/.test(option.id))
|
|
||||||
// .forEach((option) => (option.value = !option.defaultValue));
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
|
|
||||||
changeFilterValue(name: string, value: any) {
|
changeFilterValue(name: string, value: any) {
|
||||||
this.filters[name] = value;
|
this.filters[name] = value;
|
||||||
if (StorageManager.isRegistered('options_saved')) StorageManager.setValue(name, value);
|
if (StorageManager.isRegistered('options_saved')) StorageManager.setValue(name, value);
|
||||||
@@ -107,10 +87,11 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
changeSorter(headerName: HeadIdsTypes) {
|
changeSorter(headerName: HeadIdsTypes) {
|
||||||
if (headerName == this.sorterActive.headerName) this.sorterActive.dir = -1 * this.sorterActive.dir;
|
if (headerName == this.sorterActive.headerName)
|
||||||
|
this.sorterActive.dir = -1 * this.sorterActive.dir;
|
||||||
else this.sorterActive.dir = 1;
|
else this.sorterActive.dir = 1;
|
||||||
|
|
||||||
this.sorterActive.headerName = headerName;
|
this.sorterActive.headerName = headerName;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+105
-37
@@ -8,10 +8,15 @@ 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';
|
||||||
import { URLs } from '../scripts/utils/apiURLs';
|
import { URLs } from '../scripts/utils/apiURLs';
|
||||||
import { getStatusTimestamp, getStatusID, getScheduledTrain, parseSpawns } from '../scripts/utils/storeUtils';
|
import {
|
||||||
|
getStatusTimestamp,
|
||||||
|
getStatusID,
|
||||||
|
getScheduledTrain,
|
||||||
|
parseSpawns
|
||||||
|
} from '../scripts/utils/storeUtils';
|
||||||
import { APIData, StationJSONData, StoreState } from '../scripts/interfaces/store/storeTypes';
|
import { APIData, StationJSONData, StoreState } from '../scripts/interfaces/store/storeTypes';
|
||||||
import packageInfo from '../../package.json';
|
import packageInfo from '../../package.json';
|
||||||
import { RollingStockInfo, RollingStockGithubData } from '../scripts/interfaces/github_api/StockInfoGithubData';
|
import { RollingStockGithubData } from '../scripts/interfaces/github_api/StockInfoGithubData';
|
||||||
|
|
||||||
export const useStore = defineStore('store', {
|
export const useStore = defineStore('store', {
|
||||||
state: () =>
|
state: () =>
|
||||||
@@ -48,15 +53,15 @@ export const useStore = defineStore('store', {
|
|||||||
sceneries: DataStatus.Loading,
|
sceneries: DataStatus.Loading,
|
||||||
timetables: DataStatus.Loading,
|
timetables: DataStatus.Loading,
|
||||||
dispatchers: DataStatus.Loading,
|
dispatchers: DataStatus.Loading,
|
||||||
trains: DataStatus.Loading,
|
trains: DataStatus.Loading
|
||||||
},
|
},
|
||||||
|
|
||||||
currentStatsTab: null,
|
currentStatsTab: null,
|
||||||
|
|
||||||
blockScroll: false,
|
blockScroll: false,
|
||||||
listenerLaunched: false,
|
listenerLaunched: false,
|
||||||
modalLastClickedTarget: null,
|
modalLastClickedTarget: null
|
||||||
} as StoreState),
|
}) as StoreState,
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
setTrainsOnlineData() {
|
setTrainsOnlineData() {
|
||||||
@@ -65,7 +70,11 @@ export const useStore = defineStore('store', {
|
|||||||
if (!trains) return [];
|
if (!trains) return [];
|
||||||
|
|
||||||
this.trainList = trains
|
this.trainList = trains
|
||||||
.filter((train) => train.region === this.region.id && (train.online || train.timetable || train.lastSeen > Date.now() - 180000))
|
.filter(
|
||||||
|
(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;
|
||||||
@@ -107,9 +116,9 @@ export const useStore = defineStore('store', {
|
|||||||
category: timetable.category,
|
category: timetable.category,
|
||||||
followingStops: timetable.stopList,
|
followingStops: timetable.stopList,
|
||||||
routeDistance: timetable.stopList[timetable.stopList.length - 1].stopDistance,
|
routeDistance: timetable.stopList[timetable.stopList.length - 1].stopDistance,
|
||||||
sceneries: timetable.sceneries,
|
sceneries: timetable.sceneries
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined
|
||||||
} as Train;
|
} as Train;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -117,17 +126,30 @@ export const useStore = defineStore('store', {
|
|||||||
getDispatcherStatus(onlineStationData: StationAPIData) {
|
getDispatcherStatus(onlineStationData: StationAPIData) {
|
||||||
const { dispatchers } = this.apiData;
|
const { dispatchers } = this.apiData;
|
||||||
|
|
||||||
const prevDispatcherStatus = this.lastDispatcherStatuses.find((dispatcher) => dispatcher.hash === onlineStationData.stationHash);
|
const prevDispatcherStatus = this.lastDispatcherStatuses.find(
|
||||||
|
(dispatcher) => dispatcher.hash === onlineStationData.stationHash
|
||||||
|
);
|
||||||
|
|
||||||
const stationStatus = !dispatchers ? undefined : dispatchers.find((status: string[]) => status[0] == onlineStationData.stationHash && status[1] == this.region.id) || -1;
|
const stationStatus = !dispatchers
|
||||||
|
? undefined
|
||||||
|
: dispatchers.find(
|
||||||
|
(status: string[]) =>
|
||||||
|
status[0] == onlineStationData.stationHash && status[1] == this.region.id
|
||||||
|
) || -1;
|
||||||
|
|
||||||
const statusTimestamp = prevDispatcherStatus && !dispatchers ? prevDispatcherStatus.statusTimestamp : getStatusTimestamp(stationStatus);
|
const statusTimestamp =
|
||||||
const statusID = prevDispatcherStatus && !dispatchers ? prevDispatcherStatus.statusID : getStatusID(stationStatus);
|
prevDispatcherStatus && !dispatchers
|
||||||
|
? prevDispatcherStatus.statusTimestamp
|
||||||
|
: getStatusTimestamp(stationStatus);
|
||||||
|
const statusID =
|
||||||
|
prevDispatcherStatus && !dispatchers
|
||||||
|
? prevDispatcherStatus.statusID
|
||||||
|
: getStatusID(stationStatus);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hash: onlineStationData.stationHash,
|
hash: onlineStationData.stationHash,
|
||||||
statusID,
|
statusID,
|
||||||
statusTimestamp,
|
statusTimestamp
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -146,17 +168,34 @@ export const useStore = defineStore('store', {
|
|||||||
const stopName = stop.stopNameRAW.toLowerCase();
|
const stopName = stop.stopNameRAW.toLowerCase();
|
||||||
|
|
||||||
if (stationName === stopName) return true;
|
if (stationName === stopName) return true;
|
||||||
if (stopName.includes(stationName) && !stop.stopName.includes('po.') && !stop.stopName.includes('podg.')) return true;
|
if (
|
||||||
|
stopName.includes(stationName) &&
|
||||||
|
!stop.stopName.includes('po.') &&
|
||||||
|
!stop.stopName.includes('podg.')
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (stationName.includes(stopName) && !stop.stopName.includes('po.') && !stop.stopName.includes('podg.')) return true;
|
if (
|
||||||
|
stationName.includes(stopName) &&
|
||||||
|
!stop.stopName.includes('po.') &&
|
||||||
|
!stop.stopName.includes('podg.')
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (stopName.includes('podg.') && stopName.split(', podg.')[0] && stationName.includes(stopName.split(', podg.')[0])) return true;
|
if (
|
||||||
|
stopName.includes('podg.') &&
|
||||||
|
stopName.split(', podg.')[0] &&
|
||||||
|
stationName.includes(stopName.split(', podg.')[0])
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
stationGeneralInfo &&
|
stationGeneralInfo &&
|
||||||
stationGeneralInfo.checkpoints &&
|
stationGeneralInfo.checkpoints &&
|
||||||
stationGeneralInfo.checkpoints.length > 0 &&
|
stationGeneralInfo.checkpoints.length > 0 &&
|
||||||
stationGeneralInfo.checkpoints.some((cp) => cp.checkpointName.toLowerCase().includes(stop.stopNameRAW.toLowerCase()))
|
stationGeneralInfo.checkpoints.some((cp) =>
|
||||||
|
cp.checkpointName.toLowerCase().includes(stop.stopNameRAW.toLowerCase())
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -165,15 +204,25 @@ export const useStore = defineStore('store', {
|
|||||||
|
|
||||||
if (stopInfoIndex == -1) return acc;
|
if (stopInfoIndex == -1) return acc;
|
||||||
|
|
||||||
const scheduledStopTrain = getScheduledTrain(train, stopInfoIndex, stationAPIData.stationName);
|
const scheduledStopTrain = getScheduledTrain(
|
||||||
|
train,
|
||||||
|
stopInfoIndex,
|
||||||
|
stationAPIData.stationName
|
||||||
|
);
|
||||||
|
|
||||||
if (stationGeneralInfo?.checkpoints) {
|
if (stationGeneralInfo?.checkpoints) {
|
||||||
for (const checkpoint of stationGeneralInfo.checkpoints) {
|
for (const checkpoint of stationGeneralInfo.checkpoints) {
|
||||||
const index = timetable.followingStops.findIndex((stop) => stop.stopNameRAW.toLowerCase() == checkpoint.checkpointName.toLowerCase());
|
const index = timetable.followingStops.findIndex(
|
||||||
|
(stop) => stop.stopNameRAW.toLowerCase() == checkpoint.checkpointName.toLowerCase()
|
||||||
|
);
|
||||||
|
|
||||||
if (index == -1) continue;
|
if (index == -1) continue;
|
||||||
|
|
||||||
const scheduledCheckpointTrain = getScheduledTrain(train, index, stationAPIData.stationName);
|
const scheduledCheckpointTrain = getScheduledTrain(
|
||||||
|
train,
|
||||||
|
index,
|
||||||
|
stationAPIData.stationName
|
||||||
|
);
|
||||||
checkpoint.scheduledTrains.push(scheduledCheckpointTrain);
|
checkpoint.scheduledTrains.push(scheduledCheckpointTrain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,12 +234,17 @@ export const useStore = defineStore('store', {
|
|||||||
|
|
||||||
getStationTrains(stationAPIData: StationAPIData) {
|
getStationTrains(stationAPIData: StationAPIData) {
|
||||||
return this.trainList
|
return this.trainList
|
||||||
.filter((train) => train?.region === this.region.id && train.online && train.currentStationName === stationAPIData.stationName)
|
.filter(
|
||||||
|
(train) =>
|
||||||
|
train?.region === this.region.id &&
|
||||||
|
train.online &&
|
||||||
|
train.currentStationName === stationAPIData.stationName
|
||||||
|
)
|
||||||
.map((train) => ({
|
.map((train) => ({
|
||||||
driverName: train.driverName,
|
driverName: train.driverName,
|
||||||
driverId: train.driverId,
|
driverId: train.driverId,
|
||||||
trainNo: train.trainNo,
|
trainNo: train.trainNo,
|
||||||
trainId: train.trainId,
|
trainId: train.trainId
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -233,13 +287,13 @@ export const useStore = defineStore('store', {
|
|||||||
stationTrains,
|
stationTrains,
|
||||||
statusTimestamp: dispatcherStatus.statusTimestamp,
|
statusTimestamp: dispatcherStatus.statusTimestamp,
|
||||||
statusID: dispatcherStatus.statusID,
|
statusID: dispatcherStatus.statusID,
|
||||||
scheduledTrains,
|
scheduledTrains
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!station) {
|
if (!station) {
|
||||||
this.stationList.push({
|
this.stationList.push({
|
||||||
name: stationAPIData.stationName,
|
name: stationAPIData.stationName,
|
||||||
onlineInfo,
|
onlineInfo
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -258,7 +312,9 @@ export const useStore = defineStore('store', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async fetchStationsGeneralInfo() {
|
async fetchStationsGeneralInfo() {
|
||||||
const sceneryData: StationJSONData[] = await (await axios.get(`${URLs.stacjownikAPI}/api/getSceneries`)).data;
|
const sceneryData: StationJSONData[] = await (
|
||||||
|
await axios.get(`${URLs.stacjownikAPI}/api/getSceneries`)
|
||||||
|
).data;
|
||||||
|
|
||||||
if (!sceneryData) {
|
if (!sceneryData) {
|
||||||
this.dataStatuses.sceneries = DataStatus.Error;
|
this.dataStatuses.sceneries = DataStatus.Error;
|
||||||
@@ -275,7 +331,9 @@ export const useStore = defineStore('store', {
|
|||||||
routes:
|
routes:
|
||||||
scenery.routesInfo.reduce(
|
scenery.routesInfo.reduce(
|
||||||
(acc, route) => {
|
(acc, route) => {
|
||||||
const propName: keyof StationRoutes = `${route.routeTracks == 2 ? 'twoWay' : 'oneWay'}${route.isElectric ? '' : 'No'}CatenaryRouteNames`;
|
const propName: keyof StationRoutes = `${
|
||||||
|
route.routeTracks == 2 ? 'twoWay' : 'oneWay'
|
||||||
|
}${route.isElectric ? '' : 'No'}CatenaryRouteNames`;
|
||||||
|
|
||||||
acc[route.routeTracks == 2 ? 'twoWay' : 'oneWay'].push({
|
acc[route.routeTracks == 2 ? 'twoWay' : 'oneWay'].push({
|
||||||
name: route.routeName,
|
name: route.routeName,
|
||||||
@@ -285,7 +343,7 @@ export const useStore = defineStore('store', {
|
|||||||
isInternal: route.isInternal,
|
isInternal: route.isInternal,
|
||||||
tracks: route.routeTracks,
|
tracks: route.routeTracks,
|
||||||
length: route.routeLength,
|
length: route.routeLength,
|
||||||
speed: route.routeSpeed,
|
speed: route.routeSpeed
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!route.isInternal) acc[propName].push(route.routeName);
|
if (!route.isInternal) acc[propName].push(route.routeName);
|
||||||
@@ -301,11 +359,15 @@ export const useStore = defineStore('store', {
|
|||||||
oneWayCatenaryRouteNames: [],
|
oneWayCatenaryRouteNames: [],
|
||||||
oneWayNoCatenaryRouteNames: [],
|
oneWayNoCatenaryRouteNames: [],
|
||||||
twoWayCatenaryRouteNames: [],
|
twoWayCatenaryRouteNames: [],
|
||||||
twoWayNoCatenaryRouteNames: [],
|
twoWayNoCatenaryRouteNames: []
|
||||||
} as StationRoutes
|
} as StationRoutes
|
||||||
) || {},
|
) || {},
|
||||||
checkpoints: scenery.checkpoints ? scenery.checkpoints.split(';').map((sub) => ({ checkpointName: sub, scheduledTrains: [] })) : [],
|
checkpoints: scenery.checkpoints
|
||||||
},
|
? scenery.checkpoints
|
||||||
|
.split(';')
|
||||||
|
.map((sub) => ({ checkpointName: sub, scheduledTrains: [] }))
|
||||||
|
: []
|
||||||
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -327,11 +389,11 @@ export const useStore = defineStore('store', {
|
|||||||
rememberUpgrade: true,
|
rememberUpgrade: true,
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
extraHeaders: {
|
extraHeaders: {
|
||||||
version: packageInfo.version,
|
version: packageInfo.version
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('connect_error', (err) => {
|
socket.on('connect_error', () => {
|
||||||
this.dataStatuses.connection = DataStatus.Error;
|
this.dataStatuses.connection = DataStatus.Error;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -366,7 +428,11 @@ export const useStore = defineStore('store', {
|
|||||||
|
|
||||||
async fetchStockInfoData() {
|
async fetchStockInfoData() {
|
||||||
try {
|
try {
|
||||||
this.rollingStockData = (await axios.get<RollingStockGithubData>('https://raw.githubusercontent.com/Spythere/api/main/td2/data/stockInfo.json')).data;
|
this.rollingStockData = (
|
||||||
|
await axios.get<RollingStockGithubData>(
|
||||||
|
'https://raw.githubusercontent.com/Spythere/api/main/td2/data/stockInfo.json'
|
||||||
|
)
|
||||||
|
).data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ups! Wystąpił błąd podczas pobierania informacji o taborze z API:', error);
|
console.error('Ups! Wystąpił błąd podczas pobierania informacji o taborze z API:', error);
|
||||||
}
|
}
|
||||||
@@ -383,10 +449,12 @@ export const useStore = defineStore('store', {
|
|||||||
|
|
||||||
this.dataStatuses.sceneries = DataStatus.Loaded;
|
this.dataStatuses.sceneries = DataStatus.Loaded;
|
||||||
this.dataStatuses.trains = !this.apiData.trains ? DataStatus.Warning : DataStatus.Loaded;
|
this.dataStatuses.trains = !this.apiData.trains ? DataStatus.Warning : DataStatus.Loaded;
|
||||||
this.dataStatuses.dispatchers = !this.apiData.dispatchers ? DataStatus.Warning : DataStatus.Loaded;
|
this.dataStatuses.dispatchers = !this.apiData.dispatchers
|
||||||
|
? DataStatus.Warning
|
||||||
|
: DataStatus.Loaded;
|
||||||
|
|
||||||
this.setTrainsOnlineData();
|
this.setTrainsOnlineData();
|
||||||
this.setStationsOnlineInfo();
|
this.setStationsOnlineInfo();
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -47,4 +47,3 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+35
-36
@@ -1,41 +1,40 @@
|
|||||||
|
|
||||||
.option {
|
.option {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
display: none;
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
// user-select: none;
|
||||||
|
// -moz-user-select: none;
|
||||||
|
// -webkit-user-select: none;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
padding: 0.5em 0.55em;
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
border-radius: 0.5em;
|
||||||
|
|
||||||
|
&:not(.checked) {
|
||||||
|
background-color: #585858;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
span {
|
&:focus span {
|
||||||
// user-select: none;
|
// outline: 1px solid white;
|
||||||
// -moz-user-select: none;
|
border: none;
|
||||||
// -webkit-user-select: none;
|
}
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
padding: 0.5em 0.55em;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
transition: all 0.2s;
|
|
||||||
|
|
||||||
border-radius: 0.5em;
|
|
||||||
|
|
||||||
&:not(.checked) {
|
|
||||||
background-color: #585858;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus span {
|
|
||||||
// outline: 1px solid white;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin screenLandscape() {
|
@mixin screenLandscape() {
|
||||||
@media only screen and (orientation: landscape) and (max-device-height: 450px) {
|
@media only screen and (orientation: landscape) and (max-device-height: 450px) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="error-view">
|
|
||||||
<div class="container">
|
|
||||||
<img :src="getIcon('error')" alt="error" />
|
|
||||||
<div class="desc">Z powodu błędu w zapisywaniu rozkładów jazdy w tej zakładce można do odwołania nacieszyć się animacją sygnału S1a. Jak naprawię to będzie :)</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent } from "vue";
|
|
||||||
import imageMixin from "../mixins/imageMixin";
|
|
||||||
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
mixins: [imageMixin]
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.error-view {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
margin-top: 5em;
|
|
||||||
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
flex-direction: column;
|
|
||||||
max-width: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.desc {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 1.4em;
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 15em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -34,17 +34,15 @@
|
|||||||
import { defineComponent, provide, reactive, Ref, ref } from 'vue';
|
import { defineComponent, provide, reactive, Ref, ref } from 'vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
import ActionButton from '../components/Global/ActionButton.vue';
|
|
||||||
import JournalOptions from '../components/JournalView/JournalOptions.vue';
|
import JournalOptions from '../components/JournalView/JournalOptions.vue';
|
||||||
import DispatcherStats from '../components/JournalView/DispatcherStats.vue';
|
|
||||||
import SearchBox from '../components/Global/SearchBox.vue';
|
|
||||||
|
|
||||||
import Loading from '../components/Global/Loading.vue';
|
|
||||||
import { URLs } from '../scripts/utils/apiURLs';
|
import { URLs } from '../scripts/utils/apiURLs';
|
||||||
import { DataStatus } from '../scripts/enums/DataStatus';
|
import { DataStatus } from '../scripts/enums/DataStatus';
|
||||||
import { useStore } from '../store/store';
|
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 {
|
||||||
|
JournalDispatcherSearcher,
|
||||||
|
JournalDispatcherSorter
|
||||||
|
} from '../scripts/types/JournalDispatcherTypes';
|
||||||
import { DispatcherHistory } from '../scripts/interfaces/api/DispatchersAPIData';
|
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';
|
||||||
@@ -53,26 +51,22 @@ const DISPATCHERS_API_URL = `${URLs.stacjownikAPI}/api/getDispatchers`;
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
SearchBox,
|
|
||||||
ActionButton,
|
|
||||||
JournalOptions,
|
JournalOptions,
|
||||||
DispatcherStats,
|
|
||||||
Loading,
|
|
||||||
JournalDispatchersList,
|
JournalDispatchersList,
|
||||||
JournalHeader,
|
JournalHeader
|
||||||
},
|
},
|
||||||
name: 'JournalDispatchers',
|
name: 'JournalDispatchers',
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
sceneryName: {
|
sceneryName: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false
|
||||||
},
|
},
|
||||||
|
|
||||||
dispatcherName: {
|
dispatcherName: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
@@ -90,7 +84,7 @@ export default defineComponent({
|
|||||||
dataStatus: DataStatus.Loading,
|
dataStatus: DataStatus.Loading,
|
||||||
DataStatus,
|
DataStatus,
|
||||||
|
|
||||||
historyList: [] as DispatcherHistory[],
|
historyList: [] as DispatcherHistory[]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
@@ -100,7 +94,7 @@ export default defineComponent({
|
|||||||
const searchersValues = reactive({
|
const searchersValues = reactive({
|
||||||
'search-dispatcher': '',
|
'search-dispatcher': '',
|
||||||
'search-station': '',
|
'search-station': '',
|
||||||
'search-date': '',
|
'search-date': ''
|
||||||
} as JournalDispatcherSearcher);
|
} as JournalDispatcherSearcher);
|
||||||
|
|
||||||
const countFromIndex = ref(0);
|
const countFromIndex = ref(0);
|
||||||
@@ -123,15 +117,16 @@ export default defineComponent({
|
|||||||
countLimit,
|
countLimit,
|
||||||
|
|
||||||
scrollElement,
|
scrollElement,
|
||||||
maxCount: ref(15),
|
maxCount: ref(15)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
currentQueryArray(q: string[]) {
|
currentQueryArray(q: string[]) {
|
||||||
this.currentOptionsActive =
|
this.currentOptionsActive =
|
||||||
q.length > 2 || q.some((qv) => qv.startsWith('sortBy=') && qv.split('=')[1] != 'timestampFrom');
|
q.length > 2 ||
|
||||||
},
|
q.some((qv) => qv.startsWith('sortBy=') && qv.split('=')[1] != 'timestampFrom');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
@@ -139,10 +134,10 @@ export default defineComponent({
|
|||||||
return this.historyList.filter(
|
return this.historyList.filter(
|
||||||
(doc) => doc.isOnline || (doc.currentDuration && doc.currentDuration > 10 * 60000)
|
(doc) => doc.isOnline || (doc.currentDuration && doc.currentDuration > 10 * 60000)
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeRouteUpdate(to, _) {
|
beforeRouteUpdate(to) {
|
||||||
this.handleQueries(to.query);
|
this.handleQueries(to.query);
|
||||||
this.fetchHistoryData();
|
this.fetchHistoryData();
|
||||||
},
|
},
|
||||||
@@ -158,7 +153,8 @@ 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) return;
|
if (!this.scrollDataLoaded || this.scrollNoMoreData || this.dataStatus != DataStatus.Loaded)
|
||||||
|
return;
|
||||||
|
|
||||||
if (scrollTop > elementHeight * 0.85) this.addHistoryData();
|
if (scrollTop > elementHeight * 0.85) this.addHistoryData();
|
||||||
},
|
},
|
||||||
@@ -167,7 +163,8 @@ export default defineComponent({
|
|||||||
const queryKeys = Object.keys(query);
|
const queryKeys = Object.keys(query);
|
||||||
|
|
||||||
if (queryKeys.includes('sceneryName')) this.setSearchers('', `${query.sceneryName}`, '');
|
if (queryKeys.includes('sceneryName')) this.setSearchers('', `${query.sceneryName}`, '');
|
||||||
if (queryKeys.includes('dispatcherName')) this.setSearchers('', '', `${query.dispatcherName}`);
|
if (queryKeys.includes('dispatcherName'))
|
||||||
|
this.setSearchers('', '', `${query.dispatcherName}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
setSearchers(date: string, station: string, dispatcher: string) {
|
setSearchers(date: string, station: string, dispatcher: string) {
|
||||||
@@ -189,7 +186,9 @@ export default defineComponent({
|
|||||||
this.countFromIndex = this.historyList.length;
|
this.countFromIndex = this.historyList.length;
|
||||||
|
|
||||||
const responseData: DispatcherHistory[] = await (
|
const responseData: DispatcherHistory[] = await (
|
||||||
await axios.get(`${DISPATCHERS_API_URL}?${this.currentQuery}&countFrom=${this.countFromIndex}`)
|
await axios.get(
|
||||||
|
`${DISPATCHERS_API_URL}?${this.currentQuery}&countFrom=${this.countFromIndex}`
|
||||||
|
)
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
if (!responseData) return;
|
if (!responseData) return;
|
||||||
@@ -210,12 +209,15 @@ export default defineComponent({
|
|||||||
const station = this.searchersValues['search-station'].trim();
|
const station = this.searchersValues['search-station'].trim();
|
||||||
const dateString = this.searchersValues['search-date'].trim();
|
const dateString = this.searchersValues['search-date'].trim();
|
||||||
|
|
||||||
const timestampFrom = dateString ? Date.parse(new Date(dateString).toISOString()) - 120 * 60 * 1000 : undefined;
|
const timestampFrom = dateString
|
||||||
|
? Date.parse(new Date(dateString).toISOString()) - 120 * 60 * 1000
|
||||||
|
: undefined;
|
||||||
const timestampTo = timestampFrom ? timestampFrom + 86400000 : undefined;
|
const timestampTo = timestampFrom ? timestampFrom + 86400000 : undefined;
|
||||||
|
|
||||||
if (dispatcher) queries.push(`dispatcherName=${dispatcher}`);
|
if (dispatcher) queries.push(`dispatcherName=${dispatcher}`);
|
||||||
if (station) queries.push(`stationName=${station}`);
|
if (station) queries.push(`stationName=${station}`);
|
||||||
if (timestampFrom && timestampTo) queries.push(`timestampFrom=${timestampFrom}`, `timestampTo=${timestampTo}`);
|
if (timestampFrom && timestampTo)
|
||||||
|
queries.push(`timestampFrom=${timestampFrom}`, `timestampTo=${timestampTo}`);
|
||||||
|
|
||||||
// API: const SORT_TYPES = ['allStopsCount', 'endDate', 'beginDate', 'routeDistance'];
|
// API: const SORT_TYPES = ['allStopsCount', 'endDate', 'beginDate', 'routeDistance'];
|
||||||
if (this.sorterActive.id == 'timestampFrom') queries.push('sortBy=timestampFrom');
|
if (this.sorterActive.id == 'timestampFrom') queries.push('sortBy=timestampFrom');
|
||||||
@@ -260,8 +262,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
this.scrollNoMoreData = false;
|
this.scrollNoMoreData = false;
|
||||||
this.scrollDataLoaded = true;
|
this.scrollDataLoaded = true;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -42,11 +42,9 @@ import dateMixin from '../mixins/dateMixin';
|
|||||||
import routerMixin from '../mixins/routerMixin';
|
import routerMixin from '../mixins/routerMixin';
|
||||||
import modalTrainMixin from '../mixins/modalTrainMixin';
|
import modalTrainMixin from '../mixins/modalTrainMixin';
|
||||||
|
|
||||||
import DriverStats from '../components/JournalView/JournalDriverStats.vue';
|
|
||||||
import JournalOptions from '../components/JournalView/JournalOptions.vue';
|
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 Loading from '../components/Global/Loading.vue';
|
|
||||||
|
|
||||||
import { DataStatus } from '../scripts/enums/DataStatus';
|
import { DataStatus } from '../scripts/enums/DataStatus';
|
||||||
import { TimetableHistory } from '../scripts/interfaces/api/TimetablesAPIData';
|
import { TimetableHistory } from '../scripts/interfaces/api/TimetablesAPIData';
|
||||||
@@ -59,7 +57,7 @@ import { JournalFilterType } from '../scripts/enums/JournalFilterType';
|
|||||||
import {
|
import {
|
||||||
JournalFilter,
|
JournalFilter,
|
||||||
JournalTimetableSearchType,
|
JournalTimetableSearchType,
|
||||||
JournalTimetableSorter,
|
JournalTimetableSorter
|
||||||
} from '../scripts/types/JournalTimetablesTypes';
|
} from '../scripts/types/JournalTimetablesTypes';
|
||||||
import { journalTimetableFilters } from '../constants/Journal/JournalTimetablesConsts';
|
import { journalTimetableFilters } from '../constants/Journal/JournalTimetablesConsts';
|
||||||
import JournalTimetablesList from '../components/JournalView/JournalTimetables/JournalTimetablesList.vue';
|
import JournalTimetablesList from '../components/JournalView/JournalTimetables/JournalTimetablesList.vue';
|
||||||
@@ -67,15 +65,20 @@ import JournalTimetablesList from '../components/JournalView/JournalTimetables/J
|
|||||||
const TIMETABLES_API_URL = `${URLs.stacjownikAPI}/api/getTimetables`;
|
const TIMETABLES_API_URL = `${URLs.stacjownikAPI}/api/getTimetables`;
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { DriverStats, Loading, JournalOptions, JournalStats, JournalHeader, JournalTimetablesList },
|
components: {
|
||||||
|
JournalOptions,
|
||||||
|
JournalStats,
|
||||||
|
JournalHeader,
|
||||||
|
JournalTimetablesList
|
||||||
|
},
|
||||||
mixins: [dateMixin, routerMixin, modalTrainMixin, imageMixin],
|
mixins: [dateMixin, routerMixin, modalTrainMixin, imageMixin],
|
||||||
|
|
||||||
name: 'JournalTimetables',
|
name: 'JournalTimetables',
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
timetableId: {
|
timetableId: {
|
||||||
type: String,
|
type: String
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
@@ -95,13 +98,15 @@ export default defineComponent({
|
|||||||
dataStatus: DataStatus.Loading,
|
dataStatus: DataStatus.Loading,
|
||||||
dataErrorMessage: '',
|
dataErrorMessage: '',
|
||||||
|
|
||||||
DataStatus,
|
DataStatus
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const sorterActive: JournalTimetableSorter = reactive({ id: 'timetableId', dir: 'desc' });
|
const sorterActive: JournalTimetableSorter = reactive({ id: 'timetableId', dir: 'desc' });
|
||||||
// const journalFilterActive = ref(journalTimetableFilters[0]);
|
// const journalFilterActive = ref(journalTimetableFilters[0]);
|
||||||
const initFilters: readonly JournalFilter[] = JSON.parse(JSON.stringify(journalTimetableFilters));
|
const initFilters: readonly JournalFilter[] = JSON.parse(
|
||||||
|
JSON.stringify(journalTimetableFilters)
|
||||||
|
);
|
||||||
const filterList: JournalFilter[] = reactive(JSON.parse(JSON.stringify(initFilters)));
|
const filterList: JournalFilter[] = reactive(JSON.parse(JSON.stringify(initFilters)));
|
||||||
|
|
||||||
const searchersValues = reactive({
|
const searchersValues = reactive({
|
||||||
@@ -109,7 +114,7 @@ export default defineComponent({
|
|||||||
'search-driver': '',
|
'search-driver': '',
|
||||||
'search-dispatcher': '',
|
'search-dispatcher': '',
|
||||||
'search-issuedFrom': '',
|
'search-issuedFrom': '',
|
||||||
'search-date': '',
|
'search-date': ''
|
||||||
} as JournalTimetableSearchType);
|
} as JournalTimetableSearchType);
|
||||||
|
|
||||||
const countFromIndex = ref(0);
|
const countFromIndex = ref(0);
|
||||||
@@ -132,18 +137,18 @@ export default defineComponent({
|
|||||||
|
|
||||||
scrollElement,
|
scrollElement,
|
||||||
|
|
||||||
store: useStore(),
|
store: useStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
currentQueryParams(q: TimetablesQueryParams) {
|
currentQueryParams(q: TimetablesQueryParams) {
|
||||||
this.currentOptionsActive = Object.values(q).some((v) => v !== undefined);
|
this.currentOptionsActive = Object.values(q).some((v) => v !== undefined);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Handle route updates for route-links
|
// Handle route updates for route-links
|
||||||
beforeRouteUpdate(to, _) {
|
beforeRouteUpdate(to) {
|
||||||
this.handleQueries(to.query);
|
this.handleQueries(to.query);
|
||||||
this.fetchHistoryData();
|
this.fetchHistoryData();
|
||||||
},
|
},
|
||||||
@@ -159,7 +164,8 @@ 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) return;
|
if (!this.scrollDataLoaded || this.scrollNoMoreData || this.dataStatus != DataStatus.Loaded)
|
||||||
|
return;
|
||||||
|
|
||||||
if (scrollTop > elementHeight * 0.85) this.addHistoryData();
|
if (scrollTop > elementHeight * 0.85) this.addHistoryData();
|
||||||
},
|
},
|
||||||
@@ -167,12 +173,21 @@ export default defineComponent({
|
|||||||
handleQueries(query: LocationQuery) {
|
handleQueries(query: LocationQuery) {
|
||||||
const queryKeys = Object.keys(query);
|
const queryKeys = Object.keys(query);
|
||||||
|
|
||||||
if (queryKeys.includes('timetableId')) this.setSearchers('', '', `#${query.timetableId}`, '', '');
|
if (queryKeys.includes('timetableId'))
|
||||||
if (queryKeys.includes('issuedFrom')) this.setSearchers('', '', '', '', `${query.issuedFrom}`);
|
this.setSearchers('', '', `#${query.timetableId}`, '', '');
|
||||||
if (queryKeys.includes('authorName')) this.setSearchers('', '', '', `${query.authorName}`, '');
|
if (queryKeys.includes('issuedFrom'))
|
||||||
|
this.setSearchers('', '', '', '', `${query.issuedFrom}`);
|
||||||
|
if (queryKeys.includes('authorName'))
|
||||||
|
this.setSearchers('', '', '', `${query.authorName}`, '');
|
||||||
},
|
},
|
||||||
|
|
||||||
setSearchers(date: string, driver: string, train: string, dispatcher: string, issuedFrom: string) {
|
setSearchers(
|
||||||
|
date: string,
|
||||||
|
driver: string,
|
||||||
|
train: string,
|
||||||
|
dispatcher: string,
|
||||||
|
issuedFrom: string
|
||||||
|
) {
|
||||||
this.searchersValues['search-date'] = date;
|
this.searchersValues['search-date'] = date;
|
||||||
this.searchersValues['search-driver'] = driver;
|
this.searchersValues['search-driver'] = driver;
|
||||||
this.searchersValues['search-train'] = train;
|
this.searchersValues['search-train'] = train;
|
||||||
@@ -186,7 +201,9 @@ export default defineComponent({
|
|||||||
this.sorterActive.id = 'timetableId';
|
this.sorterActive.id = 'timetableId';
|
||||||
|
|
||||||
this.filterList.forEach(
|
this.filterList.forEach(
|
||||||
(f) => (f.isActive = this.initFilters.find((initFilter) => initFilter.id == f.id)?.isActive || false)
|
(f) =>
|
||||||
|
(f.isActive =
|
||||||
|
this.initFilters.find((initFilter) => initFilter.id == f.id)?.isActive || false)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.fetchHistoryData();
|
this.fetchHistoryData();
|
||||||
@@ -199,7 +216,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const responseData: TimetableHistory[] = await (
|
const responseData: TimetableHistory[] = await (
|
||||||
await axios.get(`${TIMETABLES_API_URL}`, {
|
await axios.get(`${TIMETABLES_API_URL}`, {
|
||||||
params: { ...this.currentQueryParams },
|
params: { ...this.currentQueryParams }
|
||||||
})
|
})
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
@@ -221,7 +238,9 @@ export default defineComponent({
|
|||||||
const dateString = this.searchersValues['search-date'].trim() || undefined;
|
const dateString = this.searchersValues['search-date'].trim() || undefined;
|
||||||
const issuedFrom = this.searchersValues['search-issuedFrom'].trim() || undefined;
|
const issuedFrom = this.searchersValues['search-issuedFrom'].trim() || undefined;
|
||||||
|
|
||||||
const timestampFrom = dateString ? Date.parse(new Date(dateString).toISOString()) - 120 * 60 * 1000 : undefined;
|
const timestampFrom = dateString
|
||||||
|
? Date.parse(new Date(dateString).toISOString()) - 120 * 60 * 1000
|
||||||
|
: undefined;
|
||||||
const timestampTo = timestampFrom ? timestampFrom + 86400000 : undefined;
|
const timestampTo = timestampFrom ? timestampFrom + 86400000 : undefined;
|
||||||
|
|
||||||
const queryParams: TimetablesQueryParams = {};
|
const queryParams: TimetablesQueryParams = {};
|
||||||
@@ -279,16 +298,18 @@ export default defineComponent({
|
|||||||
queryParams['timestampFrom'] = timestampFrom;
|
queryParams['timestampFrom'] = timestampFrom;
|
||||||
queryParams['timestampTo'] = timestampTo;
|
queryParams['timestampTo'] = timestampTo;
|
||||||
queryParams['issuedFrom'] = issuedFrom;
|
queryParams['issuedFrom'] = issuedFrom;
|
||||||
queryParams['sortBy'] = this.sorterActive.id != 'timetableId' ? this.sorterActive.id : undefined;
|
queryParams['sortBy'] =
|
||||||
|
this.sorterActive.id != 'timetableId' ? this.sorterActive.id : undefined;
|
||||||
|
|
||||||
if (JSON.stringify(this.currentQueryParams) != JSON.stringify(queryParams)) this.dataStatus = DataStatus.Loading;
|
if (JSON.stringify(this.currentQueryParams) != JSON.stringify(queryParams))
|
||||||
|
this.dataStatus = DataStatus.Loading;
|
||||||
|
|
||||||
this.currentQueryParams = queryParams;
|
this.currentQueryParams = queryParams;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const responseData: TimetableHistory[] = await (
|
const responseData: TimetableHistory[] = await (
|
||||||
await axios.get(`${TIMETABLES_API_URL}`, {
|
await axios.get(`${TIMETABLES_API_URL}`, {
|
||||||
params: this.currentQueryParams,
|
params: this.currentQueryParams
|
||||||
})
|
})
|
||||||
).data;
|
).data;
|
||||||
|
|
||||||
@@ -318,8 +339,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
this.scrollNoMoreData = false;
|
this.scrollNoMoreData = false;
|
||||||
this.scrollDataLoaded = true;
|
this.scrollDataLoaded = true;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
+31
-16
@@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="scenery-view">
|
<div class="scenery-view">
|
||||||
<div class="scenery-offline" v-if="!stationInfo && isComponentVisible && store.dataStatuses.sceneries == 2">
|
<div
|
||||||
|
class="scenery-offline"
|
||||||
|
v-if="!stationInfo && isComponentVisible && store.dataStatuses.sceneries == 2"
|
||||||
|
>
|
||||||
<div>{{ $t('scenery.no-scenery') }}</div>
|
<div>{{ $t('scenery.no-scenery') }}</div>
|
||||||
|
|
||||||
<action-button>
|
<action-button>
|
||||||
@@ -8,7 +11,12 @@
|
|||||||
</action-button>
|
</action-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="scenery-wrapper" v-if="stationInfo" ref="card-wrapper" :data-timetable-only="timetableOnly">
|
<div
|
||||||
|
class="scenery-wrapper"
|
||||||
|
v-if="stationInfo"
|
||||||
|
ref="card-wrapper"
|
||||||
|
:data-timetable-only="timetableOnly"
|
||||||
|
>
|
||||||
<div class="scenery-left" v-if="!timetableOnly">
|
<div class="scenery-left" v-if="!timetableOnly">
|
||||||
<div class="scenery-actions">
|
<div class="scenery-actions">
|
||||||
<button class="back-btn btn" :title="$t('scenery.return-btn')" @click="navigateTo('/')">
|
<button class="back-btn btn" :title="$t('scenery.return-btn')" @click="navigateTo('/')">
|
||||||
@@ -23,7 +31,8 @@
|
|||||||
<div class="scenery-right">
|
<div class="scenery-right">
|
||||||
<div class="info-actions">
|
<div class="info-actions">
|
||||||
<button
|
<button
|
||||||
v-for="viewMode in viewModes"
|
v-for="(viewMode, i) in viewModes"
|
||||||
|
: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="currentViewCompontent == viewMode.component"
|
||||||
@@ -33,7 +42,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<keep-alive>
|
<keep-alive>
|
||||||
<component :is="currentViewCompontent" :station="stationInfo" :key="currentViewCompontent"></component>
|
<component
|
||||||
|
:is="currentViewCompontent"
|
||||||
|
:station="stationInfo"
|
||||||
|
:key="currentViewCompontent"
|
||||||
|
></component>
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -41,7 +54,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, PropType } 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/store';
|
||||||
@@ -57,7 +70,7 @@ import imageMixin from '../mixins/imageMixin';
|
|||||||
enum SceneryViewMode {
|
enum SceneryViewMode {
|
||||||
'TIMETABLES_ACTIVE',
|
'TIMETABLES_ACTIVE',
|
||||||
'TIMETABLES_HISTORY',
|
'TIMETABLES_HISTORY',
|
||||||
'SCENERY_HISTORY',
|
'SCENERY_HISTORY'
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -67,7 +80,7 @@ export default defineComponent({
|
|||||||
ActionButton,
|
ActionButton,
|
||||||
SceneryHeader,
|
SceneryHeader,
|
||||||
SceneryTimetablesHistory,
|
SceneryTimetablesHistory,
|
||||||
SceneryDispatchersHistory,
|
SceneryDispatchersHistory
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [routerMixin, imageMixin],
|
mixins: [routerMixin, imageMixin],
|
||||||
@@ -76,21 +89,21 @@ export default defineComponent({
|
|||||||
viewModes: [
|
viewModes: [
|
||||||
{
|
{
|
||||||
id: 'scenery.option-active-timetables',
|
id: 'scenery.option-active-timetables',
|
||||||
component: 'SceneryTimetable',
|
component: 'SceneryTimetable'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'scenery.option-timetables-history',
|
id: 'scenery.option-timetables-history',
|
||||||
component: 'SceneryTimetablesHistory',
|
component: 'SceneryTimetablesHistory'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'scenery.option-dispatchers-history',
|
id: 'scenery.option-dispatchers-history',
|
||||||
component: 'SceneryDispatchersHistory',
|
component: 'SceneryDispatchersHistory'
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
sceneryViewMode: SceneryViewMode,
|
sceneryViewMode: SceneryViewMode,
|
||||||
selectedCheckpoint: '',
|
selectedCheckpoint: '',
|
||||||
currentViewCompontent: 'SceneryTimetable',
|
currentViewCompontent: 'SceneryTimetable',
|
||||||
onlineFrom: -1,
|
onlineFrom: -1
|
||||||
}),
|
}),
|
||||||
|
|
||||||
activated() {
|
activated() {
|
||||||
@@ -105,14 +118,16 @@ export default defineComponent({
|
|||||||
const isComponentVisible = computed(() => route.path === '/scenery');
|
const isComponentVisible = computed(() => route.path === '/scenery');
|
||||||
|
|
||||||
const stationInfo = computed(() => {
|
const stationInfo = computed(() => {
|
||||||
return store.stationList.find((station) => station.name === route.query.station?.toString().replace(/_/g, ' '));
|
return store.stationList.find(
|
||||||
|
(station) => station.name === route.query.station?.toString().replace(/_/g, ' ')
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
timetableOnly,
|
timetableOnly,
|
||||||
isComponentVisible,
|
isComponentVisible,
|
||||||
stationInfo,
|
stationInfo,
|
||||||
store,
|
store
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -128,8 +143,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
selectCheckpoint(cp: { checkpointName: string }) {
|
selectCheckpoint(cp: { checkpointName: string }) {
|
||||||
this.selectedCheckpoint = cp.checkpointName;
|
this.selectedCheckpoint = cp.checkpointName;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<div class="options-bar">
|
<div class="options-bar">
|
||||||
<StationFilterCard :showCard="filterCardOpen" :exit="(filterCardOpen = false)" ref="filterCardRef" />
|
<StationFilterCard
|
||||||
|
:showCard="filterCardOpen"
|
||||||
|
:exit="(filterCardOpen = false)"
|
||||||
|
ref="filterCardRef"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<StationTable :stations="computedStationList" />
|
<StationTable :stations="computedStationList" />
|
||||||
@@ -16,40 +20,38 @@
|
|||||||
import { defineComponent } from 'vue';
|
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 SelectBox from '../components/Global/SelectBox.vue';
|
|
||||||
import { useStationFiltersStore } from '../store/stationFiltersStore';
|
import { useStationFiltersStore } from '../store/stationFiltersStore';
|
||||||
import { useStore } from '../store/store';
|
import { useStore } from '../store/store';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
StationTable,
|
StationTable,
|
||||||
StationFilterCard,
|
StationFilterCard
|
||||||
SelectBox,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
filterCardOpen: false,
|
filterCardOpen: false,
|
||||||
modalHidden: true,
|
modalHidden: true,
|
||||||
STORAGE_KEY: 'options_saved',
|
STORAGE_KEY: 'options_saved',
|
||||||
focusedStationName: '',
|
focusedStationName: ''
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
filterStore: useStationFiltersStore(),
|
filterStore: useStationFiltersStore(),
|
||||||
store: useStore(),
|
store: useStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
computedStationList() {
|
computedStationList() {
|
||||||
return this.filterStore.getFilteredStationList(this.store.stationList, this.store.region.id);
|
return this.filterStore.getFilteredStationList(this.store.stationList, this.store.region.id);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.filterStore.setupFilters();
|
this.filterStore.setupFilters();
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
+17
-11
@@ -25,7 +25,7 @@ import { TrainFilter } from '../scripts/interfaces/Trains/TrainFilter';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
TrainTable,
|
TrainTable,
|
||||||
TrainOptions,
|
TrainOptions
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [modalTrainMixin],
|
mixins: [modalTrainMixin],
|
||||||
@@ -33,22 +33,22 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
train: {
|
train: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false
|
||||||
},
|
},
|
||||||
|
|
||||||
driver: {
|
driver: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false
|
||||||
},
|
},
|
||||||
|
|
||||||
trainId: {
|
trainId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
trainStatsOpen: false,
|
trainStatsOpen: false
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
@@ -69,14 +69,20 @@ export default defineComponent({
|
|||||||
provide('filterList', filterList);
|
provide('filterList', filterList);
|
||||||
|
|
||||||
const computedTrains: ComputedRef<Train[]> = computed(() => {
|
const computedTrains: ComputedRef<Train[]> = computed(() => {
|
||||||
return filteredTrainList(store.trainList, searchedTrain.value, searchedDriver.value, sorterActive, filterList);
|
return filteredTrainList(
|
||||||
|
store.trainList,
|
||||||
|
searchedTrain.value,
|
||||||
|
searchedDriver.value,
|
||||||
|
sorterActive,
|
||||||
|
filterList
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
watch([searchedTrain, searchedDriver, sorterActive, filterList], ([sT, sD, sA, fL]) => {
|
watch([searchedTrain, searchedDriver, sorterActive, filterList], ([sT, sD, sA, fL]) => {
|
||||||
const areFiltersActive = fL.some((f, i) => f.isActive !== initTrainFilters[i].isActive);
|
const areFiltersActive = fL.some((f, i) => f.isActive !== initTrainFilters[i].isActive);
|
||||||
|
|
||||||
|
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);
|
console.log(sA.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -86,7 +92,7 @@ export default defineComponent({
|
|||||||
searchedDriver,
|
searchedDriver,
|
||||||
sorterActive,
|
sorterActive,
|
||||||
store,
|
store,
|
||||||
currentOptionsActive,
|
currentOptionsActive
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -101,7 +107,7 @@ export default defineComponent({
|
|||||||
this.selectModalTrain(this.trainId);
|
this.selectModalTrain(this.trainId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user