nidus-sync/html/template/sync/upload-by-id.html
Eli Ribble 786a6c16a3
Fix up upload by ID
Show the street number as well as the rest of the address, emit an event
when the upload is processed, actually check if pools are existing, etc.
2026-03-19 15:31:04 +00:00

209 lines
6.4 KiB
HTML

{{ template "sync/layout/authenticated.html" . }}
{{ define "title" }}Pool Upload{{ end }}
{{ define "extraheader" }}
<script
type="text/javascript"
src="//unpkg.com/maplibre-gl@5.0.1/dist/maplibre-gl.js"
></script>
<script src="/static/js/map-multipoint.js"></script>
<script>
const CSV_FILE_ID={{.C.CSVFileID}};
const ORG_ID={{.Organization.ID}};
function handleShowIssuesOnly() {
const checkboxShowIssuesOnly = document.getElementById("showIssuesOnly");
const allRows = document.querySelectorAll('tr');
if (checkboxShowIssuesOnly.checked) {
allRows.forEach(row => {
if (!(row.classList.contains("has-error") || row.classList.contains("header"))) {
row.style.display = "none";
}
});
} else {
allRows.forEach(row => {
row.style.display = "table-row";
});
}
}
function onLoad() {
const map = document.querySelector("map-multipoint");
map.addEventListener("load", (event) => {
map.addSource('tegola-nidus', {
'type': 'vector',
'tiles': [
`{{.URL.Tegola}}maps/nidus/{z}/{x}/{y}?csv_file=${CSV_FILE_ID}&id=${ORG_ID}`
]
});
map.addLayer({
'id': 'pool',
'source': 'tegola-nidus',
'source-layer': 'fileupload-pool',
'type': 'circle',
'paint': {
'circle-color': "#91b979",
'circle-radius': 7,
'circle-stroke-width': 2,
'circle-stroke-color': "#7aab5f"
}
});
});
const checkboxShowIssuesOnly = document.getElementById("showIssuesOnly");
checkboxShowIssuesOnly.onclick = handleShowIssuesOnly;
// Set the correct state if the browser remembers the state of the checkbox
handleShowIssuesOnly();
}
document.addEventListener('DOMContentLoaded', onLoad);
</script>
{{ end }}
{{ define "content" }}
<div class="container mt-4 results-container">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>Upload Results: {{ .C.Upload.Name }}</h2>
<span class="badge rounded-pill {{ .C.Upload.Status }}">
<i class="bi {{ .C.Upload.Status|iconUploadStatus }} me-1"></i
>{{ .C.Upload.Status|displayUploadStatus }}
</span>
</div>
<div class="row mb-4">
<div class="col-md-4">
<div class="card summary-card h-100 border-primary">
<div class="card-body text-center">
<h1 class="display-4 text-primary">
{{ .C.Upload.CountExisting }}
</h1>
<h5>Existing Pools</h5>
<p class="text-muted">Matches found in previous records</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card summary-card h-100 border-success">
<div class="card-body text-center">
<h1 class="display-4 text-success">{{ .C.Upload.CountNew }}</h1>
<h5>New Pools</h5>
<p class="text-muted">Not found in existing records</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card summary-card h-100 border-warning">
<div class="card-body text-center">
<h1 class="display-4 text-warning">{{ .C.Upload.CountOutside }}</h1>
<h5>Outside District</h5>
<p class="text-muted">Potential geocoding errors</p>
</div>
</div>
</div>
</div>
<div class="card mb-4">
<map-multipoint
id="map"
organization-id="{{ .Organization.ID }}"
tegola="{{ .URL.Tegola }}"
xmin="{{ .Organization.ServiceArea.Min.X }}"
ymin="{{ .Organization.ServiceArea.Min.Y }}"
xmax="{{ .Organization.ServiceArea.Max.X }}"
ymax="{{ .Organization.ServiceArea.Max.Y }}"
></map-multipoint>
</div>
<div class="card mb-4">
<div
class="card-header bg-light d-flex justify-content-between align-items-center"
>
<h5 class="mb-0">Data Preview</h5>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="showIssuesOnly" />
<label class="form-check-label" for="showIssuesOnly"
>Show issues only</label
>
</div>
</div>
<div class="card-body">
{{ range .C.Upload.Errors }}
<div class="alert alert-danger" role="alert">
<i class="bi bi-exclamation-triangle me-2"></i>
<strong>Error:</strong>{{ .Message }}
</div>
{{ end }}
{{ if (or (eq .C.Upload.Status "uploaded") (eq .C.Upload.Status "parsing")) }}
<div class="alert alert-info" role="alert">
<i class="bi bi-exclamation-triangle me-2"></i>
<strong>Working:</strong> File is still processing... refresh this
page in a bit to see updates.
</div>
{{ else }}
{{ if eq (len .C.Upload.Pools) 0 }}
<div class="alert alert-warning" role="alert">
<i class="bi bi-exclamation-triangle me-2"></i>
<strong>Warning:</strong> No pools could be understood from your
file.
</div>
{{ else }}
<div class="table-responsive">
<table class="table table-hover table-striped">
<thead class="table-light">
<tr class="header">
<th></th>
<th>Number</th>
<th>Street</th>
<th>City</th>
<th>Post</th>
<th>Status</th>
<th>Condition</th>
<th>Tags</th>
</tr>
</thead>
<tbody>
{{ range .C.Upload.Pools }}
<tr {{ if gt (len .Errors) 0 }}class="has-error"{{ end }}>
<td>
{{ if gt (len .Errors) 0 }}
<i
class="bi bi-info-circle-fill text-primary ms-1"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="{{ range .Errors }}{{ .Message }}{{ end }}"
></i>
{{ end }}
</td>
<td>{{ .Address.Number }}</td>
<td>{{ .Address.Street }}</td>
<td>{{ .Address.Locality }}</td>
<td>{{ .Address.PostalCode }}</td>
<td>
<span class="badge status {{ .Status }}"
>{{ .Status|title }}</span
>
</td>
<td>
<span class="badge condition {{ .Condition }}"
>{{ .Condition|title }}</span
>
</td>
<td>{{ len .Tags }}</td>
</tr>
{{ end }}
</tbody>
</table>
</div>
{{ end }}
{{ end }}
</div>
</div>
<div class="d-flex justify-content-between mt-4 mb-5">
<form action="{{ call .URL.Upload.Discard .C.CSVFileID }}" method="POST">
<button type="submit" class="btn btn-outline-danger">Discard</button>
</form>
<form action="{{ call .URL.Upload.Commit .C.CSVFileID }}" method="POST">
<button class="btn btn-primary" id="confirmUploadBtn">
<i class="bi bi-check2 me-1"></i> Confirm and Submit Data
</button>
</form>
</div>
</div>
{{ end }}