From c8c475911b9aa1c45e1d47ddc17055992abfdfca Mon Sep 17 00:00:00 2001 From: Nathan Coad Date: Fri, 21 Mar 2025 20:37:22 +1100 Subject: [PATCH] update template --- Dockerfile | 2 +- components/views/incoming.templ | 80 +++++++++ components/views/incoming_templ.go | 270 +++++++++++++++++++++++++++++ go.mod | 41 ++--- server/handler/incomingReport.go | 105 +++++++++++ 5 files changed, 477 insertions(+), 21 deletions(-) create mode 100644 components/views/incoming.templ create mode 100644 components/views/incoming_templ.go create mode 100644 server/handler/incomingReport.go diff --git a/Dockerfile b/Dockerfile index fde6446..af08027 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ## Build -FROM golang:1.22-alpine AS build +FROM golang:1.24-alpine AS build ARG VERSION='dev' diff --git a/components/views/incoming.templ b/components/views/incoming.templ new file mode 100644 index 0000000..77cb0fd --- /dev/null +++ b/components/views/incoming.templ @@ -0,0 +1,80 @@ +package views + +import ( + "strconv" + "wnzl-snow/components/core" +) + +type IncomingRow struct { + ID int + IncidentNumber string + Description string + ShortDescription string + Urgency string + Impact string + State string + ExternalID string + WorkNotes string + AssignmentGroup string + AssignedTo string + Category string + Subcategory string + CreatedAt string +} + +templ IncomingTable(rows []IncomingRow) { + + + @core.Header() + +
+
+

Incoming Incidents

