Initial working marker display in shadow dom
This commit is contained in:
parent
bea7c28af2
commit
b94d09696e
7 changed files with 208 additions and 39 deletions
112
db/sql/publicreport_image_with_json_by_quick_id.bob.go
Normal file
112
db/sql/publicreport_image_with_json_by_quick_id.bob.go
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// Code generated by BobGen psql v0.42.1. DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package sql
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"io"
|
||||
"iter"
|
||||
"time"
|
||||
|
||||
"github.com/aarondl/opt/null"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stephenafamo/bob"
|
||||
"github.com/stephenafamo/bob/dialect/psql"
|
||||
"github.com/stephenafamo/bob/dialect/psql/dialect"
|
||||
"github.com/stephenafamo/bob/orm"
|
||||
"github.com/stephenafamo/scan"
|
||||
)
|
||||
|
||||
//go:embed publicreport_image_with_json_by_quick_id.bob.sql
|
||||
var formattedQueries_publicreport_image_with_json_by_quick_id string
|
||||
|
||||
var publicreportImageWithJSONByQuickIDSQL = formattedQueries_publicreport_image_with_json_by_quick_id[172:965]
|
||||
|
||||
type PublicreportImageWithJSONByQuickIDQuery = orm.ModQuery[*dialect.SelectQuery, publicreportImageWithJSONByQuickID, PublicreportImageWithJSONByQuickIDRow, []PublicreportImageWithJSONByQuickIDRow, publicreportImageWithJSONByQuickIDTransformer]
|
||||
|
||||
func PublicreportImageWithJSONByQuickID(QuickID int32) *PublicreportImageWithJSONByQuickIDQuery {
|
||||
var expressionTypArgs publicreportImageWithJSONByQuickID
|
||||
|
||||
expressionTypArgs.QuickID = psql.Arg(QuickID)
|
||||
|
||||
return &PublicreportImageWithJSONByQuickIDQuery{
|
||||
Query: orm.Query[publicreportImageWithJSONByQuickID, PublicreportImageWithJSONByQuickIDRow, []PublicreportImageWithJSONByQuickIDRow, publicreportImageWithJSONByQuickIDTransformer]{
|
||||
ExecQuery: orm.ExecQuery[publicreportImageWithJSONByQuickID]{
|
||||
BaseQuery: bob.BaseQuery[publicreportImageWithJSONByQuickID]{
|
||||
Expression: expressionTypArgs,
|
||||
Dialect: dialect.Dialect,
|
||||
QueryType: bob.QueryTypeSelect,
|
||||
},
|
||||
},
|
||||
Scanner: func(context.Context, []string) (func(*scan.Row) (any, error), func(any) (PublicreportImageWithJSONByQuickIDRow, error)) {
|
||||
return func(row *scan.Row) (any, error) {
|
||||
var t PublicreportImageWithJSONByQuickIDRow
|
||||
row.ScheduleScanByIndex(0, &t.ID)
|
||||
row.ScheduleScanByIndex(1, &t.ContentType)
|
||||
row.ScheduleScanByIndex(2, &t.Created)
|
||||
row.ScheduleScanByIndex(3, &t.Location)
|
||||
row.ScheduleScanByIndex(4, &t.LocationJSON)
|
||||
row.ScheduleScanByIndex(5, &t.ResolutionX)
|
||||
row.ScheduleScanByIndex(6, &t.ResolutionY)
|
||||
row.ScheduleScanByIndex(7, &t.StorageUUID)
|
||||
row.ScheduleScanByIndex(8, &t.StorageSize)
|
||||
row.ScheduleScanByIndex(9, &t.UploadedFilename)
|
||||
return &t, nil
|
||||
}, func(v any) (PublicreportImageWithJSONByQuickIDRow, error) {
|
||||
return *(v.(*PublicreportImageWithJSONByQuickIDRow)), nil
|
||||
}
|
||||
},
|
||||
},
|
||||
Mod: bob.ModFunc[*dialect.SelectQuery](func(q *dialect.SelectQuery) {
|
||||
q.AppendSelect(expressionTypArgs.subExpr(9, 549))
|
||||
q.SetTable(expressionTypArgs.subExpr(555, 742))
|
||||
q.AppendWhere(expressionTypArgs.subExpr(750, 792))
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
type PublicreportImageWithJSONByQuickIDRow = struct {
|
||||
ID int32 `db:"id"`
|
||||
ContentType string `db:"content_type"`
|
||||
Created time.Time `db:"created"`
|
||||
Location null.Val[string] `db:"location"`
|
||||
LocationJSON string `db:"location_json"`
|
||||
ResolutionX int32 `db:"resolution_x"`
|
||||
ResolutionY int32 `db:"resolution_y"`
|
||||
StorageUUID uuid.UUID `db:"storage_uuid"`
|
||||
StorageSize int64 `db:"storage_size"`
|
||||
UploadedFilename string `db:"uploaded_filename"`
|
||||
}
|
||||
|
||||
type publicreportImageWithJSONByQuickIDTransformer = bob.SliceTransformer[PublicreportImageWithJSONByQuickIDRow, []PublicreportImageWithJSONByQuickIDRow]
|
||||
|
||||
type publicreportImageWithJSONByQuickID struct {
|
||||
QuickID bob.Expression
|
||||
}
|
||||
|
||||
func (o publicreportImageWithJSONByQuickID) args() iter.Seq[orm.ArgWithPosition] {
|
||||
return func(yield func(arg orm.ArgWithPosition) bool) {
|
||||
if !yield(orm.ArgWithPosition{
|
||||
Name: "quickID",
|
||||
Start: 790,
|
||||
Stop: 792,
|
||||
Expression: o.QuickID,
|
||||
}) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o publicreportImageWithJSONByQuickID) raw(from, to int) string {
|
||||
return publicreportImageWithJSONByQuickIDSQL[from:to]
|
||||
}
|
||||
|
||||
func (o publicreportImageWithJSONByQuickID) subExpr(from, to int) bob.Expression {
|
||||
return orm.ArgsToExpression(publicreportImageWithJSONByQuickIDSQL, from, to, o.args())
|
||||
}
|
||||
|
||||
func (o publicreportImageWithJSONByQuickID) WriteSQL(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) {
|
||||
return o.subExpr(0, len(publicreportImageWithJSONByQuickIDSQL)).WriteSQL(ctx, w, d, start)
|
||||
}
|
||||
18
db/sql/publicreport_image_with_json_by_quick_id.bob.sql
Normal file
18
db/sql/publicreport_image_with_json_by_quick_id.bob.sql
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
-- Code generated by BobGen psql v0.42.1. DO NOT EDIT.
|
||||
-- This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
-- PublicreportImageWithJSONByQuickID
|
||||
SELECT
|
||||
"publicreport.image"."id" AS "id",
|
||||
"publicreport.image"."content_type" AS "content_type",
|
||||
"publicreport.image"."created" AS "created",
|
||||
"publicreport.image"."location" AS "location",
|
||||
ST_AsGeoJSON("publicreport.image"."location") AS "location_json",
|
||||
"publicreport.image"."resolution_x" AS "resolution_x",
|
||||
"publicreport.image"."resolution_y" AS "resolution_y",
|
||||
"publicreport.image"."storage_uuid" AS "storage_uuid",
|
||||
"publicreport.image"."storage_size" AS "storage_size",
|
||||
"publicreport.image"."uploaded_filename" AS "uploaded_filename"
|
||||
FROM "publicreport"."image" AS "publicreport.image"
|
||||
INNER JOIN "publicreport"."quick_image" AS "publicreport.quick_image" ON ("publicreport.image"."id" = "publicreport.quick_image"."image_id")
|
||||
WHERE ("publicreport.quick_image"."quick_id" = $1);
|
||||
15
db/sql/publicreport_image_with_json_by_quick_id.sql
Normal file
15
db/sql/publicreport_image_with_json_by_quick_id.sql
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
-- PublicreportImageWithJSONByQuickID
|
||||
SELECT
|
||||
"publicreport.image"."id" AS "id",
|
||||
"publicreport.image"."content_type" AS "content_type",
|
||||
"publicreport.image"."created" AS "created",
|
||||
"publicreport.image"."location" AS "location",
|
||||
ST_AsGeoJSON("publicreport.image"."location") AS "location_json",
|
||||
"publicreport.image"."resolution_x" AS "resolution_x",
|
||||
"publicreport.image"."resolution_y" AS "resolution_y",
|
||||
"publicreport.image"."storage_uuid" AS "storage_uuid",
|
||||
"publicreport.image"."storage_size" AS "storage_size",
|
||||
"publicreport.image"."uploaded_filename" AS "uploaded_filename"
|
||||
FROM "publicreport"."image" AS "publicreport.image"
|
||||
INNER JOIN "publicreport"."quick_image" AS "publicreport.quick_image" ON ("publicreport.image"."id" = "publicreport.quick_image"."image_id")
|
||||
WHERE ("publicreport.quick_image"."quick_id" = $1)
|
||||
|
|
@ -110,6 +110,8 @@ func bigNumber(n int) string {
|
|||
func makeFuncMap() template.FuncMap {
|
||||
funcMap := template.FuncMap{
|
||||
"bigNumber": bigNumber,
|
||||
"html": unescapeHTML,
|
||||
"json": unescapeJS,
|
||||
"GISStatement": gisStatement,
|
||||
"latLngDisplay": latLngDisplay,
|
||||
"publicReportID": publicReportID,
|
||||
|
|
@ -291,6 +293,12 @@ func timeSince(t time.Time) string {
|
|||
return fmt.Sprintf("%d days ago", int(days))
|
||||
}
|
||||
}
|
||||
func unescapeHTML(s string) template.HTML {
|
||||
return template.HTML(s)
|
||||
}
|
||||
func unescapeJS(s string) template.JS {
|
||||
return template.JS(s)
|
||||
}
|
||||
func uuidShort(uuid uuid.UUID) string {
|
||||
s := uuid.String()
|
||||
if len(s) < 7 {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
var map = null;
|
||||
// A map that just shows a single point location, and can't be moved
|
||||
class MapSinglePoint extends HTMLElement {
|
||||
// A map that just shows a bunch of markers, it can't change them
|
||||
class MapWithMarkers extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
@ -10,8 +10,10 @@ class MapSinglePoint extends HTMLElement {
|
|||
// Initial render
|
||||
this.render();
|
||||
|
||||
this._map = null;
|
||||
|
||||
// markers shown on the map. Should be none or 1, generally.
|
||||
this._markers = null;
|
||||
this._markers = [];
|
||||
}
|
||||
|
||||
// Lifecycle: when element is added to the DOM
|
||||
|
|
@ -35,7 +37,7 @@ class MapSinglePoint extends HTMLElement {
|
|||
|
||||
mapboxgl.accessToken = apiKey;
|
||||
const mapElement = this.shadowRoot.querySelector("#map");
|
||||
map = new mapboxgl.Map({
|
||||
this._map = new mapboxgl.Map({
|
||||
container: mapElement,
|
||||
center: {
|
||||
lat: lat,
|
||||
|
|
@ -44,7 +46,8 @@ class MapSinglePoint extends HTMLElement {
|
|||
style: 'mapbox://styles/mapbox/streets-v12', // style URL
|
||||
zoom: zoom,
|
||||
});
|
||||
map.on("load", function() {
|
||||
this._map.on("load", () => {
|
||||
console.log("map loaded");
|
||||
this.dispatchEvent(new CustomEvent('load'), {
|
||||
bubbles: true,
|
||||
composed: true, // Allows event to cross shadow DOM boundary
|
||||
|
|
@ -53,11 +56,13 @@ class MapSinglePoint extends HTMLElement {
|
|||
}
|
||||
});
|
||||
});
|
||||
this._markers = [];
|
||||
}
|
||||
|
||||
// Initial render of component
|
||||
render() {
|
||||
this.shadowRoot.innerHTML = `
|
||||
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.css' rel='stylesheet' />
|
||||
<style>
|
||||
.map-container {
|
||||
background-color: #e9ecef;
|
||||
|
|
@ -91,28 +96,16 @@ class MapSinglePoint extends HTMLElement {
|
|||
this._map.jumpTo(args);
|
||||
}
|
||||
|
||||
setMarker(coords) {
|
||||
console.log("Setting map marker", coords);
|
||||
this._map.jumpTo({
|
||||
center: coords,
|
||||
zoom: 14,
|
||||
});
|
||||
clearMarkers() {
|
||||
this._markers.forEach((marker) => marker.remove());
|
||||
|
||||
const marker = new mapboxgl.Marker({
|
||||
color: "#FF0000",
|
||||
draggable: true
|
||||
}).setLngLat(coords).addTo(map);
|
||||
marker.on('dragend', function(e) {
|
||||
const markerDraggedEvent = new CustomEvent("markerdragend", {
|
||||
detail: {
|
||||
marker: marker
|
||||
}
|
||||
});
|
||||
mapContainer.dispatchEvent(markerDraggedEvent);
|
||||
});
|
||||
this._markers = [marker];
|
||||
}
|
||||
addMarker(coords, color) {
|
||||
console.log("Add marker", coords, color);
|
||||
const el = document.createElement("div");
|
||||
el.id = "marker";
|
||||
const marker = new mapboxgl.Marker().setLngLat(coords).addTo(this._map);
|
||||
this._markers.push(marker);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('map-single-point', MapSinglePoint);
|
||||
customElements.define('map-with-markers', MapWithMarkers);
|
||||
|
|
@ -19,8 +19,6 @@ import (
|
|||
"github.com/stephenafamo/bob/dialect/psql/sm"
|
||||
"github.com/stephenafamo/scan"
|
||||
/*
|
||||
"strconv"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/h3utils"
|
||||
"github.com/aarondl/opt/omit"
|
||||
|
|
@ -33,7 +31,8 @@ type Contact struct {
|
|||
Phone string
|
||||
}
|
||||
type Image struct {
|
||||
URL string
|
||||
Location string
|
||||
URL string
|
||||
}
|
||||
type Report struct {
|
||||
Address string
|
||||
|
|
@ -167,7 +166,7 @@ func contentFromQuick(ctx context.Context, report_id string) (result ContentStat
|
|||
return result, fmt.Errorf("Failed to query nuisance %s: %w", report_id, err)
|
||||
}
|
||||
|
||||
images, err := quick.Images().All(ctx, db.PGInstance.BobDB)
|
||||
images, err := sql.PublicreportImageWithJSONByQuickID(quick.ID).All(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("Failed to get images %s: %w", report_id, err)
|
||||
}
|
||||
|
|
@ -183,23 +182,24 @@ func contentFromQuick(ctx context.Context, report_id string) (result ContentStat
|
|||
|
||||
for _, image := range images {
|
||||
result.Report.Images = append(result.Report.Images, Image{
|
||||
URL: fmt.Sprintf("https://%s/image/%s", config.RMODomain, image.StorageUUID),
|
||||
Location: image.LocationJSON,
|
||||
URL: fmt.Sprintf("https://%s/image/%s", config.RMODomain, image.StorageUUID),
|
||||
})
|
||||
}
|
||||
type LocationGeoJSON struct {
|
||||
Location string
|
||||
}
|
||||
row, err := bob.One(ctx, db.PGInstance.BobDB, psql.Select(
|
||||
location, err := bob.One(ctx, db.PGInstance.BobDB, psql.Select(
|
||||
sm.Columns(
|
||||
psql.F("ST_AsGeoJSON", "location"),
|
||||
),
|
||||
sm.From("publicreport.quick"),
|
||||
sm.Where(psql.Quote("public_id").EQ(psql.Arg(report_id))),
|
||||
), scan.StructMapper[LocationGeoJSON]())
|
||||
), scan.SingleColumnMapper[string])
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("Failed to query nuisance %s: %w", report_id, err)
|
||||
}
|
||||
result.Report.Location = row.Location
|
||||
result.Report.Location = location
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
{{define "title"}}Status of report {{.Report.ID|publicReportID}}{{end}}
|
||||
{{define "extraheader"}}
|
||||
<script src="/static/js/map-single-point.js"></script>
|
||||
<script src='https://api.mapbox.com/mapbox-gl-js/v3.17.0-beta.1/mapbox-gl.js'></script>
|
||||
<script src="/static/js/map-with-markers.js"></script>
|
||||
<style>
|
||||
.timeline {
|
||||
border-left: 3px solid #dee2e6;
|
||||
|
|
@ -39,6 +40,25 @@
|
|||
font-size: 1rem;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
const GEOJSON_LOCATION = {{.Report.Location|json}};
|
||||
const GEOJSON_IMAGE_LOCATIONS = [
|
||||
{{ range .Report.Images }}
|
||||
{{ .Location|json }},
|
||||
{{ end }}
|
||||
];
|
||||
function onLoad() {
|
||||
const map = document.querySelector("map-with-markers");
|
||||
map.addEventListener("load", (event) => {
|
||||
map.jumpTo({
|
||||
center: GEOJSON_LOCATION.coordinates,
|
||||
zoom: 14,
|
||||
});
|
||||
map.addMarker(GEOJSON_LOCATION.coordinates, "#FF0000");
|
||||
});
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", onLoad);
|
||||
</script>
|
||||
{{end}}
|
||||
{{define "content"}}
|
||||
<div class="container my-4">
|
||||
|
|
@ -101,7 +121,9 @@
|
|||
<h5 class="mb-0"><i class="fas fa-history me-2"></i>Report Detail</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p><strong>Foo:</strong>Bar</p>
|
||||
{{ if not (eq .Report.Comments "") }}
|
||||
<p><strong>Comments:</strong>{{ .Report.Comments }}</p>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -111,10 +133,9 @@
|
|||
<h5 class="mb-0"><i class="fas fa-map-marked-alt me-2"></i>Location Map</h5>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<map-single-point
|
||||
<map-with-markers
|
||||
api-key="{{ .MapboxToken }}"
|
||||
geojson="{{ .Report.Location }}"
|
||||
zoom="14"></map-single-point>
|
||||
zoom="14"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -134,6 +155,7 @@
|
|||
</div>
|
||||
|
||||
<!-- History Timeline -->
|
||||
<!--
|
||||
<div class="card">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h5 class="mb-0"><i class="fas fa-history me-2"></i>Request History</h5>
|
||||
|
|
@ -163,5 +185,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue