diff --git a/src/components/StationsView/FilterOption.vue b/src/components/StationsView/FilterOption.vue new file mode 100644 index 0000000..f1f633a --- /dev/null +++ b/src/components/StationsView/FilterOption.vue @@ -0,0 +1,165 @@ + + + + + \ No newline at end of file diff --git a/src/components/StationsView/FilterCard.vue b/src/components/StationsView/StationFilterCard.vue similarity index 56% rename from src/components/StationsView/FilterCard.vue rename to src/components/StationsView/StationFilterCard.vue index 5026155..274dbcd 100644 --- a/src/components/StationsView/FilterCard.vue +++ b/src/components/StationsView/StationFilterCard.vue @@ -1,47 +1,26 @@ @@ -102,10 +78,12 @@ import inputData from "@/data/options.json"; import StorageManager from "@/scripts/managers/storageManager"; import { defineComponent } from "@vue/runtime-core"; import ActionButton from "../Global/ActionButton.vue"; +import FilterOption from "./FilterOption.vue"; export default defineComponent({ - components: { ActionButton }, + components: { ActionButton, FilterOption }, props: ["showCard", "exit"], + emits: ["changeFilterValue", "invertFilters", "resetFilters"], data: () => ({ inputs: { ...inputData }, @@ -118,15 +96,14 @@ export default defineComponent({ }, methods: { - handleChange(e: Event) { - const target = e.target as HTMLInputElement; - + handleChange(change: { name: string; value: boolean }) { this.$emit("changeFilterValue", { - name: target.name, - value: !target.checked, + name: change.name, + value: !change.value, }); + if (this.saveOptions) - StorageManager.setBooleanValue(target.name, target.checked); + StorageManager.setBooleanValue(change.name, change.value); }, handleInput(e: Event) { @@ -140,7 +117,18 @@ export default defineComponent({ StorageManager.setStringValue(target.name, target.value); }, - saveFilters() { + invertFilters() { + this.inputs.options.forEach((option) => { + option.value = !option.value; + StorageManager.setBooleanValue(option.name, option.value); + }); + + this.$emit("invertFilters"); + }, + + saveFilters(change: { value }) { + this.saveOptions = change.value; + if (!this.saveOptions) { StorageManager.unregisterStorage(this.STORAGE_KEY); return; @@ -182,14 +170,12 @@ export default defineComponent({ @import "../../styles/responsive"; @import "../../styles/card"; -$accessCol: #e03b07; -$controlCol: #0085ff; -$signalCol: #bf7c00; -$statusCol: #349b32; -$saveCol: #28a826; - .card { - &-title { + > section { + margin-top: 1em; + } + + &_title { font-size: 2em; font-weight: 700; color: $accentCol; @@ -199,7 +185,7 @@ $saveCol: #28a826; text-align: center; } - &-options { + &_options { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-template-rows: repeat(4, 1fr); @@ -211,19 +197,20 @@ $saveCol: #28a826; } } - &-sliders { - margin-top: 1em; - } + &_modes { + display: flex; + justify-content: center; - &-actions { - margin-top: 0.7em; - - button { - margin: 0 0.3em; + .option { + margin: 0 1em; } } - &-save { + &_actions button { + margin: 0 0.3em; + } + + &_save { display: flex; justify-content: center; @@ -232,101 +219,13 @@ $saveCol: #28a826; } } - &-exit { + &_exit { img { width: 2em; } } } -.option { - input { - 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; - } - } - - &.checked { - &.access { - background-color: $accessCol; - - &::before { - box-shadow: 0 0 6px 1px $accessCol; - } - } - - &.control { - background-color: $controlCol; - - &::before { - box-shadow: 0 0 6px 1px $controlCol; - } - } - - &.signals { - background-color: $signalCol; - - &::before { - box-shadow: 0 0 6px 1px $signalCol; - } - } - - &.status { - background-color: $statusCol; - - &::before { - box-shadow: 0 0 6px 1px $statusCol; - } - } - - &.save { - background-color: $saveCol; - - &::before { - box-shadow: 0 0 6px 1px $saveCol; - } - } - - &::before { - position: absolute; - content: ""; - top: 0; - left: 0; - - width: 100%; - height: 100%; - - border-radius: 0.5em; - } - } - } -} - .slider { display: flex; align-items: center; diff --git a/src/components/StationsView/StationTable.vue b/src/components/StationsView/StationTable.vue index d4ae5b5..5bcb1b9 100644 --- a/src/components/StationsView/StationTable.vue +++ b/src/components/StationsView/StationTable.vue @@ -68,8 +68,8 @@ :style="calculateExpStyle(station.reqLevel)" > {{ - station.reqLevel && station.reqLevel > -1 - ? parseInt(station.reqLevel) >= 2 + station.reqLevel && Number(station.reqLevel) > -1 + ? Number(station.reqLevel) >= 2 ? station.reqLevel : "L" : "?" @@ -162,21 +162,21 @@ SBL non-public icon-unavailable @@ -240,12 +240,12 @@ export default defineComponent({ }, sorterActive: { - type: Object as () => { id: string; dir: number }, + type: Object as () => { index: number; dir: number }, required: true, }, - setFocusedStation: Function, - changeSorter: Function, + setFocusedStation: { type: Function, required: true }, + changeSorter: { type: Function, required: true }, }, mixins: [styleMixin], @@ -256,6 +256,9 @@ export default defineComponent({ timetableIcon: require("@/assets/icon-timetable.svg"), userIcon: require("@/assets/icon-user.svg"), trainIcon: require("@/assets/icon-train.svg"), + SBLIcon: require("@/assets/icon-SBL.svg"), + lockIcon: require("@/assets/icon-lock.svg"), + unavailableIcon: require("@/assets/icon-unavailable.svg"), ascIcon: require("@/assets/icon-arrow-asc.svg"), descIcon: require("@/assets/icon-arrow-desc.svg"), diff --git a/src/data/options.json b/src/data/options.json index e9b5d70..ae2db80 100644 --- a/src/data/options.json +++ b/src/data/options.json @@ -1,6 +1,5 @@ { - "options": [ - { + "options": [{ "id": "default", "name": "default", "iconName": "td2", @@ -49,7 +48,7 @@ "value": true, "defaultValue": true }, - { + { "id": "SPE", "name": "SPE", "iconName": "SPE", @@ -73,7 +72,14 @@ "value": true, "defaultValue": true }, - + { + "id": "SBL", + "name": "SBL", + "iconName": "SBL", + "section": "routes", + "value": true, + "defaultValue": true + }, { "id": "modern", "name": "współczesna", @@ -126,8 +132,7 @@ "defaultValue": true } ], - "sliders": [ - { + "sliders": [{ "id": "min-lvl", "name": "minLevel", "minRange": 0, @@ -175,5 +180,20 @@ "value": 0, "defaultValue": 0 } - ] -} + ], + "modes": [{ + "id": "include-selected", + "name": "include-selected", + "iconName": "", + "section": "mode", + "value": true, + "defaultValue": true + }, { + "id": "save", + "name": "save", + "iconName": "", + "section": "mode", + "value": true, + "defaultValue": true + }] +} \ No newline at end of file diff --git a/src/locales/en.json b/src/locales/en.json index f8095c4..3171aed 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -58,6 +58,7 @@ "SPE": "SPE", "manual": "MANUAL", "mechanical": "MECHANICAL", + "SBL": "SBL", "modern": "MODERN", "semaphores": "SEMAPHORES", "mixed": "MIXED", @@ -72,6 +73,7 @@ "routes-2t-cat": "MIN. CATENARY DOUBLE TRACK ROUTES", "routes-2t-other": "MIN. OTHER DOUBLE TRACK ROUTES" }, + "include-selected": "INCLUDE SELECTED", "save": "SAVE FILTERS", "reset": "RESET FILTERS", "close": "CLOSE FILTERS" @@ -147,4 +149,4 @@ "search-train": "Search by train number", "search-driver": "Search by driver name" } -} +} \ No newline at end of file diff --git a/src/locales/pl.json b/src/locales/pl.json index b360b22..6346e82 100644 --- a/src/locales/pl.json +++ b/src/locales/pl.json @@ -57,6 +57,7 @@ "SCS": "SCS", "SPE": "SPE", "manual": "RĘCZNE", + "SBL": "SBL", "mechanical": "MECHANICZNE", "modern": "WSPÓŁCZESNA", "semaphores": "KSZTAŁTOWA", @@ -72,6 +73,7 @@ "routes-2t-cat": "SZLAKI DWUTOROWE ZELEKTR. (MINIMUM)", "routes-2t-other": "SZLAKI DWUTOROWE NIEZELEKTR. (MINIMUM)" }, + "include-selected": "POKAŻ ZAZNACZONE", "save": "ZAPISZ FILTRY", "reset": "RESETUJ FILTRY", "close": "ZAMKNIJ FILTRY" @@ -147,4 +149,4 @@ "search-train": "Szukaj nr pociągu", "search-driver": "Szukaj maszynisty" } -} +} \ No newline at end of file diff --git a/src/scripts/interfaces/Filter.ts b/src/scripts/interfaces/Filter.ts index df6cf7a..0f99148 100644 --- a/src/scripts/interfaces/Filter.ts +++ b/src/scripts/interfaces/Filter.ts @@ -9,6 +9,7 @@ export default interface Filter { "SPE": boolean; ręczne: boolean; mechaniczne: boolean; + "SBL": boolean; współczesna: boolean; kształtowa: boolean; historyczna: boolean; @@ -21,6 +22,7 @@ export default interface Filter { minTwoWay: number; 'no-1track': boolean; 'no-2track': boolean; + 'include-selected': boolean; free: boolean; occupied: boolean; ending: boolean; diff --git a/src/scripts/managers/stationFilterManager.ts b/src/scripts/managers/stationFilterManager.ts index f58fadb..4a8f7ab 100644 --- a/src/scripts/managers/stationFilterManager.ts +++ b/src/scripts/managers/stationFilterManager.ts @@ -54,44 +54,48 @@ const sortStations = (a: Station, b: Station, sorter: { index: number; dir: numb } const filterStations = (station: Station, filters: Filter) => { - if ((station.nonPublic || !station.reqLevel) && filters['nonPublic']) return false; + const returnMode = false; - if (station.online && station.statusID == 'ending' && filters['ending']) return false; + if ((station.nonPublic || !station.reqLevel) && filters['nonPublic']) return returnMode; - if (station.online && filters['occupied']) return false; - if (!station.online && filters['free']) return false; + if (station.online && station.statusID == 'ending' && filters['ending']) return returnMode; - if (station.default && filters['default']) return false; - if (!station.default && filters['notDefault']) return false; + if (station.online && filters['occupied']) return returnMode; + if (!station.online && filters['free']) return returnMode; - if (filters['real'] && station.stationLines != '') return false; - if (filters['fictional'] && station.stationLines == '') return false; + if (station.default && filters['default']) return returnMode; + if (!station.default && filters['notDefault']) return returnMode; + + if (filters['real'] && station.stationLines != '') return returnMode; + if (filters['fictional'] && station.stationLines == '') return returnMode; if (station.reqLevel == '-1') return true; - if (parseInt(station.reqLevel) < filters['minLevel']) return false; - if (parseInt(station.reqLevel) > filters['maxLevel']) return false; + if (parseInt(station.reqLevel) < filters['minLevel']) return returnMode; + if (parseInt(station.reqLevel) > filters['maxLevel']) return returnMode; - if (filters['no-1track'] && (station.routes.oneWay.catenary != 0 || station.routes.oneWay.noCatenary != 0)) return false; - if (filters['no-2track'] && (station.routes.twoWay.catenary != 0 || station.routes.twoWay.noCatenary != 0)) return false; + if (filters['no-1track'] && (station.routes.oneWay.catenary != 0 || station.routes.oneWay.noCatenary != 0)) return returnMode; + if (filters['no-2track'] && (station.routes.twoWay.catenary != 0 || station.routes.twoWay.noCatenary != 0)) return returnMode; - if (station.routes.oneWay.catenary < filters['minOneWayCatenary']) return false; - if (station.routes.oneWay.noCatenary < filters['minOneWay']) return false; + if (station.routes.oneWay.catenary < filters['minOneWayCatenary']) return returnMode; + if (station.routes.oneWay.noCatenary < filters['minOneWay']) return returnMode; - if (station.routes.twoWay.catenary < filters['minTwoWayCatenary']) return false; - if (station.routes.twoWay.noCatenary < filters['minTwoWay']) return false; + if (station.routes.twoWay.catenary < filters['minTwoWayCatenary']) return returnMode; + if (station.routes.twoWay.noCatenary < filters['minTwoWay']) return returnMode; - if (filters[station.controlType]) return false; - if (filters[station.signalType]) return false; + if (filters[station.controlType]) return returnMode; + if (filters[station.signalType]) return returnMode; - if (filters['SPK'] && (station.controlType === 'SPK' || station.controlType.includes('+SPK'))) return false; - if (filters['SCS'] && (station.controlType === 'SCS' || station.controlType.includes('+SCS'))) return false; - if (filters['SPE'] && (station.controlType === 'SPE' || station.controlType.includes('+SPE'))) return false; + if (filters['SPK'] && (station.controlType === 'SPK' || station.controlType.includes('+SPK'))) return returnMode; + if (filters['SCS'] && (station.controlType === 'SCS' || station.controlType.includes('+SCS'))) return returnMode; + if (filters['SPE'] && (station.controlType === 'SPE' || station.controlType.includes('+SPE'))) return returnMode; - if (filters['SCS'] && filters['SPK'] && (station.controlType.includes('SPK') || station.controlType.includes('SCS'))) return false; + if (filters['SCS'] && filters['SPK'] && (station.controlType.includes('SPK') || station.controlType.includes('SCS'))) return returnMode; - if (filters['mechaniczne'] && station.controlType.includes('mechaniczne')) return false; + if (filters['mechaniczne'] && station.controlType.includes('mechaniczne')) return returnMode; - if (filters['ręczne'] && station.controlType.includes('ręczne')) return false; + if (filters['ręczne'] && station.controlType.includes('ręczne')) return returnMode; + + if (filters['SBL'] && station.SBL) return returnMode; return true; } @@ -111,12 +115,14 @@ export default class StationFilterManager { kształtowa: false, historyczna: false, mieszana: false, + SBL: false, minLevel: 0, maxLevel: 20, minOneWayCatenary: 0, minOneWay: 0, minTwoWayCatenary: 0, minTwoWay: 0, + 'include-selected': false, 'no-1track': false, 'no-2track': false, free: true, @@ -143,6 +149,24 @@ export default class StationFilterManager { this.filters = { ...this.filterInitStates }; } + invertFilters() { + Object.keys(this.filters).forEach(prop => { + if(typeof this.filters[prop] !== "boolean") return; + + this.filters[prop] = !this.filters[prop]; + + }) + + // for(let prop in this.filters) { + // if(typeof prop !== "boolean") continue; + + // this.filters[prop] = !this.filterInitStates[prop]; + + // console.log("inverted!"); + + // } + } + changeSorter(index: number) { if (index > 4 && index < 7) return; diff --git a/src/views/StationsView.vue b/src/views/StationsView.vue index 07875fd..60dc799 100644 --- a/src/views/StationsView.vue +++ b/src/views/StationsView.vue @@ -4,11 +4,7 @@
- icon-filter + icon-filter

{{ $t("options.filters") }}

@@ -37,6 +33,7 @@ :showCard="filterCardOpen" :exit="() => toggleCardsState('filter')" @changeFilterValue="changeFilterValue" + @invertFilters="invertFilters" @resetFilters="resetFilters" /> @@ -52,8 +49,9 @@ import StationFilterManager from "@/scripts/managers/stationFilterManager"; import inputData from "@/data/options.json"; import StationTable from "@/components/StationsView/StationTable.vue"; -import FilterCard from "@/components/StationsView/FilterCard.vue"; +import FilterCard from "@/components/StationsView/StationFilterCard.vue"; import ActionButton from "@/components/Global/ActionButton.vue"; + import { StoreData } from "@/scripts/interfaces/StoreData"; import { DataStatus } from "@/scripts/enums/DataStatus"; import { computed, ComputedRef, defineComponent, reactive } from "vue"; @@ -70,6 +68,7 @@ export default defineComponent({ trainIcon: require("@/assets/icon-train.svg"), timetableIcon: require("@/assets/icon-timetable.svg"), dolarIcon: require("@/assets/icon-dolar.svg"), + filterIcon: require("@/assets/icon-filter2.svg"), filterCardOpen: false, modalHidden: true, STORAGE_KEY: "options_saved", @@ -148,6 +147,9 @@ export default defineComponent({ resetFilters() { this.filterManager.resetFilters(); }, + invertFilters() { + this.filterManager.invertFilters(); + }, closeCard() { this.focusedStationName = ""; },