Skip to main content

Descriptor Picker

Overview

The descriptor picker allows the platform team to use a descriptor as a source of options for a field.

Configuration

As an example, consider the following descriptor:

# your component/system/ontology/whatever descriptor
spec:
# other irrelevant properties
mesh:
specific:
profiles:
- name: Premium
description: A premium profile
- name: Lite
description: A lite profile

Leveraging the Descriptor Picker, you can present to users a dropdown field with the options that are present under any descriptor's field, in our case the chosen field is spec.mesh.specific.profiles, that is a list of items:

descriptorpicker_easy

tip

As you noticed, under spec.mesh.specific.profiles we found a list of values, but you would obtain the same result even if there was a dictionary. Example:

# your component/system/ontology/whatever descriptor
spec:
# other irrelevant properties
mesh:
specific:
profiles:
premium:
name: Premium
description: A premium profile
lite:
name: Lite
description: A lite profile

Manipulating the DescriptorPicker output using Nunjucks

When the user selects any of the options presented through a DescriptorPicker, it is implicitly extracting the portion of the descriptor under the path that corresponds to the selected option in the descriptor. For instance, in the example above, the value of the profile field in the form context will be a whole new descriptor with this shape:

name: Premium
description: A premium profile

If you have another DescriptorPicker that is reading up the value from the profile field, you should take into account the transformations happening behind the scenes.

However, when you want to use the value of any of the DescriptorPicker fields, in the steps section of a template, keep in mind that the field value has the following structure:

type Option = {
/**
* The display name of the option
* if `optionDisplayNameAt` property is not used in the configuration for the DescriptorPicker:
* - if the options are parsed from an array of items, the default display name is the item index in the array
* - if the options are parsed from a dictionary of items, the default display name is the key of the item in the dictionary
*/
label: string;
/**
* Unique identifier of the option among the list of options
* for options coming from an array, this is the index
* for options coming from a dictionary, this is its key
*/
key: string;

/**
* The portion of the descriptor at the same level of the selected option
*/
value: Descriptor;
};

And here is an example AccessControlRequestTemplate where we want to prepare the data coming from the example above with profile, membershipTypes and regions for an access request, before sending it to the Access Request Action:

# template.yaml
# other irrelevant properties
spec:
steps:
- id: access-request
name: Send Access Request
action: access-request:send
input:
fields:
profile: '${{ parameters.profile.value.name }}' # Premium
membershipType: '${{ parameters.membershipType.key }}' # shortTerm
region: '${{ parameters.region.value.name }}' # EU
selectedGroup: '${{ parameters.region.value.group }}' # group:premium_short_eu

The configuration for the DescriptorPicker to reproduce the example above is the following:

parameters:
- title: Access Request
properties:
profile:
type: object # don't change it
ui:field: DescriptorPicker
title: Profile
description: Select the profile associated to your user account
sourceType: descriptor
source: .
optionsAt: spec.mesh.specific.profiles
optionsDisplayNameAt: name

Apart from type, ui:field that are to be left as shown above and title and description that are self-explanatory, let's dive into the options for the descriptor picker:

propertydescriptionpossible values
sourceTypeThe type of the source that this picker consumes.descriptor, field
sourceThe location of the descriptor, if sourceType is descriptor then the only allowed value will be ., meaning that witboost will place a descriptor that is contextually meaningful to the template where this picker is being used. E.g. for the Access Control Request Template, the available descriptor in the context will be the resource's descriptor that is being requested.. if sourceType is descriptor otherwise if sourceType is field then any field present under parameters.properties in the template fits here
optionsAtThe path in the descriptor where a list, or dictionary, of options is available<string>
optionsDisplayNameAt(optional) The item's field that can be used as a display name. e.g. if all items in the list have a name field, it can be used as a display name<string>

DescriptorPicker for complex structures

The DescriptorPicker also supports complex structures of nested options, either they are dictionaries, lists or a combination of them. Let's take a more complex descriptor as a reference:

spec:
mesh:
specific:
profiles:
- name: Premium
membershipTypes:
longTerm:
name: Long Term
regions:
- name: EU
group: group:premium_long_eu
- name: US
group: group:premium_long_us
shortTerm:
name: Short Term
regions:
- name: EU
group: group:premium_short_eu
- name: US
group: group:premium_short_us
- name: Lite
membershipTypes:
longTerm:
name: Long Term
regions:
- name: EU
group: group:lite_long_eu
- name: US
group: group:premium_long_us
shortTerm:
name: Short Term
regions:
- name: EU
group: group:lite_short_eu
- name: US
group: group:lite_short_us

In this example, the options are nested, meaning that choosing one of the profiles influences the list of options for the membershipTypes and as a consequence also for regions. Notice also that profiles is a list of items, membershipTypes is a dictionary and regions is a list of items.

The result of leveraging the DescriptorPicker is shown below:

complex

Given by this configuration:

parameters:
- title: Access Request
properties:
profile:
type: object
ui:field: DescriptorPicker
title: Profile
sourceType: descriptor
source: .
optionsAt: spec.mesh.specific.profiles
optionsDisplayNameAt: name

membershipType:
type: object
ui:field: DescriptorPicker
title: Membership Type
sourceType: field
source: profile
optionsAt: membershipTypes
optionsDisplayNameAt: name

region:
type: object
ui:field: DescriptorPicker
title: Region
sourceType: field
source: membershipType
optionsAt: regions
optionsDisplayNameAt: name

As you can notice, region uses the output coming from membershipType, which in turn uses the output coming from profile.