]> source.dussan.org Git - gitea.git/commitdiff
Support setting the `default` attribute of the issue template dropdown field (#31045...
authorGiteabot <teabot@gitea.io>
Fri, 24 May 2024 03:01:09 +0000 (11:01 +0800)
committerGitHub <noreply@github.com>
Fri, 24 May 2024 03:01:09 +0000 (11:01 +0800)
Backport #31045 by @Zettat123

Fix #31044

According to [GitHub issue template
documentation](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#attributes-for-dropdown),
the `default` attribute can be used to specify the preselected option
for a dropdown field.

Co-authored-by: Zettat123 <zettat123@gmail.com>
modules/issue/template/template.go
modules/issue/template/template_test.go
templates/repo/issue/fields/dropdown.tmpl

index 3be48b9edc0482f0d3699e1a302fe96269657f13..cf5fcf28e5dae730aae87dfc2dc165582924c3eb 100644 (file)
@@ -91,6 +91,9 @@ func validateYaml(template *api.IssueTemplate) error {
                        if err := validateOptions(field, idx); err != nil {
                                return err
                        }
+                       if err := validateDropdownDefault(position, field.Attributes); err != nil {
+                               return err
+                       }
                case api.IssueFormFieldTypeCheckboxes:
                        if err := validateStringItem(position, field.Attributes, false, "description"); err != nil {
                                return err
@@ -249,6 +252,28 @@ func validateBoolItem(position errorPosition, m map[string]any, names ...string)
        return nil
 }
 
+func validateDropdownDefault(position errorPosition, attributes map[string]any) error {
+       v, ok := attributes["default"]
+       if !ok {
+               return nil
+       }
+       defaultValue, ok := v.(int)
+       if !ok {
+               return position.Errorf("'default' should be an int")
+       }
+
+       options, ok := attributes["options"].([]any)
+       if !ok {
+               // should not happen
+               return position.Errorf("'options' is required and should be a array")
+       }
+       if defaultValue < 0 || defaultValue >= len(options) {
+               return position.Errorf("the value of 'default' is out of range")
+       }
+
+       return nil
+}
+
 type errorPosition string
 
 func (p errorPosition) Errorf(format string, a ...any) error {
index e24b962d61b7bfd54e3dac250d9adb7fc30eca7b..481058754d0f69b4df5ce7af600e996dca0b58ce 100644 (file)
@@ -355,6 +355,96 @@ body:
 `,
                        wantErr: "body[0](checkboxes), option[1]: can not require a hidden checkbox",
                },
+               {
+                       name: "dropdown default is not an integer",
+                       content: `
+name: "test"
+about: "this is about"
+body:
+  - type: dropdown
+    id: "1"
+    attributes:
+      label: Label of dropdown
+      description: Description of dropdown
+      multiple: true
+      options:
+        - Option 1 of dropdown
+        - Option 2 of dropdown
+        - Option 3 of dropdown
+      default: "def"
+    validations:
+      required: true
+`,
+                       wantErr: "body[0](dropdown): 'default' should be an int",
+               },
+               {
+                       name: "dropdown default is out of range",
+                       content: `
+name: "test"
+about: "this is about"
+body:
+  - type: dropdown
+    id: "1"
+    attributes:
+      label: Label of dropdown
+      description: Description of dropdown
+      multiple: true
+      options:
+        - Option 1 of dropdown
+        - Option 2 of dropdown
+        - Option 3 of dropdown
+      default: 3
+    validations:
+      required: true
+`,
+                       wantErr: "body[0](dropdown): the value of 'default' is out of range",
+               },
+               {
+                       name: "dropdown without default is valid",
+                       content: `
+name: "test"
+about: "this is about"
+body:
+  - type: dropdown
+    id: "1"
+    attributes:
+      label: Label of dropdown
+      description: Description of dropdown
+      multiple: true
+      options:
+        - Option 1 of dropdown
+        - Option 2 of dropdown
+        - Option 3 of dropdown
+    validations:
+      required: true
+`,
+                       want: &api.IssueTemplate{
+                               Name:  "test",
+                               About: "this is about",
+                               Fields: []*api.IssueFormField{
+                                       {
+                                               Type: "dropdown",
+                                               ID:   "1",
+                                               Attributes: map[string]any{
+                                                       "label":       "Label of dropdown",
+                                                       "description": "Description of dropdown",
+                                                       "multiple":    true,
+                                                       "options": []any{
+                                                               "Option 1 of dropdown",
+                                                               "Option 2 of dropdown",
+                                                               "Option 3 of dropdown",
+                                                       },
+                                               },
+                                               Validations: map[string]any{
+                                                       "required": true,
+                                               },
+                                               Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm, api.IssueFormFieldVisibleContent},
+                                       },
+                               },
+                               FileName: "test.yaml",
+                       },
+                       wantErr: "",
+               },
                {
                        name: "valid",
                        content: `
@@ -399,6 +489,7 @@ body:
         - Option 1 of dropdown
         - Option 2 of dropdown
         - Option 3 of dropdown
+      default: 1
     validations:
       required: true
   - type: checkboxes
@@ -475,6 +566,7 @@ body:
                                                                "Option 2 of dropdown",
                                                                "Option 3 of dropdown",
                                                        },
+                                                       "default": 1,
                                                },
                                                Validations: map[string]any{
                                                        "required": true,
index f4fa79738c94c1c15a2f61ccb1bd9b8a86735e89..26505f58a52c4fc39fdcc4e42cf480d7e7d3eb3f 100644 (file)
@@ -2,7 +2,7 @@
        {{template "repo/issue/fields/header" .}}
        {{/* FIXME: required validation */}}
        <div class="ui fluid selection dropdown {{if .item.Attributes.multiple}}multiple clearable{{end}}">
-               <input type="hidden" name="form-field-{{.item.ID}}" value="0">
+               <input type="hidden" name="form-field-{{.item.ID}}" value="{{.item.Attributes.default}}">
                {{svg "octicon-triangle-down" 14 "dropdown icon"}}
                {{if not .item.Validations.required}}
                {{svg "octicon-x" 14 "remove icon"}}