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.
This commit is contained in:
jordi fita mas 2024-08-15 04:18:18 +02:00
parent dca8b3a719
commit fa57c4b191
6 changed files with 83 additions and 201 deletions

View File

@ -491,44 +491,11 @@ func (form *contactForm) TaxDetails() *CustomerTaxDetails {
} }
func ServeEditContactTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { func ServeEditContactTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
conn := getConn(r) serveTagsEditForm(w, r, params, "/contacts/", "select tags from contact where slug = $1")
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)
} }
func HandleUpdateContactTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { func HandleUpdateContactTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
locale := getLocale(r) handleUpdateTags(w, r, params, "/contacts/", "update contact set tags = $1 where slug = $2 returning slug")
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)
} }
func ServeImportPage(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { func ServeImportPage(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

View File

@ -568,45 +568,11 @@ func (form *expenseFilterForm) BuildQuery(args []interface{}) (string, []interfa
} }
func ServeEditExpenseTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { func ServeEditExpenseTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
conn := getConn(r) serveTagsEditForm(w, r, params, "/expenses/", "select tags from expense where slug = $1")
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)
} }
func HandleUpdateExpenseTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { func HandleUpdateExpenseTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
locale := getLocale(r) handleUpdateTags(w, r, params, "/expenses/", "update expense set tags = $1 where slug = $2 returning slug")
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)
} }
func ServeExpenseAttachment(w http.ResponseWriter, r *http.Request, params httprouter.Params) { func ServeExpenseAttachment(w http.ResponseWriter, r *http.Request, params httprouter.Params) {

View File

@ -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) { func ServeEditInvoiceTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
conn := getConn(r) serveTagsEditForm(w, r, params, "/invoices/", "select tags from invoice where slug = $1")
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)
} }
func HandleUpdateInvoiceTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { func HandleUpdateInvoiceTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
locale := getLocale(r) handleUpdateTags(w, r, params, "/invoices/", "update invoice set tags = $1 where slug = $2 returning slug")
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)
} }
func ServeInvoiceAttachment(w http.ResponseWriter, r *http.Request, params httprouter.Params) { func ServeInvoiceAttachment(w http.ResponseWriter, r *http.Request, params httprouter.Params) {

View File

@ -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) { func ServeEditProductTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
conn := getConn(r) serveTagsEditForm(w, r, params, "/products/", "select tags from product where slug = $1")
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)
} }
func HandleUpdateProductTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { func HandleUpdateProductTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
locale := getLocale(r) handleUpdateTags(w, r, params, "/products/", "update product set tags = $1 where slug = $2 returning slug")
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)
} }

View File

@ -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) { func ServeEditQuoteTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
conn := getConn(r) serveTagsEditForm(w, r, params, "/quotes/", "select tags from quote where slug = $1")
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)
} }
func HandleUpdateQuoteTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { func HandleUpdateQuoteTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
locale := getLocale(r) handleUpdateTags(w, r, params, "/quotes/", "update quote set tags = $1 where slug = $2 returning slug")
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)
} }

73
pkg/tags.go Normal file
View File

@ -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)
}