Merge pull request #1454 from jschleic/download-ui
Refactor Share & Download UI for better usability
This commit is contained in:
commit
05401af06b
11 changed files with 407 additions and 260 deletions
|
@ -162,14 +162,16 @@ textarea {
|
||||||
padding: 7px;
|
padding: 7px;
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
|
border: 1px solid #222;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
line-height: 28px;
|
line-height: 28px;
|
||||||
color: #efefef;
|
|
||||||
border: 1px solid #222;
|
|
||||||
background-color: #393F3F;
|
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
.dark select {
|
||||||
|
color: #efefef;
|
||||||
|
background-color: #393F3F;
|
||||||
|
}
|
||||||
select[multiple="multiple"] {
|
select[multiple="multiple"] {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
@ -294,16 +296,19 @@ input[type="file"] + .error {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
display: block;
|
display: block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #232729;
|
background-color: #eee;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
color: #fff;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: fira_sans;
|
font-family: fira_sans;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
}
|
}
|
||||||
|
.dark .fieldset.toggle .legend {
|
||||||
|
background-color: #232729;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
.fieldset.toggle .legend:before {
|
.fieldset.toggle .legend:before {
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
text-indent: 24px;
|
text-indent: 24px;
|
||||||
|
@ -311,11 +316,14 @@ input[type="file"] + .error {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-image: url('./img/16-white.svg');
|
background-image: url('./img/16.svg');
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
content: " ";
|
content: " ";
|
||||||
background-position: -144px -76px;
|
background-position: -144px -76px;
|
||||||
}
|
}
|
||||||
|
.dark .fieldset.toggle .legend:before {
|
||||||
|
background-image: url('./img/16-white.svg');
|
||||||
|
}
|
||||||
.fieldset.toggle.on .legend:before {
|
.fieldset.toggle.on .legend:before {
|
||||||
background-position: -144px -51px;
|
background-position: -144px -51px;
|
||||||
}
|
}
|
||||||
|
@ -448,7 +456,8 @@ input.switch:checked ~ label:after {
|
||||||
}
|
}
|
||||||
.umap-field-iconUrl .action-button,
|
.umap-field-iconUrl .action-button,
|
||||||
.inheritable .define,
|
.inheritable .define,
|
||||||
.inheritable .undefine {
|
.inheritable .undefine,
|
||||||
|
.copy-button {
|
||||||
float: right;
|
float: right;
|
||||||
width: initial;
|
width: initial;
|
||||||
min-height: 18px;
|
min-height: 18px;
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<svg id="svg2" width="144" height="168" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
<svg id="svg2" width="168" height="168" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||||
<defs id="defs4">
|
<defs id="defs4">
|
||||||
|
<marker id="Arrow1" overflow="visible" markerHeight="6.7071066" markerWidth="4.0606604" orient="auto-start-reverse" preserveAspectRatio="xMidYMid" viewBox="0 0 4.0606602 6.7071068">
|
||||||
|
<path id="path5057" transform="rotate(180 .125 0)" d="m3-3-3 3 3 3" fill="none" stroke="context-stroke"/>
|
||||||
|
</marker>
|
||||||
<mask id="mask0_181_11898" x="2" y="2" width="15" height="15" maskUnits="userSpaceOnUse">
|
<mask id="mask0_181_11898" x="2" y="2" width="15" height="15" maskUnits="userSpaceOnUse">
|
||||||
<path id="path2351" d="m16.04 2.3158h-14.035v14.035h14.035z" fill="#fff"/>
|
<path id="path2351" d="m16.04 2.3158h-14.035v14.035h14.035z" fill="#fff"/>
|
||||||
</mask>
|
</mask>
|
||||||
|
@ -168,5 +171,12 @@
|
||||||
</g>
|
</g>
|
||||||
<path id="path2378" d="m25.147 1.8521h-4.2439c-0.07035 0-0.13782 0.027946-0.18756 0.077689-0.04974 0.049744-0.07769 0.11721-0.07769 0.18756v4.2439c0 0.070353 0.02795 0.13782 0.07769 0.18756 0.04974 0.049742 0.11721 0.077682 0.18756 0.077682h4.2439c0.07035 0 0.13782-0.02794 0.18756-0.077682 0.04974-0.049742 0.07768-0.11721 0.07768-0.18756v-4.2439c0-0.070349-0.02794-0.13782-0.07768-0.18756-0.04974-0.049743-0.11721-0.077689-0.18756-0.077689zm-0.26524 4.1591h-3.7135v-3.5463h3.7135z" fill="#464646" stroke-width=".26458"/>
|
<path id="path2378" d="m25.147 1.8521h-4.2439c-0.07035 0-0.13782 0.027946-0.18756 0.077689-0.04974 0.049744-0.07769 0.11721-0.07769 0.18756v4.2439c0 0.070353 0.02795 0.13782 0.07769 0.18756 0.04974 0.049742 0.11721 0.077682 0.18756 0.077682h4.2439c0.07035 0 0.13782-0.02794 0.18756-0.077682 0.04974-0.049742 0.07768-0.11721 0.07768-0.18756v-4.2439c0-0.070349-0.02794-0.13782-0.07768-0.18756-0.04974-0.049743-0.11721-0.077689-0.18756-0.077689zm-0.26524 4.1591h-3.7135v-3.5463h3.7135z" fill="#464646" stroke-width=".26458"/>
|
||||||
</g>
|
</g>
|
||||||
|
<path id="arrow-down" d="m156 875.36 6-6h-12z" fill="#4d4d4d" fill-rule="evenodd"/>
|
||||||
|
<path id="arrow-right" d="m159 896.36-6-6v12z" fill="#4d4d4d" fill-rule="evenodd"/>
|
||||||
|
<path id="downloadfile" d="m14.182 962.12v2.6078h2.6078zm2.9091 4.0624h-2.9091c-0.80332 0-1.4545-0.65122-1.4545-1.4545v-2.9091h-5.8182v13.091h10.182zm-10.182-5.8182h7.574l4.0624 4.0624v10.483c0 0.80333-0.65122 1.4546-1.4545 1.4546h-10.182c-0.80332 0-1.4545-0.65122-1.4545-1.4546v-13.091c0-0.80333 0.65122-1.4546 1.4545-1.4546zm4.3636 9.8806v-3.3351h1.4545v3.3351l0.94028-0.94029 1.0285 1.0285-2.6961 2.6961-2.6961-2.6961 1.0285-1.0285z" fill="#464646" fill-rule="evenodd" stroke-width=".72727"/>
|
||||||
|
<g id="downloadbackup">
|
||||||
|
<path id="path8303-6" d="m42.545 974.91c0 0.80333-0.65122 1.4546-1.4545 1.4546h-10.182c-0.80332 0-1.4545-0.65122-1.4545-1.4546h13.091z" fill="#464646" stroke-width=".72727"/>
|
||||||
|
<path id="path16669" d="m36 963.88v8.3163" fill="none" marker-end="url(#Arrow1)" stroke="#464646" stroke-width="1.5"/>
|
||||||
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
|
@ -2,7 +2,7 @@
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
width="144"
|
width="168"
|
||||||
height="168"
|
height="168"
|
||||||
id="svg2"
|
id="svg2"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
|
@ -20,6 +20,26 @@
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
<defs
|
<defs
|
||||||
id="defs4">
|
id="defs4">
|
||||||
|
<marker
|
||||||
|
style="overflow:visible"
|
||||||
|
id="Arrow1"
|
||||||
|
refX="0"
|
||||||
|
refY="0"
|
||||||
|
orient="auto-start-reverse"
|
||||||
|
inkscape:stockid="Arrow1"
|
||||||
|
markerWidth="4.0606604"
|
||||||
|
markerHeight="6.7071066"
|
||||||
|
viewBox="0 0 4.0606602 6.7071068"
|
||||||
|
inkscape:isstock="true"
|
||||||
|
inkscape:collect="always"
|
||||||
|
preserveAspectRatio="xMidYMid">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:context-stroke;stroke-width:1;stroke-linecap:butt"
|
||||||
|
d="M 3,-3 0,0 3,3"
|
||||||
|
id="path5057"
|
||||||
|
transform="rotate(180,0.125,0)"
|
||||||
|
sodipodi:nodetypes="ccc" />
|
||||||
|
</marker>
|
||||||
<mask
|
<mask
|
||||||
id="mask0_181_11898"
|
id="mask0_181_11898"
|
||||||
maskUnits="userSpaceOnUse"
|
maskUnits="userSpaceOnUse"
|
||||||
|
@ -40,9 +60,9 @@
|
||||||
borderopacity="1.0"
|
borderopacity="1.0"
|
||||||
inkscape:pageopacity="0.0"
|
inkscape:pageopacity="0.0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="4.5893817"
|
inkscape:zoom="3.2451829"
|
||||||
inkscape:cx="68.418802"
|
inkscape:cx="57.469796"
|
||||||
inkscape:cy="100.88505"
|
inkscape:cy="94.601755"
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
inkscape:current-layer="layer1"
|
inkscape:current-layer="layer1"
|
||||||
showgrid="true"
|
showgrid="true"
|
||||||
|
@ -127,7 +147,7 @@
|
||||||
inkscape:label=""
|
inkscape:label=""
|
||||||
inkscape:color="rgb(0,134,229)" />
|
inkscape:color="rgb(0,134,229)" />
|
||||||
<sodipodi:guide
|
<sodipodi:guide
|
||||||
position="120,96"
|
position="120,168"
|
||||||
orientation="-1,0"
|
orientation="-1,0"
|
||||||
id="guide4869"
|
id="guide4869"
|
||||||
inkscape:label=""
|
inkscape:label=""
|
||||||
|
@ -145,6 +165,13 @@
|
||||||
inkscape:label=""
|
inkscape:label=""
|
||||||
inkscape:locked="false"
|
inkscape:locked="false"
|
||||||
inkscape:color="rgb(0,134,229)" />
|
inkscape:color="rgb(0,134,229)" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="144,168"
|
||||||
|
orientation="-1,0"
|
||||||
|
id="guide10571"
|
||||||
|
inkscape:label=""
|
||||||
|
inkscape:locked="false"
|
||||||
|
inkscape:color="rgb(0,0,255)" />
|
||||||
</sodipodi:namedview>
|
</sodipodi:namedview>
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata7">
|
id="metadata7">
|
||||||
|
@ -852,5 +879,34 @@
|
||||||
id="path2378"
|
id="path2378"
|
||||||
style="stroke-width:0.264583" />
|
style="stroke-width:0.264583" />
|
||||||
</g>
|
</g>
|
||||||
|
<path
|
||||||
|
id="arrow-down"
|
||||||
|
d="m 156,875.36218 6,-6 h -12 z"
|
||||||
|
fill="#f2f2f2"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
style="fill:#4d4d4d;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
id="arrow-right"
|
||||||
|
d="m 159,896.36218 -6,-6 v 12 z"
|
||||||
|
fill="#f2f2f2"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
style="fill:#4d4d4d;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="m 14.181818,962.11797 v 2.60785 h 2.607845 z m 2.909091,4.06239 h -2.909091 c -0.803323,0 -1.454545,-0.65122 -1.454545,-1.45454 v -2.90909 H 6.9090909 v 13.0909 H 17.090909 Z M 6.9090909,960.36218 h 7.5739741 l 4.06239,4.06239 v 10.48306 c 0,0.80333 -0.651223,1.45455 -1.454546,1.45455 H 6.9090909 c -0.8033233,0 -1.4545455,-0.65122 -1.4545455,-1.45455 v -13.0909 c 0,-0.80333 0.6512222,-1.45455 1.4545455,-1.45455 z m 4.3636361,9.88057 v -3.33512 h 1.454546 v 3.33512 l 0.940285,-0.94029 1.02852,1.02853 L 12,973.02706 9.3039222,970.33099 10.332441,969.30246 Z"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
id="downloadfile"
|
||||||
|
style="fill:#464646;fill-opacity:1;stroke-width:0.727273" />
|
||||||
|
<g
|
||||||
|
id="downloadbackup">
|
||||||
|
<path
|
||||||
|
style="fill:#464646;fill-opacity:1;stroke-width:0.727273"
|
||||||
|
d="m 42.545455,974.90763 c 0,0.80333 -0.651223,1.45455 -1.454546,1.45455 H 30.909091 c -0.803323,0 -1.454546,-0.65122 -1.454546,-1.45455 2.557093,0 9.805435,0 13.09091,0 z"
|
||||||
|
id="path8303-6" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#464646;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1)"
|
||||||
|
d="m 36,963.87832 v 8.3163"
|
||||||
|
id="path16669"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 48 KiB |
|
@ -409,9 +409,9 @@ L.Control.Embed = L.Control.extend({
|
||||||
const shareButton = L.DomUtil.createButton(
|
const shareButton = L.DomUtil.createButton(
|
||||||
'',
|
'',
|
||||||
container,
|
container,
|
||||||
L._('Share, download and embed this map'),
|
L._('Share and download'),
|
||||||
map.renderShareBox,
|
map.share.open,
|
||||||
map
|
map.share
|
||||||
)
|
)
|
||||||
L.DomEvent.on(shareButton, 'dblclick', L.DomEvent.stopPropagation)
|
L.DomEvent.on(shareButton, 'dblclick', L.DomEvent.stopPropagation)
|
||||||
return container
|
return container
|
||||||
|
@ -896,46 +896,6 @@ L.U.Map.include({
|
||||||
this.ui.openPanel({ data: { html: container }, actions: actions })
|
this.ui.openPanel({ data: { html: container }, actions: actions })
|
||||||
},
|
},
|
||||||
|
|
||||||
EXPORT_TYPES: {
|
|
||||||
geojson: {
|
|
||||||
formatter: function (map) {
|
|
||||||
return JSON.stringify(map.toGeoJSON(), null, 2)
|
|
||||||
},
|
|
||||||
ext: '.geojson',
|
|
||||||
filetype: 'application/json',
|
|
||||||
},
|
|
||||||
gpx: {
|
|
||||||
formatter: function (map) {
|
|
||||||
return togpx(map.toGeoJSON())
|
|
||||||
},
|
|
||||||
ext: '.gpx',
|
|
||||||
filetype: 'application/gpx+xml',
|
|
||||||
},
|
|
||||||
kml: {
|
|
||||||
formatter: function (map) {
|
|
||||||
return tokml(map.toGeoJSON())
|
|
||||||
},
|
|
||||||
ext: '.kml',
|
|
||||||
filetype: 'application/vnd.google-earth.kml+xml',
|
|
||||||
},
|
|
||||||
csv: {
|
|
||||||
formatter: function (map) {
|
|
||||||
const table = []
|
|
||||||
map.eachFeature((feature) => {
|
|
||||||
const row = feature.toGeoJSON()['properties'],
|
|
||||||
center = feature.getCenter()
|
|
||||||
delete row['_umap_options']
|
|
||||||
row['Latitude'] = center.lat
|
|
||||||
row['Longitude'] = center.lng
|
|
||||||
table.push(row)
|
|
||||||
})
|
|
||||||
return csv2geojson.dsv.csvFormat(table)
|
|
||||||
},
|
|
||||||
ext: '.csv',
|
|
||||||
filetype: 'text/csv',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
renderEditToolbar: function () {
|
renderEditToolbar: function () {
|
||||||
const container = L.DomUtil.create(
|
const container = L.DomUtil.create(
|
||||||
'div',
|
'div',
|
||||||
|
@ -1083,107 +1043,6 @@ L.U.Map.include({
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
renderShareBox: function () {
|
|
||||||
const container = L.DomUtil.create('div', 'umap-share')
|
|
||||||
const title = L.DomUtil.create('h3', '', container)
|
|
||||||
title.textContent = L._('Share, download and embed this map')
|
|
||||||
|
|
||||||
const embedTitle = L.DomUtil.add('h4', '', container, L._('Embed the map'))
|
|
||||||
const iframe = L.DomUtil.create('textarea', 'umap-share-iframe', container)
|
|
||||||
const urlTitle = L.DomUtil.add('h4', '', container, L._('Direct link'))
|
|
||||||
const exportUrl = L.DomUtil.create('input', 'umap-share-url', container)
|
|
||||||
let option
|
|
||||||
exportUrl.type = 'text'
|
|
||||||
const UIFields = [
|
|
||||||
['dimensions.width', { handler: 'Input', label: L._('width') }],
|
|
||||||
['dimensions.height', { handler: 'Input', label: L._('height') }],
|
|
||||||
[
|
|
||||||
'options.includeFullScreenLink',
|
|
||||||
{ handler: 'Switch', label: L._('Include full screen link?') },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'options.currentView',
|
|
||||||
{ handler: 'Switch', label: L._('Current view instead of default map view?') },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'options.keepCurrentDatalayers',
|
|
||||||
{ handler: 'Switch', label: L._('Keep current visible layers') },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'options.viewCurrentFeature',
|
|
||||||
{ handler: 'Switch', label: L._('Open current feature on load') },
|
|
||||||
],
|
|
||||||
'queryString.moreControl',
|
|
||||||
'queryString.scrollWheelZoom',
|
|
||||||
'queryString.miniMap',
|
|
||||||
'queryString.scaleControl',
|
|
||||||
'queryString.onLoadPanel',
|
|
||||||
'queryString.captionBar',
|
|
||||||
'queryString.captionMenus',
|
|
||||||
]
|
|
||||||
for (let i = 0; i < this.HIDDABLE_CONTROLS.length; i++) {
|
|
||||||
UIFields.push(`queryString.${this.HIDDABLE_CONTROLS[i]}Control`)
|
|
||||||
}
|
|
||||||
const iframeExporter = new L.U.IframeExporter(this)
|
|
||||||
const buildIframeCode = () => {
|
|
||||||
iframe.innerHTML = iframeExporter.build()
|
|
||||||
exportUrl.value = window.location.protocol + iframeExporter.buildUrl()
|
|
||||||
}
|
|
||||||
buildIframeCode()
|
|
||||||
const builder = new L.U.FormBuilder(iframeExporter, UIFields, {
|
|
||||||
callback: buildIframeCode,
|
|
||||||
})
|
|
||||||
const iframeOptions = L.DomUtil.createFieldset(container, L._('Export options'))
|
|
||||||
iframeOptions.appendChild(builder.build())
|
|
||||||
if (this.options.shortUrl) {
|
|
||||||
L.DomUtil.create('hr', '', container)
|
|
||||||
L.DomUtil.add('h4', '', container, L._('Short URL'))
|
|
||||||
const shortUrl = L.DomUtil.create('input', 'umap-short-url', container)
|
|
||||||
shortUrl.type = 'text'
|
|
||||||
shortUrl.value = this.options.shortUrl
|
|
||||||
}
|
|
||||||
L.DomUtil.create('hr', '', container)
|
|
||||||
L.DomUtil.add('h4', '', container, L._('Backup data'))
|
|
||||||
const downloadUrl = L.Util.template(this.options.urls.map_download, {
|
|
||||||
map_id: this.options.umap_id,
|
|
||||||
})
|
|
||||||
const link = L.DomUtil.createLink(
|
|
||||||
'button',
|
|
||||||
container,
|
|
||||||
L._('Download full data'),
|
|
||||||
downloadUrl
|
|
||||||
)
|
|
||||||
let name = this.options.name || 'data'
|
|
||||||
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
|
|
||||||
link.setAttribute('download', `${name}.umap`)
|
|
||||||
L.DomUtil.create('hr', '', container)
|
|
||||||
L.DomUtil.add('h4', '', container, L._('Download data'))
|
|
||||||
const typeInput = L.DomUtil.create('select', '', container)
|
|
||||||
typeInput.name = 'format'
|
|
||||||
const exportCaveat = L.DomUtil.add(
|
|
||||||
'small',
|
|
||||||
'help-text',
|
|
||||||
container,
|
|
||||||
L._('Only visible features will be downloaded.')
|
|
||||||
)
|
|
||||||
for (const key in this.EXPORT_TYPES) {
|
|
||||||
if (this.EXPORT_TYPES.hasOwnProperty(key)) {
|
|
||||||
option = L.DomUtil.create('option', '', typeInput)
|
|
||||||
option.value = key
|
|
||||||
option.textContent = this.EXPORT_TYPES[key].name || key
|
|
||||||
if (this.EXPORT_TYPES[key].selected) option.selected = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
L.DomUtil.createButton(
|
|
||||||
'button',
|
|
||||||
container,
|
|
||||||
L._('Download data'),
|
|
||||||
() => this.download(typeInput.value),
|
|
||||||
this
|
|
||||||
)
|
|
||||||
this.ui.openPanel({ data: { html: container } })
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/* Used in view mode to define the current tilelayer */
|
/* Used in view mode to define the current tilelayer */
|
||||||
|
@ -1515,77 +1374,6 @@ L.U.ContextMenu = L.Map.ContextMenu.extend({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
L.U.IframeExporter = L.Evented.extend({
|
|
||||||
options: {
|
|
||||||
includeFullScreenLink: true,
|
|
||||||
currentView: false,
|
|
||||||
keepCurrentDatalayers: false,
|
|
||||||
viewCurrentFeature: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
queryString: {
|
|
||||||
scaleControl: false,
|
|
||||||
miniMap: false,
|
|
||||||
scrollWheelZoom: false,
|
|
||||||
zoomControl: true,
|
|
||||||
editMode: 'disabled',
|
|
||||||
moreControl: true,
|
|
||||||
searchControl: null,
|
|
||||||
tilelayersControl: null,
|
|
||||||
embedControl: null,
|
|
||||||
datalayersControl: true,
|
|
||||||
onLoadPanel: 'none',
|
|
||||||
captionBar: false,
|
|
||||||
captionMenus: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
dimensions: {
|
|
||||||
width: '100%',
|
|
||||||
height: '300px',
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function (map) {
|
|
||||||
this.map = map
|
|
||||||
this.baseUrl = L.Util.getBaseUrl()
|
|
||||||
// Use map default, not generic default
|
|
||||||
this.queryString.onLoadPanel = this.map.options.onLoadPanel
|
|
||||||
},
|
|
||||||
|
|
||||||
getMap: function () {
|
|
||||||
return this.map
|
|
||||||
},
|
|
||||||
|
|
||||||
buildUrl: function (options) {
|
|
||||||
const datalayers = []
|
|
||||||
if (this.options.viewCurrentFeature && this.map.currentFeature) {
|
|
||||||
this.queryString.feature = this.map.currentFeature.getSlug()
|
|
||||||
}
|
|
||||||
if (this.options.keepCurrentDatalayers) {
|
|
||||||
this.map.eachDataLayer((datalayer) => {
|
|
||||||
if (datalayer.isVisible() && datalayer.umap_id) {
|
|
||||||
datalayers.push(datalayer.umap_id)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.queryString.datalayers = datalayers.join(',')
|
|
||||||
} else {
|
|
||||||
delete this.queryString.datalayers
|
|
||||||
}
|
|
||||||
const currentView = this.options.currentView ? window.location.hash : ''
|
|
||||||
const queryString = L.extend({}, this.queryString, options)
|
|
||||||
return `${this.baseUrl}?${L.Util.buildQueryString(queryString)}${currentView}`
|
|
||||||
},
|
|
||||||
|
|
||||||
build: function () {
|
|
||||||
const iframeUrl = this.buildUrl()
|
|
||||||
let code = `<iframe width="${this.dimensions.width}" height="${this.dimensions.height}" frameborder="0" allowfullscreen allow="geolocation" src="${iframeUrl}"></iframe>`
|
|
||||||
if (this.options.includeFullScreenLink) {
|
|
||||||
const fullUrl = this.buildUrl({ scrollWheelZoom: true })
|
|
||||||
code += `<p><a href="${fullUrl}">${L._('See full screen')}</a></p>`
|
|
||||||
}
|
|
||||||
return code
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
L.U.Editable = L.Editable.extend({
|
L.U.Editable = L.Editable.extend({
|
||||||
initialize: function (map, options) {
|
initialize: function (map, options) {
|
||||||
L.Editable.prototype.initialize.call(this, map, options)
|
L.Editable.prototype.initialize.call(this, map, options)
|
||||||
|
|
|
@ -259,7 +259,7 @@ L.U.Map.include({
|
||||||
}
|
}
|
||||||
this.initShortcuts()
|
this.initShortcuts()
|
||||||
this.onceDataLoaded(function () {
|
this.onceDataLoaded(function () {
|
||||||
if (L.Util.queryString('share')) this.renderShareBox()
|
if (L.Util.queryString('share')) this.share.open()
|
||||||
else if (this.options.onLoadPanel === 'databrowser') this.openBrowser()
|
else if (this.options.onLoadPanel === 'databrowser') this.openBrowser()
|
||||||
else if (this.options.onLoadPanel === 'caption') this.displayCaption()
|
else if (this.options.onLoadPanel === 'caption') this.displayCaption()
|
||||||
else if (
|
else if (
|
||||||
|
@ -352,6 +352,7 @@ L.U.Map.include({
|
||||||
this.browser = new L.U.Browser(this)
|
this.browser = new L.U.Browser(this)
|
||||||
this.importer = new L.U.Importer(this)
|
this.importer = new L.U.Importer(this)
|
||||||
this.drop = new L.U.DropControl(this)
|
this.drop = new L.U.DropControl(this)
|
||||||
|
this.share = new L.U.Share(this)
|
||||||
this._controls.tilelayers = new L.U.TileLayerControl(this)
|
this._controls.tilelayers = new L.U.TileLayerControl(this)
|
||||||
this._controls.tilelayers.setLayers()
|
this._controls.tilelayers.setLayers()
|
||||||
|
|
||||||
|
@ -853,28 +854,6 @@ L.U.Map.include({
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
format: function (mode) {
|
|
||||||
const type = this.EXPORT_TYPES[mode]
|
|
||||||
const content = type.formatter(this)
|
|
||||||
let name = this.options.name || 'data'
|
|
||||||
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
|
|
||||||
const filename = name + type.ext
|
|
||||||
return { content, filetype: type.filetype, filename }
|
|
||||||
},
|
|
||||||
|
|
||||||
download: function (mode) {
|
|
||||||
const { content, filetype, filename } = this.format(mode)
|
|
||||||
const blob = new Blob([content], { type: filetype })
|
|
||||||
window.URL = window.URL || window.webkitURL
|
|
||||||
const el = document.createElement('a')
|
|
||||||
el.download = filename
|
|
||||||
el.href = window.URL.createObjectURL(blob)
|
|
||||||
el.style.display = 'none'
|
|
||||||
document.body.appendChild(el)
|
|
||||||
el.click()
|
|
||||||
document.body.removeChild(el)
|
|
||||||
},
|
|
||||||
|
|
||||||
processFileToImport: function (file, layer, type) {
|
processFileToImport: function (file, layer, type) {
|
||||||
type = type || L.Util.detectFileType(file)
|
type = type || L.Util.detectFileType(file)
|
||||||
if (!type) {
|
if (!type) {
|
||||||
|
@ -1706,9 +1685,9 @@ L.U.Map.include({
|
||||||
L.DomUtil.createButton(
|
L.DomUtil.createButton(
|
||||||
'button umap-download',
|
'button umap-download',
|
||||||
advancedButtons,
|
advancedButtons,
|
||||||
L._('Open download panel'),
|
L._('Open share & download panel'),
|
||||||
this.renderShareBox,
|
this.share.open,
|
||||||
this
|
this.share
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
271
umap/static/umap/js/umap.share.js
Normal file
271
umap/static/umap/js/umap.share.js
Normal file
|
@ -0,0 +1,271 @@
|
||||||
|
L.U.Share = L.Class.extend({
|
||||||
|
EXPORT_TYPES: {
|
||||||
|
geojson: {
|
||||||
|
formatter: function (map) {
|
||||||
|
return JSON.stringify(map.toGeoJSON(), null, 2)
|
||||||
|
},
|
||||||
|
ext: '.geojson',
|
||||||
|
filetype: 'application/json',
|
||||||
|
},
|
||||||
|
gpx: {
|
||||||
|
formatter: function (map) {
|
||||||
|
return togpx(map.toGeoJSON())
|
||||||
|
},
|
||||||
|
ext: '.gpx',
|
||||||
|
filetype: 'application/gpx+xml',
|
||||||
|
},
|
||||||
|
kml: {
|
||||||
|
formatter: function (map) {
|
||||||
|
return tokml(map.toGeoJSON())
|
||||||
|
},
|
||||||
|
ext: '.kml',
|
||||||
|
filetype: 'application/vnd.google-earth.kml+xml',
|
||||||
|
},
|
||||||
|
csv: {
|
||||||
|
formatter: function (map) {
|
||||||
|
const table = []
|
||||||
|
map.eachFeature((feature) => {
|
||||||
|
const row = feature.toGeoJSON()['properties'],
|
||||||
|
center = feature.getCenter()
|
||||||
|
delete row['_umap_options']
|
||||||
|
row['Latitude'] = center.lat
|
||||||
|
row['Longitude'] = center.lng
|
||||||
|
table.push(row)
|
||||||
|
})
|
||||||
|
return csv2geojson.dsv.csvFormat(table)
|
||||||
|
},
|
||||||
|
ext: '.csv',
|
||||||
|
filetype: 'text/csv',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function (map) {
|
||||||
|
this.map = map
|
||||||
|
},
|
||||||
|
|
||||||
|
build: function () {
|
||||||
|
this.container = L.DomUtil.create('div', 'umap-share')
|
||||||
|
this.title = L.DomUtil.create('h3', '', this.container)
|
||||||
|
this.title.textContent = L._('Share and download')
|
||||||
|
|
||||||
|
L.DomUtil.createButton(
|
||||||
|
'button copy-button',
|
||||||
|
this.container,
|
||||||
|
L._('copy'),
|
||||||
|
() => navigator.clipboard.writeText(this.mapUrl.value),
|
||||||
|
this
|
||||||
|
)
|
||||||
|
const mapUrlLabel = L.DomUtil.add(
|
||||||
|
'label',
|
||||||
|
'',
|
||||||
|
this.container,
|
||||||
|
L._('Link to view the map')
|
||||||
|
)
|
||||||
|
this.mapUrl = L.DomUtil.create('input', 'umap-share-url', mapUrlLabel)
|
||||||
|
this.mapUrl.type = 'text'
|
||||||
|
this.mapUrl.readOnly = true
|
||||||
|
this.mapUrl.value = window.location.protocol + L.Util.getBaseUrl()
|
||||||
|
|
||||||
|
if (this.map.options.shortUrl) {
|
||||||
|
L.DomUtil.createButton(
|
||||||
|
'button copy-button',
|
||||||
|
this.container,
|
||||||
|
L._('copy'),
|
||||||
|
() => navigator.clipboard.writeText(this.shortUrl.value),
|
||||||
|
this
|
||||||
|
)
|
||||||
|
const shortUrlLabel = L.DomUtil.create('label', '', this.container)
|
||||||
|
shortUrlLabel.textContent = L._('Short link')
|
||||||
|
this.shortUrl = L.DomUtil.create('input', 'umap-share-url', shortUrlLabel)
|
||||||
|
this.shortUrl.type = 'text'
|
||||||
|
this.shortUrl.readOnly = true
|
||||||
|
this.shortUrl.value = this.map.options.shortUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
L.DomUtil.create('hr', '', this.container)
|
||||||
|
|
||||||
|
L.DomUtil.add('h4', '', this.container, L._('Download'))
|
||||||
|
L.DomUtil.add('small', 'label', this.container, L._("Only visible layers' data"))
|
||||||
|
for (const key in this.EXPORT_TYPES) {
|
||||||
|
if (this.EXPORT_TYPES.hasOwnProperty(key)) {
|
||||||
|
L.DomUtil.createButton(
|
||||||
|
'download-file',
|
||||||
|
this.container,
|
||||||
|
this.EXPORT_TYPES[key].name || key,
|
||||||
|
() => this.download(key),
|
||||||
|
this
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
L.DomUtil.create('div', 'vspace', this.container)
|
||||||
|
L.DomUtil.add(
|
||||||
|
'small',
|
||||||
|
'label',
|
||||||
|
this.container,
|
||||||
|
L._('All data and settings of the map')
|
||||||
|
)
|
||||||
|
const downloadUrl = L.Util.template(this.map.options.urls.map_download, {
|
||||||
|
map_id: this.map.options.umap_id,
|
||||||
|
})
|
||||||
|
const link = L.DomUtil.createLink(
|
||||||
|
'download-backup',
|
||||||
|
this.container,
|
||||||
|
L._('full backup'),
|
||||||
|
downloadUrl
|
||||||
|
)
|
||||||
|
let name = this.map.options.name || 'data'
|
||||||
|
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
|
||||||
|
link.setAttribute('download', `${name}.umap`)
|
||||||
|
L.DomUtil.create('hr', '', this.container)
|
||||||
|
|
||||||
|
const embedTitle = L.DomUtil.add('h4', '', this.container, L._('Embed the map'))
|
||||||
|
const iframe = L.DomUtil.create('textarea', 'umap-share-iframe', this.container)
|
||||||
|
const urlTitle = L.DomUtil.add('h4', '', this.container, L._('Direct link'))
|
||||||
|
const shortUrlLabel = L.DomUtil.create('label', '', this.container)
|
||||||
|
shortUrlLabel.textContent = L._('Share this link to open a customized map view')
|
||||||
|
const exportUrl = L.DomUtil.create('input', 'umap-share-url', this.container)
|
||||||
|
exportUrl.type = 'text'
|
||||||
|
const UIFields = [
|
||||||
|
['dimensions.width', { handler: 'Input', label: L._('width') }],
|
||||||
|
['dimensions.height', { handler: 'Input', label: L._('height') }],
|
||||||
|
[
|
||||||
|
'options.includeFullScreenLink',
|
||||||
|
{ handler: 'Switch', label: L._('Include full screen link?') },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'options.currentView',
|
||||||
|
{ handler: 'Switch', label: L._('Current view instead of default map view?') },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'options.keepCurrentDatalayers',
|
||||||
|
{ handler: 'Switch', label: L._('Keep current visible layers') },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'options.viewCurrentFeature',
|
||||||
|
{ handler: 'Switch', label: L._('Open current feature on load') },
|
||||||
|
],
|
||||||
|
'queryString.moreControl',
|
||||||
|
'queryString.scrollWheelZoom',
|
||||||
|
'queryString.miniMap',
|
||||||
|
'queryString.scaleControl',
|
||||||
|
'queryString.onLoadPanel',
|
||||||
|
'queryString.captionBar',
|
||||||
|
'queryString.captionMenus',
|
||||||
|
]
|
||||||
|
for (let i = 0; i < this.map.HIDDABLE_CONTROLS.length; i++) {
|
||||||
|
UIFields.push(`queryString.${this.map.HIDDABLE_CONTROLS[i]}Control`)
|
||||||
|
}
|
||||||
|
const iframeExporter = new L.U.IframeExporter(this.map)
|
||||||
|
const buildIframeCode = () => {
|
||||||
|
iframe.innerHTML = iframeExporter.build()
|
||||||
|
exportUrl.value = window.location.protocol + iframeExporter.buildUrl()
|
||||||
|
}
|
||||||
|
buildIframeCode()
|
||||||
|
const builder = new L.U.FormBuilder(iframeExporter, UIFields, {
|
||||||
|
callback: buildIframeCode,
|
||||||
|
})
|
||||||
|
const iframeOptions = L.DomUtil.createFieldset(
|
||||||
|
this.container,
|
||||||
|
L._('Embed and link options')
|
||||||
|
)
|
||||||
|
iframeOptions.appendChild(builder.build())
|
||||||
|
},
|
||||||
|
|
||||||
|
open: function () {
|
||||||
|
if (!this.container) this.build()
|
||||||
|
this.map.ui.openPanel({ data: { html: this.container } })
|
||||||
|
},
|
||||||
|
|
||||||
|
format: function (mode) {
|
||||||
|
const type = this.EXPORT_TYPES[mode]
|
||||||
|
const content = type.formatter(this.map)
|
||||||
|
let name = this.map.options.name || 'data'
|
||||||
|
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
|
||||||
|
const filename = name + type.ext
|
||||||
|
return { content, filetype: type.filetype, filename }
|
||||||
|
},
|
||||||
|
|
||||||
|
download: function (mode) {
|
||||||
|
const { content, filetype, filename } = this.format(mode)
|
||||||
|
const blob = new Blob([content], { type: filetype })
|
||||||
|
window.URL = window.URL || window.webkitURL
|
||||||
|
const el = document.createElement('a')
|
||||||
|
el.download = filename
|
||||||
|
el.href = window.URL.createObjectURL(blob)
|
||||||
|
el.style.display = 'none'
|
||||||
|
document.body.appendChild(el)
|
||||||
|
el.click()
|
||||||
|
document.body.removeChild(el)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
L.U.IframeExporter = L.Evented.extend({
|
||||||
|
options: {
|
||||||
|
includeFullScreenLink: true,
|
||||||
|
currentView: false,
|
||||||
|
keepCurrentDatalayers: false,
|
||||||
|
viewCurrentFeature: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
queryString: {
|
||||||
|
scaleControl: false,
|
||||||
|
miniMap: false,
|
||||||
|
scrollWheelZoom: false,
|
||||||
|
zoomControl: true,
|
||||||
|
editMode: 'disabled',
|
||||||
|
moreControl: true,
|
||||||
|
searchControl: null,
|
||||||
|
tilelayersControl: null,
|
||||||
|
embedControl: null,
|
||||||
|
datalayersControl: true,
|
||||||
|
onLoadPanel: 'none',
|
||||||
|
captionBar: false,
|
||||||
|
captionMenus: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
dimensions: {
|
||||||
|
width: '100%',
|
||||||
|
height: '300px',
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function (map) {
|
||||||
|
this.map = map
|
||||||
|
this.baseUrl = L.Util.getBaseUrl()
|
||||||
|
// Use map default, not generic default
|
||||||
|
this.queryString.onLoadPanel = this.map.options.onLoadPanel
|
||||||
|
},
|
||||||
|
|
||||||
|
getMap: function () {
|
||||||
|
return this.map
|
||||||
|
},
|
||||||
|
|
||||||
|
buildUrl: function (options) {
|
||||||
|
const datalayers = []
|
||||||
|
if (this.options.viewCurrentFeature && this.map.currentFeature) {
|
||||||
|
this.queryString.feature = this.map.currentFeature.getSlug()
|
||||||
|
}
|
||||||
|
if (this.options.keepCurrentDatalayers) {
|
||||||
|
this.map.eachDataLayer((datalayer) => {
|
||||||
|
if (datalayer.isVisible() && datalayer.umap_id) {
|
||||||
|
datalayers.push(datalayer.umap_id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.queryString.datalayers = datalayers.join(',')
|
||||||
|
} else {
|
||||||
|
delete this.queryString.datalayers
|
||||||
|
}
|
||||||
|
const currentView = this.options.currentView ? window.location.hash : ''
|
||||||
|
const queryString = L.extend({}, this.queryString, options)
|
||||||
|
return `${this.baseUrl}?${L.Util.buildQueryString(queryString)}${currentView}`
|
||||||
|
},
|
||||||
|
|
||||||
|
build: function () {
|
||||||
|
const iframeUrl = this.buildUrl()
|
||||||
|
let code = `<iframe width="${this.dimensions.width}" height="${this.dimensions.height}" frameborder="0" allowfullscreen allow="geolocation" src="${iframeUrl}"></iframe>`
|
||||||
|
if (this.options.includeFullScreenLink) {
|
||||||
|
const fullUrl = this.buildUrl({ scrollWheelZoom: true })
|
||||||
|
code += `<p><a href="${fullUrl}">${L._('See full screen')}</a></p>`
|
||||||
|
}
|
||||||
|
return code
|
||||||
|
},
|
||||||
|
})
|
|
@ -239,6 +239,39 @@ ul.photon-autocomplete {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ***************************** */
|
||||||
|
/* Share and download panel */
|
||||||
|
/* ***************************** */
|
||||||
|
.download-file {
|
||||||
|
height: 1.2em;
|
||||||
|
min-height: 1.2em;
|
||||||
|
padding: 0;
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
.download-file:before,
|
||||||
|
.download-backup:before {
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-image: url('./img/16.svg');
|
||||||
|
background-size: auto auto;
|
||||||
|
background-position: -4px -145px;
|
||||||
|
content: " ";
|
||||||
|
vertical-align: bottom;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.download-backup:before {
|
||||||
|
background-position: -27px -144px;
|
||||||
|
}
|
||||||
|
.leaflet-container .download-backup {
|
||||||
|
color: black;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.vspace {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
/* *********** */
|
/* *********** */
|
||||||
/* Draw */
|
/* Draw */
|
||||||
/* *********** */
|
/* *********** */
|
||||||
|
|
|
@ -20,7 +20,7 @@ describe('L.U.Map.Export', function () {
|
||||||
|
|
||||||
describe('#formatters()', function () {
|
describe('#formatters()', function () {
|
||||||
it('should export to geojson', function () {
|
it('should export to geojson', function () {
|
||||||
const { content, filetype, filename } = this.map.format('geojson')
|
const { content, filetype, filename } = this.map.share.format('geojson')
|
||||||
assert.equal(filetype, 'application/json')
|
assert.equal(filetype, 'application/json')
|
||||||
assert.equal(filename, 'name_of_the_map.geojson')
|
assert.equal(filename, 'name_of_the_map.geojson')
|
||||||
assert.deepEqual(JSON.parse(content), {
|
assert.deepEqual(JSON.parse(content), {
|
||||||
|
@ -86,7 +86,7 @@ describe('L.U.Map.Export', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should export to gpx', function () {
|
it('should export to gpx', function () {
|
||||||
const { content, filetype, filename } = this.map.format('gpx')
|
const { content, filetype, filename } = this.map.share.format('gpx')
|
||||||
assert.equal(filetype, 'application/gpx+xml')
|
assert.equal(filetype, 'application/gpx+xml')
|
||||||
assert.equal(filename, 'name_of_the_map.gpx')
|
assert.equal(filename, 'name_of_the_map.gpx')
|
||||||
const expected =
|
const expected =
|
||||||
|
@ -95,7 +95,7 @@ describe('L.U.Map.Export', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should export to kml', function () {
|
it('should export to kml', function () {
|
||||||
const { content, filetype, filename } = this.map.format('kml')
|
const { content, filetype, filename } = this.map.share.format('kml')
|
||||||
assert.equal(filetype, 'application/vnd.google-earth.kml+xml')
|
assert.equal(filetype, 'application/vnd.google-earth.kml+xml')
|
||||||
assert.equal(filename, 'name_of_the_map.kml')
|
assert.equal(filename, 'name_of_the_map.kml')
|
||||||
const expected =
|
const expected =
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
<script src="../js/umap.datalayer.permissions.js"></script>
|
<script src="../js/umap.datalayer.permissions.js"></script>
|
||||||
<script src="../js/umap.browser.js"></script>
|
<script src="../js/umap.browser.js"></script>
|
||||||
<script src="../js/umap.importer.js"></script>
|
<script src="../js/umap.importer.js"></script>
|
||||||
|
<script src="../js/umap.share.js"></script>
|
||||||
<script src="../js/umap.js"></script>
|
<script src="../js/umap.js"></script>
|
||||||
<script src="../js/umap.ui.js"></script>
|
<script src="../js/umap.ui.js"></script>
|
||||||
<link rel="stylesheet" href="../vendors/leaflet/leaflet.css" />
|
<link rel="stylesheet" href="../vendors/leaflet/leaflet.css" />
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
<script src="{{ STATIC_URL }}umap/js/umap.tableeditor.js"></script>
|
<script src="{{ STATIC_URL }}umap/js/umap.tableeditor.js"></script>
|
||||||
<script src="{{ STATIC_URL }}umap/js/umap.browser.js"></script>
|
<script src="{{ STATIC_URL }}umap/js/umap.browser.js"></script>
|
||||||
<script src="{{ STATIC_URL }}umap/js/umap.importer.js"></script>
|
<script src="{{ STATIC_URL }}umap/js/umap.importer.js"></script>
|
||||||
|
<script src="{{ STATIC_URL }}umap/js/umap.share.js"></script>
|
||||||
<script src="{{ STATIC_URL }}umap/js/umap.js"></script>
|
<script src="{{ STATIC_URL }}umap/js/umap.js"></script>
|
||||||
<script src="{{ STATIC_URL }}umap/js/umap.ui.js"></script>
|
<script src="{{ STATIC_URL }}umap/js/umap.ui.js"></script>
|
||||||
{% endcompress %}
|
{% endcompress %}
|
||||||
|
|
|
@ -9,7 +9,7 @@ pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
def test_umap_export(map, live_server, datalayer, page):
|
def test_umap_export(map, live_server, datalayer, page):
|
||||||
page.goto(f"{live_server.url}{map.get_absolute_url()}?share")
|
page.goto(f"{live_server.url}{map.get_absolute_url()}?share")
|
||||||
link = page.get_by_role("link", name="Download full data")
|
link = page.get_by_role("link", name="full backup")
|
||||||
expect(link).to_be_visible()
|
expect(link).to_be_visible()
|
||||||
with page.expect_download() as download_info:
|
with page.expect_download() as download_info:
|
||||||
link.click()
|
link.click()
|
||||||
|
@ -73,9 +73,8 @@ def test_umap_export(map, live_server, datalayer, page):
|
||||||
|
|
||||||
def test_csv_export(map, live_server, datalayer, page):
|
def test_csv_export(map, live_server, datalayer, page):
|
||||||
page.goto(f"{live_server.url}{map.get_absolute_url()}?share")
|
page.goto(f"{live_server.url}{map.get_absolute_url()}?share")
|
||||||
button = page.get_by_role("button", name="Download data")
|
button = page.get_by_role("button", name="csv")
|
||||||
expect(button).to_be_visible()
|
expect(button).to_be_visible()
|
||||||
page.locator('select[name="format"]').select_option("csv")
|
|
||||||
with page.expect_download() as download_info:
|
with page.expect_download() as download_info:
|
||||||
button.click()
|
button.click()
|
||||||
download = download_info.value
|
download = download_info.value
|
||||||
|
|
Loading…
Reference in a new issue