-
Notifications
You must be signed in to change notification settings - Fork 22
feat: form_type
and styling
metadata arguments added
#375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
43253f7
feat: add form_type argument to parameters
Emyrk 2d79a97
fix param order
Emyrk 4bafcc6
add error type
Emyrk 19d6749
apply default form_type to state
Emyrk 9fc221c
fix parsing form_type from terraform
Emyrk b80ab8f
chore: multi select form control allows options to be string
Emyrk 50c6a0d
chore: add slider and 'form_type_metadata' argument to parameter
Emyrk c0d38d3
move code block
Emyrk 0b94955
fixup error message
Emyrk 05e682d
add invalid boolean validation field
Emyrk 0dfab58
tag-input -> tag-select
Emyrk e971837
chore: use constants over string literals for option type
Emyrk 12aec75
remove invalid option
Emyrk 0b28b64
fixup! remove invalid option
Emyrk bf2b673
testing framework for form_type
Emyrk c0be472
polishig up extra code and syntax
Emyrk cd52cae
finish all table test cases
Emyrk fec030d
final touches on the test
Emyrk f0bca91
also assert styling
Emyrk 18c3d05
add a test case for invalid multi selecT
Emyrk a04ffa6
push up an example multi select
Emyrk 2b5ff08
make gne
Emyrk 18886f8
make fmt
Emyrk acf5977
use comment instead of json
Emyrk fcdd6bd
make gen
Emyrk 5da70d5
spelling typo
Emyrk 8356ff7
Merge branch 'main' into stevenmasley/form_control
aslilac 771be40
mark the check up front
Emyrk bb00c25
cleanup output
Emyrk d25fcf6
add test dupe check up front
Emyrk 8951940
adding the example before release
Emyrk 5d485d6
cleanup test logs
Emyrk f21c732
add comment
Emyrk f110129
renaming from PR comments
Emyrk d330f21
make struct field types explicit
Emyrk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
package provider | ||
|
||
import ( | ||
"slices" | ||
|
||
"golang.org/x/xerrors" | ||
) | ||
|
||
// OptionType is a type of option that can be used in the 'type' argument of | ||
// a parameter. These should match types as defined in terraform: | ||
// | ||
// https://developer.hashicorp.com/terraform/language/expressions/types | ||
// | ||
// The value have to be string literals, as type constraint keywords are not | ||
// supported in providers. | ||
type OptionType string | ||
|
||
const ( | ||
OptionTypeString OptionType = "string" | ||
OptionTypeNumber OptionType = "number" | ||
OptionTypeBoolean OptionType = "bool" | ||
OptionTypeListString OptionType = "list(string)" | ||
) | ||
|
||
func OptionTypes() []OptionType { | ||
return []OptionType{ | ||
OptionTypeString, | ||
OptionTypeNumber, | ||
OptionTypeBoolean, | ||
OptionTypeListString, | ||
} | ||
} | ||
|
||
// ParameterFormType is the list of supported form types for display in | ||
// the Coder "create workspace" form. These form types are functional as well | ||
// as cosmetic. Refer to `formTypeTruthTable` for the allowed pairings. | ||
// For example, "multi-select" has the type "list(string)" but the option | ||
// values are "string". | ||
type ParameterFormType string | ||
|
||
const ( | ||
ParameterFormTypeDefault ParameterFormType = "" | ||
ParameterFormTypeRadio ParameterFormType = "radio" | ||
ParameterFormTypeSlider ParameterFormType = "slider" | ||
ParameterFormTypeInput ParameterFormType = "input" | ||
ParameterFormTypeDropdown ParameterFormType = "dropdown" | ||
ParameterFormTypeCheckbox ParameterFormType = "checkbox" | ||
ParameterFormTypeSwitch ParameterFormType = "switch" | ||
ParameterFormTypeMultiSelect ParameterFormType = "multi-select" | ||
ParameterFormTypeTagSelect ParameterFormType = "tag-select" | ||
ParameterFormTypeTextArea ParameterFormType = "textarea" | ||
ParameterFormTypeError ParameterFormType = "error" | ||
) | ||
|
||
// ParameterFormTypes should be kept in sync with the enum list above. | ||
func ParameterFormTypes() []ParameterFormType { | ||
return []ParameterFormType{ | ||
// Intentionally omit "ParameterFormTypeDefault" from this set. | ||
// It is a valid enum, but will always be mapped to a real value when | ||
// being used. | ||
ParameterFormTypeRadio, | ||
ParameterFormTypeSlider, | ||
ParameterFormTypeInput, | ||
ParameterFormTypeDropdown, | ||
ParameterFormTypeCheckbox, | ||
ParameterFormTypeSwitch, | ||
ParameterFormTypeMultiSelect, | ||
ParameterFormTypeTagSelect, | ||
ParameterFormTypeTextArea, | ||
ParameterFormTypeError, | ||
} | ||
} | ||
|
||
// formTypeTruthTable is a map of [`type`][`optionCount` > 0] to `form_type`. | ||
// The first value in the slice is the default value assuming `form_type` is | ||
// not specified. | ||
// | ||
// The boolean key indicates whether the `options` field is specified. | ||
// | Type | Options | Specified Form Type | form_type | Notes | | ||
// |-------------------|---------|---------------------|----------------|--------------------------------| | ||
// | `string` `number` | Y | | `radio` | | | ||
// | `string` `number` | Y | `dropdown` | `dropdown` | | | ||
// | `string` `number` | N | | `input` | | | ||
// | `string` | N | 'textarea' | `textarea` | | | ||
// | `number` | N | 'slider' | `slider` | min/max validation | | ||
// | `bool` | Y | | `radio` | | | ||
// | `bool` | N | | `checkbox` | | | ||
// | `bool` | N | `switch` | `switch` | | | ||
// | `list(string)` | Y | | `radio` | | | ||
// | `list(string)` | N | | `tag-select` | | | ||
// | `list(string)` | Y | `multi-select` | `multi-select` | Option values will be `string` | | ||
var formTypeTruthTable = map[OptionType]map[bool][]ParameterFormType{ | ||
OptionTypeString: { | ||
true: {ParameterFormTypeRadio, ParameterFormTypeDropdown}, | ||
false: {ParameterFormTypeInput, ParameterFormTypeTextArea}, | ||
}, | ||
OptionTypeNumber: { | ||
true: {ParameterFormTypeRadio, ParameterFormTypeDropdown}, | ||
false: {ParameterFormTypeInput, ParameterFormTypeSlider}, | ||
}, | ||
OptionTypeBoolean: { | ||
true: {ParameterFormTypeRadio}, | ||
false: {ParameterFormTypeCheckbox, ParameterFormTypeSwitch}, | ||
}, | ||
OptionTypeListString: { | ||
true: {ParameterFormTypeRadio, ParameterFormTypeMultiSelect}, | ||
false: {ParameterFormTypeTagSelect}, | ||
}, | ||
} | ||
|
||
// ValidateFormType handles the truth table for the valid set of `type` and | ||
// `form_type` options. | ||
// The OptionType is also returned because it is possible the 'type' of the | ||
// 'value' & 'default' fields is different from the 'type' of the options. | ||
// The use case is when using multi-select. The options are 'string' and the | ||
// value is 'list(string)'. | ||
func ValidateFormType(paramType OptionType, optionCount int, specifiedFormType ParameterFormType) (OptionType, ParameterFormType, error) { | ||
allowed, ok := formTypeTruthTable[paramType][optionCount > 0] | ||
if !ok || len(allowed) == 0 { | ||
return paramType, specifiedFormType, xerrors.Errorf("value type %q is not supported for 'form_types'", paramType) | ||
} | ||
|
||
if specifiedFormType == ParameterFormTypeDefault { | ||
// handle the default case | ||
specifiedFormType = allowed[0] | ||
} | ||
|
||
if !slices.Contains(allowed, specifiedFormType) { | ||
return paramType, specifiedFormType, xerrors.Errorf("value type %q is not supported for 'form_types'", specifiedFormType) | ||
} | ||
|
||
// This is the only current special case. If 'multi-select' is selected, the type | ||
// of 'value' and an options 'value' are different. The type of the parameter is | ||
// `list(string)` but the type of the individual options is `string`. | ||
if paramType == OptionTypeListString && specifiedFormType == ParameterFormTypeMultiSelect { | ||
return OptionTypeString, ParameterFormTypeMultiSelect, nil | ||
} | ||
|
||
return paramType, specifiedFormType, nil | ||
} | ||
|
||
func toStrings[A ~string](l []A) []string { | ||
var r []string | ||
for _, v := range l { | ||
r = append(r, string(v)) | ||
} | ||
return r | ||
} | ||
johnstcn marked this conversation as resolved.
Show resolved
Hide resolved
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good to explicitly document each type + option value for the possible values of
ParameterFormType
below.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather defer that to the truth table below. I do not want to document it in 2 places.