From 9e686f546d32f4355f18b4ab656028cdea03dfaa Mon Sep 17 00:00:00 2001 From: Adriano Caloiaro Date: Thu, 20 Feb 2025 14:51:59 -0700 Subject: [PATCH] feat: randomize question options --- flake.nix | 5 + handlers/builder.go | 5 + types/formfieldoptionorder_enumer.go | 108 +++++++ types/types.go | 94 ++++-- ui/builder/builder.templ | 67 +++- ui/builder/builder_templ.go | 464 +++++++++++++++------------ ui/builder/builder_templ.txt | 9 +- ui/fields/fields.templ | 2 +- ui/fields/fields_templ.go | 2 +- ui/fields/single_choice.templ | 4 +- ui/fields/single_choice_templ.go | 4 +- 11 files changed, 507 insertions(+), 257 deletions(-) create mode 100644 types/formfieldoptionorder_enumer.go diff --git a/flake.nix b/flake.nix index d3720d8..75b8680 100644 --- a/flake.nix +++ b/flake.nix @@ -161,6 +161,11 @@ ${sqlc}/bin/sqlc generate && echo sqlc generate done ''; }; + + jjd = { + description = "jujutsu diff, specialized for templ projects"; + exec = ''jj diff '~ glob:"**/*_templ.txt" & ~ glob:"**/*_templ.go"' --git''; + }; }; processes.frm-server = { diff --git a/handlers/builder.go b/handlers/builder.go index 6c7d482..dfef1f9 100644 --- a/handlers/builder.go +++ b/handlers/builder.go @@ -456,6 +456,11 @@ func UpdateFields(w http.ResponseWriter, r *http.Request) { field.Options = toFormFieldOption(draft.Fields[fieldID], fieldValues) case fieldName == "option_labels": field.OptionLabels = fieldValues + case fieldName == "option_ordering": + field.OptionOrder, err = types.FormFieldOptionOrderString(fieldValues[0]) + if err != nil { + field.OptionOrder = types.OptionOrderNatural + } // field logic, target field chosen case fieldGroup == builder.FieldGroupLogic && fieldName == builder.FieldLogicTargetFieldID: targetFieldID, err := uuid.Parse(fieldValues[0]) diff --git a/types/formfieldoptionorder_enumer.go b/types/formfieldoptionorder_enumer.go new file mode 100644 index 0000000..7f5ab09 --- /dev/null +++ b/types/formfieldoptionorder_enumer.go @@ -0,0 +1,108 @@ +// Code generated by "enumer -type FormFieldOptionOrder -trimprefix FormFieldOptionOrder -transform=snake -json -text"; DO NOT EDIT. + +package types + +import ( + "encoding/json" + "fmt" + "strings" +) + +const _FormFieldOptionOrderName = "option_order_naturaloption_order_random" + +var _FormFieldOptionOrderIndex = [...]uint8{0, 20, 39} + +const _FormFieldOptionOrderLowerName = "option_order_naturaloption_order_random" + +func (i FormFieldOptionOrder) String() string { + if i < 0 || i >= FormFieldOptionOrder(len(_FormFieldOptionOrderIndex)-1) { + return fmt.Sprintf("FormFieldOptionOrder(%d)", i) + } + return _FormFieldOptionOrderName[_FormFieldOptionOrderIndex[i]:_FormFieldOptionOrderIndex[i+1]] +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _FormFieldOptionOrderNoOp() { + var x [1]struct{} + _ = x[OptionOrderNatural-(0)] + _ = x[OptionOrderRandom-(1)] +} + +var _FormFieldOptionOrderValues = []FormFieldOptionOrder{OptionOrderNatural, OptionOrderRandom} + +var _FormFieldOptionOrderNameToValueMap = map[string]FormFieldOptionOrder{ + _FormFieldOptionOrderName[0:20]: OptionOrderNatural, + _FormFieldOptionOrderLowerName[0:20]: OptionOrderNatural, + _FormFieldOptionOrderName[20:39]: OptionOrderRandom, + _FormFieldOptionOrderLowerName[20:39]: OptionOrderRandom, +} + +var _FormFieldOptionOrderNames = []string{ + _FormFieldOptionOrderName[0:20], + _FormFieldOptionOrderName[20:39], +} + +// FormFieldOptionOrderString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func FormFieldOptionOrderString(s string) (FormFieldOptionOrder, error) { + if val, ok := _FormFieldOptionOrderNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _FormFieldOptionOrderNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to FormFieldOptionOrder values", s) +} + +// FormFieldOptionOrderValues returns all values of the enum +func FormFieldOptionOrderValues() []FormFieldOptionOrder { + return _FormFieldOptionOrderValues +} + +// FormFieldOptionOrderStrings returns a slice of all String values of the enum +func FormFieldOptionOrderStrings() []string { + strs := make([]string, len(_FormFieldOptionOrderNames)) + copy(strs, _FormFieldOptionOrderNames) + return strs +} + +// IsAFormFieldOptionOrder returns "true" if the value is listed in the enum definition. "false" otherwise +func (i FormFieldOptionOrder) IsAFormFieldOptionOrder() bool { + for _, v := range _FormFieldOptionOrderValues { + if i == v { + return true + } + } + return false +} + +// MarshalJSON implements the json.Marshaler interface for FormFieldOptionOrder +func (i FormFieldOptionOrder) MarshalJSON() ([]byte, error) { + return json.Marshal(i.String()) +} + +// UnmarshalJSON implements the json.Unmarshaler interface for FormFieldOptionOrder +func (i *FormFieldOptionOrder) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("FormFieldOptionOrder should be a string, got %s", data) + } + + var err error + *i, err = FormFieldOptionOrderString(s) + return err +} + +// MarshalText implements the encoding.TextMarshaler interface for FormFieldOptionOrder +func (i FormFieldOptionOrder) MarshalText() ([]byte, error) { + return []byte(i.String()), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface for FormFieldOptionOrder +func (i *FormFieldOptionOrder) UnmarshalText(text []byte) error { + var err error + *i, err = FormFieldOptionOrderString(string(text)) + return err +} diff --git a/types/types.go b/types/types.go index 8772181..df6fa28 100644 --- a/types/types.go +++ b/types/types.go @@ -3,13 +3,16 @@ package types import ( "encoding/json" "errors" + "math/rand/v2" + "slices" + "sort" "github.com/google/uuid" ) // ErrRequiredNoValueProvided is a form validation error for required fields missing values var ErrRequiredNoValueProvided = errors.New("This field is required") -var ErrUnknownOpitonProvided = errors.New("This field is required, please choose a valid option") +var ErrUnknownOptionProvided = errors.New("This field is required, please choose a valid option") // ValidationErrors is a mapping of form field IDs to the errors validating values submitted to those fields type ValidationErrors map[string]error @@ -53,6 +56,16 @@ const ( FieldLogicComparatorNot // target field value is "not" the subject value ) +// FormFieldOptionOrder enum enumerates all possible ways to order FieldOptions +// +//go:generate enumer -type FormFieldOptionOrder -trimprefix FormFieldOptionOrder -transform=snake -json -text +type FormFieldOptionOrder int + +const ( + OptionOrderNatural FormFieldOptionOrder = iota // FieldOptions are ordered naturally according to their order field + OptionOrderRandom // FieldOptions are ordered randomly +) + // FieldLogicTriggerAction enum enumerates all possible field logic trigger actions // //go:generate enumer -type FieldLogicTriggerAction -trimprefix FieldLogicTriggerAction -transform=snake -json -text @@ -60,7 +73,7 @@ type FieldLogicTriggerAction int const ( FieldLogicTriggerShow FieldLogicTriggerAction = iota // make the field visible to the user - FieldLogicTriggerRequire FieldLogicTriggerAction = iota // require the user to enter a value + FieldLogicTriggerRequire // require the user to enter a value ) // FormFields is a collection of form fields associated with a Form @@ -78,17 +91,18 @@ type FieldOptions []Option // FormField is a field associated with a form type FormField struct { - ID uuid.UUID `json:"id"` // field's unique id - Order int `json:"order"` // order in which the field appears on forms - Label string `json:"label"` // field's label (name) - Logic *FieldLogic `json:"logic"` // UI logic for this field - Options FieldOptions `json:"options"` // single/multi-select options - OptionLabels []string `json:"option_labels"` // option labels are shown below [types.FormFieldTypeSingleChoice] options - Placeholder string `json:"placeholder"` // placeholder value - Required bool `json:"required"` // whether the field is required - Hidden bool `json:"hidden"` // whether the field is hidden - Type FormFieldType `json:"type"` // field type - DataType FormFieldDataType `json:"data_type"` // the data type for form submissions to this field + ID uuid.UUID `json:"id"` // field's unique id + Order int `json:"order"` // order in which the field appears on forms + Label string `json:"label"` // field's label (name) + Logic *FieldLogic `json:"logic"` // UI logic for this field + Options FieldOptions `json:"options"` // single/multi-select options + OptionLabels []string `json:"option_labels"` // option labels are shown below [types.FormFieldTypeSingleChoice] options + OptionOrder FormFieldOptionOrder `json:"option_order"` // the order in which options appear to viewers + Placeholder string `json:"placeholder"` // placeholder value + Required bool `json:"required"` // whether the field is required + Hidden bool `json:"hidden"` // whether the field is hidden + Type FormFieldType `json:"type"` // field type + DataType FormFieldDataType `json:"data_type"` // the data type for form submissions to this field } // FormFieldSubmission is a form submission for a particular form field. Form submissions consists of one or more form field submission @@ -142,6 +156,20 @@ func (f FormFieldSortByOrder) Len() int { return len(f) } func (f FormFieldSortByOrder) Swap(i, j int) { f[i], f[j] = f[j], f[i] } func (f FormFieldSortByOrder) Less(i, j int) bool { return f[i].Order < f[j].Order } +// FormFieldOptionSortNatural implements sort.Interface for [[]Option], sorting options naturally by Order +type FormFieldOptionSortNatural []Option + +func (f FormFieldOptionSortNatural) Len() int { return len(f) } +func (f FormFieldOptionSortNatural) Swap(i, j int) { f[i], f[j] = f[j], f[i] } +func (f FormFieldOptionSortNatural) Less(i, j int) bool { return f[i].Order < f[j].Order } + +// FormFieldOptionSortRand implements sort.Interface for [[]Option], sorting options randomly +type FormFieldOptionSortRand []Option + +func (f FormFieldOptionSortRand) Len() int { return len(f) } +func (f FormFieldOptionSortRand) Swap(i, j int) { f[i], f[j] = f[j], f[i] } +func (f FormFieldOptionSortRand) Less(i, j int) bool { return rand.Int64()%2 == 0 } + // Validate validates values submitted to a form field func (f FormField) Validate(value []string) (err error) { if f.Required { @@ -164,7 +192,7 @@ func (f FormField) Validate(value []string) (err error) { } if !allValid(f, value) { - return ErrUnknownOpitonProvided + return ErrUnknownOptionProvided } return nil default: @@ -186,16 +214,17 @@ func (f FormField) MarshalJSON() ([]byte, error) { } d := struct { - ID uuid.UUID `json:"id"` // field's unique id - Order int `json:"order"` // order in which the field appears on forms - Label string `json:"label"` // field's label (name) - Logic *FieldLogic `json:"logic"` // field's logic configuration - Options FieldOptions `json:"options"` // single/multi-select options - OptionLabels []string `json:"option_labels"` // labels for [FormFieldTypeSingleChoice] options - Placeholder string `json:"placeholder"` // placeholder value - Required bool `json:"required"` // whether the field is required - Hidden bool `json:"hidden"` // whether the field is hidden - Type FormFieldType `json:"type"` // field type + ID uuid.UUID `json:"id"` // field's unique id + Order int `json:"order"` // order in which the field appears on forms + Label string `json:"label"` // field's label (name) + Logic *FieldLogic `json:"logic"` // field's logic configuration + Options FieldOptions `json:"options"` // single/multi-select options + OptionLabels []string `json:"option_labels"` // labels for [FormFieldTypeSingleChoice] options + OptionOrder FormFieldOptionOrder `json:"option_order"` // the order in which options appear + Placeholder string `json:"placeholder"` // placeholder value + Required bool `json:"required"` // whether the field is required + Hidden bool `json:"hidden"` // whether the field is hidden + Type FormFieldType `json:"type"` // field type }{ ID: id, @@ -203,6 +232,7 @@ func (f FormField) MarshalJSON() ([]byte, error) { Label: f.Label, Options: f.Options, OptionLabels: f.OptionLabels, + OptionOrder: f.OptionOrder, Placeholder: f.Placeholder, Required: f.Required, Hidden: f.Hidden, @@ -213,6 +243,22 @@ func (f FormField) MarshalJSON() ([]byte, error) { return json.Marshal(d) } +// SortedOptions returns a field's options sorted according to its [OptionOrder] +func (f *FormField) SortedOptions() (sorted []Option) { + sorted = slices.Clone(f.Options) + switch f.OptionOrder { + case OptionOrderNatural: + sort.Sort(FormFieldOptionSortNatural(sorted)) + return + case OptionOrderRandom: + sort.Sort(FormFieldOptionSortRand(sorted)) + return + default: + sort.Sort(FormFieldOptionSortNatural(sorted)) + return + } +} + // allValid checks if all field submission values are valid options func allValid(field FormField, subset []string) bool { set := make(map[string]bool) diff --git a/ui/builder/builder.templ b/ui/builder/builder.templ index 56969b0..001df87 100644 --- a/ui/builder/builder.templ +++ b/ui/builder/builder.templ @@ -295,22 +295,21 @@ templ fieldSettingsConfiguration(form frm.Form, field types.FormField) { autocomplete="off" _={ fmt.Sprintf("on keyup debounced at 600ms trigger '%s'", FieldsFormUpdateEvent) } /> +
+ + +
switch field.Type { - case types.FormFieldTypeTextSingle, types.FormFieldTypeTextMultiple: -
- -
- case types.FormFieldTypeMultiSelect, types.FormFieldTypeSingleSelect, types.FormFieldTypeSingleChoice, types.FormFieldTypeSingleChoiceSpaced:
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1081,25 +1076,25 @@ func fieldSettingsConfiguration(form frm.Form, field types.FormField) templ.Comp if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if field.Type == types.FormFieldTypeSingleChoice { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "\" class=\"pr-1\">Option labels") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1116,62 +1111,91 @@ func fieldSettingsConfiguration(form frm.Form, field types.FormField) templ.Comp return templ_7745c5c3_Err } } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = selector.Selector(selector.SelectArgs{ + ID: fields.FieldName(field, "", "option_ordering"), + Name: fields.FieldName(field, "", "option_ordering"), + Placeholder: "Choose option ordering", + Multiple: false, + SearchDisabled: true, + Options: optionOrderingOptions(field), + SelectionChangeEvent: FieldsFormUpdateEvent, + }).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "
's checked to false @@ -1179,67 +1203,67 @@ func fieldSettingsConfiguration(form frm.Form, field types.FormField) templ.Comp then trigger '%s'`, fields.FieldName(field, "", "hidden"), FieldsFormUpdateEvent)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/builder/builder.templ`, Line: 365, Col: 66} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "\">
's checked to false @@ -1247,13 +1271,13 @@ func fieldSettingsConfiguration(form frm.Form, field types.FormField) templ.Comp then trigger '%s'`, fields.FieldName(field, "", "required"), FieldsFormUpdateEvent)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/builder/builder.templ`, Line: 386, Col: 68} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/builder/builder.templ`, Line: 399, Col: 68} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "\">
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "\">
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1265,7 +1289,7 @@ func fieldSettingsConfiguration(form frm.Form, field types.FormField) templ.Comp if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1289,64 +1313,64 @@ func fieldLogicConfiguration(form frm.Form, field types.FormField) templ.Compone }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var57 := templ.GetChildren(ctx) - if templ_7745c5c3_Var57 == nil { - templ_7745c5c3_Var57 = templ.NopComponent + templ_7745c5c3_Var58 := templ.GetChildren(ctx) + if templ_7745c5c3_Var58 == nil { + templ_7745c5c3_Var58 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "\" data-hx-swap=\"innerHTML\" data-hx-target=\"") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var62 string + templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("#logic-field-value-chooser-%s", field.ID.String())) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/builder/builder.templ`, Line: 421, Col: 84} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "\" data-hx-on:htmx:config-request=\"event.detail.parameters['id'] = event.detail.triggeringEvent.detail.value\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1361,7 +1385,7 @@ func fieldLogicConfiguration(form frm.Form, field types.FormField) templ.Compone if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1376,20 +1400,20 @@ func fieldLogicConfiguration(form frm.Form, field types.FormField) templ.Compone if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1399,7 +1423,7 @@ func fieldLogicConfiguration(form frm.Form, field types.FormField) templ.Compone return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "

Choose action(s)

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "

Choose action(s)

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1414,7 +1438,7 @@ func fieldLogicConfiguration(form frm.Form, field types.FormField) templ.Compone if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1422,6 +1446,19 @@ func fieldLogicConfiguration(form frm.Form, field types.FormField) templ.Compone }) } +// optionOrderingOptions returns the available orderings for options +func optionOrderingOptions(field types.FormField) (options []selector.Option) { + for _, ordering := range types.FormFieldOptionOrderValues() { + options = append(options, + selector.Option{ + Value: ordering.String(), + Label: orderingLabelFor(ordering), + Selected: field.OptionOrder == ordering, + }) + } + return +} + // comparatorOptionsFor returns the comparators available for a logic field given its Type func comparatorOptionsFor(field types.FormField) (options selector.FieldOptions) { switch field.Type { @@ -1462,6 +1499,17 @@ func logicActionOptions(field types.FormField) (options []selector.Option) { return } +func orderingLabelFor(ordering types.FormFieldOptionOrder) string { + switch ordering { + case types.OptionOrderNatural: + return "Order options naturally" + case types.OptionOrderRandom: + return "Order options randomly" + } + + return "Unknown ordering" +} + func actionLabelFor(action types.FieldLogicTriggerAction) string { switch action { case types.FieldLogicTriggerShow: @@ -1493,9 +1541,9 @@ func LogicConfiguratorStepThree(form frm.Form, field types.FormField, targetFiel }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var63 := templ.GetChildren(ctx) - if templ_7745c5c3_Var63 == nil { - templ_7745c5c3_Var63 = templ.NopComponent + templ_7745c5c3_Var64 := templ.GetChildren(ctx) + if templ_7745c5c3_Var64 == nil { + templ_7745c5c3_Var64 = templ.NopComponent } ctx = templ.ClearChildren(ctx) switch targetField.Type { @@ -1512,69 +1560,69 @@ func LogicConfiguratorStepThree(form frm.Form, field types.FormField, targetFiel return templ_7745c5c3_Err } case types.FormFieldTypeTextSingle, types.FormFieldTypeTextMultiple: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, " 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, " value=\"") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, " value=\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var66 string - templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(field.Logic.TriggerValues[0]) + var templ_7745c5c3_Var67 string + templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.JoinStringErrs(field.Logic.TriggerValues[0]) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/builder/builder.templ`, Line: 528, Col: 41} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/builder/builder.templ`, Line: 565, Col: 41} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var67)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "\"") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, " _=\"") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, " _=\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var67 string - templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("on keyup debounced at 600ms trigger '%s'", FieldsFormUpdateEvent)) + var templ_7745c5c3_Var68 string + templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("on keyup debounced at 600ms trigger '%s'", FieldsFormUpdateEvent)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/builder/builder.templ`, Line: 530, Col: 86} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/builder/builder.templ`, Line: 567, Col: 86} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var67)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "\">") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/ui/builder/builder_templ.txt b/ui/builder/builder_templ.txt index 896bf7d..27386b3 100644 --- a/ui/builder/builder_templ.txt +++ b/ui/builder/builder_templ.txt @@ -62,18 +62,19 @@ \" name=\" \" type=\"text\" class=\"w-full rounded-md\" value=\" \" autocomplete=\"off\" _=\" -\"> -
+\">
+
- for _, option := range field.Options { + for _, option := range field.SortedOptions() {