Skip to main content

Templates Inputs

O poder criar formulários avançados é entender como funciona o react-jsonschema-form. Aqui você encontrará exemplo que estão em json, mas de json para yaml é um pulo! Também podemos conferir a documentação dessa biblioteca aqui.

Template Editor

Uma funcionalidade que podemos aproveitar no Backstage para nos ajudar a criar nosso templates, principalmente em um estágio inicial.

alt text

Quando vamos alterando o código é mostrado como ficará o formulário ao lado.

alt text

Vamos utilizar esse editor para fazer testes explicando os campos.

Parameters

o campo parameters em templates representa os dados de entrada que o usuário deve fornecer ao executar ou configurar o template. Ele é uma lista de definições de parâmetros que:

  • Define quais informações o usuário precisa fornecer.
  • Especifica os tipos, validações, descrições e comportamento esperado desses inputs.
  • Serve como base para criar a interface do usuário (UI) de entrada de dados.

Um objeto da lista parameters pode conter:

  • title (obrigatório)
    • Define o título da seção/grupo de parâmetros.
    • Tipo: string.
  • description (opcional)
    • Fornece uma descrição adicional da seção para ajudar o usuário.
    • Tipo: string
  • properties (obrigatório)
    • Define os campos (parâmetros) que o usuário deve preencher. Vamos falar mais abaixo.
    • Tipo: object contendo pares chave: valor
  • required (opcional)
    • Lista os nomes dos campos obrigatórios definidos em properties.
    • Tipo: array de strings.
  • allOf, anyOf, oneOf (opcional)
    • Define condições ou validações adicionais para os campos.
    • Tipo: array de objetos com validações específicas.
    • Exemplos:
      • allOf: Todas as condições devem ser atendidas.
      • anyOf: Pelo menos uma condição deve ser atendida.
      • oneOf: Apenas uma condição deve ser atendida.
  • if, then, else (opcional)
    • Permite aplicar lógica condicional aos campos com base nos valores de outros campos.
    • Tipo: objetos que especificam:
      • if: A condição a ser verificada.
      • then: O que acontece se a condição for verdadeira.
      • else: O que acontece se a condição for falsa.
  • errorMessage (opcional)
    • Define mensagens de erro personalizadas para validações falhas.
    • Tipo: object com pares chave: mensagem, onde a chave é o campo ou validação.

Titles

Os titles dividem o preenchimento em etapas. Basicamente isso.

alt text

Poderíamos fazer tudo em uma única etapa, é mais uma questão de organização. Cada vez que criamos um title o botão de next passa para o próximo title (sessão) até chegar em review que irá aplicar os steps.

alt text

Properties (Inputs)

Documentação

Dentro de properties cada objeto será o valor do campo. Podemos dizer que seria o valor da variável e dentro de bloco temos suas definições com as seguintes chaves:

  • type (obrigatório) Especifica o tipo de dado do campo.
    • Tipos válidos: string, integer, boolean, array, object. Quando temos um tipo object declaramos outro properties dentro dele, vamos ver no último exemplo.
  • title (opcional) O título do campo, exibido na interface.
    • Tipo: string.
  • description (opcional) Fornece um texto explicativo sobre o campo.
    • Tipo: string.
  • enum (opcional) Restringe os valores possíveis do campo a uma lista fixa.
    • Tipo: array com valores.
  • default (opcional) Valor padrão para o campo.
    • Tipo: Depende do type.
  • minimum, maximum (opcional) Define valores mínimos e máximos para campos do tipo integer. Tipo: number.
  • minLength, maxLength (opcional) Define o número mínimo/máximo de caracteres para campos do tipo string.
    • Tipo: integer.
  • format (opcional) Define formatos específicos para o campo (ex.: email, uri, date-time).
  • pattern Define o regex se o tipo for uma string.
    • Tipo: string.
  • ui:* (opcional) Configurações específicas para a interface do usuário.
    • Exemplos:
      • ui:widget: Tipo de widget usado (checkbox, textarea).
      • ui:field: Campo customizado (OwnerPicker).
      • ui:options: Opções adicionais para personalização.
  • dependencies (opcional) Define campos dependentes que só aparecem se o campo principal tiver um valor específico.
    • Tipo: object.

