Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync fields; Geometry edit updates; Boolean Fields #993

Merged
merged 6 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 30 additions & 28 deletions lib/location/decorate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default location => {
removeCallbacks: [],
trash,
update,
syncFields,
mvt_cache,
updateCallbacks: [],
})
Expand Down Expand Up @@ -64,49 +65,50 @@ async function update() {
});

await this.mvt_cache()

let dependents = this.infoj
.filter(entry => typeof entry.newValue !== 'undefined')
.filter(entry => entry.dependents && entry.dependents.length)
.map(entry => entry.dependents)
.flat()

this.infoj
// Update entry.values with newValues.
// Return dependents from updated entries.
const dependents = this.infoj
.filter(entry => typeof entry.newValue !== 'undefined')
.forEach(entry => {
.map(entry => {

entry.value = entry.newValue;
delete entry.newValue;

return entry.dependents
})

if (dependents.length) {

const response = await mapp.utils.xhr(
`${this.layer.mapview.host}/api/location/get?` +
mapp.utils.paramString({
locale: this.layer.mapview.locale.key,
layer: this.layer.key,
table: this.table,
id: this.id,
fields: [...new Set(dependents)].join(),
})
);

this.infoj
.filter(entry => typeof response[entry.field] !== 'undefined')
.forEach(entry => {
entry.value = response[entry.field];
})
.flat()
.filter(dependents => dependents !== undefined)

}
// sync dependent fields
if (dependents.length) await this.syncFields([...new Set(dependents)])

// Reload layer.
this.layer.reload()

this.updateCallbacks?.forEach(fn => typeof fn === 'function' && fn(this))
}

async function syncFields(fields) {

const response = await mapp.utils.xhr(
`${this.layer.mapview.host}/api/location/get?` +
mapp.utils.paramString({
locale: this.layer.mapview.locale.key,
layer: this.layer.key,
table: this.table,
id: this.id,
fields: fields.join(),
})
);

this.infoj
.filter(entry => typeof response[entry.field] !== 'undefined')
.forEach(entry => {
entry.value = response[entry.field];
})
}

function flyTo (maxZoom) {

const sourceVector = new ol.source.Vector();
Expand Down
35 changes: 21 additions & 14 deletions lib/ui/locations/entries/boolean.mjs
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
export default entry => {

const chkbox = mapp.ui.elements.chkbox({
label: entry.label || entry.title,
checked: entry.value,
disabled: !entry.edit,
onchange: (checked) => {
if (entry.edit) {

entry.newValue = checked
entry.location.view?.dispatchEvent(
new CustomEvent('valChange', {
detail: entry
}))
return mapp.ui.elements.chkbox({
label: entry.label || entry.title,
checked: entry.newValue !== undefined ? entry.newValue: entry.value,
disabled: !entry.edit,
onchange: (checked) => {

}
})
entry.newValue = checked
entry.location.view?.dispatchEvent(
new CustomEvent('valChange', {
detail: entry
}))

}
})

const node = mapp.utils.html.node`${chkbox}`
}

return node
const icon = `mask-icon ${entry.value? 'done': 'close'}`

return mapp.utils.html.node`
<div class="link-with-img">
<div class=${icon}></div>
<span>${entry.label || entry.field}`
}
29 changes: 15 additions & 14 deletions lib/ui/locations/entries/geometry.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default entry => {
entry.mapview = entry.location.layer.mapview

// Assign entry.style to location.style
entry.style = {...entry.location?.style, ...entry.style}
entry.style = { ...entry.location?.style, ...entry.style }

// Create ol style from entry.style if not yet defined.
entry.Style ??= mapp.utils.style(entry.style)
Expand Down Expand Up @@ -81,9 +81,11 @@ export default entry => {

list.push(modifyBtn)
}

}
} else if (entry.hideNoEdit) {

// Don't show entry with hideNoEdit flag
return;
}

// Push modify button into list.
entry.value && entry.edit?.delete && list.push(mapp.utils.html`
Expand All @@ -108,7 +110,7 @@ export default entry => {

entry.value = null

postUpdate(entry)
update(entry)
}

}}>Delete Geometry`)
Expand Down Expand Up @@ -213,7 +215,7 @@ function modify(e, entry) {
// Assign feature geometry as new value.
entry.value = feature.geometry

postUpdate(entry)
update(entry)

return;
}
Expand All @@ -237,7 +239,7 @@ function draw(entry, list) {
// Assign feature geometry as new value.
entry.value = feature.geometry

postUpdate(entry)
update(entry)
}

Object.keys(entry.draw).forEach(key => {
Expand All @@ -246,10 +248,9 @@ function draw(entry, list) {
list.push(mapp.ui.elements.drawing[key](entry))
}
})

}

