Zmiana wyglądów filtrów

This commit is contained in:
2020-07-11 01:01:52 +02:00
parent e5235b6907
commit f5db877129
7 changed files with 447 additions and 358 deletions
+4
View File
@@ -75,6 +75,10 @@ export default Vue.extend({
@import "./styles/responsive.scss"; @import "./styles/responsive.scss";
@import "./styles/variables.scss"; @import "./styles/variables.scss";
:root {
font-size: 16px;
}
html { html {
scroll-behavior: smooth; scroll-behavior: smooth;
} }
+3
View File
@@ -0,0 +1,3 @@
<svg width="34" height="34" viewBox="0 0 34 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 2L32 32M32 2L2 32" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="bevel"/>
</svg>

After

Width:  |  Height:  |  Size: 215 B

+1 -1
View File
@@ -273,7 +273,7 @@ export default Vue.extend({
font-size: calc(0.6rem + 0.35vw); font-size: calc(0.6rem + 0.35vw);
@include smallScreen() { @include smallScreen() {
font-size: 0.65rem; font-size: 0.75rem;
} }
thead th { thead th {
+1 -1
View File
@@ -37,7 +37,7 @@ export default Vue.extend({
} }
.button { .button {
font-size: 0.8em; font-size: 0.9em;
img { img {
width: 1.3em; width: 1.3em;
+415 -318
View File
@@ -1,168 +1,51 @@
<template> <template>
<transition name="slide"> <transition name="slide">
<div class="list-filter"> <section class="filter-card">
<div class="exit" @click="exitFilters">X</div> <div class="card-exit" @click="exit">
<div class="list-filter-title">FILTRY</div> <img :src="require('@/assets/icon-exit.svg')" alt="exit icon" />
<ul class="grid"> </div>
<li class="grid-row">
<div class="grid-col" v-for="(el, i) in gridElements" :key="i">
<div class="grid-item">
<div class="item-title">{{el.title}}</div>
<div class="item-content"> <div class="card-title flex">FILTRY</div>
<div class="item-input" v-for="(item, i) in el.items" :key="i">
<input
:type="el.type"
:id="item.id"
:name="item.name"
v-model="item.value"
checked
@change="handleChange"
/>
<label :for="item.id">{{ item.content }}</label>
</div>
</div>
</div>
</div>
</li>
<li class="grid-row"> <div class="card-options">
<div class="grid-col"> <div class="option" v-for="(option, i) in options" :key="i">
<div class="grid-item"> <label class="option-label">
<div class="item-title">Poziomy dyżurnego</div> <input
class="option-input"
type="checkbox"
:name="option.name"
:id="option.id"
v-model="option.value"
@change="handleChange"
/>
<span class="option-content" :class="option.section">{{option.content}}</span>
</label>
</div>
</div>
<div class="item-content centered"> <div class="card-sliders">
<div class="item-input" style="text-align: center;"> <div class="slider" v-for="(slider, i) in sliders" :key="i">
<input <input
v-model="levelFrom" class="slider-input"
type="number" type="range"
name="level-from" :name="slider.name"
min="0" :id="slider.id"
max="25" :min="slider.minRange"
@change="handleInput" :max="slider.maxRange"
/> v-model="slider.value"
<span>&nbsp;do&nbsp;</span> @change="handleInput"
<input />
v-model="levelTo"
type="number"
name="level-to"
min="0"
max="20"
value="20"
@change="handleInput"
/>
</div>
</div>
</div>
</div>
</li>
<li class="grid-row"> <span class="slider-value">{{slider.value}}</span>
<div class="grid-col">
<div class="grid-item">
<div class="item-title">
Szlaki jednotorowe
<div>(minimum)</div>
</div>
<div class="item-content"> <div class="slider-content">{{slider.content}}</div>
<div class="item-input"> </div>
<input </div>
v-model="oneWay"
type="checkbox"
id="no-1track"
name="no-1track"
checked
@change="handleChange"
/>
<label for="no-1track">Jednotory</label>
</div>
<div class="item-input"> <div class="card-reset flex">
<input <button class="button" @click="reset">RESET FILTRÓW</button>
v-model="oneWayCatenary" </div>
type="number" </section>
name="1track-e"
min="0"
max="5"
placeholder="0"
@change="handleInput"
/>
<span>&nbsp;Zelektryfikowane</span>
</div>
<div class="item-input">
<input
v-model="oneWayOther"
type="number"
name="1track-ne"
min="0"
max="5"
placeholder="0"
@change="handleInput"
/>
<span>&nbsp;Niezelektryfikowane</span>
</div>
</div>
</div>
</div>
<div class="grid-col">
<div class="grid-item">
<div class="item-title">
Szlaki dwutorowe
<div>(minimum)</div>
</div>
<div class="item-content">
<div class="item-input">
<input
v-model="twoWay"
type="checkbox"
id="no-2track"
name="no-2track"
ref="2track"
checked
@change="handleChange"
/>
<label for="no-2track">Dwutory</label>
</div>
<div class="item-input">
<input
v-model="twoWayCatenary"
type="number"
name="2track-e"
min="0"
max="5"
placeholder="0"
@change="handleInput"
/>
<span>&nbsp;Zelektryfikowane</span>
</div>
<div class="item-input">
<input
v-model="twoWayOther"
type="number"
name="2track-ne"
min="0"
max="5"
placeholder="0"
@change="handleInput"
/>
<span>&nbsp;Niezelektryfikowane</span>
</div>
</div>
</div>
</div>
</li>
<li class="grid-row">
<button class="button" @click="reset">RESET FILTRÓW</button>
</li>
</ul>
</div>
</transition> </transition>
</template> </template>
@@ -172,119 +55,170 @@ import { mapActions } from "vuex";
export default Vue.extend({ export default Vue.extend({
name: "list-filter", name: "list-filter",
watch: {
gridElements: {
handler: (v1, v2) => {},
deep: true
}
},
data: () => ({ data: () => ({
oneWay: true, options: [
twoWay: true, {
levelFrom: 0, id: "is-default",
levelTo: 20, name: "default",
oneWayCatenary: 0, section: "access",
oneWayOther: 0, value: true,
twoWayCatenary: 0, defaultValue: true,
twoWayOther: 0, content: "W PACZCE"
},
gridElements: { {
access: { id: "not-default",
title: "Dostępność", name: "notDefault",
type: "checkbox", section: "access",
items: [ value: true,
{ defaultValue: true,
id: "is-default", content: "POZA PACZKĄ"
value: true, },
name: "default", {
content: "w paczce z grą" id: "non-public",
}, name: "nonPublic",
{ section: "access",
id: "not-default", value: true,
value: true, defaultValue: true,
name: "notDefault", content: "NIEPUBLICZNA"
content: "poza paczką z grą" },
}, {
{ id: "SPK",
id: "non-public", name: "SPK",
value: true, section: "control",
name: "nonPublic", value: true,
content: "niepubliczna" defaultValue: true,
} content: "SPK"
] },
{
id: "SCS",
name: "SCS",
section: "control",
value: true,
defaultValue: true,
content: "SCS"
},
{
id: "by-hand",
name: "ręczne",
section: "control",
value: true,
defaultValue: true,
content: "RĘCZNE"
},
{
id: "levers",
name: "mechaniczne",
section: "control",
value: true,
defaultValue: true,
content: "MECHANICZNE"
},
{
id: "modern",
name: "współczesna",
section: "signals",
value: true,
defaultValue: true,
content: "WSPÓŁCZESNA"
},
{
id: "semaphore",
name: "kształtowa",
section: "signals",
value: true,
defaultValue: true,
content: "KSZTAŁTOWA"
},
{
id: "mixed",
name: "mieszana",
section: "signals",
value: true,
defaultValue: true,
content: "MIESZANA"
},
{
id: "historic",
name: "historyczna",
section: "signals",
value: true,
defaultValue: true,
content: "HISTORYCZNA"
}, },
control: { {
title: "Sterowanie", id: "free",
type: "checkbox", name: "free",
section: "status",
items: [ value: true,
{ defaultValue: true,
id: "SPK", content: "WOLNA"
value: true,
name: "SPK",
content: "SPK"
},
{
id: "SCS",
value: true,
name: "SCS",
content: "SCS"
},
{
id: "by-hand",
value: true,
name: "ręczne",
content: "ręczne"
},
{
id: "levers",
value: true,
name: "mechaniczne",
content: "mechaniczne"
}
]
}, },
{
signals: { id: "occupied",
title: "Sygnalizacja", name: "occupied",
type: "checkbox", section: "status",
value: true,
items: [ defaultValue: true,
{ content: "ZAJĘTA"
id: "modern",
value: true,
name: "współczesna",
content: "współczesna"
},
{
id: "semaphore",
value: true,
name: "kształtowa",
content: "kształtowa"
},
{
id: "mixed",
value: true,
name: "mieszana",
content: "mieszana"
},
{
id: "historic",
value: true,
name: "historyczna",
content: "historyczna"
}
]
}, },
{
status: { id: "ending",
title: "Status", name: "ending",
type: "checkbox", section: "status",
value: true,
items: [] defaultValue: true,
content: "KOŃCZY"
} }
} ],
sliders: [
{
id: "min-level",
name: "minLevel",
minRange: 0,
maxRange: 20,
value: 0,
defaultValue: 0,
content: "MINIMALNY WYMAGANY POZIOM DYŻURNEGO"
},
{
id: "min-oneway-e",
name: "minOneWayCatenary",
minRange: 0,
maxRange: 5,
value: 0,
defaultValue: 0,
content: "MINIMALNA LICZBA SZLAKÓW JEDNOTOROWYCH ZELEKTRYFIKOWANYCH"
},
{
id: "min-oneway-ne",
name: "minOneWay",
minRange: 0,
maxRange: 5,
value: 0,
defaultValue: 0,
content: "MINIMALNA LICZBA SZLAKÓW JEDNOTOROWYCH NIEZELEKTRYFIKOWANYCH"
},
{
id: "min-twoway-e",
name: "minTwoWayCatenary",
minRange: 0,
maxRange: 5,
value: 0,
defaultValue: 0,
content: "MINIMALNA LICZBA SZLAKÓW DWUTOROWYCH ZELEKTRYFIKOWANYCH"
},
{
id: "min-twoway-ne",
name: "minTwoWay",
minRange: 0,
maxRange: 5,
value: 0,
defaultValue: 0,
content: "MINIMALNA LICZBA SZLAKÓW DWUTOROWYCH NIEZELEKTRYFIKOWANYCH"
}
]
}), }),
props: ["exit"], props: ["exit"],
methods: { methods: {
@@ -299,20 +233,8 @@ export default Vue.extend({
}); });
}, },
reset() { reset() {
for (const [key, value] of Object.entries(this.gridElements)) { this.options.forEach(option => (option.value = option.defaultValue));
for (const item of this.gridElements[key].items) { this.sliders.forEach(slider => (slider.value = slider.defaultValue));
item.value = true;
}
}
this.oneWay = true;
this.twoWay = true;
this.levelFrom = 0;
this.levelTo = 20;
this.oneWayCatenary = 0;
this.oneWayOther = 0;
this.twoWayCatenary = 0;
this.twoWayOther = 0;
this.resetFilters(); this.resetFilters();
}, },
@@ -337,74 +259,249 @@ export default Vue.extend({
opacity: 0; opacity: 0;
} }
.list-filter { .filter-card {
position: fixed; position: fixed;
top: 50%; top: 50%;
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
z-index: 0;
overflow: auto; overflow: auto;
max-height: 90%; max-height: 95vh;
padding: 0.5em; padding: 0.5em;
max-width: 600px;
width: 65%;
background: rgba(black, 0.85); background: #262a2e;
white-space: nowrap;
font-size: calc(0.6rem + 0.4vw); font-size: calc(0.75rem + 0.4vw);
@include smallScreen() { @include smallScreen() {
width: 100vw; width: 85vw;
font-size: 1em; font-size: 1em;
} }
box-shadow: 0 0 15px 5px #474747;
}
.card {
&-exit {
position: absolute;
top: 0;
right: 0;
margin: 0.8em;
img {
width: 1.1em;
}
cursor: pointer;
}
&-title {
font-size: 2em;
font-weight: 700;
color: $accentCol;
margin: 0.5em 0;
}
&-options {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(6em, 1fr));
padding: 0 1.5em;
}
&-sliders {
margin-top: 1em;
}
&-reset {
margin-top: 0.7em;
}
} }
.exit { .option {
position: absolute; margin: 0.3em;
top: 0;
right: 0;
padding: 0.4rem;
font-size: calc(1rem + 0.4vw);
cursor: pointer; &-input {
} display: none;
.list-filter-title { &:not(:checked) + span {
text-align: center; background-color: #585858;
font-size: 1.9em;
font-weight: bold;
}
.grid { &::before {
&-row { box-shadow: none;
display: flex; }
justify-content: center;
@include smallScreen() {
flex-wrap: wrap;
} }
} }
&-col { &-content {
padding: 0.3rem;
}
&-item {
user-select: none; user-select: none;
-moz-user-select: none; -moz-user-select: none;
-webkit-user-select: none; -webkit-user-select: none;
}
}
.item { width: 100%;
&-title {
text-align: center; text-align: center;
margin-bottom: 0.5rem;
font-weight: bold; cursor: pointer;
color: $accentCol;
padding: 0.6em 0.5em;
border-radius: 0.4em;
font-size: 0.65em;
background-color: #333;
display: inline-block;
position: relative;
transition: all 0.2s;
&.access {
background-color: #e03b07;
&::before {
box-shadow: 0 0 6px 1px #e03b07;
}
}
&.control {
background-color: #0085ff;
&::before {
box-shadow: 0 0 6px 1px #0085ff;
}
}
&.signals {
background-color: #b000bf;
&::before {
box-shadow: 0 0 6px 1px #b000bf;
}
}
&.status {
background-color: #05b702;
&::before {
box-shadow: 0 0 6px 1px #05b702;
}
}
&::before {
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: inherit;
}
} }
} }
button.button { .slider {
margin-top: 0.5em; display: flex;
padding: 0.5em;
&-value {
display: flex;
justify-content: center;
align-items: center;
color: $accentCol;
margin-right: 0.3em;
padding: 0.1em 0.2em;
font-size: 1.1em;
font-weight: 500;
border-radius: 0.2em;
}
&-content {
display: flex;
align-items: center;
font-size: 0.6em;
}
&-input {
-webkit-appearance: none;
appearance: none;
background: none;
border: none;
outline: none;
min-width: 25%;
&::-webkit-slider-thumb {
-webkit-appearance: none;
height: 20px;
width: 20px;
margin-top: -7px;
border-radius: 50%;
background: white;
border: 4px solid $accentCol;
@include smallScreen() {
width: 15px;
height: 15px;
margin-top: -5px;
border: 3px solid $accentCol;
}
}
&::-moz-range-thumb {
height: 15px;
width: 15px;
border-radius: 50%;
background: white;
border: 4px solid $accentCol;
cursor: pointer;
@include smallScreen() {
width: 15px;
height: 15px;
border: 3px solid $accentCol;
}
}
&::-webkit-slider-runnable-track {
width: 100%;
height: 5px;
cursor: pointer;
background: #ffffff;
border-radius: 1em;
}
&::-moz-range-track {
width: 100%;
height: 5px;
cursor: pointer;
background: #ffffff;
border-radius: 1em;
}
&::-ms-track {
width: 100%;
height: 5px;
cursor: pointer;
background: #ffffff;
border-radius: 1em;
}
}
} }
</style> </style>
+22 -37
View File
@@ -23,9 +23,10 @@ class Store extends VuexModule {
signalType: string; signalType: string;
controlType: string; controlType: string;
default: boolean; default: boolean;
nonPublic: boolean nonPublic: boolean;
routes: { oneWay: { catenary: number; noCatenary: number; }, twoWay: { catenary: number; noCatenary: number; } }; routes: { oneWay: { catenary: number; noCatenary: number; }, twoWay: { catenary: number; noCatenary: number; } };
online: boolean; online: boolean;
occupiedTo: string;
}[] = []; }[] = [];
private filteredStations: {}[] = []; private filteredStations: {}[] = [];
@@ -42,38 +43,19 @@ class Store extends VuexModule {
"kształtowa": false, "kształtowa": false,
"historyczna": false, "historyczna": false,
"mieszana": false, "mieszana": false,
"levelFrom": 0, "minLevel": 0,
"levelTo": 20, "minOneWayCatenary": 0,
"1track-ne": 0, "minOneWay": 0,
"2track-ne": 0, "minTwoWayCatenary": 0,
"1track-e": 0, "minTwoWay": 0,
"2track-e": 0,
"no-1track": false, "no-1track": false,
"no-2track": false "no-2track": false,
"free": false,
"occupied": false,
"ending": false
} as const; } as const;
private filters = { private filters: any = this.filterInitStates;
"default": false,
"notDefault": false,
"nonPublic": false,
"SPK": false,
"SCS": false,
"ręczne": false,
"mechaniczne": false,
"współczesna": false,
"kształtowa": false,
"historyczna": false,
"mieszana": false,
"levelFrom": 0,
"levelTo": 20,
"1track-ne": 0,
"2track-ne": 0,
"1track-e": 0,
"2track-e": 0,
"no-1track": false,
"no-2track": false
} as any;
get getStationCount(): number { get getStationCount(): number {
return this.stationCount; return this.stationCount;
@@ -210,21 +192,23 @@ class Store extends VuexModule {
if ((station.nonPublic || !station.reqLevel) && this.filters['nonPublic']) return false; if ((station.nonPublic || !station.reqLevel) && this.filters['nonPublic']) return false;
if (!station.reqLevel) return true; if (!station.reqLevel) return true;
if (station.online && this.filters['occupied']) return false;
if (!station.online && this.filters['free']) return false;
if (station.online && station.occupiedTo == "KOŃCZY" && this.filters['ending']) return false;
if (station.default && this.filters['default']) return false; if (station.default && this.filters['default']) return false;
if (!station.default && this.filters['notDefault']) return false; if (!station.default && this.filters['notDefault']) return false;
if (station.reqLevel < this.filters['level-from']) return false; if (station.reqLevel < this.filters['minLevel']) return false;
if (station.reqLevel > this.filters['level-to']) return false;
if (this.filters["no-1track"] && (station.routes.oneWay.catenary != 0 || station.routes.oneWay.noCatenary != 0)) return false; if (this.filters["no-1track"] && (station.routes.oneWay.catenary != 0 || station.routes.oneWay.noCatenary != 0)) return false;
if (this.filters["no-2track"] && (station.routes.twoWay.catenary != 0 || station.routes.twoWay.noCatenary != 0)) return false; if (this.filters["no-2track"] && (station.routes.twoWay.catenary != 0 || station.routes.twoWay.noCatenary != 0)) return false;
if (station.routes.oneWay.catenary < this.filters['1track-e']) return false; if (station.routes.oneWay.catenary < this.filters['minOneWayCatenary']) return false;
if (station.routes.oneWay.noCatenary < this.filters['1track-ne']) return false; if (station.routes.oneWay.noCatenary < this.filters['minOneWay']) return false;
if (station.routes.twoWay.catenary < this.filters['2track-e']) return false;
if (station.routes.twoWay.noCatenary < this.filters['2track-ne']) return false;
if (station.routes.twoWay.catenary < this.filters['minTwoWayCatenary']) return false;
if (station.routes.twoWay.noCatenary < this.filters['minTwoWay']) return false;
if (this.filters[station.controlType]) return false; if (this.filters[station.controlType]) return false;
if (this.filters[station.signalType]) return false; if (this.filters[station.signalType]) return false;
@@ -271,6 +255,7 @@ class Store extends VuexModule {
if (!toUpdate) { if (!toUpdate) {
this.stations[i].online = false; this.stations[i].online = false;
this.stations[i].occupiedTo = "WOLNA";
continue; continue;
} }
+1 -1
View File
@@ -6,5 +6,5 @@ $bgCol: #525252;
$errorCol: #ff1919; $errorCol: #ff1919;
$warningCol: #ff975b; $warningCol: #ff975b;
$accentCol: #ffc62b; $accentCol: #ffc014;
$accent2Col: #ff3d5d; $accent2Col: #ff3d5d;