Compare commits

..
1 Commits
Author SHA1 Message Date
livio f1224b21c4 Aggiunge spostamento tra gruppi 0.4.2 2026-09-25 08:59:38 +02:00
5 changed files with 140 additions and 31 deletions

No files matched your search

+2 -2
View File
@@ -28,8 +28,8 @@
<ApplicationId>com.companyname.lmemappecatastaliapp</ApplicationId> <ApplicationId>com.companyname.lmemappecatastaliapp</ApplicationId>
<!-- Versions --> <!-- Versions -->
<ApplicationDisplayVersion>0.4.1</ApplicationDisplayVersion> <ApplicationDisplayVersion>0.4.2</ApplicationDisplayVersion>
<ApplicationVersion>36</ApplicationVersion> <ApplicationVersion>37</ApplicationVersion>
<Version>$(ApplicationDisplayVersion)</Version> <Version>$(ApplicationDisplayVersion)</Version>
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged --> <!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
+7
View File
@@ -2,6 +2,13 @@
App .NET MAUI Blazor Hybrid per Android, iOS, Mac Catalyst e Windows, pensata per consultare mappe catastali e lavorare sul campo con GPS. App .NET MAUI Blazor Hybrid per Android, iOS, Mac Catalyst e Windows, pensata per consultare mappe catastali e lavorare sul campo con GPS.
## Versione 0.4.2
- Nuovo comando `Sposta nel gruppo` visibile accanto a Rinomina e Rimuovi per padri, sottogruppi e singoli oggetti.
- Scelta della categoria e del sottogruppo di destinazione, con possibilita di creare un nuovo gruppo.
- I disegni possono essere organizzati in sottogruppi come i dati importati.
- `Sposta geometria` resta separato e continua a traslare gli oggetti in metri verso nord, sud, est o ovest.
## Versione 0.4.1 ## Versione 0.4.1
- Pannelli operativi allineati a destra, con ricerca lasciata nella posizione precedente. - Pannelli operativi allineati a destra, con ricerca lasciata nella posizione precedente.
+1 -1
View File
@@ -85,7 +85,7 @@ public sealed class MapExportService
{ {
var root = new XElement("gpx", var root = new XElement("gpx",
new XAttribute("version", "1.1"), new XAttribute("version", "1.1"),
new XAttribute("creator", "LME Mappe Catastali 0.4.1"), new XAttribute("creator", "LME Mappe Catastali 0.4.2"),
new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"), new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
new XElement("metadata", new XElement("name", name))); new XElement("metadata", new XElement("name", name)));
foreach (var feature in features.EnumerateArray()) foreach (var feature in features.EnumerateArray())
+12
View File
@@ -573,6 +573,7 @@ input[type="checkbox"] {
} }
.layer-rename-button, .layer-rename-button,
.layer-membership-button,
.layer-remove-button { .layer-remove-button {
width: 100%; width: 100%;
min-height: 28px; min-height: 28px;
@@ -592,6 +593,16 @@ input[type="checkbox"] {
background: #d9eee7; background: #d9eee7;
} }
.layer-membership-button {
border-color: #bfdbfe;
background: #eff6ff;
color: #1d4ed8;
}
.layer-membership-button:active {
background: #dbeafe;
}
.layer-remove-button { .layer-remove-button {
border-color: #fecaca; border-color: #fecaca;
background: #fff1f2; background: #fff1f2;
@@ -827,6 +838,7 @@ input[type="checkbox"] {
} }
.layer-manager-object > summary .layer-rename-button, .layer-manager-object > summary .layer-rename-button,
.layer-manager-object > summary .layer-membership-button,
.layer-manager-object > summary .layer-remove-button { .layer-manager-object > summary .layer-remove-button {
min-height: 24px; min-height: 24px;
font-size: 9px; font-size: 9px;
+118 -28
View File
@@ -1184,7 +1184,7 @@ function drawingLayerLabel(layer, layerType) {
function layerManagerCategories() { function layerManagerCategories() {
return [ return [
{ key: "gpsPosition", label: "Posizione GPS", roots: [lmeState.gpsMarker, lmeState.gpsAccuracy].filter(Boolean) }, { key: "gpsPosition", label: "Posizione GPS", roots: [lmeState.gpsMarker, lmeState.gpsAccuracy].filter(Boolean) },
{ key: "drawings", label: "Disegni e POI", roots: [lmeState.drawings].filter(Boolean) }, { key: "drawings", label: "Disegni e POI", roots: [lmeState.drawings].filter(Boolean), blocks: true },
{ key: "gpsTrail", label: "Traccia GPS", roots: [lmeState.gpsTrail].filter(Boolean) }, { key: "gpsTrail", label: "Traccia GPS", roots: [lmeState.gpsTrail].filter(Boolean) },
{ key: "gpsParcels", label: "Particella rilevata dal GPS", roots: [lmeState.gpsParcelLayer].filter(Boolean) }, { key: "gpsParcels", label: "Particella rilevata dal GPS", roots: [lmeState.gpsParcelLayer].filter(Boolean) },
{ key: "selectedParcels", label: "Particelle catastali evidenziate", roots: [lmeState.selectedParcelsLayer].filter(Boolean) }, { key: "selectedParcels", label: "Particelle catastali evidenziate", roots: [lmeState.selectedParcelsLayer].filter(Boolean) },
@@ -1382,11 +1382,11 @@ function managedObjectCanRemove(record) {
return ["drawings", "imported", "importedSheets", "selectedParcels", "gpsParcels"].includes(record.categoryKey); return ["drawings", "imported", "importedSheets", "selectedParcels", "gpsParcels"].includes(record.categoryKey);
} }
function layerManagerRowActions(renameButton, removeButton) { function layerManagerRowActions(renameButton, moveButton, removeButton) {
if (!renameButton && !removeButton) { if (!renameButton && !moveButton && !removeButton) {
return ""; return "";
} }
return `<span class="layer-row-actions">${renameButton}${removeButton}</span>`; return `<span class="layer-row-actions">${renameButton}${moveButton}${removeButton}</span>`;
} }
const layerManagerPalettes = [ const layerManagerPalettes = [
@@ -1472,7 +1472,87 @@ function removeManagedRecords(records, subject) {
setInfo(`${records.length === 1 ? "Oggetto rimosso" : `${records.length} oggetti rimossi`} dal progetto.`); setInfo(`${records.length === 1 ? "Oggetto rimosso" : `${records.length} oggetti rimossi`} dal progetto.`);
} }
function moveManagedRecordsToCategory(records, targetCategory) { function managedMoveDestinations() {
return layerManagerCategories()
.filter(category => ["drawings", "imported"].includes(category.key))
.map(category => {
const records = managedRecordsForCategory(category);
const groups = new Map();
records.forEach(record => {
if (!groups.has(record.source)) {
groups.set(record.source, managedBlockName(record.source, [record]));
}
});
if (!groups.size) {
groups.set("Progetto corrente", "Gruppo principale");
}
return {
key: category.key,
name: managedCategoryName(category, records),
groups: [...groups].map(([source, name]) => ({ source, name }))
};
});
}
function showMoveManagedRecordsDialog(records, subject) {
if (lmeState.readOnly) { setInfo("Il progetto e' in sola lettura."); return; }
if (!records.length || records.some(record => !["drawings", "imported"].includes(record.categoryKey))) {
setInfo("Questo oggetto o gruppo non puo essere spostato.");
return;
}
if (records.some(record => record.layer?.feature?.properties?._lmeLocked)) {
setInfo("Sblocca prima tutti gli oggetti da spostare.");
return;
}
const destinations = managedMoveDestinations();
const categoryOptions = destinations.map(destination =>
`<option value="${escapeHtml(destination.key)}">${escapeHtml(destination.name)}</option>`).join("");
const dialog = showAppDialog("Sposta nel gruppo", `<form class="lme-edit-form move-group-form"><p>Cambia l'appartenenza di ${escapeHtml(subject)} senza modificarne la posizione sulla mappa.</p><label>Categoria<select name="category">${categoryOptions}</select></label><label>Gruppo esistente<select name="group"></select></label><label>Oppure crea un nuovo gruppo<input name="newGroup" type="text" maxlength="120" placeholder="Nome del nuovo gruppo"></label><div class="dialog-command-row"><button type="button" data-cancel>Annulla</button><button type="submit" class="primary-command">Sposta nel gruppo</button></div></form>`);
const form = dialog.querySelector("form");
const categorySelect = form.elements.category;
const groupSelect = form.elements.group;
const newGroupInput = form.elements.newGroup;
const currentCategory = records.every(record => record.categoryKey === records[0].categoryKey)
? records[0].categoryKey
: "drawings";
categorySelect.value = currentCategory;
const refreshGroups = () => {
const destination = destinations.find(item => item.key === categorySelect.value);
groupSelect.innerHTML = (destination?.groups || []).map(group =>
`<option value="${escapeHtml(group.source)}">${escapeHtml(group.name)}</option>`).join("");
const currentSource = records.every(record => record.source === records[0].source)
? records[0].source
: "";
if (destination?.key === currentCategory && currentSource
&& destination.groups.some(group => group.source === currentSource)) {
groupSelect.value = currentSource;
}
};
categorySelect.addEventListener("change", refreshGroups);
refreshGroups();
dialog.querySelector("[data-cancel]").addEventListener("click", () => dialog.remove());
form.addEventListener("submit", event => {
event.preventDefault();
const destination = destinations.find(item => item.key === categorySelect.value);
if (!destination) return;
const requestedName = newGroupInput.value.trim().slice(0, 120);
const existingByName = requestedName
? destination.groups.find(group => group.name.toLocaleLowerCase("it") === requestedName.toLocaleLowerCase("it"))
: null;
const selectedGroup = destination.groups.find(group => group.source === groupSelect.value);
const target = existingByName || (requestedName
? { source: `Gruppo ${requestedName}`, name: requestedName }
: selectedGroup);
if (!target) {
setInfo("Scegli un gruppo di destinazione o inserisci il nome di un nuovo gruppo.");
return;
}
dialog.remove();
moveManagedRecordsToGroup(records, destination.key, target.source, target.name);
});
}
function moveManagedRecordsToGroup(records, targetCategory, targetSource, targetGroupName) {
if (lmeState.readOnly) { setInfo("Il progetto e' in sola lettura."); return; } if (lmeState.readOnly) { setInfo("Il progetto e' in sola lettura."); return; }
const movable = records.filter(record => ["drawings", "imported"].includes(record.categoryKey)); const movable = records.filter(record => ["drawings", "imported"].includes(record.categoryKey));
if (!movable.length || !["drawings", "imported"].includes(targetCategory)) { if (!movable.length || !["drawings", "imported"].includes(targetCategory)) {
@@ -1488,8 +1568,10 @@ function moveManagedRecordsToCategory(records, targetCategory) {
const feature = record.layer.toGeoJSON(); const feature = record.layer.toGeoJSON();
feature.properties = { feature.properties = {
...(feature.properties || {}), ...(feature.properties || {}),
_lmeSource: feature.properties?._lmeSource || "Progetto corrente" _lmeSource: targetSource,
_lmeGroupName: targetGroupName
}; };
delete feature.properties._lmeManagerId;
return feature; return feature;
}); });
movable.forEach(record => { movable.forEach(record => {
@@ -1505,8 +1587,9 @@ function moveManagedRecordsToCategory(records, targetCategory) {
refreshImportedMeasurements(); refreshImportedMeasurements();
refreshDrawingMeasurements(); refreshDrawingMeasurements();
refreshLayerManager(); refreshLayerManager();
finishMapChange(`Spostati ${features.length} oggetti in ${targetCategory === "drawings" ? "Disegni e POI" : "Progetti e dati importati"}.`); const categoryName = targetCategory === "drawings" ? "Disegni e POI" : "Progetti e dati importati";
setInfo(`${features.length} oggetti spostati in ${targetCategory === "drawings" ? "Disegni e POI" : "Progetti e dati importati"}.`); finishMapChange(`Spostati ${features.length} oggetti in ${categoryName} > ${targetGroupName}.`);
setInfo(`${features.length} oggetti spostati in ${categoryName} > ${targetGroupName}.`);
} }
function managedObjectDetails(layer) { function managedObjectDetails(layer) {
@@ -1614,7 +1697,10 @@ function renderLayerManagerCategory(category, records) {
const removeButton = managedCategoryCanRemove(category, records) const removeButton = managedCategoryCanRemove(category, records)
? `<button type="button" class="layer-remove-button" aria-label="Rimuovi gruppo dal progetto" title="Rimuovi dal progetto">Rimuovi</button>` ? `<button type="button" class="layer-remove-button" aria-label="Rimuovi gruppo dal progetto" title="Rimuovi dal progetto">Rimuovi</button>`
: ""; : "";
const rowActions = layerManagerRowActions(renameButton, removeButton); const moveButton = records.length && ["drawings", "imported"].includes(category.key)
? `<button type="button" class="layer-membership-button" aria-label="Sposta gruppo in un altro gruppo" title="Sposta nel gruppo">Sposta nel gruppo</button>`
: "";
const rowActions = layerManagerRowActions(renameButton, moveButton, removeButton);
group.classList.toggle("layer-manager-with-actions", Boolean(rowActions)); group.classList.toggle("layer-manager-with-actions", Boolean(rowActions));
const visibleCount = records.filter(record => !lmeState.managerHiddenObjectIds.has(record.id)).length; const visibleCount = records.filter(record => !lmeState.managerHiddenObjectIds.has(record.id)).length;
const categoryVisible = !lmeState.managerHiddenCategories.has(category.key) const categoryVisible = !lmeState.managerHiddenCategories.has(category.key)
@@ -1641,6 +1727,11 @@ function renderLayerManagerCategory(category, records) {
event.stopPropagation(); event.stopPropagation();
removeManagedRecords(records, `il gruppo '${categoryName}'`); removeManagedRecords(records, `il gruppo '${categoryName}'`);
}); });
group.querySelector(".layer-membership-button")?.addEventListener("click", event => {
event.preventDefault();
event.stopPropagation();
showMoveManagedRecordsDialog(records, `il gruppo '${categoryName}'`);
});
bindManagedParentHighlight(group, `category:${category.key}`, records); bindManagedParentHighlight(group, `category:${category.key}`, records);
const children = group.querySelector(".layer-manager-children"); const children = group.querySelector(".layer-manager-children");
if (records.length) children.appendChild(renderManagedGroupTools(records)); if (records.length) children.appendChild(renderManagedGroupTools(records));
@@ -1674,6 +1765,7 @@ function renderLayerManagerBlock(category, source, records) {
const blockName = managedBlockName(source, records); const blockName = managedBlockName(source, records);
const rowActions = layerManagerRowActions( const rowActions = layerManagerRowActions(
`<button type="button" class="layer-rename-button" aria-label="Rinomina gruppo" title="Rinomina">Rinomina</button>`, `<button type="button" class="layer-rename-button" aria-label="Rinomina gruppo" title="Rinomina">Rinomina</button>`,
`<button type="button" class="layer-membership-button" aria-label="Sposta gruppo in un altro gruppo" title="Sposta nel gruppo">Sposta nel gruppo</button>`,
`<button type="button" class="layer-remove-button" aria-label="Rimuovi gruppo dal progetto" title="Rimuovi dal progetto">Rimuovi</button>`); `<button type="button" class="layer-remove-button" aria-label="Rimuovi gruppo dal progetto" title="Rimuovi dal progetto">Rimuovi</button>`);
block.classList.add("layer-manager-with-actions"); block.classList.add("layer-manager-with-actions");
const blockLocked = records.length > 0 && records.every(record => Boolean(record.layer?.feature?.properties?._lmeLocked)); const blockLocked = records.length > 0 && records.every(record => Boolean(record.layer?.feature?.properties?._lmeLocked));
@@ -1700,6 +1792,11 @@ function renderLayerManagerBlock(category, source, records) {
event.stopPropagation(); event.stopPropagation();
removeManagedRecords(records, `il gruppo '${blockName}'`); removeManagedRecords(records, `il gruppo '${blockName}'`);
}); });
block.querySelector(".layer-membership-button").addEventListener("click", event => {
event.preventDefault();
event.stopPropagation();
showMoveManagedRecordsDialog(records, `il gruppo '${blockName}'`);
});
bindManagedParentHighlight(block, `block:${category.key}:${source}`, records); bindManagedParentHighlight(block, `block:${category.key}:${source}`, records);
const children = block.querySelector(".layer-manager-children"); const children = block.querySelector(".layer-manager-children");
children.appendChild(renderManagedGroupTools(records)); children.appendChild(renderManagedGroupTools(records));
@@ -1724,7 +1821,10 @@ function renderLayerManagerObject(record, index) {
const removeButton = managedObjectCanRemove(record) const removeButton = managedObjectCanRemove(record)
? `<button type="button" class="layer-remove-button" aria-label="Rimuovi oggetto dal progetto" title="Rimuovi dal progetto">Rimuovi</button>` ? `<button type="button" class="layer-remove-button" aria-label="Rimuovi oggetto dal progetto" title="Rimuovi dal progetto">Rimuovi</button>`
: ""; : "";
const rowActions = layerManagerRowActions(renameButton, removeButton); const moveButton = ["drawings", "imported"].includes(record.categoryKey)
? `<button type="button" class="layer-membership-button" aria-label="Sposta oggetto in un altro gruppo" title="Sposta nel gruppo">Sposta nel gruppo</button>`
: "";
const rowActions = layerManagerRowActions(renameButton, moveButton, removeButton);
object.classList.toggle("layer-manager-with-actions", Boolean(rowActions)); object.classList.toggle("layer-manager-with-actions", Boolean(rowActions));
const objectName = managedObjectLabel(record, index); const objectName = managedObjectLabel(record, index);
const locked = Boolean(record.layer?.feature?.properties?._lmeLocked); const locked = Boolean(record.layer?.feature?.properties?._lmeLocked);
@@ -1743,6 +1843,11 @@ function renderLayerManagerObject(record, index) {
event.stopPropagation(); event.stopPropagation();
removeManagedRecords([record], `'${objectName}'`); removeManagedRecords([record], `'${objectName}'`);
}); });
object.querySelector(".layer-membership-button")?.addEventListener("click", event => {
event.preventDefault();
event.stopPropagation();
showMoveManagedRecordsDialog([record], `'${objectName}'`);
});
object.querySelector(".layer-inline-lock")?.addEventListener("click", event => { object.querySelector(".layer-inline-lock")?.addEventListener("click", event => {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@@ -1786,7 +1891,7 @@ function renderLayerSelectionToolbar() {
toolbar.innerHTML = `<label>Cerca oggetti<input type="search" value="${escapeHtml(lmeState.managerSearchText)}" placeholder="Nome o gruppo"></label> toolbar.innerHTML = `<label>Cerca oggetti<input type="search" value="${escapeHtml(lmeState.managerSearchText)}" placeholder="Nome o gruppo"></label>
<div class="layer-selection-summary"><strong>${selectedCount} selezionati</strong><button type="button" data-action="clear">Deseleziona</button></div> <div class="layer-selection-summary"><strong>${selectedCount} selezionati</strong><button type="button" data-action="clear">Deseleziona</button></div>
<div class="layer-batch-actions"> <div class="layer-batch-actions">
<button type="button" data-action="duplicate">Duplica</button><button type="button" data-action="move">Sposta</button> <button type="button" data-action="duplicate">Duplica</button><button type="button" data-action="move">Sposta geometria</button>
<button type="button" data-action="buffer">Buffer</button><button type="button" data-action="union">Unisci</button> <button type="button" data-action="buffer">Buffer</button><button type="button" data-action="union">Unisci</button>
<button type="button" data-action="split">Dividi</button><button type="button" data-action="delete" class="danger-command">Rimuovi</button> <button type="button" data-action="split">Dividi</button><button type="button" data-action="delete" class="danger-command">Rimuovi</button>
</div>`; </div>`;
@@ -1818,17 +1923,11 @@ function renderManagedGroupTools(records) {
const tools = document.createElement("div"); const tools = document.createElement("div");
tools.className = "layer-group-tools"; tools.className = "layer-group-tools";
const properties = records[0]?.layer?.feature?.properties || {}; const properties = records[0]?.layer?.feature?.properties || {};
const sourceCategory = records[0]?.categoryKey;
const membershipAction = sourceCategory === "drawings"
? `<button type="button" data-group-action="membership">Sposta in Progetti e dati importati</button>`
: sourceCategory === "imported"
? `<button type="button" data-group-action="membership">Sposta in Disegni e POI</button>`
: "";
tools.innerHTML = `<strong>Azioni gruppo</strong><span class="layer-group-totals">${escapeHtml(managedGroupTotals(records))}</span><div class="layer-style-controls"> tools.innerHTML = `<strong>Azioni gruppo</strong><span class="layer-group-totals">${escapeHtml(managedGroupTotals(records))}</span><div class="layer-style-controls">
<label>Colore<input type="color" value="${normalizedColor(properties._lmeColor, "#16806a")}"></label> <label>Colore<input type="color" value="${normalizedColor(properties._lmeColor, "#16806a")}"></label>
<label>Spessore<input type="range" min="1" max="10" step="1" value="${Number(properties._lmeWeight) || 3}"></label> <label>Spessore<input type="range" min="1" max="10" step="1" value="${Number(properties._lmeWeight) || 3}"></label>
<label>Opacita<input type="range" min="0.1" max="1" step="0.1" value="${Number(properties._lmeOpacity) || 1}"></label></div> <label>Opacita<input type="range" min="0.1" max="1" step="0.1" value="${Number(properties._lmeOpacity) || 1}"></label></div>
<div class="layer-compact-actions"><button type="button" data-group-action="select">Seleziona tutti</button><button type="button" data-group-action="lock">Blocca/sblocca</button><button type="button" data-group-action="labels">Etichette</button>${membershipAction}</div>`; <div class="layer-compact-actions"><button type="button" data-group-action="select">Seleziona tutti</button><button type="button" data-group-action="lock">Blocca/sblocca</button><button type="button" data-group-action="labels">Etichette</button></div>`;
const inputs = tools.querySelectorAll("input"); const inputs = tools.querySelectorAll("input");
inputs.forEach(input => input.addEventListener("change", () => { inputs.forEach(input => input.addEventListener("change", () => {
applyManagedStyle(records, { color: inputs[0].value, weight: Number(inputs[1].value), opacity: Number(inputs[2].value) }); applyManagedStyle(records, { color: inputs[0].value, weight: Number(inputs[1].value), opacity: Number(inputs[2].value) });
@@ -1845,8 +1944,6 @@ function renderManagedGroupTools(records) {
const visible = !records.every(record => Boolean(record.layer?.feature?.properties?._lmeLabelVisible)); const visible = !records.every(record => Boolean(record.layer?.feature?.properties?._lmeLabelVisible));
updateManagedProperties(records, properties => { properties._lmeLabelVisible = visible; }); updateManagedProperties(records, properties => { properties._lmeLabelVisible = visible; });
}); });
tools.querySelector("[data-group-action='membership']")?.addEventListener("click", () =>
moveManagedRecordsToCategory(records, sourceCategory === "drawings" ? "imported" : "drawings"));
return tools; return tools;
} }
@@ -1869,11 +1966,6 @@ function renderManagedObjectTools(record) {
const properties = record.layer.feature?.properties || (record.layer.feature = { type: "Feature", properties: {} }).properties; const properties = record.layer.feature?.properties || (record.layer.feature = { type: "Feature", properties: {} }).properties;
const selected = lmeState.managerSelectedObjectIds.has(record.id); const selected = lmeState.managerSelectedObjectIds.has(record.id);
const locked = Boolean(properties._lmeLocked); const locked = Boolean(properties._lmeLocked);
const membershipAction = record.categoryKey === "drawings"
? `<button type="button" data-action="membership">Sposta in Progetti e dati importati</button>`
: record.categoryKey === "imported"
? `<button type="button" data-action="membership">Sposta in Disegni e POI</button>`
: "";
const tools = document.createElement("section"); const tools = document.createElement("section");
tools.className = "layer-object-tools"; tools.className = "layer-object-tools";
tools.innerHTML = `<label class="layer-manager-suboption"><input type="checkbox" data-field="selected" ${selected ? "checked" : ""}><span>Seleziona per azioni multiple</span></label> tools.innerHTML = `<label class="layer-manager-suboption"><input type="checkbox" data-field="selected" ${selected ? "checked" : ""}><span>Seleziona per azioni multiple</span></label>
@@ -1888,7 +1980,7 @@ function renderManagedObjectTools(record) {
<label>Note<textarea data-field="notes" rows="2" maxlength="1000" placeholder="Note tecniche">${escapeHtml(properties._lmeNotes || "")}</textarea></label> <label>Note<textarea data-field="notes" rows="2" maxlength="1000" placeholder="Note tecniche">${escapeHtml(properties._lmeNotes || "")}</textarea></label>
<label class="layer-photo-picker">Foto<input type="file" data-field="photo" accept="image/*"></label> <label class="layer-photo-picker">Foto<input type="file" data-field="photo" accept="image/*"></label>
${properties._lmePhoto ? `<img class="layer-photo-preview" src="${properties._lmePhoto}" alt="Foto allegata"><button type="button" data-action="remove-photo">Rimuovi foto</button>` : ""} ${properties._lmePhoto ? `<img class="layer-photo-preview" src="${properties._lmePhoto}" alt="Foto allegata"><button type="button" data-action="remove-photo">Rimuovi foto</button>` : ""}
<div class="layer-compact-actions"><button type="button" data-action="attributes">Attributi</button><button type="button" data-action="duplicate">Duplica</button><button type="button" data-action="numeric">Coordinate</button><button type="button" data-action="inspect">WGS84 / UTM</button><button type="button" data-action="move">Sposta geometria</button><button type="button" data-action="buffer">Buffer</button>${membershipAction}</div>`; <div class="layer-compact-actions"><button type="button" data-action="attributes">Attributi</button><button type="button" data-action="duplicate">Duplica</button><button type="button" data-action="numeric">Coordinate</button><button type="button" data-action="inspect">WGS84 / UTM</button><button type="button" data-action="move">Sposta geometria</button><button type="button" data-action="buffer">Buffer</button></div>`;
tools.querySelector("[data-field='selected']").addEventListener("change", event => { tools.querySelector("[data-field='selected']").addEventListener("change", event => {
if (event.target.checked) lmeState.managerSelectedObjectIds.add(record.id); if (event.target.checked) lmeState.managerSelectedObjectIds.add(record.id);
else lmeState.managerSelectedObjectIds.delete(record.id); else lmeState.managerSelectedObjectIds.delete(record.id);
@@ -1918,8 +2010,6 @@ function renderManagedObjectTools(record) {
tools.querySelector("[data-action='inspect']").addEventListener("click", () => showCoordinateInspectorForRecord(record)); tools.querySelector("[data-action='inspect']").addEventListener("click", () => showCoordinateInspectorForRecord(record));
tools.querySelector("[data-action='move']").addEventListener("click", () => moveManagedRecords([record])); tools.querySelector("[data-action='move']").addEventListener("click", () => moveManagedRecords([record]));
tools.querySelector("[data-action='buffer']").addEventListener("click", () => bufferManagedRecords([record])); tools.querySelector("[data-action='buffer']").addEventListener("click", () => bufferManagedRecords([record]));
tools.querySelector("[data-action='membership']")?.addEventListener("click", () =>
moveManagedRecordsToCategory([record], record.categoryKey === "drawings" ? "imported" : "drawings"));
return tools; return tools;
} }