web-mojo 2.1.1043 → 2.1.1087
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -16
- package/dist/admin.cjs.js +1 -1
- package/dist/admin.cjs.js.map +1 -1
- package/dist/admin.es.js +16 -14
- package/dist/admin.es.js.map +1 -1
- package/dist/auth.cjs.js +1 -1
- package/dist/auth.cjs.js.map +1 -1
- package/dist/auth.css +305 -266
- package/dist/auth.es.js +537 -2175
- package/dist/auth.es.js.map +1 -1
- package/dist/charts.cjs.js +1 -1
- package/dist/charts.cjs.js.map +1 -1
- package/dist/charts.css +319 -0
- package/dist/charts.es.js +555 -2
- package/dist/charts.es.js.map +1 -1
- package/dist/chunks/ChatView-BnC15uoD.js +2 -0
- package/dist/chunks/{ChatView-CGBaudUc.js.map → ChatView-BnC15uoD.js.map} +1 -1
- package/dist/chunks/{ChatView-DguKw-gR.js → ChatView-D-5lHZ5H.js} +7 -8
- package/dist/chunks/{ChatView-DguKw-gR.js.map → ChatView-D-5lHZ5H.js.map} +1 -1
- package/dist/chunks/{Collection-DD1_31eh.js → Collection-B64LJ92k.js} +2 -2
- package/dist/chunks/{Collection-DD1_31eh.js.map → Collection-B64LJ92k.js.map} +1 -1
- package/dist/chunks/{Collection-YRfGoT73.js → Collection-CsAk0UhA.js} +2 -2
- package/dist/chunks/{Collection-YRfGoT73.js.map → Collection-CsAk0UhA.js.map} +1 -1
- package/dist/chunks/ContextMenu-CfMAB33c.js +3 -0
- package/dist/chunks/ContextMenu-CfMAB33c.js.map +1 -0
- package/dist/chunks/{ContextMenu-B4_YS0G8.js → ContextMenu-Cvls3QC_.js} +350 -3
- package/dist/chunks/ContextMenu-Cvls3QC_.js.map +1 -0
- package/dist/chunks/DataView-DESqBxT-.js +2 -0
- package/dist/chunks/DataView-DESqBxT-.js.map +1 -0
- package/dist/chunks/{DataView-OUqaLmGB.js → DataView-QXyfcg2M.js} +3 -2
- package/dist/chunks/DataView-QXyfcg2M.js.map +1 -0
- package/dist/chunks/Dialog-BfXN-fFA.js +2 -0
- package/dist/chunks/Dialog-BfXN-fFA.js.map +1 -0
- package/dist/chunks/{Dialog-BiVgKzSK.js → Dialog-DHUsZ92-.js} +1375 -7
- package/dist/chunks/Dialog-DHUsZ92-.js.map +1 -0
- package/dist/chunks/{FormView-BClEkzmE.js → FormView-DGRmcKUG.js} +282 -123
- package/dist/chunks/FormView-DGRmcKUG.js.map +1 -0
- package/dist/chunks/FormView-KGvr68ju.js +3 -0
- package/dist/chunks/FormView-KGvr68ju.js.map +1 -0
- package/dist/chunks/{ListView-BMNhd5-B.js → ListView-BGJG4GYH.js} +3 -3
- package/dist/chunks/{ListView-BMNhd5-B.js.map → ListView-BGJG4GYH.js.map} +1 -1
- package/dist/chunks/{ListView-BRGiITfD.js → ListView-BpGEatee.js} +2 -2
- package/dist/chunks/{ListView-BRGiITfD.js.map → ListView-BpGEatee.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-CCroU6BZ.js → MetricsMiniChartWidget-BKbFGvXG.js} +4 -4
- package/dist/chunks/{MetricsMiniChartWidget-CCroU6BZ.js.map → MetricsMiniChartWidget-BKbFGvXG.js.map} +1 -1
- package/dist/chunks/MetricsMiniChartWidget-BNdGuSZV.js +2 -0
- package/dist/chunks/{MetricsMiniChartWidget-Esvv-lFp.js.map → MetricsMiniChartWidget-BNdGuSZV.js.map} +1 -1
- package/dist/chunks/{PDFViewer-NeL91Gon.js → PDFViewer-BIBNhuWY.js} +3 -3
- package/dist/chunks/{PDFViewer-NeL91Gon.js.map → PDFViewer-BIBNhuWY.js.map} +1 -1
- package/dist/chunks/{PDFViewer-D4uo3oiA.js → PDFViewer-nZAQQScE.js} +2 -2
- package/dist/chunks/{PDFViewer-D4uo3oiA.js.map → PDFViewer-nZAQQScE.js.map} +1 -1
- package/dist/chunks/Rest-BpDyhFfG.js +2 -0
- package/dist/chunks/Rest-BpDyhFfG.js.map +1 -0
- package/dist/chunks/{Rest-CS4jRCAs.js → Rest-DpbPbmra.js} +96 -5
- package/dist/chunks/Rest-DpbPbmra.js.map +1 -0
- package/dist/chunks/TokenManager-BWc_pRpg.js +2 -0
- package/dist/chunks/TokenManager-BWc_pRpg.js.map +1 -0
- package/dist/chunks/{TopNav-DC8oGpHp.js → TokenManager-N3e5wDu1.js} +369 -6
- package/dist/chunks/TokenManager-N3e5wDu1.js.map +1 -0
- package/dist/chunks/{WebSocketClient-D-5DJoMX.js → WebSocketClient-DghNkEyO.js} +2 -2
- package/dist/chunks/{WebSocketClient-D-5DJoMX.js.map → WebSocketClient-DghNkEyO.js.map} +1 -1
- package/dist/chunks/{WebSocketClient-DzcqAmho.js → WebSocketClient-E08hfP5f.js} +2 -2
- package/dist/chunks/{WebSocketClient-DzcqAmho.js.map → WebSocketClient-E08hfP5f.js.map} +1 -1
- package/dist/chunks/version-CKPqwcQJ.js +2 -0
- package/dist/chunks/version-CKPqwcQJ.js.map +1 -0
- package/dist/chunks/version-Dtwh-YkD.js +38 -0
- package/dist/chunks/version-Dtwh-YkD.js.map +1 -0
- package/dist/css/web-mojo.css +1 -17
- package/dist/docit.cjs.js +1 -1
- package/dist/docit.cjs.js.map +1 -1
- package/dist/docit.es.js +6 -8
- package/dist/docit.es.js.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +34 -36
- package/dist/index.es.js.map +1 -1
- package/dist/lightbox.cjs.js +1 -1
- package/dist/lightbox.cjs.js.map +1 -1
- package/dist/lightbox.es.js +5 -4
- package/dist/lightbox.es.js.map +1 -1
- package/dist/map.cjs.js +1 -1
- package/dist/map.cjs.js.map +1 -1
- package/dist/map.es.js +82 -3
- package/dist/map.es.js.map +1 -1
- package/dist/timeline.cjs.js +1 -1
- package/dist/timeline.es.js +4 -4
- package/package.json +1 -1
- package/dist/chunks/ChatView-CGBaudUc.js +0 -2
- package/dist/chunks/ContextMenu-B4_YS0G8.js.map +0 -1
- package/dist/chunks/ContextMenu-DcLhcYMp.js +0 -3
- package/dist/chunks/ContextMenu-DcLhcYMp.js.map +0 -1
- package/dist/chunks/DataView-CdDY9ijM.js +0 -2
- package/dist/chunks/DataView-CdDY9ijM.js.map +0 -1
- package/dist/chunks/DataView-OUqaLmGB.js.map +0 -1
- package/dist/chunks/Dialog-BiVgKzSK.js.map +0 -1
- package/dist/chunks/Dialog-DmIPK_Bi.js +0 -2
- package/dist/chunks/Dialog-DmIPK_Bi.js.map +0 -1
- package/dist/chunks/FormView-BClEkzmE.js.map +0 -1
- package/dist/chunks/FormView-nulck4nL.js +0 -3
- package/dist/chunks/FormView-nulck4nL.js.map +0 -1
- package/dist/chunks/MetricsMiniChartWidget-Esvv-lFp.js +0 -2
- package/dist/chunks/Page-CvbwEoLv.js +0 -2
- package/dist/chunks/Page-CvbwEoLv.js.map +0 -1
- package/dist/chunks/Page-Deq4y2Kq.js +0 -351
- package/dist/chunks/Page-Deq4y2Kq.js.map +0 -1
- package/dist/chunks/Rest-BNYqGlnP.js +0 -2
- package/dist/chunks/Rest-BNYqGlnP.js.map +0 -1
- package/dist/chunks/Rest-CS4jRCAs.js.map +0 -1
- package/dist/chunks/TokenManager-CAZNcCMs.js +0 -366
- package/dist/chunks/TokenManager-CAZNcCMs.js.map +0 -1
- package/dist/chunks/TokenManager-CJBYcVqs.js +0 -2
- package/dist/chunks/TokenManager-CJBYcVqs.js.map +0 -1
- package/dist/chunks/TopNav-23B5R-dl.js +0 -2
- package/dist/chunks/TopNav-23B5R-dl.js.map +0 -1
- package/dist/chunks/TopNav-DC8oGpHp.js.map +0 -1
- package/dist/chunks/WebApp-C1vcdSuu.js +0 -1388
- package/dist/chunks/WebApp-C1vcdSuu.js.map +0 -1
- package/dist/chunks/WebApp-CpxtmTk0.js +0 -2
- package/dist/chunks/WebApp-CpxtmTk0.js.map +0 -1
package/dist/map.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./chunks/Rest-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./chunks/Rest-BpDyhFfG.js"),e=require("./chunks/Collection-B64LJ92k.js");class MapView extends t.View{constructor(t={}){super({className:"map-view",...t}),this.markers=t.markers||[],this.center=t.center||null,this.zoom=t.zoom||13,this.height=t.height||400,this.showZoomControl=!1!==t.showZoomControl,this.tileLayer=t.tileLayer||"osm",this.showLeafletBranding=!0===t.showLeafletBranding,this.showLayerControl=!0===t.showLayerControl,this.layerOptions=t.layerOptions||{osm:"OSM",satellite:"Satellite",terrain:"Terrain",dark:"Dark",light:"Light",watercolor:"Watercolor",bw:"B/W",streets:"Streets"},this.map=null,this.leafletMarkers=[],this._tileLayer=null,this.template='\n <div class="map-container">\n <div id="map-{{id}}" style="height: {{height}}px; width: 100%; border-radius: 0.375rem; border: 1px solid #dee2e6;"></div>\n </div>\n '}async onAfterRender(){await this.loadLeaflet(),await this.initializeMap()}async loadLeaflet(){if(window.L)return;const t=new Promise(t=>{const e=document.createElement("link");e.rel="stylesheet",e.href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css",e.onload=t,e.onerror=t,document.head.appendChild(e)}),e=new Promise((t,e)=>{const i=document.createElement("script");i.src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js",i.onload=t,i.onerror=e,document.head.appendChild(i)});await Promise.all([t,e])}getTileLayerUrl(){const t={osm:{url:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",attribution:"© OpenStreetMap contributors",maxZoom:19},satellite:{url:"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",attribution:"© Esri",maxZoom:19},terrain:{url:"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",attribution:"© OpenTopoMap contributors",maxZoom:17},dark:{url:"https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",attribution:"© OpenStreetMap contributors © CARTO",maxZoom:20},light:{url:"https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",attribution:"© OpenStreetMap contributors © CARTO",maxZoom:20},watercolor:{url:"https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg",attribution:"© Stadia Maps © Stamen Design © OpenStreetMap contributors",maxZoom:16},bw:{url:"https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png",attribution:"© OpenStreetMap contributors © CARTO",maxZoom:20},streets:{url:"https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",attribution:"© OpenStreetMap contributors © CARTO",maxZoom:20}};return t[this.tileLayer]||t.osm}async initializeMap(){const t=this.element.querySelector(`#map-${this.id}`);if(!t||!window.L)return;let e=this.center;if(!e&&this.markers.length>0&&(e=[this.markers[0].lat,this.markers[0].lng]),e||(e=[0,0]),this.map=window.L.map(t,{center:e,zoom:this.zoom,zoomControl:this.showZoomControl}),this.map&&this.map.attributionControl&&!1===this.showLeafletBranding)try{this.map.attributionControl.setPrefix("")}catch(s){}const i=this.getTileLayerUrl();if(this._tileLayer=window.L.tileLayer(i.url,{attribution:i.attribution,maxZoom:i.maxZoom}).addTo(this.map),this.showLayerControl){const e=t.parentElement||this.element.querySelector(".map-container");if(e){e.style.position=e.style.position||"relative";const t=document.createElement("select");t.className="form-select form-select-sm",t.style.position="absolute",t.style.top="8px",t.style.right="8px",t.style.zIndex="1000",t.style.maxWidth="180px",t.setAttribute("aria-label","Map tile layer"),Object.entries(this.layerOptions||{}).forEach(([e,i])=>{const s=document.createElement("option");s.value=e,s.textContent=i,e===this.tileLayer&&(s.selected=!0),t.appendChild(s)}),t.addEventListener("change",()=>this.setTileLayer(t.value)),e.appendChild(t)}}this.addMarkers(this.markers),this.markers.length>1&&this.fitBounds(),setTimeout(()=>{this.map&&this.map.invalidateSize()},300)}addMarkers(t){this.map&&Array.isArray(t)&&t.forEach(t=>{const{lat:e,lng:i,popup:s,icon:r}=t;if(!e||!i)return;const a={};r&&(a.icon=window.L.icon(r));const o=window.L.marker([e,i],a).addTo(this.map);s&&o.bindPopup(s),this.leafletMarkers.push(o)})}fitBounds(){if(!this.map||0===this.leafletMarkers.length)return;const t=new window.L.featureGroup(this.leafletMarkers);this.map.fitBounds(t.getBounds().pad(.1))}updateMarkers(t){this.clearMarkers(),this.markers=t,this.addMarkers(t),t.length>1?this.fitBounds():1===t.length&&this.map.setView([t[0].lat,t[0].lng],this.zoom)}clearMarkers(){this.leafletMarkers.forEach(t=>{this.map.removeLayer(t)}),this.leafletMarkers=[]}setView(t,e,i=null){this.map&&this.map.setView([t,e],i||this.zoom)}setZoom(t){this.map&&this.map.setZoom(t)}setTileLayer(t){if(!this.map)return;const e=this.tileLayer;this.tileLayer=t||this.tileLayer;const i=this.getTileLayerUrl();try{this._tileLayer&&this.map.removeLayer(this._tileLayer)}catch(s){}this._tileLayer=window.L.tileLayer(i.url,{attribution:i.attribution,maxZoom:i.maxZoom}).addTo(this.map),this.tileLayer=t||e,setTimeout(()=>{try{this.map.invalidateSize()}catch(s){}},150)}async onBeforeDestroy(){this.map&&(this.map.remove(),this.map=null),await super.onBeforeDestroy()}static async showAsDialog(t={}){const e=new MapView(t),i={title:"Map View",header:!0,body:e,size:"lg",centered:!1,...t.dialogOptions||{}};await e.init(),await e.getApp().showDialog(i)}}exports.View=t.View,exports.Collection=e.Collection,exports.Model=e.Model,exports.MapView=MapView;
|
|
2
2
|
//# sourceMappingURL=map.cjs.js.map
|
package/dist/map.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.cjs.js","sources":["../src/extensions/map/MapView.js"],"sourcesContent":["/**\n * MapView - Interactive map component using Leaflet\n * \n * Features:\n * - Display single or multiple markers\n * - Auto-zoom to fit markers\n * - Customizable marker popups\n * - Support for different tile layers\n * \n * @example\n * const mapView = new MapView({\n * markers: [\n * { lat: 37.422, lng: -122.084, popup: 'Mountain View, CA' }\n * ],\n * zoom: 10,\n * height: 400\n * });\n */\n\nimport View from '@core/View.js';\n\nclass MapView extends View {\n constructor(options = {}) {\n super({\n className: 'map-view',\n ...options\n });\n\n this.markers = options.markers || [];\n this.center = options.center || null;\n this.zoom = options.zoom || 13;\n this.height = options.height || 400;\n this.showZoomControl = options.showZoomControl !== false;\n this.tileLayer = options.tileLayer || 'osm'; // 'osm', 'satellite', 'terrain'\n \n this.map = null;\n this.leafletMarkers = [];\n\n this.template = `\n <div class=\"map-container\">\n <div id=\"map-{{id}}\" style=\"height: {{height}}px; width: 100%; border-radius: 0.375rem; border: 1px solid #dee2e6;\"></div>\n </div>\n `;\n }\n\n async onAfterRender() {\n await this.loadLeaflet();\n await this.initializeMap();\n }\n\n async loadLeaflet() {\n // Check if Leaflet is already loaded\n if (window.L) return;\n\n // Load Leaflet CSS and wait for it\n const cssLoaded = new Promise((resolve) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';\n link.onload = resolve;\n link.onerror = resolve; // Continue even if CSS fails\n document.head.appendChild(link);\n });\n\n // Load Leaflet JS\n const jsLoaded = new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';\n script.onload = resolve;\n script.onerror = reject;\n document.head.appendChild(script);\n });\n\n // Wait for both CSS and JS to load\n await Promise.all([cssLoaded, jsLoaded]);\n }\n\n getTileLayerUrl() {\n const tileLayers = {\n // Standard street maps\n osm: {\n url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n attribution: '© OpenStreetMap contributors',\n maxZoom: 19\n },\n \n // Satellite imagery\n satellite: {\n url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',\n attribution: '© Esri',\n maxZoom: 19\n },\n \n // Terrain and topographic\n terrain: {\n url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',\n attribution: '© OpenTopoMap contributors',\n maxZoom: 17\n },\n \n // Dark mode styles\n dark: {\n url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n \n // Light/minimal styles\n light: {\n url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n \n // Watercolor artistic style\n watercolor: {\n url: 'https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg',\n attribution: '© Stadia Maps © Stamen Design © OpenStreetMap contributors',\n maxZoom: 16\n },\n \n // Black and white\n bw: {\n url: 'https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n \n // Streets with labels\n streets: {\n url: 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n }\n };\n\n return tileLayers[this.tileLayer] || tileLayers.osm;\n }\n\n async initializeMap() {\n const mapElement = this.element.querySelector(`#map-${this.id}`);\n if (!mapElement || !window.L) return;\n\n // Determine map center\n let mapCenter = this.center;\n if (!mapCenter && this.markers.length > 0) {\n // Use first marker as center\n mapCenter = [this.markers[0].lat, this.markers[0].lng];\n }\n if (!mapCenter) {\n // Default to world view\n mapCenter = [0, 0];\n }\n\n // Create map\n this.map = window.L.map(mapElement, {\n center: mapCenter,\n zoom: this.zoom,\n zoomControl: this.showZoomControl\n });\n\n // Add tile layer\n const tileConfig = this.getTileLayerUrl();\n window.L.tileLayer(tileConfig.url, {\n attribution: tileConfig.attribution,\n maxZoom: tileConfig.maxZoom\n }).addTo(this.map);\n\n // Add markers\n this.addMarkers(this.markers);\n\n // Auto-fit bounds if multiple markers\n if (this.markers.length > 1) {\n this.fitBounds();\n }\n\n // Fix tile rendering issues by invalidating size after a delay\n // This ensures the container has proper dimensions and CSS is applied\n setTimeout(() => {\n if (this.map) {\n this.map.invalidateSize();\n }\n }, 300);\n }\n\n addMarkers(markers) {\n if (!this.map || !Array.isArray(markers)) return;\n\n markers.forEach(markerData => {\n const { lat, lng, popup, icon } = markerData;\n \n if (!lat || !lng) return;\n\n const markerOptions = {};\n \n // Custom icon if provided\n if (icon) {\n markerOptions.icon = window.L.icon(icon);\n }\n\n const marker = window.L.marker([lat, lng], markerOptions).addTo(this.map);\n\n // Add popup if provided\n if (popup) {\n marker.bindPopup(popup);\n }\n\n this.leafletMarkers.push(marker);\n });\n }\n\n fitBounds() {\n if (!this.map || this.leafletMarkers.length === 0) return;\n\n const group = new window.L.featureGroup(this.leafletMarkers);\n this.map.fitBounds(group.getBounds().pad(0.1));\n }\n\n updateMarkers(newMarkers) {\n // Clear existing markers\n this.clearMarkers();\n \n // Add new markers\n this.markers = newMarkers;\n this.addMarkers(newMarkers);\n \n // Fit bounds if multiple markers\n if (newMarkers.length > 1) {\n this.fitBounds();\n } else if (newMarkers.length === 1) {\n this.map.setView([newMarkers[0].lat, newMarkers[0].lng], this.zoom);\n }\n }\n\n clearMarkers() {\n this.leafletMarkers.forEach(marker => {\n this.map.removeLayer(marker);\n });\n this.leafletMarkers = [];\n }\n\n setView(lat, lng, zoom = null) {\n if (!this.map) return;\n this.map.setView([lat, lng], zoom || this.zoom);\n }\n\n setZoom(zoom) {\n if (!this.map) return;\n this.map.setZoom(zoom);\n }\n\n async onBeforeDestroy() {\n if (this.map) {\n this.map.remove();\n this.map = null;\n }\n await super.onBeforeDestroy();\n }\n}\n\nexport default MapView;\n"],"names":["MapView","View","constructor","options","super","className","this","markers","center","zoom","height","showZoomControl","tileLayer","map","leafletMarkers","template","onAfterRender","loadLeaflet","initializeMap","window","L","cssLoaded","Promise","resolve","link","document","createElement","rel","href","onload","onerror","head","appendChild","jsLoaded","reject","script","src","all","getTileLayerUrl","tileLayers","osm","url","attribution","maxZoom","satellite","terrain","dark","light","watercolor","bw","streets","mapElement","element","querySelector","id","mapCenter","length","lat","lng","zoomControl","tileConfig","addTo","addMarkers","fitBounds","setTimeout","invalidateSize","Array","isArray","forEach","markerData","popup","icon","markerOptions","marker","bindPopup","push","group","featureGroup","getBounds","pad","updateMarkers","newMarkers","clearMarkers","setView","removeLayer","setZoom","onBeforeDestroy","remove"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"map.cjs.js","sources":["../src/extensions/map/MapView.js"],"sourcesContent":["/**\n * MapView - Interactive map component using Leaflet\n *\n * Features:\n * - Display single or multiple markers\n * - Auto-zoom to fit markers\n * - Customizable marker popups\n * - Support for different tile layers\n *\n * @example\n * const mapView = new MapView({\n * markers: [\n * { lat: 37.422, lng: -122.084, popup: 'Mountain View, CA' }\n * ],\n * zoom: 10,\n * height: 400\n * });\n */\n\nimport View from '@core/View.js';\n\nclass MapView extends View {\n constructor(options = {}) {\n super({\n className: 'map-view',\n ...options\n });\n\n this.markers = options.markers || [];\n this.center = options.center || null;\n this.zoom = options.zoom || 13;\n this.height = options.height || 400;\n this.showZoomControl = options.showZoomControl !== false;\n this.tileLayer = options.tileLayer || 'osm'; // 'osm', 'satellite', 'terrain'\n this.showLeafletBranding = options.showLeafletBranding === true;\n this.showLayerControl = options.showLayerControl === true;\n this.layerOptions = options.layerOptions || {\n osm: 'OSM',\n satellite: 'Satellite',\n terrain: 'Terrain',\n dark: 'Dark',\n light: 'Light',\n watercolor: 'Watercolor',\n bw: 'B/W',\n streets: 'Streets'\n };\n\n this.map = null;\n this.leafletMarkers = [];\n this._tileLayer = null;\n\n this.template = `\n <div class=\"map-container\">\n <div id=\"map-{{id}}\" style=\"height: {{height}}px; width: 100%; border-radius: 0.375rem; border: 1px solid #dee2e6;\"></div>\n </div>\n `;\n }\n\n async onAfterRender() {\n await this.loadLeaflet();\n await this.initializeMap();\n }\n\n async loadLeaflet() {\n // Check if Leaflet is already loaded\n if (window.L) return;\n\n // Load Leaflet CSS and wait for it\n const cssLoaded = new Promise((resolve) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';\n link.onload = resolve;\n link.onerror = resolve; // Continue even if CSS fails\n document.head.appendChild(link);\n });\n\n // Load Leaflet JS\n const jsLoaded = new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';\n script.onload = resolve;\n script.onerror = reject;\n document.head.appendChild(script);\n });\n\n // Wait for both CSS and JS to load\n await Promise.all([cssLoaded, jsLoaded]);\n }\n\n getTileLayerUrl() {\n const tileLayers = {\n // Standard street maps\n osm: {\n url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n attribution: '© OpenStreetMap contributors',\n maxZoom: 19\n },\n\n // Satellite imagery\n satellite: {\n url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',\n attribution: '© Esri',\n maxZoom: 19\n },\n\n // Terrain and topographic\n terrain: {\n url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',\n attribution: '© OpenTopoMap contributors',\n maxZoom: 17\n },\n\n // Dark mode styles\n dark: {\n url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n\n // Light/minimal styles\n light: {\n url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n\n // Watercolor artistic style\n watercolor: {\n url: 'https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg',\n attribution: '© Stadia Maps © Stamen Design © OpenStreetMap contributors',\n maxZoom: 16\n },\n\n // Black and white\n bw: {\n url: 'https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n\n // Streets with labels\n streets: {\n url: 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n }\n };\n\n return tileLayers[this.tileLayer] || tileLayers.osm;\n }\n\n async initializeMap() {\n const mapElement = this.element.querySelector(`#map-${this.id}`);\n if (!mapElement || !window.L) return;\n\n // Determine map center\n let mapCenter = this.center;\n if (!mapCenter && this.markers.length > 0) {\n // Use first marker as center\n mapCenter = [this.markers[0].lat, this.markers[0].lng];\n }\n if (!mapCenter) {\n // Default to world view\n mapCenter = [0, 0];\n }\n\n // Create map\n this.map = window.L.map(mapElement, {\n center: mapCenter,\n zoom: this.zoom,\n zoomControl: this.showZoomControl\n });\n // Optionally hide Leaflet branding/prefix (removes Leaflet link/flag in attribution control)\n if (this.map && this.map.attributionControl && this.showLeafletBranding === false) {\n try { this.map.attributionControl.setPrefix(''); } catch (e) {}\n }\n\n // Add tile layer\n const tileConfig = this.getTileLayerUrl();\n this._tileLayer = window.L.tileLayer(tileConfig.url, {\n attribution: tileConfig.attribution,\n maxZoom: tileConfig.maxZoom\n }).addTo(this.map);\n\n // Optional built-in tile layer selector UI\n if (this.showLayerControl) {\n const container = mapElement.parentElement || this.element.querySelector('.map-container');\n if (container) {\n container.style.position = container.style.position || 'relative';\n const selector = document.createElement('select');\n selector.className = 'form-select form-select-sm';\n selector.style.position = 'absolute';\n selector.style.top = '8px';\n selector.style.right = '8px';\n selector.style.zIndex = '1000';\n selector.style.maxWidth = '180px';\n selector.setAttribute('aria-label', 'Map tile layer');\n\n // Populate options\n Object.entries(this.layerOptions || {}).forEach(([key, label]) => {\n const opt = document.createElement('option');\n opt.value = key;\n opt.textContent = label;\n if (key === this.tileLayer) opt.selected = true;\n selector.appendChild(opt);\n });\n\n selector.addEventListener('change', () => this.setTileLayer(selector.value));\n container.appendChild(selector);\n }\n }\n\n // Add markers\n this.addMarkers(this.markers);\n\n // Auto-fit bounds if multiple markers\n if (this.markers.length > 1) {\n this.fitBounds();\n }\n\n // Fix tile rendering issues by invalidating size after a delay\n // This ensures the container has proper dimensions and CSS is applied\n setTimeout(() => {\n if (this.map) {\n this.map.invalidateSize();\n }\n }, 300);\n }\n\n addMarkers(markers) {\n if (!this.map || !Array.isArray(markers)) return;\n\n markers.forEach(markerData => {\n const { lat, lng, popup, icon } = markerData;\n\n if (!lat || !lng) return;\n\n const markerOptions = {};\n\n // Custom icon if provided\n if (icon) {\n markerOptions.icon = window.L.icon(icon);\n }\n\n const marker = window.L.marker([lat, lng], markerOptions).addTo(this.map);\n\n // Add popup if provided\n if (popup) {\n marker.bindPopup(popup);\n }\n\n this.leafletMarkers.push(marker);\n });\n }\n\n fitBounds() {\n if (!this.map || this.leafletMarkers.length === 0) return;\n\n const group = new window.L.featureGroup(this.leafletMarkers);\n this.map.fitBounds(group.getBounds().pad(0.1));\n }\n\n updateMarkers(newMarkers) {\n // Clear existing markers\n this.clearMarkers();\n\n // Add new markers\n this.markers = newMarkers;\n this.addMarkers(newMarkers);\n\n // Fit bounds if multiple markers\n if (newMarkers.length > 1) {\n this.fitBounds();\n } else if (newMarkers.length === 1) {\n this.map.setView([newMarkers[0].lat, newMarkers[0].lng], this.zoom);\n }\n }\n\n clearMarkers() {\n this.leafletMarkers.forEach(marker => {\n this.map.removeLayer(marker);\n });\n this.leafletMarkers = [];\n }\n\n setView(lat, lng, zoom = null) {\n if (!this.map) return;\n this.map.setView([lat, lng], zoom || this.zoom);\n }\n\n setZoom(zoom) {\n if (!this.map) return;\n this.map.setZoom(zoom);\n }\n\n setTileLayer(key) {\n if (!this.map) return;\n // Resolve tile layer config using the same logic as getTileLayerUrl\n const original = this.tileLayer;\n this.tileLayer = key || this.tileLayer;\n const tileConfig = this.getTileLayerUrl();\n try {\n if (this._tileLayer) {\n this.map.removeLayer(this._tileLayer);\n }\n } catch (e) {\n // ignore if layer already removed\n }\n this._tileLayer = window.L.tileLayer(tileConfig.url, {\n attribution: tileConfig.attribution,\n maxZoom: tileConfig.maxZoom\n }).addTo(this.map);\n // Keep property in sync\n this.tileLayer = key || original;\n\n // Nudge map to ensure proper redraw\n setTimeout(() => {\n try { this.map.invalidateSize(); } catch (e) {}\n }, 150);\n }\n\n async onBeforeDestroy() {\n if (this.map) {\n this.map.remove();\n this.map = null;\n }\n await super.onBeforeDestroy();\n }\n\n static async showAsDialog(options = {}) {\n const view = new MapView(options);\n const dopts = options.dialogOptions || {};\n const dialogOptions = {\n title: \"Map View\",\n header: true,\n body: view,\n size: 'lg',\n centered: false,\n ...dopts\n }\n await view.init();\n await view.getApp().showDialog(dialogOptions);\n }\n}\n\nexport default MapView;\n"],"names":["MapView","View","constructor","options","super","className","this","markers","center","zoom","height","showZoomControl","tileLayer","showLeafletBranding","showLayerControl","layerOptions","osm","satellite","terrain","dark","light","watercolor","bw","streets","map","leafletMarkers","_tileLayer","template","onAfterRender","loadLeaflet","initializeMap","window","L","cssLoaded","Promise","resolve","link","document","createElement","rel","href","onload","onerror","head","appendChild","jsLoaded","reject","script","src","all","getTileLayerUrl","tileLayers","url","attribution","maxZoom","mapElement","element","querySelector","id","mapCenter","length","lat","lng","zoomControl","attributionControl","setPrefix","e","tileConfig","addTo","container","parentElement","style","position","selector","top","right","zIndex","maxWidth","setAttribute","Object","entries","forEach","key","label","opt","value","textContent","selected","addEventListener","setTileLayer","addMarkers","fitBounds","setTimeout","invalidateSize","Array","isArray","markerData","popup","icon","markerOptions","marker","bindPopup","push","group","featureGroup","getBounds","pad","updateMarkers","newMarkers","clearMarkers","setView","removeLayer","setZoom","original","onBeforeDestroy","remove","showAsDialog","view","dialogOptions","title","header","body","size","centered","init","getApp","showDialog"],"mappings":"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"}
|
package/dist/map.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { V as View } from "./chunks/Rest-
|
|
2
|
-
import { C, M } from "./chunks/Collection-
|
|
1
|
+
import { V as View } from "./chunks/Rest-DpbPbmra.js";
|
|
2
|
+
import { C, M } from "./chunks/Collection-CsAk0UhA.js";
|
|
3
3
|
class MapView extends View {
|
|
4
4
|
constructor(options = {}) {
|
|
5
5
|
super({
|
|
@@ -12,8 +12,21 @@ class MapView extends View {
|
|
|
12
12
|
this.height = options.height || 400;
|
|
13
13
|
this.showZoomControl = options.showZoomControl !== false;
|
|
14
14
|
this.tileLayer = options.tileLayer || "osm";
|
|
15
|
+
this.showLeafletBranding = options.showLeafletBranding === true;
|
|
16
|
+
this.showLayerControl = options.showLayerControl === true;
|
|
17
|
+
this.layerOptions = options.layerOptions || {
|
|
18
|
+
osm: "OSM",
|
|
19
|
+
satellite: "Satellite",
|
|
20
|
+
terrain: "Terrain",
|
|
21
|
+
dark: "Dark",
|
|
22
|
+
light: "Light",
|
|
23
|
+
watercolor: "Watercolor",
|
|
24
|
+
bw: "B/W",
|
|
25
|
+
streets: "Streets"
|
|
26
|
+
};
|
|
15
27
|
this.map = null;
|
|
16
28
|
this.leafletMarkers = [];
|
|
29
|
+
this._tileLayer = null;
|
|
17
30
|
this.template = `
|
|
18
31
|
<div class="map-container">
|
|
19
32
|
<div id="map-{{id}}" style="height: {{height}}px; width: 100%; border-radius: 0.375rem; border: 1px solid #dee2e6;"></div>
|
|
@@ -111,11 +124,40 @@ class MapView extends View {
|
|
|
111
124
|
zoom: this.zoom,
|
|
112
125
|
zoomControl: this.showZoomControl
|
|
113
126
|
});
|
|
127
|
+
if (this.map && this.map.attributionControl && this.showLeafletBranding === false) {
|
|
128
|
+
try {
|
|
129
|
+
this.map.attributionControl.setPrefix("");
|
|
130
|
+
} catch (e) {
|
|
131
|
+
}
|
|
132
|
+
}
|
|
114
133
|
const tileConfig = this.getTileLayerUrl();
|
|
115
|
-
window.L.tileLayer(tileConfig.url, {
|
|
134
|
+
this._tileLayer = window.L.tileLayer(tileConfig.url, {
|
|
116
135
|
attribution: tileConfig.attribution,
|
|
117
136
|
maxZoom: tileConfig.maxZoom
|
|
118
137
|
}).addTo(this.map);
|
|
138
|
+
if (this.showLayerControl) {
|
|
139
|
+
const container = mapElement.parentElement || this.element.querySelector(".map-container");
|
|
140
|
+
if (container) {
|
|
141
|
+
container.style.position = container.style.position || "relative";
|
|
142
|
+
const selector = document.createElement("select");
|
|
143
|
+
selector.className = "form-select form-select-sm";
|
|
144
|
+
selector.style.position = "absolute";
|
|
145
|
+
selector.style.top = "8px";
|
|
146
|
+
selector.style.right = "8px";
|
|
147
|
+
selector.style.zIndex = "1000";
|
|
148
|
+
selector.style.maxWidth = "180px";
|
|
149
|
+
selector.setAttribute("aria-label", "Map tile layer");
|
|
150
|
+
Object.entries(this.layerOptions || {}).forEach(([key, label]) => {
|
|
151
|
+
const opt = document.createElement("option");
|
|
152
|
+
opt.value = key;
|
|
153
|
+
opt.textContent = label;
|
|
154
|
+
if (key === this.tileLayer) opt.selected = true;
|
|
155
|
+
selector.appendChild(opt);
|
|
156
|
+
});
|
|
157
|
+
selector.addEventListener("change", () => this.setTileLayer(selector.value));
|
|
158
|
+
container.appendChild(selector);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
119
161
|
this.addMarkers(this.markers);
|
|
120
162
|
if (this.markers.length > 1) {
|
|
121
163
|
this.fitBounds();
|
|
@@ -171,6 +213,29 @@ class MapView extends View {
|
|
|
171
213
|
if (!this.map) return;
|
|
172
214
|
this.map.setZoom(zoom);
|
|
173
215
|
}
|
|
216
|
+
setTileLayer(key) {
|
|
217
|
+
if (!this.map) return;
|
|
218
|
+
const original = this.tileLayer;
|
|
219
|
+
this.tileLayer = key || this.tileLayer;
|
|
220
|
+
const tileConfig = this.getTileLayerUrl();
|
|
221
|
+
try {
|
|
222
|
+
if (this._tileLayer) {
|
|
223
|
+
this.map.removeLayer(this._tileLayer);
|
|
224
|
+
}
|
|
225
|
+
} catch (e) {
|
|
226
|
+
}
|
|
227
|
+
this._tileLayer = window.L.tileLayer(tileConfig.url, {
|
|
228
|
+
attribution: tileConfig.attribution,
|
|
229
|
+
maxZoom: tileConfig.maxZoom
|
|
230
|
+
}).addTo(this.map);
|
|
231
|
+
this.tileLayer = key || original;
|
|
232
|
+
setTimeout(() => {
|
|
233
|
+
try {
|
|
234
|
+
this.map.invalidateSize();
|
|
235
|
+
} catch (e) {
|
|
236
|
+
}
|
|
237
|
+
}, 150);
|
|
238
|
+
}
|
|
174
239
|
async onBeforeDestroy() {
|
|
175
240
|
if (this.map) {
|
|
176
241
|
this.map.remove();
|
|
@@ -178,6 +243,20 @@ class MapView extends View {
|
|
|
178
243
|
}
|
|
179
244
|
await super.onBeforeDestroy();
|
|
180
245
|
}
|
|
246
|
+
static async showAsDialog(options = {}) {
|
|
247
|
+
const view = new MapView(options);
|
|
248
|
+
const dopts = options.dialogOptions || {};
|
|
249
|
+
const dialogOptions = {
|
|
250
|
+
title: "Map View",
|
|
251
|
+
header: true,
|
|
252
|
+
body: view,
|
|
253
|
+
size: "lg",
|
|
254
|
+
centered: false,
|
|
255
|
+
...dopts
|
|
256
|
+
};
|
|
257
|
+
await view.init();
|
|
258
|
+
await view.getApp().showDialog(dialogOptions);
|
|
259
|
+
}
|
|
181
260
|
}
|
|
182
261
|
export {
|
|
183
262
|
C as Collection,
|
package/dist/map.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.es.js","sources":["../src/extensions/map/MapView.js"],"sourcesContent":["/**\n * MapView - Interactive map component using Leaflet\n * \n * Features:\n * - Display single or multiple markers\n * - Auto-zoom to fit markers\n * - Customizable marker popups\n * - Support for different tile layers\n * \n * @example\n * const mapView = new MapView({\n * markers: [\n * { lat: 37.422, lng: -122.084, popup: 'Mountain View, CA' }\n * ],\n * zoom: 10,\n * height: 400\n * });\n */\n\nimport View from '@core/View.js';\n\nclass MapView extends View {\n constructor(options = {}) {\n super({\n className: 'map-view',\n ...options\n });\n\n this.markers = options.markers || [];\n this.center = options.center || null;\n this.zoom = options.zoom || 13;\n this.height = options.height || 400;\n this.showZoomControl = options.showZoomControl !== false;\n this.tileLayer = options.tileLayer || 'osm'; // 'osm', 'satellite', 'terrain'\n \n this.map = null;\n this.leafletMarkers = [];\n\n this.template = `\n <div class=\"map-container\">\n <div id=\"map-{{id}}\" style=\"height: {{height}}px; width: 100%; border-radius: 0.375rem; border: 1px solid #dee2e6;\"></div>\n </div>\n `;\n }\n\n async onAfterRender() {\n await this.loadLeaflet();\n await this.initializeMap();\n }\n\n async loadLeaflet() {\n // Check if Leaflet is already loaded\n if (window.L) return;\n\n // Load Leaflet CSS and wait for it\n const cssLoaded = new Promise((resolve) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';\n link.onload = resolve;\n link.onerror = resolve; // Continue even if CSS fails\n document.head.appendChild(link);\n });\n\n // Load Leaflet JS\n const jsLoaded = new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';\n script.onload = resolve;\n script.onerror = reject;\n document.head.appendChild(script);\n });\n\n // Wait for both CSS and JS to load\n await Promise.all([cssLoaded, jsLoaded]);\n }\n\n getTileLayerUrl() {\n const tileLayers = {\n // Standard street maps\n osm: {\n url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n attribution: '© OpenStreetMap contributors',\n maxZoom: 19\n },\n \n // Satellite imagery\n satellite: {\n url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',\n attribution: '© Esri',\n maxZoom: 19\n },\n \n // Terrain and topographic\n terrain: {\n url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',\n attribution: '© OpenTopoMap contributors',\n maxZoom: 17\n },\n \n // Dark mode styles\n dark: {\n url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n \n // Light/minimal styles\n light: {\n url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n \n // Watercolor artistic style\n watercolor: {\n url: 'https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg',\n attribution: '© Stadia Maps © Stamen Design © OpenStreetMap contributors',\n maxZoom: 16\n },\n \n // Black and white\n bw: {\n url: 'https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n \n // Streets with labels\n streets: {\n url: 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n }\n };\n\n return tileLayers[this.tileLayer] || tileLayers.osm;\n }\n\n async initializeMap() {\n const mapElement = this.element.querySelector(`#map-${this.id}`);\n if (!mapElement || !window.L) return;\n\n // Determine map center\n let mapCenter = this.center;\n if (!mapCenter && this.markers.length > 0) {\n // Use first marker as center\n mapCenter = [this.markers[0].lat, this.markers[0].lng];\n }\n if (!mapCenter) {\n // Default to world view\n mapCenter = [0, 0];\n }\n\n // Create map\n this.map = window.L.map(mapElement, {\n center: mapCenter,\n zoom: this.zoom,\n zoomControl: this.showZoomControl\n });\n\n // Add tile layer\n const tileConfig = this.getTileLayerUrl();\n window.L.tileLayer(tileConfig.url, {\n attribution: tileConfig.attribution,\n maxZoom: tileConfig.maxZoom\n }).addTo(this.map);\n\n // Add markers\n this.addMarkers(this.markers);\n\n // Auto-fit bounds if multiple markers\n if (this.markers.length > 1) {\n this.fitBounds();\n }\n\n // Fix tile rendering issues by invalidating size after a delay\n // This ensures the container has proper dimensions and CSS is applied\n setTimeout(() => {\n if (this.map) {\n this.map.invalidateSize();\n }\n }, 300);\n }\n\n addMarkers(markers) {\n if (!this.map || !Array.isArray(markers)) return;\n\n markers.forEach(markerData => {\n const { lat, lng, popup, icon } = markerData;\n \n if (!lat || !lng) return;\n\n const markerOptions = {};\n \n // Custom icon if provided\n if (icon) {\n markerOptions.icon = window.L.icon(icon);\n }\n\n const marker = window.L.marker([lat, lng], markerOptions).addTo(this.map);\n\n // Add popup if provided\n if (popup) {\n marker.bindPopup(popup);\n }\n\n this.leafletMarkers.push(marker);\n });\n }\n\n fitBounds() {\n if (!this.map || this.leafletMarkers.length === 0) return;\n\n const group = new window.L.featureGroup(this.leafletMarkers);\n this.map.fitBounds(group.getBounds().pad(0.1));\n }\n\n updateMarkers(newMarkers) {\n // Clear existing markers\n this.clearMarkers();\n \n // Add new markers\n this.markers = newMarkers;\n this.addMarkers(newMarkers);\n \n // Fit bounds if multiple markers\n if (newMarkers.length > 1) {\n this.fitBounds();\n } else if (newMarkers.length === 1) {\n this.map.setView([newMarkers[0].lat, newMarkers[0].lng], this.zoom);\n }\n }\n\n clearMarkers() {\n this.leafletMarkers.forEach(marker => {\n this.map.removeLayer(marker);\n });\n this.leafletMarkers = [];\n }\n\n setView(lat, lng, zoom = null) {\n if (!this.map) return;\n this.map.setView([lat, lng], zoom || this.zoom);\n }\n\n setZoom(zoom) {\n if (!this.map) return;\n this.map.setZoom(zoom);\n }\n\n async onBeforeDestroy() {\n if (this.map) {\n this.map.remove();\n this.map = null;\n }\n await super.onBeforeDestroy();\n }\n}\n\nexport default MapView;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"map.es.js","sources":["../src/extensions/map/MapView.js"],"sourcesContent":["/**\n * MapView - Interactive map component using Leaflet\n *\n * Features:\n * - Display single or multiple markers\n * - Auto-zoom to fit markers\n * - Customizable marker popups\n * - Support for different tile layers\n *\n * @example\n * const mapView = new MapView({\n * markers: [\n * { lat: 37.422, lng: -122.084, popup: 'Mountain View, CA' }\n * ],\n * zoom: 10,\n * height: 400\n * });\n */\n\nimport View from '@core/View.js';\n\nclass MapView extends View {\n constructor(options = {}) {\n super({\n className: 'map-view',\n ...options\n });\n\n this.markers = options.markers || [];\n this.center = options.center || null;\n this.zoom = options.zoom || 13;\n this.height = options.height || 400;\n this.showZoomControl = options.showZoomControl !== false;\n this.tileLayer = options.tileLayer || 'osm'; // 'osm', 'satellite', 'terrain'\n this.showLeafletBranding = options.showLeafletBranding === true;\n this.showLayerControl = options.showLayerControl === true;\n this.layerOptions = options.layerOptions || {\n osm: 'OSM',\n satellite: 'Satellite',\n terrain: 'Terrain',\n dark: 'Dark',\n light: 'Light',\n watercolor: 'Watercolor',\n bw: 'B/W',\n streets: 'Streets'\n };\n\n this.map = null;\n this.leafletMarkers = [];\n this._tileLayer = null;\n\n this.template = `\n <div class=\"map-container\">\n <div id=\"map-{{id}}\" style=\"height: {{height}}px; width: 100%; border-radius: 0.375rem; border: 1px solid #dee2e6;\"></div>\n </div>\n `;\n }\n\n async onAfterRender() {\n await this.loadLeaflet();\n await this.initializeMap();\n }\n\n async loadLeaflet() {\n // Check if Leaflet is already loaded\n if (window.L) return;\n\n // Load Leaflet CSS and wait for it\n const cssLoaded = new Promise((resolve) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';\n link.onload = resolve;\n link.onerror = resolve; // Continue even if CSS fails\n document.head.appendChild(link);\n });\n\n // Load Leaflet JS\n const jsLoaded = new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';\n script.onload = resolve;\n script.onerror = reject;\n document.head.appendChild(script);\n });\n\n // Wait for both CSS and JS to load\n await Promise.all([cssLoaded, jsLoaded]);\n }\n\n getTileLayerUrl() {\n const tileLayers = {\n // Standard street maps\n osm: {\n url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n attribution: '© OpenStreetMap contributors',\n maxZoom: 19\n },\n\n // Satellite imagery\n satellite: {\n url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',\n attribution: '© Esri',\n maxZoom: 19\n },\n\n // Terrain and topographic\n terrain: {\n url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',\n attribution: '© OpenTopoMap contributors',\n maxZoom: 17\n },\n\n // Dark mode styles\n dark: {\n url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n\n // Light/minimal styles\n light: {\n url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n\n // Watercolor artistic style\n watercolor: {\n url: 'https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg',\n attribution: '© Stadia Maps © Stamen Design © OpenStreetMap contributors',\n maxZoom: 16\n },\n\n // Black and white\n bw: {\n url: 'https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n },\n\n // Streets with labels\n streets: {\n url: 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png',\n attribution: '© OpenStreetMap contributors © CARTO',\n maxZoom: 20\n }\n };\n\n return tileLayers[this.tileLayer] || tileLayers.osm;\n }\n\n async initializeMap() {\n const mapElement = this.element.querySelector(`#map-${this.id}`);\n if (!mapElement || !window.L) return;\n\n // Determine map center\n let mapCenter = this.center;\n if (!mapCenter && this.markers.length > 0) {\n // Use first marker as center\n mapCenter = [this.markers[0].lat, this.markers[0].lng];\n }\n if (!mapCenter) {\n // Default to world view\n mapCenter = [0, 0];\n }\n\n // Create map\n this.map = window.L.map(mapElement, {\n center: mapCenter,\n zoom: this.zoom,\n zoomControl: this.showZoomControl\n });\n // Optionally hide Leaflet branding/prefix (removes Leaflet link/flag in attribution control)\n if (this.map && this.map.attributionControl && this.showLeafletBranding === false) {\n try { this.map.attributionControl.setPrefix(''); } catch (e) {}\n }\n\n // Add tile layer\n const tileConfig = this.getTileLayerUrl();\n this._tileLayer = window.L.tileLayer(tileConfig.url, {\n attribution: tileConfig.attribution,\n maxZoom: tileConfig.maxZoom\n }).addTo(this.map);\n\n // Optional built-in tile layer selector UI\n if (this.showLayerControl) {\n const container = mapElement.parentElement || this.element.querySelector('.map-container');\n if (container) {\n container.style.position = container.style.position || 'relative';\n const selector = document.createElement('select');\n selector.className = 'form-select form-select-sm';\n selector.style.position = 'absolute';\n selector.style.top = '8px';\n selector.style.right = '8px';\n selector.style.zIndex = '1000';\n selector.style.maxWidth = '180px';\n selector.setAttribute('aria-label', 'Map tile layer');\n\n // Populate options\n Object.entries(this.layerOptions || {}).forEach(([key, label]) => {\n const opt = document.createElement('option');\n opt.value = key;\n opt.textContent = label;\n if (key === this.tileLayer) opt.selected = true;\n selector.appendChild(opt);\n });\n\n selector.addEventListener('change', () => this.setTileLayer(selector.value));\n container.appendChild(selector);\n }\n }\n\n // Add markers\n this.addMarkers(this.markers);\n\n // Auto-fit bounds if multiple markers\n if (this.markers.length > 1) {\n this.fitBounds();\n }\n\n // Fix tile rendering issues by invalidating size after a delay\n // This ensures the container has proper dimensions and CSS is applied\n setTimeout(() => {\n if (this.map) {\n this.map.invalidateSize();\n }\n }, 300);\n }\n\n addMarkers(markers) {\n if (!this.map || !Array.isArray(markers)) return;\n\n markers.forEach(markerData => {\n const { lat, lng, popup, icon } = markerData;\n\n if (!lat || !lng) return;\n\n const markerOptions = {};\n\n // Custom icon if provided\n if (icon) {\n markerOptions.icon = window.L.icon(icon);\n }\n\n const marker = window.L.marker([lat, lng], markerOptions).addTo(this.map);\n\n // Add popup if provided\n if (popup) {\n marker.bindPopup(popup);\n }\n\n this.leafletMarkers.push(marker);\n });\n }\n\n fitBounds() {\n if (!this.map || this.leafletMarkers.length === 0) return;\n\n const group = new window.L.featureGroup(this.leafletMarkers);\n this.map.fitBounds(group.getBounds().pad(0.1));\n }\n\n updateMarkers(newMarkers) {\n // Clear existing markers\n this.clearMarkers();\n\n // Add new markers\n this.markers = newMarkers;\n this.addMarkers(newMarkers);\n\n // Fit bounds if multiple markers\n if (newMarkers.length > 1) {\n this.fitBounds();\n } else if (newMarkers.length === 1) {\n this.map.setView([newMarkers[0].lat, newMarkers[0].lng], this.zoom);\n }\n }\n\n clearMarkers() {\n this.leafletMarkers.forEach(marker => {\n this.map.removeLayer(marker);\n });\n this.leafletMarkers = [];\n }\n\n setView(lat, lng, zoom = null) {\n if (!this.map) return;\n this.map.setView([lat, lng], zoom || this.zoom);\n }\n\n setZoom(zoom) {\n if (!this.map) return;\n this.map.setZoom(zoom);\n }\n\n setTileLayer(key) {\n if (!this.map) return;\n // Resolve tile layer config using the same logic as getTileLayerUrl\n const original = this.tileLayer;\n this.tileLayer = key || this.tileLayer;\n const tileConfig = this.getTileLayerUrl();\n try {\n if (this._tileLayer) {\n this.map.removeLayer(this._tileLayer);\n }\n } catch (e) {\n // ignore if layer already removed\n }\n this._tileLayer = window.L.tileLayer(tileConfig.url, {\n attribution: tileConfig.attribution,\n maxZoom: tileConfig.maxZoom\n }).addTo(this.map);\n // Keep property in sync\n this.tileLayer = key || original;\n\n // Nudge map to ensure proper redraw\n setTimeout(() => {\n try { this.map.invalidateSize(); } catch (e) {}\n }, 150);\n }\n\n async onBeforeDestroy() {\n if (this.map) {\n this.map.remove();\n this.map = null;\n }\n await super.onBeforeDestroy();\n }\n\n static async showAsDialog(options = {}) {\n const view = new MapView(options);\n const dopts = options.dialogOptions || {};\n const dialogOptions = {\n title: \"Map View\",\n header: true,\n body: view,\n size: 'lg',\n centered: false,\n ...dopts\n }\n await view.init();\n await view.getApp().showDialog(dialogOptions);\n }\n}\n\nexport default MapView;\n"],"names":[],"mappings":"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"}
|
package/dist/timeline.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./chunks/ListView-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./chunks/ListView-BpGEatee.js"),e=require("./chunks/Rest-BpDyhFfG.js"),i=require("./chunks/Collection-B64LJ92k.js");class TimelineViewItem extends t.ListViewItem{constructor(t={}){super({className:"timeline-item",...t}),this.dateFormat=t.dateFormat||"date",this.dotStyle=t.dotStyle||"solid",this.showDate=!1!==t.showDate,this.theme=t.theme||"primary",this.template||(this.template='\n <div class="timeline-marker timeline-marker-{{markerType}}">\n {{#hasIcon}}\n <i class="bi {{model.icon}} text-{{displayColor}}"></i>\n {{/hasIcon}}\n {{^hasIcon}}\n <div class="timeline-dot bg-{{displayColor}}"></div>\n {{/hasIcon}}\n </div>\n \n <div class="timeline-content">\n {{#showDate}}\n <div class="timeline-date text-muted small">\n {{formattedDate}}\n </div>\n {{/showDate}}\n \n <div class="timeline-card">\n {{#model.title}}\n <h6 class="timeline-title mb-1">{{model.title}}</h6>\n {{/model.title}}\n \n {{#model.description}}\n <p class="timeline-description mb-0">{{model.description}}</p>\n {{/model.description}}\n \n {{#model.meta}}\n <div class="timeline-meta mt-2 text-muted small">\n {{model.meta}}\n </div>\n {{/model.meta}}\n </div>\n </div>\n ')}async onInit(){await super.onInit(),this.processItemData()}processItemData(){this.displayColor=this.model?.get?.("color")||this.model?.color||this.theme;const t=!(!this.model?.get?.("icon")&&!this.model?.icon)&&"icon"===this.dotStyle;this.hasIcon=t,this.markerType=t?"icon":this.dotStyle;const e=this.model?.get?.("date")||this.model?.date;this.formattedDate=this.formatDate(e)}formatDate(t){if(!t)return"";switch(this.dateFormat){case"datetime":return e.dataFormatter.pipe(t,"datetime");case"relative":return e.dataFormatter.pipe(t,"timeago");default:return e.dataFormatter.pipe(t,"date")}}async onActionSelect(t,e){t.stopPropagation(),this.emit("item:click",{item:this,model:this.model,index:this.index,data:this.model?.toJSON?this.model.toJSON():this.model}),this.listView&&this.listView.emit("item:click",{item:this,model:this.model,index:this.index,data:this.model?.toJSON?this.model.toJSON():this.model})}}class TimelineView extends t.ListView{constructor(t={}){super({className:"timeline-view",itemClass:t.itemClass||TimelineViewItem,selectionMode:"none",emptyMessage:t.emptyMessage||"No timeline events to display",template:'\n <div class="timeline-container timeline-{{position}}">\n {{#loading}}\n <div class="timeline-loading text-center py-4">\n <div class="spinner-border spinner-border-sm" role="status">\n <span class="visually-hidden">Loading...</span>\n </div>\n <span class="ms-2 text-muted">Loading timeline...</span>\n </div>\n {{/loading}}\n {{^loading}}\n {{#isEmpty}}\n <div class="timeline-empty text-center text-muted py-4">\n <i class="bi bi-clock-history fs-1 d-block mb-2"></i>\n <p>{{emptyMessage}}</p>\n </div>\n {{/isEmpty}}\n {{^isEmpty}}\n <div class="timeline" data-container="items"></div>\n {{/isEmpty}}\n {{/loading}}\n </div>\n ',...t}),this.position=t.position||"left",this.dateFormat=t.dateFormat||"date",this.dotStyle=t.dotStyle||"solid",this.showDate=!1!==t.showDate,this.theme=t.theme||"primary",this.groupBy=t.groupBy||"none"}_createItemView(t,e){if(this.itemViews.has(t.id))return;const i=new this.itemClass({model:t,index:e,listView:this,template:this.itemTemplate,dateFormat:this.dateFormat,dotStyle:this.dotStyle,showDate:this.showDate,theme:this.theme});return this.itemViews.set(t.id,i),i.on("item:click",this._onItemClick.bind(this)),i}_onItemClick(t){this.emit("item:click",t)}setPosition(t){return"left"!==t&&"center"!==t?(console.warn('Invalid position. Use "left" or "center"'),this):(this.position=t,this.isMounted()&&this.render(),this)}setDateFormat(t){return this.dateFormat=t,this.forEachItem(e=>{e.dateFormat=t,e.processItemData(),e.isMounted()&&e.render()}),this}setDotStyle(t){return this.dotStyle=t,this.forEachItem(e=>{e.dotStyle=t,e.processItemData(),e.isMounted()&&e.render()}),this}toggleDates(t=null){return this.showDate=null!==t?t:!this.showDate,this.forEachItem(t=>{t.showDate=this.showDate,t.isMounted()&&t.render()}),this}}exports.ListView=t.ListView,exports.ListViewItem=t.ListViewItem,exports.View=e.View,exports.Collection=i.Collection,exports.Model=i.Model,exports.TimelineView=TimelineView,exports.TimelineViewItem=TimelineViewItem;
|
|
2
2
|
//# sourceMappingURL=timeline.cjs.js.map
|
package/dist/timeline.es.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as ListViewItem, a as ListView } from "./chunks/ListView-
|
|
2
|
-
import { d as dataFormatter } from "./chunks/Rest-
|
|
3
|
-
import { V } from "./chunks/Rest-
|
|
4
|
-
import { C, M } from "./chunks/Collection-
|
|
1
|
+
import { L as ListViewItem, a as ListView } from "./chunks/ListView-BGJG4GYH.js";
|
|
2
|
+
import { d as dataFormatter } from "./chunks/Rest-DpbPbmra.js";
|
|
3
|
+
import { V } from "./chunks/Rest-DpbPbmra.js";
|
|
4
|
+
import { C, M } from "./chunks/Collection-CsAk0UhA.js";
|
|
5
5
|
class TimelineViewItem extends ListViewItem {
|
|
6
6
|
constructor(options = {}) {
|
|
7
7
|
super({
|