chore: add custom prompt

This commit is contained in:
Yohan Boniface 2024-07-01 18:54:06 +02:00
parent 796865314a
commit 186025e0f0
7 changed files with 71 additions and 24 deletions

View file

@ -11,6 +11,8 @@
color: var(--text-color); color: var(--text-color);
border-radius: 5px; border-radius: 5px;
overflow-y: auto; overflow-y: auto;
height: fit-content;
max-height: 90vh;
} }
.umap-dialog .umap-close-link { .umap-dialog .umap-close-link {
float: right; float: right;

View file

@ -14,7 +14,7 @@ import { HTTPError, NOKError, Request, RequestError, ServerRequest } from './req
import Rules from './rules.js' import Rules from './rules.js'
import { SCHEMA } from './schema.js' import { SCHEMA } from './schema.js'
import { SyncEngine } from './sync/engine.js' import { SyncEngine } from './sync/engine.js'
import Dialog from './ui/dialog.js' import { Dialog, Prompt } from './ui/dialog.js'
import { EditPanel, FullPanel, Panel } from './ui/panel.js' import { EditPanel, FullPanel, Panel } from './ui/panel.js'
import Tooltip from './ui/tooltip.js' import Tooltip from './ui/tooltip.js'
import URLs from './urls.js' import URLs from './urls.js'
@ -42,6 +42,7 @@ window.U = {
NOKError, NOKError,
Orderable, Orderable,
Panel, Panel,
Prompt,
Request, Request,
RequestError, RequestError,
Rules, Rules,

View file

@ -165,6 +165,7 @@ const ENTRIES = {
export default class Help { export default class Help {
constructor(map) { constructor(map) {
this.map = map this.map = map
this.dialog = new U.Dialog()
this.isMacOS = /mac/i.test( this.isMacOS = /mac/i.test(
// eslint-disable-next-line compat/compat -- Fallback available. // eslint-disable-next-line compat/compat -- Fallback available.
navigator.userAgentData ? navigator.userAgentData.platform : navigator.platform navigator.userAgentData ? navigator.userAgentData.platform : navigator.platform
@ -207,7 +208,7 @@ export default class Help {
}) })
} }
} }
this.map.dialog.open({ content: container, className: 'dark' }) this.dialog.open({ content: container, className: 'dark' })
} }
button(container, entries, classname) { button(container, entries, classname) {
@ -241,10 +242,10 @@ export default class Help {
const actionsContainer = DomUtil.create('ul', 'umap-edit-actions', container) const actionsContainer = DomUtil.create('ul', 'umap-edit-actions', container)
const addAction = (action) => { const addAction = (action) => {
const actionContainer = DomUtil.add('li', '', actionsContainer) const actionContainer = DomUtil.add('li', '', actionsContainer)
DomUtil.add('i', action.options.className, actionContainer), DomUtil.add('i', action.options.className, actionContainer)
DomUtil.add('span', '', actionContainer, action.options.tooltip) DomUtil.add('span', '', actionContainer, action.options.tooltip)
DomEvent.on(actionContainer, 'click', action.addHooks, action) DomEvent.on(actionContainer, 'click', action.addHooks, action)
DomEvent.on(actionContainer, 'click', this.map.dialog.close, this.map.dialog) DomEvent.on(actionContainer, 'click', this.dialog.close, this.map.dialog)
} }
title.textContent = translate('Where do we go from here?') title.textContent = translate('Where do we go from here?')
for (const id in this.map.helpMenuActions) { for (const id in this.map.helpMenuActions) {

View file

@ -2,7 +2,7 @@ import { DomEvent, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
import { uMapAlert as Alert } from '../components/alerts/alert.js' import { uMapAlert as Alert } from '../components/alerts/alert.js'
import { translate } from './i18n.js' import { translate } from './i18n.js'
import { SCHEMA } from './schema.js' import { SCHEMA } from './schema.js'
import Dialog from './ui/dialog.js' import { Dialog } from './ui/dialog.js'
import * as Utils from './utils.js' import * as Utils from './utils.js'
const TEMPLATE = ` const TEMPLATE = `
@ -53,7 +53,7 @@ export default class Importer {
this.TYPES = ['geojson', 'csv', 'gpx', 'kml', 'osm', 'georss', 'umap'] this.TYPES = ['geojson', 'csv', 'gpx', 'kml', 'osm', 'georss', 'umap']
this.IMPORTERS = [] this.IMPORTERS = []
this.loadImporters() this.loadImporters()
this.dialog = new Dialog(this.map._controlContainer) this.dialog = new Dialog()
} }
loadImporters() { loadImporters() {

View file

@ -1,11 +1,10 @@
import { DomEvent, DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js' import { DomEvent, DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
import { translate } from '../i18n.js' import { translate } from '../i18n.js'
export default class Dialog { export class Dialog {
constructor(parent) { constructor() {
this.parent = parent
this.className = 'umap-dialog window' this.className = 'umap-dialog window'
this.container = DomUtil.create('dialog', this.className, this.parent) this.container = DomUtil.create('dialog', this.className, document.body)
DomEvent.disableClickPropagation(this.container) DomEvent.disableClickPropagation(this.container)
DomEvent.on(this.container, 'contextmenu', DomEvent.stopPropagation) // Do not activate our custom context menu. DomEvent.on(this.container, 'contextmenu', DomEvent.stopPropagation) // Do not activate our custom context menu.
DomEvent.on(this.container, 'wheel', DomEvent.stopPropagation) DomEvent.on(this.container, 'wheel', DomEvent.stopPropagation)
@ -48,5 +47,45 @@ export default class Dialog {
DomEvent.on(closeButton, 'click', this.close, this) DomEvent.on(closeButton, 'click', this.close, this)
this.container.appendChild(buttonsContainer) this.container.appendChild(buttonsContainer)
this.container.appendChild(content) this.container.appendChild(content)
DomEvent.once(this.container, 'keydown', (e) => {
DomEvent.stop(e)
if (e.key === 'Escape') this.close()
})
}
}
const PROMPT = `
<form>
<h3></h3>
<input type="text" name="prompt" />
<input type="submit" value="${translate('Ok')}" />
</form>
`
export class Prompt extends Dialog {
get input() {
return this.container.querySelector('input[name="prompt"]')
}
get title() {
return this.container.querySelector('h3')
}
get form() {
return this.container.querySelector('form')
}
open({ className, title } = {}) {
const content = DomUtil.element({ tagName: 'div', safeHTML: PROMPT })
super.open({ className, content })
this.title.textContent = title
const promise = new Promise((resolve, reject) => {
DomEvent.on(this.form, 'submit', (e) => {
DomEvent.stop(e)
resolve(this.input.value)
this.close()
})
})
return promise
} }
} }

View file

@ -57,7 +57,6 @@ U.Map = L.Map.extend({
this.panel = new U.Panel(this) this.panel = new U.Panel(this)
this.tooltip = new U.Tooltip(this._controlContainer) this.tooltip = new U.Tooltip(this._controlContainer)
this.dialog = new U.Dialog(this._controlContainer)
if (this.hasEditMode()) { if (this.hasEditMode()) {
this.editPanel = new U.EditPanel(this) this.editPanel = new U.EditPanel(this)
this.fullPanel = new U.FullPanel(this) this.fullPanel = new U.FullPanel(this)
@ -539,18 +538,16 @@ U.Map = L.Map.extend({
initShortcuts: function () { initShortcuts: function () {
const globalShortcuts = function (e) { const globalShortcuts = function (e) {
if (e.key === 'Escape') { if (e.key === 'Escape') {
if (this.dialog.visible) { if (this.importer.dialog.visible) {
this.dialog.close()
} else if (this.importer.dialog.visible) {
this.importer.dialog.close() this.importer.dialog.close()
} else if (this.editEnabled && this.editTools.drawing()) { } else if (this.editEnabled && this.editTools.drawing()) {
this.editTools.stopDrawing() this.editTools.stopDrawing()
} else if (this.measureTools.enabled()) { } else if (this.measureTools.enabled()) {
this.measureTools.stopDrawing() this.measureTools.stopDrawing()
} else if (this.editPanel?.isOpen()) {
this.editPanel?.close()
} else if (this.fullPanel?.isOpen()) { } else if (this.fullPanel?.isOpen()) {
this.fullPanel?.close() this.fullPanel?.close()
} else if (this.editPanel?.isOpen()) {
this.editPanel?.close()
} else if (this.panel.isOpen()) { } else if (this.panel.isOpen()) {
this.panel.close() this.panel.close()
} }

View file

@ -89,6 +89,19 @@ U.TableEditor = L.Class.extend({
return true return true
}, },
addProperty: function () {
new U.Prompt()
.open({
className: 'dark',
title: L._('Please enter the name of the property'),
})
.then((newName) => {
if (!newName || !this.validateName(newName)) return
this.datalayer.indexProperty(newName)
this.edit()
})
},
edit: function () { edit: function () {
const id = 'tableeditor:edit' const id = 'tableeditor:edit'
this.compileProperties() this.compileProperties()
@ -102,13 +115,7 @@ U.TableEditor = L.Class.extend({
) )
const iconElement = L.DomUtil.createIcon(addButton, 'icon-add') const iconElement = L.DomUtil.createIcon(addButton, 'icon-add')
addButton.insertBefore(iconElement, addButton.firstChild) addButton.insertBefore(iconElement, addButton.firstChild)
const addProperty = function () { L.DomEvent.on(addButton, 'click', this.addProperty, this)
const newName = prompt(L._('Please enter the name of the property'))
if (!newName || !this.validateName(newName)) return
this.datalayer.indexProperty(newName)
this.edit()
}
L.DomEvent.on(addButton, 'click', addProperty, this)
this.datalayer.map.fullPanel.open({ this.datalayer.map.fullPanel.open({
content: this.table, content: this.table,
className: 'umap-table-editor', className: 'umap-table-editor',