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 class="options_filters">
<span class="journal-filter active" tabindex="0">AKTYWNY</span>
<span class="journal-filter abandoned" tabindex="0">PORZUCONY</span>
<span class="journal-filter fulfilled" tabindex="0">WYPEŁNIONY</span>
<button
v-for="filter in journalFilters"
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>
</template>
<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 ActionButton from '../Global/ActionButton.vue';
import SelectBox from '../Global/SelectBox.vue';
export default defineComponent({
components: { SelectBox, ActionButton },
emits: ['changedOptions'],
emits: ['changedOptions', 'changedFilter'],
data: () => ({
exitIcon: require('@/assets/icon-exit.svg'),
journalFilters,
}),
setup() {
@@ -81,6 +89,7 @@ export default defineComponent({
searchedTrain: inject('searchedTrain') as string,
searchedDriver: inject('searchedDriver') as string,
sorterActive: inject('sorterActive') as { id: string | number; dir: number },
journalFilterActive: inject('journalFilterActive') as JournalFilter
};
},
@@ -92,6 +101,11 @@ export default defineComponent({
this.$emit('changedOptions');
},
changeJournalFilter(filter: JournalFilter) {
this.journalFilterActive = filter;
this.$emit('changedFilter');
},
search() {
this.$emit('changedOptions');
},
@@ -111,6 +125,7 @@ export default defineComponent({
<style lang="scss" scoped>
@import '../../styles/responsive';
@import '../../styles/option.scss';
.options {
&_wrapper {
@@ -133,24 +148,21 @@ export default defineComponent({
}
&_filters {
display: flex;
margin: 0.5em 0 0 0;
.journal-filter {
background-color: #333;
padding: 0.25em 0.3em;
.journal-filter-option {
margin: 0 0.25em 0 0;
cursor: pointer;
&.abandoned {
&#abandoned {
color: salmon;
}
&.fulfilled {
&#fulfilled {
color: lightgreen;
}
&.active {
&#active {
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-total-stops": "total stops",
"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": {
"users": "PLAYERS ONLINE",
+6 -1
View File
@@ -195,7 +195,12 @@
"option-distance": "kilometraż",
"option-total-stops": "stacje",
"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": {
"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;
border: none;
font-family: "Quicksand", sans-serif;
font-size: 1em;
}
input {
@@ -214,7 +216,24 @@ ul {
&--image {
color: white;
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 {
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
// user-select: none;
// -moz-user-select: none;
// -webkit-user-select: none;
width: 100%;
text-align: center;
@@ -33,4 +33,9 @@
}
}
}
&:focus span {
// outline: 1px solid white;
border: none;
}
}
+32 -44
View File
@@ -1,13 +1,17 @@
<template>
<section class="history-view">
<div class="history-wrapper">
<JournalOptions @changedOptions="search" />
<JournalOptions @changedOptions="search" @changedFilter="search" />
<div class="history_list">
<div class="list_wrapper" ref="scrollElement">
<transition name="warning" mode="out-in">
<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">
{{ $t('app.error') }}
@@ -112,17 +116,12 @@
</transition>
</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>
</section>
</template>
<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 SearchBox from '@/components/Global/SearchBox.vue';
@@ -132,8 +131,9 @@ import { DataStatus } from '@/scripts/enums/DataStatus';
import ActionButton from '@/components/Global/ActionButton.vue';
import JournalOptions from '@/components/JournalView/JournalOptions.vue';
import FilterOption from '@/scripts/interfaces/FilterOption';
import { URLs } from '@/scripts/utils/apiURLs';
import { journalFilters } from '@/data/journalFilters';
import { JournalFilterType } from '@/scripts/enums/JournalFilterType';
const PROD_MODE = true;
@@ -174,31 +174,6 @@ interface TimetableHistory {
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({
components: { SearchBox, ActionButton, JournalOptions },
mixins: [dateMixin],
@@ -216,6 +191,8 @@ export default defineComponent({
});
const sorterActive = ref({ id: 'timetableId', dir: -1 });
const journalFilterActive = ref(journalFilters[0]);
const searchedDriver = ref('');
const searchedTrain = ref('');
const countFromIndex = ref(0);
@@ -224,6 +201,7 @@ export default defineComponent({
provide('searchedTrain', searchedTrain);
provide('searchedDriver', searchedDriver);
provide('sorterActive', sorterActive);
provide('journalFilterActive', journalFilterActive);
const scrollElement: Ref<HTMLElement | null> = ref(null);
@@ -256,14 +234,13 @@ export default defineComponent({
searchedDriver,
searchedTrain,
sorterActive,
journalFilterActive,
countFromIndex,
countLimit,
scrollElement,
maxCount: ref(15),
filters: reactive({ ...initFilters }) as { [filterSection: string]: { [filterId: string]: FilterOption } },
};
},
@@ -290,9 +267,7 @@ export default defineComponent({
this.fetchHistoryData({
searchedDriver: this.searchedDriver,
searchedTrain: this.searchedTrain,
fulfilled: true,
abandoned: true,
terminated: true
filter: this.journalFilterActive,
});
},
@@ -304,9 +279,7 @@ export default defineComponent({
props: {
searchedDriver?: string;
searchedTrain?: string;
fulfilled?: boolean;
terminated?: boolean;
abandoned?: boolean;
filter?: JournalFilter;
} = {}
) {
this.historyDataStatus.status = DataStatus.Loading;
@@ -324,7 +297,22 @@ export default defineComponent({
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 {
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;
img {
+7
View File
@@ -1,5 +1,6 @@
import { ComponentCustomProperties } from 'vue'
import { Store } from 'vuex'
import { JournalFilterType } from './scripts/enums/JournalFilterType';
import { TrainFilterType } from './scripts/enums/TrainFilterType';
declare module '@vue/runtime-core' {
@@ -18,4 +19,10 @@ declare module '@vue/runtime-core' {
id: TrainFilterType;
isActive: boolean;
}
interface JournalFilter {
id: JournalFilterType;
filterSection: string;
isActive: boolean;
}
}