Histórico da Página
...
04. EXEMPLO DE UTILIZAÇÃO
Back-End Progress
Introdução:
Para exemplificar a técnica citada acima, criamos uma API Rest que irá retornar os dados da tabela de idiomas, chamando uma UPC que acrescenta os dados da tabela usuar.
Cadastro da UPC:
Primeiramente temos que cadastrar a API REST no cadastro de programas (MEN012AA) e também especificar a UPC a ser utilizada, conforme o exemplo abaixo:
...
Na aba Opções, teremos que especificar o Template como "API REST", conforme o exemplo abaixo:
API Rest com chamada de UPC:
Abaixo temos um exemplo de partes de uma API REST que possui 2 procedures, a procedure pGetAll para tratar as chamadas GET dos dados a serem apresentados e a procedure pGetMetaData que trata os GETs para a criação de novos campos.possuí duas procedures:
- pGetMetaData que retorna o metadados do campos em questão;
- pGetAll que retorna os valores dos campos em questão;
Como podemos essas duas procedures tem chamadas para programas de UPC:
Bloco de código | ||||
---|---|---|---|---|
| ||||
PROCEDURE pGetAll: DEFINE INPUT PARAMETER oJsonInput AS JsonObject NO-UNDO. DEFINE OUTPUT PARAMETER oJsonOutput AS JsonObject NO-UNDO. ... oIdiomas = JsonAPIUtils:convertTempTableToJsonArray(TEMP-TABLE ttIdiomas:HANDLE). oObj = new JsonObject(). oObj:add('root', oIdiomas). /* realiza a chamada da UPC Progress */ {include/i-epcrest.i &endpoint=getAll &event=getAll &jsonVar=oObj} oIdiomas = oObj:getJsonArray('root'). oResponse = NEW JsonAPIResponse(oIdiomas). oJsonOutput = oResponse:createJsonResponse(). ... END PROCEDURE. PROCEDURE pGetMetaData: DEFINE INPUT PARAMETER oJsonInput AS JsonObject NO-UNDO. DEFINE OUTPUT PARAMETER oJsonOutput AS JsonObject NO-UNDO. ... // monsta-se a lista de campos que aparecerão em tela oObj = new JsonObject(). oObj:add('root', jAList). /* realiza a chamada da UPC Progress */ {include/i-epcrest.i &endpoint=getMetaData &event=getMetaData &jsonVar=oObj} oIdiomas = oObj:getJsonArray('root'). oResponse = NEW JsonAPIResponse(oIdiomas). oJsonOutput = oResponse:createJsonResponse(). ... END PROCEDURE. |
Programa UPC:
Abaixo temos um exemplo de uma UPC criada para a API REST:
Bloco de código | ||||
---|---|---|---|---|
| ||||
/************************************************************************** ** idiomas_upc.p - Exemplo de epc para Endpoints REST ***************************************************************************/ USING PROGRESS.json.*. USING PROGRESS.json.ObjectModel.*. USING com.totvs.framework.api.*. DEFINE INPUT PARAMETER pEndPoint AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER pEvent AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER pAPI AS CHARACTER NO-UNDO. DEFINE INPUT-OUTPUT PARAMETER jsonIO AS JSONObject NO-UNDO. DEFINE VARIABLE jAList AS JsonArray NO-UNDO. DEFINE VARIABLE jObj AS JsonObject NO-UNDO. DEFINE VARIABLE hBuf AS HANDLE NO-UNDO. DEFINE VARIABLE ix AS INTEGER NO-UNDO. DEFINE VARIABLE iTot AS INTEGER NO-UNDO. DEFINE VARIABLE cType AS CHARACTER NO-UNDO. // carrega as definicoes dos campos da tabela IF pEndPoint = "getMetaData" AND pEvent = "getMetaData" THEN DO ON STOP UNDO, LEAVE: // obtem a lista de campos e valores ASSIGN jAList = jsonIO:getJsonArray('root'). // cria um buffer da tabela para obter os campos da tabela usuar_mestre CREATE BUFFER hBuf FOR TABLE 'usuar_mestre'. DO ix = 1 TO hBuf:NUM-FIELDS: // ignora os campos que nao estao nesta lista IF NOT CAN-DO("nom_usuario,cod_usuario,cod_dialet,dat_fim_valid,cod_e_mail_local", hBuf:BUFFER-FIELD(ix):NAME) THEN NEXT. // monta a formatacao do item ASSIGN jObj = NEW JsonObject(). jObj:add('property', hBuf:BUFFER-FIELD(ix):NAME). jObj:add('label', hBuf:BUFFER-FIELD(ix):Label). jObj:add('visible', TRUE). jObj:add('disabled', FALSE). // ajusta o tipo ASSIGN cType = JsonAPIUtils:convertAblTypeToHtmlType(hBuf:BUFFER-FIELD(ix):type). jObj:add('type', cType). // adiciona o objeto na lista jAList:add(jObj). END. hBuf:BUFFER-RELEASE(). DELETE OBJECT hBuf. // retorna a nova lista com os campos adicionados jsonIO:Set("root", jAList). END. // carrega os valores dos campos da tabela IF pEndPoint = "getAll" AND pEvent = "getAll" THEN DO ON STOP UNDO, LEAVE: // obtem a lista de campos e valores ASSIGN jAList = jsonIO:getJsonArray('root'). FIND FIRST usuar_mestre NO-LOCK NO-ERROR. // quardado o tamanho da lista em variavel para evitar LOOP devido a adicionar novos itens na lista ASSIGN iTot = jAList:length. DO ix = 1 TO iTot: ASSIGN jObj = jAList:GetJsonObject(ix). // alimenta os novos dados IF AVAILABLE usuar_mestre THEN DO: jObj:add('cod_usuario', usuar_mestre.cod_usuario) NO-ERROR. jObj:add('nom_usuario', usuar_mestre.nom_usuario) NO-ERROR. jObj:add('cod_dialet', usuar_mestre.cod_dialet) NO-ERROR. jObj:add('dat_fim_valid', usuar_mestre.dat_fim_valid) NO-ERROR. jObj:add('cod_e_mail_local', usuar_mestre.cod_e_mail_local) NO-ERROR. END. // adiciona o objeto na lista jAList:add(jObj). FIND NEXT usuar_mestre NO-LOCK NO-ERROR. END. // devolve para o json ROOT a lista nova com novos objetos jsonIO:Set("root", jAList). END. IF pEndPoint = "getOne" AND pEvent = "getOne" THEN DO ON STOP UNDO, LEAVE: // nao implementado END. IF pEndPoint = "create" AND pEvent = "afterCreate" THEN DO ON STOP UNDO, LEAVE: // nao implementado END. /* fim */ |
Resultado ao chamar ao API tendo uma UPC cadastrada:
Ao fazer as requisições, virão os seguintes resultados na UPC.
Bloco de código | ||
---|---|---|
| ||
Busca do METADADOS onde foram adicionados os novos campos cod_usuario e nom_usuario: GET - http://localhost:8180/dts/datasul-rest/resources/prg/trn/v1/idiomas/metadados "items": [ { "visible": true, "property": "cod_idioma", "disabled": false, "label": "Idioma", "type": "string" }, { "visible": true, "property": "des_idioma", "disabled": false, "label": "Descrição", "type": "string" }, { "visible": true, "property": "cod_idiom_padr", "disabled": false, "label": "Idioma Padrão", "type": "string" }, { "visible": true, "property": "cod_usuario", "disabled": false, "label": "Usuário", "type": "string" }, { "visible": true, "property": "nom_usuario", "disabled": false, "label": "Nome", "type": "string" } ] Busca dos dados onde foram adiconados novos valores: GET - http://localhost:8180/dts/datasul-rest/resources/prg/trn/v1/idiomas "items": [ { "codIdioma": "12345678", "desIdioma": "12345678901234567890", "cod_dialet": "Pt", "cod_usuario": "super", "nom_usuario": "Super" }, { "codIdioma": "ale", "desIdioma": "Alemão", "cod_dialet": "PT", "cod_usuario": "Manoel", "nom_usuario": "Manoel de Carvalho" }, { "codIdioma": "EN", "desIdioma": "Ingles", "cod_dialet": "PT", "cod_usuario": "Joao", "nom_usuario": "Joao da Silva" } ] |
Front-End PO-UI
Introdução:
Basicamente utilizamos o componente de Page-Dynamic-Detail para comunicar com o back-end através de duas APIS:
...
Sendo que a primeira API é utilizada para fazer a montagem da tela, e a segunda API retorna os dados.
...
HTML:
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
<div class="po-wrapper"> <po-toolbar p-title="Datasul - Dynamic - Custom"></po-toolbar> <po-menu [p-menus]="menus"></po-menu> <po-page-default p-title="Idiomas"> <p> </p> <po-dynamic-view [p-fields]="fields" [p-value]="employee"> </po-dynamic-view> <po-page-dynamic-detail p-auto-router p-title="Detail" [p-actions]="actions" [p-breadcrumb]="breadcrumb" [p-fields]="fields" [p-service-api]="serviceApi"> </po-page-dynamic-detail> </po-page-default> </div> |
...
TypeScript:
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
import { Component } from '@angular/core'; import { PoMenuItem } from '@po-ui/ng-components'; import { PoDynamicViewField } from '@po-ui/ng-components'; import { PoBreadcrumb } from '@po-ui/ng-components'; import { PoPageDynamicDetailActions, PoPageDynamicDetailField } from '@po-ui/ng-templates'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { readonly menus: Array<PoMenuItem> = [ { label: 'Home', action: this.onClick.bind(this) } ]; private onClick() { alert('Clicked in menu item') } public readonly serviceApi = 'https://po-sample-api.herokuapp.com/v1/people'; public readonly serviceMetadataApi: 'http://localhost:3000/v1/metadata'; // endpoint dos metadados //public readonly serviceLoadApi: 'http://localhost:3000/load-metadata' // endpoint de customizações dos metadados public readonly actions: PoPageDynamicDetailActions = { back: '/documentation/po-page-dynamic-table' }; public readonly breadcrumb: PoBreadcrumb = { items: [ { label: 'Home', link: '/' }, { label: 'People', link: '/documentation/po-page-dynamic-table' }, { label: 'Detail' } ] }; public readonly fields: Array<PoPageDynamicDetailField> = [ { "visible": true, "property": "cod_idioma", "label": "Idioma", "type": "string" }, { "visible": true, "property": "des_idioma", "label": "Descrição", "type": "string" }, { "visible": true, "property": "cod_idiom_padr", "label": "Idioma Padrão", "type": "string" }, { "visible": true, "property": "cod_usuario", "label": "Usuário", "type": "string" }, { "visible": true, "property": "nom_usuario", "label": "Nome", "type": "string" } ]; employee = { cod_idioma: "EN", des_idioma: "Inglês", cod_dialet: "Pt", cod_usuario: "super", nom_usuario: "Super" }; } |
...
05. Facilitadores Progress
07. Links Úteis
- Dynamic-Form (https://po-ui.io/documentation/po-dynamic-form);
- Dynamic-View (https://po-ui.io/documentation/po-dynamic-view);
Templates:
- Page-Dynamic-Detail (https://po-ui.io/documentation/po-page-dynamic-detail);
- Page-Dymic-Edit (https://po-ui.io/documentation/po-page-dynamic-edit);
- Page-Dynamic-Search (https://po-ui.io/documentation/po-page-dynamic-search);
- Page-Dynamic-Table (https://po-ui.io/documentation/po-page-dynamic-table);
HTML |
---|
<!-- esconder o menu --> <style> div.theme-default .ia-splitter #main { margin-left: 0px; } .ia-fixed-sidebar, .ia-splitter-left { display: none; } #main { padding-left: 10px; padding-right: 10px; overflow-x: hidden; } .aui-header-primary .aui-nav, .aui-page-panel { margin-left: 0px !important; } .aui-header-primary .aui-nav { margin-left: 0px !important; } </style> |
...