Filtry dzienników; poprawki stylistyczne

This commit is contained in:
2022-09-07 20:37:58 +02:00
parent 0d9a3f4b4f
commit 21bacb1c95
8 changed files with 167 additions and 147 deletions
@@ -1,12 +1,7 @@
<template> <template>
<section class="journal-timetables"> <section class="journal-timetables">
<div class="journal_wrapper"> <div class="journal_wrapper">
<JournalOptions <JournalOptions @on-search-confirm="searchHistory" :sorter-option-ids="['timestampFrom', 'duration']" />
@on-filter-change="search"
@on-input-change="search"
@on-sorter-change="search"
:sorter-option-ids="['timestampFrom', 'duration']"
/>
<div class="list_wrapper" @scroll="handleScroll"> <div class="list_wrapper" @scroll="handleScroll">
<transition name="warning" mode="out-in"> <transition name="warning" mode="out-in">
@@ -135,13 +130,13 @@ export default defineComponent({
if (this.sceneryName || this.dispatcherName) { if (this.sceneryName || this.dispatcherName) {
this.searchersValues['search-station'] = this.sceneryName?.toString() || ''; this.searchersValues['search-station'] = this.sceneryName?.toString() || '';
this.searchersValues['search-dispatcher'] = this.dispatcherName?.toString() || ''; this.searchersValues['search-dispatcher'] = this.dispatcherName?.toString() || '';
this.search(); this.searchHistory();
} }
}, },
mounted() { mounted() {
if (!this.sceneryName && !this.dispatcherName) { if (!this.sceneryName && !this.dispatcherName) {
this.search(); this.searchHistory();
} }
}, },
@@ -156,7 +151,7 @@ export default defineComponent({
if (scrollTop > elementHeight * 0.85) this.addHistoryData(); if (scrollTop > elementHeight * 0.85) this.addHistoryData();
}, },
search() { searchHistory() {
this.fetchHistoryData({ this.fetchHistoryData({
searchers: this.searchersValues, searchers: this.searchersValues,
}); });
@@ -112,7 +112,7 @@ export default defineComponent({
text-align: center; text-align: center;
background-color: #4d4d4d; background-color: #4d4d4d;
margin-top: 1em; margin: 1em 0;
span { span {
position: relative; position: relative;
+112 -82
View File
@@ -1,37 +1,46 @@
<template> <template>
<div class="journal-options"> <div class="journal-options">
<button class="btn--open"> <button class="btn--open" @click="showOptions = !showOptions">
<img :src="getIcon('filter2')" alt="Open filters" /> <img :src="getIcon('filter2')" alt="Open filters" />
FILTRY FILTRY
</button> </button>
<div class="options_wrapper"> <div class="options_wrapper" v-if="showOptions">
<div class="options_content"> <div class="options_content">
<h1>SORTUJ WG:</h1> <h1>SORTUJ WG:</h1>
<div class="content_select"> <div class="options_sorters">
<!-- <select-box
:itemList="translatedSorterOptions"
:defaultItemIndex="0"
@selected="onSorterChange"
:prefix="$t('journal.sort-prefix')"
/> -->
<div v-for="opt in translatedSorterOptions"> <div v-for="opt in translatedSorterOptions">
<button class="sort-option">{{ opt.value.toUpperCase() }}</button> <button class="sort-option" :data-selected="opt.id == sorterActive.id" @click="onSorterChange(opt)">
{{ opt.value.toUpperCase() }}
</button>
</div> </div>
</div> </div>
<h1 v-if="filters.length != 0">FILTRUJ WG:</h1>
<div class="options_filters">
<button
v-for="filter in filters"
class="filter-option btn--option"
:class="{ checked: journalFilterActive.id === filter.id }"
:id="filter.id"
@click="onFilterChange(filter)"
>
{{ $t(`journal.filter-${filter.id}`) }}
</button>
</div>
<h1>SZUKAJ:</h1> <h1>SZUKAJ:</h1>
<div class="content_search"> <div class="content_search">
<div class="search-box" v-for="(value, propName) in searchersValues" :key="propName"> <div class="search-box" v-for="(value, propName) in searchersValues" :key="propName">
<input <input
class="search-input" class="search-input"
:type="propName == 'search-date' ? 'date' : 'input'"
@keydown.enter="onSearchConfirm"
:placeholder="$t(`journal.${propName}`)" :placeholder="$t(`journal.${propName}`)"
v-model="searchersValues[propName]" v-model="searchersValues[propName]"
@keydown.enter="onInputSearch"
/> />
<button class="search-exit"> <button class="search-exit">
@@ -39,32 +48,20 @@
</button> </button>
</div> </div>
<!-- <label for="">Data</label>
<div class="search-box"> <div class="search-box">
<input class="search-input" placeholder="Data" type="date" /> <input class="search-input" placeholder="Data" type="date" v-model="searchDate" />
<button class="search-exit"> <button class="search-exit">
<img :src="getIcon('exit')" alt="exit-icon" /> <img :src="getIcon('exit')" alt="exit-icon" />
</button> </button>
</div> </div> -->
<action-button class="search-button" @click="onInputSearch"> <action-button class="search-button" @click="onSearchConfirm">
{{ $t('journal.search') }} {{ $t('journal.search') }}
</action-button> </action-button>
</div> </div>
</div> </div>
<h1>FILTRUJ WG:</h1>
<div class="options_filters">
<button
v-for="filter in filters"
class="filter-option btn--option"
:class="{ checked: journalFilterActive.id === filter.id }"
:id="filter.id"
@click="onFilterChange(filter)"
>
{{ $t(`journal.filter-${filter.id}`) }}
</button>
</div>
</div> </div>
</div> </div>
</template> </template>
@@ -77,7 +74,7 @@ import SelectBox from '../Global/SelectBox.vue';
export default defineComponent({ export default defineComponent({
components: { SelectBox, ActionButton }, components: { SelectBox, ActionButton },
emits: ['onSorterChange', 'onInputChange', 'onFilterChange'], emits: ['onSearchConfirm'],
mixins: [imageMixin], mixins: [imageMixin],
props: { props: {
@@ -92,6 +89,12 @@ export default defineComponent({
}, },
}, },
data() {
return {
showOptions: false,
};
},
setup() { setup() {
return { return {
searchersValues: inject('searchersValues') as { [key: string]: string }, searchersValues: inject('searchersValues') as { [key: string]: string },
@@ -113,22 +116,21 @@ export default defineComponent({
onSorterChange(item: { id: string | number; value: string }) { onSorterChange(item: { id: string | number; value: string }) {
this.sorterActive.id = item.id; this.sorterActive.id = item.id;
this.sorterActive.dir = -1; this.sorterActive.dir = -1;
this.$emit('onSearchConfirm');
this.$emit('onSorterChange');
}, },
onFilterChange(filter: JournalFilter) { onFilterChange(filter: JournalFilter) {
this.journalFilterActive = filter; this.journalFilterActive = filter;
this.$emit('onFilterChange'); this.$emit('onSearchConfirm');
},
onInputSearch() {
this.$emit('onInputChange');
}, },
onInputClear(id: any) { onInputClear(id: any) {
this.searchersValues[id] = ''; this.searchersValues[id] = '';
this.onInputSearch(); this.$emit('onSearchConfirm');
},
onSearchConfirm() {
this.$emit('onSearchConfirm');
}, },
}, },
}); });
@@ -139,6 +141,26 @@ export default defineComponent({
@import '../../styles/search_box.scss'; @import '../../styles/search_box.scss';
@import '../../styles/variables.scss'; @import '../../styles/variables.scss';
.journal-options {
position: relative;
margin-bottom: 0.5em;
}
.options_wrapper {
position: absolute;
background-color: #111111ee;
box-shadow: 0 0 10px 2px #111;
width: 100%;
max-width: 500px;
padding: 1em;
z-index: 100;
}
.btn--open { .btn--open {
display: flex; display: flex;
@@ -171,20 +193,7 @@ h1 {
} }
} }
.journal-options { .options_sorters {
position: relative;
}
.options_wrapper {
position: absolute;
background-color: #111111dd;
padding: 1em;
z-index: 100;
}
.content_select {
display: flex; display: flex;
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
@@ -213,6 +222,11 @@ h1 {
margin: 0 0.25em 0 0; margin: 0 0.25em 0 0;
} }
.sort-option[data-selected='true'] {
color: $accentCol;
font-weight: bold;
}
.filter-option { .filter-option {
&#abandoned { &#abandoned {
color: salmon; color: salmon;
@@ -228,38 +242,54 @@ h1 {
} }
@include smallScreen() { @include smallScreen() {
.journal-options { h1 {
width: 100%; text-align: center;
}
.options { &::before {
&_wrapper { width: 75%;
justify-content: center; left: 50%;
align-items: center; transform: translateX(-50%);
}
&_content {
padding: 0 1em;
flex-direction: column;
.content_select {
margin: 0 auto;
padding: 0;
}
.content_search {
justify-content: center;
}
}
&_filters {
justify-content: center;
.filter-option {
margin: 0.25em 0.25em;
}
} }
} }
.options_wrapper {
max-width: 100%;
}
.btn--open {
margin: 0 auto;
}
.filter-option,
.sort-option {
margin: 0.25em 0.25em;
}
.options_filters,
.options_sorters {
justify-content: center;
}
// .options {
// &_wrapper {
// justify-content: center;
// align-items: center;
// }
// &_content {
// padding: 0 1em;
// flex-direction: column;
// .content_select {
// margin: 0 auto;
// padding: 0;
// }
// .content_search {
// justify-content: center;
// }
// }
// }
} }
</style> </style>
@@ -6,39 +6,37 @@
<div class="journal_wrapper"> <div class="journal_wrapper">
<JournalOptions <JournalOptions
@on-input-change="searchHistory" @on-search-confirm="searchHistory"
@on-filter-change="searchHistory"
@on-sorter-change="searchHistory"
:sorter-option-ids="['timetableId', 'beginDate', 'distance', 'total-stops']" :sorter-option-ids="['timetableId', 'beginDate', 'distance', 'total-stops']"
:filters="journalTimetableFilters" :filters="journalTimetableFilters"
/> />
<div class="list_wrapper" @scroll="handleScroll"> <div class="list_wrapper" @scroll="handleScroll">
<transition name="warning" mode="out-in"> <!-- <transition name="warning" mode="out-in"> -->
<div :key="dataStatus"> <!-- <div :key="dataStatus"> -->
<Loading v-if="dataStatus == (DataStatus.Loading || DataStatus.Initialized)" /> <Loading v-if="dataStatus == DataStatus.Loading || dataStatus == DataStatus.Initialized" />
<div v-else-if="dataStatus == DataStatus.Error" class="journal_warning error"> <div v-else-if="dataStatus == DataStatus.Error" class="journal_warning error">
{{ $t('app.error') }} {{ $t('app.error') }}
</div> </div>
<div v-else-if="timetableHistory.length == 0" class="journal_warning"> <div v-else-if="timetableHistory.length == 0" class="journal_warning">
{{ $t('app.no-result') }} {{ $t('app.no-result') }}
</div> </div>
<div v-else> <div v-else>
<JournalTimetablesList :timetableHistory="timetableHistory" /> <JournalTimetablesList :timetableHistory="timetableHistory" />
<button <button
class="btn btn--option btn--load-data" class="btn btn--option btn--load-data"
v-if="!scrollNoMoreData && scrollDataLoaded" v-if="!scrollNoMoreData && scrollDataLoaded && timetableHistory.length >= 15"
@click="addHistoryData" @click="addHistoryData"
> >
{{ $t('journal.load-data') }} {{ $t('journal.load-data') }}
</button> </button>
</div> </div>
</div> <!-- </div> -->
</transition> <!-- </transition> -->
<div class="journal_warning" v-if="scrollNoMoreData">{{ $t('journal.no-further-data') }}</div> <div class="journal_warning" v-if="scrollNoMoreData">{{ $t('journal.no-further-data') }}</div>
<div class="journal_warning" v-else-if="!scrollDataLoaded">{{ $t('journal.loading-further-data') }}</div> <div class="journal_warning" v-else-if="!scrollDataLoaded">{{ $t('journal.loading-further-data') }}</div>
@@ -105,6 +103,7 @@ export default defineComponent({
const searchersValues = reactive({ const searchersValues = reactive({
'search-train': '', 'search-train': '',
'search-driver': '', 'search-driver': '',
// 'search-date': '',
} as JournalTimetableSearcher); } as JournalTimetableSearcher);
const countFromIndex = ref(0); const countFromIndex = ref(0);
@@ -194,6 +193,9 @@ export default defineComponent({
const driver = props.searchers?.['search-driver'].trim(); const driver = props.searchers?.['search-driver'].trim();
const train = props.searchers?.['search-train'].trim(); const train = props.searchers?.['search-train'].trim();
// TODO: dodanie możliwości sortowania timestampem z API
// const date = props.searchers?.['search-date'].trim();
if (driver) queries.push(`driverName=${driver}`); if (driver) queries.push(`driverName=${driver}`);
if (train) queries.push(train.startsWith('#') ? `timetableId=${train.replace('#', '')}` : `trainNo=${train}`); if (train) queries.push(train.startsWith('#') ? `timetableId=${train.replace('#', '')}` : `trainNo=${train}`);
@@ -247,8 +249,6 @@ export default defineComponent({
: ''; : '';
this.dataStatus = DataStatus.Loaded; this.dataStatus = DataStatus.Loaded;
console.log(this.dataStatus);
} catch (error) { } catch (error) {
this.dataStatus = DataStatus.Error; this.dataStatus = DataStatus.Error;
this.dataErrorMessage = 'Ups! Coś poszło nie tak!'; this.dataErrorMessage = 'Ups! Coś poszło nie tak!';
@@ -91,7 +91,7 @@
<img :src="getIcon(`arrow-${item.showStock.value ? 'asc' : 'desc'}`)" alt="Arrow" /> <img :src="getIcon(`arrow-${item.showStock.value ? 'asc' : 'desc'}`)" alt="Arrow" />
</button> </button>
<div class="info-extended" v-if="timetable.stockString" v-show="item.showStock.value"> <div class="info-extended" v-if="timetable.stockString && item.showStock.value">
<hr /> <hr />
<div> <div>
+3 -3
View File
@@ -8,11 +8,11 @@
} }
&-enter-active { &-enter-active {
transition: all 150ms ease-out; transition: all 150ms 100ms ease-out;
} }
&-leave-active { &-leave-active {
transition: all 150ms ease-out; transition: all 150ms 100ms ease-out;
} }
} }
@@ -47,7 +47,7 @@
.journal_item, .journal_item,
.journal_warning { .journal_warning {
background: #202020; background-color: #1a1a1a;
padding: 1em; padding: 1em;
margin-bottom: 1em; margin-bottom: 1em;
} }
+19 -24
View File
@@ -12,6 +12,25 @@
--clr-error: #df3e3e; --clr-error: #df3e3e;
--clr-warning: #c59429; --clr-warning: #c59429;
font-size: 16px;
}
::-webkit-scrollbar {
width: 1rem;
height: 1rem;
background-color: transparent;
&-track {
border-radius: 0.5em;
background-color: #333;
}
&-thumb {
border-radius: 0.5em;
background-color: #666;
}
} }
html { html {
@@ -36,30 +55,6 @@ body {
} }
} }
*:focus-visible {
outline: 1px solid white;
outline-offset: 1px;
}
:root {
font-size: 16px;
}
::-webkit-scrollbar {
width: 1rem;
height: 1rem;
&-track {
border-radius: 0.5em;
}
&-thumb {
border-radius: 0.5em;
background-color: #1b1b1b;
}
}
.g-tooltip { .g-tooltip {
position: relative; position: relative;
+1 -1
View File
@@ -1,3 +1,3 @@
export type JournalTimetableSearcher = { export type JournalTimetableSearcher = {
[key in 'search-driver' | 'search-train']: string; [key in 'search-driver' | 'search-train' | 'search-date']: string;
}; };