From d67499abda0bc259d06f8ec720bc0d42bda3447f Mon Sep 17 00:00:00 2001 From: Uriel Gomez Date: Thu, 26 Sep 2024 13:10:53 -0600 Subject: [PATCH] Loteador con cuentas de google --- assets/desarrollos/peninsula/loteador.xslt | 4 +- custom.js | 59 +++++++------- loteador/index.html | 90 ++++++++++++---------- loteador/jquery.maphilight.js | 52 ++++++------- loteador/login.xml | 1 + loteador/login.xslt | 3 + loteador/loteador.css | 5 ++ loteador/manifest.json | 16 +++- loteador/mapselection.js | 64 +++++++-------- manifest.json | 5 +- 10 files changed, 165 insertions(+), 134 deletions(-) create mode 100644 loteador/login.xml create mode 100644 loteador/login.xslt diff --git a/assets/desarrollos/peninsula/loteador.xslt b/assets/desarrollos/peninsula/loteador.xslt index 87af4ee..74ae613 100644 --- a/assets/desarrollos/peninsula/loteador.xslt +++ b/assets/desarrollos/peninsula/loteador.xslt @@ -1,5 +1,7 @@ - + (xover.site.seed || '').replace(/^#/,'') + +
`).textContent = args.join()) - } else if (handler.indexOf("event:") == 0) { - window.document.dispatch.apply(document, [handler.split(":").pop(), ...args]) - } else { - window.document.dispatch.apply(document, [handler, ...args]) - } - }) - } - } catch (e) { - return Promise.reject(e); +xo.listener.on('load::data', function () { + window.loteador && loteador.inicializar() +}) + +xo.listener.on('logout', function () { + window.loteador && window.loteador.limpiar() + xover.stores.seed.clear() +}) + +xo.listener.on('Response:reject?response.response_value.message', function ({ response }) { + for (let container of [document.querySelector('.toast-container')]) { + container.replaceContent(HTML(``)) + container.dispatch('show') + } + event.preventDefault() + event.stopPropagation() +}) + +xo.listener.on(`show::.toast-container`, function () { + for (let toastTrigger of this.findAll('.toast')) { + const toast = new bootstrap.Toast(toastTrigger); + toast.show(); } -} \ No newline at end of file +}) \ No newline at end of file diff --git a/loteador/index.html b/loteador/index.html index 8e7bdd7..c05021b 100644 --- a/loteador/index.html +++ b/loteador/index.html @@ -3,6 +3,7 @@ + Lotificador @@ -14,7 +15,10 @@ - + + + + +
+
@@ -177,11 +183,11 @@
-
+
-
-
+
+
diff --git a/loteador/jquery.maphilight.js b/loteador/jquery.maphilight.js index d6eda07..ac1ab33 100644 --- a/loteador/jquery.maphilight.js +++ b/loteador/jquery.maphilight.js @@ -5,16 +5,16 @@ factory(root.jQuery); } })(this, function ($) { - var has_VML, has_canvas, create_canvas_for, add_shape_to, clear_canvas, shape_from_area, + let has_VML, has_canvas, create_canvas_for, add_shape_to, clear_canvas, shape_from_area, canvas_style, hex_to_decimal, css3color, is_image_loaded, options_from_area; has_canvas = !!document.createElement('canvas').getContext; // VML: more complex has_VML = (function () { - var a = document.createElement('div'); + let a = document.createElement('div'); a.innerHTML = ''; - var b = a.firstChild; + let b = a.firstChild; b.style.behavior = "url(#default#VML)"; return b ? typeof b.adj == "object" : true; })(); @@ -32,11 +32,11 @@ return 'rgba(' + hex_to_decimal(color.substr(0, 2)) + ',' + hex_to_decimal(color.substr(2, 2)) + ',' + hex_to_decimal(color.substr(4, 2)) + ',' + opacity + ')'; }; create_canvas_for = function (img) { - var c = $('').get(0); + let c = $('').get(0); c.getContext("2d").clearRect(0, 0, $(img).width(), $(img).height()); return c; }; - var draw_shape = function (context, shape, coords, x_shift, y_shift) { + let draw_shape = function (context, shape, coords, x_shift, y_shift) { x_shift = x_shift || 0; y_shift = y_shift || 0; @@ -56,7 +56,7 @@ context.closePath(); }; add_shape_to = function (canvas, shape, coords, options, name) { - var i, context = canvas.getContext('2d'); + let i, context = canvas.getContext('2d'); // Because I don't want to worry about setting things back to a base state @@ -73,8 +73,8 @@ // Redraw the shape shifted off the canvas massively so we can cast a shadow // onto the canvas without having to worry about the stroke or fill (which // cannot have 0 opacity or width, since they're what cast the shadow). - var x_shift = canvas.width * 100; - var y_shift = canvas.height * 100; + let x_shift = canvas.width * 100; + let y_shift = canvas.height * 100; draw_shape(context, shape, coords, x_shift, y_shift); context.shadowOffsetX = options.shadowX - x_shift; @@ -85,7 +85,7 @@ // Now, work out where to cast the shadow from! It looks better if it's cast // from a fill when it's an outside shadow or a stroke when it's an interior // shadow. Allow the user to override this if they need to. - var shadowFrom = options.shadowFrom; + let shadowFrom = options.shadowFrom; if (!shadowFrom) { if (options.shadowPosition == 'outside') { shadowFrom = 'fill'; @@ -146,8 +146,8 @@ return $('').get(0); }; add_shape_to = function (canvas, shape, coords, options, name) { - var fill, stroke, opacity, e; - for (var i in coords) { coords[i] = parseInt(coords[i], 10); } + let fill, stroke, opacity, e; + for (let i in coords) { coords[i] = parseInt(coords[i], 10); } fill = ''; stroke = (options.stroke ? 'strokeweight="' + options.strokeWidth + '" stroked="t" strokecolor="#' + options.strokeColor + '"' : 'stroked="f"'); opacity = ''; @@ -163,14 +163,14 @@ }; clear_canvas = function (canvas) { // jquery1.8 + ie7 - var $html = $("
" + canvas.innerHTML + "
"); + let $html = $("
" + canvas.innerHTML + "
"); $html.children('[name=highlighted]').remove(); $(canvas).html($html.html()); }; } shape_from_area = function (area) { - var i, coords, + let i, coords, shape = (area.getAttribute('shape') || 'rect').toLowerCase().substr(0, 4); if (shape === 'defa') { // 'default' doesn't really apply to what we're doing; it's the background state @@ -182,7 +182,7 @@ }; options_from_area = function (area, options) { - var $area = $(area); + let $area = $(area); return $.extend({}, options, $.metadata ? $area.metadata() : false, $area.data('maphilight')); }; @@ -200,15 +200,15 @@ border: 0 }; - var ie_hax_done = false; + let ie_hax_done = false; $.fn.maphilight = function (opts) { opts = $.extend({}, $.fn.maphilight.defaults, opts); if (!has_canvas && !ie_hax_done) { $(window).ready(function () { document.namespaces.add("v", "urn:schemas-microsoft-com:vml"); - var style = document.createStyleSheet(); - var shapes = ['shape', 'rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group', 'textbox']; + let style = document.createStyleSheet(); + let shapes = ['shape', 'rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group', 'textbox']; $.each(shapes, function () { style.addRule('v\\:' + this, "behavior: url(#default#VML); antialias:true"); @@ -219,7 +219,7 @@ } return this.each(function () { - var img, wrap, options, map, canvas, canvas_always, highlighted_shape, usemap, imgSrc; + let img, wrap, options, map, canvas, canvas_always, highlighted_shape, usemap, imgSrc; img = $(this); if (!is_image_loaded(this)) { @@ -248,7 +248,7 @@ if (img.hasClass('maphilighted')) { // We're redrawing an old map, probably to pick up changes to the options. // Just clear out all the old stuff. - var wrapper = img.parent(); + let wrapper = img.parent(); img.insertBefore(wrapper); wrapper.remove(); $(map).unbind('.maphilight'); @@ -294,7 +294,7 @@ $(canvas).empty(); } $(map).find('area[coords]').each(function () { - var shape, area_options; + let shape, area_options; area_options = options_from_area(this, options); if (area_options.alwaysOn) { if (!canvas_always && has_canvas) { @@ -318,7 +318,7 @@ }); }).trigger('alwaysOn.maphilight') .bind('mouseover.maphilight focusin.maphilight', function (e) { - var shape, area_options, area = e.target; + let shape, area_options, area = e.target; area_options = options_from_area(area, options); if (!area_options.neverOn && !area_options.alwaysOn) { shape = shape_from_area(area); @@ -330,21 +330,21 @@ if (typeof area_options.groupBy == 'string') { area_options.groupBy = [area_options.groupBy]; } - var el = $(this); + let el = $(this); $.each(area_options.groupBy, function (index, groupitem) { - var areas; + let areas; // two ways groupBy might work; attribute and selector if (/^[a-zA-Z][\-a-zA-Z]+$/.test(groupitem)) { areas = map.find('area[' + groupitem + '="' + el.attr(groupitem) + '"]'); } else { areas = map.find(groupitem); } - var first = this; + let first = this; areas.each(function () { if (this != first) { - var subarea_options = options_from_area(this, options); + let subarea_options = options_from_area(this, options); if (!subarea_options.neverOn && !subarea_options.alwaysOn) { - var shape = shape_from_area(this); + let shape = shape_from_area(this); add_shape_to(canvas, shape[0], shape[1], subarea_options, "highlighted"); } } diff --git a/loteador/login.xml b/loteador/login.xml new file mode 100644 index 0000000..72d2bab --- /dev/null +++ b/loteador/login.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/loteador/login.xslt b/loteador/login.xslt new file mode 100644 index 0000000..02598ce --- /dev/null +++ b/loteador/login.xslt @@ -0,0 +1,3 @@ + + + diff --git a/loteador/loteador.css b/loteador/loteador.css index 251db08..ebb9d17 100644 --- a/loteador/loteador.css +++ b/loteador/loteador.css @@ -54,6 +54,11 @@ form:not([desarrollo*="$"]) #Mapa { background-color: rgba(0, 0, 0, .5); padding: 20px; flex-direction: column; + visibility: hidden; +} + +#Filtros:has(*) { + visibility: visible; } div#Filtros div:not(:has(h4>:checked)) .filter_option span { diff --git a/loteador/manifest.json b/loteador/manifest.json index f4539e7..a6f4372 100644 --- a/loteador/manifest.json +++ b/loteador/manifest.json @@ -1,10 +1,22 @@ { + "server": { + "request": "https://server.panax.io/request.asp", + "login": "https://server.panax.io/login.asp", + "download": "https://server.panax.io/download.asp" + }, "sources": { "^#(.+)$": "../assets/desarrollos/$1/lotes.xml", + "^#(peninsula)$": { + "server:download": { + "file": "assets/desarrollos/$1/lotes.xml", + "^authorization": "${xover.session.encodeCredential(xover.session.user_login, xover.session.id_token) || ''}" + } + }, "^#(.+):map$": "../assets/desarrollos/$1/loteador.map", - "^#(.+):settings$": "../assets/desarrollos/$1/loteador_settings.xml" + "^#(.+):settings$": "../assets/desarrollos/$1/loteador_settings.xml", + "#login": "login.xml" }, - "start": ["#ws"], + "start": [ "#ws" ], "settings": { "^#(.+)$": { "headers": { diff --git a/loteador/mapselection.js b/loteador/mapselection.js index e160888..6859d13 100644 --- a/loteador/mapselection.js +++ b/loteador/mapselection.js @@ -101,8 +101,8 @@ const color_array = ['#FF6633', '#FFB399', '#FF33FF', '#FFFF99', '#00B3E6', '#FF3380', '#CCCC00', '#66E64D', '#4D80CC', '#9900B3', '#E64D66', '#4DB380', '#FF4D4D', '#99E6E6', '#6666FF']/*generateComplementaryColors(baseColor, numColors);*/ -var filters = {} -var attributes, attribute_pattern, value_attribute, text_attribute, oSource; //Definimos a este nivel para que sean accesibles dentro de las funciones jquery +let filters = {} +let attributes, attribute_pattern, value_attribute, text_attribute, oSource; //Definimos a este nivel para que sean accesibles dentro de las funciones jquery async function actualizaColores(oSource) { function rgbToHex(rgb) { if (!rgb) return undefined; @@ -118,11 +118,11 @@ async function actualizaColores(oSource) { return `#${r}${g}${b}`; } - let xmlData = xo.stores[location.hash]; + let xmlData = xo.stores[xo.site.seed || location.hash]; if (!xmlData.documentElement) await xmlData.fetch(); xmlData = xmlData.document; - let desarrollo_id = (location.hash || '').replace(/^#/, '').toLowerCase(); + let desarrollo_id = xo.site.seed.replace(/^#/, '').toLowerCase(); let xmlFilters = xover.sources[`#${desarrollo_id}:settings`]; if (!xmlFilters.documentElement) await xmlFilters.fetch(); let sFilters_bind = `${xmlFilters.find('filters').attr('bind')}`; @@ -131,7 +131,7 @@ async function actualizaColores(oSource) { attribute_pattern = undefined; value_attribute = undefined; text_attribute = undefined; - var bind; + let bind; //first = $(xmlData).find('filters').select('filter').first().attr("bind"); let filter = xmlFilters.select('//filters/filter').filter(function (filter) { @@ -152,9 +152,9 @@ async function actualizaColores(oSource) { //$(xmlData).find('filters').select('filter[bind="' + first + '"]').select('option').each(function () { // filters[filter.attr("value")] = filter.attr("color") //.replace(/\s+/gi, "-") //}) - var binding = String(attributes["value"]).match(/^(.+)?(@[^\]]+?)$/); - var path = binding[1]; - var attribute = binding[2]; + let binding = String(attributes["value"]).match(/^(.+)?(@[^\]]+?)$/); + let path = binding[1]; + let attribute = binding[2]; if (path) path = String(path).replace(/\/$/, '').replace(/\//, '>'); attribute = attribute.replace(/^@/, ''); [document.querySelector(`[name="filter_headers"]:checked`)].filter(el => el).map(radio => radio.closest(`.filter[bind]`)).pop() @@ -284,7 +284,7 @@ function getValueObjectFromTree(oNode, full_path) { let values = {}; if (path) { - path = String(path).replace(/\/$/, '').replace(/\//, '>'); /*Primer replace quita �ltima diagonal*//*Segundo replace cambia diagonales por "mayor que" para buscarlo como selector*/ + path = String(path).replace(/\/$/, '').replace(/\//, '>'); /*Primer replace quita última diagonal*//*Segundo replace cambia diagonales por "mayor que" para buscarlo como selector*/ $(xmlTree).find(path).each(function () { let oNode = $(this); let val = oNode.attr(attribute); @@ -307,7 +307,7 @@ function getValueFromTree(oNode, full_path) { let values = []; if (path) { - path = String(path).replace(/\/$/, '').replace(/\//, '>'); /*Primer replace quita �ltima diagonal*//*Segundo replace cambia diagonales por "mayor que" para buscarlo como selector*/ + path = String(path).replace(/\/$/, '').replace(/\//, '>'); /*Primer replace quita última diagonal*//*Segundo replace cambia diagonales por "mayor que" para buscarlo como selector*/ $(xmlTree).find(path).each(function () { let element = $(this); values.push(element.attr(attribute)); @@ -372,11 +372,11 @@ function testConditions(oNode, conditions) { } async function Colorea(oSource) { - let xmlData = xo.stores[location.hash]; + let xmlData = xo.stores[xo.site.seed || location.hash]; if (!xmlData.documentElement) await xmlData.fetch(); xmlData = xmlData.document; - let desarrollo_id = (location.hash || '').replace(/^#/, '').toLowerCase(); + let desarrollo_id = xo.site.seed.replace(/^#/, '').toLowerCase(); let xmlFilters = xover.sources[`#${desarrollo_id}:settings`]; if (!xmlFilters.documentElement) await xmlFilters.fetch(); if (oSource && oSource.closest(`.filter`) && !oSource.closest("#Filtros,body").querySelector(`[name="filter_headers"]:checked`)) { @@ -402,10 +402,10 @@ function mutuallyExclusiveClick() { async function iluminarMapa(conditions) { conditions = (conditions || {}); - let xmlData = xo.stores[location.hash]; + let xmlData = xo.stores[xo.site.seed || location.hash]; if (!xmlData.documentElement) await xmlData.fetch(); xmlData = xmlData.document; - let desarrollo_id = (location.hash || '').replace(/^#/, ''); + let desarrollo_id = xo.site.seed.replace(/^#/, '').toLowerCase(); let xmlFilters = xover.sources[`#${desarrollo_id}:settings`]; if (!xmlFilters.documentElement) await xmlFilters.fetch(); @@ -434,12 +434,12 @@ async function iluminarMapa(conditions) { let ubicacion_seleccionada = undefined; let binding = {} binding.bindData = function (scope, attribute, x_source, removeAttribute) { - scope.find('*[' + attribute + ']').each(function () { // Buscamos dentro del detalle todos los nodos que son visibles dependiendo de un atributo (S�lo uno. TODO: que puedan ser m�s de un atributo y con operadores and y or) + scope.find('*[' + attribute + ']').each(function () { // Buscamos dentro del detalle todos los nodos que son visibles dependiendo de un atributo (Sólo uno. TODO: que puedan ser más de un atributo y con operadores and y or) let condition = $(this).attr('visible'); let bindings = condition.match(/{{[^}]+}}/); for (let b = 0; b < bindings.length; b++) { let attr = bindings[b]; //Recuperamos el nombre del atributo a enlazar. - let value = String(getValueFromTree(x_source, attr.replace(/[{}]/gi, ''))); //Recuperamos el valor sin importar la profundidad a la que est� definido + let value = String(getValueFromTree(x_source, attr.replace(/[{}]/gi, ''))); //Recuperamos el valor sin importar la profundidad a la que está definido value = (value.length ? "'" + value + "'" : value); condition = condition.replace(attr, value) } @@ -481,7 +481,7 @@ function resize() { Colorea(); return true; }; - window.removeEventListener('resize', resize ); + window.removeEventListener('resize', resize); window.addEventListener('resize', resize); }, imageMap = new ImageMap(document.querySelector(`map`)); @@ -490,12 +490,14 @@ function resize() { } loteador = {}; +loteador.limpiar = function () { + window.document.querySelectorAll(`.loteador,#Filtros`).select(`.//html:canvas|.//@data-maphilight|*[@bind]`).remove() +} loteador.inicializar = async function () { (function () { //$('.map').maphilight(); - previousWidth = 0; + let previousWidth = 0; let img = document.querySelector('img[usemap]'); - $('img[usemap]').maphilight(); $('area').click(async function (e) { @@ -508,14 +510,12 @@ loteador.inicializar = async function () { ubicacion_seleccionada = txtIdentificador } - //$('#ViviendaDetalles').show(); - - let xmlData = xo.stores[location.hash]; + let xmlData = xo.stores[xo.site.seed || location.hash]; if (!xmlData.documentElement) await xmlData.fetch(); xmlData = xmlData.document; - let desarrollo_id = (location.hash || '').replace(/^#/, '').toLowerCase(); + let desarrollo_id = xo.site.seed.replace(/^#/, '').toLowerCase(); let xmlFilters = xover.sources[`#${desarrollo_id}:settings`]; if (!xmlFilters.documentElement) await xmlFilters.fetch(); @@ -524,15 +524,15 @@ loteador.inicializar = async function () { let target_node = undefined; if (ubicacion_seleccionada) { target_node = $(xmlData).find(sFilters_bind + '[' + sElement_id + '="' + ubicacion_seleccionada + '"]'); //Recuperamos el nodo en el XML correspondiente al nodo seleccionado. - // TODO: Informar que si el nodo seleccionado no tiene correspondencia, considerar que a veces esto es con toda la intención, pues el rango obtenido podr�a estar filtrado. + // TODO: Informar que si el nodo seleccionado no tiene correspondencia, considerar que a veces esto es con toda la intención, pues el rango obtenido podría estar filtrado. let htmlDetails = $(xmlFilters).find('details').clone(); // Clon xamos el html de los detalles //binding.bindData(htmlDetails, 'visible', target_node); - htmlDetails.find('*[visible]').each(function () { // Buscamos dentro del detalle todos los nodos que son visibles dependiendo de un atributo (S�lo uno. TODO: que puedan ser m�s de un atributo y con operadores and y or) + htmlDetails.find('*[visible]').each(function () { // Buscamos dentro del detalle todos los nodos que son visibles dependiendo de un atributo (Sólo uno. TODO: que puedan ser más de un atributo y con operadores and y or) let condition = $(this).attr('visible'); let bindings = condition.match(/{{[^}]+}}/); for (let b = 0; b < bindings.length; b++) { let attr = bindings[b]; //Recuperamos el nombre del atributo a enlazar. - let value = String(getValueFromTree(target_node, attr.replace(/[{}]/gi, ''))); //Recuperamos el valor sin importar la profundidad a la que est� definido + let value = String(getValueFromTree(target_node, attr.replace(/[{}]/gi, ''))); //Recuperamos el valor sin importar la profundidad a la que está definido value = (value.length ? "'" + value + "'" : value); condition = condition.replace(attr, value) } @@ -546,12 +546,12 @@ loteador.inicializar = async function () { htmlDetails.find('*[bind]').each(function () { // Buscamos dentro del detalle todos los nodos que fueron marcados para hacer binding let attr = $(this).attr('bind'); //Recuperamos el nombre del atributo a enlazar. - let value = getValueFromTree(target_node, attr); //Recuperamos el valor sin importar la profundidad a la que est� definido + let value = getValueFromTree(target_node, attr); //Recuperamos el valor sin importar la profundidad a la que está definido if (!value) { $(this).remove(); } else { $(this).removeAttr('bind'); //Quitamos el atributo para que no se renderee - $(this).html(value.join()); //Colocamos el valor, si es m�s de un valor lo concatenamos + $(this).html(value.join()); //Colocamos el valor, si es más de un valor lo concatenamos } }); @@ -560,10 +560,10 @@ loteador.inicializar = async function () { let bindings = condition.match(/{{[^}]+}}/); for (let b = 0; b < bindings.length; b++) { let attr = bindings[b]; //Recuperamos el nombre del atributo a enlazar. - let value = String(getValueFromTree(target_node, attr.replace(/[{}]/gi, ''))); //Recuperamos el valor sin importar la profundidad a la que est� definido + let value = String(getValueFromTree(target_node, attr.replace(/[{}]/gi, ''))); //Recuperamos el valor sin importar la profundidad a la que está definido condition = condition.replace(attr, value) } - $(this).attr('value', condition); //Colocamos el valor, si es m�s de un valor lo concatenamos + $(this).attr('value', condition); //Colocamos el valor, si es más de un valor lo concatenamos }); $('#ViviendaDetalles').html(htmlDetails.get(0).innerHTML); @@ -600,10 +600,10 @@ loteador.inicializar = async function () { })(); let color, txtBind; - let xmlData = xo.stores[location.hash]; + let xmlData = xo.stores[xo.site.seed || location.hash]; if (!xmlData.documentElement) await xmlData.fetch(); xmlData = xmlData.document; - let desarrollo_id = (location.hash || '').replace(/^#/, '').toLowerCase(); + let desarrollo_id = xo.site.seed.replace(/^#/, '').toLowerCase(); let xmlFilters = xover.sources[`#${desarrollo_id}:settings`]; //let mapDoc = xo.sources[location.hash + ':loteador']; diff --git a/manifest.json b/manifest.json index ce91dcd..381cefb 100644 --- a/manifest.json +++ b/manifest.json @@ -15,11 +15,12 @@ "#terminos_condiciones": "./assets/terminos_condiciones.resx", "^#(.+)~edit$": "#$1", "#ws": { - "server:ws": [ + "xover.socket.connect": [ "ws://localhost:8003", { "message": "#messages", - "hotreload": "event:hotreload" + "hotreload": "event:hotreload", + "databaseChange": "event:databaseChange" } ] }