DepartamentoHome novo arquivo

0:00 / 0:00

Tela inicial do módulo. Controla a navegação lateral (sidebar), o breadcrumb do header e o roteamento entre as entidades via parâmetro MID. É a primeira action instanciada quando o usuário abre o módulo.

CÓDIGO COMPLETO
package br.xt.app.departamento;

import br.jasap.core.Effect;
import br.jasap.effect.Response;
import br.jasap.gui.JasapPage;
import br.jasap.gui.SideMenu;
import br.jasap.gui.Table;
import br.jasap.gui.TableRow;
import br.jasap.util.Js;
import br.xt.AppsRootAction;
import br.xt.acore.view.XtPage;

public class DepartamentoHome extends AppsRootAction {

    public static final String MID = "__DEPARTAMENTO_MID";

    @Override
    public Effect execute() throws Exception {
        render();
        return new Response();
    }

    public void render() throws Exception {
        XtPage page = new XtPage(getManager());
        if (isAjaxCall()) {
            eval(Js.CLOSE_SUB_WINDOWS);
        } else {
            page.getBody().append(page.content("", "", false));
            page.setWinTitle("Departamento");
            page.getCommands().add(link(MenuItem.class).putInteger(MID, 0).ajax());
            getOutput().write(this, page);
        }
    }

    public static class Title extends DepartamentoHome {
        @Override
        public Effect execute() throws Exception {
            int mid = getInput().getInteger(MID, 0);

            Table aux = new Table(getManager());
            TableRow line = aux.row();

            line.col().setStyle("padding: 0 5 0 5;").setContent(ui().btTitleActive("DEPARTAMENTO", ""));

            update(JasapPage.DIV_HEADER_LEFT, aux);
            update(JasapPage.DIV_HEADER_CENTER, "");
            return new Response();
        }
    }

    public static class MenuItem extends DepartamentoHome {
        @Override
        public Effect execute() throws Exception {
            int mid = getInput().getInteger(MID, 0);

            if (mid > 0) {
                eval(link(Title.class).putInteger(MID, mid).ajax());
                eval(link(Title.class).putInteger(MID, mid).ajax(false));
            } else {
                eval(link(MenuInicial.class).ajax(false));
                eval(link(Title.class).putInteger(MID, mid).ajax(false));
            }

            return new Response();
        }
    }

    public static class MenuInicial extends DepartamentoHome {
        @Override
        public Effect execute() throws Exception {
            SideMenu m = new SideMenu();

            update("sidebar", m.toHtml());
            return new Response();
        }
    }

}
Conceitos Java — throws Exception, @Override e public static class

throws Exception

Aparece em quase todos os métodos deste arquivo (e de qualquer arquivo do Jasap). O Java obriga a declarar quando um método pode dar erro. Coisas que podem dar erro: acessar dados da requisição HTTP, montar componentes visuais, escrever a resposta pro browser, criar links pra actions.

Quando um método chama outro que pode dar erro, ele precisa declarar throws Exception também. É como uma corrente: se o método A chama o método B que pode falhar, o método A precisa avisar que também pode falhar.

No Jasap, quase tudo pode falhar (acesso a dados, reflexão Java, I/O de rede). Por isso quase todo método tem throws Exception. Regra simples: se o método chama qualquer coisa do Jasap (ui(), link(), getInput(), update(), eval()), precisa ter throws Exception.

Essa regra vale pra todos os arquivos daqui pra frente.

@Override

Cada subclass (Title, MenuItem, MenuInicial) tem @Override public Effect execute(). Por quê? Porque cada subclass é uma action independente — quando o Jasap recebe uma requisição para Title, ele chama o execute() dela, não o da mãe.

O @Override é uma anotação de segurança: garante que você está sobrescrevendo um método que realmente existe na classe mãe. Se errar o nome (ex: excute() em vez de execute()), o compilador avisa na hora em vez de deixar passar.

Sem sobrescrever, todas as subclasses executariam o execute() da mãe — que chama render() e montaria a página inteira de novo, em vez de fazer o trabalho específico da subclass.

public static class

As subclasses Title, MenuItem e MenuInicial são inner classes estáticas. Isso significa que elas vivem dentro do arquivo DepartamentoHome.java, mas o Jasap as trata como actions independentes — cada uma tem sua própria URL no framework e é instanciada separadamente.

