/* * SPDX-FileCopyrightText: 2023 jordi fita mas * SPDX-License-Identifier: AGPL-3.0-only */ package form import ( "context" "database/sql/driver" "dev.tandem.ws/tandem/camper/pkg/locale" "net/http" "strconv" "dev.tandem.ws/tandem/camper/pkg/database" ) type Select struct { Name string Selected []string Options []*Option Error error } func (s *Select) setError(err error) { s.Error = err } func (s *Select) Value() (driver.Value, error) { return s.String(), nil } func (s *Select) String() string { if s.Selected == nil { return "" } return s.Selected[0] } func (s *Select) Int() int { i, err := strconv.Atoi(s.String()) if err != nil { panic(err) } return i } func (s *Select) FillValue(r *http.Request) { s.Selected = r.Form[s.Name] } func (s *Select) FillValueIndex(r *http.Request, idx int) { if vs := r.Form[s.Name]; len(vs) > idx { s.Selected = []string{vs[idx]} } else { s.Selected = nil } } func (s *Select) ValidOptionsSelected() bool { if len(s.Selected) == 0 { return false } for _, selected := range s.Selected { if !s.isValidOption(selected) { return false } } return true } func (s *Select) isValidOption(selected string) bool { for _, option := range s.Options { if option.Value == selected { return true } } return false } func (s *Select) IsSelected(v string) bool { for _, selected := range s.Selected { if selected == v { return true } } return false } type Option struct { Value string Label string } func MustGetOptions(ctx context.Context, conn *database.Conn, sql string, args ...interface{}) []*Option { rows, err := conn.Query(ctx, sql, args...) if err != nil { panic(err) } defer rows.Close() var options []*Option for rows.Next() { option := &Option{} err = rows.Scan(&option.Value, &option.Label) if err != nil { panic(err) } options = append(options, option) } if rows.Err() != nil { panic(rows.Err()) } return options } func MustGetCountryOptions(ctx context.Context, conn *database.Conn, l *locale.Locale) []*Option { return MustGetOptions(ctx, conn, "select country.country_code, coalesce(i18n.name, country.name) as l10n_name from country left join country_i18n as i18n on country.country_code = i18n.country_code and i18n.lang_tag = $1 order by l10n_name", l.Language) } func MustGetDocumentTypeOptions(ctx context.Context, conn *database.Conn, l *locale.Locale) []*Option { return MustGetOptions(ctx, conn, "select idt.id_document_type_id::text, coalesce(i18n.name, idt.name) as l10n_name from id_document_type as idt left join id_document_type_i18n as i18n on idt.id_document_type_id = i18n.id_document_type_id and i18n.lang_tag = $1 order by l10n_name", l.Language) }