Criar UI para exibir um registro

Objetivos de aprendizagem

Após concluir esta unidade, você estará apto a:
  • Fazer uma solicitação para que a API de interface de usuário obtenha os dados e metadados do registro.
  • Compreender por que e como solicitar fatores de forma, tipos de layout e modos de acesso.
  • Compreender por que e como solicitar registros filho.

Buscar um registro

Outro poder da API de interface de usuário é reunir tudo o que é necessário para gerar a UI. Você sabe quantas solicitações de HTTP ela precisa fazer para obter os metadados de objeto, os metadados de layout e os dados de campo necessários para exibir o registro Contêineres universais? Um.

/ui-api/record-ui/{recordIds}

Vejamos como essa solicitação fica no código do Visualizador de registros. Navegue até o arquivo /client-src/sagas/recordFetcher.js. Você pode vê-lo no GitHub ou em seu equipamento local.

Essa linha constrói a URL de destino da API de UI.
let recordViewUrl = action.creds.instanceUrl + '/services/data/v48.0/ui-api/record-ui/' 
  + action.recordId + '?formFactor=' + action.context.formFactor + '&layoutTypes=Full&modes=View,Edit';

A solicitação envia uma ID de registro, action.recordId, que é o registro selecionado pelo usuário na lista Itens recentes. (O ponto de extremidade é compatível com várias IDs de registro, mas o aplicativo Visualizador de registros solicita apenas uma.)

A resposta inclui as informações do layout, que dizem onde cada campo fica e em quais seções da UI eles funcionam. Também informam quais seções estão recolhidas, o que chamamos de estado do usuário do layout.

Para especificar o que será incluído nas informações do layout, a solicitação usa estes parâmetros: formFactor, layoutTypes e modes.

O fator de forma altera o layout dos campos. Escolha um fator de forma que corresponda ao tipo de hardware que executará o aplicativo. Large é o layout para clientes de área de trabalho. Medium é o layout para tablets e Small para celulares. Nos fatores de forma grande e médio, o layout das seções tem duas colunas. No fator de forma pequeno, o layout das seções tem uma coluna.

O tipo de layout determina quantos campos são retornados. Os tipos de layout possíveis são Full e Compact. O layout completo (“Full”) padrão inclui todos os campos do layout de página que foram atribuídos ao usuário atual. O layout compacto (“Compact”) inclui todos os campos do layout compacto que foram atribuídos ao usuário atual. É possível editar ambos os tipos de layout em Configuração. A despeito do tipo de layout, a resposta inclui apenas os campos aos quais o usuário tem acesso.

O modo corresponde à tarefa que o usuário está fazendo: Create, View ou Edit. As informações do layout mudam conforme o modo. Por exemplo, no modo de criação, o layout não contém a seção Informações do sistema, que tem campos como Criado por e Última modificação feita por.

O aplicativo Visualizador de registros solicita os modos de exibição e edição; assim, se o usuário clica em Editar, o aplicativo já tem as informações necessárias para renderizar a UI.

Dica

Dica

Para retornar registros filho sem precisar criar consultas que associem dois registros, use o parâmetro childRelationships. A resposta é paginada e inclui um nível de relacionamentos do tipo filho. Por exemplo, esta solicitação retorna um registro Conta e os respectivos registros filho Oportunidade.

/ui-api/record-ui/001R0000003IG0vIAG?childRelationships=Account.Opportunities

Enviar solicitações e atualizar estado global

O aplicativo Visualizador de registros envia solicitações REST aos pontos de extremidade da API de UI e atualiza de modo assíncrono o próprio estado Redux com essas informações. Aí, a árvore do componente React… Hm, o que será que ela faz?… Ela reage à alteração de estado e atualiza a UI.

As sagas Redux gerenciam as solicitações REST do aplicativo. A solicitação /ui-api/record-ui/{recordIds} é realizada usando a saga recordFetcher.js. Esse código constrói a URL de REST e emite a solicitação usando a chave de acesso de Oauth como Bearer. Também define o cabeçalho X-Chatter-Entity-Encoding como false para garantir que os caracteres especiais no JSON não sejam retornados como HTML escapado.

Quando a resposta retorna e o JSON é devidamente analisado, a saga conclui enviando uma ação RECEIVE_RECORD que inclui a resposta de JSON. No modelo Redux, as ações são emitidas para expressar uma intenção de alterar o estado global. Ao separar as operações para fazer a solicitação externa, modificar o estado e atualizar o componente, mantemos uma associação flexível entre esses itens.

