1626 lines
59 KiB
Markdown
1626 lines
59 KiB
Markdown
---
|
||
title: WCMAPI
|
||
source: https://tdn.totvs.com/display/fluig/WCMAPI
|
||
path: \Plataforma Documentação técnica\Recurso de Páginas e Widgets (WCM)\WCMAPI.md
|
||
---
|
||
|
||
- 1 [Visão Geral](#WCMAPI-VisãoGeral)
|
||
- 1.1 [Como Começar](#WCMAPI-ComoComeçar)
|
||
- 1.2 [Contexto de Dados (Tenant e Página)](#WCMAPI-ContextodeDados(TenantePágina))
|
||
- 1.3 [Contexto da Página](#WCMAPI-ContextodaPágina)
|
||
- 1.4 [Usuário Atual](#WCMAPI-UsuárioAtual)
|
||
- 1.5 [Contexto do Usuário](#WCMAPI-ContextodoUsuário)
|
||
- 1.6 [Sessão e Autenticação](#WCMAPI-SessãoeAutenticação)
|
||
- 1.7 [Ambiente](#WCMAPI-Ambiente)
|
||
- 1.8 [Interface (UI)](#WCMAPI-Interface(UI))
|
||
- 1.9 [Carregamento de Recursos (CSS e JS)](#WCMAPI-CarregamentodeRecursos(CSSeJS))
|
||
- 1.10 [Renderização de Templates FTL](#WCMAPI-RenderizaçãodeTemplatesFTL)
|
||
- 1.11 [Ciclo de Vida de Widgets](#WCMAPI-CiclodeVidadeWidgets)
|
||
- 1.12 [Sistema de Eventos](#WCMAPI-SistemadeEventos)
|
||
- 1.13 [Requisições AJAX](#WCMAPI-RequisiçõesAJAX)
|
||
- 1.14 [OAuth](#WCMAPI-OAuth)
|
||
- 1.15 [Atributos de Sessão no Servidor](#WCMAPI-AtributosdeSessãonoServidor)
|
||
- 1.16 [Utilitários JavaScript](#WCMAPI-UtilitáriosJavaScript)
|
||
- 1.17 [Utilitários de URL](#WCMAPI-UtilitáriosdeURL)
|
||
- 1.18 [Configurações Globais jQuery](#WCMAPI-ConfiguraçõesGlobaisjQuery)
|
||
- 1.19 [Namespace WCM](#WCMAPI-NamespaceWCM)
|
||
- 1.20 [Boas Práticas](#WCMAPI-BoasPráticas)
|
||
- 1.21 [Erros Comuns](#WCMAPI-ErrosComuns)
|
||
- 1.22 [Dicas de Performance](#WCMAPI-DicasdePerformance)
|
||
|
||
# Visão Geral
|
||
|
||
---
|
||
|
||
O `WCMAPI` é a **API JavaScript central da plataforma Fluig WCM**. Ele expõe um objeto singleton global disponível em todos os widgets, temas e formulários da plataforma.
|
||
Por meio do `WCMAPI` você consegue:
|
||
|
||
- Saber quem é o usuário logado e qual é o tenant (empresa) ativo
|
||
- Ler o contexto da página atual (código, tipo, layout)
|
||
- Carregar dinamicamente arquivos CSS e JavaScript
|
||
- Renderizar templates FreeMarker (`.ftl`) de forma síncrona ou assíncrona
|
||
- Instanciar widgets via `loadWidgets()`
|
||
- Publicar e assinar eventos entre widgets (pub/sub)
|
||
- Realizar chamadas AJAX com autenticação JWT automática
|
||
- Validar tokens OAuth de integrações externas
|
||
- O objeto é acessível em **qualquer script carregado após este arquivo**:
|
||
|
||
```
|
||
// Sempre use o singleton - nunca instancie o WCMAPI diretamente
|
||
const usuarioLogado = WCMAPI.getUserLogin();
|
||
const tenant = WCMAPI.getTenantCode();
|
||
```
|
||
|
||
## Como Começar
|
||
|
||
---
|
||
|
||
O `WCMAPI` já estará disponível como variável global no momento em que seu widget ou tema for executado. **Não é necessário importar, instanciar ou configurar nada.**
|
||
|
||
### Dentro de um widget Fluig
|
||
|
||
```
|
||
// Verificar se o usuário está logado antes de fazer qualquer operação
|
||
if (WCMAPI.getUserIsLogged()) {
|
||
const login = WCMAPI.getUserLogin();
|
||
const nome = `${WCMAPI.getUserFirstName()} ${WCMAPI.getUserLastName()}`;
|
||
console.log(`Bem-vindo, ${nome}!`);
|
||
}
|
||
```
|
||
|
||
### Renderizando um template FTL no widget
|
||
|
||
```
|
||
// Renderizar o template view.ftl do app "meuWidget" e injetar no elemento #conteudo
|
||
WCMAPI.convertFtlAsync('meuWidget', 'view.ftl', { filtro: 'ativo' }, (html) => {
|
||
$('#conteudo').html(html);
|
||
WCMAPI.loadWidgets();
|
||
});
|
||
```
|
||
|
||
### Verificando feature flags
|
||
|
||
```
|
||
if (WCMAPI.isFeatureEnabled('NOVO_PAINEL')) {
|
||
carregarNovoPainel();
|
||
} else {
|
||
carregarPainelLegado();
|
||
}
|
||
```
|
||
|
||
## Contexto de Dados (Tenant e Página)
|
||
|
||
---
|
||
|
||
Estes valores são fornecidos automaticamente pela plataforma antes de qualquer widget ser inicializado.
|
||
|
||
**Regra fundamental:** nunca acesse ou modifique propriedades do `WCMAPI` diretamente (ex.: `WCMAPI.tenantCode`). Utilize **sempre** os métodos getter/setter correspondentes. O acesso direto às propriedades é considerado legado e pode ser removido em versões futuras.
|
||
|
||
### getTenantCode() / setTenantCode(value)
|
||
|
||
**Descrição:** Retorna ou define o código único que identifica o tenant (empresa) ativo. Preenchido automaticamente pela plataforma; raramente é necessário usar o setter em widgets.
|
||
**Retorno de `getTenantCode()`:** `string` — ex.: `'minhaempresa'`
|
||
**Parâmetros de `setTenantCode()`:**
|
||
|
||
- `value` (`string`): novo código do tenant
|
||
|
||
```
|
||
const tenant = WCMAPI.getTenantCode();
|
||
const url = `/api/public/2.0/${tenant}/users`;
|
||
```
|
||
|
||
### getTenantId() / getOrganizationId() / setOrganizationId(value)
|
||
|
||
**Descrição:** Retorna ou define o identificador numérico do tenant. `getTenantId()` é um alias para `getOrganizationId()`. Use `setOrganizationId()` para definir o valor — não existe `setTenantId()`.
|
||
**Retorno:** `number` — valor padrão `-1` quando não há tenant carregado.
|
||
**Parâmetros de `setOrganizationId()`:**
|
||
|
||
- `value` (`number`): identificador numérico do tenant
|
||
|
||
```
|
||
const idTenant = WCMAPI.getTenantId();
|
||
```
|
||
|
||
### getTenantURI() / setTenantURI(value)
|
||
|
||
**Descrição:** Retorna ou define o segmento de URI do tenant usado nas URLs de páginas da plataforma.
|
||
**Retorno de `getTenantURI()`:** `string` — ex.: `'/portal/p/minhaempresa'`
|
||
|
||
```
|
||
// Redirecionar para a home do tenant
|
||
window.location.href = `${WCMAPI.getTenantURI()}/home`;
|
||
```
|
||
|
||
### getTenantURL() / setTenantURL(value)
|
||
|
||
**Descrição:** Retorna ou define a URL completa do tenant (esquema + host + caminho do tenant).
|
||
**Retorno de `getTenantURL()`:** `string` — ex.: `'https://minhaempresa.fluig.com/minhaempresa'`
|
||
|
||
### getTenantPATH() / setTenantPATH(value)
|
||
|
||
**Descrição:** Retorna ou define apenas o segmento de caminho do tenant (sem esquema e host).
|
||
**Retorno de `getTenantPATH()`:** `string` — ex.: `'/minhaempresa'`
|
||
|
||
### getServerURL() / setServerURL(value)
|
||
|
||
**Descrição:** Retorna ou define a URL base do servidor (esquema + host), sem nenhum caminho adicional.
|
||
**Retorno de `getServerURL()`:** `string` — ex.: `'https://minhaempresa.fluig.com'`
|
||
|
||
### getServerContextURL() / setServerContextURL(value)
|
||
|
||
**Descrição:** Retorna ou define a URL completa do contexto do servidor (esquema + host + context path do portal).
|
||
**Retorno de `getServerContextURL()`:** `string`
|
||
|
||
### getContextPath() / setContextPath(value)
|
||
|
||
**Descrição:** Retorna ou define o context path do portal no servidor de aplicação.
|
||
**Retorno de `getContextPath()`:** `string` — ex.: `'/portal'`
|
||
|
||
### getHomePage()
|
||
|
||
**Descrição:** Monta e retorna a URL completa da página inicial do tenant.
|
||
**Retorno:** `string` — equivale a `getTenantURI() + '/' + getHomePageCode()`
|
||
|
||
```
|
||
// Redirecionar o usuário para a home
|
||
window.location.href = WCMAPI.getHomePage();
|
||
```
|
||
|
||
### getPageCode() / setPageCode(code) / getPageId() / setPageId(id) / getPageType() / setPageType(type) / getPageLayout() / setPageLayout(layoutId)
|
||
|
||
**Descrição:** Retornam ou definem informações sobre a página WCM atualmente renderizada. Os setters são utilizados internamente pela plataforma; em widgets, utilize apenas os getters.
|
||
|
||
| | | | |
|
||
| --- | --- | --- | --- |
|
||
| Getter | Setter | Retorno | Exemplo |
|
||
| `getPageCode()` | `setPageCode(code)` | `string|null` | `'home'` |
|
||
| `getPageId()` | `setPageId(id)` | `number|null` | `42` |
|
||
| `getPageType()` | `setPageType(type)` | `string|null` | `'public'` |
|
||
| `getPageLayout()` | `setPageLayout(layoutId)` | `number|null` | `3` |
|
||
| `getPageTitle()` | `setPageTitle(title)` | `string|null` | `'Início'` |
|
||
| `getParentPageCode()` | `setParentPageCode(code)` | `string|null` | `'portal'` |
|
||
| `getFriendlyURL()` | `setFriendlyURL(url)` | `string|null` | `'/inicio'` |
|
||
|
||
```
|
||
// Evitar exibir avisos na página de boas-vindas
|
||
if (WCMAPI.getPageCode() !== 'welcome') {
|
||
mostrarAvisoImportante();
|
||
}
|
||
```
|
||
|
||
### getSpaceAlias() / setSpaceAlias(value)
|
||
|
||
**Descrição:** Retorna ou define o alias (identificador curto) do espaço Fluig atual.
|
||
**Retorno de `getSpaceAlias()`:** `string` — ex.: `'default'`
|
||
|
||
```
|
||
const alias = WCMAPI.getSpaceAlias();
|
||
```
|
||
|
||
### getSpaceId() / setSpaceId(id)
|
||
|
||
**Descrição:** Retorna ou define o identificador numérico do espaço Fluig atual.
|
||
**Retorno de `getSpaceId()`:** `number|null`
|
||
|
||
```
|
||
const spaceId = WCMAPI.getSpaceId();
|
||
```
|
||
|
||
### getHomePageCode() / setHomePageCode(value)
|
||
|
||
**Descrição:** Retorna ou define o código da página configurada como home/landing page do tenant. Usado por `getHomePage()` para montar a URL completa.
|
||
**Retorno de `getHomePageCode()`:** `string` — padrão `'home'`
|
||
|
||
```
|
||
const homeCode = WCMAPI.getHomePageCode(); // 'home'
|
||
window.location.href = WCMAPI.getHomePage();
|
||
```
|
||
|
||
### getUploadURL() / setUploadURL(value)
|
||
|
||
**Descrição:** Retorna ou define a URL utilizada para operações de upload de arquivos na plataforma.
|
||
**Retorno de `getUploadURL()`:** `string`
|
||
|
||
```
|
||
const uploadEndpoint = WCMAPI.getUploadURL();
|
||
```
|
||
|
||
### getProtectedContextPath() / setProtectedContextPath(value)
|
||
|
||
**Descrição:** Retorna ou define o context path para recursos protegidos (que requerem autenticação).
|
||
**Retorno de `getProtectedContextPath()`:** `string`
|
||
|
||
```
|
||
const protectedPath = WCMAPI.getProtectedContextPath();
|
||
```
|
||
|
||
### getDomainId() / setDomainId(value) / getDomainName() / setDomainName(value)
|
||
|
||
**Descrição:** Retornam ou definem o identificador numérico e o nome legível do domínio atual, preenchidos pela plataforma no carregamento da página.
|
||
|
||
| | | |
|
||
| --- | --- | --- |
|
||
| Getter | Setter | Retorno |
|
||
| `getDomainId()` | `setDomainId(id)` | `number|null` |
|
||
| `getDomainName()` | `setDomainName(name)` | `string|null` |
|
||
|
||
```
|
||
const domainId = WCMAPI.getDomainId();
|
||
const domainName = WCMAPI.getDomainName();
|
||
```
|
||
|
||
### getDefaultDomainURL() / setDefaultDomainURL(value)
|
||
|
||
**Descrição:** Retorna ou define a URL base padrão do domínio atual.
|
||
**Retorno de `getDefaultDomainURL()`:** `string|null`
|
||
|
||
```
|
||
const domainUrl = WCMAPI.getDefaultDomainURL();
|
||
```
|
||
|
||
### getIsSAMLEnabled() / setIsSAMLEnabled(value)
|
||
|
||
**Descrição:** Indica se a autenticação SAML/SSO está habilitada para o tenant. Quando `true`, o login é delegado ao Identity Provider configurado. Use `getIsSAMLEnabled()` no lugar do acesso à propriedade `isSAMLEnabled` diretamente.
|
||
|
||
> Veja também `isIdentityEnabled()`, que é um alias para `getIsSAMLEnabled()`.
|
||
> **Retorno de `getIsSAMLEnabled()`:** `boolean`
|
||
|
||
```
|
||
if (WCMAPI.getIsSAMLEnabled()) {
|
||
// exibir botão "Entrar com SSO"
|
||
}
|
||
```
|
||
|
||
### getIdpHomePageURL() / setIdpHomePageURL(value)
|
||
|
||
**Descrição:** Retorna ou define a URL da página inicial do Identity Provider (IdP), usada nos fluxos de logout com SAML ativo.
|
||
**Retorno de `getIdpHomePageURL()`:** `string`
|
||
|
||
```
|
||
const idpUrl = WCMAPI.getIdpHomePageURL();
|
||
```
|
||
|
||
### getFluigPaas() / setFluigPaas(value)
|
||
|
||
**Descrição:** Indica se a plataforma está rodando em modo PaaS (Fluig em nuvem). Quando `true`, certos recursos e caminhos específicos de PaaS são ativados.
|
||
**Retorno de `getFluigPaas()`:** `boolean`
|
||
|
||
```
|
||
if (WCMAPI.getFluigPaas()) {
|
||
usarRecursosDePaas();
|
||
}
|
||
```
|
||
|
||
### getApplicationCode() / setApplicationCode(value)
|
||
|
||
**Descrição:** Retorna ou define o código de aplicação usado para escopo de caminhos de recursos estáticos. Padrão: `'fluig'`.
|
||
**Retorno de `getApplicationCode()`:** `string`
|
||
|
||
```
|
||
const appCode = WCMAPI.getApplicationCode(); // 'fluig'
|
||
```
|
||
|
||
### getEnvType() / setEnvType(value)
|
||
|
||
**Descrição:** Retorna ou define o identificador do ambiente de implantação, como `'production'` ou `'staging'`.
|
||
**Retorno de `getEnvType()`:** `string`
|
||
|
||
```
|
||
if (WCMAPI.getEnvType() !== 'production') {
|
||
console.log('[DEV] Modo de diagnóstico ativo');
|
||
}
|
||
```
|
||
|
||
### getTenantLocales() / setTenantLocales(value)
|
||
|
||
**Descrição:** Retorna ou define a lista de códigos de idioma disponíveis para o tenant. Útil para renderizar seletores de idioma em widgets.
|
||
**Retorno de `getTenantLocales()`:** `string[]` — ex.: `'pt_BR', 'en_US'.`
|
||
|
||
```
|
||
const locales = WCMAPI.getTenantLocales();
|
||
locales.forEach((locale) => adicionarOpcaoDeIdioma(locale));
|
||
```
|
||
|
||
### isFeatureEnabled(featureFlag)
|
||
|
||
**Parâmetros:**
|
||
|
||
- `featureFlag` (`string`): identificador da feature a verificar
|
||
|
||
**Retorno:** `boolean`
|
||
|
||
```
|
||
if (WCMAPI.isFeatureEnabled('EXPORTAR_RELATORIO_PDF')) {
|
||
$('#btn-exportar-pdf').show();
|
||
}
|
||
```
|
||
|
||
### getIsEditMode() / setIsEditMode(value)
|
||
|
||
**Descrição:** Indica se a página está atualmente em modo de edição WCM. Quando `true`, a plataforma exibe controles de edição e a engrenagem dos widgets.
|
||
|
||
**Não acesse `WCMAPI.isEditMode` diretamente.** Use `getIsEditMode()` para leitura e `setIsEditMode()` para escrita.
|
||
**Retorno de `getIsEditMode()`:** `boolean`
|
||
**Parâmetros de `setIsEditMode()`:**
|
||
|
||
- `value` (`boolean`): `true` para ativar o modo de edição
|
||
|
||
```
|
||
if (WCMAPI.getIsEditMode()) {
|
||
mostrarControlesDeEdicao();
|
||
}
|
||
// Ativar programaticamente (raramente necessário em widgets):
|
||
WCMAPI.setIsEditMode(true);
|
||
```
|
||
|
||
## Contexto da Página
|
||
|
||
---
|
||
|
||
Essas informações são fornecidas automaticamente pela plataforma no carregamento da página e devem ser tratadas como somente leitura. O uso dos setters não tem efeito no comportamento da plataforma.
|
||
|
||
### getIsPreviewMode() / setIsPreviewMode(value)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Indica se a página está sendo renderizada em modo de pré-visualização. Neste modo, as alterações ainda não foram publicadas e a URL geralmente contém o parâmetro `?preview=true`.
|
||
**Retorno de `getIsPreviewMode()`:** `string` — `'true'` ou `'false'` (chega como string do FreeMarker, não como boolean nativo).
|
||
|
||
```
|
||
if (WCMAPI.getIsPreviewMode() === 'true') {
|
||
mostrarAvisoPreVisualizacao();
|
||
}
|
||
```
|
||
|
||
### getPageAuthType() / setPageAuthType(value)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Indica o tipo de autenticação exigido para acesso à página atual.
|
||
**Retorno de `getPageAuthType()`:** `string` — ex.: `'PUBLIC'`, `'PRIVATE'`
|
||
|
||
```
|
||
if (WCMAPI.getPageAuthType() === 'PUBLIC') {
|
||
exibirConteudoPublico();
|
||
}
|
||
```
|
||
|
||
### getIsResponsiveLayout() / setIsResponsiveLayout(value)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Indica se o layout da página atual é responsivo (adapta-se a diferentes tamanhos de tela).
|
||
**Retorno de `getIsResponsiveLayout()`:** `boolean`
|
||
|
||
```
|
||
if (WCMAPI.getIsResponsiveLayout()) {
|
||
aplicarEstilosResponsivos();
|
||
}
|
||
```
|
||
|
||
### getIsNewBuilder() / setIsNewBuilder(value)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Indica se a página foi construída com o editor New Builder da plataforma Fluig. Pode ser usado para ativar funcionalidades exclusivas do New Builder.
|
||
**Retorno de `getIsNewBuilder()`:** `boolean`
|
||
|
||
```
|
||
if (WCMAPI.getIsNewBuilder()) {
|
||
habilitarRecursosNewBuilder();
|
||
}
|
||
```
|
||
|
||
### getPageIsInternal() / setPageIsInternal(value)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Indica se a página está marcada como interna, ou seja, visível apenas para usuários autenticados. Quando `true`, o acesso anônimo deve ser bloqueado. Padrão `false` quando a variável não está presente no modelo do servidor.
|
||
**Retorno de `getPageIsInternal()`:** `boolean`
|
||
|
||
```
|
||
if (WCMAPI.getPageIsInternal() && !WCMAPI.getUserIsLogged()) {
|
||
window.location.href = WCMAPI.getContextPath() + '/login';
|
||
}
|
||
```
|
||
|
||
## Usuário Atual
|
||
|
||
---
|
||
|
||
### getUserLogin() / setUserLogin(login)
|
||
|
||
**Descrição:** Retorna ou define o login (identificador único) do usuário autenticado.
|
||
**Retorno de `getUserLogin()`:** `string|null` — `null` se o usuário não estiver autenticado.
|
||
|
||
```
|
||
const login = WCMAPI.getUserLogin();
|
||
if (login) {
|
||
buscarPerfilUsuario(login);
|
||
}
|
||
```
|
||
|
||
### getUserId() / setUserId(id)
|
||
|
||
**Descrição:** Retorna ou define o identificador numérico do usuário autenticado.
|
||
**Retorno de `getUserId()`:** `number|null`
|
||
|
||
```
|
||
const idUsuario = WCMAPI.getUserId();
|
||
```
|
||
|
||
### getUserCode() / setUserCode(code)
|
||
|
||
**Descrição:** Retorna ou define o código do usuário (equivalente ao login na maioria dos casos).
|
||
**Retorno de `getUserCode()`:** `string`
|
||
|
||
### getUserFirstName() / setUserFirstName(value) / getUserLastName() / setUserLastName(value) / getUser() / setUser(value)
|
||
|
||
**Descrição:** Retornam ou definem as partes do nome do usuário autenticado.
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| Getter | Setter |
|
||
| `getUserFirstName()` | `setUserFirstName(value)` |
|
||
| `getUserLastName()` | `setUserLastName(value)` |
|
||
| `getUser()` | `setUser(value)` |
|
||
|
||
```
|
||
const nomeCompleto = `${WCMAPI.getUserFirstName()} ${WCMAPI.getUserLastName()}`;
|
||
$('#saudacao').text(`Olá, ${nomeCompleto}!`);
|
||
```
|
||
|
||
### getUserEmail() / setUserEmail(email)
|
||
|
||
**Descrição:** Retorna ou define o e-mail do usuário autenticado.
|
||
**Retorno de `getUserEmail()`:** `string`
|
||
|
||
### getUserLocationId() / setUserLocationId(id) / getUserLocationCode() / setUserLocationCode(code) / getUserLocationUrl() / setUserLocationUrl(url)
|
||
|
||
**Descrição:** Retornam ou definem informações sobre a localização (unidade/empresa) associada ao usuário.
|
||
|
||
```
|
||
const codigoFilial = WCMAPI.getUserLocationCode();
|
||
const idFilial = WCMAPI.getUserLocationId();
|
||
```
|
||
|
||
### getLocale() / setLocale(value) / getLocaleDisplayName() / setLocaleDisplayName(value)
|
||
|
||
**Descrição:** Retornam ou definem informações sobre o idioma configurado para o usuário.
|
||
|
||
| | | |
|
||
| --- | --- | --- |
|
||
| Getter | Setter | Exemplo |
|
||
| `getLocale()` | `setLocale(value)` | `'pt_BR'` |
|
||
| `getLocaleDisplayName()` | `setLocaleDisplayName(value)` | `'português (Brasil)'` |
|
||
|
||
```
|
||
const locale = WCMAPI.getLocale(); // 'pt_BR'
|
||
```
|
||
|
||
### getTimezone() / setTimezone(value)
|
||
|
||
**Descrição:** Retorna ou define o identificador de fuso horário IANA configurado para o usuário.
|
||
**Retorno de `getTimezone()`:** `string|null` — ex.: `'America/Sao_Paulo'`
|
||
|
||
```
|
||
const tz = WCMAPI.getTimezone(); // 'America/Sao_Paulo'
|
||
```
|
||
|
||
### isAdmin()
|
||
|
||
**Descrição:** Verifica se o usuário atual possui privilégios de administrador da plataforma Fluig.
|
||
**Retorno:** `boolean`
|
||
|
||
> **Atenção:** Esta operação é **síncrona** e faz uma chamada ao servidor. Evite utilizá-la em loops ou em caminhos críticos de renderização.
|
||
|
||
```
|
||
if (WCMAPI.isAdmin()) {
|
||
$('#painel-admin').show();
|
||
}
|
||
```
|
||
|
||
### isIdentityEnabled()
|
||
|
||
**Descrição:** Indica se a autenticação SAML/SSO está habilitada para o tenant.
|
||
**Retorno:** `boolean`
|
||
|
||
## Contexto do Usuário
|
||
|
||
---
|
||
|
||
Essas informações são fornecidas automaticamente pela plataforma no carregamento da página e devem ser tratadas como somente leitura.
|
||
|
||
> Disponíveis apenas quando `WCMAPI.getUserIsLogged()` retorna `true`.
|
||
> Para os métodos completos de acesso aos dados do usuário (login, email, nome etc.), consulte a seção [Usuário Atual](https://tdn.totvs.com/pages/viewpage.action?pageId=1060213081#WCMAPIAtualiza%C3%A7%C3%A3odadocumenta%C3%A7%C3%A3o-usu%C3%A1rio-atual).
|
||
|
||
### getUserType() / setUserType(value)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Retorna o tipo de conta do usuário autenticado, conforme cadastrado na plataforma.
|
||
**Retorno de `getUserType()`:** `string` — ex.: `'interno'`, `'externo'`
|
||
|
||
```
|
||
const tipo = WCMAPI.getUserType();
|
||
if (tipo === 'externo') {
|
||
ocultarMenusInternos();
|
||
}
|
||
```
|
||
|
||
### getIsMobileAppMode()
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Indica se a plataforma está sendo executada dentro de um aplicativo móvel Fluig. O valor é determinado em tempo de renderização pelo servidor e não muda após o carregamento da página.
|
||
**Retorno:** `boolean` — `true` se executando dentro do app móvel
|
||
|
||
```
|
||
if (WCMAPI.getIsMobileAppMode()) {
|
||
ocultarFuncionalidadesDesktop();
|
||
ativarInterfaceMobile();
|
||
}
|
||
```
|
||
|
||
## Sessão e Autenticação
|
||
|
||
---
|
||
|
||
### getUserIsLogged() / setUserIsLogged(value)
|
||
|
||
**Descrição:** Retorna ou define se o usuário está autenticado na sessão atual. O setter aceita `boolean` ou as strings `'true'`/`'false'` para compatibilidade com valores vindos de templates JSP/FreeMarker.
|
||
**Retorno de `getUserIsLogged()`:** `boolean`
|
||
|
||
```
|
||
if (!WCMAPI.getUserIsLogged()) {
|
||
window.location.href = `${WCMAPI.getContextPath()}/login`;
|
||
}
|
||
```
|
||
|
||
### getIsStateless() / setIsStateless(value)
|
||
|
||
**Descrição:** Indica ou define se a plataforma está operando em modo stateless (sem sessão HTTP, apenas JWT). Nesse modo, as verificações de sessão e o ping de keep-alive são desativados automaticamente.
|
||
**Retorno de `getIsStateless()`:** `boolean`
|
||
|
||
```
|
||
if (WCMAPI.getIsStateless()) {
|
||
// autenticação baseada apenas em JWT
|
||
}
|
||
```
|
||
|
||
### extendSession()
|
||
|
||
**Descrição:** Reinicia os contadores de expiração da sessão. Deve ser chamado em resposta a interações do usuário para evitar logout por inatividade.
|
||
Internamente, agenda:
|
||
|
||
- Um aviso após **28 minutos** de inatividade
|
||
- O logout forçado após **29 minutos** de inatividade
|
||
- Não tem efeito no modo stateless ou quando cookies SAML estão presentes.
|
||
|
||
```
|
||
$(document).on('mousemove keydown click', () => {
|
||
WCMAPI.extendSession();
|
||
});
|
||
```
|
||
|
||
### login(user, password)
|
||
|
||
**Descrição:** Autentica o usuário com login e senha. Em caso de sucesso, recarrega a página; em caso de falha, exibe um alerta nativo do navegador.
|
||
**Parâmetros:**
|
||
|
||
- `user` (`string`): login do usuário
|
||
- `password` (`string`): senha em texto plano
|
||
|
||
**Retorno:** `boolean|*` — `true` em caso de sucesso
|
||
|
||
> A senha é transmitida em texto plano para o `WCMSpaceAPI`. Certifique-se de usar HTTPS.
|
||
|
||
```
|
||
var ok = WCMAPI.login('admin', 'minhasenha');
|
||
```
|
||
|
||
### logoff()
|
||
|
||
**Descrição:** Encerra a sessão do usuário e redireciona para o endpoint de logout da plataforma. A operação é imediata e irrecuperável — o usuário será redirecionado para a tela de login.
|
||
|
||
```
|
||
$('#btn-sair').on('click', () => WCMAPI.logoff());
|
||
```
|
||
|
||
### hasPermissionToChangePermission(callback)
|
||
|
||
**Descrição:** Verifica de forma assíncrona se o usuário logado tem o direito de gerenciar permissões na plataforma (recurso `PermissionsAdmin` com ação `execute`).
|
||
**Parâmetros:**
|
||
|
||
- `callback` (`Function`): chamado com `(err, result)` onde `result.content` é `boolean`
|
||
|
||
**Retorno:** `jqXHR` — o objeto de deferred do jQuery
|
||
|
||
```
|
||
WCMAPI.hasPermissionToChangePermission((err, result) => {
|
||
if (result?.content) {
|
||
$('#btn-gerenciar-permissoes').show();
|
||
}
|
||
});
|
||
```
|
||
|
||
## Ambiente
|
||
|
||
---
|
||
|
||
Essas informações são fornecidas automaticamente pela plataforma no carregamento da página e devem ser tratadas como somente leitura. Elas refletem a configuração da instância no momento da renderização.
|
||
|
||
### getVersion() / setVersion(value)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Retorna a versão da plataforma Fluig. Útil para lógica condicional baseada em versão ou para exibição em painéis de diagnóstico.
|
||
**Retorno de `getVersion()`:** `string` — ex.: `'1.7.0'`
|
||
|
||
```
|
||
const versao = WCMAPI.getVersion(); // '1.7.0'
|
||
```
|
||
|
||
### getFluigVersion() / setFluigVersion(value) / getFluigInstanceVersionName() / setFluigInstanceVersionName(value) / getFluigVersionBuild() / setFluigVersionBuild(value) / getFluigVersionStatus() / setFluigVersionStatus(value) / getFluigVersionStatusInfo() / setFluigVersionStatusInfo(value)
|
||
|
||
**Somente leitura** — disponível apenas quando informações detalhadas de versão estiverem configuradas na plataforma.
|
||
**Descrição:** Informações detalhadas da versão da instância WCM, mais granulares do que `getVersion()`. Se não estiverem configuradas, os métodos retornam string vazia.
|
||
|
||
| | | |
|
||
| --- | --- | --- |
|
||
| Getter | Setter | Exemplo de retorno |
|
||
| `getFluigVersion()` | `setFluigVersion(value)` | `'2.0.0-260417'` |
|
||
| `getFluigInstanceVersionName()` | `setFluigInstanceVersionName(value)` | `'Voyager'` |
|
||
| `getFluigVersionBuild()` | `setFluigVersionBuild(value)` | `'788'` |
|
||
| `getFluigVersionStatus()` | `setFluigVersionStatus(value)` | `'0'`, `'1'` |
|
||
| `getFluigVersionStatusInfo()` | `setFluigVersionStatusInfo(value)` | texto descritivo |
|
||
|
||
```
|
||
const ver = WCMAPI.getFluigVersion(); // '2.0.0-260417'
|
||
const build = WCMAPI.getFluigVersionBuild(); // '6727'
|
||
const status = WCMAPI.getFluigVersionStatus(); // '0'
|
||
```
|
||
|
||
### getNocodeActive() / setNocodeActive(value)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Indica se o módulo No-Code está ativo para o tenant atual. Quando `true`, funcionalidades de criação de aplicações sem código estão habilitadas. Padrão `false` quando a variável não estiver presente no modelo do servidor.
|
||
**Retorno de `getNocodeActive()`:** `boolean`
|
||
|
||
```
|
||
if (WCMAPI.getNocodeActive()) {
|
||
habilitarMenuNoCode();
|
||
}
|
||
```
|
||
|
||
### getGoogleAnalyticsEnabled() / setGoogleAnalyticsEnabled(value) / getGoogleAnalyticsAccount() / setGoogleAnalyticsAccount(value)
|
||
|
||
**Somente leitura** — fornecidos automaticamente pela plataforma.
|
||
**Descrição:** Indicam se o Google Analytics está ativo e qual é o ID da conta configurada para o tenant. Use em conjunto para inicializar o rastreamento.
|
||
|
||
| | | |
|
||
| --- | --- | --- |
|
||
| Getter | Setter | Retorno |
|
||
| `getGoogleAnalyticsEnabled()` | `setGoogleAnalyticsEnabled(value)` | `boolean` |
|
||
| `getGoogleAnalyticsAccount()` | `setGoogleAnalyticsAccount(value)` | `string`, ex.: `'UA-XXXXX-Y'` |
|
||
|
||
```
|
||
if (WCMAPI.getGoogleAnalyticsEnabled()) {
|
||
inicializarGoogleAnalytics(WCMAPI.getGoogleAnalyticsAccount());
|
||
}
|
||
```
|
||
|
||
## Interface (UI)
|
||
|
||
---
|
||
|
||
Essas informações são fornecidas automaticamente pela plataforma no carregamento da página e devem ser tratadas como somente leitura. Refletem a configuração visual do tema ativo e as funcionalidades de edição de texto do tenant.
|
||
|
||
### getThemeId() / setThemeId(id)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Retorna o identificador numérico do tema aplicado à página atual. Chega como string do FreeMarker; converta com `parseInt()` se necessário.
|
||
**Retorno de `getThemeId()`:** `string` (número como string) — ex.: `'3'`
|
||
|
||
```
|
||
const themeId = parseInt(WCMAPI.getThemeId(), 10);
|
||
```
|
||
|
||
### getColorMenu() / setColorMenu(value) / getColorBackground() / setColorBackground(value)
|
||
|
||
**Somente leitura** — fornecidos automaticamente pela plataforma.
|
||
**Descrição:** Retornam as cores definidas pelo tema ativo — a cor do menu de navegação e a cor de fundo da página, respectivamente. Úteis para personalização dinâmica de componentes que precisam combinar com o tema.
|
||
|
||
| | | |
|
||
| --- | --- | --- |
|
||
| Getter | Setter | Descrição |
|
||
| `getColorMenu()` | `setColorMenu(value)` | Cor do menu de navegação, ex.: `'#003366'` |
|
||
| `getColorBackground()` | `setColorBackground(value)` | Cor de fundo da página, ex.: `'#f5f5f5'` |
|
||
|
||
```
|
||
const corMenu = WCMAPI.getColorMenu();
|
||
$('.meu-componente-header').css('background-color', corMenu);
|
||
```
|
||
|
||
### getImageBackground() / setImageBackground(value) / getImageLogo() / setImageLogo(value)
|
||
|
||
**Somente leitura** — fornecidos automaticamente pela plataforma.
|
||
**Descrição:** Retornam as URLs das imagens configuradas no tema ativo — imagem de fundo da página e logotipo exibido no cabeçalho. Vazios quando não configurados.
|
||
|
||
| | | |
|
||
| --- | --- | --- |
|
||
| Getter | Setter | Descrição |
|
||
| `getImageBackground()` | `setImageBackground(value)` | URL da imagem de fundo da página |
|
||
| `getImageLogo()` | `setImageLogo(value)` | URL do logotipo do cabeçalho |
|
||
|
||
```
|
||
const logo = WCMAPI.getImageLogo();
|
||
if (logo) {
|
||
$('#logo-customizado').attr('src', logo);
|
||
}
|
||
```
|
||
|
||
### getIsDisabledRichEditor() / setIsDisabledRichEditor(value)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Indica se o editor de texto rico (rich editor) foi substituído pelo editor simples (simple editor) para o tenant. Quando `true`, o `loadJS` troca automaticamente caminhos contendo `'richeditor'` por `'simpleeditor'`.
|
||
**Retorno de `getIsDisabledRichEditor()`:** `boolean`
|
||
|
||
```
|
||
if (WCMAPI.getIsDisabledRichEditor()) {
|
||
inicializarEditorSimples();
|
||
} else {
|
||
inicializarEditorRico();
|
||
}
|
||
```
|
||
|
||
### getEnableRichEditorSanitizer() / setEnableRichEditorSanitizer(value)
|
||
|
||
**Somente leitura** — fornecido automaticamente pela plataforma.
|
||
**Descrição:** Indica se a sanitização XSS está ativa no editor de texto rico. Quando `true`, o conteúdo gerado pelo usuário passa por sanitização antes de ser salvo, prevenindo a injeção de scripts maliciosos.
|
||
**Retorno de `getEnableRichEditorSanitizer()`:** `boolean`
|
||
|
||
```
|
||
if (WCMAPI.getEnableRichEditorSanitizer()) {
|
||
// sanitização XSS já está ativa no editor rico do tenant
|
||
console.log('XSS sanitizer habilitado');
|
||
}
|
||
```
|
||
|
||
## Carregamento de Recursos (CSS e JS)
|
||
|
||
### loadCSS(path)
|
||
|
||
**Descrição:** Injeta dinamicamente um arquivo CSS no `<head>` da página, evitando duplicatas.
|
||
**Quando usar:** sempre que um widget ou componente precisar de um arquivo CSS específico.
|
||
**Parâmetros:**
|
||
|
||
- `path` (`string`): URL ou caminho do arquivo CSS
|
||
|
||
```
|
||
WCMAPI.loadCSS('/wcm/resources/css/meu-widget.css');
|
||
```
|
||
|
||
### loadJS(path, callback)
|
||
|
||
**Descrição:** Carrega dinamicamente um arquivo JavaScript com cache habilitado, evitando carregamentos duplicados.
|
||
**Quando usar:** sempre que um widget precisar de um script externo. Prefira sempre `WCMAPI.loadJS()` em vez de `$.getScript()` dentro da plataforma — o WCMAPI garante controle de duplicatas e cache correto.
|
||
**Parâmetros:**
|
||
|
||
- `path` (`string`): URL ou caminho do arquivo JavaScript
|
||
- `callback` (`Function`, opcional): executado após o carregamento
|
||
|
||
```
|
||
WCMAPI.loadJS('/my_custom_path/resources/js/meu-script.js', () => {
|
||
// faça algo
|
||
});
|
||
```
|
||
|
||
### jsBasePath()
|
||
|
||
**Descrição:** Retorna o diretório base da última tag `<script>` adicionada à página no momento da chamada. Útil para resolver caminhos relativos dentro de scripts inline de widgets que não possuem acesso a um sistema de módulos.
|
||
**Retorno:** `string`
|
||
|
||
```
|
||
const base = WCMAPI.jsBasePath();
|
||
WCMAPI.loadJS(`${base}/helpers.js`);
|
||
```
|
||
|
||
## Renderização de Templates FTL
|
||
|
||
---
|
||
|
||
### convertFtlAsync(appCode, fileNameFtl, pars, callback, errorCallback)
|
||
|
||
**Descrição:** Renderiza um template FreeMarker (`.ftl`) de um aplicativo Fluig de forma **assíncrona** (não bloqueante) e entrega o HTML resultante por meio de um callback.
|
||
CSS e JS declarados pelo template são carregados automaticamente após a resposta.
|
||
**Parâmetros:**
|
||
|
||
- `appCode` (`string`): código do aplicativo Fluig, ex.: `'wcm_meupainel'`
|
||
- `fileNameFtl` (`string`): nome do arquivo FTL, ex.: `'view.ftl'`
|
||
- `pars` (`Object|string`): parâmetros passados ao template (serializado automaticamente se for objeto)
|
||
- `callback` (`Function`): chamado com o HTML renderizado — `callback(html)`
|
||
- `errorCallback` (`Function`, opcional): chamado em caso de erro — `errorCallback(err)`
|
||
|
||
```
|
||
WCMAPI.convertFtlAsync(
|
||
'meuApp',
|
||
'view.ftl',
|
||
{ usuarioId: WCMAPI.getUserId(), filtro: 'ativo' },
|
||
(html) => {
|
||
$('#meu-container').html(html);
|
||
WCMAPI.loadWidgets();
|
||
},
|
||
(erro) => {
|
||
console.error('Falha ao renderizar o template', erro);
|
||
}
|
||
);
|
||
```
|
||
|
||
> ✅ **Prefira este método** ao `convertFtl()` em qualquer situação onde o bloqueio da thread do navegador seja indesejável.
|
||
|
||
### convertFtl(appCode, fileNameFtl, pars, component, callback)
|
||
|
||
**Descrição:** Renderiza um template FTL de forma **síncrona** (bloqueante) e injeta o HTML resultante em um elemento da página. Também carrega os recursos CSS e JS declarados pelo template.
|
||
**Parâmetros:**
|
||
|
||
- `appCode` (`string`): código do aplicativo Fluig
|
||
- `fileNameFtl` (`string`): nome do arquivo FTL
|
||
- `pars` (`Object|string`): parâmetros para o template
|
||
- `component` (`string|jQuery`): ID do elemento ou objeto jQuery onde o HTML será injetado. Passe `undefined` para receber o HTML como string de retorno
|
||
- `callback` (`Function`, opcional): executado após todos os recursos JS serem carregados
|
||
|
||
**Retorno:** `string` — HTML renderizado quando `component` é `undefined`; caso contrário, `""`
|
||
|
||
```
|
||
WCMAPI.convertFtl('meuApp', 'edit.ftl', { id: 10 }, 'div-edicao', () => {
|
||
console.log('Widget em modo de edição pronto');
|
||
});
|
||
const html = WCMAPI.convertFtl('meuApp', 'partial.ftl', { id: 10 });
|
||
$('#lista').append(html);
|
||
```
|
||
|
||
> **Atenção:** Esta versão bloqueia o navegador durante o round-trip ao servidor. Use `convertFtlAsync()` sempre que possível.
|
||
|
||
### extractHtmlContentAndResources(html, appCode) *(interno)*
|
||
|
||
**Descrição:** Método interno utilizado por `convertFtl` e `convertFtlAsync` para separar o HTML renderizado em nós de conteúdo DOM e descritores de recursos (CSS/JS). Não deve ser chamado diretamente por widgets.
|
||
|
||
## Ciclo de Vida de Widgets
|
||
|
||
---
|
||
|
||
### loadWidgets()
|
||
|
||
**Descrição:** Inicializa os widgets presentes na página. Chamado automaticamente pela plataforma no carregamento da página e ao final de `convertFtl` / `convertFtlAsync`.
|
||
**Quando usar:** sempre que widgets forem carregados dinamicamente — por exemplo, após injetar HTML via `convertFtlAsync`, `convertFtl` ou uma requisição AJAX.
|
||
|
||
```
|
||
$.get('/minha-api/widget-html', (html) => {
|
||
$('#container').html(html);
|
||
WCMAPI.loadWidgets();
|
||
});
|
||
```
|
||
|
||
### openEditMode(instId, slot) / openViewMode(instId, slot)
|
||
|
||
**Descrição:** Re-renderizam sincronamente uma instância de widget em modo de edição ou visualização, substituindo o nó DOM atual.
|
||
**Parâmetros:**
|
||
|
||
- `instId` (`number`): ID numérico da instância do widget
|
||
- `slot` (`string`): ID do elemento slot container
|
||
|
||
```
|
||
// Abrir o widget de ID 42 em modo de edição
|
||
WCMAPI.openEditMode(42, 'slot-principal');
|
||
```
|
||
|
||
### editContent(control, instanceId)
|
||
|
||
**Descrição:** Re-renderiza um widget em modo de edição quando acionado pelo ícone de engrenagem no modo de visualização. Diferente de `openEditMode()`, este método também carrega os recursos CSS e JS declarados pelo template de edição antes de injetar o HTML.
|
||
**Parâmetros:**
|
||
|
||
- `control` (`Element|string`): elemento DOM clicado, usado para localizar o slot pai
|
||
- `instanceId` (`number`): ID numérico da instância
|
||
|
||
### updateWidgetPreferences(instanceId, prefs)
|
||
|
||
**Descrição:** Salva as preferências de um widget para **todos os usuários** e re-renderiza o widget em modo de edição imediatamente, para que o usuário veja o resultado da configuração.
|
||
**Parâmetros:**
|
||
|
||
- `instanceId` (`number`): ID numérico da instância do widget
|
||
- `prefs` (`Object`): pares chave/valor das preferências a salvar
|
||
|
||
**Retorno:** `boolean` — `true` em caso de sucesso, `false` em caso de falha
|
||
|
||
```
|
||
const salvo = WCMAPI.updateWidgetPreferences(12, {
|
||
cor: '#003366',
|
||
exibirCabecalho: true,
|
||
quantidadeItens: 5
|
||
});
|
||
if (!salvo) {
|
||
alert('Erro ao salvar as configurações. Tente novamente.');
|
||
}
|
||
```
|
||
|
||
### updateUserWidgetPreferences(instanceId, prefs)
|
||
|
||
**Descrição:** Idêntico a `updateWidgetPreferences()`, porém as preferências são salvas **apenas para o usuário logado**, permitindo personalização individual.
|
||
**Parâmetros:**
|
||
|
||
- `instanceId` (`number`): ID numérico da instância
|
||
- `prefs` (`Object`): pares chave/valor das preferências
|
||
|
||
**Retorno:** `boolean`
|
||
|
||
```
|
||
// Salvar preferência de idioma apenas para este usuário
|
||
WCMAPI.updateUserWidgetPreferences(12, { idioma: 'en_US' });
|
||
```
|
||
|
||
## Sistema de Eventos
|
||
|
||
---
|
||
|
||
O `WCMAPI` oferece um barramento de eventos pub/sub para comunicação desacoplada entre widgets e temas. Os nomes dos eventos padrão (como `WCMAPI.LISTENER_LOGIN`) são constantes injetadas pela plataforma.
|
||
|
||
### Eventos disponíveis
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| Constante | Quando dispara |
|
||
| `WCMAPI.LISTENER_LOGIN` | Quando o usuário efetua login |
|
||
| `WCMAPI.LISTENER_LOGOUT` | Quando o usuário efetua logout |
|
||
| `WCMAPI.LISTENER_EDITMODEON` | Quando o modo de edição é ativado |
|
||
| `WCMAPI.LISTENER_EDITMODEOFF` | Quando o modo de edição é desativado |
|
||
| `WCMAPI.LISTENER_SAVEWIDGETPREFS_OPEN` | Quando o painel de preferências de widget é aberto |
|
||
| `WCMAPI.LISTENER_SAVEWIDGETPREFS_CLOSE` | Quando o painel de preferências de widget é fechado |
|
||
| `WCMAPI.LISTENER_BEFORE_SAVEWIDGETPREFS` | Antes de salvar as preferências de widget |
|
||
| `WCMAPI.LISTENER_AFTER_SAVEWIDGETPREFS` | Após salvar as preferências de widget |
|
||
|
||
### addListener(oObj, eventName, callback, listenerName)
|
||
|
||
**Descrição:** Registra uma função de callback para ser chamada quando o evento indicado for disparado. Se um listener com o mesmo `listenerName` já estiver registrado para o mesmo evento, ele será atualizado em vez de duplicado.
|
||
**Parâmetros:**
|
||
|
||
- `oObj` (`Object`): contexto (`this`) para o callback
|
||
- `eventName` (`string`): nome do evento (ex.: `WCMAPI.LISTENER_LOGIN`)
|
||
- `callback` (`Function`): função chamada com `(eventName, data)`
|
||
- `listenerName` (`string`, opcional): nome único do listener, padrão `'DEFAULT'`
|
||
|
||
**Retorno:** `boolean` — sempre `true`
|
||
|
||
```
|
||
WCMAPI.addListener(
|
||
this,
|
||
WCMAPI.LISTENER_EDITMODEON,
|
||
(eventName, data) => meuWidget.mostrarControlesDeEdicao(),
|
||
'meuWidget-editmode'
|
||
);
|
||
```
|
||
|
||
### removeListener(eventName, listenerName)
|
||
|
||
**Descrição:** Remove um listener registrado pelo nome.
|
||
**Parâmetros:**
|
||
|
||
- `eventName` (`string`): nome do evento
|
||
- `listenerName` (`string`, opcional): nome do listener a remover, padrão `'DEFAULT'`
|
||
|
||
```
|
||
// Remover o listener ao destruir o widget
|
||
WCMAPI.removeListener(WCMAPI.LISTENER_EDITMODEON, 'meuWidget-editmode');
|
||
```
|
||
|
||
### fireEvent(eventName, data)
|
||
|
||
**Descrição:** Dispara todos os listeners registrados para o evento informado. Erros dentro de callbacks individuais são silenciados para não impedir a notificação dos demais listeners.
|
||
**Parâmetros:**
|
||
|
||
- `eventName` (`string`): nome do evento a disparar
|
||
- `data` (`*`, opcional): payload enviado para todos os listeners
|
||
|
||
```
|
||
WCMAPI.fireEvent('DOCUMENTO_SELECIONADO', { id: 99, titulo: 'Contrato 2024' });
|
||
WCMAPI.addListener(this, 'DOCUMENTO_SELECIONADO', (evt, data) => {
|
||
console.log('Documento selecionado:', data.titulo);
|
||
}, 'visualizador-docs');
|
||
```
|
||
|
||
### containsListener(eventName, listener, varIdx)
|
||
|
||
**Descrição:** Verifica se um listener com o nome informado já está registrado para um evento. Método interno, raramente necessário em widgets.
|
||
**Retorno:** `boolean`
|
||
|
||
## Requisições AJAX
|
||
|
||
---
|
||
|
||
O `WCMAPI` oferece métodos CRUD padronizados que já aplicam as configurações padrão da plataforma (JSON content-type, tratamento de erros, serialização automática).
|
||
|
||
> **JWT Automático:** Todas as requisições jQuery feitas na plataforma recebem automaticamente o header `Authorization: Bearer <token>` via `$.ajaxSetup()`, desde que o cookie `jwt.token` esteja presente.
|
||
|
||
### Create(options) / Read(options) / Update(options) / Delete(options)
|
||
|
||
**Importante:** Os métodos WCMAPI.Create(), WCMAPI.Read(), WCMAPI.Update() e Delete(options) estão depreciados. Use FLUIGC.ajax() ou $.ajax() que fornece uma API mais robusta e moderna.
|
||
|
||
**Descrição:** Wrappers padronizados para chamadas AJAX com os verbos HTTP correspondentes (`POST`, `GET`, `PUT`, `DELETE`). Qualquer `options.data` que seja objeto ou array é automaticamente serializado para JSON antes do envio.
|
||
**Parâmetros:**
|
||
|
||
- `options` (`Object`): configuração jQuery.ajax. `url` é obrigatório.
|
||
- `options.data`: payload da requisição (auto-serializado se for objeto)
|
||
- `options.success`: callback de sucesso com a resposta parseada
|
||
|
||
```
|
||
WCMAPI.Create({
|
||
url: '/api/public/2.0/posts',
|
||
data: { titulo: 'Meu Post', conteudo: 'Texto aqui' },
|
||
success: (resposta) => {
|
||
console.log('Post criado com ID:', resposta.content.id);
|
||
}
|
||
});
|
||
WCMAPI.Read({
|
||
url: `/api/public/2.0/documents/${documentoId}`,
|
||
success: (resposta) => {
|
||
exibirDocumento(resposta.content);
|
||
}
|
||
});
|
||
WCMAPI.Update({
|
||
url: `/api/public/2.0/documents/${documentoId}`,
|
||
data: { titulo: 'Título Atualizado' },
|
||
success: () => mostrarMensagemSucesso()
|
||
});
|
||
WCMAPI.Delete({
|
||
url: `/api/public/2.0/documents/${documentoId}`,
|
||
success: () => removerDaLista(documentoId)
|
||
});
|
||
```
|
||
|
||
### callCommand(command, data, oObj, callback, errorCallback, dataType)
|
||
|
||
**Descrição:** Realiza uma requisição GET simples, prefixando o `command` com o valor retornado por `WCMAPI.getServerURL()`. O errorCallback é opcional; se omitido, erros são ignorados silenciosamente.
|
||
**Parâmetros:**
|
||
|
||
- `command` (`string`): caminho da URL (anexado ao valor de `getServerURL()`)
|
||
- `data` (`*`): dado repassado ao callback de sucesso e erro
|
||
- `oObj` (`Object`): contexto (`this`) para os callbacks
|
||
- `callback` (`Function`): `callback(response, data)`
|
||
- `errorCallback` (`Function`, opcional): `errorCallback(xhr, textStatus, errorThrown, data)`
|
||
- `dataType` (`string`, opcional): tipo de dado esperado, padrão `'json'`
|
||
|
||
```
|
||
WCMAPI.callCommand(
|
||
'/wcm/api/rest/wcm/usuario/atual',
|
||
null,
|
||
this,
|
||
(response) => console.log('Usuário:', response)
|
||
);
|
||
```
|
||
|
||
### readHtml(options)
|
||
|
||
**Descrição:** Atalho para fazer uma requisição AJAX com as configurações padrão da plataforma, mescladas com as opções fornecidas.
|
||
|
||
```
|
||
WCMAPI.readHtml({
|
||
url: '/wcm/api/rest/wcm/minha-rota',
|
||
dataType: 'html',
|
||
success: (html) => $('#container').html(html)
|
||
});
|
||
```
|
||
|
||
### syncAjax(url)
|
||
|
||
**Descrição:** Realiza uma requisição GET síncrona (bloqueante) e retorna o texto da resposta.
|
||
**Parâmetros:**
|
||
|
||
- `url` (`string`): URL da requisição
|
||
|
||
**Retorno:** `string|false` — texto da resposta, ou `false` se o objeto XHR não puder ser criado
|
||
|
||
> Use com extrema moderação
|
||
>
|
||
> Requisições síncronas bloqueiam completamente a thread do navegador e estão obsoletas nos padrões modernos. Este método é usado internamente apenas nos pings de keep-alive de sessão.
|
||
|
||
### failHandler(args, styleGuide) *(usado internamente)*
|
||
|
||
**Descrição:** Tratador centralizado de erros AJAX, chamado automaticamente pelo objeto padrão retornado por `ajaxRequestDefault()`. Inspeciona o Content-Type e o status HTTP da resposta para exibir a mensagem de erro correta.
|
||
|
||
- Quando `styleGuide = true`: usa componentes FLUIGC (modais e mensagens)
|
||
- Quando `styleGuide = false`: usa os componentes legados WCMC
|
||
- Raramente você precisará chamar este método diretamente.
|
||
|
||
```
|
||
$.ajax({
|
||
url: '/minha-api',
|
||
error: (xhr) => WCMAPI.failHandler(xhr, true)
|
||
});
|
||
```
|
||
|
||
## OAuth
|
||
|
||
---
|
||
|
||
### validateAndAuthenticateOAuth(consumerKey)
|
||
|
||
**Descrição:** Valida o token OAuth para uma chave de consumer e, caso o token esteja ausente ou inválido, inicia o fluxo de autorização abrindo a URL do provedor em uma nova aba.
|
||
Use este método antes de fazer chamadas a APIs de terceiros integradas via OAuth (ex: Google Drive, Dropbox).
|
||
**Parâmetros:**
|
||
|
||
- `consumerKey` (`string`): chave do consumer OAuth da integração
|
||
|
||
**Retorno:** `boolean` — `true` se o token é válido; `false` se o fluxo de autorização foi iniciado
|
||
|
||
```
|
||
// Verificar e autenticar antes de usar o Google Drive
|
||
if (WCMAPI.validateAndAuthenticateOAuth('google-drive')) {
|
||
carregarArquivosGoogleDrive();
|
||
} else {
|
||
// O usuário será redirecionado para autorizar o acesso
|
||
mostrarMensagem('Autorizando acesso ao Google Drive...');
|
||
}
|
||
```
|
||
|
||
### validateOAuth(consumerKey)
|
||
|
||
**Descrição:** Verifica a validade do token OAuth **sem iniciar o fluxo de autorização**. Use quando você precisa apenas verificar o status para, por exemplo, exibir um botão "Conectar".
|
||
**Parâmetros:**
|
||
|
||
- `consumerKey` (`string`): chave do consumer OAuth
|
||
|
||
**Retorno:** `boolean` — `true` se o token é válido
|
||
|
||
```
|
||
if (!WCMAPI.validateOAuth('minha-integracao')) {
|
||
$('#btn-conectar').show();
|
||
} else {
|
||
$('#btn-conectar').hide();
|
||
carregarDadosDaIntegracao();
|
||
}
|
||
```
|
||
|
||
## Atributos de Sessão no Servidor
|
||
|
||
---
|
||
|
||
### setSessionAttribute(name, value) / getSessionAttribute(name)
|
||
|
||
**Descrição:** Armazena e recupera atributos na sessão HTTP do servidor via chamadas síncronas ao `WCMSpaceAPI.SessionService`.
|
||
**Parâmetros:**
|
||
|
||
- `name` (`string`): chave do atributo de sessão
|
||
- `value` (`*`): valor a armazenar (somente para `setSessionAttribute`)
|
||
|
||
```
|
||
// Salvar o ID do último documento visualizado
|
||
WCMAPI.setSessionAttribute('ultimo-documento', 42);
|
||
// Recuperar o valor posteriormente (em outra página/widget)
|
||
var ultimoDoc = WCMAPI.getSessionAttribute('ultimo-documento');
|
||
if (ultimoDoc) {
|
||
reabrirDocumento(ultimoDoc);
|
||
}
|
||
```
|
||
|
||
> **Atenção:** Não funciona em modo stateless (`WCMAPI.getIsStateless() === true`).
|
||
|
||
## Utilitários JavaScript
|
||
|
||
---
|
||
|
||
### Verificação de tipos
|
||
|
||
**Legado.** Prefira os recursos nativos do JavaScript moderno: `typeof`, `Array.isArray()`, `=== null`, `=== undefined`, etc. Evite utilizar estes métodos em novos desenvolvimentos.
|
||
|
||
| | | |
|
||
| --- | --- | --- |
|
||
| Método | Equivalente nativo | Retorno |
|
||
| `isUndefined(o)` | `o === undefined` | `boolean` |
|
||
| `isNull(o)` | `o === null` | `boolean` |
|
||
| `isString(o)` | `typeof o === 'string'` | `boolean` |
|
||
| `isNumber(o)` | `typeof o === 'number'` | `boolean` |
|
||
| `isArray(obj)` | `Array.isArray(obj)` | `boolean` |
|
||
| `isObject(o)` | — | `boolean` |
|
||
| `isJSON(o)` | — | `boolean` |
|
||
| `isEmpty(o)` | — | `boolean` |
|
||
|
||
```
|
||
// Antes de serializar dados para envio ao servidor:
|
||
const payload = obterDados();
|
||
if (WCMAPI.isObject(payload)) {
|
||
WCMAPI.Create({ url: '/api/salvar', data: payload, success: cb });
|
||
} else {
|
||
console.error('Dados inválidos:', payload);
|
||
}
|
||
```
|
||
|
||
### cloneObject(source)
|
||
|
||
**Descrição:** Cria uma cópia profunda (deep clone) de um objeto ou array simples. Não copia propriedades chamadas `'clone'` para evitar referências circulares.
|
||
**Limitação:** Não clona corretamente `Date`, `RegExp`, `Map`, `Set` ou outras classes built-in complexas — esses são copiados por referência.
|
||
**Parâmetros:**
|
||
|
||
- `source` (`Object|Array`): objeto ou array a clonar
|
||
|
||
**Retorno:** `Object|Array`
|
||
|
||
```
|
||
const configuracaoOriginal = { cor: 'azul', icone: { nome: 'star', tamanho: 16 } };
|
||
const copia = WCMAPI.cloneObject(configuracaoOriginal);
|
||
copia.icone.tamanho = 32;
|
||
console.log(configuracaoOriginal.icone.tamanho); // 16 — intocado
|
||
```
|
||
|
||
### replaceAll(str, de, para)
|
||
|
||
**Descrição:** Substitui todas as ocorrências de uma substring por outra. Alternativa a `String.prototype.replaceAll()` para compatibilidade com ambientes legados. Usa abordagem iterativa em vez de regex global, evitando problemas com caracteres especiais.
|
||
|
||
```
|
||
var resultado = WCMAPI.replaceAll('a.b.c.d', '.', '/');
|
||
// 'a/b/c/d'
|
||
```
|
||
|
||
### stringify(o)
|
||
|
||
**Descrição:** Serializa para JSON e então aplica `encodeURI()`. Útil para passar objetos complexos como parâmetros de URL.
|
||
|
||
```
|
||
const dados = { filtro: 'ativo', pagina: 1 };
|
||
const url = `/minha-api?params=${WCMAPI.stringify(dados)}`;
|
||
```
|
||
|
||
### validateXSS(data, replace)
|
||
|
||
**Descrição:** Sanitiza um valor de string ou campo de formulário contra ataques XSS usando o utilitário `FLUIGC.utilities.preventXSS`.
|
||
Suporta dois modos:
|
||
|
||
- **String:** recebe e retorna uma string sanitizada
|
||
- **Elemento de formulário:** recebe um elemento DOM ou jQuery com `.value`, atualiza o valor no lugar e retorna o objeto jQuery
|
||
- O parâmetro `replace` quando `true` também remove as entidades `>` e `<` do resultado sanitizado.
|
||
|
||
```
|
||
// Modo string — sanitizar dados antes de exibir
|
||
var textoSeguro = WCMAPI.validateXSS(comentarioDoUsuario, false);
|
||
$('#area-comentario').text(textoSeguro);
|
||
// Modo input — sanitizar o campo diretamente ao perder o foco
|
||
$('#campo-titulo').on('blur', function() {
|
||
WCMAPI.validateXSS(this, false);
|
||
});
|
||
```
|
||
|
||
### emailIsValid(email)
|
||
|
||
**Descrição:** Valida se uma string é um endereço de e-mail sintaticamente válido. Não verifica a existência do domínio.
|
||
**Retorno:** `boolean`
|
||
|
||
```
|
||
const email = $('#campo-email').val();
|
||
if (!WCMAPI.emailIsValid(email)) {
|
||
mostrarErro('Informe um e-mail válido.');
|
||
return;
|
||
}
|
||
```
|
||
|
||
### formatDateUtc(date)
|
||
|
||
**Descrição:** Formata uma data como string localizada usando a meia-noite UTC para evitar que o deslocamento de fuso horário do cliente altere o dia exibido.
|
||
**Parâmetros:**
|
||
|
||
- `date` (`string|number|Date`): valor de data aceito por `new Date()`
|
||
|
||
**Retorno:** `string` — data formatada conforme o locale do navegador
|
||
|
||
```
|
||
// Em pt-BR: '15/06/2024'
|
||
var dataFormatada = WCMAPI.formatDateUtc('2024-06-15T00:00:00Z');
|
||
$('#data-publicacao').text(dataFormatada);
|
||
```
|
||
|
||
### generateId()
|
||
|
||
**Descrição:** Gera uma string de identificador DOM único e incremental no formato `'wcmid<n>'`. Útil ao criar elementos dinamicamente que precisam de um atributo `id` garantidamente único na página.
|
||
**Retorno:** `string` — ex.: `'wcmid2'`, `'wcmid3'`, ...
|
||
|
||
```
|
||
const id = WCMAPI.generateId();
|
||
const $div = $('<div>').attr('id', id).addClass('meu-componente');
|
||
$('body').append($div);
|
||
WCMAPI.loadJS('/meuapp/componente.js', () => {
|
||
new MeuComponente({ target: `#${id}` });
|
||
});
|
||
```
|
||
|
||
### getZIndex()
|
||
|
||
**Descrição:** Retorna o maior valor de `z-index` em uso por elementos absolutamente ou fixamente posicionados na página. Útil ao criar modais ou overlays que precisam aparecer acima de todo o conteúdo existente.
|
||
**Retorno:** `number` — mínimo `1`
|
||
|
||
```
|
||
const $meuModal = $('#meu-modal');
|
||
$meuModal.css('z-index', WCMAPI.getZIndex() + 10);
|
||
$meuModal.show();
|
||
```
|
||
|
||
### getSourceImage(imageSource, options, callback)
|
||
|
||
**Descrição:** Carrega uma imagem e corrige sua orientação com base nos metadados EXIF, entregando uma URL de dados (Base64) ao callback quando necessário. Se a imagem não tiver dados EXIF de orientação, a URL original é retornada sem processamento.
|
||
Requer a biblioteca `blueimp-load-image` carregada na página.
|
||
**Parâmetros:**
|
||
|
||
- `imageSource` (`string`): URL ou data URL da imagem
|
||
- `options` (`Object`): opções para `loadImage()`, ex.: {{
|
||
Unknown macro: { maxWidth}}}
|
||
- `callback` (`Function`): `callback(src)` onde `src` é a URL original ou o Base64 corrigido
|
||
|
||
```
|
||
WCMAPI.getSourceImage('/uploads/foto.jpg', { maxWidth: 400 }, function(src) {
|
||
$('img.foto-perfil').attr('src', src);
|
||
});
|
||
```
|
||
|
||
## Utilitários de URL
|
||
|
||
---
|
||
|
||
### \_get(name)
|
||
|
||
**Descrição:** Extrai o valor de um parâmetro de query string da URL da página atual. Retorna `null` quando o parâmetro não está presente.
|
||
|
||
```
|
||
// URL: https://exemplo.com/pagina?filtro=ativo&pagina=2
|
||
var filtro = WCMAPI._get('filtro'); // 'ativo'
|
||
var pagina = WCMAPI._get('pagina'); // '2'
|
||
var outro = WCMAPI._get('outro'); // null
|
||
```
|
||
|
||
### \_getParam(url, name)
|
||
|
||
**Descrição:** Extrai o valor de um parâmetro de query string de uma URL específica (não da URL atual). Usado internamente para verificar parâmetros de versão antes de adicioná-los.
|
||
|
||
```
|
||
var versao = WCMAPI._getParam('/recursos/script.js?v=1.7.1', 'v');
|
||
// '1.7.1'
|
||
```
|
||
|
||
### \_getAllParams(url)
|
||
|
||
**Descrição:** Extrai todos os parâmetros de uma URL e os retorna como objeto.
|
||
**Retorno:** `Object.<string, string>`
|
||
|
||
```
|
||
var params = WCMAPI._getAllParams('https://exemplo.com/p?a=1&b=hello');
|
||
// { a: '1', b: 'hello' }
|
||
```
|
||
|
||
### getURLParameter(name) *(função global)*
|
||
|
||
**Descrição:** Extrai o valor de um parâmetro da URL atual. Diferente de `WCMAPI._get()`, esta é uma **função global** (não método do WCMAPI).
|
||
|
||
> **Atenção:** Quando o parâmetro não existe, esta função retorna a **string** `'null'` (e não `null`). Prefira `WCMAPI._get()` em novo código para evitar comparações indevidas.
|
||
|
||
```
|
||
var modoEdicao = getURLParameter('edit');
|
||
// Se o parâmetro não existir: modoEdicao === 'null' (string!)
|
||
// Forma segura com WCMAPI._get():
|
||
var modoEdicao = WCMAPI._get('edit'); // null (tipo correto)
|
||
```
|
||
|
||
## Configurações Globais jQuery
|
||
|
||
---
|
||
|
||
### $.cachedScript(url, options)
|
||
|
||
**Descrição:** Extensão do jQuery que carrega um script com cache habilitado no navegador. Diferente do `$.getScript()` padrão (que desabilita o cache), este helper é essencial para performance em uma plataforma onde os mesmos scripts de widget podem ser solicitados em cada carregamento de página.
|
||
|
||
```
|
||
$.cachedScript('/wcm/recursos/js/minha-lib.js').done(function() {
|
||
// biblioteca disponível — instanciar componente
|
||
new MinhaLib({ target: '#app' });
|
||
});
|
||
```
|
||
|
||
## Namespace WCM
|
||
|
||
---
|
||
|
||
O objeto global `WCM` é um namespace legado mantido por compatibilidade retroativa. Ele expõe URLs de conveniência derivadas do contexto atual do `WCMAPI`.
|
||
|
||
```
|
||
// WCM.contextUrl — ex.: '/portal/wcm'
|
||
// WCM.restUrl — ex.: '/wcm/api/rest/wcm/'
|
||
$.get(WCM.restUrl + 'meu-endpoint', function(data) {
|
||
// ...
|
||
});
|
||
```
|
||
|
||
## Boas Práticas
|
||
|
||
---
|
||
|
||
### Use sempre getters e setters — nunca acesse propriedades diretamente
|
||
|
||
Todas as propriedades do `WCMAPI` devem ser acessadas e modificadas exclusivamente pelos métodos `get...()` e `set...()` correspondentes. O acesso direto às propriedades (ex.: `WCMAPI.userId`) é considerado **legado**, não está documentado como API pública e pode ser removido em versões futuras.
|
||
|
||
```
|
||
// ❌ Incorreto — acesso direto à propriedade (legado)
|
||
var id = WCMAPI.userId;
|
||
var login = WCMAPI.userLogin;
|
||
var tenant = WCMAPI.tenantCode;
|
||
// ✅ Correto — use sempre os métodos getter
|
||
var id = WCMAPI.getUserId();
|
||
var login = WCMAPI.getUserLogin();
|
||
var tenant = WCMAPI.getTenantCode();
|
||
// ✅ Correto — para modificar, use o setter
|
||
WCMAPI.setPageTitle('Minha Página Customizada');
|
||
```
|
||
|
||
### Use sempre o singleton `WCMAPI`
|
||
|
||
Nunca instancie `TLib` diretamente. O objeto `WCMAPI` é criado pela plataforma com uma guarda contra instanciação dupla.
|
||
|
||
```
|
||
// ✅ Correto
|
||
var login = WCMAPI.getUserLogin();
|
||
// ❌ Incorreto
|
||
var api = new TLib();
|
||
```
|
||
|
||
### Prefira `convertFtlAsync` ao `convertFtl`
|
||
|
||
A versão assíncrona não bloqueia a interface enquanto aguarda a resposta do servidor.
|
||
|
||
```
|
||
// ✅ Correto — não bloqueia o navegador
|
||
WCMAPI.convertFtlAsync('meuApp', 'view.ftl', params, function(html) {
|
||
$('#container').html(html);
|
||
WCMAPI.loadWidgets();
|
||
});
|
||
// Usar com cautela — bloqueia o navegador
|
||
var html = WCMAPI.convertFtl('meuApp', 'view.ftl', params);
|
||
```
|
||
|
||
### Sempre chame `loadWidgets()` após injetar HTML
|
||
|
||
Qualquer HTML que contenha elementos com a classe `wcm-widget-class` precisa que `loadWidgets()` seja chamado após a injeção para que os widgets sejam inicializados.
|
||
|
||
```
|
||
$('#container').html(htmlRenderizado);
|
||
WCMAPI.loadWidgets(); // não esqueça!
|
||
```
|
||
|
||
### Use nomes únicos para seus listeners de eventos
|
||
|
||
O sistema de eventos atualiza um listener existente quando o nome já está registrado. Nomes descritivos e únicos por widget evitam conflitos silenciosos.
|
||
|
||
```
|
||
// ✅ Nome específico para este widget
|
||
WCMAPI.addListener(this, WCMAPI.LISTENER_EDITMODEON, handler, 'widgetCalendario-editmode');
|
||
// ❌ Nome genérico pode conflitar com outros widgets
|
||
WCMAPI.addListener(this, WCMAPI.LISTENER_EDITMODEON, handler, 'meu-listener');
|
||
```
|
||
|
||
### Remova listeners ao destruir widgets
|
||
|
||
Para evitar memory leaks e comportamentos indesejados, remova os listeners ao destruir ou esconder um widget.
|
||
|
||
```
|
||
destroyWidget() {
|
||
WCMAPI.removeListener(WCMAPI.LISTENER_EDITMODEON, 'widgetCalendario-editmode');
|
||
WCMAPI.removeListener(WCMAPI.LISTENER_LOGOUT, 'widgetCalendario-logout');
|
||
// limpeza do DOM...
|
||
};
|
||
```
|
||
|
||
### Verifique o login antes de operações sensíveis
|
||
|
||
```
|
||
if (!WCMAPI.getUserIsLogged()) {
|
||
return;
|
||
}
|
||
const login = WCMAPI.getUserLogin();
|
||
```
|
||
|
||
### Sanitize inputs do usuário com `validateXSS`
|
||
|
||
Antes de inserir qualquer conteúdo gerado pelo usuário no DOM, sanitize-o:
|
||
|
||
```
|
||
var conteudo = WCMAPI.validateXSS($('#campo-descricao').val(), false);
|
||
$('#area-preview').html(conteudo);
|
||
```
|
||
|
||
## Erros Comuns
|
||
|
||
---
|
||
|
||
### "WCMAPI is not defined"
|
||
|
||
**Causa:** O script do widget está sendo executado antes do `wcmapi.js` ser carregado.
|
||
**Solução:** Verifique a ordem de carregamento dos recursos no template do widget ou tema. O `wcmapi.js` deve aparecer antes dos scripts dos widgets.
|
||
|
||
### Listener disparando múltiplas vezes
|
||
|
||
**Causa:** `addListener` está sendo chamado mais de uma vez com o nome `'DEFAULT'` (padrão quando `listenerName` não é informado), e cada chamada atualiza o listener existente — mas se diferentes widgets usam o mesmo nome, os callbacks podem se acumular.
|
||
**Solução:** Sempre informe um `listenerName` único e específico para seu widget.
|
||
|
||
### `getURLParameter` retornando `'null'` em vez de `null`
|
||
|
||
**Causa:** Esta função global retorna a string `'null'` quando o parâmetro não existe.
|
||
**Solução:** Use `WCMAPI._get()` que retorna o tipo nulo correto.
|
||
|
||
```
|
||
// ❌ Armadilha
|
||
if (getURLParameter('modo') == null) { /* nunca entra aqui */ }
|
||
// ✅ Correto
|
||
if (WCMAPI._get('modo') === null) { /* funciona */ }
|
||
```
|
||
|
||
### Widget não inicializa após injeção de HTML
|
||
|
||
**Causa:** `loadWidgets()` não foi chamado após a injeção do HTML.
|
||
**Solução:**
|
||
|
||
```
|
||
$('#container').html(htmlRenderizado);
|
||
WCMAPI.loadWidgets(); // essencial
|
||
```
|
||
|
||
### Sessão expirando mesmo com o usuário ativo
|
||
|
||
**Causa:** `extendSession()` não está sendo chamado em resposta às interações do usuário, ou o interceptor foi removido.
|
||
**Solução:** Vincule `extendSession()` aos eventos de interação de forma global no tema:
|
||
|
||
```
|
||
let timerSessao;
|
||
$(document).on('mousemove keydown click', () => {
|
||
clearTimeout(timerSessao);
|
||
timerSessao = setTimeout(() => WCMAPI.extendSession(), 500);
|
||
});
|
||
```
|
||
|
||
### Requisições AJAX falhando com 401 em modo stateless
|
||
|
||
**Causa:** O cookie `jwt.token` não está presente ou está expirado. O `$.ajaxSetup` global injeta o token automaticamente, mas ele precisa existir.
|
||
**Solução:** Verifique se o fluxo de autenticação está renovando o JWT corretamente. Em modo stateless (`WCMAPI.getIsStateless() === true`), toda autenticação depende do token JWT.
|
||
|
||
## Dicas de Performance
|
||
|
||
---
|
||
|
||
### Evite `isAdmin()` em loops ou na inicialização
|
||
|
||
`isAdmin()` faz uma chamada síncrona ao servidor. Guarde o resultado em cache:
|
||
|
||
```
|
||
const userAdmin = WCMAPI.isAdmin();
|
||
minhaLista.forEach((item) => {
|
||
if (ehAdmin) {
|
||
exibirBotaoExcluir(item);
|
||
}
|
||
});
|
||
```
|
||
|
||
### Prefira `convertFtlAsync` para templates pesados
|
||
|
||
Templates que carregam muitos dados ou recursos devem usar a versão assíncrona para não travar a interface enquanto o servidor processa.
|
||
|
||
### Use `WCMAPI.loadJS` para scripts de widgets, nunca `$.getScript`
|
||
|
||
`$.getScript` desabilita o cache do navegador. `WCMAPI.loadJS` usa `$.cachedScript` internamente, permitindo que o navegador faça cache dos scripts entre carregamentos de página.
|
||
|
||
### Use `WCMAPI._getParam` para verificar parâmetros de versão em URLs
|
||
|
||
Ao montar URLs para recursos externos, verifique se já existe um parâmetro `v` antes de adicionar:
|
||
|
||
```
|
||
const urlRecurso = '/meu-recurso/arquivo.js';
|
||
if (!WCMAPI._getParam(urlRecurso, 'v')) {
|
||
urlRecurso += `?v=${WCMAPI.getVersion()}`;
|
||
}
|
||
```
|
||
|
||
### Nomeie e remova listeners para evitar memory leaks
|
||
|
||
Em widgets com ciclo de vida bem definido (criação e destruição), sempre remova os listeners ao destruir o widget para liberar memória.
|
||
|
||
### Integração com outras APIs do Fluig
|
||
|
||
O `WCMAPI` é a **porta de entrada** — use-o para obter o contexto e, a partir dele, construa chamadas para:
|
||
|
||
- **REST API pública:** `/api/public/2.0/...` — use `WCMAPI.Read()` / `WCMAPI.Create()` etc.
|
||
- **WCMSpaceAPI:** API síncrona de baixo nível (use com cautela)
|
||
- **FLUIGC:** componentes visuais do guia de estilo Fluig
|
||
- **WCMSpaceAPI.OAuthService:** para integrações OAuth, utilize os helpers `validateOAuth` e `validateAndAuthenticateOAuth` do próprio `WCMAPI` |