Após um tempinho no ar da versão de montagem de menus em formato de árvore, chegaram muitos pedidos para agregar uma condição de segurança, isso de forma a filtrar somente os itens possíveis de serem abertos a um determinado grupo de usuários.
Então, para não ficar chato e repetitivo, vamos aplicar o mesmo conceito dos menus recursivos, mas desta vez gerando uma TreeView, que também opera do mesmo modo do JsCookMenu.
ara entender o funcionamento de menus do tipo recursivo, recomendo uma leitura do post anterior (http://profdouglasoliveira.blogspot.com/2010/10/criando-um-menu-recursivo.html) que trata mais profundamente da questão comportamental de menus hierárquicos, os nós, e outros elementos, nesse post estaremos apenas discutindo o TreeView e o parâmetro de segurança.
Tree View
Na versão X o Genexus inovou com a possibilidade de agregar User Controls para aprimorar os resultados da interface web. Tree View é um dos mais interessantes, e tem por objetivo listar opções de seleção em um formato tipicamente de árvore. Nosso objetivo é produzir um menu que seja filtrado nas operações possíveis de serem realizadas conforme o grupo de usuários.
Um WebPanel pode ser programado com os seguintes eventos, sendo que o &PerfilId consiste em um Dynamic Combo Box que permite selecionar o perfil do usuário, e ao ser clicado, se chama a carga do menu.
Event Start
&selectedTreeNode.Expanded = 1
EndEvent
Event &PerfilId.Click
&treeNodeCollectionData = MenuTreeDP(2, &PerfilId)
EndEvent
O Web Panel, é construído de forma simples, com o Dynamic Combo e o Tree View logo abaixo.
Transações
Nesse exemplo são necessárias duas transações, uma para conter os dados do menu e outra para conter os dados do perfil, conforme apresentamos no diagrama de tabelas abaixo. MenuTitulo e MenuLink são do tipo Char.
O elemento PaiMenuId é definido como um subtipo de MenuId, ou seja, torna a tabela Menu recursiva. PaiMenuId deve possuir o Nullable=true na definição desta estrutura.
Para realizar a carga nas tabelas teríamos que definir a de Perfil, com seus diversos grupos de usuários.
E a tabela de Menu com os itens em cada um dos grupos. Essa tabela poderia inclusive ser melhorada para um modelo 1-N, para evitar a repetição dos itens, mas deixemos esse assunto pra lá, a idéia aqui é didática e não otimização.
Data Provider (DP)
Finalmente, para carregar os dados da tabela e apresentar no Tree View necessitamos de um objeto Data Provider. E o mecanismo também é simples, obedecendo a estrutura do TreeNodeCollection SDT, carregando os valores de Id, Name, Link e Target, conforme os valores armazenados na tabela Menu.
TreeNodeCollection
where PaiMenuId = &PaiMenuId
where PerfilId = &PerfilId when &PerfilId<>0
{
TreeNode
{
Id = MenuId.ToString()
Name = MenuTitulo
Link = MenuLink
LinkTarget = '_self'
Nodes = MenuTreeDP(MenuId, &PerfilId)
}
}
A linha a seguir, gera a chamada recursiva, ao próprio DP, que no nosso caso se chama MenuTreeDP.
Nodes = MenuTreeDP(MenuId, &PerfilId)
Diferente da primeira versão, nessa será necessário fornecer ao DP duas informações, a raiz (&PaiMenuId) e o perfil (&PerfilId) a ser filtrado os itens do respectivo usuário. Portanto, não se esqueça da regra Parm nesse DP.
parm(
&PaiMenuId,
&PerfilId
);
Conclusão
Esse exemplo é basicamente um complemento do primeiro post, e com poucos ajustes, permite controlar um pouco melhor o menu.
Não se esqueça que o usuário poderá chamar no endereço do Browser os itens que não aparecem no menu, portanto, algo a mais deve ser incorporado nos objetos chamados para evitar acessos indevidos.
E também se faz necessário um pouquinho de WebSession ou Cookie, para gravar o perfil de acesso do usuário, provavelmente definido no login.
Boa programação...