No Redux, os redutores interceptam as ações e as usam para transformar aspectos do estado global. Nesse caso, para atualizar a parte “record” do estado global, o redutor record.js intercepta a ação RECEIVE_RECORD e processa seu JSON.
/* /reducers/record.js */
case 'RECEIVE_RECORD':
      return {
        record: recordLayout.getLayoutModel(action.recordId, action.record),
        mode: 'View'
      }

A carga de JSON é mantida em action.record. O novo estado resultante fica disponível para os componentes por meio de state.record. Essa parte do estado do redutor record.js é acoplada ao estado global em reducers/index.js.

Analisar a resposta JSON e exibir o registro

Agora, vamos dar uma olhada mais aprofundada no auxiliar recordLayout.getLayoutModel() que é usado no redutor de estado record.js. Ele manipula as informações de dados do registro, layouts e objetos do JSON /ui-api/record-ui/{recordIds} para criar uma estrutura de dados. Essa estrutura de dados é o estado que alimenta os componentes React do aplicativo.

No fundo do arquivo /client-src/helpers/recordLayout.js, getLayoutModel() monta um objeto que contém:
  • as informações do layout
  • um mapa dos editValues usados para rastrear as alterações feitas nos valores de campo na UI
  • a objectInfo isolada que corresponde ao registro em questão
  • a ID do registro

A função recordLayout.getLayoutModel() processa as informações de layout conforme passa repetidamente pelos layouts. Para cada seção de cada layout na resposta, realizamos a chamada de getLayoutSectionModel(). Esse método recupera as informações de cabeçalho da seção do JSON de seção. Depois, ele passa repetidamente por cada linha da seção e, dentro de cada linha, por cada item do layout.

Para cada item do layout, getLayoutItemModel() monta um objeto que contém:
  • uma lista aninhada de valores (podem ser vários valores em um item no caso de dados como endereços)
  • informações de link (links para outros registros)
  • informações de link personalizadas (links para URLs externas)

Cada valor contém informações sobre o que será exibido como texto, o rótulo, os metadados do campo, a capacidade de edição e a URL de lista de opções da API de UI correspondente, quando for o caso.

Esse método conta com alguns casos especiais porque precisamos seguir procedimentos diferentes para valores da lista de opções, referências, datas e itens sem campo. Nos casos comuns, para cada item de layout respaldado por um campo sem data, extraímos as propriedades displayValue e value da entrada correspondente no JSON de dados do registro.
} else if (record.fields[compValue]) {
        var displayValue = record.fields[compValue].displayValue;
        let rawValue = record.fields[compValue].value;
        if (displayValue == null && rawValue != null) {
          displayValue = rawValue.toString();
        }
        values.push(
          {displayValue: displayValue,
           value: rawValue,
           label:component.label,
           field:compValue,
           fieldInfo,
           picklistUrl,
           editableForNew:item.editableForNew,
           editableForUpdate:item.editableForUpdate,
           isNull:displayValue == null})

Renderizar componentes do layout

Como já vimos, o objeto retornado de recordLayout.getLayoutModel() é salvo no estado global como state.record.record. Este estado é usado para renderizar os componentes correspondentes na UI. O contêiner de nível superior RecordViewerWrapper.js confere se state.record.record está disponível e o transfere para um componente RecordViewer.js aninhado na propriedade record. Aninhados dentro do componente RecordViewer.js, RecordSection.js e RecordRow.js renderizam as respectivas seções e linhas.

Observe RecordRow.js, especialmente getViewItemCells(). Quando renderizamos cada célula na linha, o caminho da felicidade cria uma <div> para cada componente no item. Damos uma chave a <div> porque o React exige uma. Usamos displayValue para renderizar o texto que você vê na tela.
{ item.values.map((component, i) => {
             if (component.displayValue && component.displayValue.length > 0) {
               if (component.fieldInfo.htmlFormatted) {
                 return (
                   <div key={'component' + itemLabel + ',' + i} dangerouslySetInnerHTML={{__html: component.displayValue}}></div>
                 )
               } else {
                 return (
                   <div key={'component' + itemLabel + ',' + i}>{component.displayValue}</div>
                 )
               }
             } else {
               return null
             }
           }
          )}

Como resultado, nosso aplicativo é ativado dinamicamente pelas informações de layout e objeto retornadas pela API de UI. Use a API de UI para criar uma UI que consiga se reorganizar conforme o administrador atualiza os layouts e os objetos no Salesforce, em vez de ter de codificar os campos e suas posições no layout.

Recursos

Continue a aprender de graça!
Inscreva-se em uma conta para continuar.
O que você ganha com isso?
  • Receba recomendações personalizadas para suas metas de carreira
  • Pratique suas habilidades com desafios práticos e testes
  • Monitore e compartilhe seu progresso com os empregadores
  • Conecte-se a orientação e oportunidades de carreira