Only show image count, re-add timeline

This commit is contained in:
Eli Ribble 2026-02-05 02:36:24 +00:00
parent 287133e35d
commit 947ece00f1
No known key found for this signature in database
5 changed files with 180 additions and 65 deletions

View file

@ -0,0 +1,112 @@
// Code generated by BobGen psql v0.42.5. 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/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/bob/dialect/psql"
"github.com/Gleipnir-Technology/bob/dialect/psql/dialect"
"github.com/Gleipnir-Technology/bob/orm"
"github.com/aarondl/opt/null"
"github.com/google/uuid"
"github.com/stephenafamo/scan"
)
//go:embed publicreport_image_with_json_by_nuisance_id.bob.sql
var formattedQueries_publicreport_image_with_json_by_nuisance_id string
var publicreportImageWithJSONByNuisanceIDSQL = formattedQueries_publicreport_image_with_json_by_nuisance_id[175:983]
type PublicreportImageWithJSONByNuisanceIDQuery = orm.ModQuery[*dialect.SelectQuery, publicreportImageWithJSONByNuisanceID, PublicreportImageWithJSONByNuisanceIDRow, []PublicreportImageWithJSONByNuisanceIDRow, publicreportImageWithJSONByNuisanceIDTransformer]
func PublicreportImageWithJSONByNuisanceID(NuisanceID int32) *PublicreportImageWithJSONByNuisanceIDQuery {
var expressionTypArgs publicreportImageWithJSONByNuisanceID
expressionTypArgs.NuisanceID = psql.Arg(NuisanceID)
return &PublicreportImageWithJSONByNuisanceIDQuery{
Query: orm.Query[publicreportImageWithJSONByNuisanceID, PublicreportImageWithJSONByNuisanceIDRow, []PublicreportImageWithJSONByNuisanceIDRow, publicreportImageWithJSONByNuisanceIDTransformer]{
ExecQuery: orm.ExecQuery[publicreportImageWithJSONByNuisanceID]{
BaseQuery: bob.BaseQuery[publicreportImageWithJSONByNuisanceID]{
Expression: expressionTypArgs,
Dialect: dialect.Dialect,
QueryType: bob.QueryTypeSelect,
},
},
Scanner: func(context.Context, []string) (func(*scan.Row) (any, error), func(any) (PublicreportImageWithJSONByNuisanceIDRow, error)) {
return func(row *scan.Row) (any, error) {
var t PublicreportImageWithJSONByNuisanceIDRow
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) (PublicreportImageWithJSONByNuisanceIDRow, error) {
return *(v.(*PublicreportImageWithJSONByNuisanceIDRow)), nil
}
},
},
Mod: bob.ModFunc[*dialect.SelectQuery](func(q *dialect.SelectQuery) {
q.AppendSelect(expressionTypArgs.subExpr(9, 549))
q.SetTable(expressionTypArgs.subExpr(555, 751))
q.AppendWhere(expressionTypArgs.subExpr(759, 807))
}),
}
}
type PublicreportImageWithJSONByNuisanceIDRow = 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 publicreportImageWithJSONByNuisanceIDTransformer = bob.SliceTransformer[PublicreportImageWithJSONByNuisanceIDRow, []PublicreportImageWithJSONByNuisanceIDRow]
type publicreportImageWithJSONByNuisanceID struct {
NuisanceID bob.Expression
}
func (o publicreportImageWithJSONByNuisanceID) args() iter.Seq[orm.ArgWithPosition] {
return func(yield func(arg orm.ArgWithPosition) bool) {
if !yield(orm.ArgWithPosition{
Name: "nuisanceID",
Start: 805,
Stop: 807,
Expression: o.NuisanceID,
}) {
return
}
}
}
func (o publicreportImageWithJSONByNuisanceID) raw(from, to int) string {
return publicreportImageWithJSONByNuisanceIDSQL[from:to]
}
func (o publicreportImageWithJSONByNuisanceID) subExpr(from, to int) bob.Expression {
return orm.ArgsToExpression(publicreportImageWithJSONByNuisanceIDSQL, from, to, o.args())
}
func (o publicreportImageWithJSONByNuisanceID) WriteSQL(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) {
return o.subExpr(0, len(publicreportImageWithJSONByNuisanceIDSQL)).WriteSQL(ctx, w, d, start)
}

View file

@ -0,0 +1,18 @@
-- Code generated by BobGen psql v0.42.5. DO NOT EDIT.
-- This file is meant to be re-generated in place and/or deleted at any time.
-- PublicreportImageWithJSONByNuisanceID
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"."nuisance_image" AS "publicreport.nuisance_image" ON ("publicreport.image"."id" = "publicreport.nuisance_image"."image_id")
WHERE ("publicreport.nuisance_image"."nuisance_id" = $1);

View file

