mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
feat: move proxy settings page to deployment options (#8246)
* feat: Move workspace proxy page to deployment options Workspace proxy settings page is now an admin feature * WorkspaceProxy response extends region
This commit is contained in:
+24
-9
@@ -188,32 +188,39 @@ func DisplayTable(out any, sort string, filterColumns []string) (string, error)
|
||||
// returned. If the table tag is malformed, an error is returned.
|
||||
//
|
||||
// The returned name is transformed from "snake_case" to "normal text".
|
||||
func parseTableStructTag(field reflect.StructField) (name string, defaultSort, recursive bool, err error) {
|
||||
func parseTableStructTag(field reflect.StructField) (name string, defaultSort, recursive bool, skipParentName bool, err error) {
|
||||
tags, err := structtag.Parse(string(field.Tag))
|
||||
if err != nil {
|
||||
return "", false, false, xerrors.Errorf("parse struct field tag %q: %w", string(field.Tag), err)
|
||||
return "", false, false, false, xerrors.Errorf("parse struct field tag %q: %w", string(field.Tag), err)
|
||||
}
|
||||
|
||||
tag, err := tags.Get("table")
|
||||
if err != nil || tag.Name == "-" {
|
||||
// tags.Get only returns an error if the tag is not found.
|
||||
return "", false, false, nil
|
||||
return "", false, false, false, nil
|
||||
}
|
||||
|
||||
defaultSortOpt := false
|
||||
recursiveOpt := false
|
||||
skipParentNameOpt := false
|
||||
for _, opt := range tag.Options {
|
||||
switch opt {
|
||||
case "default_sort":
|
||||
defaultSortOpt = true
|
||||
case "recursive":
|
||||
recursiveOpt = true
|
||||
case "recursive_inline":
|
||||
// recursive_inline is a helper to make recursive tables look nicer.
|
||||
// It skips prefixing the parent name to the child name. If you do this,
|
||||
// make sure the child name is unique across all nested structs in the parent.
|
||||
recursiveOpt = true
|
||||
skipParentNameOpt = true
|
||||
default:
|
||||
return "", false, false, xerrors.Errorf("unknown option %q in struct field tag", opt)
|
||||
return "", false, false, false, xerrors.Errorf("unknown option %q in struct field tag", opt)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.ReplaceAll(tag.Name, "_", " "), defaultSortOpt, recursiveOpt, nil
|
||||
return strings.ReplaceAll(tag.Name, "_", " "), defaultSortOpt, recursiveOpt, skipParentNameOpt, nil
|
||||
}
|
||||
|
||||
func isStructOrStructPointer(t reflect.Type) bool {
|
||||
@@ -235,7 +242,7 @@ func typeToTableHeaders(t reflect.Type) ([]string, string, error) {
|
||||
defaultSortName := ""
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
name, defaultSort, recursive, err := parseTableStructTag(field)
|
||||
name, defaultSort, recursive, skip, err := parseTableStructTag(field)
|
||||
if err != nil {
|
||||
return nil, "", xerrors.Errorf("parse struct tags for field %q in type %q: %w", field.Name, t.String(), err)
|
||||
}
|
||||
@@ -260,7 +267,11 @@ func typeToTableHeaders(t reflect.Type) ([]string, string, error) {
|
||||
return nil, "", xerrors.Errorf("get child field header names for field %q in type %q: %w", field.Name, fieldType.String(), err)
|
||||
}
|
||||
for _, childName := range childNames {
|
||||
headers = append(headers, fmt.Sprintf("%s %s", name, childName))
|
||||
fullName := fmt.Sprintf("%s %s", name, childName)
|
||||
if skip {
|
||||
fullName = childName
|
||||
}
|
||||
headers = append(headers, fullName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
@@ -296,7 +307,7 @@ func valueToTableMap(val reflect.Value) (map[string]any, error) {
|
||||
for i := 0; i < val.NumField(); i++ {
|
||||
field := val.Type().Field(i)
|
||||
fieldVal := val.Field(i)
|
||||
name, _, recursive, err := parseTableStructTag(field)
|
||||
name, _, recursive, skip, err := parseTableStructTag(field)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("parse struct tags for field %q in type %T: %w", field.Name, val, err)
|
||||
}
|
||||
@@ -318,7 +329,11 @@ func valueToTableMap(val reflect.Value) (map[string]any, error) {
|
||||
return nil, xerrors.Errorf("get child field values for field %q in type %q: %w", field.Name, fieldType.String(), err)
|
||||
}
|
||||
for childName, childValue := range childMap {
|
||||
row[fmt.Sprintf("%s %s", name, childName)] = childValue
|
||||
fullName := fmt.Sprintf("%s %s", name, childName)
|
||||
if skip {
|
||||
fullName = childName
|
||||
}
|
||||
row[fullName] = childValue
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -49,6 +49,11 @@ type tableTest3 struct {
|
||||
Sub tableTest2 `table:"inner,recursive,default_sort"`
|
||||
}
|
||||
|
||||
type tableTest4 struct {
|
||||
Inline tableTest2 `table:"ignored,recursive_inline"`
|
||||
SortField string `table:"sort_field,default_sort"`
|
||||
}
|
||||
|
||||
func Test_DisplayTable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -188,6 +193,31 @@ foo foo1 foo3 2022-08-02T15:49:10Z
|
||||
compareTables(t, expected, out)
|
||||
})
|
||||
|
||||
t.Run("Inline", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
expected := `
|
||||
NAME AGE
|
||||
Alice 25
|
||||
`
|
||||
|
||||
inlineIn := []tableTest4{
|
||||
{
|
||||
Inline: tableTest2{
|
||||
Name: stringWrapper{
|
||||
str: "Alice",
|
||||
},
|
||||
Age: 25,
|
||||
NotIncluded: "IgnoreMe",
|
||||
},
|
||||
},
|
||||
}
|
||||
out, err := cliui.DisplayTable(inlineIn, "", []string{"name", "age"})
|
||||
log.Println("rendered table:\n" + out)
|
||||
require.NoError(t, err)
|
||||
compareTables(t, expected, out)
|
||||
})
|
||||
|
||||
// This test ensures that safeties against invalid use of `table` tags
|
||||
// causes errors (even without data).
|
||||
t.Run("Errors", func(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user