feat: display importers in a dialog instead of direclty in the form

The goal is to keep the form smaller, specifically to keep the
submit button visible as much as possible.
This commit is contained in:
Yohan Boniface 2024-12-02 19:27:06 +01:00
parent d64cdae987
commit d99fe70e36
5 changed files with 42 additions and 19 deletions

View file

@ -157,6 +157,9 @@ dt {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.grid-container.by4 {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.grid-container > * {
text-align: center;
}

View file

@ -602,3 +602,6 @@ input[type=hidden].blur + [type="button"] {
input.highlightable:not(:placeholder-shown) {
border: 1px solid var(--color-brightCyan);
}
.umap-upload [type=url] {
margin-bottom: 0;
}

View file

@ -110,6 +110,9 @@ html[dir="rtl"] .icon {
.icon-list {
background-position: var(--tile) calc(var(--tile) * 4);
}
.icon-magic {
background-position: calc(var(--tile) * 7) 0;
}
.icon-marker {
background-position: calc(var(--tile) * 3) calc(var(--tile) * 5);
}

View file

@ -11,13 +11,9 @@ const TEMPLATE = `
<fieldset class="formbox">
<legend class="counter">${translate('Choose data')}</legend>
<input type="file" multiple autofocus onchange />
<input class="highlightable" type="url" placeholder="${translate('Provide an URL here')}" onchange />
<textarea onchange placeholder="${translate('Paste your data here')}"></textarea>
<div class="importers" hidden>
<h4>${translate('Import helpers:')}</h4>
<ul class="grid-container">
</ul>
</div>
<input class="highlightable" type="url" placeholder="${translate('Provide an URL here')}" onchange />
<button class="flat importers" hidden data-ref="importersButton"><i class="icon icon-16 icon-magic"></i>${translate('Import helpers')}</button>
</fieldset>
<fieldset class="formbox">
<legend class="counter" data-help="importFormats">${translate(
@ -49,6 +45,14 @@ const TEMPLATE = `
</div>
`
const GRID_TEMPLATE = `
<div>
<h3><i class="icon icon-16 icon-magic"></i>${translate('Import helpers')}</h3>
<p>${translate('Import helpers will fill the URL field for you.')}</p>
<ul class="grid-container by4" data-ref="grid"></ul>
</div>
`
export default class Importer extends Utils.WithTemplate {
constructor(umap) {
super()
@ -56,7 +60,7 @@ export default class Importer extends Utils.WithTemplate {
this.TYPES = ['geojson', 'csv', 'gpx', 'kml', 'osm', 'georss', 'umap']
this.IMPORTERS = []
this.loadImporters()
this.dialog = new Dialog()
this.dialog = new Dialog({ className: 'importers dark' })
}
loadImporters() {
@ -149,20 +153,26 @@ export default class Importer extends Utils.WithTemplate {
)
}
showImporters() {
if (!this.IMPORTERS.length) return
const [element, { grid }] = Utils.loadTemplateWithRefs(GRID_TEMPLATE)
for (const plugin of this.IMPORTERS.sort((a, b) => (a.id > b.id ? 1 : -1))) {
const button = Utils.loadTemplate(
`<li><button type="button" class="${plugin.id}">${plugin.name}</button></li>`
)
button.addEventListener('click', () => plugin.open(this))
grid.appendChild(button)
}
this.dialog.open({ template: element, cancel: false, accept: false })
}
build() {
this.container = DomUtil.create('div', 'umap-upload')
this.container.innerHTML = TEMPLATE
this.container = this.loadTemplate(TEMPLATE)
if (this.IMPORTERS.length) {
const parent = this.container.querySelector('.importers ul')
for (const plugin of this.IMPORTERS.sort((a, b) => (a.id > b.id ? 1 : -1))) {
L.DomUtil.createButton(
plugin.id,
DomUtil.element({ tagName: 'li', parent }),
plugin.name,
() => plugin.open(this)
)
}
this.qs('.importers').toggleAttribute('hidden', false)
// TODO use this.elements instead of this.qs
const button = this.qs('[data-ref=importersButton]')
button.addEventListener('click', () => this.showImporters())
button.toggleAttribute('hidden', false)
}
for (const type of this.TYPES) {
DomUtil.element({

View file

@ -607,6 +607,7 @@ def test_overpass_import_with_bbox(page, live_server, tilelayer, settings):
}
page.goto(f"{live_server.url}/map/new/")
page.get_by_role("link", name="Import data").click()
page.get_by_role("button", name="Import helpers").click()
page.get_by_role("button", name="Overpass").click()
page.get_by_placeholder("amenity=drinking_water").fill("building")
page.get_by_role("button", name="Choose this data").click()
@ -657,6 +658,7 @@ def test_overpass_import_retains_boundary(page, live_server, tilelayer, settings
page.route(re.compile("https://foobar.io/api.*"), handle)
page.goto(f"{live_server.url}/map/new/")
page.get_by_role("link", name="Import data").click()
page.get_by_role("button", name="Import helpers").click()
page.get_by_role("button", name="Overpass").click()
page.get_by_placeholder("amenity=drinking_water").fill("building")
page.get_by_placeholder("Type area name, or let empty").click()
@ -669,6 +671,7 @@ def test_overpass_import_retains_boundary(page, live_server, tilelayer, settings
expect(page.get_by_placeholder("Provide an URL here")).to_have_value(
"https://my.overpass.io/interpreter?data=[out:json];nwr[building](area:3601393025);out geom;"
)
page.get_by_role("button", name="Import helpers").click()
page.get_by_role("button", name="Overpass").click()
expect(page.locator("#area")).to_contain_text(
"Bray-sur-Seine, Seine-et-Marne, Île-de-France, France"
@ -710,6 +713,7 @@ def test_import_from_datasets(page, live_server, tilelayer, settings):
page.goto(f"{live_server.url}/map/new/")
expect(page.locator(".leaflet-marker-icon")).to_be_hidden()
page.get_by_role("link", name="Import data").click()
page.get_by_role("button", name="Import helpers").click()
page.get_by_role("button", name="Datasets").click()
page.get_by_role("dialog").get_by_role("combobox").select_option(
"https://remote.org/data.json"