Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6811b16ec4 | ||
|
fe96dbc5c2 | ||
|
94161d5be6 | ||
|
73394bc922 | ||
|
ee8d898fe8 | ||
|
f47b52cd43 | ||
|
21cc72e1a4 | ||
|
3cf8a5137b | ||
|
cde4adccdc | ||
|
041f4c1e74 | ||
|
47e4dda875 | ||
|
3026ec0b0f | ||
|
b021786b1a | ||
|
ad3effe687 | ||
|
b307271c73 | ||
|
0360f78669 | ||
|
6588e27c00 | ||
|
c57444bb53 | ||
|
c8483dc0fc |
@ -20,7 +20,7 @@
|
||||
"dependencies": {
|
||||
"@fastify/leveldb": "^6.0.0",
|
||||
"@fastify/static": "^8.0.0",
|
||||
"@fastify/view": "^10.0.0",
|
||||
"@fastify/view": "^11.0.0",
|
||||
"@types/node": "^22.13.5",
|
||||
"esbuild": "^0.25.0",
|
||||
"fastify": "^5.2.1",
|
||||
@ -30,4 +30,4 @@
|
||||
"pug": "^3.0.2",
|
||||
"undici": "^7.3.0"
|
||||
}
|
||||
}
|
||||
}
|
@ -75,7 +75,9 @@ type NominatimResult = {
|
||||
};
|
||||
|
||||
export const is_restauration_type = (e: NominatimResult) =>
|
||||
["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"].includes(e.type);
|
||||
["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"].indexOf(
|
||||
e.type
|
||||
) != -1;
|
||||
export const is_attraction_type = (e: NominatimResult): boolean =>
|
||||
[
|
||||
"tourism",
|
||||
@ -86,18 +88,18 @@ export const is_attraction_type = (e: NominatimResult): boolean =>
|
||||
"historic",
|
||||
"natural",
|
||||
"waterway",
|
||||
].includes(e.category) ||
|
||||
].indexOf(e.category) != -1 ||
|
||||
[
|
||||
"place_of_worship",
|
||||
"national_park",
|
||||
"nature_reserve",
|
||||
"protected_area",
|
||||
].includes(e.type) || is_travel_type(e);
|
||||
].indexOf(e.type) != -1 || is_travel_type(e);
|
||||
|
||||
export const is_hotel_type = (e: NominatimResult): boolean =>
|
||||
["hotel", "hostel", "guest_house"].includes(e.type)
|
||||
["hotel", "hostel", "guest_house"].indexOf(e.type) != -1
|
||||
export const is_travel_type = (e: NominatimResult): boolean =>
|
||||
["bus_stop", "tram_stop", "station", , "aerodrome", "parking"].includes(e.type)
|
||||
["bus_stop", "tram_stop", "station", , "aerodrome", "parking"].indexOf(e.type) != -1
|
||||
|
||||
|
||||
export const icon_type = (item: string | NominatimResult): string => {
|
||||
@ -139,17 +141,12 @@ export const icon_type = (item: string | NominatimResult): string => {
|
||||
"nature_reserve",
|
||||
],
|
||||
"dice-five": ["water_park", "theme_park", "casino"],
|
||||
"arrow-right": ["other"],
|
||||
"train": ["train"],
|
||||
"car-side":["car"],
|
||||
"bycicle":["bike"],
|
||||
"plane":["plane", "flight"],
|
||||
"": ["?", "neighbourhood", "quarter", "highway", "place"],
|
||||
};
|
||||
|
||||
for (let k in types)
|
||||
if (types[k].includes(t) || types[k].includes(c)) return k;
|
||||
|
||||
for (let k in types) {
|
||||
if (types[k].indexOf(t) >= 0 || types[k].indexOf(c) >= 0) return k;
|
||||
}
|
||||
console.log(item.display_name, item.category, item.type);
|
||||
return "question";
|
||||
};
|
||||
|
@ -17,6 +17,7 @@ const filter_existing = function (
|
||||
return true;
|
||||
});
|
||||
case "travel":
|
||||
console.log(r);
|
||||
return r.filter((e) => {
|
||||
if (
|
||||
leg.travel.find(
|
||||
@ -43,8 +44,9 @@ const process_results = function (tpe: "nominatim" | "travel", r: geoloc[]) {
|
||||
return rr;
|
||||
});
|
||||
case "travel":
|
||||
console.log(r);
|
||||
return r.map((el) => {
|
||||
el.path = getGeoLine(
|
||||
(el as any).path = getGeoLine(
|
||||
{
|
||||
lat: (el as any).from_geo.lat,
|
||||
lng: (el as any).from_geo.lon,
|
||||
|
41
src/client/helper/journey.ts
Normal file
41
src/client/helper/journey.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import journey_wrapper from './types/wrapper';
|
||||
|
||||
/* LIST HELPERS */
|
||||
export const filter_selected = function (journey: journey_wrapper, list: geoloc[], step: boolean) {
|
||||
return list.filter((e) =>
|
||||
step ? e.step == journey.sel_day : e.step >= 0,
|
||||
);
|
||||
}
|
||||
|
||||
export const filter_unselected = function (list: geoloc[]) {
|
||||
return list.filter((e) => e.step == undefined || e.step < 0);
|
||||
}
|
||||
|
||||
export const remove_item = function (list: geoloc[], idx: number) {
|
||||
list[idx].step = -1;
|
||||
list.splice(idx, 1);
|
||||
}
|
||||
|
||||
|
||||
/* JOURNEY ADD/RM ITEM HELPER */
|
||||
export const journey_add_place = function (journey: journey_wrapper, tpe: String, item: geoloc) {
|
||||
switch (tpe) {
|
||||
case 'hotel': return journey.leg_get().hotel = item;
|
||||
case 'restaurant': return journey.leg_get().places.restaurants.push(item);
|
||||
case 'place': return journey.leg_get().places.activities.push(item);
|
||||
case 'other': return;
|
||||
case 'flight': return journey.leg_get().travel.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
export const journey_del_place = function (journey: journey_wrapper, tpe: String, idx: number) {
|
||||
console.log(tpe)
|
||||
switch (tpe) {
|
||||
case "hotel": return journey.leg_get().hotel = null;
|
||||
case "restaurants": return journey.leg_get().places.restaurants.splice(idx, 1);
|
||||
case "activities": return journey.leg_get().places.activities.splice(idx, 1);
|
||||
case "other": return;
|
||||
case "flight": return journey.leg_get().travel.splice(idx, 1);
|
||||
default: return true;
|
||||
}
|
||||
}
|
@ -6,24 +6,27 @@ var nav = {
|
||||
};
|
||||
|
||||
|
||||
const sideScroll = function (element: Element, direction: 'left' | 'right' | 'none', speed: number = 25, step: number = 15) {
|
||||
const sideScroll = function (element: Element, direction: 'left' | 'right' | 'none', speed: number, step: number) {
|
||||
nav.scrollDir = direction
|
||||
if (direction == 'none') return;
|
||||
(nav as any).scrollInterval = setInterval(() => {
|
||||
nav.scrollInterval = setInterval(() => {
|
||||
element.scrollLeft += (direction == 'left') ? -step : step;
|
||||
}, speed);
|
||||
}
|
||||
|
||||
export const focus_leg = function (journey: journey_wrapper, idx: number | null = null) {
|
||||
const c = document.querySelector('.scroll-content.nav-leg')!!
|
||||
console.log(idx, c, journey)
|
||||
const item = c.children[(idx != null ? idx : journey.sel_leg) + 1];
|
||||
c.scrollLeft = (item as any).offsetLeft + ((item as any).offsetWidth / 2) - (c as any).offsetWidth / 2
|
||||
}
|
||||
|
||||
export const focus_day = function (journey: journey_wrapper, idx: number | null = null) {
|
||||
const c = document.querySelector('.scroll-content.nav-day')!!
|
||||
console.log(idx, c, journey)
|
||||
const item = c.children[(idx != null ? idx : journey.sel_day) + 1];
|
||||
c.scrollLeft = (item as any).offsetLeft + ((item as any).offsetWidth / 2) - (c as any).offsetWidth / 2;
|
||||
//focus_leg(journey) // We dont render both navs anymore
|
||||
}
|
||||
|
||||
export const nav_mousemove = function (e: PointerEvent) {
|
||||
@ -35,7 +38,7 @@ export const nav_mousemove = function (e: PointerEvent) {
|
||||
(left > c.offsetWidth * 0.9 ? 'right' : 'none')
|
||||
if (!nav.scrollInterval || nav.scrollDir != newDir) {
|
||||
if (nav.scrollInterval) clearInterval(nav.scrollInterval)
|
||||
sideScroll(c, newDir);
|
||||
sideScroll(c, newDir, 25, 10);
|
||||
}
|
||||
}
|
||||
export const nav_mouseleave = function (_e: PointerEvent) {
|
||||
|
@ -2,11 +2,10 @@
|
||||
import * as api from "./api";
|
||||
import journey_wrapper from "./types/wrapper";
|
||||
import { migrator } from "./types/migration";
|
||||
import { journey_add_place, journey_del_place } from "./helper/journey";
|
||||
import { search_nominatim, search_flight } from "./helper/api";
|
||||
import { focus_day, focus_leg, nav_mouseleave, nav_mousemove } from "./helper/nav";
|
||||
import { set_search_set_results } from "./helper/api";
|
||||
import toast from "./types/toast";
|
||||
import search_drawer from "./types/search_drawer";
|
||||
import { to_xy } from "./types/geom";
|
||||
|
||||
Vue.component("l-map", window.Vue2Leaflet.LMap);
|
||||
Vue.component("l-tile-layer", window.Vue2Leaflet.LTileLayer);
|
||||
@ -20,10 +19,22 @@ Vue.component("l-control-scale", window.Vue2Leaflet.LControlScale);
|
||||
const app = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
journey: new journey_wrapper(),
|
||||
search_drawer: new search_drawer(),
|
||||
edit_active: ["view", "short"].indexOf(window.location.pathname.split("/")[1]) == -1,
|
||||
journey: new journey_wrapper(window.location.pathname.split("/").pop() || String.gen_id(16)),
|
||||
map_override: { active: false, elements: [] },
|
||||
query: {
|
||||
type: "", query: "", res: [], load: false, sub: false, note: false, drawer: false, addmarker: false,
|
||||
},
|
||||
useDay: false,
|
||||
toast: new toast(),
|
||||
toast: {
|
||||
show: false,
|
||||
title: '',
|
||||
desc: '',
|
||||
special: '',
|
||||
acceptText: '',
|
||||
cancelText: '',
|
||||
func: () => { },
|
||||
},
|
||||
lang: {
|
||||
format: "ddd D MMM",
|
||||
formatLocale: {
|
||||
@ -35,14 +46,18 @@ const app = new Vue({
|
||||
methods: {
|
||||
start_journey: function () { window.location.href = "/" + this.journey.id },
|
||||
|
||||
compute_bb: function () {
|
||||
if (!this.$refs.map) return undefined
|
||||
const bounds = this.$refs.map.mapObject.getBounds();
|
||||
return [[bounds.getSouthWest().lng, bounds.getSouthWest().lat],
|
||||
[bounds.getNorthEast().lng, bounds.getNorthEast().lat]]
|
||||
},
|
||||
generate_rotation: function (index, list) {
|
||||
if (index < 0 || index >= list.length) return 0;
|
||||
const c0 = to_xy(list[(index == 0) ? index : (index - 1)])
|
||||
const c1 = to_xy(list[(index == (list.length - 1)) ? index : (index + 1)])
|
||||
const brng = Math.atan2(c1[1] - c0[1], c1[0] - c0[0])- Math.PI / 2;
|
||||
const flip = (brng>-Math.PI/2)?'transform: scale(1,1);': 'transform: scale(1, -1);';
|
||||
const rot = `rotate:${brng}rad;`
|
||||
return `${rot}${flip}`;
|
||||
const c0 = list[(index == 0) ? index : (index - 1)]
|
||||
const c1 = list[(index == list.length - 1) ? index : (index + 1)]
|
||||
const brng = Math.atan2(c1[1] - c0[1], c1[0] - c0[0]);
|
||||
return `rotate:${brng - Math.PI / 2}rad`;
|
||||
|
||||
},
|
||||
generate_marker: function (item, fcolor) {
|
||||
@ -57,6 +72,106 @@ const app = new Vue({
|
||||
return `<i class="fa fa-${api.icon_type(item) || "star"} fa-2x ${classes}" style="${styling}; color:${fcolor || "white"}; text-align:center; align-content:center;"></i>`;
|
||||
},
|
||||
|
||||
import_data: function (v) {
|
||||
this.journey.data = Object.assign(
|
||||
{},
|
||||
JSON.parse(v.toDecoded()),
|
||||
);
|
||||
this.journey.data.main.forEach((e) => {
|
||||
if (e.date_range) {
|
||||
e.date_range[0] = new Date(e.date_range[0]);
|
||||
e.date_range[1] = new Date(e.date_range[1]);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
toast_reset: function () {
|
||||
this.toast.show = false;
|
||||
this.toast.title = '';
|
||||
this.toast.desc = ''
|
||||
this.toast.special = '';
|
||||
this.toast.acceptText = ''
|
||||
this.toast.cancelText = ''
|
||||
this.toast.func = () => { }
|
||||
},
|
||||
|
||||
toast_impexp: function (is_import) {
|
||||
this.toast.show = true;
|
||||
this.toast.title = is_import ? 'Import' : 'Export';
|
||||
this.toast.desc = ''
|
||||
this.toast.special = JSON.stringify(this.journey.data).toEncoded();
|
||||
this.toast.acceptText = is_import ? 'load' : ''
|
||||
this.toast.cancelText = 'cancel'
|
||||
this.toast.func = () => { this.import_data(this.toast.special); this.toast_reset(); }
|
||||
},
|
||||
|
||||
search_set_results(r) {
|
||||
this.query.load = false;
|
||||
this.query.res = r;
|
||||
return r
|
||||
},
|
||||
search_set_clear(keep_drawer) {
|
||||
this.query.res = [];
|
||||
this.query.note = false;
|
||||
this.query.type = null;
|
||||
this.query.addmarker = false;
|
||||
this.query.sub = false;
|
||||
this.query.drawer = keep_drawer;
|
||||
setTimeout(() => this.$refs.map.mapObject.invalidateSize(), 500);
|
||||
},
|
||||
search_set_active: function (is_notes, tpe) {
|
||||
this.query.drawer = true;
|
||||
this.query.note = is_notes;
|
||||
this.query.type = !is_notes ? tpe : null;
|
||||
this.query.load = !is_notes;
|
||||
setTimeout(() => this.$refs.map.mapObject.invalidateSize(), 500);
|
||||
},
|
||||
|
||||
drawer_hover_item: function (item) {
|
||||
if (item) {
|
||||
this.map_override.active = true
|
||||
if (item.type == 'flight') {
|
||||
this.map_override.elements = [[item.from_geo.lat, item.from_geo.lon], [item.to_geo.lat, item.to_geo.lon]]
|
||||
} else {
|
||||
this.map_override.elements = [[item.lat, item.lon]]
|
||||
}
|
||||
} else {
|
||||
this.map_override.active = false
|
||||
}
|
||||
},
|
||||
|
||||
drawer_click_item: function (item) {
|
||||
const tpe = this.query.type
|
||||
this.search_set_clear(item ? true : false);
|
||||
this.drawer_hover_item();
|
||||
if (item) {
|
||||
item.step = -1;
|
||||
journey_add_place(this.journey, tpe, item)
|
||||
}
|
||||
},
|
||||
|
||||
search_active: function (_e) {
|
||||
const tpe = this.query.type;
|
||||
const query = this.query.query;
|
||||
switch (tpe) {
|
||||
case 'hotel':
|
||||
case 'restaurant': ;
|
||||
case 'place':
|
||||
case 'other':
|
||||
return search_nominatim(tpe, query, this.compute_bb(), this.journey.leg_get())
|
||||
|
||||
case 'flight':
|
||||
return search_flight(tpe, query, this.journey.leg_get());
|
||||
}
|
||||
},
|
||||
|
||||
search_enable: function (f) {
|
||||
const is_notes = f == 'notes';
|
||||
this.search_set_active(is_notes, f)
|
||||
setTimeout(() => document.getElementById(is_notes ? 'query_note' : 'query_input').focus(), 500);
|
||||
if (!is_notes) this.search_active()
|
||||
},
|
||||
|
||||
refreshTextAreaHeight: function (e) {
|
||||
e.target.style['height'] = 'auto';
|
||||
e.target.style['height'] = e.target.scrollHeight + 'px';
|
||||
@ -64,62 +179,53 @@ const app = new Vue({
|
||||
},
|
||||
|
||||
onMapClick(e) {
|
||||
if (this.search_drawer.query.addmarker) {
|
||||
if (this.query.addmarker) {
|
||||
const newMarker = {
|
||||
latlon: [e.latlng.lat, e.latlng.lng],
|
||||
sname: this.search_drawer.query.query,
|
||||
type: this.search_drawer.query.type,
|
||||
sname: this.query.query,
|
||||
type: this.query.type,
|
||||
};
|
||||
this.search_drawer.click_item(this.journey,newMarker)
|
||||
this.drawer_click_item(newMarker)
|
||||
}
|
||||
},
|
||||
},
|
||||
created: function () {
|
||||
set_search_set_results((r) => { this.search_drawer.results(r); });
|
||||
set_search_set_results(this.search_set_results);
|
||||
this.nav_mouseleave = nav_mouseleave;
|
||||
this.nav_mousemove = nav_mousemove;
|
||||
this.focus_day = focus_day;
|
||||
this.focus_leg = focus_leg;
|
||||
this.place_delete = (tpe, idx) => journey_del_place(this.journey, tpe, idx);
|
||||
|
||||
this.save_data = api.throttle(() => {
|
||||
api.save(this.journey.id, this.journey.data);
|
||||
}, 2000);
|
||||
}, 1000);
|
||||
|
||||
this.pressed_prev_next = api.throttle((dir_prev) => {
|
||||
if (this.useDay && dir_prev) return this.journey.day_prev();
|
||||
if (!this.useDay && dir_prev) return this.journey.leg_prev();
|
||||
if (this.useDay && !dir_prev) return this.journey.day_next();
|
||||
if (!this.useDay && !dir_prev) return this.journey.leg_next();
|
||||
this.pressed_prev = api.throttle(() => {
|
||||
if (this.useDay) this.journey.day_prev();
|
||||
else this.journey.leg_prev();
|
||||
}, 250)
|
||||
this.pressed_next = api.throttle(() => {
|
||||
if (this.useDay) this.journey.day_next();
|
||||
else this.journey.leg_next();
|
||||
}, 250)
|
||||
|
||||
window.addEventListener("keydown", (e) => {
|
||||
switch (e.key) {
|
||||
case "ArrowLeft": return this.pressed_prev_next(true)
|
||||
case "ArrowRight": return this.pressed_prev_next(false)
|
||||
default: return;
|
||||
case "ArrowLeft": return this.pressed_prev()
|
||||
case "ArrowRight": return this.pressed_next()
|
||||
default: return console.log(e.key);
|
||||
}
|
||||
});
|
||||
|
||||
api.load(this.journey.id).then((r) => {
|
||||
app.journey.data = migrator(r)
|
||||
setTimeout(() => focus_leg(this.journey) && focus_day(this.journey) && this.$refs.map.mapObject.keyboard.disable(), 50);
|
||||
|
||||
;
|
||||
this.search_drawer.refresh_map = () => { this.$refs.map.mapObject.invalidateSize() }
|
||||
this.search_drawer.get_leg = () => { return this.journey.leg_get() }
|
||||
this.search_drawer.get_bb = () => {
|
||||
if (!this.$refs.map) return []
|
||||
const bounds = this.$refs.map.mapObject.getBounds();
|
||||
return [[bounds.getSouthWest().lng, bounds.getSouthWest().lat],
|
||||
[bounds.getNorthEast().lng, bounds.getNorthEast().lat]]
|
||||
}
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
journey: {
|
||||
handler: function (ndata, odata) {
|
||||
if (this.journey.edit) this.save_data();
|
||||
window.location.hash = `#${this.journey.sel_leg}_${this.journey.sel_day}`
|
||||
if (this.edit_active) this.save_data();
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
|
@ -7,12 +7,10 @@ declare global {
|
||||
}
|
||||
interface geoloc {
|
||||
title: string
|
||||
osm_id: number
|
||||
latlon: [number, number]
|
||||
notes: string
|
||||
type?: string
|
||||
osm_id?: number
|
||||
latlon?: [number, number]
|
||||
step?: -1
|
||||
path?: number[][]
|
||||
step: -1
|
||||
}
|
||||
|
||||
interface map {
|
||||
|
@ -160,15 +160,6 @@ function recursiveMidPoint(src: LatLng, dst: LatLng, opt: { step?: number, dist?
|
||||
return geom;
|
||||
}
|
||||
|
||||
export function to_xy(point: number[]){
|
||||
const R = 6378137; // Earth's radius in meters (WGS84 standard)
|
||||
const lon =((point[0] + 180) % 360 + 360) % 360 - 180;
|
||||
const lat = ((point[1] + 90) % 180 + 180) % 180 - 90;
|
||||
const x = R * (lon* Math.PI / 180);
|
||||
const y = R * Math.log(Math.tan((Math.PI / 4) + (lat * Math.PI / 360)));
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
export function getGeoLine(src: LatLng, dst: LatLng, opt: { step?: number, dist?: number }): LatLng[] {
|
||||
export function getGeoLine(src: LatLng, dst: LatLng, opt: { step?: number, dist?: number }) {
|
||||
return recursiveMidPoint(src, dst, opt, 1)
|
||||
}
|
@ -8,7 +8,7 @@ function migrate_A_to_0(e: journey): journey {
|
||||
v.day_title = v.day_title || (v as any).step_title;
|
||||
v.places.activities = v.places.activities || (v as any).places.places;
|
||||
v.travel = v.travel || [];
|
||||
v.day_title = typeof (v.day_title) == "string" ? [v.day_title] : [];
|
||||
v.day_title = typeof (v.day_title) == "string" ? [v.day_title] : []
|
||||
})
|
||||
console.log(e)
|
||||
return e;
|
||||
|
@ -1,150 +0,0 @@
|
||||
import { search_flight, search_nominatim } from "../helper/api";
|
||||
import { leg_template } from "./format";
|
||||
import journey_wrapper from "./wrapper";
|
||||
|
||||
|
||||
declare global {
|
||||
type query_type = "hotel" | "restaurant" | "place" | "flight"
|
||||
type note_type = "notes"
|
||||
type sub_type = "travel" | "other"
|
||||
|
||||
interface query {
|
||||
type: query_type | note_type | "",
|
||||
sub: sub_type | "",
|
||||
query: string,
|
||||
res: any[],
|
||||
load: boolean,
|
||||
/* DELETE BELOW IF POSIBLE */
|
||||
addmarker: Boolean,
|
||||
}
|
||||
|
||||
interface map_override {
|
||||
active: Boolean,
|
||||
elements: number[][]
|
||||
}
|
||||
}
|
||||
|
||||
class search_drawer {
|
||||
map_override: map_override = { active: false, elements: [] };
|
||||
multipath : any[]=[];
|
||||
|
||||
query: query = {
|
||||
type: "", query: "", sub: "", res: [], load: false, addmarker: false,
|
||||
}
|
||||
|
||||
resfresh_map: () => void = () => { }
|
||||
get_bb: () => any[] = () => []
|
||||
get_leg: () => leg = () => leg_template
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
show_drawer() {
|
||||
return this.is_note() || this.is_query()
|
||||
}
|
||||
|
||||
is_note() {
|
||||
return ["notes"].includes(this.query.type)
|
||||
}
|
||||
is_place(){
|
||||
return ["hotel", "restaurant", "place"].includes(this.query.type)
|
||||
}
|
||||
is_query() {
|
||||
return this.is_place()|| this.is_flight() || this.is_multipath()
|
||||
}
|
||||
is_sub_travel() {
|
||||
return ["travel"].includes(this.query.sub)
|
||||
}
|
||||
is_multipath(){
|
||||
return ["flight", "train", "car","bike", "other"].includes(this.query.type)
|
||||
}
|
||||
is_flight(){
|
||||
return ["flight"].includes(this.query.type)
|
||||
}
|
||||
|
||||
results(r: any[]) {
|
||||
this.query.load = false;
|
||||
this.query.res = r;
|
||||
return r
|
||||
}
|
||||
reset() {
|
||||
this.query.res = [];
|
||||
this.multipath = [];
|
||||
this.map_override.elements = []
|
||||
this.query.type = "";
|
||||
this.query.addmarker = false;
|
||||
setTimeout(() => this.resfresh_map(), 500);
|
||||
}
|
||||
|
||||
active(tpe: query_type) {
|
||||
this.query.type = tpe;
|
||||
this.query.load = this.is_query();
|
||||
setTimeout(() => this.resfresh_map(), 500);
|
||||
}
|
||||
|
||||
search(_e = null) {
|
||||
const tpe = this.query.type;
|
||||
const query = this.query.query;
|
||||
switch (tpe) {
|
||||
case 'flight':
|
||||
return search_flight(tpe, query, this.get_leg());
|
||||
default:
|
||||
return search_nominatim(tpe, query, this.get_bb(), this.get_leg())
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
enable(f: query_type) {
|
||||
this.active(f)
|
||||
setTimeout(() => document.getElementById(this.is_note() ? 'query_note' : 'query_input')?.focus(), 500);
|
||||
if (this.is_query()) this.search()
|
||||
}
|
||||
|
||||
hover_item (item?:any) {
|
||||
if (item) {
|
||||
this.map_override.active = true
|
||||
if (item.type == 'flight') {
|
||||
this.map_override.elements.push([item.from_geo.lat, item.from_geo.lon])
|
||||
this.map_override.elements.push([item.to_geo.lat, item.to_geo.lon])
|
||||
} else {
|
||||
this.map_override.elements.push([item.lat, item.lon])
|
||||
}
|
||||
} else {
|
||||
this.map_override.active = false
|
||||
}
|
||||
}
|
||||
|
||||
click_item (journey: journey_wrapper, item?:any) {
|
||||
const tpe = this.query.type
|
||||
if(this.is_multipath()){
|
||||
if(this.query.addmarker){
|
||||
if(item){
|
||||
this.map_override.active = true
|
||||
this.map_override.elements.push(item.latlon? item.latlon: [item.lat,item.lon])
|
||||
this.multipath.push(item)
|
||||
return;
|
||||
}else{
|
||||
let new_item :geoloc = {
|
||||
type: (tpe as string),
|
||||
path: this.map_override.elements,
|
||||
title: '-',
|
||||
notes: "",
|
||||
}
|
||||
this.map_override.active = false
|
||||
journey.add_place(tpe, new_item)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.reset();
|
||||
this.hover_item();
|
||||
if (item) {
|
||||
item.step = -1;
|
||||
journey.add_place(tpe, item)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default search_drawer;
|
@ -1,62 +0,0 @@
|
||||
import journey_wrapper from "./wrapper";
|
||||
import { focus_leg } from "../helper/nav";
|
||||
|
||||
interface toaster {
|
||||
show: boolean,
|
||||
title: String,
|
||||
desc: String,
|
||||
special: String,
|
||||
acceptText: String,
|
||||
cancelText: String,
|
||||
func: () => void,
|
||||
}
|
||||
|
||||
const default_toaster = {
|
||||
show: false,
|
||||
title: ' ',
|
||||
desc: ' ',
|
||||
special: ' ',
|
||||
acceptText: ' ',
|
||||
cancelText: ' ',
|
||||
func: () => { }
|
||||
}
|
||||
|
||||
class toast {
|
||||
data: toaster = default_toaster;
|
||||
|
||||
reset = function (): void {
|
||||
this.data.show = false
|
||||
this.data.title = ' '
|
||||
this.data.desc = ' '
|
||||
this.data.special = ' '
|
||||
this.data.acceptText = ' '
|
||||
this.data.cancelText = ' '
|
||||
this.data.func = () => { };
|
||||
}
|
||||
constructor() {
|
||||
this.reset()
|
||||
}
|
||||
|
||||
impexp = function (is_import: boolean, journey: journey_wrapper): void {
|
||||
this.data.show = true;
|
||||
this.data.title = is_import ? 'Import' : 'Export';
|
||||
this.data.desc = ''
|
||||
this.data.special = JSON.stringify(journey.data).toEncoded();
|
||||
this.data.acceptText = is_import ? 'load' : ''
|
||||
this.data.cancelText = 'cancel'
|
||||
this.data.func = () => { journey.import_data(JSON.parse(this.data.special.toDecoded().toString())); this.reset(toast); }
|
||||
}
|
||||
|
||||
delete_leg = function (v: number, journey: journey_wrapper): void {
|
||||
this.data.show = true;
|
||||
this.data.title = `Delete Leg`;
|
||||
this.data.desc = `Remove leg <${journey.leg_get(v).title || v}>`
|
||||
this.data.special = '';
|
||||
this.data.acceptText = 'delete'
|
||||
this.data.cancelText = 'cancel'
|
||||
this.data.func = () => { journey.rm_leg(v); focus_leg(journey); this.reset(toast); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default toast;
|
@ -6,16 +6,12 @@ const date_day_diff = (d0: Date, d1: Date): number =>
|
||||
|
||||
class journey_wrapper {
|
||||
id: String
|
||||
edit: Boolean = true
|
||||
data: journey = journey_template;
|
||||
sel_leg: number = 0;
|
||||
sel_day: number = 0;
|
||||
|
||||
constructor(id: String | undefined) {
|
||||
if (id)
|
||||
this.id = id;
|
||||
else
|
||||
this.from_url()
|
||||
constructor(id: String) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
leg_first = () => this.data.main[0]
|
||||
@ -65,9 +61,6 @@ class journey_wrapper {
|
||||
day_sel(idx: number): void {
|
||||
this.sel_day = idx;
|
||||
}
|
||||
day_count(): number {
|
||||
return this.leg_len();
|
||||
}
|
||||
day_next() {
|
||||
this.sel_day += 1
|
||||
if (this.sel_day > this.leg_len() - 1) {
|
||||
@ -158,50 +151,6 @@ class journey_wrapper {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import_data(v: any) {
|
||||
this.data = Object.assign({}, v);
|
||||
this.data.main.forEach((e) => {
|
||||
if (e.date_range) {
|
||||
e.date_range[0] = new Date(e.date_range[0]);
|
||||
e.date_range[1] = new Date(e.date_range[1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
add_place(tpe: String, item: geoloc) {
|
||||
switch (tpe) {
|
||||
case 'hotel': return this.leg_get().hotel = item;
|
||||
case 'restaurant': return this.leg_get().places.restaurants.push(item);
|
||||
case 'place': return this.leg_get().places.activities.push(item);
|
||||
case 'other':
|
||||
case 'train':
|
||||
case 'car':
|
||||
case 'bike':
|
||||
case 'flight': return this.leg_get().travel.push(item);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
del_place(tpe: String, idx: number) {
|
||||
switch (tpe) {
|
||||
case "hotel": return this.leg_get().hotel = null;
|
||||
case "restaurants": return this.leg_get().places.restaurants.splice(idx, 1);
|
||||
case "activities": return this.leg_get().places.activities.splice(idx, 1);
|
||||
case "other": return;
|
||||
case "flight": return this.leg_get().travel.splice(idx, 1);
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
|
||||
from_url() {
|
||||
const path = window.location.pathname.slice(1).split('/')
|
||||
const hash = window.location.hash.slice(1).split('_')
|
||||
this.id = path.at(-1) || String.gen_id(16).toString()
|
||||
this.sel_leg = parseInt(hash.at(0) || '0')
|
||||
this.sel_day = parseInt(hash.at(1) || '0')
|
||||
this.edit = !["view", "short"].includes(path.at(0) || "")
|
||||
}
|
||||
}
|
||||
|
||||
export default journey_wrapper;
|
@ -13,8 +13,8 @@ interface FlightData {
|
||||
|
||||
function clean_times(s: string): string | null {
|
||||
if (s == "—" || s == "Scheduled") return null
|
||||
if (s.startsWith("Estimated departure")) return null
|
||||
if (s.startsWith("Landed")) return s.replace("Landed ", "")
|
||||
if (s.indexOf("Estimated departure") == 0) return null
|
||||
if (s.indexOf("Landed") == 0) return s.replace("Landed ", "")
|
||||
return s
|
||||
}
|
||||
|
||||
|
@ -2,86 +2,49 @@
|
||||
.input.w-100.text-dark
|
||||
input#query_input(
|
||||
type="search"
|
||||
@input="search_drawer.search()"
|
||||
@focus="search_drawer.search()"
|
||||
@input="search_active"
|
||||
@focus="search_active"
|
||||
placeholder="Search ... "
|
||||
style="width:85%;"
|
||||
:disabled="search_drawer.is_note()"
|
||||
v-model="search_drawer.query.query"
|
||||
:disabled="query.note"
|
||||
v-model="query.query"
|
||||
)
|
||||
.spinner(v-if="search_drawer.query.load")
|
||||
.spinner(v-if="query.load")
|
||||
|
||||
div(v-if="search_drawer.is_query()")
|
||||
div(v-if="search_drawer.is_flight()")
|
||||
template(v-for="(item, idx) in search_drawer.query.res" )
|
||||
.query-result.col-12.bg-white.text-dark(
|
||||
:key="'q'+idx"
|
||||
@mouseover="search_drawer.hover_item(item)"
|
||||
@mouseleave="search_drawer.hover_item()"
|
||||
@click="search_drawer.click_item(journey,item)" )
|
||||
div( v-html="generate_icon('plane', 'var(--dark)')")
|
||||
.col-10()
|
||||
| {{ item.from }} => {{item.to}}
|
||||
.bg-dark.divider(
|
||||
:key="'qdiv'+idx" style="height:1px" )
|
||||
div(v-if="['hotel', 'restaurant', 'place','other', 'travel'].indexOf(query.type)>=0")
|
||||
template(v-for="(item, idx) in query.res" )
|
||||
.query-result.col-12.bg-white.text-dark(
|
||||
v-if="!search_drawer.query.addmarker"
|
||||
@click="search_drawer.query.addmarker=true" )
|
||||
div( v-html="generate_icon('star', 'var(--dark)')")
|
||||
:key="'q'+idx"
|
||||
@mouseover="drawer_hover_item(item)"
|
||||
@mouseleave="drawer_hover_item()"
|
||||
@click="drawer_click_item(item)" )
|
||||
div( v-html="generate_icon(item, 'var(--dark)')")
|
||||
.col-10()
|
||||
| Start custom
|
||||
.query-result.col-12.bg-white.text-dark(
|
||||
v-else
|
||||
@click="search_drawer.click_item(journey)" )
|
||||
div( v-html="generate_icon('star', 'var(--dark)')")
|
||||
.col-10()
|
||||
| Finish
|
||||
div(v-else-if="search_drawer.is_multipath()")
|
||||
template(v-for="(item, idx) in search_drawer.query.res" )
|
||||
.query-result.col-12.bg-white.text-dark(
|
||||
:key="'q'+idx"
|
||||
@mouseover="search_drawer.hover_item(item)"
|
||||
@mouseleave="search_drawer.hover_item()"
|
||||
@click="search_drawer.click_item(journey,item)" )
|
||||
div( v-html="generate_icon('plane', 'var(--dark)')")
|
||||
.col-10()
|
||||
| {{ item.from }} => {{item.to}}
|
||||
.bg-dark.divider(
|
||||
:key="'qdiv'+idx" style="height:1px" )
|
||||
.query-result.col-12.bg-white.text-dark(
|
||||
v-if="!search_drawer.query.addmarker"
|
||||
@click="search_drawer.query.addmarker=true" )
|
||||
div( v-html="generate_icon('star', 'var(--dark)')")
|
||||
.col-10()
|
||||
| Start custom
|
||||
.query-result.col-12.bg-white.text-dark(
|
||||
v-else
|
||||
@click="search_drawer.click_item(journey)" )
|
||||
div( v-html="generate_icon('star', 'var(--dark)')")
|
||||
.col-10()
|
||||
| Finish
|
||||
div(v-else-if="true")
|
||||
template(v-for="(item, idx) in search_drawer.query.res" )
|
||||
.query-result.col-12.bg-white.text-dark(
|
||||
:key="'q'+idx"
|
||||
@mouseover="search_drawer.hover_item(item)"
|
||||
@mouseleave="search_drawer.hover_item()"
|
||||
@click="search_drawer.click_item(journey,item)" )
|
||||
div( v-html="generate_icon(item, 'var(--dark)')")
|
||||
.col-10()
|
||||
| {{ item.name }}
|
||||
.bg-dark.divider(
|
||||
:key="'qdiv'+idx" style="height:1px" )
|
||||
.query-result.col-12.bg-white.text-dark(
|
||||
v-if="!search_drawer.query.load && search_drawer.query.res && search_drawer.is_query()"
|
||||
@click="search_drawer.query.addmarker=true" )
|
||||
div( v-html="generate_icon('star', 'var(--dark)')")
|
||||
.col-10()
|
||||
| Add custom
|
||||
| {{ item.name }}
|
||||
.bg-dark.divider(
|
||||
:key="'qdiv'+idx" style="height:1px" )
|
||||
.query-result.col-12.bg-white.text-dark(
|
||||
v-if="query.load==false && query.res.length>=0 && query.query!=''"
|
||||
@click="query.addmarker=true" )
|
||||
div( v-html="generate_icon('star', 'var(--dark)')")
|
||||
.col-10()
|
||||
| Add custom
|
||||
|
||||
.col-12.text-white.text-center(
|
||||
) {{search_drawer.query.load? `Loading ...` : `Found ${search_drawer.query.res.length} results`}}
|
||||
div(v-else)
|
||||
template()
|
||||
.query-result.col-12.bg-white.text-dark()
|
||||
| Unsuppored Query type {{search_drawer.query.type}}
|
||||
.col-12.text-white.text-center(
|
||||
) {{query.load? `Loading ...` : `Found ${query.res.length} results`}}
|
||||
div(v-else-if="['flight'].indexOf(query.type)>=0")
|
||||
template(v-for="(item, idx) in query.res" )
|
||||
.query-result.col-12.bg-white.text-dark(
|
||||
:key="'q'+idx"
|
||||
@mouseover="drawer_hover_item(item)"
|
||||
@mouseleave="drawer_hover_item()"
|
||||
@click="drawer_click_item(item)" )
|
||||
div( v-html="generate_icon('plane', 'var(--dark)')")
|
||||
.col-10()
|
||||
| {{ item.from }} => {{item.to}}
|
||||
.bg-dark.divider(
|
||||
:key="'qdiv'+idx" style="height:1px" )
|
||||
div(v-else)
|
||||
template()
|
||||
.query-result.col-12.bg-white.text-dark()
|
||||
| Unsuppored Query type {{query.type}}
|
||||
|
@ -26,7 +26,7 @@
|
||||
.text {{ element.title || "Leg "+idx}}
|
||||
i.fa.fa-times.text-small.fright(
|
||||
style="top: 2px; right: 2px; position: absolute",
|
||||
@click="toast.delete_leg(idx, journey)"
|
||||
@click="journey.rm_leg(idx); focus_leg(journey);"
|
||||
)
|
||||
.list-group-item.bg-white.text-white.show.placeholder-right(
|
||||
:class="journey.sel_leg < journey.data.main.length-1? '': 'bg-dark'"
|
||||
|
@ -16,10 +16,10 @@ include smallbar.pug
|
||||
template(v-else)
|
||||
include leg/top_leg.pug
|
||||
.row(style="aspect-ratio:1.25;min-height:432px;max-height:calc(100vh - 125px);width:calc(100% + 24px);")
|
||||
.map-container(:class=" { 'col-2 col-sm-5 col-md-8': search_drawer.is_query(), 'col-2 col-sm-5 col-md-6': search_drawer.is_note() , 'col-12': (!search_drawer.is_query() && !search_drawer.is_note()) }" )
|
||||
.map-container(:class=" { 'col-2 col-sm-5 col-md-8': query.type, 'col-2 col-sm-5 col-md-6': query.note , 'col-12': (!query.type && !query.note) }" )
|
||||
include map.pug
|
||||
.row.drawer-container(:class="{ 'col-10 col-sm-7 col-md-4': search_drawer.is_query(), 'col-10 col-sm-7 col-md-6': search_drawer.is_note(), 'col-0': (!search_drawer.is_query() && !search_drawer.is_note()) }")
|
||||
.h-100(:class="{ 'w-100 ': search_drawer.is_query(), 'w-0': !search_drawer.is_query() }")
|
||||
.row.drawer-container(:class="{ 'col-10 col-sm-7 col-md-4': query.type, 'col-10 col-sm-7 col-md-6': query.note, 'col-0': (!query.type && !query.note) }")
|
||||
.h-100(:class="{ 'w-100 ': query.type, 'w-0': !query.type }")
|
||||
include leg/drawer.pug
|
||||
.h-100(:class="{ 'w-100': search_drawer.is_note(), 'w-0': !search_drawer.is_note() }")
|
||||
.h-100(:class="{ 'w-100': query.note, 'w-0': !query.note }")
|
||||
include leg/drawer-notes.pug
|
||||
|
@ -4,11 +4,7 @@ l-map(
|
||||
@click="onMapClick"
|
||||
style="height:100%"
|
||||
no-blocking-animations=true
|
||||
:max-bounds="[[-90, -180],[90, 180]]"
|
||||
:max-bounds-viscosity="1.0"
|
||||
:world-copy-jump="true"
|
||||
:no-wrap="true"
|
||||
:style="search_drawer.query.addmarker?'cursor:crosshair':''"
|
||||
:style="query.addmarker?'cursor:crosshair':''"
|
||||
ref="map"
|
||||
)
|
||||
l-tile-layer(
|
||||
@ -23,5 +19,5 @@ l-map(
|
||||
include map/restaurants.pug
|
||||
|
||||
include map/travel.pug
|
||||
template(v-if="journey.edit")
|
||||
template(v-if="edit_active")
|
||||
include map/right_menu.pug
|
@ -19,19 +19,19 @@ mixin map_marker(place, color_sel_c, color_sel_o, color_else)
|
||||
:options="{maxWidth:400, minWidth:300}")
|
||||
h1.row.text-medium.text-center {{ place.sname }}
|
||||
span.row.text-small.text-gray {{ place.display_name }}
|
||||
span(v-if="journey.edit")
|
||||
span(v-if="edit_active")
|
||||
.row.input()
|
||||
textarea.col-12.col-sm-12.text-small(
|
||||
placeholder="",
|
||||
v-model="place.notes",
|
||||
)
|
||||
.leaflet-popup-button-group(v-if="journey.edit")
|
||||
.leaflet-popup-button-group(v-if="edit_active")
|
||||
a.text-gray(
|
||||
v-on:click.prevent="place.step = ((place.step==journey.sel_day)?-1:journey.sel_day)"
|
||||
v-html="generate_icon(((place.step==journey.sel_day)?'calendar-xmark':'calendar-plus'), 'NA')"
|
||||
)
|
||||
a.text-gray(
|
||||
v-on:click.prevent="journey.del_place(\""+place+"\",index)"
|
||||
v-on:click.prevent="place_delete(\""+place+"\",index)"
|
||||
v-html="generate_icon('trash', 'NA')"
|
||||
)
|
||||
span.row.text-small.text-dark(v-else) {{ place.notes }}
|
||||
|
@ -1,11 +1,11 @@
|
||||
l-marker(
|
||||
v-if="search_drawer.map_override.active",
|
||||
v-for="(el, idx) in search_drawer.map_override.elements"
|
||||
v-if="map_override.active",
|
||||
v-for="(el, idx) in map_override.elements"
|
||||
:key="'ovr'+idx"
|
||||
:lat-lng="el"
|
||||
)
|
||||
l-icon(v-html="generate_marker('plus', 'darkgreen')")
|
||||
l-polyline(
|
||||
v-if="search_drawer.map_override.active && search_drawer.map_override.elements.length>1"
|
||||
:lat-lngs="search_drawer.map_override.elements" :color="'darkgreen'"
|
||||
v-if="map_override.active && map_override.elements.length>1"
|
||||
:lat-lngs="map_override.elements" :color="'darkgreen'"
|
||||
)
|
@ -1,21 +1,21 @@
|
||||
.map-menu.map-menu-top
|
||||
div(v-if="search_drawer.is_query()" @click="search_drawer.click_item(journey)" )
|
||||
div(v-if="query.type" @click="drawer_click_item()" )
|
||||
.map-menu-item(v-html="generate_icon('close')")
|
||||
div(v-if="!search_drawer.is_query()" @click="search_drawer.enable('hotel')")
|
||||
div(v-if="!query.type" @click="search_enable('hotel')")
|
||||
.map-menu-item( v-html="generate_icon('bed')")
|
||||
div(v-if="!search_drawer.is_query()" @click="search_drawer.enable('restaurant')")
|
||||
div(v-if="!query.type" @click="search_enable('restaurant')")
|
||||
.map-menu-item( v-html="generate_icon('utensils')")
|
||||
div(v-if="!search_drawer.is_query()" @click="search_drawer.enable('place')")
|
||||
div(v-if="!query.type" @click="search_enable('place')")
|
||||
.map-menu-item( v-html="generate_icon('star')")
|
||||
.map-menu-sub(v-if="!search_drawer.is_query()" @mouseenter="search_drawer.query.sub='travel'" @mouseleave="search_drawer.query.sub=''" )
|
||||
.map-menu-item(@click="search_drawer.enable('other')" v-html="generate_icon('route')")
|
||||
.map-menu-item(v-if="search_drawer.is_sub_travel()" @click="search_drawer.enable('flight')" v-html="generate_icon('plane')")
|
||||
.map-menu-item(v-if="search_drawer.is_sub_travel()" @click="search_drawer.enable('train')" v-html="generate_icon('train')")
|
||||
.map-menu-item(v-if="search_drawer.is_sub_travel()" @click="search_drawer.enable('car')" v-html="generate_icon('car')")
|
||||
.map-menu-item(v-if="search_drawer.is_sub_travel()" @click="search_drawer.enable('bike')" v-html="generate_icon('person-biking')")
|
||||
.map-menu-sub(v-if="!query.type" @mouseenter="query.sub=true" @mouseleave="query.sub=false" )
|
||||
.map-menu-item(v-html="generate_icon('route')")
|
||||
.map-menu-item(v-if="query.sub" @click="search_enable('flight')" v-html="generate_icon('plane')")
|
||||
.map-menu-item(v-if="query.sub" @click="search_enable('train')" v-html="generate_icon('train')")
|
||||
.map-menu-item(v-if="query.sub" @click="search_enable('car')" v-html="generate_icon('car')")
|
||||
.map-menu-item(v-if="query.sub" @click="search_enable('other')" v-html="generate_icon('person-biking')")
|
||||
|
||||
.map-menu.map-menu-center
|
||||
div(v-if="search_drawer.is_note()" @click="search_drawer.click_item(journey)" )
|
||||
div(v-if="query.note" @click="drawer_click_item()" )
|
||||
.map-menu-item(v-html="generate_icon('close')")
|
||||
div(v-if="!search_drawer.is_note()" @click="search_drawer.enable('notes')")
|
||||
div(v-if="!query.note" @click="search_enable('notes')")
|
||||
.map-menu-item( v-html="generate_icon('pencil')")
|
@ -3,18 +3,18 @@ mixin flight_popup()
|
||||
:options="{maxWidth:400, minWidth:300}"
|
||||
)
|
||||
h1.row.text-medium.text-center.text-uppercase {{ travel.id }}
|
||||
span.row.text-small.text-gray {{ travel.title? travel.title:`${travel.from||'?'}-${travel.to||'?'}` }}
|
||||
span(v-if="journey.edit")
|
||||
span.row.text-small.text-gray {{ travel.from }} - {{travel.to}}
|
||||
span(v-if="edit_active")
|
||||
.row.input(style="margin-bottom:0")
|
||||
textarea.col-12.col-sm-12.text-small(
|
||||
placeholder="",
|
||||
v-model="travel.notes",
|
||||
)
|
||||
span.row.text-small.text-dark(v-else) {{ travel.notes }}
|
||||
span(v-if="journey.edit")
|
||||
.leaflet-popup-button-group()
|
||||
span(v-if="edit_active")
|
||||
.leaflet-popup-button-group(v-if="edit_active")
|
||||
a.text-gray(
|
||||
v-on:click.prevent="journey.del_place('flight',idx)"
|
||||
v-on:click.prevent="place_delete('flight',idx)"
|
||||
v-html="generate_icon('trash', 'NA')"
|
||||
)
|
||||
|
||||
@ -24,10 +24,9 @@ div(v-for= "(travel, idx) in journey.leg_get().travel")
|
||||
|
||||
l-marker(
|
||||
v-for="(place, index) in travel.path"
|
||||
:key="'trvl'+index"
|
||||
:key="'plane'+index"
|
||||
:lat-lng="place"
|
||||
style="margin-left:0;"
|
||||
)
|
||||
l-icon(v-html="generate_icon(travel, travel.color || 'gray', generate_rotation(index,travel.path)+'margin:-6px -6px; position:absolute', 'travel-path-icon')"
|
||||
l-icon(v-html="generate_icon('plane', travel.color || 'gray', generate_rotation(index,travel.path), 'travel-path-icon')"
|
||||
)
|
||||
+flight_popup()
|
||||
|
@ -14,11 +14,11 @@
|
||||
.tooltip-text Editor
|
||||
.col-1
|
||||
.col-1
|
||||
a.text-white.tooltip(v-on:click.prevent="toast.impexp(true, journey)")
|
||||
a.text-white.tooltip(v-on:click.prevent="toast_impexp(true)")
|
||||
i.fas.fa-file-import
|
||||
.tooltip-text Import
|
||||
.col-1
|
||||
a.text-white.tooltip(v-on:click.prevent="toast.impexp(false, journey)")
|
||||
a.text-white.tooltip(v-on:click.prevent="toast_impexp(false)")
|
||||
i.fas.fa-file-export
|
||||
.tooltip-text Export
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
template
|
||||
.overlay.text-dark(v-if="toast.data.show" @click="")
|
||||
.overlay.text-dark(v-if="toast.show" @click="")
|
||||
.popup.bg-white(@click.stop)
|
||||
.row
|
||||
.col-auto.text-huge {{ toast.data.title }}
|
||||
.row(v-if="toast.data.desc")
|
||||
.col-auto.text-medium {{ toast.data.desc }}
|
||||
.row(v-if="toast.data.special")
|
||||
.col-auto.text-huge {{ toast.title }}
|
||||
.row(v-if="toast.desc")
|
||||
.col-auto.text-medium {{ toast.desc }}
|
||||
.row(v-if="toast.special")
|
||||
.col-auto.text-medium
|
||||
.input
|
||||
input(v-model="toast.data.special")
|
||||
input(v-model="toast.special")
|
||||
.row.align
|
||||
button.button.bg-white(@click="toast.data.func" v-if="toast.data.acceptText") {{ toast.data.acceptText }}
|
||||
button.button.bg-white(@click="toast.data.show=false;" v-if="toast.data.cancelText") {{ toast.data.cancelText }}
|
||||
button.button.bg-white(@click="toast.func" v-if="toast.acceptText") {{ toast.acceptText }}
|
||||
button.button.bg-white(@click="toast.show=false;" v-if="toast.cancelText") {{ toast.cancelText }}
|
Loading…
x
Reference in New Issue
Block a user