Move handler objects to common location to share with RMO
This commit is contained in:
parent
87fe5ec2e5
commit
0f6da8e25f
33 changed files with 449 additions and 308 deletions
15
html/config.go
Normal file
15
html/config.go
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package html
|
||||
|
||||
import (
|
||||
"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||
)
|
||||
|
||||
type ContentConfig struct {
|
||||
IsProductionEnvironment bool
|
||||
}
|
||||
|
||||
func NewContentConfig() ContentConfig {
|
||||
return ContentConfig{
|
||||
IsProductionEnvironment: config.IsProductionEnvironment(),
|
||||
}
|
||||
}
|
||||
7
html/content.go
Normal file
7
html/content.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package html
|
||||
|
||||
type Content[T any] struct {
|
||||
C T
|
||||
Config ContentConfig
|
||||
URL ContentURL
|
||||
}
|
||||
26
html/handler.go
Normal file
26
html/handler.go
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package html
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type handlerFunctionGet[T any] func(context.Context, *http.Request) (*Response[T], *nhttp.ErrorWithStatus)
|
||||
|
||||
func MakeGet[T any](f handlerFunctionGet[T]) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
resp, e := f(ctx, r)
|
||||
if e != nil {
|
||||
log.Warn().Int("status", e.Status)
|
||||
http.Error(w, e.Error(), e.Status)
|
||||
return
|
||||
}
|
||||
RenderOrError(w, resp.Template, Content[T]{
|
||||
C: resp.Content,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -38,3 +38,15 @@ func RespondError(w http.ResponseWriter, m string, e error, s int) {
|
|||
log.Warn().Int("status", s).Err(e).Str("user message", m).Msg("Responding with an error")
|
||||
http.Error(w, m, s)
|
||||
}
|
||||
|
||||
type Response[T any] struct {
|
||||
Content T
|
||||
Template string
|
||||
}
|
||||
|
||||
func NewResponse[T any](template string, content T) *Response[T] {
|
||||
return &Response[T]{
|
||||
Content: content,
|
||||
Template: template,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package sync
|
||||
package html
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
|
@ -6,7 +6,7 @@ import (
|
|||
"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||
)
|
||||
|
||||
type contentURL struct {
|
||||
type ContentURL struct {
|
||||
Configuration contentURLConfiguration
|
||||
OAuthRefreshArcGIS string
|
||||
Root string
|
||||
|
|
@ -16,8 +16,8 @@ type contentURL struct {
|
|||
Upload contentURLUpload
|
||||
}
|
||||
|
||||
func newContentURL() contentURL {
|
||||
return contentURL{
|
||||
func NewContentURL() ContentURL {
|
||||
return ContentURL{
|
||||
Configuration: newContentURLConfiguration(),
|
||||
OAuthRefreshArcGIS: config.MakeURLNidus("/arcgis/oauth/begin"),
|
||||
Root: config.MakeURLNidus("/"),
|
||||
32
http/error_with_status.go
Normal file
32
http/error_with_status.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type ErrorWithStatus struct {
|
||||
Message string
|
||||
Status int
|
||||
}
|
||||
|
||||
func (e *ErrorWithStatus) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
func NewError(mesg_format string, args ...any) *ErrorWithStatus {
|
||||
return NewErrorStatus(http.StatusInternalServerError, mesg_format, args...)
|
||||
}
|
||||
func NewErrorMaybe(mesg_format string, err error, args ...any) *ErrorWithStatus {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
allArgs := append([]any{err}, args...)
|
||||
return NewErrorStatus(http.StatusInternalServerError, mesg_format, allArgs...)
|
||||
}
|
||||
func NewErrorStatus(status int, mesg_format string, args ...any) *ErrorWithStatus {
|
||||
w := fmt.Errorf(mesg_format, args...)
|
||||
return &ErrorWithStatus{
|
||||
Message: w.Error(),
|
||||
Status: status,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,67 @@
|
|||
package rmo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/bob"
|
||||
"github.com/Gleipnir-Technology/bob/dialect/psql"
|
||||
"github.com/Gleipnir-Technology/bob/dialect/psql/sm"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/stephenafamo/scan"
|
||||
//"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||
)
|
||||
|
||||
type contentMailer struct{}
|
||||
type address struct {
|
||||
Number int32 `db:"number_"`
|
||||
Street string `db:"street"`
|
||||
Locality string `db:"locality"`
|
||||
PostalCode string `db:"postal_code"`
|
||||
Country string `db:"country"`
|
||||
}
|
||||
type contentMailer struct {
|
||||
Address address
|
||||
}
|
||||
|
||||
func getMailer(w http.ResponseWriter, r *http.Request) {
|
||||
func getMailer(ctx context.Context, r *http.Request) (*html.Response[contentMailer], *nhttp.ErrorWithStatus) {
|
||||
public_id := chi.URLParam(r, "public_id")
|
||||
if public_id == "" {
|
||||
return nil, nhttp.NewErrorStatus(http.StatusBadRequest, "No 'public_id' in the url params")
|
||||
}
|
||||
|
||||
/*
|
||||
compliance_request, err := models.ComplianceReportRequests.Query(
|
||||
models.Preload.ComplianceReportRequest.Site(),
|
||||
models.SelectWhere.ComplianceReportRequests.PublicID.EQ(public_id),
|
||||
).One(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
respondError(w, "failed to get compliance request", err, http.StatusBadRequest)
|
||||
}
|
||||
site := compliance_request.
|
||||
*/
|
||||
report, err := bob.One(ctx, db.PGInstance.BobDB, psql.Select(
|
||||
sm.Columns(
|
||||
"address.number_",
|
||||
"address.street",
|
||||
"address.locality",
|
||||
"address.postal_code",
|
||||
"address.country",
|
||||
),
|
||||
sm.From("compliance_report_request").As("crr"),
|
||||
sm.InnerJoin("site").OnEQ(psql.Raw("crr.site_id"), psql.Raw("site.id")),
|
||||
sm.InnerJoin("address").OnEQ(psql.Raw("site.address_id"), psql.Raw("address.id")),
|
||||
sm.Where(psql.Raw("crr.public_id").EQ(psql.Arg(public_id))),
|
||||
), scan.StructMapper[address]())
|
||||
if err != nil {
|
||||
return nil, nhttp.NewErrorStatus(http.StatusNotFound, "No compliance report with that public ID")
|
||||
}
|
||||
return html.NewResponse(
|
||||
"rmo/mailer.html", contentMailer{
|
||||
Address: report,
|
||||
},
|
||||
), nil
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func Router() chi.Router {
|
|||
r.Get("/email/unsubscribe", getEmailUnsubscribe)
|
||||
r.Get("/email/unsubscribe/report/{report_id}", getEmailReportUnsubscribe)
|
||||
r.Get("/image/{uuid}", getImageByUUID)
|
||||
r.Get("/mailer/{public_id}", getMailer)
|
||||
r.Get("/mailer/{public_id}", html.MakeGet(getMailer))
|
||||
r.Route("/mock", addMockRoutes)
|
||||
r.Post("/register-notifications", postRegisterNotifications)
|
||||
r.Get("/register-notifications-complete", getRegisterNotificationsComplete)
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentAdminDash struct{}
|
||||
|
||||
func getAdminDash(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentAdminDash], *errorWithStatus) {
|
||||
func getAdminDash(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentAdminDash], *nhttp.ErrorWithStatus) {
|
||||
content := contentAdminDash{}
|
||||
return newResponse("sync/admin-dash.html", content), nil
|
||||
return html.NewResponse("sync/admin-dash.html", content), nil
|
||||
}
|
||||
|
|
|
|||
24
sync/cell.go
24
sync/cell.go
|
|
@ -6,6 +6,8 @@ import (
|
|||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/h3utils"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/uber/h3-go/v4"
|
||||
)
|
||||
|
|
@ -19,46 +21,46 @@ type contentCell struct {
|
|||
Treatments []Treatment
|
||||
}
|
||||
|
||||
func getCellDetails(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentCell], *errorWithStatus) {
|
||||
func getCellDetails(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentCell], *nhttp.ErrorWithStatus) {
|
||||
cell_str := chi.URLParam(r, "cell")
|
||||
if cell_str == "" {
|
||||
return nil, newErrorStatus(http.StatusBadRequest, "There should always be a cell")
|
||||
return nil, nhttp.NewErrorStatus(http.StatusBadRequest, "There should always be a cell")
|
||||
}
|
||||
c, err := HexToInt64(cell_str)
|
||||
if err != nil {
|
||||
return nil, newErrorStatus(http.StatusBadRequest, "Cannot convert provided cell to uint64")
|
||||
return nil, nhttp.NewErrorStatus(http.StatusBadRequest, "Cannot convert provided cell to uint64")
|
||||
}
|
||||
center, err := h3.Cell(c).LatLng()
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get center: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get center: %w", err)
|
||||
}
|
||||
boundary, err := h3.Cell(c).Boundary()
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get boundary: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get boundary: %w", err)
|
||||
}
|
||||
inspections, err := inspectionsByCell(ctx, org, h3.Cell(c))
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get inspections by cell: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get inspections by cell: %w", err)
|
||||
}
|
||||
geojson, err := h3utils.H3ToGeoJSON([]h3.Cell{h3.Cell(c)})
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get boundaries: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get boundaries: %w", err)
|
||||
}
|
||||
resolution := h3.Cell(c).Resolution()
|
||||
sources, err := breedingSourcesByCell(ctx, org, h3.Cell(c))
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get sources: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get sources: %w", err)
|
||||
}
|
||||
traps, err := trapsByCell(ctx, org, h3.Cell(c))
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get traps: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get traps: %w", err)
|
||||
}
|
||||
|
||||
treatments, err := treatmentsByCell(ctx, org, h3.Cell(c))
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get treatments: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get treatments: %w", err)
|
||||
}
|
||||
return newResponse("sync/cell.html", contentCell{
|
||||
return html.NewResponse("sync/cell.html", contentCell{
|
||||
BreedingSources: sources,
|
||||
CellBoundary: boundary,
|
||||
Inspections: inspections,
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentCommunicationRoot struct{}
|
||||
|
||||
func getCommunicationRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentCommunicationRoot], *errorWithStatus) {
|
||||
return newResponse("sync/communication-root.html", contentCommunicationRoot{}), nil
|
||||
func getCommunicationRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentCommunicationRoot], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/communication-root.html", contentCommunicationRoot{}), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,26 +5,17 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/arcgis"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
//"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type contentConfig struct {
|
||||
IsProductionEnvironment bool
|
||||
}
|
||||
|
||||
func newContentConfig() contentConfig {
|
||||
return contentConfig{
|
||||
IsProductionEnvironment: config.IsProductionEnvironment(),
|
||||
}
|
||||
}
|
||||
|
||||
type contentConfigurationRoot struct{}
|
||||
|
||||
func getConfigurationRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentConfigurationRoot], *errorWithStatus) {
|
||||
return newResponse("sync/configuration/root.html", contentConfigurationRoot{}), nil
|
||||
func getConfigurationRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentConfigurationRoot], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/configuration/root.html", contentConfigurationRoot{}), nil
|
||||
}
|
||||
|
||||
type contentSettingOrganization struct {
|
||||
|
|
@ -35,10 +26,10 @@ type contentSettingIntegration struct {
|
|||
ArcGISOAuth *models.ArcgisOauthToken
|
||||
}
|
||||
|
||||
func getConfigurationOrganization(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentSettingOrganization], *errorWithStatus) {
|
||||
func getConfigurationOrganization(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*html.Response[contentSettingOrganization], *nhttp.ErrorWithStatus) {
|
||||
org, err := u.Organization().One(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
return nil, newError("get organization: %w", err)
|
||||
return nil, nhttp.NewError("get organization: %w", err)
|
||||
}
|
||||
/*
|
||||
var district contentDistrict
|
||||
|
|
@ -74,44 +65,44 @@ func getConfigurationOrganization(ctx context.Context, r *http.Request, org *mod
|
|||
data := contentSettingOrganization{
|
||||
Organization: org,
|
||||
}
|
||||
return newResponse("sync/configuration/organization.html", data), nil
|
||||
return html.NewResponse("sync/configuration/organization.html", data), nil
|
||||
}
|
||||
func getConfigurationIntegration(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentSettingIntegration], *errorWithStatus) {
|
||||
func getConfigurationIntegration(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*html.Response[contentSettingIntegration], *nhttp.ErrorWithStatus) {
|
||||
oauth, err := arcgis.GetOAuthForUser(ctx, u)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get oauth: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get oauth: %w", err)
|
||||
}
|
||||
data := contentSettingIntegration{
|
||||
ArcGISOAuth: oauth,
|
||||
}
|
||||
return newResponse("sync/configuration/integration.html", data), nil
|
||||
return html.NewResponse("sync/configuration/integration.html", data), nil
|
||||
}
|
||||
func getConfigurationIntegrationArcgis(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentSettingIntegration], *errorWithStatus) {
|
||||
func getConfigurationIntegrationArcgis(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*html.Response[contentSettingIntegration], *nhttp.ErrorWithStatus) {
|
||||
oauth, err := arcgis.GetOAuthForUser(ctx, u)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get oauth: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get oauth: %w", err)
|
||||
}
|
||||
data := contentSettingIntegration{
|
||||
ArcGISOAuth: oauth,
|
||||
}
|
||||
return newResponse("sync/configuration/integration-arcgis.html", data), nil
|
||||
return html.NewResponse("sync/configuration/integration-arcgis.html", data), nil
|
||||
}
|
||||
|
||||
type contentSettingPlaceholder struct{}
|
||||
|
||||
func getConfigurationPesticide(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentSettingPlaceholder], *errorWithStatus) {
|
||||
func getConfigurationPesticide(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentSettingPlaceholder], *nhttp.ErrorWithStatus) {
|
||||
content := contentSettingPlaceholder{}
|
||||
return newResponse("sync/configuration/pesticide.html", content), nil
|
||||
return html.NewResponse("sync/configuration/pesticide.html", content), nil
|
||||
}
|
||||
func getConfigurationPesticideAdd(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentSettingPlaceholder], *errorWithStatus) {
|
||||
func getConfigurationPesticideAdd(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentSettingPlaceholder], *nhttp.ErrorWithStatus) {
|
||||
content := contentSettingPlaceholder{}
|
||||
return newResponse("sync/configuration/pesticide-add.html", content), nil
|
||||
return html.NewResponse("sync/configuration/pesticide-add.html", content), nil
|
||||
}
|
||||
func getConfigurationUserAdd(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentSettingPlaceholder], *errorWithStatus) {
|
||||
func getConfigurationUserAdd(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentSettingPlaceholder], *nhttp.ErrorWithStatus) {
|
||||
content := contentSettingPlaceholder{}
|
||||
return newResponse("sync/configuration/user-add.html", content), nil
|
||||
return html.NewResponse("sync/configuration/user-add.html", content), nil
|
||||
}
|
||||
func getConfigurationUserList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentSettingPlaceholder], *errorWithStatus) {
|
||||
func getConfigurationUserList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentSettingPlaceholder], *nhttp.ErrorWithStatus) {
|
||||
content := contentSettingPlaceholder{}
|
||||
return newResponse("sync/configuration/user-list.html", content), nil
|
||||
return html.NewResponse("sync/configuration/user-list.html", content), nil
|
||||
}
|
||||
|
|
|
|||
45
sync/dash.go
45
sync/dash.go
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
|
@ -61,8 +62,8 @@ func getDistrict(w http.ResponseWriter, r *http.Request) {
|
|||
html.RenderOrError(w, "sync/district.html", &context)
|
||||
}
|
||||
|
||||
func getLayoutTest(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentLayoutTest], *errorWithStatus) {
|
||||
return newResponse("sync/layout-test.html", contentLayoutTest{}), nil
|
||||
func getLayoutTest(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentLayoutTest], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/layout-test.html", contentLayoutTest{}), nil
|
||||
}
|
||||
|
||||
func getRoot(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -93,40 +94,40 @@ func getRoot(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func getSource(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentSource], *errorWithStatus) {
|
||||
func getSource(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentSource], *nhttp.ErrorWithStatus) {
|
||||
globalid_s := chi.URLParam(r, "globalid")
|
||||
if globalid_s == "" {
|
||||
return nil, newError("No globalid provided: %w", nil)
|
||||
return nil, nhttp.NewError("No globalid provided: %w", nil)
|
||||
}
|
||||
globalid, err := uuid.Parse(globalid_s)
|
||||
if err != nil {
|
||||
return nil, newError("globalid is not a UUID: %w", nil)
|
||||
return nil, nhttp.NewError("globalid is not a UUID: %w", nil)
|
||||
}
|
||||
userContent, err := contentForUser(r.Context(), user)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get user content: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get user content: %w", err)
|
||||
}
|
||||
s, err := sourceByGlobalId(r.Context(), org, globalid)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get source: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get source: %w", err)
|
||||
}
|
||||
inspections, err := inspectionsBySource(r.Context(), org, globalid)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get inspections: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get inspections: %w", err)
|
||||
}
|
||||
traps, err := trapsBySource(r.Context(), org, globalid)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get traps: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get traps: %w", err)
|
||||
}
|
||||
|
||||
treatments, err := treatmentsBySource(r.Context(), org, globalid)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get treatments: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get treatments: %w", err)
|
||||
}
|
||||
treatment_models := modelTreatment(treatments)
|
||||
latlng, err := s.H3Cell.LatLng()
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get latlng: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get latlng: %w", err)
|
||||
}
|
||||
data := contentSource{
|
||||
Inspections: inspections,
|
||||
|
|
@ -148,40 +149,40 @@ func getSource(ctx context.Context, r *http.Request, org *models.Organization, u
|
|||
User: userContent,
|
||||
}
|
||||
|
||||
return newResponse("sync/source.html", data), nil
|
||||
return html.NewResponse("sync/source.html", data), nil
|
||||
}
|
||||
|
||||
func getStadia(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentDashboard], *errorWithStatus) {
|
||||
func getStadia(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*html.Response[contentDashboard], *nhttp.ErrorWithStatus) {
|
||||
data := contentDashboard{
|
||||
MapData: ComponentMap{
|
||||
MapboxToken: config.MapboxToken,
|
||||
},
|
||||
}
|
||||
return newResponse("sync/stadia.html", data), nil
|
||||
return html.NewResponse("sync/stadia.html", data), nil
|
||||
}
|
||||
func getTemplateTest(w http.ResponseWriter, r *http.Request) {
|
||||
html.RenderOrError(w, "sync/template-test.html", nil)
|
||||
}
|
||||
func getTrap(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentTrap], *errorWithStatus) {
|
||||
func getTrap(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentTrap], *nhttp.ErrorWithStatus) {
|
||||
globalid_s := chi.URLParam(r, "globalid")
|
||||
if globalid_s == "" {
|
||||
return nil, newError("No globalid provided: %w", nil)
|
||||
return nil, nhttp.NewError("No globalid provided: %w", nil)
|
||||
}
|
||||
globalid, err := uuid.Parse(globalid_s)
|
||||
if err != nil {
|
||||
return nil, newError("globalid is not a UUID: %w", nil)
|
||||
return nil, nhttp.NewError("globalid is not a UUID: %w", nil)
|
||||
}
|
||||
userContent, err := contentForUser(r.Context(), user)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get user content: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get user content: %w", err)
|
||||
}
|
||||
t, err := trapByGlobalId(r.Context(), org, globalid)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get trap: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get trap: %w", err)
|
||||
}
|
||||
latlng, err := t.H3Cell.LatLng()
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get latlng: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get latlng: %w", err)
|
||||
}
|
||||
data := contentTrap{
|
||||
MapData: ComponentMap{
|
||||
|
|
@ -198,7 +199,7 @@ func getTrap(ctx context.Context, r *http.Request, org *models.Organization, use
|
|||
Trap: t,
|
||||
User: userContent,
|
||||
}
|
||||
return newResponse("sync/trap.html", data), nil
|
||||
return html.NewResponse("sync/trap.html", data), nil
|
||||
}
|
||||
|
||||
func dashboard(ctx context.Context, w http.ResponseWriter, org *models.Organization, user *models.User) {
|
||||
|
|
@ -260,7 +261,7 @@ func dashboard(ctx context.Context, w http.ResponseWriter, org *models.Organizat
|
|||
}
|
||||
html.RenderOrError(w, "sync/dashboard.html", contentAuthenticated[contentDashboard]{
|
||||
C: content,
|
||||
URL: newContentURL(),
|
||||
URL: html.NewContentURL(),
|
||||
User: userContent,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentDownloadPlaceholder struct{}
|
||||
|
||||
func getDownloadList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentDownloadPlaceholder], *errorWithStatus) {
|
||||
func getDownloadList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentDownloadPlaceholder], *nhttp.ErrorWithStatus) {
|
||||
content := contentDownloadPlaceholder{}
|
||||
return newResponse("sync/download-list.html", content), nil
|
||||
return html.NewResponse("sync/download-list.html", content), nil
|
||||
}
|
||||
|
|
|
|||
119
sync/handler.go
Normal file
119
sync/handler.go
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
package sync
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/auth"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type handlerFunctionGet[T any] func(context.Context, *http.Request, *models.Organization, *models.User) (*html.Response[T], *nhttp.ErrorWithStatus)
|
||||
type wrappedHandler func(http.ResponseWriter, *http.Request)
|
||||
type contentAuthenticated[T any] struct {
|
||||
C T
|
||||
Config html.ContentConfig
|
||||
Organization *models.Organization
|
||||
URL html.ContentURL
|
||||
User User
|
||||
}
|
||||
|
||||
// w http.ResponseWriter, r *http.Request, u *models.User) {
|
||||
func authenticatedHandler[T any](f handlerFunctionGet[T]) http.Handler {
|
||||
return auth.NewEnsureAuth(func(w http.ResponseWriter, r *http.Request, u *models.User) {
|
||||
ctx := r.Context()
|
||||
userContent, err := contentForUser(ctx, u)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
org, err := u.Organization().One(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if org == nil {
|
||||
http.Error(w, "nil org", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
resp, e := f(ctx, r, org, u)
|
||||
//log.Info().Str("template", template).Err(e).Msg("handler done")
|
||||
if e != nil {
|
||||
log.Warn().Int("status", e.Status).Err(e).Str("user message", e.Message).Msg("Responding with an error from sync pages")
|
||||
http.Error(w, e.Error(), e.Status)
|
||||
return
|
||||
}
|
||||
html.RenderOrError(w, resp.Template, contentAuthenticated[T]{
|
||||
C: resp.Content,
|
||||
Config: html.NewContentConfig(),
|
||||
Organization: org,
|
||||
URL: html.NewContentURL(),
|
||||
User: userContent,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
type handlerFunctionPost[T any] func(context.Context, *http.Request, *models.Organization, *models.User, T) (string, *nhttp.ErrorWithStatus)
|
||||
|
||||
func authenticatedHandlerPost[T any](f handlerFunctionPost[T]) http.Handler {
|
||||
return auth.NewEnsureAuth(func(w http.ResponseWriter, r *http.Request, u *models.User) {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
respondError(w, "Failed to parse form", err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var content T
|
||||
|
||||
err = decoder.Decode(&content, r.PostForm)
|
||||
if err != nil {
|
||||
respondError(w, "Failed to decode form", err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
ctx := r.Context()
|
||||
org, err := u.Organization().One(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
path, e := f(ctx, r, org, u, content)
|
||||
if e != nil {
|
||||
http.Error(w, e.Error(), e.Status)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, path, http.StatusFound)
|
||||
})
|
||||
}
|
||||
func authenticatedHandlerPostMultipart[T any](f handlerFunctionPost[T]) http.Handler {
|
||||
return auth.NewEnsureAuth(func(w http.ResponseWriter, r *http.Request, u *models.User) {
|
||||
err := r.ParseMultipartForm(32 << 10) // 32 MB buffer
|
||||
if err != nil {
|
||||
respondError(w, "Failed to parse form", err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var content T
|
||||
|
||||
err = decoder.Decode(&content, r.PostForm)
|
||||
if err != nil {
|
||||
respondError(w, "Failed to decode form", err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
ctx := r.Context()
|
||||
org, err := u.Organization().One(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
path, e := f(ctx, r, org, u, content)
|
||||
if e != nil {
|
||||
http.Error(w, e.Error(), e.Status)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, path, http.StatusFound)
|
||||
})
|
||||
}
|
||||
|
|
@ -5,10 +5,12 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentIntelligenceRoot struct{}
|
||||
|
||||
func getIntelligenceRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentIntelligenceRoot], *errorWithStatus) {
|
||||
return newResponse("sync/intelligence-root.html", contentIntelligenceRoot{}), nil
|
||||
func getIntelligenceRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentIntelligenceRoot], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/intelligence-root.html", contentIntelligenceRoot{}), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import (
|
|||
)
|
||||
|
||||
type contentMailer struct {
|
||||
Config contentConfig
|
||||
Config html.ContentConfig
|
||||
DocumentID string
|
||||
LogoURL string
|
||||
Organization *models.Organization
|
||||
|
|
@ -71,7 +71,7 @@ func getMailerPreview(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
doc_id := uuid.New()
|
||||
html.RenderOrError(w, "sync/mailer.html", contentMailer{
|
||||
Config: newContentConfig(),
|
||||
Config: html.NewContentConfig(),
|
||||
DocumentID: doc_id.String(),
|
||||
LogoURL: config.MakeURLNidus("/api/district/%s/logo", org.Slug.GetOr("unset")),
|
||||
Organization: org,
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentMessageList struct{}
|
||||
|
||||
func getMessageList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentMessageList], *errorWithStatus) {
|
||||
func getMessageList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentMessageList], *nhttp.ErrorWithStatus) {
|
||||
content := contentMessageList{}
|
||||
return newResponse("sync/message-list.html", content), nil
|
||||
return html.NewResponse("sync/message-list.html", content), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ func addMock(r chi.Router, path string, template string) {
|
|||
}
|
||||
|
||||
type contentMock struct {
|
||||
Config contentConfig
|
||||
Config html.ContentConfig
|
||||
DistrictName string
|
||||
URLs ContentMockURLs
|
||||
}
|
||||
|
|
@ -66,7 +66,7 @@ func renderMock(template_name string) http.HandlerFunc {
|
|||
code = "abc-123"
|
||||
}
|
||||
data := contentMock{
|
||||
Config: newContentConfig(),
|
||||
Config: html.NewContentConfig(),
|
||||
DistrictName: "Delta MVCD",
|
||||
URLs: ContentMockURLs{
|
||||
Dispatch: "/mock/dispatch",
|
||||
|
|
@ -91,13 +91,13 @@ func renderMock(template_name string) http.HandlerFunc {
|
|||
}
|
||||
|
||||
type contentMockList struct {
|
||||
Config contentConfig
|
||||
Config html.ContentConfig
|
||||
Mocks []mock
|
||||
}
|
||||
|
||||
func renderMockList(w http.ResponseWriter, r *http.Request) {
|
||||
data := contentMockList{
|
||||
Config: newContentConfig(),
|
||||
Config: html.NewContentConfig(),
|
||||
Mocks: mocks,
|
||||
}
|
||||
html.RenderOrError(w, "sync/mock/root.html", data)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import (
|
|||
//"time"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/notification"
|
||||
//"github.com/Gleipnir-Technology/bob"
|
||||
//"github.com/Gleipnir-Technology/bob/dialect/psql"
|
||||
|
|
@ -22,12 +24,12 @@ type contentNotificationList struct {
|
|||
Notifications []notification.Notification
|
||||
}
|
||||
|
||||
func getNotificationList(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentNotificationList], *errorWithStatus) {
|
||||
func getNotificationList(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*html.Response[contentNotificationList], *nhttp.ErrorWithStatus) {
|
||||
notifications, err := notification.ForUser(ctx, u)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get notifications: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get notifications: %w", err)
|
||||
}
|
||||
return newResponse("sync/notification-list.html", contentNotificationList{
|
||||
return html.NewResponse("sync/notification-list.html", contentNotificationList{
|
||||
Notifications: notifications,
|
||||
}), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import (
|
|||
"github.com/Gleipnir-Technology/nidus-sync/background"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
|
|
@ -65,7 +67,7 @@ func getArcgisOauthCallback(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, config.MakeURLNidus("/"), http.StatusFound)
|
||||
}
|
||||
|
||||
func getOAuthRefresh(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentOauthPrompt], *errorWithStatus) {
|
||||
func getOAuthRefresh(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentOauthPrompt], *nhttp.ErrorWithStatus) {
|
||||
data := contentOauthPrompt{}
|
||||
return newResponse("sync/oauth-prompt.html", data), nil
|
||||
return html.NewResponse("sync/oauth-prompt.html", data), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentOperationsRoot struct{}
|
||||
|
||||
func getOperationsRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentOperationsRoot], *errorWithStatus) {
|
||||
return newResponse("sync/operations-root.html", contentOperationsRoot{}), nil
|
||||
func getOperationsRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentOperationsRoot], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/operations-root.html", contentOperationsRoot{}), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentParcel struct{}
|
||||
|
||||
func getParcel(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentParcel], *errorWithStatus) {
|
||||
return newResponse("sync/parcel.html", contentParcel{}), nil
|
||||
func getParcel(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentParcel], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/parcel.html", contentParcel{}), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentPlanningRoot struct{}
|
||||
|
||||
func getPlanningRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentPlanningRoot], *errorWithStatus) {
|
||||
return newResponse("sync/planning-root.html", contentPlanningRoot{}), nil
|
||||
func getPlanningRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentPlanningRoot], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/planning-root.html", contentPlanningRoot{}), nil
|
||||
}
|
||||
|
|
|
|||
14
sync/pool.go
14
sync/pool.go
|
|
@ -5,16 +5,18 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentPoolList struct{}
|
||||
|
||||
func getPoolList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentPoolList], *errorWithStatus) {
|
||||
return newResponse("sync/pool-list.html", contentPoolList{}), nil
|
||||
func getPoolList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentPoolList], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/pool-list.html", contentPoolList{}), nil
|
||||
}
|
||||
func getPoolCreate(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentPoolList], *errorWithStatus) {
|
||||
return newResponse("sync/pool-upload.html", contentPoolList{}), nil
|
||||
func getPoolCreate(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentPoolList], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/pool-upload.html", contentPoolList{}), nil
|
||||
}
|
||||
func getPoolByID(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentPoolList], *errorWithStatus) {
|
||||
return newResponse("sync/pool-by-id.html", contentPoolList{}), nil
|
||||
func getPoolByID(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentPoolList], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/pool-by-id.html", contentPoolList{}), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,19 +6,21 @@ import (
|
|||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentRadar struct {
|
||||
Organization *models.Organization
|
||||
}
|
||||
|
||||
func getRadar(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentRadar], *errorWithStatus) {
|
||||
func getRadar(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentRadar], *nhttp.ErrorWithStatus) {
|
||||
org, err := user.Organization().One(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
return nil, newError("get org: %w", err)
|
||||
return nil, nhttp.NewError("get org: %w", err)
|
||||
}
|
||||
data := contentRadar{
|
||||
Organization: org,
|
||||
}
|
||||
return newResponse("sync/radar.html", data), nil
|
||||
return html.NewResponse("sync/radar.html", data), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentReviewRoot struct{}
|
||||
|
||||
func getReviewRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentReviewRoot], *errorWithStatus) {
|
||||
return newResponse("sync/review-root.html", contentReviewRoot{}), nil
|
||||
func getReviewRoot(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentReviewRoot], *nhttp.ErrorWithStatus) {
|
||||
return html.NewResponse("sync/review-root.html", contentReviewRoot{}), nil
|
||||
}
|
||||
|
|
|
|||
151
sync/routes.go
151
sync/routes.go
|
|
@ -1,17 +1,10 @@
|
|||
package sync
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/api"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/auth"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func Router() chi.Router {
|
||||
|
|
@ -98,147 +91,3 @@ func Router() chi.Router {
|
|||
html.AddStaticRoute(r, "/static")
|
||||
return r
|
||||
}
|
||||
|
||||
type errorWithStatus struct {
|
||||
Message string
|
||||
Status int
|
||||
}
|
||||
|
||||
func (e *errorWithStatus) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
func newError(mesg_format string, args ...interface{}) *errorWithStatus {
|
||||
return newErrorStatus(http.StatusInternalServerError, mesg_format, args...)
|
||||
}
|
||||
func newErrorMaybe(mesg_format string, err error, args ...interface{}) *errorWithStatus {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
allArgs := append([]interface{}{err}, args...)
|
||||
return newErrorStatus(http.StatusInternalServerError, mesg_format, allArgs...)
|
||||
}
|
||||
func newErrorStatus(status int, mesg_format string, args ...interface{}) *errorWithStatus {
|
||||
w := fmt.Errorf(mesg_format, args...)
|
||||
return &errorWithStatus{
|
||||
Message: w.Error(),
|
||||
Status: status,
|
||||
}
|
||||
}
|
||||
|
||||
type response[T any] struct {
|
||||
content T
|
||||
template string
|
||||
}
|
||||
|
||||
func newResponse[T any](template string, content T) *response[T] {
|
||||
return &response[T]{
|
||||
content: content,
|
||||
template: template,
|
||||
}
|
||||
}
|
||||
|
||||
type handlerFunctionGet[T any] func(context.Context, *http.Request, *models.Organization, *models.User) (*response[T], *errorWithStatus)
|
||||
type wrappedHandler func(http.ResponseWriter, *http.Request)
|
||||
type contentAuthenticated[T any] struct {
|
||||
C T
|
||||
Config contentConfig
|
||||
Organization *models.Organization
|
||||
URL contentURL
|
||||
User User
|
||||
}
|
||||
|
||||
// w http.ResponseWriter, r *http.Request, u *models.User) {
|
||||
func authenticatedHandler[T any](f handlerFunctionGet[T]) http.Handler {
|
||||
return auth.NewEnsureAuth(func(w http.ResponseWriter, r *http.Request, u *models.User) {
|
||||
ctx := r.Context()
|
||||
userContent, err := contentForUser(ctx, u)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
org, err := u.Organization().One(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
resp, e := f(ctx, r, org, u)
|
||||
//log.Info().Str("template", template).Err(e).Msg("handler done")
|
||||
if e != nil {
|
||||
log.Warn().Int("status", e.Status).Err(e).Str("user message", e.Message).Msg("Responding with an error from sync pages")
|
||||
http.Error(w, e.Error(), e.Status)
|
||||
return
|
||||
}
|
||||
if org == nil {
|
||||
http.Error(w, "nil org", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
html.RenderOrError(w, resp.template, contentAuthenticated[T]{
|
||||
C: resp.content,
|
||||
Config: newContentConfig(),
|
||||
Organization: org,
|
||||
URL: newContentURL(),
|
||||
User: userContent,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
type handlerFunctionPost[T any] func(context.Context, *http.Request, *models.Organization, *models.User, T) (string, *errorWithStatus)
|
||||
|
||||
func authenticatedHandlerPost[T any](f handlerFunctionPost[T]) http.Handler {
|
||||
return auth.NewEnsureAuth(func(w http.ResponseWriter, r *http.Request, u *models.User) {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
respondError(w, "Failed to parse form", err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var content T
|
||||
|
||||
err = decoder.Decode(&content, r.PostForm)
|
||||
if err != nil {
|
||||
respondError(w, "Failed to decode form", err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
ctx := r.Context()
|
||||
org, err := u.Organization().One(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
path, e := f(ctx, r, org, u, content)
|
||||
if e != nil {
|
||||
http.Error(w, e.Error(), e.Status)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, path, http.StatusFound)
|
||||
})
|
||||
}
|
||||
func authenticatedHandlerPostMultipart[T any](f handlerFunctionPost[T]) http.Handler {
|
||||
return auth.NewEnsureAuth(func(w http.ResponseWriter, r *http.Request, u *models.User) {
|
||||
err := r.ParseMultipartForm(32 << 10) // 32 MB buffer
|
||||
if err != nil {
|
||||
respondError(w, "Failed to parse form", err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var content T
|
||||
|
||||
err = decoder.Decode(&content, r.PostForm)
|
||||
if err != nil {
|
||||
respondError(w, "Failed to decode form", err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
ctx := r.Context()
|
||||
org, err := u.Organization().One(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
path, e := f(ctx, r, org, u, content)
|
||||
if e != nil {
|
||||
http.Error(w, e.Error(), e.Status)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, path, http.StatusFound)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import (
|
|||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentActiveServiceRequest struct {
|
||||
|
|
@ -32,11 +34,11 @@ type contentServiceRequestList struct {
|
|||
ClosedRequests []contentClosedServiceRequest
|
||||
}
|
||||
|
||||
func getServiceRequestDetail(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentServiceRequestDetail], *errorWithStatus) {
|
||||
func getServiceRequestDetail(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentServiceRequestDetail], *nhttp.ErrorWithStatus) {
|
||||
content := contentServiceRequestDetail{}
|
||||
return newResponse("sync/service-request-detail.html", content), nil
|
||||
return html.NewResponse("sync/service-request-detail.html", content), nil
|
||||
}
|
||||
func getServiceRequestList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentServiceRequestList], *errorWithStatus) {
|
||||
func getServiceRequestList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentServiceRequestList], *nhttp.ErrorWithStatus) {
|
||||
now := time.Now()
|
||||
content := contentServiceRequestList{
|
||||
ActiveRequests: []contentActiveServiceRequest{
|
||||
|
|
@ -112,5 +114,5 @@ func getServiceRequestList(ctx context.Context, r *http.Request, org *models.Org
|
|||
},
|
||||
},
|
||||
}
|
||||
return newResponse("sync/service-request-list.html", content), nil
|
||||
return html.NewResponse("sync/service-request-list.html", content), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ func postSignup(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
type contentUnauthenticated[T any] struct {
|
||||
C T
|
||||
Config contentConfig
|
||||
URL contentURL
|
||||
Config html.ContentConfig
|
||||
URL html.ContentURL
|
||||
}
|
||||
|
||||
func signin(w http.ResponseWriter, errorCode string, next string) {
|
||||
|
|
@ -111,8 +111,8 @@ func signin(w http.ResponseWriter, errorCode string, next string) {
|
|||
InvalidCredentials: errorCode == "invalid-credentials",
|
||||
Next: next,
|
||||
},
|
||||
Config: newContentConfig(),
|
||||
URL: newContentURL(),
|
||||
Config: html.NewContentConfig(),
|
||||
URL: html.NewContentURL(),
|
||||
}
|
||||
html.RenderOrError(w, "sync/signin.html", data)
|
||||
}
|
||||
|
|
|
|||
16
sync/sudo.go
16
sync/sudo.go
|
|
@ -10,6 +10,8 @@ import (
|
|||
"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
"github.com/gorilla/schema"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
|
@ -19,9 +21,9 @@ type contentSudo struct {
|
|||
ForwardEmailNidusAddress string
|
||||
}
|
||||
|
||||
func getSudo(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentSudo], *errorWithStatus) {
|
||||
func getSudo(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentSudo], *nhttp.ErrorWithStatus) {
|
||||
if user.Role != enums.UserroleRoot {
|
||||
return nil, &errorWithStatus{
|
||||
return nil, &nhttp.ErrorWithStatus{
|
||||
Message: "You have to be a root user to access this",
|
||||
Status: http.StatusForbidden,
|
||||
}
|
||||
|
|
@ -30,7 +32,7 @@ func getSudo(ctx context.Context, r *http.Request, org *models.Organization, use
|
|||
ForwardEmailRMOAddress: config.ForwardEmailRMOAddress,
|
||||
ForwardEmailNidusAddress: config.ForwardEmailNidusAddress,
|
||||
}
|
||||
return newResponse("sync/sudo.html", content), nil
|
||||
return html.NewResponse("sync/sudo.html", content), nil
|
||||
}
|
||||
|
||||
var decoder = schema.NewDecoder()
|
||||
|
|
@ -42,9 +44,9 @@ type FormEmail struct {
|
|||
To string `schema:"emailTo"`
|
||||
}
|
||||
|
||||
func postSudoEmail(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, e FormEmail) (string, *errorWithStatus) {
|
||||
func postSudoEmail(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, e FormEmail) (string, *nhttp.ErrorWithStatus) {
|
||||
if u.Role != enums.UserroleRoot {
|
||||
return "", &errorWithStatus{
|
||||
return "", &nhttp.ErrorWithStatus{
|
||||
Message: "You must have sudo powers to do this",
|
||||
Status: http.StatusForbidden,
|
||||
}
|
||||
|
|
@ -71,9 +73,9 @@ type FormSMS struct {
|
|||
Phone string `schema:"smsPhone"`
|
||||
}
|
||||
|
||||
func postSudoSMS(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, sms FormSMS) (string, *errorWithStatus) {
|
||||
func postSudoSMS(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, sms FormSMS) (string, *nhttp.ErrorWithStatus) {
|
||||
if u.Role != enums.UserroleRoot {
|
||||
return "", &errorWithStatus{
|
||||
return "", &nhttp.ErrorWithStatus{
|
||||
Message: "You must have sudo powers to do this",
|
||||
Status: http.StatusForbidden,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
)
|
||||
|
||||
type contentTextMessages struct{}
|
||||
|
||||
func getTextMessages(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentTextMessages], *errorWithStatus) {
|
||||
func getTextMessages(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*html.Response[contentTextMessages], *nhttp.ErrorWithStatus) {
|
||||
content := contentTextMessages{}
|
||||
return newResponse("sync/text-messages.html", content), nil
|
||||
return html.NewResponse("sync/text-messages.html", content), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ import (
|
|||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/html"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/platform"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/userfile"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/rs/zerolog/log"
|
||||
//"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type contentUploadList struct {
|
||||
|
|
@ -19,11 +21,11 @@ type contentUploadList struct {
|
|||
}
|
||||
type contentUploadPlaceholder struct{}
|
||||
|
||||
func getUploadList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentUploadList], *errorWithStatus) {
|
||||
func getUploadList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*html.Response[contentUploadList], *nhttp.ErrorWithStatus) {
|
||||
rows, err := platform.UploadSummaryList(ctx, org)
|
||||
return newResponse("sync/upload-list.html", contentUploadList{
|
||||
return html.NewResponse("sync/upload-list.html", contentUploadList{
|
||||
RecentUploads: rows,
|
||||
}), newErrorMaybe("get upload list: %w", err)
|
||||
}), nhttp.NewErrorMaybe("get upload list: %w", err)
|
||||
}
|
||||
|
||||
type contentUploadDetail struct {
|
||||
|
|
@ -36,110 +38,108 @@ type contentUploadPoolList struct {
|
|||
}
|
||||
type contentUploadPool struct{}
|
||||
|
||||
func getUploadPool(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentUploadPool], *errorWithStatus) {
|
||||
func getUploadPool(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*html.Response[contentUploadPool], *nhttp.ErrorWithStatus) {
|
||||
data := contentUploadPool{}
|
||||
return newResponse("sync/upload-csv-pool.html", data), nil
|
||||
return html.NewResponse("sync/upload-csv-pool.html", data), nil
|
||||
}
|
||||
|
||||
type contentUploadPoolFlyoverCreate struct{}
|
||||
|
||||
func getUploadPoolFlyoverCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentUploadPoolFlyoverCreate], *errorWithStatus) {
|
||||
func getUploadPoolFlyoverCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*html.Response[contentUploadPoolFlyoverCreate], *nhttp.ErrorWithStatus) {
|
||||
data := contentUploadPoolFlyoverCreate{}
|
||||
return newResponse("sync/upload-csv-pool-flyover.html", data), nil
|
||||
return html.NewResponse("sync/upload-csv-pool-flyover.html", data), nil
|
||||
}
|
||||
|
||||
type contentUploadPoolCustomCreate struct{}
|
||||
|
||||
func getUploadPoolCustomCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentUploadPoolCustomCreate], *errorWithStatus) {
|
||||
func getUploadPoolCustomCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*html.Response[contentUploadPoolCustomCreate], *nhttp.ErrorWithStatus) {
|
||||
data := contentUploadPoolCustomCreate{}
|
||||
return newResponse("sync/upload-csv-pool-custom.html", data), nil
|
||||
return html.NewResponse("sync/upload-csv-pool-custom.html", data), nil
|
||||
}
|
||||
func getUploadByID(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentUploadDetail], *errorWithStatus) {
|
||||
test := newContentURLUpload()
|
||||
log.Info().Str("output", test.Discard(123)).Send()
|
||||
func getUploadByID(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*html.Response[contentUploadDetail], *nhttp.ErrorWithStatus) {
|
||||
file_id_str := chi.URLParam(r, "id")
|
||||
file_id_, err := strconv.ParseInt(file_id_str, 10, 32)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to parse file_id: %w", err)
|
||||
return nil, nhttp.NewError("Failed to parse file_id: %w", err)
|
||||
}
|
||||
file_id := int32(file_id_)
|
||||
detail, err := platform.GetUploadPoolDetail(ctx, u.OrganizationID, file_id)
|
||||
if err != nil {
|
||||
return nil, newError("Failed to get pool: %w", err)
|
||||
return nil, nhttp.NewError("Failed to get pool: %w", err)
|
||||
}
|
||||
data := contentUploadDetail{
|
||||
CSVFileID: file_id,
|
||||
Organization: org,
|
||||
Upload: detail,
|
||||
}
|
||||
return newResponse("sync/upload-by-id.html", data), nil
|
||||
return html.NewResponse("sync/upload-by-id.html", data), nil
|
||||
}
|
||||
|
||||
type FormUploadCommit struct{}
|
||||
|
||||
func postUploadCommit(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadCommit) (string, *errorWithStatus) {
|
||||
func postUploadCommit(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadCommit) (string, *nhttp.ErrorWithStatus) {
|
||||
file_id_str := chi.URLParam(r, "id")
|
||||
file_id_, err := strconv.ParseInt(file_id_str, 10, 32)
|
||||
if err != nil {
|
||||
return "", newError("Failed to parse file_id: %w", err)
|
||||
return "", nhttp.NewError("Failed to parse file_id: %w", err)
|
||||
}
|
||||
err = platform.UploadCommit(ctx, org, int32(file_id_))
|
||||
if err != nil {
|
||||
return "", newError("Failed to mark discarded: %w", err)
|
||||
return "", nhttp.NewError("Failed to mark discarded: %w", err)
|
||||
}
|
||||
return "/configuration/upload", nil
|
||||
}
|
||||
|
||||
type FormUploadDiscard struct{}
|
||||
|
||||
func postUploadDiscard(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadDiscard) (string, *errorWithStatus) {
|
||||
func postUploadDiscard(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadDiscard) (string, *nhttp.ErrorWithStatus) {
|
||||
file_id_str := chi.URLParam(r, "id")
|
||||
file_id_, err := strconv.ParseInt(file_id_str, 10, 32)
|
||||
if err != nil {
|
||||
return "", newError("Failed to parse file_id: %w", err)
|
||||
return "", nhttp.NewError("Failed to parse file_id: %w", err)
|
||||
}
|
||||
err = platform.UploadDiscard(ctx, org, int32(file_id_))
|
||||
if err != nil {
|
||||
return "", newError("Failed to mark discarded: %w", err)
|
||||
return "", nhttp.NewError("Failed to mark discarded: %w", err)
|
||||
}
|
||||
return "/configuration/upload", nil
|
||||
}
|
||||
|
||||
type FormUploadPool struct{}
|
||||
|
||||
func postUploadPoolFlyoverCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadPool) (string, *errorWithStatus) {
|
||||
func postUploadPoolFlyoverCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadPool) (string, *nhttp.ErrorWithStatus) {
|
||||
uploads, err := userfile.SaveFileUpload(r, "csvfile", userfile.CollectionCSV)
|
||||
if err != nil {
|
||||
return "", newError("Failed to extract image uploads: %s", err)
|
||||
return "", nhttp.NewError("Failed to extract image uploads: %s", err)
|
||||
}
|
||||
if len(uploads) == 0 {
|
||||
return "", newErrorStatus(http.StatusBadRequest, "No upload found")
|
||||
return "", nhttp.NewErrorStatus(http.StatusBadRequest, "No upload found")
|
||||
}
|
||||
if len(uploads) != 1 {
|
||||
return "", newErrorStatus(http.StatusBadRequest, "You must only submit one file at a time")
|
||||
return "", nhttp.NewErrorStatus(http.StatusBadRequest, "You must only submit one file at a time")
|
||||
}
|
||||
upload := uploads[0]
|
||||
saved_upload, err := platform.NewUpload(r.Context(), u, upload, enums.FileuploadCsvtypeFlyover)
|
||||
if err != nil {
|
||||
return "", newError("Failed to create new pool: %w", err)
|
||||
return "", nhttp.NewError("Failed to create new pool: %w", err)
|
||||
}
|
||||
return fmt.Sprintf("/configuration/upload/%d", saved_upload.ID), nil
|
||||
}
|
||||
func postUploadPoolCustomCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadPool) (string, *errorWithStatus) {
|
||||
func postUploadPoolCustomCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadPool) (string, *nhttp.ErrorWithStatus) {
|
||||
uploads, err := userfile.SaveFileUpload(r, "csvfile", userfile.CollectionCSV)
|
||||
if err != nil {
|
||||
return "", newError("Failed to extract image uploads: %s", err)
|
||||
return "", nhttp.NewError("Failed to extract image uploads: %s", err)
|
||||
}
|
||||
if len(uploads) == 0 {
|
||||
return "", newErrorStatus(http.StatusBadRequest, "No upload found")
|
||||
return "", nhttp.NewErrorStatus(http.StatusBadRequest, "No upload found")
|
||||
}
|
||||
if len(uploads) != 1 {
|
||||
return "", newErrorStatus(http.StatusBadRequest, "You must only submit one file at a time")
|
||||
return "", nhttp.NewErrorStatus(http.StatusBadRequest, "You must only submit one file at a time")
|
||||
}
|
||||
upload := uploads[0]
|
||||
pool_upload, err := platform.NewUpload(r.Context(), u, upload, enums.FileuploadCsvtypePoollist)
|
||||
if err != nil {
|
||||
return "", newError("Failed to create new pool: %w", err)
|
||||
return "", nhttp.NewError("Failed to create new pool: %w", err)
|
||||
}
|
||||
return fmt.Sprintf("/configuration/upload/%d", pool_upload.ID), nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue