Fix measurements in popup details
This commit is contained in:
+60
-27
@@ -5,6 +5,7 @@ const TILE_MAX_NATIVE_ZOOM = 19;
|
|||||||
const MAP_MAX_ZOOM = 24;
|
const MAP_MAX_ZOOM = 24;
|
||||||
const MAP_ZOOM_STEP = 0.25;
|
const MAP_ZOOM_STEP = 0.25;
|
||||||
const WHEEL_PIXELS_PER_ZOOM_LEVEL = 240;
|
const WHEEL_PIXELS_PER_ZOOM_LEVEL = 240;
|
||||||
|
const FEET_PER_METER = 3.280839895;
|
||||||
const TIMELINE_PRESETS = [
|
const TIMELINE_PRESETS = [
|
||||||
{
|
{
|
||||||
id: "purchase",
|
id: "purchase",
|
||||||
@@ -330,7 +331,8 @@ function buildPopupContent(properties) {
|
|||||||
const title = `<strong>${escapeHtml(name)}</strong>`;
|
const title = `<strong>${escapeHtml(name)}</strong>`;
|
||||||
const subtitle = name === label ? "" : `<div>${escapeHtml(label)}</div>`;
|
const subtitle = name === label ? "" : `<div>${escapeHtml(label)}</div>`;
|
||||||
const allEntries = [...lifecycleEntries, ...entries, ...relationshipEntries];
|
const allEntries = [...lifecycleEntries, ...entries, ...relationshipEntries];
|
||||||
if (allEntries.length === 0 && linkEntries.length === 0) {
|
const measurementTable = buildMeasurementTable(details?.measurements);
|
||||||
|
if (allEntries.length === 0 && linkEntries.length === 0 && !measurementTable) {
|
||||||
return `${title}${subtitle}`;
|
return `${title}${subtitle}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,12 +343,16 @@ function buildPopupContent(properties) {
|
|||||||
.map((link) => `<div><a href="${escapeHtml(link.url)}" target="_blank" rel="noreferrer">Info</a></div>`)
|
.map((link) => `<div><a href="${escapeHtml(link.url)}" target="_blank" rel="noreferrer">Info</a></div>`)
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
return `${title}${subtitle}<div>${detailRows}${linkRows}</div>`;
|
return `${title}${subtitle}<div>${detailRows}${measurementTable}${linkRows}</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldShowDetailField(key, details = {}) {
|
function shouldShowDetailField(key, details = {}) {
|
||||||
|
if (key === "measurements") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
Array.isArray(details.measurements) &&
|
hasDatedMeasurements(details.measurements) &&
|
||||||
(key === "canopyDiameter" || key === "height")
|
(key === "canopyDiameter" || key === "height")
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
@@ -382,12 +388,8 @@ function formatDetailLabel(key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function formatDetailValue(key, value) {
|
function formatDetailValue(key, value) {
|
||||||
if (key === "measurements") {
|
|
||||||
return formatPlantMeasurements(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key === "canopyDiameter" || key === "height") {
|
if (key === "canopyDiameter" || key === "height") {
|
||||||
return `${value} m`;
|
return formatMetersAsFeet(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key === "offsetFeet" || key === "spacingFeet") {
|
if (key === "offsetFeet" || key === "spacingFeet") {
|
||||||
@@ -397,32 +399,63 @@ function formatDetailValue(key, value) {
|
|||||||
return String(value);
|
return String(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatPlantMeasurements(measurements) {
|
function formatMetersAsFeet(value) {
|
||||||
if (!Array.isArray(measurements)) {
|
return `${formatNumber(value * FEET_PER_METER)} ft`;
|
||||||
return String(measurements);
|
|
||||||
}
|
|
||||||
|
|
||||||
return measurements.map(formatPlantMeasurement).join("; ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatPlantMeasurement(measurement) {
|
function formatNumber(value) {
|
||||||
const parts = [];
|
return Number(value.toFixed(1)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (measurement.measuredDate) {
|
function buildMeasurementTable(measurements) {
|
||||||
parts.push(formatDetailValue("measuredDate", measurement.measuredDate));
|
const datedMeasurements = getDatedMeasurements(measurements);
|
||||||
|
if (!datedMeasurements.length) {
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (measurement.canopyDiameter !== undefined) {
|
const rows = datedMeasurements
|
||||||
parts.push(
|
.map(
|
||||||
`canopy ${formatDetailValue("canopyDiameter", measurement.canopyDiameter)}`,
|
(measurement) => `
|
||||||
);
|
<tr>
|
||||||
|
<td>${escapeHtml(measurement.measuredDate)}</td>
|
||||||
|
<td>${escapeHtml(formatOptionalMeasurement(measurement.canopyDiameter))}</td>
|
||||||
|
<td>${escapeHtml(formatOptionalMeasurement(measurement.height))}</td>
|
||||||
|
</tr>
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
.join("");
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="measurement-table-block">
|
||||||
|
<div><span>${escapeHtml(formatDetailLabel("measurements"))}:</span></div>
|
||||||
|
<table class="measurement-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Canopy dia.</th>
|
||||||
|
<th>Height</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>${rows}</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatOptionalMeasurement(value) {
|
||||||
|
return value === undefined ? "" : formatMetersAsFeet(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasDatedMeasurements(measurements) {
|
||||||
|
return getDatedMeasurements(measurements).length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDatedMeasurements(measurements) {
|
||||||
|
if (!Array.isArray(measurements)) {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (measurement.height !== undefined) {
|
return measurements.filter((measurement) => measurement.measuredDate);
|
||||||
parts.push(`height ${formatDetailValue("height", measurement.height)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts.join(", ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeHtml(value) {
|
function escapeHtml(value) {
|
||||||
|
|||||||
+27
@@ -129,6 +129,33 @@ main {
|
|||||||
font-family: "Iowan Old Style", "Palatino Linotype", "URW Palladio L", serif;
|
font-family: "Iowan Old Style", "Palatino Linotype", "URW Palladio L", serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.measurement-table-block {
|
||||||
|
margin-top: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.measurement-table {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 0.15rem;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 0.92em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.measurement-table th,
|
||||||
|
.measurement-table td {
|
||||||
|
padding: 0.12rem 0.35rem 0.12rem 0;
|
||||||
|
border-bottom: 1px solid rgba(87, 68, 38, 0.18);
|
||||||
|
text-align: left;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.measurement-table th {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.measurement-table tbody tr:last-child td {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.timeline-control {
|
.timeline-control {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 0.45rem;
|
gap: 0.45rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user