mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 05:18:11 +00:00
Poprawki wizualne i zachowania strony
This commit is contained in:
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
"vue": "^2.6.12",
|
"vue": "^2.6.12",
|
||||||
"vue-class-component": "^7.2.6",
|
"vue-class-component": "^7.2.6",
|
||||||
"vue-i18n": "^8.24.3",
|
"vue-i18n": "^8.24.3",
|
||||||
"vue-property-decorator": "^8.4.2",
|
"vue-property-decorator": "^8.5.1",
|
||||||
"vue-router": "^3.5.1",
|
"vue-router": "^3.5.1",
|
||||||
"vuex": "^3.6.2"
|
"vuex": "^3.6.2"
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
<template>
|
git <template>
|
||||||
<div class="app">
|
<div class="app">
|
||||||
<UpdateModal
|
<UpdateModal
|
||||||
:currentVersion="VERSION"
|
:currentVersion="VERSION"
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<button class="action-btn">
|
||||||
|
<slot></slot>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Vue } from "vue-property-decorator";
|
||||||
|
|
||||||
|
@Component
|
||||||
|
export default class ActionButton extends Vue {}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../styles/variables";
|
||||||
|
@import "../../styles/responsive";
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
background: #333;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
color: #bdbdbd;
|
||||||
|
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
outline: none;
|
||||||
|
padding: 0.35em 0.65em;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&.outlined {
|
||||||
|
border: 1px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.button_icon {
|
||||||
|
width: 1.25em;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
margin-right: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 1em;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
transition: max-width 0.35s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
color: $accentCol;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $accentCol;
|
||||||
|
|
||||||
|
background: #5c5c5c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<div class="search-box">
|
||||||
|
<input v-model="searchedItem" :placeholder="title" />
|
||||||
|
|
||||||
|
<img
|
||||||
|
class="search-exit"
|
||||||
|
:src="exitIcon"
|
||||||
|
alt="exit-icon"
|
||||||
|
@click="() => (searchedItem = '')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Vue, Prop, Model } from "vue-property-decorator";
|
||||||
|
|
||||||
|
@Component
|
||||||
|
export default class SearchBox extends Vue {
|
||||||
|
@Prop({ required: true }) title!: string;
|
||||||
|
@Model("changed") readonly searchedItem!: string;
|
||||||
|
|
||||||
|
// @Emit("changed")
|
||||||
|
// onItemChanged() {
|
||||||
|
// return this.searchedItem;
|
||||||
|
// }
|
||||||
|
|
||||||
|
exitIcon = require("@/assets/icon-exit.svg");
|
||||||
|
|
||||||
|
// searchedItem: string = "";
|
||||||
|
|
||||||
|
// @Watch("searchedItem")
|
||||||
|
// watchSelectedItem(item) {
|
||||||
|
// this.onItemChanged();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.search {
|
||||||
|
&-box {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
background: #333;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-exit {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
top: 50%;
|
||||||
|
right: 10px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
min-width: 85%;
|
||||||
|
padding: 0.35em 0.5em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,109 +1,118 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="select-box">
|
<div class="select-box">
|
||||||
<div class="title">Sortuj według</div>
|
<div class="select-box_content">
|
||||||
|
<label>
|
||||||
|
<select v-model="selectedItem">
|
||||||
|
<option value disabled selected hidden>
|
||||||
|
{{ title }}
|
||||||
|
</option>
|
||||||
|
<option v-for="item in itemList" :key="item.id" :value="item.id">
|
||||||
|
{{ item.value }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
<div class="option-selected" @click="toggleOptionList">
|
<span> </span>
|
||||||
<span>{{ selectedOption }}</span>
|
</label>
|
||||||
<img :src="require('@/assets/icon-select.svg')" alt="icon-select" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="option-container">
|
|
||||||
<ul class="option-list" :class="{ open: listOpen }">
|
|
||||||
<li
|
|
||||||
class="option-item"
|
|
||||||
v-for="(option, i) in sortOptionList"
|
|
||||||
:key="i"
|
|
||||||
@click="() => chooseOption(option)"
|
|
||||||
>
|
|
||||||
<input type="option-radio" name="sort" :id="option.id" />
|
|
||||||
<label :for="option.id">{{ option.content }}</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue, Prop } from "vue-property-decorator";
|
import { Component, Vue, Prop, Watch, Emit } from "vue-property-decorator";
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class SelectBox extends Vue {
|
export default class SelectBox extends Vue {
|
||||||
@Prop() title!: string;
|
@Prop({ required: true }) title!: string;
|
||||||
@Prop() optionList!: string[];
|
@Prop({ required: true }) itemList!: { id: string | number; value: string }[];
|
||||||
|
|
||||||
selectedOption: string = "";
|
@Emit("selected")
|
||||||
|
onItemSelected() {
|
||||||
|
return this.selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ascIcon = require("@/assets/icon-arrow-asc.svg");
|
||||||
|
descIcon = require("@/assets/icon-arrow-desc.svg");
|
||||||
|
|
||||||
|
selectedItem: string = "";
|
||||||
|
|
||||||
|
@Watch("selectedItem")
|
||||||
|
watchSelectedItem(item) {
|
||||||
|
this.onItemSelected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.option {
|
@import "../../styles/variables.scss";
|
||||||
&-container {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
input {
|
.select-box {
|
||||||
display: none;
|
&_content {
|
||||||
|
position: relative;
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
min-width: 10em;
|
||||||
|
|
||||||
|
background-color: #333;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
|
||||||
|
padding: 0.35em 0.5em;
|
||||||
|
|
||||||
|
font-size: 1em;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
+ span > img {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
padding: 0.5rem 1rem;
|
position: relative;
|
||||||
width: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
&-item {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(#868686, 0.85);
|
|
||||||
}
|
|
||||||
|
|
||||||
transition: background 150ms ease-in;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-selected,
|
|
||||||
&-list {
|
|
||||||
background: #333;
|
|
||||||
border-radius: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-selected {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
min-width: 150px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
span {
|
span {
|
||||||
margin-right: 2rem;
|
$arrowCol: #d8d8d8;
|
||||||
}
|
$arrowWidth: 0.35em;
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 0.75em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-list {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 20%;
|
||||||
left: 0;
|
right: 0.25em;
|
||||||
|
|
||||||
z-index: 10;
|
pointer-events: none;
|
||||||
|
|
||||||
width: 100%;
|
&::before,
|
||||||
background-color: rgba(#222, 0.95);
|
&::after {
|
||||||
overflow: hidden;
|
content: "";
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
|
||||||
max-height: 0;
|
position: absolute;
|
||||||
|
right: 0.5em;
|
||||||
|
|
||||||
&.open {
|
border-left: $arrowWidth solid transparent;
|
||||||
max-height: 250px;
|
border-right: $arrowWidth solid transparent;
|
||||||
opacity: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
transition: all 150ms ease-in;
|
&::before {
|
||||||
|
border-top: $arrowWidth solid $arrowCol;
|
||||||
|
|
||||||
|
transform: translateY(150%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-bottom: $arrowWidth solid $arrowCol;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -217,8 +217,6 @@ export default class SceneryInfo extends styleMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
navigateToTrain(trainNo: number) {
|
navigateToTrain(trainNo: number) {
|
||||||
console.log(trainNo);
|
|
||||||
|
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: "TrainsView",
|
name: "TrainsView",
|
||||||
params: { queryTrain: trainNo.toString() },
|
params: { queryTrain: trainNo.toString() },
|
||||||
|
|||||||
@@ -60,10 +60,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-actions flex">
|
<div class="card-actions flex">
|
||||||
<button class="button" @click="resetFilters">
|
<action-button class="outlined" @click.native="resetFilters">
|
||||||
{{ $t("filters.reset") }}
|
{{ $t("filters.reset") }}
|
||||||
</button>
|
</action-button>
|
||||||
<button class="button" @click="exit">{{ $t("filters.close") }}</button>
|
<action-button class="outlined" @click.native="exit">{{
|
||||||
|
$t("filters.close")
|
||||||
|
}}</action-button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
@@ -74,8 +76,9 @@ import { Vue, Component, Prop } from "vue-property-decorator";
|
|||||||
import inputData from "@/data/options.json";
|
import inputData from "@/data/options.json";
|
||||||
|
|
||||||
import StorageManager from "@/scripts/storageManager";
|
import StorageManager from "@/scripts/storageManager";
|
||||||
|
import ActionButton from "../Global/ActionButton.vue";
|
||||||
|
|
||||||
@Component
|
@Component({ components: { ActionButton } })
|
||||||
export default class FilterCard extends Vue {
|
export default class FilterCard extends Vue {
|
||||||
inputs = { ...inputData };
|
inputs = { ...inputData };
|
||||||
saveOptions: boolean = false;
|
saveOptions: boolean = false;
|
||||||
@@ -151,9 +154,13 @@ export default class FilterCard extends Vue {
|
|||||||
@import "../../styles/responsive";
|
@import "../../styles/responsive";
|
||||||
@import "../../styles/card";
|
@import "../../styles/card";
|
||||||
|
|
||||||
.card {
|
$accessCol: #e03b07;
|
||||||
font-size: 1.25em;
|
$controlCol: #0085ff;
|
||||||
|
$signalCol: #bf7c00;
|
||||||
|
$statusCol: #349b32;
|
||||||
|
$saveCol: #28a826;
|
||||||
|
|
||||||
|
.card {
|
||||||
&-title {
|
&-title {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -171,7 +178,7 @@ export default class FilterCard extends Vue {
|
|||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
|
|
||||||
@include smallScreen() {
|
@include smallScreen() {
|
||||||
grid-template-columns: repeat(auto-fit, minmax(6em, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(8em, 1fr));
|
||||||
grid-template-rows: auto;
|
grid-template-rows: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,8 +192,6 @@ export default class FilterCard extends Vue {
|
|||||||
|
|
||||||
button {
|
button {
|
||||||
margin: 0 0.3em;
|
margin: 0 0.3em;
|
||||||
border: 1px solid white;
|
|
||||||
font-size: 0.85em;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +200,6 @@ export default class FilterCard extends Vue {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.option {
|
.option {
|
||||||
width: 7em;
|
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,8 +228,6 @@ export default class FilterCard extends Vue {
|
|||||||
|
|
||||||
padding: 0.45em 0.4em;
|
padding: 0.45em 0.4em;
|
||||||
|
|
||||||
font-size: 0.8em;
|
|
||||||
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@@ -243,42 +245,42 @@ export default class FilterCard extends Vue {
|
|||||||
|
|
||||||
&.checked {
|
&.checked {
|
||||||
&.access {
|
&.access {
|
||||||
background-color: #e03b07;
|
background-color: $accessCol;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
box-shadow: 0 0 6px 1px #e03b07;
|
box-shadow: 0 0 6px 1px $accessCol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.control {
|
&.control {
|
||||||
background-color: #0085ff;
|
background-color: $controlCol;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
box-shadow: 0 0 6px 1px #0085ff;
|
box-shadow: 0 0 6px 1px $controlCol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.signals {
|
&.signals {
|
||||||
background-color: #b000bf;
|
background-color: $signalCol;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
box-shadow: 0 0 6px 1px #b000bf;
|
box-shadow: 0 0 6px 1px $signalCol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.status {
|
&.status {
|
||||||
background-color: #05b702;
|
background-color: $statusCol;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
box-shadow: 0 0 6px 1px #05b702;
|
box-shadow: 0 0 6px 1px $statusCol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.save {
|
&.save {
|
||||||
background-color: #05b702;
|
background-color: $saveCol;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
box-shadow: 0 0 6px 1px #05b702;
|
box-shadow: 0 0 6px 1px $saveCol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,16 +312,12 @@ export default class FilterCard extends Vue {
|
|||||||
margin-right: 0.3em;
|
margin-right: 0.3em;
|
||||||
padding: 0.1em 0.2em;
|
padding: 0.1em 0.2em;
|
||||||
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
border-radius: 0.2em;
|
border-radius: 0.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-content {
|
&-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-input {
|
&-input {
|
||||||
|
|||||||
@@ -1,37 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="train-options">
|
<div class="train-options">
|
||||||
<div class="options_wrapper">
|
<div class="options_wrapper">
|
||||||
<div class="train-sorter option">
|
<select-box
|
||||||
<div class="train-sorter_wrapper">
|
:title="$t('trains.option-distance')"
|
||||||
<div class="train-sorter_selected" @click="toggleSorterOptions">
|
:itemList="translatedSorterOptions"
|
||||||
<span>{{ currentSorterOption }}</span>
|
@selected="changeSorter"
|
||||||
<img :src="descIcon" alt="icon-select" />
|
/>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="train-sorter_options">
|
|
||||||
<ul :class="{ open: sorterOptionsOpen }">
|
|
||||||
<li
|
|
||||||
v-for="(option, i) in sorterOptions"
|
|
||||||
:key="i"
|
|
||||||
@click="() => chooseOption(option)"
|
|
||||||
>
|
|
||||||
<input type="radio" name="sort" :id="option.id" />
|
|
||||||
<label :for="option.id">
|
|
||||||
{{ $t(`trains.option-${option.id}`) }}
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="train-search_train option">
|
|
||||||
<div class="search-box">
|
<div class="search-box">
|
||||||
<input
|
<input
|
||||||
class="search-input"
|
class="search-input"
|
||||||
:placeholder="$t('trains.search-no')"
|
|
||||||
v-model="searchedTrain"
|
v-model="searchedTrain"
|
||||||
|
:placeholder="$t('trains.search-no')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
class="search-exit"
|
class="search-exit"
|
||||||
:src="exitIcon"
|
:src="exitIcon"
|
||||||
@@ -39,15 +21,14 @@
|
|||||||
@click="() => (searchedTrain = '')"
|
@click="() => (searchedTrain = '')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="train-search_driver option">
|
|
||||||
<div class="search-box">
|
<div class="search-box">
|
||||||
<input
|
<input
|
||||||
class="search-input"
|
class="search-input"
|
||||||
:placeholder="$t('trains.search-driver')"
|
|
||||||
v-model="searchedDriver"
|
v-model="searchedDriver"
|
||||||
|
:placeholder="$t('trains.search-driver')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
class="search-exit"
|
class="search-exit"
|
||||||
:src="exitIcon"
|
:src="exitIcon"
|
||||||
@@ -57,29 +38,52 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue, Watch, Prop } from "vue-property-decorator";
|
import { Component, Vue, Watch, Prop, Emit } from "vue-property-decorator";
|
||||||
|
import SelectBox from "../Global/SelectBox.vue";
|
||||||
|
|
||||||
@Component
|
@Component({ components: { SelectBox } })
|
||||||
export default class TrainOptions extends Vue {
|
export default class TrainOptions extends Vue {
|
||||||
ascIcon = require("@/assets/icon-arrow-asc.svg");
|
// Passed as component parameters
|
||||||
descIcon = require("@/assets/icon-arrow-desc.svg");
|
@Prop() readonly queryTrain!: string;
|
||||||
|
@Prop() readonly focusedTrain!: string;
|
||||||
|
|
||||||
exitIcon = require("@/assets/icon-exit.svg");
|
exitIcon = require("@/assets/icon-exit.svg");
|
||||||
|
|
||||||
clickEventListener!: EventListener;
|
|
||||||
|
|
||||||
sorterOptionsOpen = false;
|
|
||||||
currentSorterOption = this.$t("trains.option-distance");
|
|
||||||
|
|
||||||
searchedTrain = "";
|
searchedTrain = "";
|
||||||
searchedDriver = "";
|
searchedDriver = "";
|
||||||
|
|
||||||
// Passed as component parameters
|
sorterOptions: { id: string; value: string }[] = [
|
||||||
@Prop() readonly queryTrain!: string;
|
{
|
||||||
@Prop() readonly focusedTrain!: string;
|
id: "mass",
|
||||||
|
value: "masa",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "speed",
|
||||||
|
value: "prędkość",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "length",
|
||||||
|
value: "długość",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "distance",
|
||||||
|
value: "kilometraż",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "timetable",
|
||||||
|
value: "numer pociągu",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
get translatedSorterOptions() {
|
||||||
|
return this.sorterOptions.map((option) => ({
|
||||||
|
id: option.id,
|
||||||
|
value: this.$t(`trains.option-${option.id}`),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.queryTrain) {
|
if (this.queryTrain) {
|
||||||
@@ -88,67 +92,44 @@ export default class TrainOptions extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sorterOptions: { id: string; content: string }[] = [
|
/* Emitters to TrainsView managing variables */
|
||||||
{
|
|
||||||
id: "mass",
|
|
||||||
content: "masa",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "speed",
|
|
||||||
content: "prędkość",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "length",
|
|
||||||
content: "długość",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "distance",
|
|
||||||
content: "kilometraż",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "timetable",
|
|
||||||
content: "numer pociągu",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
toggleSorterOptions() {
|
@Emit("changeSearchedTrain")
|
||||||
this.sorterOptionsOpen = !this.sorterOptionsOpen;
|
chooseTrain(train: string) {
|
||||||
|
return train;
|
||||||
}
|
}
|
||||||
|
|
||||||
closeSorterOptions() {
|
@Emit("changeSearchedDriver")
|
||||||
this.sorterOptionsOpen = false;
|
chooseDriver(driverName: string) {
|
||||||
|
return driverName;
|
||||||
}
|
}
|
||||||
|
|
||||||
chooseOption(option: { id: string; content: string }) {
|
@Emit()
|
||||||
this.$emit("changeSorter", { id: option.id, dir: -1 });
|
changeSorter(optionID: string) {
|
||||||
|
return { id: optionID, dir: -1 };
|
||||||
this.currentSorterOption = this.$t(`trains.option-${option.id}`);
|
|
||||||
|
|
||||||
this.closeSorterOptions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Watchers for search boxes */
|
||||||
|
|
||||||
@Watch("searchedTrain")
|
@Watch("searchedTrain")
|
||||||
onSearchedTrainChanged(train: string) {
|
watchSearchedTrain(train: string) {
|
||||||
this.$emit("changeSearchedTrain", train);
|
this.chooseTrain(train);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Watch("searchedDriver")
|
@Watch("searchedDriver")
|
||||||
onSearchedDriverChanged(driver: string) {
|
watchSearchedDriver(driver: string) {
|
||||||
this.$emit("changeSearchedDriver", driver);
|
this.chooseDriver(driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Watcher for train no passed in link params */
|
||||||
|
|
||||||
@Watch("queryTrain")
|
@Watch("queryTrain")
|
||||||
onQueryTrainChanged(train: string) {
|
onQueryTrainChanged(train: string | undefined) {
|
||||||
if (train && train != "") {
|
if (!train) return;
|
||||||
this.searchedTrain = train;
|
if (train == "") return;
|
||||||
this.searchedDriver = "";
|
console.log("query train changed", train);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Watch("focusedTrain")
|
// this.chooseTrain(train);
|
||||||
onFocusedTrainChanged(train: string) {
|
|
||||||
this.searchedTrain = train;
|
|
||||||
this.searchedDriver = "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -164,93 +145,14 @@ export default class TrainOptions extends Vue {
|
|||||||
|
|
||||||
.options_wrapper {
|
.options_wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
|
||||||
|
|
||||||
.option {
|
|
||||||
background: #333;
|
|
||||||
border-radius: 0.5em 0.5em 0 0;
|
|
||||||
|
|
||||||
margin-right: 0.35em;
|
|
||||||
|
|
||||||
@include smallScreen() {
|
@include smallScreen() {
|
||||||
width: 100%;
|
justify-content: center;
|
||||||
margin: 0.35em 0;
|
flex-direction: column;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.train-sorter {
|
|
||||||
user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
|
|
||||||
&_options {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
ul {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
transition: all 150ms ease-in;
|
|
||||||
|
|
||||||
z-index: 9;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
max-height: 0;
|
|
||||||
|
|
||||||
&.open {
|
|
||||||
max-height: 250px;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
display: flex;
|
|
||||||
transition: background 150ms ease-in;
|
|
||||||
|
|
||||||
background-color: rgba(#222, 0.95);
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
border-radius: 0 0 0.5em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(#868686, 0.85);
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
width: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&_selected {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
padding: 0.5em 0.5em;
|
|
||||||
min-width: 200px;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
span {
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 2em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,16 +163,19 @@ export default class TrainOptions extends Vue {
|
|||||||
background: #333;
|
background: #333;
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
|
|
||||||
|
margin: 0.5em 0 0.5em 0.5em;
|
||||||
|
|
||||||
|
@include smallScreen() {
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-input {
|
&-input {
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
padding: 0.5em 0.5em;
|
|
||||||
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
min-width: 85%;
|
min-width: 85%;
|
||||||
|
padding: 0.35em 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-exit {
|
&-exit {
|
||||||
|
|||||||
@@ -1,17 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="train-stats">
|
<div class="train-stats">
|
||||||
<div class="btn-wrapper">
|
|
||||||
<button
|
|
||||||
class="stats-btn button"
|
|
||||||
@click="toggleStats"
|
|
||||||
v-if="trains.length > 0"
|
|
||||||
>
|
|
||||||
{{ $t("trains.stats") }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<transition name="stats-anim">
|
<transition name="stats-anim">
|
||||||
<div class="stats-body" v-if="statsOpen">
|
<div class="stats-body" v-if="trainStatsOpen">
|
||||||
<h2 class="stats-header">{{ $t("trains.stats") }}</h2>
|
<h2 class="stats-header">{{ $t("trains.stats") }}</h2>
|
||||||
|
|
||||||
<div class="stats-speed">
|
<div class="stats-speed">
|
||||||
@@ -88,12 +78,7 @@ import Train from "@/scripts/interfaces/Train";
|
|||||||
@Component
|
@Component
|
||||||
export default class TrainStats extends Vue {
|
export default class TrainStats extends Vue {
|
||||||
@Prop() readonly trains!: Train[];
|
@Prop() readonly trains!: Train[];
|
||||||
|
@Prop() readonly trainStatsOpen!: boolean;
|
||||||
statsOpen: boolean = false;
|
|
||||||
|
|
||||||
toggleStats() {
|
|
||||||
this.statsOpen = !this.statsOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
get speedStats(): { avg: string; min: string; max: string } {
|
get speedStats(): { avg: string; min: string; max: string } {
|
||||||
if (this.trains.length == 0) return { avg: "0", min: "0", max: "0" };
|
if (this.trains.length == 0) return { avg: "0", min: "0", max: "0" };
|
||||||
@@ -217,6 +202,7 @@ export default class TrainStats extends Vue {
|
|||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -99,7 +99,7 @@
|
|||||||
"option-speed": "prędkość",
|
"option-speed": "prędkość",
|
||||||
"option-length": "długość",
|
"option-length": "długość",
|
||||||
"option-distance": "kilometraż",
|
"option-distance": "kilometraż",
|
||||||
"option-timetable": "numer pociagu",
|
"option-timetable": "numer pociągu",
|
||||||
"search-no": "Szukaj nr pociągu...",
|
"search-no": "Szukaj nr pociągu...",
|
||||||
"search-driver": "Szukaj maszynisty...",
|
"search-driver": "Szukaj maszynisty...",
|
||||||
"detailed-timetable": "Szczegółowy rozkład jazdy pociągu ",
|
"detailed-timetable": "Szczegółowy rozkład jazdy pociągu ",
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
import Station from "../interfaces/Station";
|
||||||
|
import TrainStop from "../interfaces/TrainStop";
|
||||||
|
|
||||||
|
const timetableURL = (trainNo: number) => `https://api.td2.info.pl:9640/?method=readFromSWDR&value=getTimetable%3B${trainNo}%3Beu`;
|
||||||
|
const getLocoURL = (locoType: string) => `https://rj.td2.info.pl/dist/img/thumbnails/${locoType.includes("EN") ? locoType + "rb" : locoType}.png`;
|
||||||
|
|
||||||
|
const getStatusID = (stationStatus: any) => {
|
||||||
|
if (!stationStatus) return "not-signed";
|
||||||
|
|
||||||
|
const statusCode = stationStatus[2];
|
||||||
|
const statusTimestamp = stationStatus[3];
|
||||||
|
|
||||||
|
switch (statusCode) {
|
||||||
|
case 0:
|
||||||
|
if (statusTimestamp - Date.now() > 21000000) return "no-limit";
|
||||||
|
|
||||||
|
return "online";
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return "brb";
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (statusTimestamp == 0) return "ending";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
return "no-space";
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unavailable";
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStatusTimestamp = (stationStatus: any) => {
|
||||||
|
if (!stationStatus) return -2;
|
||||||
|
|
||||||
|
const statusCode = stationStatus[2];
|
||||||
|
const statusTimestamp = stationStatus[3];
|
||||||
|
|
||||||
|
switch (statusCode) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
return statusTimestamp;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (statusTimestamp == 0) return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const parseSpawns = (spawnString: string) => {
|
||||||
|
if (!spawnString) return [];
|
||||||
|
if (spawnString === "NO_SPAWN") return [];
|
||||||
|
|
||||||
|
return spawnString.split(";").map(spawn => {
|
||||||
|
const spawnArray = spawn.split(",");
|
||||||
|
const spawnName = spawnArray[6] ? spawnArray[6] : spawnArray[0];
|
||||||
|
const spawnLength = parseInt(spawnArray[2]);
|
||||||
|
|
||||||
|
return { spawnName, spawnLength };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTimestamp = (date: string) => (date ? new Date(date).getTime() : 0);
|
||||||
|
|
||||||
|
const timestampToString = (timestamp: number) =>
|
||||||
|
new Date(timestamp).toLocaleTimeString("pl-PL", {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit"
|
||||||
|
});
|
||||||
|
|
||||||
|
const getTrainStopStatus = (stopInfo: TrainStop, timetableData: { currentStationName: string }, station: Station) => {
|
||||||
|
let stopStatus: string = "",
|
||||||
|
stopLabel: string = "",
|
||||||
|
stopStatusID: number = -1;
|
||||||
|
|
||||||
|
if (stopInfo.terminatesHere && stopInfo.confirmed) {
|
||||||
|
stopStatus = "terminated";
|
||||||
|
stopLabel = "Skończył bieg";
|
||||||
|
stopStatusID = 5;
|
||||||
|
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && timetableData.currentStationName == station.stationName) {
|
||||||
|
stopStatus = "departed";
|
||||||
|
stopLabel = "Odprawiony";
|
||||||
|
stopStatusID = 2;
|
||||||
|
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && timetableData.currentStationName != station.stationName) {
|
||||||
|
stopStatus = "departed-away";
|
||||||
|
stopLabel = "Odjechał";
|
||||||
|
stopStatusID = 4;
|
||||||
|
} else if (timetableData.currentStationName == station.stationName && !stopInfo.stopped) {
|
||||||
|
stopStatus = "online";
|
||||||
|
stopLabel = "Na stacji";
|
||||||
|
stopStatusID = 0;
|
||||||
|
} else if (timetableData.currentStationName == station.stationName && stopInfo.stopped) {
|
||||||
|
stopStatus = "stopped";
|
||||||
|
stopLabel = "Postój";
|
||||||
|
stopStatusID = 1;
|
||||||
|
} else if (timetableData.currentStationName != station.stationName) {
|
||||||
|
stopStatus = "arriving";
|
||||||
|
stopLabel = "W drodze";
|
||||||
|
stopStatusID = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { stopStatus, stopLabel, stopStatusID };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
timetableURL,
|
||||||
|
getLocoURL,
|
||||||
|
getStatusID,
|
||||||
|
parseSpawns,
|
||||||
|
getTimestamp,
|
||||||
|
timestampToString,
|
||||||
|
getStatusTimestamp,
|
||||||
|
getTrainStopStatus
|
||||||
|
};
|
||||||
@@ -15,23 +15,15 @@
|
|||||||
|
|
||||||
box-shadow: 0 0 15px 5px #474747;
|
box-shadow: 0 0 15px 5px #474747;
|
||||||
|
|
||||||
// width: 75%;
|
|
||||||
width: 650px;
|
width: 650px;
|
||||||
max-height: 95%;
|
max-height: 95%;
|
||||||
|
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
|
|
||||||
|
|
||||||
@include smallScreen {
|
@include smallScreen {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @include midScreen {
|
|
||||||
// width: 85%;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
&-exit {
|
&-exit {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|||||||
@@ -107,7 +107,6 @@ input {
|
|||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
|
|
||||||
padding: 0.15em;
|
padding: 0.15em;
|
||||||
margin: 0.2em;
|
|
||||||
|
|
||||||
max-width: 55px;
|
max-width: 55px;
|
||||||
outline: none;
|
outline: none;
|
||||||
@@ -141,33 +140,6 @@ input {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
background: #333;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
color: #bdbdbd;
|
|
||||||
|
|
||||||
font-size: 1em;
|
|
||||||
|
|
||||||
outline: none;
|
|
||||||
padding: 0.35em 0.5em;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
transition: all 0.3s;
|
|
||||||
|
|
||||||
&.open {
|
|
||||||
color: $accentCol;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: #5c5c5c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: white;
|
color: white;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|||||||
@@ -7,24 +7,11 @@
|
|||||||
{{ $t("journal.subtitle") }}
|
{{ $t("journal.subtitle") }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="search-box">
|
<!-- <select-box
|
||||||
<div class="search-box_content">
|
:itemList="filteredStationList"
|
||||||
<label :class="{ disabled: dataLoading }">
|
:title="$t('journal.select')"
|
||||||
<select v-model="inputStationName" :disabled="dataLoading">
|
@itemSelected="itemSelected"
|
||||||
<option value disabled selected hidden>
|
/> -->
|
||||||
{{ dataLoading ? $t("app.loading") : $t("journal.select") }}
|
|
||||||
</option>
|
|
||||||
<option
|
|
||||||
v-for="station in filteredStationList"
|
|
||||||
:key="station"
|
|
||||||
:value="station"
|
|
||||||
>
|
|
||||||
{{ station }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="disclaimer" v-html="$t('journal.disclaimer')"></div>
|
<div class="disclaimer" v-html="$t('journal.disclaimer')"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -100,8 +87,9 @@ import { Getter } from "vuex-class";
|
|||||||
|
|
||||||
import Station from "@/scripts/interfaces/Station";
|
import Station from "@/scripts/interfaces/Station";
|
||||||
import ISceneryInfoData from "@/scripts/interfaces/ISceneryInfoData";
|
import ISceneryInfoData from "@/scripts/interfaces/ISceneryInfoData";
|
||||||
|
import SelectBox from "@/components/Global/SelectBox.vue";
|
||||||
|
|
||||||
@Component
|
@Component({ components: { SelectBox } })
|
||||||
export default class HistoryView extends Vue {
|
export default class HistoryView extends Vue {
|
||||||
@Getter("getStationList") stationList!: Station[];
|
@Getter("getStationList") stationList!: Station[];
|
||||||
|
|
||||||
@@ -133,11 +121,6 @@ export default class HistoryView extends Vue {
|
|||||||
this.dataLoading = false;
|
this.dataLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Watch("inputStationName")
|
|
||||||
onInputChanged(val: string) {
|
|
||||||
this.itemSelected(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get filteredStationList() {
|
get filteredStationList() {
|
||||||
return this.sceneryHistoryList
|
return this.sceneryHistoryList
|
||||||
.map((station) => station.stationName)
|
.map((station) => station.stationName)
|
||||||
|
|||||||
+51
-101
@@ -1,28 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="stations_view">
|
<div class="stations-view">
|
||||||
<DonationModal :modalHidden="modalHidden" @toggleModal="toggleModal" />
|
<DonationModal :modalHidden="modalHidden" @toggleModal="toggleModal" />
|
||||||
|
|
||||||
<div class="stations_wrapper">
|
<div class="wrapper">
|
||||||
<div class="stations_body">
|
<div class="body">
|
||||||
<div class="body_bar">
|
<div class="options-bar">
|
||||||
<div class="bar_actions">
|
<action-button @click.native="() => toggleCardsState('filter')">
|
||||||
<button
|
|
||||||
class="action-btn"
|
|
||||||
:class="{ open: filterCardOpen }"
|
|
||||||
@click="() => toggleCardsState('filter')"
|
|
||||||
>
|
|
||||||
<img
|
<img
|
||||||
|
class="button_icon"
|
||||||
:src="require('@/assets/icon-filter2.svg')"
|
:src="require('@/assets/icon-filter2.svg')"
|
||||||
alt="icon-filter"
|
alt="icon-filter"
|
||||||
/>
|
/>
|
||||||
<p>{{ $t("options.filters") }}</p>
|
<p>{{ $t("options.filters") }}</p>
|
||||||
</button>
|
</action-button>
|
||||||
|
|
||||||
<!-- <button class="action-btn" @click="toggleModal">
|
|
||||||
<img :src="dolarIcon" alt="icon-dolar" />
|
|
||||||
|
|
||||||
<p>{{ $t("options.donate") }}</p>
|
|
||||||
</button> -->
|
|
||||||
</div>
|
</div>
|
||||||
<!--
|
<!--
|
||||||
<div class="bar_indicators">
|
<div class="bar_indicators">
|
||||||
@@ -46,9 +36,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</transition>
|
</transition>
|
||||||
</div> -->
|
</div> -->
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="body_table">
|
|
||||||
<StationTable
|
<StationTable
|
||||||
:stations="computedStations"
|
:stations="computedStations"
|
||||||
:sorterActive="filterManager.getSorter()"
|
:sorterActive="filterManager.getSorter()"
|
||||||
@@ -57,7 +45,6 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<transition name="card-anim">
|
<transition name="card-anim">
|
||||||
<FilterCard
|
<FilterCard
|
||||||
@@ -83,14 +70,15 @@ import inputData from "@/data/options.json";
|
|||||||
|
|
||||||
import StationTable from "@/components/StationsView/StationTable.vue";
|
import StationTable from "@/components/StationsView/StationTable.vue";
|
||||||
import FilterCard from "@/components/StationsView/FilterCard.vue";
|
import FilterCard from "@/components/StationsView/FilterCard.vue";
|
||||||
|
|
||||||
import DonationModal from "@/components/Global/DonationModal.vue";
|
import DonationModal from "@/components/Global/DonationModal.vue";
|
||||||
|
import ActionButton from "@/components/Global/ActionButton.vue";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
StationTable,
|
StationTable,
|
||||||
FilterCard,
|
FilterCard,
|
||||||
DonationModal,
|
DonationModal,
|
||||||
|
ActionButton,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class StationsView extends Vue {
|
export default class StationsView extends Vue {
|
||||||
@@ -227,6 +215,17 @@ export default class StationsView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes blinkAnim {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.indicator-anim {
|
.indicator-anim {
|
||||||
&-enter-active,
|
&-enter-active,
|
||||||
&-leave-active {
|
&-leave-active {
|
||||||
@@ -240,110 +239,61 @@ export default class StationsView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stations_view {
|
.stations-view {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
padding: 1em 0;
|
padding: 1em 0;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stations_wrapper {
|
.wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
padding: 0 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stations_body {
|
.body {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.body_bar {
|
.options-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bar_actions {
|
// .bar_indicators {
|
||||||
width: 100%;
|
// border: 1px solid red;
|
||||||
|
|
||||||
font-size: 1.1em;
|
// & > span {
|
||||||
}
|
// margin-left: 0.5em;
|
||||||
|
// padding: 0.5em 0.5em;
|
||||||
|
|
||||||
.bar_indicators {
|
// // background-color: #e68e00;
|
||||||
border: 1px solid red;
|
// border-radius: 1em 1em 0 0;
|
||||||
|
|
||||||
> span {
|
// &.loading {
|
||||||
margin-left: 0.5em;
|
// background-color: $accentCol;
|
||||||
padding: 0.5em 0.5em;
|
// }
|
||||||
|
|
||||||
// background-color: #e68e00;
|
// &.error {
|
||||||
border-radius: 1em 1em 0 0;
|
// background-color: $errorCol;
|
||||||
|
// }
|
||||||
|
|
||||||
&.loading {
|
// &.success {
|
||||||
background-color: $accentCol;
|
// background-color: $secondaryCol;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&.error {
|
// & > img {
|
||||||
background-color: $errorCol;
|
// width: 1.7em;
|
||||||
}
|
// animation: blinkAnim 2s ease-in-out infinite forwards;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
&.success {
|
@include smallScreen {
|
||||||
background-color: $secondaryCol;
|
.options-bar {
|
||||||
}
|
font-size: 1.2em;
|
||||||
|
|
||||||
& > img {
|
|
||||||
width: 1.7em;
|
|
||||||
animation: blinkAnim 2s ease-in-out infinite forwards;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-btn {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
background: #333;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
color: #e0e0e0;
|
|
||||||
font-size: 1em;
|
|
||||||
|
|
||||||
padding: 0.3em;
|
|
||||||
|
|
||||||
outline: none;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
transition: all 0.3s;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 1.3em;
|
|
||||||
margin-right: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 1em;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
transition: max-width 0.35s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $accentCol;
|
|
||||||
background: rgba(#e0e0e0, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.open {
|
|
||||||
color: $accentCol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes blinkAnim {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="trains-view">
|
<section class="trains-view">
|
||||||
<div class="body-wrapper">
|
<div class="wrapper">
|
||||||
<!-- <TrainSorter :trainList="computedTrains" @changeSorter="changeSorter" />
|
<!-- <TrainSorter :trainList="computedTrains" @changeSorter="changeSorter" />
|
||||||
<TrainSearch
|
<TrainSearch
|
||||||
@changeSearchedTrain="changeSearchedTrain"
|
@changeSearchedTrain="changeSearchedTrain"
|
||||||
@@ -10,11 +10,17 @@
|
|||||||
/> -->
|
/> -->
|
||||||
|
|
||||||
<div class="options-bar">
|
<div class="options-bar">
|
||||||
<TrainStats :trains="trains" class="test" />
|
<div class="stats">
|
||||||
|
<action-button @click.native="toggleStats">
|
||||||
|
{{ $t("trains.stats") }}
|
||||||
|
</action-button>
|
||||||
|
<TrainStats :trains="trains" :trainStatsOpen="trainStatsOpen" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<TrainOptions
|
<TrainOptions
|
||||||
:queryTrain="queryTrain"
|
:queryTrain="queryTrain"
|
||||||
:focusedTrain="focusedTrain"
|
:focusedTrain="focusedTrain"
|
||||||
@changeSorter="changeSorter"
|
@change-sorter="changeSorter"
|
||||||
@changeSearchedTrain="changeSearchedTrain"
|
@changeSearchedTrain="changeSearchedTrain"
|
||||||
@changeSearchedDriver="changeSearchedDriver"
|
@changeSearchedDriver="changeSearchedDriver"
|
||||||
/>
|
/>
|
||||||
@@ -30,7 +36,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import { Component, Prop } from "vue-property-decorator";
|
import { Component, Prop, Watch } from "vue-property-decorator";
|
||||||
import { Getter } from "vuex-class";
|
import { Getter } from "vuex-class";
|
||||||
|
|
||||||
import Train from "@/scripts/interfaces/Train";
|
import Train from "@/scripts/interfaces/Train";
|
||||||
@@ -38,12 +44,14 @@ import Train from "@/scripts/interfaces/Train";
|
|||||||
import TrainTable from "@/components/TrainsView/TrainTable.vue";
|
import TrainTable from "@/components/TrainsView/TrainTable.vue";
|
||||||
import TrainStats from "@/components/TrainsView/TrainStats.vue";
|
import TrainStats from "@/components/TrainsView/TrainStats.vue";
|
||||||
import TrainOptions from "@/components/TrainsView/TrainOptions.vue";
|
import TrainOptions from "@/components/TrainsView/TrainOptions.vue";
|
||||||
|
import ActionButton from "@/components/Global/ActionButton.vue";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
TrainTable,
|
TrainTable,
|
||||||
TrainStats,
|
TrainStats,
|
||||||
TrainOptions,
|
TrainOptions,
|
||||||
|
ActionButton,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class TrainsView extends Vue {
|
export default class TrainsView extends Vue {
|
||||||
@@ -54,12 +62,20 @@ export default class TrainsView extends Vue {
|
|||||||
|
|
||||||
sorterActive: { id: string; dir: number } = { id: "distance", dir: -1 };
|
sorterActive: { id: string; dir: number } = { id: "distance", dir: -1 };
|
||||||
|
|
||||||
|
trainStatsOpen: boolean = false;
|
||||||
|
|
||||||
searchedTrain: string = "";
|
searchedTrain: string = "";
|
||||||
searchedDriver: string = "";
|
searchedDriver: string = "";
|
||||||
focusedTrain: string = "";
|
focusedTrain: string = "";
|
||||||
|
|
||||||
|
toggleStats() {
|
||||||
|
this.trainStatsOpen = !this.trainStatsOpen;
|
||||||
|
}
|
||||||
|
|
||||||
changeSearchedTrain(trainNo: string) {
|
changeSearchedTrain(trainNo: string) {
|
||||||
this.searchedTrain = trainNo;
|
this.searchedTrain = trainNo;
|
||||||
|
|
||||||
|
console.log("train", trainNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeSearchedDriver(name: string) {
|
changeSearchedDriver(name: string) {
|
||||||
@@ -73,6 +89,14 @@ export default class TrainsView extends Vue {
|
|||||||
changeSorter(sorter: { id: string; dir: number }) {
|
changeSorter(sorter: { id: string; dir: number }) {
|
||||||
this.sorterActive = sorter;
|
this.sorterActive = sorter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Watch("queryTrain")
|
||||||
|
// onQueryTrainChanged(train: string) {
|
||||||
|
// // this.searchedTrain = train;
|
||||||
|
// this.changeSearchedTrain(train);
|
||||||
|
// console.log(train);
|
||||||
|
// }
|
||||||
|
|
||||||
get computedTrains() {
|
get computedTrains() {
|
||||||
return this.trains
|
return this.trains
|
||||||
.filter(
|
.filter(
|
||||||
@@ -130,16 +154,24 @@ export default class TrainsView extends Vue {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.body-wrapper {
|
.wrapper {
|
||||||
margin: 1rem auto;
|
margin: 1rem auto;
|
||||||
max-width: 1300px;
|
max-width: 1300px;
|
||||||
|
|
||||||
padding: 0 0.5rem;
|
padding: 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options-bar button {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include smallScreen {
|
@include smallScreen {
|
||||||
.options-bar {
|
.options-bar {
|
||||||
font-size: 1.15em;
|
font-size: 1.25em;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user