From fa57c4b19173e6e89f550f2e1b21bb559bf99930 Mon Sep 17 00:00:00 2001 From: jordi fita mas Date: Thu, 15 Aug 2024 04:18:18 +0200 Subject: [PATCH] Refactor inline tag edit form into its own file I was repeating myself a lot for this use case, because each one needed a different URL and SQL query, however they were kind of structurally similar and could be refactored into common functions. --- pkg/contacts.go | 37 ++----------------------- pkg/expenses.go | 38 ++----------------------- pkg/invoices.go | 62 ++--------------------------------------- pkg/products.go | 37 ++----------------------- pkg/quote.go | 37 ++----------------------- pkg/tags.go | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 201 deletions(-) create mode 100644 pkg/tags.go diff --git a/pkg/contacts.go b/pkg/contacts.go index 0cd478a..99771e8 100644 --- a/pkg/contacts.go +++ b/pkg/contacts.go @@ -491,44 +491,11 @@ func (form *contactForm) TaxDetails() *CustomerTaxDetails { } func ServeEditContactTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { - conn := getConn(r) - locale := getLocale(r) - company := getCompany(r) - slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return - } - form := newTagsForm(companyURI(company, "/contacts/"+slug+"/tags"), slug, locale) - if notFoundErrorOrPanic(conn.QueryRow(r.Context(), `select tags from contact where slug = $1`, form.Slug).Scan(form.Tags)) { - http.NotFound(w, r) - return - } - mustRenderStandaloneTemplate(w, r, "tags/edit.gohtml", form) + serveTagsEditForm(w, r, params, "/contacts/", "select tags from contact where slug = $1") } func HandleUpdateContactTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { - locale := getLocale(r) - conn := getConn(r) - company := getCompany(r) - slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return - } - form := newTagsForm(companyURI(company, "/contacts/"+slug+"/tags/edit"), slug, locale) - if err := form.Parse(r); err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if err := verifyCsrfTokenValid(r); err != nil { - http.Error(w, err.Error(), http.StatusForbidden) - return - } - if conn.MustGetText(r.Context(), "", "update contact set tags = $1 where slug = $2 returning slug", form.Tags, form.Slug) == "" { - http.NotFound(w, r) - } - mustRenderStandaloneTemplate(w, r, "tags/view.gohtml", form) + handleUpdateTags(w, r, params, "/contacts/", "update contact set tags = $1 where slug = $2 returning slug") } func ServeImportPage(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { diff --git a/pkg/expenses.go b/pkg/expenses.go index 0dccea4..4774f18 100644 --- a/pkg/expenses.go +++ b/pkg/expenses.go @@ -568,45 +568,11 @@ func (form *expenseFilterForm) BuildQuery(args []interface{}) (string, []interfa } func ServeEditExpenseTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { - conn := getConn(r) - locale := getLocale(r) - company := getCompany(r) - slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return - } - form := newTagsForm(companyURI(company, "/expenses/"+slug+"/tags"), slug, locale) - if notFoundErrorOrPanic(conn.QueryRow(r.Context(), `select tags from expense where slug = $1`, form.Slug).Scan(form.Tags)) { - http.NotFound(w, r) - return - } - mustRenderStandaloneTemplate(w, r, "tags/edit.gohtml", form) + serveTagsEditForm(w, r, params, "/expenses/", "select tags from expense where slug = $1") } func HandleUpdateExpenseTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { - locale := getLocale(r) - conn := getConn(r) - company := getCompany(r) - slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return - } - form := newTagsForm(companyURI(company, "/expenses/"+slug+"/tags/edit"), slug, locale) - if err := form.Parse(r); err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if err := verifyCsrfTokenValid(r); err != nil { - http.Error(w, err.Error(), http.StatusForbidden) - return - } - if conn.MustGetText(r.Context(), "", "update expense set tags = $1 where slug = $2 returning slug", form.Tags, form.Slug) == "" { - http.NotFound(w, r) - return - } - mustRenderStandaloneTemplate(w, r, "tags/view.gohtml", form) + handleUpdateTags(w, r, params, "/expenses/", "update expense set tags = $1 where slug = $2 returning slug") } func ServeExpenseAttachment(w http.ResponseWriter, r *http.Request, params httprouter.Params) { diff --git a/pkg/invoices.go b/pkg/invoices.go index 6619761..1962198 100644 --- a/pkg/invoices.go +++ b/pkg/invoices.go @@ -1447,70 +1447,12 @@ func handleInvoiceAction(w http.ResponseWriter, r *http.Request, action string, } } -type tagsForm struct { - Action string - Slug string - Tags *TagsField -} - -func newTagsForm(uri string, slug string, locale *Locale) *tagsForm { - return &tagsForm{ - Action: uri, - Slug: slug, - Tags: &TagsField{ - Name: "tags-" + slug, - Label: pgettext("input", "Tags", locale), - }, - } -} - -func (form *tagsForm) Parse(r *http.Request) error { - if err := r.ParseForm(); err != nil { - return err - } - form.Tags.FillValue(r) - return nil -} - func ServeEditInvoiceTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { - conn := getConn(r) - locale := getLocale(r) - company := getCompany(r) - slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return - } - form := newTagsForm(companyURI(company, "/invoices/"+slug+"/tags"), slug, locale) - if notFoundErrorOrPanic(conn.QueryRow(r.Context(), `select tags from invoice where slug = $1`, form.Slug).Scan(form.Tags)) { - http.NotFound(w, r) - return - } - mustRenderStandaloneTemplate(w, r, "tags/edit.gohtml", form) + serveTagsEditForm(w, r, params, "/invoices/", "select tags from invoice where slug = $1") } func HandleUpdateInvoiceTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { - locale := getLocale(r) - conn := getConn(r) - company := getCompany(r) - slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return - } - form := newTagsForm(companyURI(company, "/invoices/"+slug+"/tags/edit"), slug, locale) - if err := form.Parse(r); err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if err := verifyCsrfTokenValid(r); err != nil { - http.Error(w, err.Error(), http.StatusForbidden) - return - } - if conn.MustGetText(r.Context(), "", "update invoice set tags = $1 where slug = $2 returning slug", form.Tags, form.Slug) == "" { - http.NotFound(w, r) - } - mustRenderStandaloneTemplate(w, r, "tags/view.gohtml", form) + handleUpdateTags(w, r, params, "/invoices/", "update invoice set tags = $1 where slug = $2 returning slug") } func ServeInvoiceAttachment(w http.ResponseWriter, r *http.Request, params httprouter.Params) { diff --git a/pkg/products.go b/pkg/products.go index 5913456..729bc86 100644 --- a/pkg/products.go +++ b/pkg/products.go @@ -367,42 +367,9 @@ func HandleProductSearch(w http.ResponseWriter, r *http.Request, _ httprouter.Pa } func ServeEditProductTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { - conn := getConn(r) - locale := getLocale(r) - company := getCompany(r) - slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return - } - form := newTagsForm(companyURI(company, "/products/"+slug+"/tags"), slug, locale) - if notFoundErrorOrPanic(conn.QueryRow(r.Context(), `select tags from product where slug = $1`, form.Slug).Scan(form.Tags)) { - http.NotFound(w, r) - return - } - mustRenderStandaloneTemplate(w, r, "tags/edit.gohtml", form) + serveTagsEditForm(w, r, params, "/products/", "select tags from product where slug = $1") } func HandleUpdateProductTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { - locale := getLocale(r) - conn := getConn(r) - company := getCompany(r) - slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return - } - form := newTagsForm(companyURI(company, "/products/"+slug+"/tags/edit"), slug, locale) - if err := form.Parse(r); err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if err := verifyCsrfTokenValid(r); err != nil { - http.Error(w, err.Error(), http.StatusForbidden) - return - } - if conn.MustGetText(r.Context(), "", "update product set tags = $1 where slug = $2 returning slug", form.Tags, form.Slug) == "" { - http.NotFound(w, r) - } - mustRenderStandaloneTemplate(w, r, "tags/view.gohtml", form) + handleUpdateTags(w, r, params, "/products/", "update product set tags = $1 where slug = $2 returning slug") } diff --git a/pkg/quote.go b/pkg/quote.go index af98c4d..4a9fcd1 100644 --- a/pkg/quote.go +++ b/pkg/quote.go @@ -1187,42 +1187,9 @@ func handleQuoteAction(w http.ResponseWriter, r *http.Request, action string, re } func ServeEditQuoteTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { - conn := getConn(r) - locale := getLocale(r) - company := getCompany(r) - slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return - } - form := newTagsForm(companyURI(company, "/quotes/"+slug+"/tags"), slug, locale) - if notFoundErrorOrPanic(conn.QueryRow(r.Context(), `select tags from quote where slug = $1`, form.Slug).Scan(form.Tags)) { - http.NotFound(w, r) - return - } - mustRenderStandaloneTemplate(w, r, "tags/edit.gohtml", form) + serveTagsEditForm(w, r, params, "/quotes/", "select tags from quote where slug = $1") } func HandleUpdateQuoteTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { - locale := getLocale(r) - conn := getConn(r) - company := getCompany(r) - slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return - } - form := newTagsForm(companyURI(company, "/quotes/"+slug+"/tags/edit"), slug, locale) - if err := form.Parse(r); err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if err := verifyCsrfTokenValid(r); err != nil { - http.Error(w, err.Error(), http.StatusForbidden) - return - } - if conn.MustGetText(r.Context(), "", "update quote set tags = $1 where slug = $2 returning slug", form.Tags, form.Slug) == "" { - http.NotFound(w, r) - } - mustRenderStandaloneTemplate(w, r, "tags/view.gohtml", form) + handleUpdateTags(w, r, params, "/quotes/", "update quote set tags = $1 where slug = $2 returning slug") } diff --git a/pkg/tags.go b/pkg/tags.go new file mode 100644 index 0000000..358de77 --- /dev/null +++ b/pkg/tags.go @@ -0,0 +1,73 @@ +package pkg + +import ( + "github.com/julienschmidt/httprouter" + "net/http" +) + +func serveTagsEditForm(w http.ResponseWriter, r *http.Request, params httprouter.Params, prefix string, sql string) { + conn := getConn(r) + locale := getLocale(r) + company := getCompany(r) + slug := params[0].Value + if !ValidUuid(slug) { + http.NotFound(w, r) + return + } + form := newTagsForm(companyURI(company, prefix+slug+"/tags"), slug, locale) + if notFoundErrorOrPanic(conn.QueryRow(r.Context(), sql, form.Slug).Scan(form.Tags)) { + http.NotFound(w, r) + return + } + mustRenderStandaloneTemplate(w, r, "tags/edit.gohtml", form) +} + +type tagsForm struct { + Action string + Slug string + Tags *TagsField +} + +func newTagsForm(uri string, slug string, locale *Locale) *tagsForm { + return &tagsForm{ + Action: uri, + Slug: slug, + Tags: &TagsField{ + Name: "tags-" + slug, + Label: pgettext("input", "Tags", locale), + }, + } +} + +func (form *tagsForm) Parse(r *http.Request) error { + if err := r.ParseForm(); err != nil { + return err + } + form.Tags.FillValue(r) + return nil +} + +func handleUpdateTags(w http.ResponseWriter, r *http.Request, params httprouter.Params, prefix string, sql string) { + locale := getLocale(r) + conn := getConn(r) + company := getCompany(r) + slug := params[0].Value + if !ValidUuid(slug) { + http.NotFound(w, r) + return + } + form := newTagsForm(companyURI(company, prefix+slug+"/tags/edit"), slug, locale) + if err := form.Parse(r); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := verifyCsrfTokenValid(r); err != nil { + http.Error(w, err.Error(), http.StatusForbidden) + return + } + if conn.MustGetText(r.Context(), "", sql, form.Tags, form.Slug) == "" { + http.NotFound(w, r) + return + } + mustRenderStandaloneTemplate(w, r, "tags/view.gohtml", form) +}