Dodano filtry dla dziennika rozkładów jazdy

This commit is contained in:
2022-05-17 01:39:40 +02:00
parent 42155fe6b8
commit 2d8155fdbe
9 changed files with 138 additions and 62 deletions
+25 -13
View File
@@ -41,26 +41,34 @@
</div> </div>
<div class="options_filters"> <div class="options_filters">
<span class="journal-filter active" tabindex="0">AKTYWNY</span> <button
<span class="journal-filter abandoned" tabindex="0">PORZUCONY</span> v-for="filter in journalFilters"
<span class="journal-filter fulfilled" tabindex="0">WYPEŁNIONY</span> class="journal-filter-option btn--option"
:class="{ checked: journalFilterActive.id === filter.id }"
:id="filter.id"
@click="changeJournalFilter(filter)"
>
{{ $t(`journal.filter-${filter.id}`) }}
</button>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, inject } from 'vue'; import { journalFilters } from '@/data/journalFilters';
import { computed, defineComponent, inject, JournalFilter } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import ActionButton from '../Global/ActionButton.vue'; import ActionButton from '../Global/ActionButton.vue';
import SelectBox from '../Global/SelectBox.vue'; import SelectBox from '../Global/SelectBox.vue';
export default defineComponent({ export default defineComponent({
components: { SelectBox, ActionButton }, components: { SelectBox, ActionButton },
emits: ['changedOptions'], emits: ['changedOptions', 'changedFilter'],
data: () => ({ data: () => ({
exitIcon: require('@/assets/icon-exit.svg'), exitIcon: require('@/assets/icon-exit.svg'),
journalFilters,
}), }),
setup() { setup() {
@@ -81,6 +89,7 @@ export default defineComponent({
searchedTrain: inject('searchedTrain') as string, searchedTrain: inject('searchedTrain') as string,
searchedDriver: inject('searchedDriver') as string, searchedDriver: inject('searchedDriver') as string,
sorterActive: inject('sorterActive') as { id: string | number; dir: number }, sorterActive: inject('sorterActive') as { id: string | number; dir: number },
journalFilterActive: inject('journalFilterActive') as JournalFilter
}; };
}, },
@@ -92,6 +101,11 @@ export default defineComponent({
this.$emit('changedOptions'); this.$emit('changedOptions');
}, },
changeJournalFilter(filter: JournalFilter) {
this.journalFilterActive = filter;
this.$emit('changedFilter');
},
search() { search() {
this.$emit('changedOptions'); this.$emit('changedOptions');
}, },
@@ -111,6 +125,7 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../../styles/responsive'; @import '../../styles/responsive';
@import '../../styles/option.scss';
.options { .options {
&_wrapper { &_wrapper {
@@ -133,24 +148,21 @@ export default defineComponent({
} }
&_filters { &_filters {
display: flex;
margin: 0.5em 0 0 0; margin: 0.5em 0 0 0;
.journal-filter { .journal-filter-option {
background-color: #333;
padding: 0.25em 0.3em;
margin: 0 0.25em 0 0; margin: 0 0.25em 0 0;
cursor: pointer; &#abandoned {
&.abandoned {
color: salmon; color: salmon;
} }
&.fulfilled { &#fulfilled {
color: lightgreen; color: lightgreen;
} }
&.active { &#active {
color: lightblue; color: lightblue;
} }
} }
+29
View File
@@ -0,0 +1,29 @@
import { JournalFilterType } from "@/scripts/enums/JournalFilterType";
import { JournalFilter } from "vue";
export const journalFilters: JournalFilter[] = [
{
id: JournalFilterType.all,
filterSection: "timetable-status",
isActive: true
},
{
id: JournalFilterType.active,
filterSection: "timetable-status",
isActive: false
},
{
id: JournalFilterType.fulfilled,
filterSection: "timetable-status",
isActive: false
},
{
id: JournalFilterType.abandoned,
filterSection: "timetable-status",
isActive: false
},
]
+6 -1
View File
@@ -193,7 +193,12 @@
"option-distance": "distance", "option-distance": "distance",
"option-total-stops": "total stops", "option-total-stops": "total stops",
"option-beginDate": "date", "option-beginDate": "date",
"option-timetableId": "timetable ID" "option-timetableId": "timetable ID",
"filter-all": "ALL ENTRIES",
"filter-abandoned": "ABANDONED",
"filter-fulfilled": "FULFILLED",
"filter-active": "ACTIVE"
}, },
"scenery": { "scenery": {
"users": "PLAYERS ONLINE", "users": "PLAYERS ONLINE",
+6 -1
View File
@@ -195,7 +195,12 @@
"option-distance": "kilometraż", "option-distance": "kilometraż",
"option-total-stops": "stacje", "option-total-stops": "stacje",
"option-beginDate": "data", "option-beginDate": "data",
"option-timetableId": "ID rozkładu" "option-timetableId": "ID rozkładu",
"filter-all": "WSZYSTKIE",
"filter-abandoned": "PORZUCONE",
"filter-fulfilled": "WYPEŁNIONE",
"filter-active": "AKTYWNE"
}, },
"scenery": { "scenery": {
"users": "GRACZE ONLINE", "users": "GRACZE ONLINE",
+6
View File
@@ -0,0 +1,6 @@
export const enum JournalFilterType {
active = "active",
fulfilled = "fulfilled",
abandoned = "abandoned",
all = "all"
}
+19
View File
@@ -114,6 +114,8 @@ select {
// font-family: "Open Sans", sans-serif; // font-family: "Open Sans", sans-serif;
border: none; border: none;
font-family: "Quicksand", sans-serif; font-family: "Quicksand", sans-serif;
font-size: 1em;
} }
input { input {
@@ -214,7 +216,24 @@ ul {
&--image { &--image {
color: white; color: white;
transition: color 0.3s; transition: color 0.3s;
}
&--option {
cursor: pointer;
color: white;
background-color: #333;
border-radius: 0.25em;
padding: 0.25em 0.5em;
&:hover {
background-color: #3c3c3c;
}
&.checked {
color: var(--clr-primary);
font-weight: bold;
}
} }
} }
+8 -3
View File
@@ -7,9 +7,9 @@
} }
span { span {
user-select: none; // user-select: none;
-moz-user-select: none; // -moz-user-select: none;
-webkit-user-select: none; // -webkit-user-select: none;
width: 100%; width: 100%;
text-align: center; text-align: center;
@@ -33,4 +33,9 @@
} }
} }
} }
&:focus span {
// outline: 1px solid white;
border: none;
}
} }
+32 -44
View File
@@ -1,13 +1,17 @@
<template> <template>
<section class="history-view"> <section class="history-view">
<div class="history-wrapper"> <div class="history-wrapper">
<JournalOptions @changedOptions="search" /> <JournalOptions @changedOptions="search" @changedFilter="search" />
<div class="history_list"> <div class="history_list">
<div class="list_wrapper" ref="scrollElement"> <div class="list_wrapper" ref="scrollElement">
<transition name="warning" mode="out-in"> <transition name="warning" mode="out-in">
<div :key="historyDataStatus.status"> <div :key="historyDataStatus.status">
<!-- <div v-if="isDataLoading" class="history_warning"></div> -->
<div class="history_loading" v-if="isDataLoading">
<img :src="icons.loading" alt="loading icon" />
<span class="loading-label">{{ $t('app.loading') }}</span>
</div>
<div v-if="!isDataLoading && isDataError" class="history_warning error"> <div v-if="!isDataLoading && isDataError" class="history_warning error">
{{ $t('app.error') }} {{ $t('app.error') }}
@@ -112,17 +116,12 @@
</transition> </transition>
</div> </div>
</div> </div>
<div class="history-loading" v-if="isDataLoading">
<img :src="icons.loading" alt="loading icon" />
<span class="loading-label">{{ $t('app.loading') }}</span>
</div>
</div> </div>
</section> </section>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, provide, reactive, Ref, ref } from 'vue'; import { computed, defineComponent, JournalFilter, provide, Ref, ref } from 'vue';
import axios from 'axios'; import axios from 'axios';
import SearchBox from '@/components/Global/SearchBox.vue'; import SearchBox from '@/components/Global/SearchBox.vue';
@@ -132,8 +131,9 @@ import { DataStatus } from '@/scripts/enums/DataStatus';
import ActionButton from '@/components/Global/ActionButton.vue'; import ActionButton from '@/components/Global/ActionButton.vue';
import JournalOptions from '@/components/JournalView/JournalOptions.vue'; import JournalOptions from '@/components/JournalView/JournalOptions.vue';
import FilterOption from '@/scripts/interfaces/FilterOption';
import { URLs } from '@/scripts/utils/apiURLs'; import { URLs } from '@/scripts/utils/apiURLs';
import { journalFilters } from '@/data/journalFilters';
import { JournalFilterType } from '@/scripts/enums/JournalFilterType';
const PROD_MODE = true; const PROD_MODE = true;
@@ -174,31 +174,6 @@ interface TimetableHistory {
authorId?: number; authorId?: number;
} }
const initFilters = {
status: {
active: {
id: 'active',
name: 'status',
value: false,
defaultValue: false,
},
abandoned: {
id: 'abandoned',
name: 'status',
value: false,
defaultValue: false,
},
fulfilled: {
id: 'fulfilled',
name: 'status',
value: true,
defaultValue: true,
},
},
};
export default defineComponent({ export default defineComponent({
components: { SearchBox, ActionButton, JournalOptions }, components: { SearchBox, ActionButton, JournalOptions },
mixins: [dateMixin], mixins: [dateMixin],
@@ -216,6 +191,8 @@ export default defineComponent({
}); });
const sorterActive = ref({ id: 'timetableId', dir: -1 }); const sorterActive = ref({ id: 'timetableId', dir: -1 });
const journalFilterActive = ref(journalFilters[0]);
const searchedDriver = ref(''); const searchedDriver = ref('');
const searchedTrain = ref(''); const searchedTrain = ref('');
const countFromIndex = ref(0); const countFromIndex = ref(0);
@@ -224,6 +201,7 @@ export default defineComponent({
provide('searchedTrain', searchedTrain); provide('searchedTrain', searchedTrain);
provide('searchedDriver', searchedDriver); provide('searchedDriver', searchedDriver);
provide('sorterActive', sorterActive); provide('sorterActive', sorterActive);
provide('journalFilterActive', journalFilterActive);
const scrollElement: Ref<HTMLElement | null> = ref(null); const scrollElement: Ref<HTMLElement | null> = ref(null);
@@ -256,14 +234,13 @@ export default defineComponent({
searchedDriver, searchedDriver,
searchedTrain, searchedTrain,
sorterActive, sorterActive,
journalFilterActive,
countFromIndex, countFromIndex,
countLimit, countLimit,
scrollElement, scrollElement,
maxCount: ref(15), maxCount: ref(15),
filters: reactive({ ...initFilters }) as { [filterSection: string]: { [filterId: string]: FilterOption } },
}; };
}, },
@@ -290,9 +267,7 @@ export default defineComponent({
this.fetchHistoryData({ this.fetchHistoryData({
searchedDriver: this.searchedDriver, searchedDriver: this.searchedDriver,
searchedTrain: this.searchedTrain, searchedTrain: this.searchedTrain,
fulfilled: true, filter: this.journalFilterActive,
abandoned: true,
terminated: true
}); });
}, },
@@ -304,9 +279,7 @@ export default defineComponent({
props: { props: {
searchedDriver?: string; searchedDriver?: string;
searchedTrain?: string; searchedTrain?: string;
fulfilled?: boolean; filter?: JournalFilter;
terminated?: boolean;
abandoned?: boolean;
} = {} } = {}
) { ) {
this.historyDataStatus.status = DataStatus.Loading; this.historyDataStatus.status = DataStatus.Loading;
@@ -324,7 +297,22 @@ export default defineComponent({
queries.push('countLimit=15'); queries.push('countLimit=15');
// queries.push(`fulfilled=${Number(props.fulfilled) || 1}`, `terminated=${Number(props.terminated) || 1}`, `abandoned=${Number(props.abandoned) || 1}`, `active=1`); switch (props.filter?.id) {
case JournalFilterType.abandoned:
queries.push('fulfilled=0', 'terminated=1');
break;
case JournalFilterType.active:
queries.push('terminated=0');
break;
case JournalFilterType.fulfilled:
queries.push('fulfilled=1');
break;
default:
break;
}
try { try {
const responseData: APIResponse | null = await (await axios.get(`${API_URL}?${queries.join('&')}`)).data; const responseData: APIResponse | null = await (await axios.get(`${API_URL}?${queries.join('&')}`)).data;
@@ -459,7 +447,7 @@ li,
} }
} }
.history-loading { .history_loading {
margin-top: 2em; margin-top: 2em;
img { img {
+7
View File
@@ -1,5 +1,6 @@
import { ComponentCustomProperties } from 'vue' import { ComponentCustomProperties } from 'vue'
import { Store } from 'vuex' import { Store } from 'vuex'
import { JournalFilterType } from './scripts/enums/JournalFilterType';
import { TrainFilterType } from './scripts/enums/TrainFilterType'; import { TrainFilterType } from './scripts/enums/TrainFilterType';
declare module '@vue/runtime-core' { declare module '@vue/runtime-core' {
@@ -18,4 +19,10 @@ declare module '@vue/runtime-core' {
id: TrainFilterType; id: TrainFilterType;
isActive: boolean; isActive: boolean;
} }
interface JournalFilter {
id: JournalFilterType;
filterSection: string;
isActive: boolean;
}
} }