async function postUpdate(entry) {
async function update(entry) {

if (entry.L) {

Expand All @@ -275,17 +276,17 @@ async function postUpdate(entry) {
body: JSON.stringify({ [entry.field]: entry.value }),
})

if (entry.dependents) {
await entry.location.syncFields(entry.dependents)
}

if (entry.location.layer.geom === entry.field) {

// Reload the layer if the layers geom field has been updated.
entry.location.layer.reload()
}

const content = mapp.ui.locations.entries[entry.type](entry)

mapp.utils.render(entry.node, content)

entry.title && content.before(mapp.ui.locations.entries.title(entry))

entry.location.viewEntries.remove()
entry.location.view?.classList.remove('disabled')
entry.location.viewEntries = entry.location.view.appendChild(mapp.ui.locations.infoj(entry.location))
}
51 changes: 19 additions & 32 deletions lib/ui/locations/entries/numeric.mjs
Original file line number Diff line number Diff line change
@@ -1,41 +1,36 @@
export default entry => {

formatEntryValue(entry);
entry.formatterParams ??= {}

if (!entry.edit) {
return displayValueNode(entry);
}
entry.formatterParams.options ??= {}

if (entry.edit.range) {
return createSlider(entry);
}
if (entry.edit) {

return createNumberInput(entry);
}
if (entry.edit.range) {
return createSlider(entry);
}

function formatEntryValue(entry) {
if (isNaN(entry.value)) return;
return createNumberInput(entry);
}

if (entry.type === 'integer') {
if (entry.value === undefined || entry.value === null || isNaN(entry.value)) return;

const options = {

// Number of decimal places is always 0 for integers
maximumFractionDigits: 0
};
entry.value = parseFloat(entry.value).toLocaleString(entry?.formatterParams?.locale || 'en-GB', options);
} else {
if (entry.type === 'integer') {

// Convert the value using toLocaleString with the formatterParams defined
entry.value = parseFloat(entry.value).toLocaleString(entry?.formatterParams?.locale || 'en-GB', entry?.formatterParams?.options)
entry.formatterParams.options.maximumFractionDigits = 0
}

return mapp.utils.html.node`
<div class="val" style=${entry.css_val}>
${entry.prefix}${parseFloat(entry.value).toLocaleString(entry.formatterParams.locale || 'en-GB', entry.formatterParams.options)}${entry.suffix}`;

}

function createSlider(entry) {
return mapp.ui.elements.slider({
min: entry.edit.range.min,
max: entry.edit.range.max,
val: entry.value,
val: entry.newValue || entry.value,
callback: e => {
entry.newValue = entry.type === 'integer'
? parseInt(e.target.value)
Expand All @@ -52,10 +47,9 @@ function createNumberInput(entry) {
return mapp.utils.html.node`
<input
type="number"
value=${entry.value}
value=${entry.newValue || entry.value}
placeholder=${entry.edit.placeholder}
onkeyup=${e => handleKeyUp(e, entry)}
>`;
onkeyup=${e => handleKeyUp(e, entry)}>`;
}

function handleKeyUp(e, entry) {
Expand All @@ -67,11 +61,4 @@ function handleKeyUp(e, entry) {
entry.location.view?.dispatchEvent(
new CustomEvent('valChange', { detail: entry })
);
}

function displayValueNode(entry) {
return mapp.utils.html.node`
<div class="val" style=${entry.css_val}>
${entry.prefix}${entry.value}${entry.suffix}
</div>`;
}
3 changes: 2 additions & 1 deletion lib/ui/locations/entries/pin.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export default entry => {

entry.srid = entry.srid || entry.location.layer.srid
// Assign srid from location.layer if not implicit.
entry.srid ??= entry.location.layer.srid

// Remove existing pin layer
entry.location.layer.mapview.Map.removeLayer(entry.L)
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/locations/entries/text.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function edit(entry) {
<input
type="text"
maxlength=${entry.edit.maxlength}
value="${entry.value || ''}"
value="${entry.newValue || entry.value || ''}"
placeholder="${entry.edit.placeholder || ''}"
onkeyup=${e => {
entry.newValue = e.target.value
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/locations/entries/textarea.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default entry => {
e.target.style.height = 'auto';
e.target.style.height = e.target.scrollHeight + 'px';
}, 100)}>
${entry.value || ''}`
${entry.newValue || entry.value || ''}`
}

const node = mapp.utils.html.node`
Expand Down
22 changes: 10 additions & 12 deletions public/css/_ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,17 @@
}
}

.link-with-img {

& >button,
& >.mask-icon,
& >.bg-icon {
width: 1.5em;
height: 1.5em;
}
.link-with-img>* {
height: 1.2em;
line-height: 1.2em;
display: inline-block;
vertical-align: middle;
}

& >* {
display: inline-block;
vertical-align: middle;
}
.link-with-img>button,
.link-with-img>.mask-icon,
.link-with-img>.bg-icon {
width: 1.5em;
}

.dataview-mask {
Expand Down
Loading