O extends DepartamentoHome existe para herdar os métodos utilitários (ui(), link(), eval(), update()), as constantes (MID) e o contexto (session, manager, input/output). Sem essa herança, seriam classes soltas sem acesso a nada do Home.

É como se fossem funcionários do mesmo departamento: trabalham independentes, mas compartilham as ferramentas e o espaço do departamento.

Visão Geral — public class, MID, execute() e render()
public class DepartamentoHome extends AppsRootAction {

    public static final String MID = "__DEPARTAMENTO_MID";

}
ElementoO que significa
DepartamentoHomeNome da classe. Convenção do projeto: prefixo do módulo + Home. É a tela raiz — o ponto de entrada quando o usuário abre o módulo
extends AppsRootActionHerança — esta classe recebe todos os recursos de AppsRootAction: ui(), link(), eval(), update(), getInput(), getManager() e todos os métodos do framework ficam disponíveis automaticamente
public static final String MIDGuarda o nome da chave usada para transportar o número do item clicado no menu entre o browser e o servidor. MID=0 abre o menu inicial; MID=1,2,3… abrirá cada entidade quando forem adicionadas
@Override
public Effect execute() throws Exception {
    render();
    return new Response();
}

public void render() throws Exception {
    XtPage page = new XtPage(getManager());
    if (isAjaxCall()) {
        eval(Js.CLOSE_SUB_WINDOWS);
    } else {
        page.getBody().append(page.content("", "", false));
        page.setWinTitle("Departamento");
        page.getCommands().add(link(MenuItem.class).putInteger(MID, 0).ajax());
        getOutput().write(this, page);
    }
}

Por que execute() não faz o trabalho direto? Porque ele delega para render(). Assim, qualquer inner class (Title, MenuItem, MenuInicial) pode chamar render() para re-renderizar a home sem duplicar código — basta chamar o método herdado.

O render() lida com dois cenários distintos:

CenárioO que acontece
Primeira abertura (não é Ajax)Monta a página completa: cria a estrutura com sidebar, header e área de conteúdo (page.content), define o título da aba do browser (setWinTitle), agenda o disparo automático do MenuItem com MID=0 para preencher o sidebar assim que a página carregar, e envia tudo ao browser (getOutput().write)
Chamada Ajax (já está dentro do módulo)Só fecha todos os modais abertos (Js.CLOSE_SUB_WINDOWS) — a página já existe no browser, não precisa recriar
TrechoO que faz
isAjaxCall()Verifica se a requisição veio de Ajax (já está dentro do módulo) ou de abertura direta no browser (primeira vez)
eval(Js.CLOSE_SUB_WINDOWS)Fecha todos os modais abertos quando o usuário volta ao home via Ajax
page.content("", "", false)Cria a estrutura da página: sidebar vazio, header e área de conteúdo — preenchidos depois por Ajax
page.setWinTitle("Departamento")Define o texto da aba do navegador
page.getCommands().add(...)Dispara MenuItem com MID=0 automaticamente após a página carregar — sem isso o sidebar abriria vazio
getOutput().write(this, page)Envia a página completa ao browser. Só chamado na abertura inicial, não nas chamadas Ajax
return new Response()Avisa o Jasap que a action terminou — tudo que foi preparado com update(), eval() e getOutput().write() pode ser enviado ao browser
Title — atualiza o breadcrumb
0:00 / 0:00
public static class Title extends DepartamentoHome {
    @Override
    public Effect execute() throws Exception {
        int mid = getInput().getInteger(MID, 0);

        Table aux = new Table(getManager());
        TableRow line = aux.row();

        line.col().setStyle("padding: 0 5 0 5;").setContent(ui().btTitleActive("DEPARTAMENTO", ""));

        update(JasapPage.DIV_HEADER_LEFT, aux);
        update(JasapPage.DIV_HEADER_CENTER, "");
        return new Response();
    }
}

Responsável por atualizar o breadcrumb no topo da tela — o letreiro que mostra onde o usuário está. É uma inner class estática: o Jasap a registra e instancia como uma action independente, com sua própria URL. Quando o Jasap chama Title, executa o execute() dela — não o do DepartamentoHome. O extends DepartamentoHome existe apenas para herdar os métodos utilitários: update(), ui(), link(), getInput().