Existem mais campos se for explicar tudo teremos que documentar a biblioteca react-jsonschema-formd aqui e o propósito não é esse.

Alguns exemplos:

parameters:
- title: Fill in some steps
properties:
name:

title: Simple text input # Se não for definido irá aparecer o nome da variável, nesse caso name.
type: string # Obrigatório. O que esperar do campo de empreenchimento.
description: Description about input # É opcional
maxLength: 8 # Tamanho máximo é opcional
pattern: '^([a-zA-Z][a-zA-Z0-9]*)(-[a-zA-Z0-9]+)*$' # Regra do tempo para entrada esperada baseada em regex, é opcional
ui:autofocus: true
ui:help: 'Hint: additional description...' # Aqui é uma segunda descrição
errorMessage: # Opcional
properties:
name: '1-8 alphanumeric tokens (first starts with letter) delimited by -' # Mensagem de erro para name

Vamos explicar o detalhes iniciais primeiro.

alt text

Gerando um erro.

O erro específico para cada um dos campos.

alt text

Podemos ter uma entrada com varias linhas caso necessário. Muitas vezes é necessário passar todo um conteúdo para criar um arquivo. Um kubeconfig seria um ótimo exemplo!

parameters:
- title: Fill in some steps
properties:
examples:
title: Place Holde Example
type: string
description: Insert your multi line string
ui:widget: textarea
ui:options:
rows: 10
ui:placeholder: |
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: backstage
spec:
type: library
owner: CNCF
lifecycle: experimental

alt text

Um exemplo de seleção entre possíveis valores.

parameters:
- title: Fill in some steps
properties:
volume_type:
title: Volume Type
type: string
description: The volume type to be used
default: gp2 # Esse será o valor padrão caso não tenha mudança
enum:
- gp2
- gp3
- io1
- io2
- sc1
- st1
- standard
enumNames:
- 'General Purpose SSD (gp2)'
- 'General Purpose SSD (gp3)'
- 'Provisioned IOPS (io1)'
- 'Provisioned IOPS (io2)'
- 'Cold HDD (sc1)'
- 'Throughput Optimized HDD (st1)'
- 'Magnetic (standard)'

alt text

As vezes é necessário escolher mais de um.

parameters:
- title: Fill in some steps
properties:
name:
title: Select environments
type: array
items:
type: string
enum:
- production
- staging
- development
uniqueItems: true
ui:widget: checkboxes # observe que aqui usamos o checkbox

alt text

As vezes é necessário misturar.

alt text

Vários exemplos usando um boleano.

alt text

o uniqueItems nesse exemplo não faz muito sentido pois cada entrada é única. Já nesse sentido abaixo já faz um pouco mais de sentido.

# Edit the template parameters below to see how they will render in the scaffolder form UI
parameters:
- title: Configure servers
properties:
serverNames:
title: Enter server names
type: array
items:
type: string
uniqueItems: true
description: "List of unique server names. Duplicate entries are not allowed."
required:
- serverNames

alt text

Alguns inputs podem ou não aparece dependendo de outra entrada.

parameters:
- title: Configure your cluster
properties:
clusterType: # Estamos dando duas opções
title: Select cluster type
type: string
enum:
- Development
- Production
nodeCount:
title: Number of nodes
type: integer
minimum: 1 # Aqui ele já inicial com 1 e não deixar de zero
enableAutoScaling:
title: Enable Auto Scaling
type: boolean
required:
- clusterType
dependencies:
# Dependendo de qual clusterType tivermos precisamos de mais entradas.
clusterType:
oneOf:
- properties:
clusterType:
const: Production
# Se production então esses dois campos irão aparecer
autoScalingMinNodes:
title: Minimum nodes for auto-scaling
type: integer
minimum: 2
autoScalingMaxNodes:
title: Maximum nodes for auto-scaling
type: integer
minimum: 3
required:
- autoScalingMinNodes
- autoScalingMaxNodes
- properties:
clusterType:
const: Development
# Se desenvolvimento esse campo irá aparecer
debugMode:
title: Enable debug mode
type: boolean

