history of added stops

This commit is contained in:
Kacper Donat 2020-11-01 12:11:20 +01:00
parent c2b959a9da
commit 75c0c98c8d
10 changed files with 140 additions and 26 deletions

View File

@ -3,6 +3,7 @@
<div v-if="filter.length < 3" class="mt-2">
<favourites />
<stop-history />
</div>
<div v-if="state === 'fetching'" class="text-center p-4">
@ -22,9 +23,9 @@
</div>
<ul class="stop-group__stops list-underlined">
<li v-for="stop in group" :key="stop.id" class="d-flex">
<picker-stop :stop="stop" class="flex-grow-1">
<picker-stop :stop="stop" class="flex-grow-1 finder__stop">
<template v-slot:primary-action>
<button @click="select(stop, $event)" class="btn btn-action">
<button @click="select(stop, $event)" class="btn btn-action stretched-link">
<tooltip>dodaj przystanek</tooltip>
<ui-icon icon="add" />
</button>

View File

@ -1,23 +1,25 @@
<div class="finder__stop">
<div>
<div class="d-flex">
<slot name="primary-action" />
<div class="overflow-hidden align-self-center">
<stop :stop="stop" />
<div class="stop__destinations" v-if="destinations && destinations.length > 0">
<ul class="ml-1">
<li class="stop__destination destination" v-for="destination in destinations" :key="destination.stop.id">
<ul class="destination__lines">
<li v-for="line in destination.lines">
<line-symbol :line="line" :key="line.symbol" simple/>
</li>
</ul>
<span class="destination__name ml-1">{{ destination.stop.name }}</span>
</li>
</ul>
<div class="d-flex position-relative" style="min-width: 0">
<slot name="primary-action" />
<div class="overflow-hidden align-self-center">
<stop :stop="stop" />
<div class="stop__destinations" v-if="destinations && destinations.length > 0">
<ul>
<li class="stop__destination destination" v-for="destination in destinations" :key="destination.stop.id">
<ul class="destination__lines">
<li v-for="line in destination.lines">
<line-symbol :line="line" :key="line.symbol" simple/>
</li>
</ul>
<span class="destination__name ml-1">{{ destination.stop.name }}</span>
</li>
</ul>
</div>
</div>
</div>
<div class="stop__actions flex-space-left">
<div class="stop__actions">
<slot name="actions">
<button class="btn btn-action" ref="action-info" @click="details = !details">
<tooltip>dodatkowe informacje</tooltip>

View File

@ -0,0 +1,11 @@
<ul class="list-underlined history" v-if="all.length > 0">
<li v-for="entry in all" class="history__entry">
<picker-stop :stop="entry.stop" class="flex-grow-1 finder__stop">
<template v-slot:primary-action>
<button @click="select(entry.stop, $event)" class="btn btn-action stretched-link">
<ui-icon icon="history" />
</button>
</template>
</picker-stop>
</li>
</ul>

View File

