Composição

Um composite, ou uma visualização composta, é um DSV que agrega outros DSV’s. Quando usado, ele executa cada DSV agregado separadamente, mas exibe todos os resultados em uma única tela. Permite ao desenvolvedor desenvolver visualizações compostas, que agregam em si a exibição de outras visualizações como itens.

Estrutura do composite

O composite é uma espécie de objeto literal que possui as propriedades adjustItemHeaders, autoCreateFilters, items, layout, type e messageWhenEmpty.

Para que o composite funcione a propriedade type deve ser uma string no valor “composite”.

Abaixo a estrutura simplificada da composite:

{
  help: '',
  messageWhenEmpty: '',
  autoCreateFilters: true
  type: 'composite',
  title: '',
  layout: [],
  items: {}
}

Cada umas das propriedades acima é abordada neste manual.

Criando composites

O composite é criado de forma semelhante a um DSV não composto, com algumas diferenças.

Uma vez que apenas agrega outras visualizações, o composite não possui um DataSourceQuery (DSQ) associado. Dessa forma, ele não possui a propriedade dataSourceQueryKey. Além disso, é necessário definir as posições de seus itens agregados, e associar os filtros que irão para a tela aos filtros desses itens.

Posicionando os itens do composite

O layout dos itens do composite é definido através de suas propriedades layout e items.

A propriedade items é um mapa que relaciona caracteres a definições de visualizações. Como identificadores, são aceitos letras e o sinal de arroba.

As definições de visualização são objetos literais. Esses objetos contém definições de DSV’s (o código que seria normalmente escrito em um script .idsv). Por exemplo:

items: {
  x: {
    dataSourceQueryKey: -1892603430,
    help: '1) Clique em um nome de usuário.' +
      'Deve ser aberta uma nova aba com o valor -1892603527 impresso na tela', type: 'report',

    filters: [
      {name: 'begin', label: 'Data inicial', required: true},
      {name: 'end', label: 'Data final', required: true}
    ],
    columns: [
      {name: "U_iClass.NOME", label: ""},
      {name: "U_iName", label: "Nome do usuário", links: [
        {
            label: "Link com parâmetro numérico", 
            target: "",
            processKey: -1892603527, 
            newTab: true,
            params: {teste: -1892603527}
        }]
      },
      {name: 'U_iFullName', label: 'Nome completo do usuário'},
      {name: 'U_iBegin', label: 'Início'},
      {name: 'U_iEnd', label: 'Fim'}
    ]
  }
}

Caso se deseje utilizar como item scripts de DSV presentes na iVFS, podemos indicar apenas suas chaves através da propriedade key, conforme o exemplo abaixo:

items: {
  x: {key: -1892603425}, // 0003 Link com parâmetro numérico em DSV.idsv
  y: {key: -1892603531}  // 0006 Links em DSVs
}

O item possui ainda a propriedade verticalAlignment, opcional, que determina o alinhamento vertical do item na renderização. Os valores possíveis e o comportamento determinado por eles são os mesmos da propriedade CSS vertical-align. No exemplo abaixo, temos um item alinhado na borda inferior da célula na qual será renderizado, e outro alinhado de forma centralizada verticalmente:

items: {
  // 0001 Agrupamento com Pivot.idsv
  s: {key: -1892603435, verticalAlignment: 'bottom'},

  // 0002 Agrupamento com useToGroup.idsv
  c: {key: -1892603431, verticalAlignment: 'middle'},

  r: {key: -1892603425}, // 0003 Link com parâmetro numérico em DSV.idsv

  // 0005 Propriedade Help dos filtros declarados em um idsv.idsv
  u: {key: -1892603783},
  m: {key: -1892603419} // 0004 Expressão de formatação.idsv
}

A propriedade layout é um array de strings, onde cada elemento do array é uma linha, e cada caractere de cada linha ocupa uma coluna. Isso forma uma grade que o composite utiliza para posicionar os itens. Em cada célula, colocamos um caractere correspondente a uma das chaves na propriedade items, ou um ponto (.) para indicar um espaço vazio. Exemplo:

layout: [
  'abc',
  '..d',
]

