Template Steps Customization
The Scaffolder Wizard allows you to define a set of input fields displayed to the user, by defining them inside the template.yaml
.
To let users fill out the information required by your template, you will need to use value pickers. When you define a new field inside template.yaml
, you are also defining the value picker that will help the user to fill the field. Value pickers are then rendered to HTML input fields, using React Json Schema library to render a form from a YAML file, providing an wide set of pickers that may fit your use case. On top of React Json Schema, Witboost provides an additional set of pickers tailored to the platform, allowing to perform more complex operations and enrich your templates leveraging the potential of the platform and its catalog.
Please refer to the Picker section for more information about each Witboost picker.
Some of the pickers listed below have an additional property called ui:style
that you can use to customize the appearance of the component.
By adding some CSS rules to it, you can change the appearance of the single pickers.
Use this feature with care, since it could break the page behaviour.
Most of the pickers listed below can also be hidden by setting their property ui:widget
to hidden
.
Layout
Object Layout
To group together pickers, you can use an object that will hold all of their values together. When defining an object, you can just list all of its children as properties:
ObjectExample:
type: object
title: My Object
description: an example object
required:
- name
- dataType
properties:
name:
type: string
title: Column Name
dataType:
type: string
default: TEXT
title: Column Data Type
enum:
- TEXT
- NUMBER
- DATE
- BOOLEAN
If you need just to group elements together, without showing a title or a description, you can just set the ui:option
called displayTitle
to false:
ObjectExample:
type: object
title: My Object
description: an example object
ui:options:
displayTitle: false
required:
- name
- dataType
properties:
name:
type: string
title: Column Name
dataType:
type: string
default: TEXT
title: Column Data Type
enum:
- TEXT
- NUMBER
- DATE
- BOOLEAN
Horizontal Layout
If you want to display different pickers inside an object horizontally instead of vertically, you can simply add the field ui:ObjectFieldTemplate: HorizontalTemplate
.
In this way, all the pickers inside said object will be displayed one after the other horizontally.
You can also specify additional options using the ui:options
value:
elementsPerRow
: how many elements per row should be displayed (this is honored if the overall width is less than the screen resolution)minElementWidth
: the minimum width of every element in the layout (default200
)displayTitle
: if false, title and description are not shown even if defined (defaulttrue
)
As an example, you can display different pickers horizontally with 8 elements per row by defining:
HorizontalExample:
type: object
ui:ObjectFieldTemplate: HorizontalTemplate
ui:options:
elementsPerRow: 8
properties: ...
It could happen that fewer than 8 elements are displayed if the screen does not have 8 * minElementWidth pixels available. To fix this, you can try reducing the minimum elements width to 150:
HorizontalExample:
type: object
ui:ObjectFieldTemplate: HorizontalTemplate
ui:options:
elementsPerRow: 8
minElementWidth: 150
required:
- name
- dataType
properties: ...
You can also use the minElementWidth
the other way around: by increasing it over 200, you can make elements go to a new line if there is not enough space for them.
Table Layout
Sometimes, you would like to display pickers that collect inputs needed to fill a table-like structure (e.g. when asking the user to insert a schema for a table). In this case, you usually would like to have an array of elements, each containing multiple values, but rendering that to the user in a friendly way can be very difficult.
To improve this, you can define a layout for such arrays by leveraging two custom layouts:
ui:ArrayFieldTemplate: ArrayTableTemplate
that should be added to the array componentui:ObjectFieldTemplate: TableRowTemplate
that should be added to the items of the array
The resulting definition would be something like:
SchemaExample:
title: Schema Example
description: A Schema Example
type: array
ui:ArrayFieldTemplate: ArrayTableTemplate
ui:options:
maxDescriptionRows: 2
default: []
items:
type: object
ui:ObjectFieldTemplate: TableRowTemplate
required:
- name
- dataType
properties:
name:
type: string
title: Column Name
dataType:
type: string
default: TEXT
title: Column Data Type
enum:
- TEXT
- NUMBER
- DATE
- BOOLEAN
constraint:
type: string
title: Constraint
enum:
- PRIMARY_KEY
- NOT_NULL
- UNIQUE
- NO CONSTRAINT
dataLength:
type: integer
title: Column DataLength
precision:
type: integer
title: Column Precision
minimum: 1
scale:
type: integer
title: Column Scale
minimum: 1
When displaying items in a table, the description of the single fields are moved to the column headers.
Since column headers could be stretched in case of long descriptions, you can configure how many lines of description are displayed at maximum by leveraging the ui:option
called maxDescriptionRows
(default 3
).
Conditional Fields
If you need to display a picker only when a condition is met, you can leverage the React Json Form "if-then-else" functionality.
As an example, think about a case where you have a selector for the data type, and in case the selected value is a string, you want the user to insert also its length. You can achieve this behaviour leveraging the allOf
feature:
The allOf
property must be declared either at the root properties
field or in any defined object field where a properties
field is declared.
properties:
dataType:
type: string
title: data type
enum:
- array
- binary
- boolean
- date
- float
- int
- string
- varchar
allOf:
- if:
properties:
dataType:
anyOf:
- const: varchar
- const: string
required: [dataType]
then:
properties:
length:
title: Length
type: number
description: Maximum length of the string
You can also add multiple allOf
clauses based on the selected values:
dataType:
type: string
title: data type
enum:
- array
- binary
- boolean
- date
- float
- int
- string
- varchar
allOf:
- if:
properties:
dataType:
anyOf:
- const: varchar
- const: string
required: [dataType]
then:
properties:
length:
title: Length
type: number
description: Maximum length of the string
- if:
properties:
dataType:
const: float
required: [dataType]
then:
properties:
columnScale:
title: Scale
type: number
description: The scale of the floating point number
Validation
Since there are default validations (like checking if the ID of the DP already exists), in order to achieve the best user experience, you need to define name
, domain
, and identifier
in the same page of the template (also there needs to be a dataproduct
field if you are creating a component definition).
Target repository for the template
At one point in the creation time, you will need to define on which (remote) location the template is going to exist. Currently, you need to provide either totally empty repository (non-initialized one, this means also without the README file) or non existing one (which will be created for you).
When using GitLab and providing ExistingGroup/NonExistingGroupOne/NonExistingGroupTwo
in the User/Group
field, the NonExistingGroupOne
and NonExistingGroupTwo
will be created automatically(if the token provided has the corresponding rights).
Insert documentation in your Entities
You can document any type of entity (Templates, Systems, ...) following this procedure.
Create a mkdocs.yml file in the root of your repository with the following content:
site_name: 'example-docs'
nav:
- Home: index.md
plugins:
- techdocs-core
Update your component's entity description by adding the following lines to its catalog-info.yaml in the root of its repository:
metadata:
annotations:
backstage.io/techdocs-ref: dir:.
The backstage.io/techdocs-ref annotation is used by TechDocs to download the documentation source files for generating an entity's TechDocs site.
Create a /docs folder in the root of your repository with at least an index.md file in it. (If you add more markdown files, make sure to update the nav in the mkdocs.yml file to get proper navigation for your documentation.)
Although docs is a popular directory name for storing documentation, it can be renamed to something else and can be configured by mkdocs.yml. See https://www.mkdocs.org/user-guide/configuration/#docs_dir
The docs/index.md can for example have the following content:
# example docs
This is a basic example of documentation.