Picto field: make sure we open on the right tab

This commit is contained in:
Yohan Boniface 2023-11-14 18:45:40 +01:00
parent 35afd02551
commit 4bfc3d6666
2 changed files with 124 additions and 30 deletions

View file

@ -537,38 +537,41 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
onDefine: function () { onDefine: function () {
this.buildTabs() this.buildTabs()
this.showSymbols() const value = this.value()
if (!value || value.startsWith('/')) this.showSymbolsTab()
else if (value.startsWith('http')) this.showURLTab()
else this.showCharsTab()
}, },
buildTabs: function () { buildTabs: function () {
const symbol = L.DomUtil.add( const symbol = L.DomUtil.add(
'button', 'button',
'flat on', 'flat tab-symbols',
this.tabsContainer, this.tabsContainer,
L._('Symbol') L._('Symbol')
), ),
char = L.DomUtil.add( char = L.DomUtil.add(
'button', 'button',
'flat', 'flat tab-chars',
this.tabsContainer, this.tabsContainer,
L._('Emoji & Character') L._('Emoji & Character')
) )
url = L.DomUtil.add('button', 'flat', this.tabsContainer, L._('URL')) url = L.DomUtil.add('button', 'flat tab-url', this.tabsContainer, L._('URL'))
toggle = (e) => {
L.DomUtil.removeClass(symbol, 'on')
L.DomUtil.removeClass(char, 'on')
L.DomUtil.removeClass(url, 'on')
L.DomUtil.addClass(e.target, 'on')
}
L.DomEvent.on(symbol, 'click', L.DomEvent.stop) L.DomEvent.on(symbol, 'click', L.DomEvent.stop)
.on(symbol, 'click', this.showSymbols, this) .on(symbol, 'click', this.showSymbolsTab, this)
.on(symbol, 'click', toggle)
L.DomEvent.on(char, 'click', L.DomEvent.stop) L.DomEvent.on(char, 'click', L.DomEvent.stop)
.on(char, 'click', this.showChars, this) .on(char, 'click', this.showCharsTab, this)
.on(char, 'click', toggle)
L.DomEvent.on(url, 'click', L.DomEvent.stop) L.DomEvent.on(url, 'click', L.DomEvent.stop)
.on(url, 'click', this.showURL, this) .on(url, 'click', this.showURLTab, this)
.on(url, 'click', toggle) },
highlightTab: function (name) {
const els = this.tabsContainer.querySelectorAll('button')
for (let el of els) {
L.DomUtil.removeClass(el, 'on')
}
let el = this.tabsContainer.querySelector(`.tab-${name}`)
L.DomUtil.addClass(el, 'on')
}, },
isUrl: function () { isUrl: function () {
@ -586,25 +589,33 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
const img = L.DomUtil.create( const img = L.DomUtil.create(
'img', 'img',
'', '',
L.DomUtil.create('div', 'umap-pictogram-choice visible', this.buttonsContainer) L.DomUtil.create(
'div',
'umap-pictogram-choice visible',
this.buttonsContainer
)
) )
img.src = this.value() img.src = this.value()
L.DomEvent.on(img, 'click', this.showSymbols, this) L.DomEvent.on(img, 'click', this.showSymbolsTab, this)
} else { } else {
const el = L.DomUtil.create( const el = L.DomUtil.create(
'span', 'span',
'', '',
L.DomUtil.create('div', 'umap-pictogram-choice visible', this.buttonsContainer) L.DomUtil.create(
'div',
'umap-pictogram-choice visible',
this.buttonsContainer
)
) )
el.textContent = this.value() el.textContent = this.value()
L.DomEvent.on(el, 'click', this.showSymbols, this) L.DomEvent.on(el, 'click', this.showSymbolsTab, this)
} }
} }
this.button = L.DomUtil.createButton( this.button = L.DomUtil.createButton(
'button action-button', 'button action-button',
this.buttonsContainer, this.buttonsContainer,
this.value() ? L._('Change') : L._('Add'), this.value() ? L._('Change') : L._('Add'),
this.showSymbols, this.onDefine,
this this
) )
}, },
@ -613,7 +624,9 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
const baseClass = 'umap-pictogram-choice visible', const baseClass = 'umap-pictogram-choice visible',
value = pictogram.src, value = pictogram.src,
search = this.searchInput.value.toLowerCase(), search = this.searchInput.value.toLowerCase(),
title = pictogram.attribution ? `${pictogram.name} — © ${pictogram.attribution}` : pictogram.name title = pictogram.attribution
? `${pictogram.name} — © ${pictogram.attribution}`
: pictogram.name
if (search && title.toLowerCase().indexOf(search) === -1) return if (search && title.toLowerCase().indexOf(search) === -1) return
const className = value === this.value() ? `${baseClass} selected` : baseClass, const className = value === this.value() ? `${baseClass} selected` : baseClass,
container = L.DomUtil.create('div', className, parent), container = L.DomUtil.create('div', className, parent),
@ -631,7 +644,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
}, },
this this
) )
return true // Icon has been added (not filtered) return true // Icon has been added (not filtered)
}, },
clear: function () { clear: function () {
@ -643,10 +656,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
}, },
addCategory: function (category, items) { addCategory: function (category, items) {
const parent = L.DomUtil.create( const parent = L.DomUtil.create('div', 'umap-pictogram-category'),
'div',
'umap-pictogram-category',
),
title = L.DomUtil.add('h6', '', parent, category), title = L.DomUtil.add('h6', '', parent, category),
grid = L.DomUtil.create('div', 'umap-pictogram-grid', parent) grid = L.DomUtil.create('div', 'umap-pictogram-grid', parent)
let status = false let status = false
@ -677,16 +687,18 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
return !this.value() || this.value() === this.obj.getMap().options.default_iconUrl return !this.value() || this.value() === this.obj.getMap().options.default_iconUrl
}, },
showChars: function () { showCharsTab: function () {
// Do not show default value here, as it's not a character // Do not show default value here, as it's not a character
// and it has not been explicitely chosen by the user. // and it has not been explicitely chosen by the user.
this.highlightTab('chars')
if (this.isDefault()) this.input.value = '' if (this.isDefault()) this.input.value = ''
this.input.type = 'text' this.input.type = 'text'
this.input.placeholder = L._('Type char or paste emoji') this.input.placeholder = L._('Type char or paste emoji')
this.pictogramsContainer.innerHTML = '' this.pictogramsContainer.innerHTML = ''
}, },
showSymbols: function () { showSymbolsTab: function () {
this.highlightTab('symbols')
this.input.type = 'hidden' this.input.type = 'hidden'
this.buttonsContainer.innerHTML = '' this.buttonsContainer.innerHTML = ''
this.searchInput = L.DomUtil.create('input', '', this.pictogramsContainer) this.searchInput = L.DomUtil.create('input', '', this.pictogramsContainer)
@ -719,7 +731,8 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
} }
}, },
showURL: function () { showURLTab: function () {
this.highlightTab('url')
this.input.type = 'url' this.input.type = 'url'
this.input.placeholder = L._('Add URL') this.input.placeholder = L._('Add URL')
this.pictogramsContainer.innerHTML = '' this.pictogramsContainer.innerHTML = ''

View file

@ -134,3 +134,84 @@ def test_can_change_picto_at_marker_level(map, live_server, page, pictos):
expect(marker).to_have_attribute("src", "/uploads/pictogram/circle.svg") expect(marker).to_have_attribute("src", "/uploads/pictogram/circle.svg")
undefine.click() undefine.click()
expect(marker).to_have_attribute("src", "/uploads/pictogram/star.svg") expect(marker).to_have_attribute("src", "/uploads/pictogram/star.svg")
def test_can_use_remote_url_as_picto(map, live_server, page, pictos):
# Faster than doing a login
map.edit_status = Map.ANONYMOUS
map.save()
DataLayerFactory(map=map, data=DATALAYER_DATA)
page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
marker = page.locator(".umap-div-icon img")
expect(marker).to_have_count(1)
# Should have default img
expect(marker).to_have_attribute("src", "/static/umap/img/marker.png")
edit_settings = page.get_by_title("Edit map settings")
expect(edit_settings).to_be_visible()
edit_settings.click()
shape_settings = page.get_by_text("Default shape properties")
expect(shape_settings).to_be_visible()
shape_settings.click()
define = page.locator(".umap-field-iconUrl .define")
expect(define).to_be_visible()
define.click()
url_tab = page.get_by_role("button", name="URL")
input_el = page.locator("input[name='iconUrl']")
expect(input_el).to_be_hidden()
expect(url_tab).to_be_visible()
url_tab.click()
expect(input_el).to_be_visible()
input_el.fill("https://foo.bar/img.jpg")
input_el.blur()
expect(marker).to_have_attribute("src", "https://foo.bar/img.jpg")
# Now close and reopen the form, it should still be the URL tab
close = page.locator("#umap-ui-container").get_by_text("Close")
expect(close).to_be_visible()
close.click()
edit_settings.click()
shape_settings.click()
modify = page.locator(".umap-field-iconUrl").get_by_text("Change")
expect(modify).to_be_visible()
modify.click()
# Should be on URL tab
expect(input_el).to_be_visible()
def test_can_use_char_as_picto(map, live_server, page, pictos):
# Faster than doing a login
map.edit_status = Map.ANONYMOUS
map.save()
DataLayerFactory(map=map, data=DATALAYER_DATA)
page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
marker = page.locator(".umap-div-icon span")
# Should have default img, so not a span
expect(marker).to_have_count(0)
edit_settings = page.get_by_title("Edit map settings")
expect(edit_settings).to_be_visible()
edit_settings.click()
shape_settings = page.get_by_text("Default shape properties")
expect(shape_settings).to_be_visible()
shape_settings.click()
define = page.locator(".umap-field-iconUrl .define")
define.click()
url_tab = page.get_by_role("button", name="Emoji & Character")
input_el = page.locator("input[name='iconUrl']")
expect(input_el).to_be_hidden()
expect(url_tab).to_be_visible()
url_tab.click()
expect(input_el).to_be_visible()
input_el.fill("")
input_el.blur()
expect(marker).to_have_count(1)
expect(marker).to_have_text("")
# Now close and reopen the form, it should still be the URL tab
close = page.locator("#umap-ui-container").get_by_text("Close")
expect(close).to_be_visible()
close.click()
edit_settings.click()
shape_settings.click()
modify = page.locator(".umap-field-iconUrl").get_by_text("Change")
expect(modify).to_be_visible()
modify.click()
# Should be on URL tab
expect(input_el).to_be_visible()