Por enquanto, sem entidades, o Title só mostra "DEPARTAMENTO" fixo. Quando a primeira entidade for criada, um switch(mid) será adicionado para variar o breadcrumb conforme a tela ativa (ex: "DEPARTAMENTO > Produtos").

TrechoO que faz
getInput().getInteger(MID, 0)Lê o MID da requisição. Padrão 0 se não vier. Está presente para quando entidades forem adicionadas e o breadcrumb precisar variar por tela
new Table(getManager()) + aux.row()O Jasap exige componentes de layout no header — não aceita HTML direto. Table e TableRow geram a estrutura esperada
setStyle("padding: 0 5 0 5;")Espaçamento interno da célula: top, right, bottom, left em pixels
ui().btTitleActive("DEPARTAMENTO", "")Botão de breadcrumb no estado ativo — texto sem link. Quando entidades forem adicionadas, "DEPARTAMENTO" virará btTitle (clicável) e o nome da entidade aparecerá ao lado
update(DIV_HEADER_LEFT, aux)Substitui o header esquerdo pelo breadcrumb montado
update(DIV_HEADER_CENTER, "")Limpa o centro do header para não sobrar conteúdo de outra tela
MenuItem — roteador central
0:00 / 0:00
public static class MenuItem extends DepartamentoHome {
    @Override
    public Effect execute() throws Exception {
        int mid = getInput().getInteger(MID, 0);

        if (mid > 0) {
            eval(link(Title.class).putInteger(MID, mid).ajax());
            eval(link(Title.class).putInteger(MID, mid).ajax(false));
        } else {
            eval(link(MenuInicial.class).ajax(false));
            eval(link(Title.class).putInteger(MID, mid).ajax(false));
        }

        return new Response();
    }
}

Roteador central do módulo. Toda navegação passa por aqui. Cada link do sidebar aponta para MenuItem com um MID diferente. O MenuItem recebe o número, decide o que fazer e dispara as actions necessárias. Nenhuma tela é aberta diretamente — tudo passa pelo MenuItem primeiro.

SituaçãoO que acontece
mid > 0Entidade solicitada. Quando entidades forem adicionadas, um switch(mid) com eval(preAjax(XxxList.class).modalMax()) será inserido aqui para abrir a tela correspondente. O Title é chamado para atualizar o breadcrumb
mid == 0Menu inicial. Reconstrói o sidebar via MenuInicial e redefine o breadcrumb via Title — é o "voltar pra recepção"
TrechoO que faz
eval(...ajax())Executa imediatamente, no mesmo ciclo da requisição
eval(...ajax(false))Enfileira para executar após o ciclo atual — garante a ordem correta quando múltiplas ações acontecem em sequência (ex: primeiro abre a tela, depois atualiza o breadcrumb)
MenuInicial — conteúdo do sidebar
0:00 / 0:00
public static class MenuInicial extends DepartamentoHome {
    @Override
    public Effect execute() throws Exception {
        SideMenu m = new SideMenu();
        update("sidebar", m.toHtml());
        return new Response();
    }
}

Renderiza o conteúdo do sidebar via Ajax, após a página já estar no browser. Quando o render() monta a página pela primeira vez, o sidebar vem vazio — é o MenuInicial que preenche ele logo em seguida, chamado automaticamente pelo page.getCommands().add(...). E quando o usuário volta ao menu inicial (clica no breadcrumb "DEPARTAMENTO"), o MenuItem com MID=0 chama o MenuInicial de novo para reconstruir o sidebar — sem recarregar a página inteira.

No estado atual o SideMenu é criado vazio porque não há entidades. Conforme forem adicionadas, cada uma ganhará um m.add(...) aqui.

TrechoO que faz
new SideMenu()Cria o componente de menu lateral do Jasap com estilos e comportamento prontos
m.add(visivel, label, link, null)Quando entidades existirem: visivel controla a exibição, label é o texto, link aponta para MenuItem com o MID da entidade
m.toHtml()Converte o SideMenu em HTML
update("sidebar", m.toHtml())Substitui o conteúdo do id="sidebar" na tela. O ID é definido pelo XtPage ao montar a estrutura da página