Se uma letra (ou arroba) se repetir, seu DSV associado ocupará o espaço correspondente na renderização. Note que, nesses casos, o espaço ocupado pelo caractere no layout deve ser um quadrilátero. Com os mesmos itens do exemplo, podemos fazer com que o item “a” ocupe não apenas o dobro da largura, mas também o dobro da altura que os demais:

layout: [
  'aabc',
  'aa.d',
]

Note que se colocássemos o caractere ‘b’ no lugar do ponto, o item “b” teria a mesma altura que o item “a” na renderização.

Associando os filtros de tela aos filtros dos DSV’s agregados

Assim como o DSV comum indica quais filtros de seu DataSourceQuery irá utilizar, o composite indica quais filtros de seus itens agregados serão usados.

Os filtros do composite são declarados da mesma forma que os filtros de um DSV comum, mas possuem uma propriedade a mais, chamada targets. Essa propriedade é utilizada para indicar que filtros dos itens do composite receberão os valores passados para os filtros do composite.

A propriedade targets é um array de strings. Cada string é iniciada com uma letra, que deve ser uma das chaves utilizadas na propriedades itens do composite. Através dessa chave o filtro é associado aos itens da composição. Após a primeira letra, a string deve conter um ponto e o nome de um filtro. Isso associa o filtro do composite ao filtro, no item informado, que tiver o nome após o ponto.

Observação: o ponto e o nome do filtro podem ser omitidos na string, podendo ser preenchida apenas a chave do item. Nesse caso, será feita uma associação do filtro do composite com um filtro no item que possua o mesmo nome do filtro do composite.

Ainda utilizando os exemplos de layout acima, caso desejemos criar um filtro associado ao filtro “pessoas” no item “a”, ao filtro “clientes” no item “b” e ao filtro “entidades” no item “c”, fazemos da seguinte forma:

filters: [
  {
    name: 'entidades',
    label: 'Entidades',
    targets: [
      'a.pessoas',
      'b.clientes',
      'c'
    ]
  }
]

Repare que a associação com o filtro “entidades” no item “c” ocorre pelo fato de ambos os filtros (do composite e do item) possuírem o mesmo nome.

O composite possui uma propriedade chamada autoCreateFilters. Quando essa propriedade é verdadeira (seu valor padrão), o composite monta seus filtros automaticamente a partir dos itens que agrega, montando também a propriedade targets de cada filtro.

Composites como itens de composites

É possível criar composites aninhados. Um composite pode ser utilizado como item de outro composite normalmente. Tanto a criação automática de filtros quando a passagem de seus valores para os subitens é feita de forma transparente ao desenvolvedor. Os composites podem ter vários níveis de aninhamento.

Configurando cabeçalho e rodapé

Por padrão, o composite oculta o rodapé de seus itens. Os cabeçalhos dos itens de um composite exibem apenas seu texto complementar e o título do item da composição. Informações como data e hora da consulta, assim como o nome do usuário e a base de dados utilizada são omitidos dos itens por serem as mesmas informações já exibidas no cabeçalho do composite.

No entanto caso seja necessário, esse comportamento pode ser desligado. Isso fará com que cada item da composição exiba seu próprio cabeçalho e rodapé conforme sua própria configuração. Para isso, configure a propriedade adjustItemHeadersAndFooters do composite, em sua definição ou instância, para o valor falso.

Note que um item do composite pode ser outro composite. Nesse caso, o composite interno ainda controla a forma de exibição de seus itens, independente da configuração daquele que o contém. Dessa forma, pode ser necessário configurar a propriedade adjustItemHeadersAndFooters também no composite aninhado.

Observação: caso o cabeçalho de um item declare, na instância ou definição, valores explícitos para as propriedades que controlam a exibição dos itens do cabeçalho (nome de usuário, variáveis utilizadas na consulta etc.), essa configuração se sobreporá a configuração do composite. Por exemplo, se uma visualização do tipo relatório declarar que seu cabeçalho deve exibir as variáveis utilizadas na consulta, o composite poderá ocultar os demais itens de cabeçalho, mas as variáveis utilizadas para aquele item irão aparecer no cabeçalho do item.