| 311 | } |
| 312 | |
| 313 | func RichMultiSelect(inv *serpent.Invocation, richOptions RichMultiSelectOptions) ([]string, error) { |
| 314 | var opts []string |
| 315 | var defaultOpts []string |
| 316 | |
| 317 | asLine := func(option codersdk.TemplateVersionParameterOption) string { |
| 318 | line := option.Name |
| 319 | if len(option.Description) > 0 { |
| 320 | line += ": " + option.Description |
| 321 | } |
| 322 | return line |
| 323 | } |
| 324 | |
| 325 | var predefinedOpts []string |
| 326 | for i, option := range richOptions.Options { |
| 327 | opts = append(opts, asLine(option)) // Some options may have description defined. |
| 328 | |
| 329 | // Check if option is selected by default |
| 330 | if slices.Contains(richOptions.Defaults, option.Value) { |
| 331 | defaultOpts = append(defaultOpts, opts[i]) |
| 332 | predefinedOpts = append(predefinedOpts, option.Value) |
| 333 | } |
| 334 | } |
| 335 | |
| 336 | // Check if "defaults" contains extra/custom options, user could select them. |
| 337 | for _, def := range richOptions.Defaults { |
| 338 | if !slices.Contains(predefinedOpts, def) { |
| 339 | opts = append(opts, def) |
| 340 | defaultOpts = append(defaultOpts, def) |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | selected, err := MultiSelect(inv, MultiSelectOptions{ |
| 345 | Message: richOptions.Message, |
| 346 | Options: opts, |
| 347 | Defaults: defaultOpts, |
| 348 | EnableCustomInput: richOptions.EnableCustomInput, |
| 349 | }) |
| 350 | if err != nil { |
| 351 | return nil, err |
| 352 | } |
| 353 | |
| 354 | // Check selected option, convert descriptions (line) to values |
| 355 | // |
| 356 | // The function must return an initialized empty array, since it is later marshaled |
| 357 | // into JSON. Otherwise, `var results []string` would be marshaled to "null". |
| 358 | // See: https://github.com/golang/go/issues/27589 |
| 359 | results := []string{} |
| 360 | for _, sel := range selected { |
| 361 | custom := true |
| 362 | for i, option := range richOptions.Options { |
| 363 | if asLine(option) == sel { |
| 364 | results = append(results, richOptions.Options[i].Value) |
| 365 | custom = false |
| 366 | break |
| 367 | } |
| 368 | } |
| 369 | |
| 370 | if custom { |