RoutesMaker/Public/ecma/Views/MenuView.ecma.js

307 lines
11 KiB
JavaScript

"use strict";
import { CoordenatesModel } from "../Models/CoordenatesModel.ecma.js";
import {Utils} from "../Utils/Utils.ecma.js";
/**
* @callback menu_view_event_callback
* @param {!HTMLElement} item
* @param {!Event} event
* @returns {void}
*/
export const MenuView = (function(){
const MenuView = function(routes_maker){
const self = this;
let built = false;
const constructor = () => {};
const load_database = (item, event) => {
Utils.upload((...data) => {
try{
const [layers, routes, menu] = JSON.parse(data[0].content);
menu.forEach(([type, key]) => {
if(routes[key]){
const [name, dots] = routes[key];
routes_maker.routes.add(name, key);
add_new_item(routes_maker[type].get(key), type);
dots.forEach(([longitude, latitude]) => {
routes_maker.map.set_point(longitude, latitude);
});
};
});
}catch(exception){
console.error(exception);
};
});
};
const save_database = (item, event) => {
Utils.download([
[],
routes_maker.routes.get_data(),
[...routes_maker.base.item.querySelectorAll(".map-menu [data-field=items] li")].map(item => [
item.getAttribute("data-type"),
item.getAttribute("data-key")
])
], "application/json");
};
const add_new_item = (object, type) => {
object && select_item(Utils.set_html(".map-menu [data-field=items] ul", [
["li", {
data_type : type,
data_name : object.name,
data_key : object.key,
data_selected : true,
title : object.name
}, [
MenuView.toggle_button("visible", (button, event, on) => {
routes_maker.routes.visible(button.parentNode.getAttribute("data-key"), on);
}, "Visible", true),
["span", {
class : "name",
on_click : (item, event) => {
select_item(item.parentNode);
}
}, object.name]
]]
], routes_maker.base.item)[0]);
};
const get_new_name = () => routes_maker.base.item.querySelector(".map-menu [name=item_name]").value.trim();
const add_new_route = (item, event) => {
add_new_item(routes_maker.routes.add(get_new_name()), "routes");
};
const add_new_layer = (item, event) => {
const name = get_new_name().trim();
name && Utils.upload((...files) => {
add_new_item(routes_maker.layers.add(name, files[0]), "layers");
});
};
const select_item = item => {
routes_maker.base.item.querySelectorAll(".map-menu [data-field=items] ul>[data-selected=true]").forEach(item => {
item.setAttribute("data-selected", false);
});
item.setAttribute("data-selected", true);
routes_maker.routes.select(self.get_selected()[0]);
self.recalculate_total_distance();
};
const clear_item_name = (item, event) => {
item.parentNode.querySelector("[type=text]").value = "";
};
const show_markers = (item, event) => {
Utils.set_attributes(".map", {data_show_markers : item.checked}, routes_maker.base.item);
};
const show_routes = (item, event) => {
Utils.set_attributes(".map", {data_show_routes : item.checked}, routes_maker.base.item);
};
this.build = () => {
if(!built && routes_maker.base.item){
built = true;
Utils.set_html(routes_maker.base.item, [
["form", {
class : "map-menu",
method : "GET",
action : "#",
on_submit : (form, event) => false
}, [
["fieldset", null, [
["legend", {data_i18n : "menu"}, "Menu"],
["nav", null, [
["ul", null, [
MenuView.create_button("load_database", load_database, "Load database"),
MenuView.create_button("save_database", save_database, "Save database"),
MenuView.create_item("item_name", [
["label", {for : "item_name"}, [
["span", {data_i18n : "item_name"}, "Item name"],
["input", {
type : "text",
name : "item_name",
id : "item_name",
data_i18n : "item_name",
data_i18n_without : true,
placeholder : "Item name...",
value : ""
}]
]],
MenuView.button("add_route", add_new_route, "Add route"),
MenuView.button("add_layer", add_new_layer, "Add layer"),
MenuView.button("clear", clear_item_name, "Clear")
], "Item name"),
MenuView.create_item("items", [["nav", null, [["ul", null]]]], "Items"),
MenuView.create_item("distance", [["label", {for : "distance"}, [
["span", {data_i18n : "distance"}, "Distance"],
["input", {
type : "number",
name : "distance",
readonly : true,
id : "distance",
data_i18n : "distance",
data_i18n_without : true,
placeholder : "Distance...",
value : 0
}],
["span", {data_i18n : "meters_symbol"}, "m"]
]]], "Distance"),
MenuView.create_checkbox("show_markers", true, show_markers, "Show markers"),
MenuView.create_checkbox("show_routes", true, show_routes, "Show routes")
]]
]]
]]
]]
]);
};
};
/**
* @returns {string|null}
* @access public
*/
this.get_selected = () => {
/** @type {HTMLLIElement|null} */
const item_selected = routes_maker.base.item.querySelector(".map-menu [data-field=items] [data-selected=true]");
return item_selected ? [
item_selected.getAttribute("data-key"),
item_selected.getAttribute("data-type")
] : [null, null];
};
this.recalculate_total_distance = () => {
const [key, type] = self.get_selected();
key &&
(routes_maker.base.item.querySelector(".map-menu [name=distance]").value = routes_maker[type].get(key).get_distance() >> 0);
};
constructor();
};
/**
* @param {!string} name
* @returns {string}
* @access public
* @static
*/
MenuView.get_id = name => name.replace(/_/g, "-").toLowerCase();
/**
* @param {!string} name
* @param {!Array.<Array.<any|null>>} item
* @param {!string} text
* @returns {[string, Object.<string, any>, Array.<any>]}
* @access public
* @static
*/
MenuView.create_item = (name, item, text) => ["li", {
data_field : name,
data_i18n : name,
data_i18n_without : true,
title : text
}, item];
/**
* @param {!string} name
* @param {!boolean} checked
* @param {!menu_view_event_callback} action
* @param {!string} text
* @returns {[string, Object.<string, any>, Array.<any>]}
* @access public
* @static
*/
MenuView.create_checkbox = (name, checked, action, text) => {
/** @type {string} */
const id = MenuView.get_id(name);
return MenuView.create_item(name, [["label", {for : id}, [
["input", {
type : "checkbox",
name : name,
id : id,
checked : checked,
on_change : action
}],
["span", {data_i18n : name}, text]
]]], text);
};
/**
* @param {!string} name
* @param {!menu_view_event_callback} action
* @param {!string} text
* @returns {[string, Object.<string, any>, Array.<any>]}
* @access public
* @static
*/
MenuView.button = (name, action, text) => ["button", {
type : "button",
data_i18n : name,
data_i18n_without : true,
title : text,
on_click : action
}, [
["span", {data_icon : name}],
["span", {data_i18n : name}, text]
]];
/**
* @param {!string} name
* @param {!menu_view_event_callback} action
* @param {!string} text
* @returns {[string, Object.<string, any>, Array.<any>]}
* @access public
* @static
*/
MenuView.create_button = (name, action, text) => MenuView.create_item(name, [["button", {
type : "button",
data_i18n : name,
data_i18n_without : true,
title : text,
on_click : action
}, [
["span", {data_icon : name}],
["span", {data_i18n : name}, text]
]]], text);
MenuView.toggle_button = (name, action, text, on = true) => ["button", {
type : "button",
data_i18n : name,
data_i18n_without : true,
title : text,
data_toggle : on,
on_click : (button, event, on = null) => {
button.setAttribute("data-toggle", on !== null ? on : on = button.getAttribute("data-toggle") != "true");
action(button, event, on);
}
}, [
["span", {data_icon : name}],
["span", {data_i18n : name}, text]
]]
return MenuView;
})();