new choosing layout
This commit is contained in:
parent
12fb18d902
commit
4221fab3d1
@ -1,5 +1,5 @@
|
||||
<div class="finder">
|
||||
<input class="form-control" v-model="filter" />
|
||||
<input class="form-control" v-model="filter" placeholder="Zacznij pisać nazwę aby szukać..."/>
|
||||
|
||||
<div v-if="state === 'fetching'">
|
||||
<fa icon="spinner-third" pulse/>
|
||||
@ -30,8 +30,4 @@
|
||||
<fa :icon="['far', 'exclamation-triangle']"></fa>
|
||||
Nie znaleziono więcej przystanków, spełniających te kryteria.
|
||||
</div>
|
||||
<div class="alert alert-info" v-else>
|
||||
<fa :icon="['far', 'search']"></fa>
|
||||
Wprowadź zapytanie powyżej, aby wyszukać przystanek.
|
||||
</div>
|
||||
</div>
|
@ -1,12 +0,0 @@
|
||||
<div class="picker">
|
||||
<ul class="picker__stops list-underlined">
|
||||
<li v-for="stop in stops" :key="stop.id" class="d-flex align-items-center">
|
||||
<button @click="remove(stop)" class="btn btn-action">
|
||||
<fa :icon="['fal', 'times']" />
|
||||
</button>
|
||||
<stop :stop="stop" class="flex-grow-1"></stop>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<stop-finder @select="add" :blacklist="stops"/>
|
||||
</div>
|
@ -79,8 +79,7 @@
|
||||
|
||||
font-size: medium;
|
||||
background: transparent;
|
||||
padding-top: .5rem;
|
||||
padding-bottom: .5rem;
|
||||
padding: .5rem .75rem;
|
||||
|
||||
line-height: $btn-line-height;
|
||||
|
||||
|
@ -25,103 +25,11 @@ Vue.use(Vuex);
|
||||
import('bootstrap'),
|
||||
]);
|
||||
|
||||
// here goes "public" API
|
||||
window['czydojade'] = Object.assign({}, window['czydojade'], {
|
||||
components
|
||||
});
|
||||
|
||||
store.dispatch('messages/update');
|
||||
store.dispatch('load', window['czydojade'].state);
|
||||
|
||||
let intervals = { messages: null, departures: null };
|
||||
|
||||
window['app'] = new Vue({
|
||||
el: '#app',
|
||||
store: store,
|
||||
data: {
|
||||
sections: {
|
||||
messages: true
|
||||
},
|
||||
settings: {
|
||||
messages: false,
|
||||
departures: false
|
||||
},
|
||||
autorefresh: {
|
||||
messages: {
|
||||
active: true,
|
||||
interval: 60
|
||||
},
|
||||
departures: {
|
||||
active: true,
|
||||
interval: 10
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
computed: {
|
||||
messages(this: any) {
|
||||
return {
|
||||
count: this.$store.getters['messages/count'],
|
||||
counts: this.$store.getters['messages/counts'],
|
||||
state: this.$store.state.messages.state
|
||||
};
|
||||
},
|
||||
departures(this: any) {
|
||||
return {
|
||||
state: this.$store.state.departures.state
|
||||
};
|
||||
},
|
||||
stops: {
|
||||
get(this: Vue) {
|
||||
return this.$store.state.stops;
|
||||
},
|
||||
set(this: Vue, value) {
|
||||
this.$store.commit('updateStops', value);
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
stops(this: any, stops) {
|
||||
this.updateDepartures({ stops });
|
||||
},
|
||||
autorefresh: {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
handler(this: any, settings) {
|
||||
if (intervals.messages) {
|
||||
clearInterval(intervals.messages);
|
||||
intervals.messages = null;
|
||||
}
|
||||
|
||||
if (intervals.departures) {
|
||||
clearInterval(intervals.departures);
|
||||
intervals.messages = null;
|
||||
}
|
||||
|
||||
if (settings.messages.active) {
|
||||
intervals.messages = setInterval(() => this.updateMessages(), Math.max(5, settings.messages.interval) * 1000);
|
||||
}
|
||||
|
||||
if (settings.departures.active) {
|
||||
intervals.departures = setInterval(() => this.updateDepartures({ stops: this.stops }), Math.max(5, settings.departures.interval) * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
updateMessages: 'messages/update',
|
||||
updateDepartures: 'departures/update'
|
||||
}),
|
||||
...mapMutations({
|
||||
updateStops: 'updateStops'
|
||||
}),
|
||||
save(this: Vue) {
|
||||
this.$store.dispatch('save').then(x => console.log(x));
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$el.classList.remove('not-ready');
|
||||
}
|
||||
// here goes "public" API
|
||||
window['czydojade'] = Object.assign({}, window['czydojade'], {
|
||||
components, application: new components.Application({ el: '#app' })
|
||||
});
|
||||
})();
|
||||
|
@ -1,5 +1,94 @@
|
||||
import Vue from 'vue'
|
||||
import store from '../store'
|
||||
import { Component, Watch } from "vue-property-decorator";
|
||||
import { Mutation, Action } from 'vuex-class'
|
||||
import { ObtainPayload } from "../store/departures";
|
||||
import { Stop } from "../model";
|
||||
|
||||
@Component({ store })
|
||||
export class Application extends Vue {
|
||||
private messages: boolean = true;
|
||||
private sections = {
|
||||
messages: true
|
||||
};
|
||||
|
||||
private settings = {
|
||||
messages: false,
|
||||
departures: false
|
||||
};
|
||||
|
||||
private autorefresh = {
|
||||
messages: {
|
||||
active: true,
|
||||
interval: 60
|
||||
},
|
||||
departures: {
|
||||
active: true,
|
||||
interval: 10
|
||||
}
|
||||
};
|
||||
|
||||
private intervals = { messages: null, departures: null };
|
||||
|
||||
get messages() {
|
||||
return {
|
||||
count: this.$store.getters['messages/count'],
|
||||
counts: this.$store.getters['messages/counts'],
|
||||
state: this.$store.state.messages.state
|
||||
};
|
||||
}
|
||||
|
||||
get departures() {
|
||||
return {
|
||||
state: this.$store.state.departures.state
|
||||
};
|
||||
}
|
||||
|
||||
get stops() {
|
||||
return this.$store.state.stops;
|
||||
}
|
||||
|
||||
set stops(value) {
|
||||
this.$store.commit('updateStops', value);
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.$el.classList.remove('not-ready');
|
||||
}
|
||||
|
||||
@Action('messages/update') updateMessages: () => void;
|
||||
@Action('departures/update') updateDepartures: (payload: ObtainPayload) => void;
|
||||
|
||||
@Mutation add: (stops: Stop[]) => void;
|
||||
@Mutation remove: (stop: Stop) => void;
|
||||
@Mutation clear: () => void;
|
||||
|
||||
save() {
|
||||
this.$store.dispatch('save').then(x => console.log(x));
|
||||
}
|
||||
|
||||
@Watch('stops')
|
||||
onStopUpdate(this: any, stops) {
|
||||
this.updateDepartures({ stops });
|
||||
}
|
||||
|
||||
@Watch('settings', { immediate: true, deep: true })
|
||||
onAutorefreshUpdate(settings) {
|
||||
if (this.intervals.messages) {
|
||||
clearInterval(this.intervals.messages);
|
||||
this.intervals.messages = null;
|
||||
}
|
||||
|
||||
if (this.intervals.departures) {
|
||||
clearInterval(this.intervals.departures);
|
||||
this.intervals.messages = null;
|
||||
}
|
||||
|
||||
if (settings.messages.active) {
|
||||
this.intervals.messages = setInterval(() => this.updateMessages(), Math.max(5, settings.messages.interval) * 1000);
|
||||
}
|
||||
|
||||
if (settings.departures.active) {
|
||||
this.intervals.departures = setInterval(() => this.updateDepartures({ stops: this.stops }), Math.max(5, settings.departures.interval) * 1000);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,3 +5,4 @@ export * from './departures'
|
||||
export * from './stop'
|
||||
export * from './messages'
|
||||
export * from './map'
|
||||
export * from './app'
|
@ -6,20 +6,6 @@ import { ensureArray, FetchingState, filter, map } from "../utils";
|
||||
import { debounce } from "../decorators";
|
||||
import urls from '../urls';
|
||||
|
||||
@Component({ template: require("../../components/picker.html") })
|
||||
export class PickerComponent extends Vue {
|
||||
@Prop({ default: () => [], type: Array })
|
||||
protected stops?: Stop[];
|
||||
|
||||
private remove(stop: Stop) {
|
||||
this.$emit('update:stops', this.stops.filter(s => s != stop));
|
||||
}
|
||||
|
||||
private add(stop: Stop|Stop[]) {
|
||||
this.$emit('update:stops', [...this.stops, ...ensureArray(stop)]);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({ template: require('../../components/finder.html') })
|
||||
export class FinderComponent extends Vue {
|
||||
protected found?: StopGroups = {};
|
||||
@ -64,5 +50,4 @@ export class FinderComponent extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
Vue.component('StopPicker', PickerComponent);
|
||||
Vue.component('StopFinder', FinderComponent);
|
||||
|
@ -33,13 +33,15 @@ Vue.directive('hover', {
|
||||
el.addEventListener('focusout', deactivate);
|
||||
},
|
||||
unbind(el, binding) {
|
||||
const { activate, deactivate, keyboard } = binding['events'];
|
||||
if (typeof binding['events'] !== 'undefined') {
|
||||
const { activate, deactivate, keyboard } = binding['events'];
|
||||
|
||||
el.removeEventListener('mouseenter', activate);
|
||||
el.removeEventListener('click', activate);
|
||||
el.removeEventListener('keydown', keyboard);
|
||||
el.removeEventListener('mouseleave', deactivate);
|
||||
el.removeEventListener('focusout', deactivate);
|
||||
el.removeEventListener('mouseenter', activate);
|
||||
el.removeEventListener('click', activate);
|
||||
el.removeEventListener('keydown', keyboard);
|
||||
el.removeEventListener('mouseleave', deactivate);
|
||||
el.removeEventListener('focusout', deactivate);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -72,6 +74,8 @@ Vue.directive('responsive', {
|
||||
}
|
||||
},
|
||||
unbind(el, binding) {
|
||||
window.removeEventListener('resize', binding['resize']);
|
||||
if (typeof binding['resize'] !== 'undefined') {
|
||||
window.removeEventListener('resize', binding['resize']);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -10,7 +10,7 @@ export interface DeparturesState extends CommonState {
|
||||
departures: Departure[],
|
||||
}
|
||||
|
||||
interface ObtainPayload {
|
||||
export interface ObtainPayload {
|
||||
stops: Stop[]
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Stop } from "../model";
|
||||
import { ActionTree, MutationTree } from "vuex";
|
||||
import urls from "../urls";
|
||||
import { ensureArray } from "../utils";
|
||||
|
||||
export interface RootState {
|
||||
stops: Stop[],
|
||||
@ -16,7 +17,9 @@ export const state: RootState = {
|
||||
};
|
||||
|
||||
export const mutations: MutationTree<RootState> = {
|
||||
updateStops: (state, stops) => state.stops = stops,
|
||||
add: (state, stops) => state.stops = [...state.stops, ...ensureArray(stops)],
|
||||
remove: (state, stop) => state.stops = state.stops.filter(s => s != stop),
|
||||
clear: (state) => state.stops = [],
|
||||
};
|
||||
|
||||
export const actions: ActionTree<RootState, undefined> = {
|
||||
|
@ -46,6 +46,7 @@
|
||||
<fa :icon="['fal', 'clock']" fixed-width></fa>
|
||||
<span class="text">Odjazdy</span>
|
||||
</h2>
|
||||
|
||||
<button class="btn btn-action flex-space-left" ref="settings-departures" v-hover="settings.departures">
|
||||
<fa :icon="['fal', 'cog']" fixed-width></fa>
|
||||
</button>
|
||||
@ -77,12 +78,32 @@
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-md-4 order-md-first">
|
||||
<section class="section picker" v-if="stops.length > 0">
|
||||
<header class="section__title flex">
|
||||
<h2>
|
||||
<fa :icon="['fal', 'sign']" fixed-width></fa>
|
||||
<span class="text">Przystanki</span>
|
||||
</h2>
|
||||
<button class="btn btn-action flex-space-left" @click="clear">
|
||||
<fa :icon="['fal', 'trash-alt']" fixed-width></fa>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<ul class="picker__stops list-underlined">
|
||||
<li v-for="stop in stops" :key="stop.id" class="d-flex align-items-center">
|
||||
<button @click="remove(stop)" class="btn btn-action">
|
||||
<fa :icon="['fal', 'times']"></fa>
|
||||
</button>
|
||||
<stop :stop="stop" class="flex-grow-1"></stop>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="section picker">
|
||||
<h2 class="section__title">
|
||||
<fa :icon="['fal', 'sign']" fixed-width></fa>
|
||||
Przystanki
|
||||
<fa :icon="['fal', 'search']" fixed-width></fa>
|
||||
Wybierz przystanki
|
||||
</h2>
|
||||
<stop-picker :stops.sync="stops"></stop-picker>
|
||||
<stop-finder @select="add" :blacklist="stops"/>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user