Zmieniono położenie filtrów

This commit is contained in:
2020-07-06 15:57:44 +02:00
parent 2ee6c6bfeb
commit 57bb48c030
11 changed files with 195 additions and 134 deletions
+6
View File
@@ -10157,6 +10157,12 @@
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz", "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz",
"integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw==" "integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw=="
}, },
"vuex-module-decorators": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/vuex-module-decorators/-/vuex-module-decorators-0.17.0.tgz",
"integrity": "sha512-EFzrR3oyRMTHwpIgYzhW0BVKD71+FBs2U5Mn/ZQwlsaPyROZexDXTZTSYOYeuwg0kqQsK/YBkG4sQ8B4jmVMPg==",
"dev": true
},
"watchpack": { "watchpack": {
"version": "1.7.2", "version": "1.7.2",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz",
+2 -1
View File
@@ -23,7 +23,8 @@
"sass": "^1.26.5", "sass": "^1.26.5",
"sass-loader": "^8.0.2", "sass-loader": "^8.0.2",
"typescript": "~3.9.3", "typescript": "~3.9.3",
"vue-template-compiler": "^2.6.11" "vue-template-compiler": "^2.6.11",
"vuex-module-decorators": "^0.17.0"
}, },
"browserslist": [ "browserslist": [
"> 1%", "> 1%",
+8 -7
View File
@@ -10,7 +10,7 @@
</header> </header>
<div class="app-info"> <div class="app-info">
<span>Scenerie online: {{stations.length}} | Maszyniści online: {{ trainCount }}</span> <span>Scenerie online: {{stationCount}} | Maszyniści online: {{ trainCount }}</span>
</div> </div>
<main class="app-main"> <main class="app-main">
@@ -38,7 +38,8 @@ export default Vue.extend({
components: { Error, Loading }, components: { Error, Loading },
computed: mapGetters({ computed: mapGetters({
stations: "getStations", stations: "getStations",
trainCount: "getTrainCount" trainCount: "getTrainCount",
stationCount: "getStationCount"
}), }),
methods: { methods: {
@@ -81,6 +82,11 @@ body {
min-height: 100vh; min-height: 100vh;
} }
button,
input {
font-family: "Lato", sans-serif;
}
*, *,
*::before, *::before,
*::after { *::after {
@@ -146,11 +152,6 @@ a {
padding: 0.3rem; padding: 0.3rem;
} }
&-main {
display: flex;
justify-content: center;
}
} }
footer { footer {
+2
View File
@@ -19,6 +19,8 @@ export default {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
min-height: 100vh;
flex-direction: column; flex-direction: column;
font-size: calc(1rem + 1.5vw); font-size: calc(1rem + 1.5vw);
+2
View File
@@ -13,6 +13,8 @@ export default Vue.extend({});
justify-content: center; justify-content: center;
align-items: center; align-items: center;
min-height: 100vh;
font-size: calc(0.75rem + 1vw); font-size: calc(0.75rem + 1vw);
color: #fdc62f; color: #fdc62f;
+9 -7
View File
@@ -2,8 +2,6 @@
<div class="list"> <div class="list">
<Card :stationInfo="focusedStationInfo" :closeCard="closeCard" /> <Card :stationInfo="focusedStationInfo" :closeCard="closeCard" />
<Options />
<div class="table-wrapper"> <div class="table-wrapper">
<table class="table"> <table class="table">
<thead> <thead>
@@ -115,13 +113,11 @@ import Vue from "vue";
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import Card from "@/components/ui/Card.vue"; import Card from "@/components/ui/Card.vue";
import Options from "@/components/ui/Options.vue";
export default Vue.extend({ export default Vue.extend({
name: "List", name: "List",
components: { components: {
Card, Card
Options
}, },
data: () => ({ data: () => ({
focusedStationName: "" focusedStationName: ""
@@ -238,7 +234,7 @@ ul {
.list { .list {
display: flex; display: flex;
flex-direction: column; justify-content: center;
} }
.default-station { .default-station {
@@ -246,8 +242,13 @@ ul {
} }
.table { .table {
&-wrapper {
overflow: auto;
}
display: block; display: block;
overflow-y: hidden;
max-height: 100vh;
white-space: nowrap; white-space: nowrap;
border-collapse: collapse; border-collapse: collapse;
@@ -258,6 +259,7 @@ ul {
thead th { thead th {
padding: 0.8rem; padding: 0.8rem;
background-color: #444; background-color: #444;
min-width: 100px;
} }
tr { tr {
+41 -10
View File
@@ -1,7 +1,11 @@
<template> <template>
<div class="options"> <div class="options">
<div class="option-buttons"> <div class="option-buttons">
<button class="button-filters" @click="filtersOpen = !filtersOpen">FILTRY</button> <button
class="button-filters"
:class="{'open': filtersOpen}"
@click="filtersOpen = !filtersOpen"
>FILTRY</button>
</div> </div>
<div class="option-wrapper"> <div class="option-wrapper">
@@ -29,30 +33,57 @@ export default Vue.extend({
<style lang="scss" scoped> <style lang="scss" scoped>
@import "../../styles/variables.scss";
@import "../../styles/responsive.scss";
.options { .options {
font-size: calc(0.7rem + 0.5vw); font-size: calc(0.7rem + 0.5vw);
display: flex;
padding: 1rem;
@include smallScreen() {
flex-direction: column;
padding: 1rem 0;
}
} }
button.button-filters { button {
color: #e0e0e0; color: #e0e0e0;
font-size: 0.9em; font-size: 1em;
background: #333;
border: none;
border: 2px solid #e0e0e0;
background: rgba(#e0e0e0, 0.2);
outline: none; outline: none;
border-radius: 0.5em;
padding: 0.5em; padding: 0.5em;
margin: 0.4em 0;
cursor: pointer; cursor: pointer;
transition: background 0.4s, color 0.4s; border-left: 3px solid white;
transition: all 0.3s;
@include smallScreen {
border-left: none;
border-top: 2px solid white;
}
&.open {
color: $accentCol;
border-radius: 1em 0 0 1em;
border: none;
@include smallScreen() {
border-radius: 1em 1em 0 0;
}
font-weight: bold;
}
&:hover { &:hover {
color: #ffffff; color: #ffffff;
background: rgba(#e0e0e0, 0.4); background: rgba(#e0e0e0, 0.1);
} }
img { img {
+103 -73
View File
@@ -1,61 +1,15 @@
<template> <template>
<div class="list-filter"> <div class="list-filter">
<div class="filter-content"> <div class="filter-grid">
<div class="content-row"> <div class="grid-row">
<div class="content-column"> <div class="grid-column" v-for="(el, i) in gridElements" :key="i">
<div class="column-title">Dostępność:</div> <div class="column-title">{{el.title}}</div>
<div class="content-item"> <div class="column-content">
<input type="checkbox" id="is-default" checked @change="handleChange" /> <div class="grid-item" v-for="(item, i) in el.items" :key="i">
<label for="is-default">W paczce z grą</label> <input :type="el.type" :id="item.id" :name="item.name" checked @change="handleChange" />
</div> <label :for="item.id">{{ item.content }}</label>
</div>
<div class="content-item">
<input type="checkbox" id="not-default" checked @change="handleChange" />
<label for="not-default">Poza paczką z grą</label>
</div>
</div>
<div class="content-column">
<div class="column-title">Sterowanie:</div>
<div class="content-item">
<input type="checkbox" id="control-SPK" checked @change="handleChange" />
<label for="control-SPK">SPK</label>
</div>
<div class="content-item">
<input type="checkbox" id="control-SCS" checked @change="handleChange" />
<label for="control-SCS">SCS</label>
</div>
<div class="content-item">
<input type="checkbox" id="control-hands" checked @change="handleChange" />
<label for="control-hands">ręczne</label>
</div>
<div class="content-item">
<input type="checkbox" id="control-levers" checked @change="handleChange" />
<label for="control-levers">mechaniczne</label>
</div>
</div>
<div class="content-column">
<div class="column-title">Sygnalizacja:</div>
<div class="content-item">
<input type="checkbox" id="signals-modern" checked @change="handleChange" />
<label for="signals-modern">współczesna</label>
</div>
<div class="content-item">
<input type="checkbox" id="signals-mixed" checked @change="handleChange" />
<label for="signals-mixed">mieszana</label>
</div>
<div class="content-item">
<input type="checkbox" id="signals-historic" checked @change="handleChange" />
<label for="signals-historic">kształtowa</label>
</div> </div>
</div> </div>
</div> </div>
@@ -64,21 +18,98 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from "vue"; import { Vue, Component } from "vue-property-decorator";
import { mapActions } from "vuex"; import { mapActions } from "vuex";
export default Vue.extend({ export default Vue.extend({
name: "list-filter", name: "list-filter",
data: () => ({}), data: () => ({
methods: { gridElements: {
...mapActions(["addFilter", "removeFilter"]), access: {
handleChange(e: any) { title: "Dostępność",
// this.$store.commit(e.target.checked ? "removeFilter" : "addFilter", { type: "checkbox",
// id: e.target.id items: [
// }); {
id: "is-default",
name: "default",
content: "w paczce z grą"
},
{
id: "not-default",
name: "notDefault",
content: "poza paczką z grą"
},
{
id: "non-public",
name: "nonPublic",
content: "niepubliczna"
}
]
},
if (e.target.checked) this.removeFilter(e.target.id); control: {
else this.addFilter(e.target.id); title: "Sterowanie",
type: "checkbox",
items: [
{
id: "SPK",
name: "SPK",
content: "SPK"
},
{
id: "SCS",
name: "SCS",
content: "SCS"
},
{
id: "by-hand",
name: "ręczne",
content: "ręczne"
},
{
id: "levers",
name: "mechaniczne",
content: "mechaniczne"
}
]
},
signals: {
title: "Sygnalizacja",
type: "checkbox",
items: [
{
id: "modern",
name: "współczesna",
content: "współczesna"
},
{
id: "semaphore",
name: "kształtowa",
content: "kształtowa"
},
{
id: "mixed",
name: "mieszana",
content: "mieszana"
},
{
id: "historic",
name: "historyczna",
content: "historyczna"
}
]
}
}
}),
methods: {
...mapActions(["addFilters", "removeFilters"]),
handleChange(e: any) {
if (e.target.checked) {
this.removeFilters([e.target.name]);
} else this.addFilters([e.target.name]);
} }
} }
}); });
@@ -91,20 +122,19 @@ export default Vue.extend({
display: flex; display: flex;
font-size: calc(0.6rem + 0.4vw); font-size: calc(0.6rem + 0.4vw);
}
.filter-content {
background: #333;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
padding: 0.3rem;
@include smallScreen() { @include smallScreen() {
width: 100%; width: 100%;
} }
} }
.content { .filter-grid {
background: #333;
border-radius: 0 1rem 1rem 1rem;
padding: 0.3rem;
}
.grid {
&-row { &-row {
display: flex; display: flex;
justify-content: center; justify-content: center;
+1 -2
View File
@@ -1615,7 +1615,6 @@
"noCatenary": 0 "noCatenary": 0
} }
}, },
"default": false, "default": false
"non-public": true
} }
] ]
+18 -32
View File
@@ -87,13 +87,13 @@ export default new Vuex.Store({
commit('filterStations'); commit('filterStations');
}, },
addFilter({ commit }, filterId) { addFilters({ commit }, filterId) {
commit('addFilter', filterId); commit('addFilters', filterId);
commit('filterStations'); commit('filterStations');
}, },
removeFilter({ commit }, filterId) { removeFilters({ commit }, filterId) {
commit('removeFilter', filterId); commit('removeFilters', filterId);
commit('filterStations'); commit('filterStations');
} }
}, },
@@ -101,40 +101,25 @@ export default new Vuex.Store({
setStations: (state, stations) => state.stations = stations, setStations: (state, stations) => state.stations = stations,
setTrainCount: (state, count) => state.trainCount = count, setTrainCount: (state, count) => state.trainCount = count,
addFilter(state: any, filterId: string) { addFilters(state: any, filters: string[]) {
state.filters.push(filterId); state.filters.push(...filters);
}, },
removeFilter: (state: { filters: string[] }, filterId: string) => { removeFilters: (state: { filters: string[] }, filters: string[]) => {
state.filters = state.filters.filter((id: string) => id !== filterId); filters.forEach(filter => {
state.filters = state.filters.filter((id: string) => id !== filter);
})
}, },
filterStations(state: any) { filterStations(state: any) {
let isDefault = state.filters.includes("is-default");
let isNotDefault = state.filters.includes("not-default");
let hasSPK = state.filters.includes("control-SPK");
let hasSCS = state.filters.includes("control-SCS");
let hasHand = state.filters.includes("control-hands");
let hasLevers = state.filters.includes("control-levers");
let modernSignals = state.filters.includes("signals-modern");
let mixedSignals = state.filters.includes("signals-mixed");
let historicSignals = state.filters.includes("signals-historic");
state.filteredStations = state.stations.filter((station: any) => { state.filteredStations = state.stations.filter((station: any) => {
if (isDefault && station.default) return false; if (station.default && state.filters.includes("default")) return false;
if (isNotDefault && !station.default) return false; if ((!station.default) && state.filters.includes("notDefault")) return false;
if (hasSPK && (station.controlType === "SPK" || station.controlType === "SCS-SPK")) return false; if ((station.nonPublic || !station.reqLevel) && (state.filters.includes("nonPublic"))) return false;
if (hasSCS && (station.controlType === "SCS" || station.controlType === "SCS-SPK")) return false;
if (hasHand && (station.controlType === "ręczne")) return false;
if (hasLevers && (station.controlType === "mechaniczne"
|| station.controlType === "mechaniczne+SCS"
|| station.controlType === "mechaniczne+SPK")) return false;
if (modernSignals && (station.signalType === "współczesna")) return false; if (state.filters.includes(station.controlType)) return false;
if (mixedSignals && (station.signalType === "mieszana")) return false; if (state.filters.includes(station.signalType)) return false;
if (historicSignals && (station.signalType === "kształtowa" || station.signalType === "historyczna")) return false;
if (station.controlType && state.filters.filter((f: string) => station.controlType.includes(f)).length > 0) return false;
return true; return true;
}) })
@@ -142,6 +127,7 @@ export default new Vuex.Store({
}, },
getters: { getters: {
getStations: state => state.filteredStations, getStations: state => state.filteredStations,
getStationCount: state => state.stations.length,
getTrainCount: state => state.trainCount, getTrainCount: state => state.trainCount,
getFilters: (state: any) => state.filters, getFilters: (state: any) => state.filters,
} }
+3 -2
View File
@@ -1,5 +1,6 @@
<template> <template>
<div class="home"> <div class="home">
<Options />
<List /> <List />
</div> </div>
</template> </template>
@@ -7,10 +8,11 @@
<script lang="ts"> <script lang="ts">
import { Vue, Component } from "vue-property-decorator"; import { Vue, Component } from "vue-property-decorator";
import Options from "@/components/ui/Options.vue";
import List from "@/components/ui/List.vue"; import List from "@/components/ui/List.vue";
@Component({ @Component({
components: { List } components: { Options, List }
}) })
export default class Home extends Vue { export default class Home extends Vue {
mounted() {} mounted() {}
@@ -19,7 +21,6 @@ export default class Home extends Vue {
<style lang="scss" scoped> <style lang="scss" scoped>
.home { .home {
overflow: auto;
padding: 1rem; padding: 1rem;
} }
</style> </style>