mirror of
https://github.com/go-gitea/gitea.git
synced 2025-10-27 00:23:41 +09:00
Extend issue template yaml engine (#29274)
Add new option:
`visible`: witch can hide a specific field of the form or the created
content afterwards
It is a string array witch can contain `form` and `content`. If only
`form` is present, it wont show up in the created issue afterwards and
the other way around. By default it sets both except for markdown
As they are optional and github don't have any similar thing, it is non
breaking and also do not conflict with it.
With this you can:
- define "post issue creation" elements like a TODO list to track an
issue state
- make sure to have a checkbox that reminds the user to check for a
thing but dont have it in the created issue afterwards
- define markdown for the created issue (was the downside of using yaml
instead of md in the past)
- ...
## Demo
```yaml
name: New Contribution
description: External Contributor creating a pull
body:
- type: checkboxes
id: extern-todo
visible: [form]
attributes:
label: Contribution Guidelines
options:
- label: I checked there exist no similar feature to be extended
required: true
- label: I did read the CONTRIBUTION.MD
required: true
- type: checkboxes
id: intern-todo
visible: [content]
attributes:
label: Maintainer Check-List
options:
- label: Does this pull follow the KISS principe
- label: Checked if internal bord was notifyed
# ....
```
[Demo
Video](https://cloud.obermui.de/s/tm34fSAbJp9qw9z/download/vid-20240220-152751.mkv)
---
*Sponsored by Kithara Software GmbH*
---------
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -318,6 +319,42 @@ body:
|
||||
`,
|
||||
wantErr: "body[0](checkboxes), option[0]: 'required' should be a bool",
|
||||
},
|
||||
{
|
||||
name: "field is required but hidden",
|
||||
content: `
|
||||
name: "test"
|
||||
about: "this is about"
|
||||
body:
|
||||
- type: "input"
|
||||
id: "1"
|
||||
attributes:
|
||||
label: "a"
|
||||
validations:
|
||||
required: true
|
||||
visible: [content]
|
||||
`,
|
||||
wantErr: "body[0](input): can not require a hidden field",
|
||||
},
|
||||
{
|
||||
name: "checkboxes is required but hidden",
|
||||
content: `
|
||||
name: "test"
|
||||
about: "this is about"
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: "1"
|
||||
attributes:
|
||||
label: Label of checkboxes
|
||||
description: Description of checkboxes
|
||||
options:
|
||||
- label: Option 1
|
||||
required: false
|
||||
- label: Required and hidden
|
||||
required: true
|
||||
visible: [content]
|
||||
`,
|
||||
wantErr: "body[0](checkboxes), option[1]: can not require a hidden checkbox",
|
||||
},
|
||||
{
|
||||
name: "valid",
|
||||
content: `
|
||||
@@ -374,8 +411,11 @@ body:
|
||||
required: true
|
||||
- label: Option 2 of checkboxes
|
||||
required: false
|
||||
- label: Option 3 of checkboxes
|
||||
- label: Hidden Option 3 of checkboxes
|
||||
visible: [content]
|
||||
- label: Required but not submitted
|
||||
required: true
|
||||
visible: [form]
|
||||
`,
|
||||
want: &api.IssueTemplate{
|
||||
Name: "Name",
|
||||
@@ -390,6 +430,7 @@ body:
|
||||
Attributes: map[string]any{
|
||||
"value": "Value of the markdown",
|
||||
},
|
||||
Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm},
|
||||
},
|
||||
{
|
||||
Type: "textarea",
|
||||
@@ -404,6 +445,7 @@ body:
|
||||
Validations: map[string]any{
|
||||
"required": true,
|
||||
},
|
||||
Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm, api.IssueFormFieldVisibleContent},
|
||||
},
|
||||
{
|
||||
Type: "input",
|
||||
@@ -419,6 +461,7 @@ body:
|
||||
"is_number": true,
|
||||
"regex": "[a-zA-Z0-9]+",
|
||||
},
|
||||
Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm, api.IssueFormFieldVisibleContent},
|
||||
},
|
||||
{
|
||||
Type: "dropdown",
|
||||
@@ -436,6 +479,7 @@ body:
|
||||
Validations: map[string]any{
|
||||
"required": true,
|
||||
},
|
||||
Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm, api.IssueFormFieldVisibleContent},
|
||||
},
|
||||
{
|
||||
Type: "checkboxes",
|
||||
@@ -446,9 +490,11 @@ body:
|
||||
"options": []any{
|
||||
map[string]any{"label": "Option 1 of checkboxes", "required": true},
|
||||
map[string]any{"label": "Option 2 of checkboxes", "required": false},
|
||||
map[string]any{"label": "Option 3 of checkboxes", "required": true},
|
||||
map[string]any{"label": "Hidden Option 3 of checkboxes", "visible": []string{"content"}},
|
||||
map[string]any{"label": "Required but not submitted", "required": true, "visible": []string{"form"}},
|
||||
},
|
||||
},
|
||||
Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm, api.IssueFormFieldVisibleContent},
|
||||
},
|
||||
},
|
||||
FileName: "test.yaml",
|
||||
@@ -467,7 +513,12 @@ body:
|
||||
- type: markdown
|
||||
id: id1
|
||||
attributes:
|
||||
value: Value of the markdown
|
||||
value: Value of the markdown shown in form
|
||||
- type: markdown
|
||||
id: id2
|
||||
attributes:
|
||||
value: Value of the markdown shown in created issue
|
||||
visible: [content]
|
||||
`,
|
||||
want: &api.IssueTemplate{
|
||||
Name: "Name",
|
||||
@@ -480,8 +531,17 @@ body:
|
||||
Type: "markdown",
|
||||
ID: "id1",
|
||||
Attributes: map[string]any{
|
||||
"value": "Value of the markdown",
|
||||
"value": "Value of the markdown shown in form",
|
||||
},
|
||||
Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm},
|
||||
},
|
||||
{
|
||||
Type: "markdown",
|
||||
ID: "id2",
|
||||
Attributes: map[string]any{
|
||||
"value": "Value of the markdown shown in created issue",
|
||||
},
|
||||
Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleContent},
|
||||
},
|
||||
},
|
||||
FileName: "test.yaml",
|
||||
@@ -515,6 +575,7 @@ body:
|
||||
Attributes: map[string]any{
|
||||
"value": "Value of the markdown",
|
||||
},
|
||||
Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm},
|
||||
},
|
||||
},
|
||||
FileName: "test.yaml",
|
||||
@@ -548,6 +609,7 @@ body:
|
||||
Attributes: map[string]any{
|
||||
"value": "Value of the markdown",
|
||||
},
|
||||
Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm},
|
||||
},
|
||||
},
|
||||
FileName: "test.yaml",
|
||||
@@ -622,9 +684,14 @@ body:
|
||||
- type: markdown
|
||||
id: id1
|
||||
attributes:
|
||||
value: Value of the markdown
|
||||
- type: textarea
|
||||
value: Value of the markdown shown in form
|
||||
- type: markdown
|
||||
id: id2
|
||||
attributes:
|
||||
value: Value of the markdown shown in created issue
|
||||
visible: [content]
|
||||
- type: textarea
|
||||
id: id3
|
||||
attributes:
|
||||
label: Label of textarea
|
||||
description: Description of textarea
|
||||
@@ -634,7 +701,7 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: id3
|
||||
id: id4
|
||||
attributes:
|
||||
label: Label of input
|
||||
description: Description of input
|
||||
@@ -646,7 +713,7 @@ body:
|
||||
is_number: true
|
||||
regex: "[a-zA-Z0-9]+"
|
||||
- type: dropdown
|
||||
id: id4
|
||||
id: id5
|
||||
attributes:
|
||||
label: Label of dropdown
|
||||
description: Description of dropdown
|
||||
@@ -658,7 +725,7 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: id5
|
||||
id: id6
|
||||
attributes:
|
||||
label: Label of checkboxes
|
||||
description: Description of checkboxes
|
||||
@@ -669,20 +736,26 @@ body:
|
||||
required: false
|
||||
- label: Option 3 of checkboxes
|
||||
required: true
|
||||
visible: [form]
|
||||
- label: Hidden Option of checkboxes
|
||||
visible: [content]
|
||||
`,
|
||||
values: map[string][]string{
|
||||
"form-field-id2": {"Value of id2"},
|
||||
"form-field-id3": {"Value of id3"},
|
||||
"form-field-id4": {"0,1"},
|
||||
"form-field-id5-0": {"on"},
|
||||
"form-field-id5-2": {"on"},
|
||||
"form-field-id4": {"Value of id4"},
|
||||
"form-field-id5": {"0,1"},
|
||||
"form-field-id6-0": {"on"},
|
||||
"form-field-id6-2": {"on"},
|
||||
},
|
||||
},
|
||||
want: `### Label of textarea
|
||||
|
||||
` + "```bash\nValue of id2\n```" + `
|
||||
want: `Value of the markdown shown in created issue
|
||||
|
||||
Value of id3
|
||||
### Label of textarea
|
||||
|
||||
` + "```bash\nValue of id3\n```" + `
|
||||
|
||||
Value of id4
|
||||
|
||||
### Label of dropdown
|
||||
|
||||
@@ -692,7 +765,7 @@ Option 1 of dropdown, Option 2 of dropdown
|
||||
|
||||
- [x] Option 1 of checkboxes
|
||||
- [ ] Option 2 of checkboxes
|
||||
- [x] Option 3 of checkboxes
|
||||
- [ ] Hidden Option of checkboxes
|
||||
|
||||
`,
|
||||
},
|
||||
@@ -704,7 +777,7 @@ Option 1 of dropdown, Option 2 of dropdown
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := RenderToMarkdown(template, tt.args.values); got != tt.want {
|
||||
t.Errorf("RenderToMarkdown() = %v, want %v", got, tt.want)
|
||||
assert.EqualValues(t, tt.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user