+
+ + + + + + + + + + + + + + + + + + + + + for _, row := range rows { + + + + + + + + + + + + + + + + + } + +
IDIncident #DescriptionShort DescriptionUrgencyImpactStateExternal IDWork NotesAssignment GroupAssigned ToCategorySubcategoryCreated At
{ strconv.Itoa(row.ID) }{ row.IncidentNumber }{ row.Description }{ row.ShortDescription }{ row.Urgency }{ row.Impact }{ row.State }{ row.ExternalID }{ row.WorkNotes }{ row.AssignmentGroup }{ row.AssignedTo }{ row.Category }{ row.Subcategory }{ row.CreatedAt }
+
+
+
+ @core.Footer() + + +} \ No newline at end of file diff --git a/components/views/incoming_templ.go b/components/views/incoming_templ.go new file mode 100644 index 0000000..4d3f5df --- /dev/null +++ b/components/views/incoming_templ.go @@ -0,0 +1,270 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.778 +package views + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import ( + "strconv" + "wnzl-snow/components/core" +) + +type IncomingRow struct { + ID int + IncidentNumber string + Description string + ShortDescription string + Urgency string + Impact string + State string + ExternalID string + WorkNotes string + AssignmentGroup string + AssignedTo string + Category string + Subcategory string + CreatedAt string +} + +func IncomingTable(rows []IncomingRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = core.Header().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Incoming Incidents

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, row := range rows { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
IDIncident #DescriptionShort DescriptionUrgencyImpactStateExternal IDWork NotesAssignment GroupAssigned ToCategorySubcategoryCreated At
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(row.ID)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 56, Col: 80} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(row.IncidentNumber) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 57, Col: 78} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(row.Description) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 58, Col: 75} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(row.ShortDescription) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 59, Col: 80} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(row.Urgency) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 60, Col: 71} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(row.Impact) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 61, Col: 70} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(row.State) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 62, Col: 69} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(row.ExternalID) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 63, Col: 74} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(row.WorkNotes) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 64, Col: 73} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(row.AssignmentGroup) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 65, Col: 79} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(row.AssignedTo) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 66, Col: 74} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(row.Category) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 67, Col: 72} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(row.Subcategory) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 68, Col: 75} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(row.CreatedAt) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/incoming.templ`, Line: 69, Col: 73} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = core.Footer().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/go.mod b/go.mod index 8b85926..00c5f6e 100644 --- a/go.mod +++ b/go.mod @@ -3,22 +3,23 @@ module wnzl-snow go 1.24.1 require ( - github.com/a-h/templ v0.2.778 - github.com/go-co-op/gocron/v2 v2.12.1 + github.com/a-h/templ v0.3.833 + github.com/go-co-op/gocron/v2 v2.16.1 github.com/jmoiron/sqlx v1.4.0 github.com/joho/godotenv v1.5.1 - github.com/pressly/goose/v3 v3.22.1 + github.com/pressly/goose/v3 v3.24.1 github.com/xuri/excelize/v2 v2.9.0 gopkg.in/yaml.v2 v2.4.0 - modernc.org/sqlite v1.33.1 + modernc.org/sqlite v1.36.1 ) require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/jonboulle/clockwork v0.4.0 // indirect - github.com/kr/pretty v0.3.0 // indirect + github.com/jonboulle/clockwork v0.5.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mfridman/interpolate v0.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -27,21 +28,21 @@ require ( github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/msoleps v1.0.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect - github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/sethvargo/go-retry v0.3.0 // indirect - github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect - github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect + github.com/xuri/efp v0.0.0-20250227110027-3491fafc2b79 // indirect + github.com/xuri/nfp v0.0.0-20250226145837-86d5fc24b2ba // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.28.0 // indirect - golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect - golang.org/x/net v0.30.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect - modernc.org/gc/v3 v3.0.0-20241004144649-1aea3fae8852 // indirect - modernc.org/libc v1.61.0 // indirect - modernc.org/mathutil v1.6.0 // indirect - modernc.org/memory v1.8.0 // indirect - modernc.org/strutil v1.2.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect + golang.org/x/net v0.37.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + modernc.org/gc/v3 v3.0.0 // indirect + modernc.org/libc v1.61.13 // indirect + modernc.org/mathutil v1.7.1 // indirect + modernc.org/memory v1.9.0 // indirect + modernc.org/strutil v1.2.1 // indirect modernc.org/token v1.1.0 // indirect ) diff --git a/server/handler/incomingReport.go b/server/handler/incomingReport.go new file mode 100644 index 0000000..63e2838 --- /dev/null +++ b/server/handler/incomingReport.go @@ -0,0 +1,105 @@ +package handler + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "wnzl-snow/components/views" +) + +func (h *Handler) RenderIncomingTable(w http.ResponseWriter, r *http.Request) { + /* + db, err := sql.Open("sqlite3", "./your.db") + if err != nil { + http.Error(w, "Failed to connect to the database", http.StatusInternalServerError) + return + } + defer db.Close() + + query := ` + SELECT + id, + incident_number, + description, + short_description, + urgency, + impact, + state, + external_id, + work_notes, + assignment_group, + assigned_to, + category, + subcategory, + created_at + FROM incoming + ORDER BY created_at DESC + ` + + rows, err := db.Query(query) + if err != nil { + http.Error(w, "Failed to query the database", http.StatusInternalServerError) + return + } + defer rows.Close() + + var results []views.IncomingRow + for rows.Next() { + var row views.IncomingRow + err := rows.Scan( + &row.ID, + &row.IncidentNumber, + &row.Description, + &row.ShortDescription, + &row.Urgency, + &row.Impact, + &row.State, + &row.ExternalID, + &row.WorkNotes, + &row.AssignmentGroup, + &row.AssignedTo, + &row.Category, + &row.Subcategory, + &row.CreatedAt, + ) + if err != nil { + log.Printf("Scan error: %v", err) + continue + } + results = append(results, row) + } + + if err := rows.Err(); err != nil { + log.Printf("Row iteration error: %v", err) + } + */ + + ctx := context.Background() + + h.Logger.Debug("Querying updates table") + results, err := h.Database.Queries().GetReportUpdates(ctx) + if err != nil { + h.Logger.Error("Unable to query incoming table", "error", err) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusInternalServerError) + json.NewEncoder(w).Encode(map[string]string{ + "status": "ERROR", + "message": fmt.Sprintf("Unable to query incoming table: '%s'", err), + }) + return + } + + if len(results) == 0 { + h.Logger.Error("Empty updates result") + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusInternalServerError) + json.NewEncoder(w).Encode(map[string]string{ + "status": "ERROR", + "message": fmt.Sprintf("Empty updates result"), + }) + return + } + + views.IncomingTable(results).Render(r.Context(), w) +}