@ -76,8 +76,12 @@
.stop-group__header {
@extend .section__title;
display: flex;
padding: 0 !important;
margin-bottom: 0 !important;
.actions {
margin: -.5rem -.75rem;
margin-left: auto;
}
}
.stop-group__name {

View File

@ -0,0 +1,13 @@
import Component from "vue-class-component";
import Vue from "vue";
import { History } from "../store";
import { HistoryEntry } from "../store/history";
import { Mutation } from "vuex-class";
import { Stop } from "../model";
@Component({ template: require('../../components/stop/history.html' )})
export class StopHistory extends Vue {
@History.Getter all: HistoryEntry[];
@Mutation("add") select: (stops: Stop[]) => void;
}

View File

@ -1,10 +1,13 @@
import Component from "vue-class-component";
import Vue from "vue";
import { Destination, Line, StopWithDestinations as Stop, StopGroup, StopGroups } from "../model";
import { Line, StopGroup, StopGroups, StopWithDestinations as Stop } from "../model";
import { Prop, Watch } from "vue-property-decorator";
import { FetchingState, filter, map, match, unique } from "../utils";
import { debounce } from "../decorators";
import urls from '../urls';
import { Mutation } from "vuex-class";
import { HistoryEntry } from "../store/history";
import { StopHistory } from "./history";
@Component({ template: require('../../components/picker/stop.html') })
export class PickerStopComponent extends Vue {
@ -49,7 +52,8 @@ export class PickerStopComponent extends Vue {
@Component({
template: require('../../components/finder.html'),
components: {
"PickerStop": PickerStopComponent
"PickerStop": PickerStopComponent,
"StopHistory": StopHistory,
}
})
export class FinderComponent extends Vue {
@ -61,6 +65,8 @@ export class FinderComponent extends Vue {
@Prop({default: [], type: Array})
public blacklist: Stop[];
@Mutation('history/push') pushToHistory: (entry: HistoryEntry) => void;
get filtered(): StopGroups {
const groups = map(
this.found,
@ -91,6 +97,11 @@ export class FinderComponent extends Vue {
}
private select(stop) {
this.pushToHistory({
date: this.$moment(),
stop: stop,
})
this.$emit('select', stop);
}
}

View File

@ -12,6 +12,7 @@ import {
faClock,
faCog,
faExclamationTriangle,
faHistory,
faHourglassHalf,
faInfoCircle,
faMapMarkerAlt,
@ -97,6 +98,7 @@ const definitions = {
{ icon: faSolidExclamationTriangle, transform: "shrink-5 down-4 right-6" }
]),
'close': simple(faTimes),
'history': simple(faHistory),
...lineTypeIcons,
...messageTypeIcons,
};

View File

@ -0,0 +1,66 @@
import { Stop } from "../model";
import { Module } from "vuex";
import { RootState } from "./root";
import * as moment from "moment";
import { Moment } from "moment";
import { Jsonified } from "../utils";
export interface HistoryEntry {
stop: Stop,
date: Moment,
}
export interface HistorySettings {
maxEntries: number,
}
export interface HistoryState {
entries: Jsonified<HistoryEntry>[],
settings: HistorySettings,
}
export function serializeHistoryEntry(entry: HistoryEntry): Jsonified<HistoryEntry> {
return {
...entry,
date: entry.date.toISOString(),
}
}
export function deserializeHistoryEntry(serialized: Jsonified<HistoryEntry>): HistoryEntry {
return {
...serialized,
date: moment(serialized.date),
}
}
export const history: Module<HistoryState, RootState> = {
namespaced: true,
state: {
entries: [],
settings: {
maxEntries: 10,
}
},
mutations: {
clear(state: HistoryState) {
state.entries = [];
},
push(state: HistoryState, entry: HistoryEntry) {
state.entries = state.entries.filter(cur => cur.stop.id != entry.stop.id);
state.entries.unshift(serializeHistoryEntry(entry));
if (state.entries.length > state.settings.maxEntries) {
state.entries = state.entries.slice(0, state.settings.maxEntries);
}
},
saveSettings(state: HistoryState, settings: Partial<HistorySettings>) {
Object.assign(state.settings, settings);
}
},
getters: {
all: ({ entries, settings }) => entries.slice(0, settings.maxEntries).map(deserializeHistoryEntry),
latest: ({ entries }) => n => entries.slice(0, n).map(deserializeHistoryEntry),
}
}
export default history;

View File

@ -3,6 +3,7 @@ import Vuex from 'vuex';
import messages, { MessagesState } from './messages';
import departures, { DeparturesState } from './departures'
import favourites, { FavouritesState } from './favourites'
import history, { HistoryState } from "./history";
import departureSettings, { DeparturesSettingsState } from "./settings/departures";
import messagesSettings, { MessagesSettingsState } from "./settings/messages";
@ -14,12 +15,13 @@ export type State = {
messages: MessagesState;
departures: DeparturesState;
favourites: FavouritesState;
"departures-settings": DeparturesSettingsState,
"messages-settings": MessagesSettingsState,
"departures-settings": DeparturesSettingsState;
"messages-settings": MessagesSettingsState;
history: HistoryState;
} & RootState;
const localStoragePersist = new VuexPersistence<State>({
modules: ['favourites', 'departures-settings', 'messages-settings'],
modules: ['favourites', 'departures-settings', 'messages-settings', 'history'],
});
const sessionStoragePersist = new VuexPersistence<State>({
@ -35,6 +37,7 @@ const store = new Vuex.Store<RootState>({
favourites,
'departures-settings': departureSettings,
'messages-settings': messagesSettings,
history,
},
plugins: [
localStoragePersist.plugin,
@ -49,3 +52,4 @@ export const DeparturesSettings = namespace('departures-settings');
export const MessagesSettings = namespace('messages-settings');
export const Departures = namespace('departures');
export const Messages = namespace('messages');
export const History = namespace('history');

View File

@ -86,8 +86,8 @@
</header>
<ul class="picker__stops list-underlined">
<li v-for="stop in stops" :key="stop.id" class="d-flex align-items-center">
<picker-stop :stop="stop" class="flex-grow-1">
<li v-for="stop in stops" :key="stop.id" class="picker__stop">
<picker-stop :stop="stop">
<template v-slot:primary-action>
<button @click="remove(stop)" class="btn btn-action">
<tooltip>usuń przystanek</tooltip>