Add ability to replace favourite with confirmation.
This commit is contained in:
parent
4647bb2cc1
commit
c2b959a9da
@ -16,9 +16,19 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="favourite-add-form__actions">
|
<div class="favourite-add-form__actions">
|
||||||
<button class="btn btn-sm btn-primary" type="submit">
|
<template v-if="confirmation">
|
||||||
<ui-icon icon="add" />
|
<button class="btn btn-xs btn-danger" type="submit">
|
||||||
zapisz
|
nadpisz
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn btn-xs btn-action" @click="$emit('close')">
|
||||||
|
anuluj
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<button class="btn btn-xs btn-primary" type="submit">
|
||||||
|
<ui-icon icon="add" />
|
||||||
|
zapisz
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.btn-xs {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
border-radius: 1.5px;
|
border-radius: 1.5px;
|
||||||
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -29,4 +35,13 @@
|
|||||||
border: 1px $primary solid;
|
border: 1px $primary solid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.btn-danger {
|
||||||
|
background: $danger-gradient;
|
||||||
|
border-color: transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: 1px $danger solid;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,14 @@ $border-radius: 0;
|
|||||||
$border-radius-lg: $border-radius;
|
$border-radius-lg: $border-radius;
|
||||||
$border-radius-sm: $border-radius;
|
$border-radius-sm: $border-radius;
|
||||||
|
|
||||||
|
$danger: #cd2e12;
|
||||||
|
|
||||||
@import "~bootstrap/scss/functions";
|
@import "~bootstrap/scss/functions";
|
||||||
@import "~bootstrap/scss/variables";
|
@import "~bootstrap/scss/variables";
|
||||||
|
|
||||||
$primary: #005ea8;
|
$primary: #005ea8;
|
||||||
$primary-gradient: linear-gradient(120deg, #0083c5 10%, #005ea8 90%);
|
$primary-gradient: linear-gradient(120deg, #0083c5 10%, #005ea8 90%);
|
||||||
|
$danger-gradient: linear-gradient(120deg, $danger 10%, darken($danger, 10%) 90%);
|
||||||
|
|
||||||
$custom-control-indicator-checked-bg: $dark;
|
$custom-control-indicator-checked-bg: $dark;
|
||||||
$custom-control-indicator-active-bg: $dark;
|
$custom-control-indicator-active-bg: $dark;
|
||||||
|
@ -73,6 +73,7 @@ $dialog-sizes: (
|
|||||||
@each $size, $width in $dialog-sizes {
|
@each $size, $width in $dialog-sizes {
|
||||||
.ui-modal.ui-modal--#{$size} {
|
.ui-modal.ui-modal--#{$size} {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { Component, Prop } from 'vue-property-decorator'
|
import { Component, Watch } from 'vue-property-decorator'
|
||||||
import { namespace, State, Mutation } from "vuex-class";
|
import { Mutation, State } from "vuex-class";
|
||||||
import { Favourite } from "../store/favourites";
|
import { Favourite } from "../store/favourites";
|
||||||
import { SavedState } from "../store/root";
|
|
||||||
import { Stop } from "../model";
|
import { Stop } from "../model";
|
||||||
import * as uuid from "uuid";
|
import * as uuid from "uuid";
|
||||||
import { Favourites } from "../store";
|
import { Favourites } from "../store";
|
||||||
@ -34,8 +33,15 @@ export class FavouritesAdderComponent extends Vue {
|
|||||||
private name = "";
|
private name = "";
|
||||||
private errors = { name: [] };
|
private errors = { name: [] };
|
||||||
|
|
||||||
|
private confirmation = false;
|
||||||
|
|
||||||
@Favourites.Mutation add: (favourite: Favourite) => void;
|
@Favourites.Mutation add: (favourite: Favourite) => void;
|
||||||
|
|
||||||
|
@Watch('name')
|
||||||
|
handleNameChange() {
|
||||||
|
this.confirmation = false;
|
||||||
|
}
|
||||||
|
|
||||||
async save() {
|
async save() {
|
||||||
const favourite: Favourite = createFavouriteEntry(this.name, this.stops);
|
const favourite: Favourite = createFavouriteEntry(this.name, this.stops);
|
||||||
|
|
||||||
@ -54,8 +60,9 @@ export class FavouritesAdderComponent extends Vue {
|
|||||||
errors.name.push("Musisz podać nazwę.");
|
errors.name.push("Musisz podać nazwę.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.$store.state.favourites.favourites.filter(other => other.name == favourite.name).length > 0) {
|
if (this.$store.state.favourites.favourites.filter(other => other.name == favourite.name).length > 0 && !this.confirmation) {
|
||||||
errors.name.push("Istnieje już zapisana grupa przystanków o takiej nazwie.");
|
errors.name.push("Istnieje już zapisana grupa przystanków o takiej nazwie.");
|
||||||
|
this.confirmation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.errors = errors;
|
this.errors = errors;
|
||||||
|
@ -53,12 +53,12 @@ const simple = (icon: IconDefinition, props: any = {}): SimpleIcon => ({
|
|||||||
icon, ...props, type: "simple"
|
icon, ...props, type: "simple"
|
||||||
});
|
});
|
||||||
|
|
||||||
const stack = (icons: IconDescription[]): StackedIcon => ({type: "stacked", icons});
|
const stack = (icons: IconDescription[]): StackedIcon => ({ type: "stacked", icons });
|
||||||
|
|
||||||
const lineTypeIcons = Object
|
const lineTypeIcons = Object
|
||||||
.values(fac)
|
.values(fac)
|
||||||
.map<[string, Icon]>(icon => [ `line-${icon.iconName}`, simple(icon) ])
|
.map<[string, Icon]>(icon => [`line-${ icon.iconName }`, simple(icon)])
|
||||||
.reduce((acc, [icon, definition]) => ({ ...acc, [icon]: definition}), {})
|
.reduce((acc, [icon, definition]) => ({ ...acc, [icon]: definition }), {})
|
||||||
|
|
||||||
const messageTypeIcons: Dictionary<Icon> = {
|
const messageTypeIcons: Dictionary<Icon> = {
|
||||||
'message-breakdown': simple(faExclamationTriangle),
|
'message-breakdown': simple(faExclamationTriangle),
|
||||||
@ -66,7 +66,7 @@ const messageTypeIcons: Dictionary<Icon> = {
|
|||||||
'message-unknown': simple(faQuestionCircle),
|
'message-unknown': simple(faQuestionCircle),
|
||||||
};
|
};
|
||||||
|
|
||||||
const definitions: Dictionary<Icon> = {
|
const definitions = {
|
||||||
'favourite': simple(faStar),
|
'favourite': simple(faStar),
|
||||||
'unknown': simple(faQuestionSquare),
|
'unknown': simple(faQuestionSquare),
|
||||||
'add': simple(faCheck),
|
'add': simple(faCheck),
|
||||||
@ -93,14 +93,16 @@ const definitions: Dictionary<Icon> = {
|
|||||||
'decrement': simple(faMinus, { "fixed-width": true }),
|
'decrement': simple(faMinus, { "fixed-width": true }),
|
||||||
'relative-time': simple(faHourglassHalf),
|
'relative-time': simple(faHourglassHalf),
|
||||||
'departure-warning': stack([
|
'departure-warning': stack([
|
||||||
{icon: faClockBold},
|
{ icon: faClockBold },
|
||||||
{icon: faSolidExclamationTriangle, transform: "shrink-5 down-4 right-6"}
|
{ icon: faSolidExclamationTriangle, transform: "shrink-5 down-4 right-6" }
|
||||||
]),
|
]),
|
||||||
'close': simple(faTimes),
|
'close': simple(faTimes),
|
||||||
...lineTypeIcons,
|
...lineTypeIcons,
|
||||||
...messageTypeIcons,
|
...messageTypeIcons,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type PredefinedIcon = keyof typeof definitions;
|
||||||
|
|
||||||
const extractAllIcons = (icons: Icon[]) => icons.map(icon => {
|
const extractAllIcons = (icons: Icon[]) => icons.map(icon => {
|
||||||
switch (icon.type) {
|
switch (icon.type) {
|
||||||
case "simple":
|
case "simple":
|
||||||
@ -122,11 +124,11 @@ library.add(...extractAllIcons(Object.values(definitions)));
|
|||||||
})
|
})
|
||||||
export class UiIcon extends Vue {
|
export class UiIcon extends Vue {
|
||||||
@Prop({
|
@Prop({
|
||||||
type: [ String, Object ],
|
type: [String, Object],
|
||||||
validator: value => typeof value === "object" || Object.keys(definitions).includes(value),
|
validator: value => typeof value === "object" || Object.keys(definitions).includes(value),
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
icon: string | IconDefinition;
|
icon: PredefinedIcon | IconDefinition;
|
||||||
|
|
||||||
get definition(): Icon {
|
get definition(): Icon {
|
||||||
return typeof this.icon === "string"
|
return typeof this.icon === "string"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { RootState } from "./root";
|
import { RootState } from "./root";
|
||||||
import { Module } from "vuex";
|
import { Module } from "vuex";
|
||||||
import { Stop } from "../model";
|
import { Stop } from "../model";
|
||||||
|
import { except } from "../utils";
|
||||||
|
|
||||||
export interface Favourite {
|
export interface Favourite {
|
||||||
id: string;
|
id: string;
|
||||||
@ -19,7 +20,13 @@ const favourites: Module<FavouritesState, RootState> = {
|
|||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
add(state, favourite: Favourite) {
|
add(state, favourite: Favourite) {
|
||||||
state.favourites.push(favourite);
|
const existing = state.favourites.find((current: Favourite) => current.name === favourite.name);
|
||||||
|
|
||||||
|
if (!existing) {
|
||||||
|
state.favourites.push(favourite);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(existing, except(favourite, ["id"]));
|
||||||
},
|
},
|
||||||
remove(state, favourite: Favourite) {
|
remove(state, favourite: Favourite) {
|
||||||
state.favourites = state.favourites.filter(f => f != favourite);
|
state.favourites = state.favourites.filter(f => f != favourite);
|
||||||
|
@ -38,6 +38,14 @@ export function filter<T, KT extends keyof T>(source: T, filter: (value: T[KT],
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function except<T>(source: T, keys: (keyof T)[]) {
|
||||||
|
return filter(source, (_, key) => !keys.includes(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function only<T>(source: T, keys: (keyof T)[]) {
|
||||||
|
return filter(source, (_, key) => keys.includes(key))
|
||||||
|
}
|
||||||
|
|
||||||
export function signed(number: number): string {
|
export function signed(number: number): string {
|
||||||
return number > 0 ? `+${number}` : number.toString();
|
return number > 0 ? `+${number}` : number.toString();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user