alt text

alt text

Podemos fazer campos aparecerem se uma funcionalidade esta ou não ativada (feature flags). Não é a mesma idéia proposta acima em um fluxo padrão, mas também funciona como uma condicional.

Secrets

Aqui podemos ver um exemplo escondendo o campo de password

parameters:
- title: Authenticaion
description: Provide authentication for the resource
required:
- username
- password
properties:
username:
title: username
type: string
password:
title: password
type: string
ui:field: Secret

alt text

Um outro caso é que um objeto pode conter outro, depetindo toda a cadeia de properties.

alt text


Campos Customizados

Você ainda pode criar campos customizados.

Configuramos pattern para forçar um regex em um determinado campo dizendo que só podería ser letra minuscula e traço. É perfeitamente possível rederizar um campo que isso já esteja implementado e nem precisar especificar.

Poderíamos usar isso para password criando um campo que force um tamanho mínimo e use letras maiucuslas, minusculas, caracteres especiais e números.

ui:field: MeuCampoCustomizado

Claro que irá exigir um conhecimento melhor de node, mas não é muito complicado não.

Campos Customizados BuiltIn

Nessa mesma pegada já existe alguns campos customizados que vão além do que a biblioteca oferece e foi implementado pelo próprio Backstage.

Se estamos entregando algo em um repositório já devemos mapeá-lo para ser descoberto pelo backstage. Provavelmente ele terá um catalog-info.yaml que deve ser preenchido. Com certeza será necessário buscar entidades, definir owner, etc.

Aqui temos o conjunto de ui:fiels customizados para pegar objetos dentro do backstage.

  • EntityPicker
  • MultiEntityPicker
  • OwnerPicker (Importante)
  • RepoUrlPicker (Importante)
  • RepoBranchPicker

É importante entender bem nossa opções pois a grande maioria dos templates irá utilizar em algum momento isso.

ui:field: RepoUrlPicker

Facilita a seleção de um provedor de repositório e a inserção de um projeto ou proprietário e nome do repositório.

parameters:
- title: Choose a location
required:
- repoUrl
properties:
repoUrl:
title: Repository Location
type: string
ui:field: RepoUrlPicker # Campo personlizado do Backstage
ui:options:
allowedHosts:
- github.com
- gitlab.com

alt text

A allowedHosts deve ser definida para onde você deseja habilitar este modelo para publicação. E pode ser qualquer host que esteja listado na sua integrations configuração em app-config.yaml.

Podemos restringir quem será o dono do repositorio e quais repositório são permitidos.

alt text

Também podemos existir autenticação durante o processo, mas é necessário que toda a parte de autenticação do backstage esteja configurada.

alt text

Ainda é possível selecionar uma branch específica usando o RepoBranchPicker se necessário.

ui:field: OwnerPicker

Quase sempre precisaremos definir o owner de um component e provavelmente será algum Group. Não é boa prática definir um user como owner de alguma alguma coisa pois se ele sair do sistema perderemos as relações. Para restringir o owner baseado no que temos no catalog podemos utilizar o OwnerPicker dizendo que somente queremos os groups e com o tipo especificado.

alt text

ui:field: EntityPicker e ui:field: MultiEntityPicker

Filtrar uma entidade seria o mesmo processo. Se vamos criar um component que faz parte de um system e queremos definir qual sistema, poderíamos fazer uma filtragem e somente permitir que seja escolhido alguns.

alt text