@ -0,0 +1,15 @@
-- PublicreportImageWithJSONByNuisanceID
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"."nuisance_image" AS "publicreport.nuisance_image" ON ("publicreport.image"."id" = "publicreport.nuisance_image"."image_id")
WHERE ("publicreport.nuisance_image"."nuisance_id" = $1)

View file

@ -37,26 +37,28 @@ type ContentStatusByID struct {
District *ContentDistrict
MapboxToken string
Report Report
Timeline []TimelineEntry
URL ContentURL
}
type DetailEntry struct {
Name string
Value string
}
type Image struct {
Location string
URL string
}
type Report struct {
Address string
Comments string
Created time.Time
Details []DetailEntry
ID string
Images []Image
Location string // GeoJSON
Status string
Type string
Address string
Comments string
Created time.Time
Details []DetailEntry
ID string
ImageCount int
Location string // GeoJSON
Status string
Type string
}
type TimelineEntry struct {
At time.Time
Detail string
Title string
}
var (
@ -109,9 +111,16 @@ func contentFromNuisance(ctx context.Context, report_id string) (result ContentS
if err != nil {
return result, fmt.Errorf("Failed to query nuisance %s: %w", report_id, err)
}
images, err := sql.PublicreportImageWithJSONByNuisanceID(nuisance.ID).All(ctx, db.PGInstance.BobDB)
if err != nil {
return result, fmt.Errorf("Failed to get images %s: %w", report_id, err)
}
result.Report.ID = report_id
result.Report.Address = nuisance.Address
result.Report.Created = nuisance.Created
result.Report.ImageCount = len(images)
result.Report.Status = nuisance.Status.String()
result.Report.Type = nuisance.Status.String()
result.Report.Details = []DetailEntry{
@ -136,6 +145,13 @@ func contentFromNuisance(ctx context.Context, report_id string) (result ContentS
Value: "guess not",
},
}
result.Timeline = []TimelineEntry{
TimelineEntry{
At: nuisance.Created,
Detail: "Initial report was submitted",
Title: "Created",
},
}
type LocationGeoJSON struct {
Location string
@ -165,23 +181,12 @@ 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 := 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)
}
result.Report.ID = report_id
result.Report.Address = quick.Address
result.Report.Comments = quick.Comments
result.Report.Created = quick.Created
result.Report.Type = "Quick"
for _, image := range images {
result.Report.Images = append(result.Report.Images, Image{
Location: image.LocationJSON,
URL: config.MakeURLReport("/image/%s", image.StorageUUID.String()),
})
}
type LocationGeoJSON struct {
Location string
}

View file

@ -42,11 +42,6 @@
</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) => {
@ -101,7 +96,7 @@ document.addEventListener("DOMContentLoaded", onLoad);
<div class="col-md-12">
<strong><i class="fas fa-images me-2"></i>Images:</strong>
<span>{{ if gt (len .Report.Images) 0 }}{{len .Report.Images}}{{else}}None provided{{end}}</span>
<span>{{ if gt .Report.ImageCount 0 }}{{.Report.ImageCount}}{{else}}None provided{{end}}</span>
</div>
</div>
{{range .Report.Details}}
@ -127,52 +122,22 @@ document.addEventListener("DOMContentLoaded", onLoad);
</div>
</div>
<div class="card mb-4">
<div class="card-header bg-info text-white">
<h5 class="mb-0"><i class="fas fa-photo me-2"></i>Images</h5>
</div>
<div class="card-body p-0">
{{ if gt (len .Report.Images) 0 }}
{{ range .Report.Images }}
<img src="{{ .URL }}" width="256"/>
{{ end }}
{{ else }}
<p>None</p>
{{ end }}
</div>
</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>
</div>
<div class="card-body">
<div class="timeline">
{{range .Timeline}}
<div class="timeline-item">
<div class="timeline-date">July 17, 2023 - 2:45 PM</div>
<h5 class="mb-1">Scheduled for Treatment</h5>
<p class="mb-0">Site visit scheduled for July 19. Technician: Michael Johnson</p>
</div>
<div class="timeline-item">
<div class="timeline-date">July 16, 2023 - 10:30 AM</div>
<h5 class="mb-1">Assessment Complete</h5>
<p class="mb-0">Initial assessment completed. Property requires treatment for mosquito larvae.</p>
</div>
<div class="timeline-item">
<div class="timeline-date">July 15, 2023 - 1:15 PM</div>
<h5 class="mb-1">In Review</h5>
<p class="mb-0">Report assigned to field supervisor for initial assessment.</p>
</div>
<div class="timeline-item">
<div class="timeline-date">July 15, 2023 - 9:30 AM</div>
<h5 class="mb-1">Report Created</h5>
<p class="mb-0">New mosquito nuisance report submitted by Jane Doe.</p>
<div class="timeline-date">{{.At|timeSince}}</div>
<h5 class="mb-1">{{.Title}}</h5>
<p class="mb-0">{{.Detail}}</p>
</div>
{{end}}
</div>
</div>
</div>
-->
</div>
{{end}}