---
name: fluig-widgets
description: Desenvolvimento de Widgets customizadas para TOTVS Fluig (Super Widget, FTL, WCMAPI). Use quando precisar criar widgets, paginas personalizadas, componentes visuais com FLUIGC ou integrar datasets via client-side.
license: MIT
metadata:
  version: "1.0.0"
  author: Nevoa
  category: development
  platform: totvs-fluig
---

# Skill: fluig-widgets

> Desenvolvimento de Widgets customizadas para TOTVS Fluig (Super Widget, FTL, WCMAPI).

## Quando Usar

- Criar widget customizada para paginas do Fluig
- Dashboard com graficos ou listagens
- Widget que inicia processos
- Widget que consome datasets via API REST
- Carrossel de imagens, banners, cards
- Formulario externo (fora do workflow)

## Estrutura de uma Widget

```
wcm/widget/${NOME_WIDGET}/
â”œâ”€â”€ src/main/
â”‚   â”œâ”€â”€ resources/
â”‚   â”‚   â”œâ”€â”€ application.info          <- Metadados da widget
â”‚   â”‚   â”œâ”€â”€ view.ftl                  <- Template de visualizacao
â”‚   â”‚   â”œâ”€â”€ edit.ftl                  <- Template de edicao (config)
â”‚   â”‚   â””â”€â”€ ${NOME_WIDGET}.properties <- i18n (portugues)
â”‚   â””â”€â”€ webapp/resources/
â”‚       â”œâ”€â”€ js/
â”‚       â”‚   â””â”€â”€ ${NOME_WIDGET}.js     <- JavaScript (SuperWidget)
â”‚       â””â”€â”€ css/
â”‚           â””â”€â”€ ${NOME_WIDGET}.css    <- Estilos customizados
```

### Estrutura Alternativa (legada)
```
wcm/widget/${NOME_WIDGET}/
â”œâ”€â”€ WEB-INF/classes/
â”‚   â”œâ”€â”€ application.info
â”‚   â”œâ”€â”€ view.ftl
â”‚   â””â”€â”€ edit.ftl
â””â”€â”€ resources/
    â”œâ”€â”€ js/${NOME_WIDGET}.js
    â””â”€â”€ css/${NOME_WIDGET}.css
```

## application.info

```properties
application.type=widget
application.code=${NOME_WIDGET}
application.title=${TITULO_WIDGET}
application.description=${DESCRICAO_WIDGET}
application.category=${CATEGORIA}
application.renderer=freemarker
developer.code=${DEVELOPER_CODE}
developer.name=${DEVELOPER_NAME}
developer.url=http://www.fluig.com
application.uiwidget=true
application.mobileapp=false
application.version=${build.version}-${build.revision}
view.file=view.ftl
edit.file=edit.ftl
locale.file.base.name=${NOME_WIDGET}
application.resource.js.1=/resources/js/${NOME_WIDGET}.js
application.resource.css.2=/resources/css/${NOME_WIDGET}.css
```

## view.ftl (Freemarker Template)

```html
<div id="${NOME_WIDGET}_${ instanceId}" class="super-widget wcm-widget-class fluig-style-guide"
    data-params="${NOME_WIDGET}.instance({
        'param1': '${ param1!""}',
        'param2': '${ param2!""}'
    })">

    <!-- Conteudo da widget -->
    <div class="panel panel-default">
        <div class="panel-heading">
            <h4>${ i18n.getTranslation('widget.titulo')}</h4>
        </div>
        <div class="panel-body">
            <div id="conteudo_${ instanceId}"></div>
        </div>
    </div>
</div>

<!-- Template Mustache para renderizar dados -->
<script type="text/template" class="template-item">
{{#itens}}
<tr>
    <td>{{campo1}}</td>
    <td>{{campo2}}</td>
</tr>
{{/itens}}
</script>
```

**Variaveis FTL importantes:**
- `${instanceId}` - ID unico da instancia da widget na pagina
- `${i18n.getTranslation('chave')}` - Traducao do .properties
- `${param!"valorPadrao"}` - Parametro salvo com valor default
- `${isEditMode?string}` - Se esta em modo edicao

## edit.ftl (Configuracao)

```html
<div id="${NOME_WIDGET}_${ instanceId}" class="super-widget wcm-widget-class fluig-style-guide"
    data-params="${NOME_WIDGET}.instance({
        'param1': '${ param1!""}',
        'param2': '${ param2!""}'
    })">
    <div class="panel panel-primary">
        <div class="panel-heading">
            <h4>${ i18n.getTranslation('label.configuracao')}</h4>
        </div>
        <div class="panel-body">
            <div class="form-group">
                <label>${ i18n.getTranslation('label.param1')}</label>
                <input class="form-control" type="text"
                    id="param1_${ instanceId}" value="${ param1!}"/>
            </div>
            <hr/>
            <button class="btn btn-primary" data-salvar-config>
                ${ i18n.getTranslation('salvar')}
            </button>
        </div>
    </div>
</div>
```

## JavaScript (SuperWidget)

```javascript
var ${NOME_WIDGET} = SuperWidget.extend({
    // Variaveis da widget (recebidas do data-params)
    param1: null,
    param2: null,

    // Inicializacao
    init: function() {
        if (!this.isEditMode) {
            this.carregarDados();
        }
    },

    // Bindind de eventos
    bindings: {
        local: {
            'salvar-config': ['click_salvarConfig'],
            'acao-botao': ['click_executarAcao']
        }
    },

    // Salvar preferencias (modo edicao)
    salvarConfig: function(el, ev) {
        var preferences = {};
        preferences.param1 = $('#param1_' + this.instanceId).val();
        preferences.param2 = $('#param2_' + this.instanceId).val();

        WCMSpaceAPI.PageService.UPDATEPREFERENCES({
            async: true,
            success: function(data) {
                FLUIGC.toast({
                    message: data.message,
                    type: 'success'
                });
            },
            fail: function(xhr, message, errorData) {
                FLUIGC.toast({
                    message: errorData.message,
                    type: 'danger'
                });
            }
        }, this.instanceId, preferences);
    },

    // Carregar dados via API de dataset
    carregarDados: function() {
        var that = this;
        $.ajax({
            type: 'GET',
            dataType: 'json',
            url: '/api/public/ecm/dataset/search?datasetId=' + this.param1,
            contentType: 'application/json',
            success: function(data) {
                if (data && data.content.length > 0) {
                    var template = $(".template-item").html();
                    var html = Mustache.render(template, { itens: data.content });
                    $("#conteudo_" + that.instanceId).html(html);
                }
            },
            error: function(xhr, status, error) {
                FLUIGC.toast({
                    message: 'Erro ao carregar dados: ' + error,
                    type: 'danger'
                });
            }
        });
    }
});
```

## APIs Disponiveis no Client-Side

APIs principais: `WCMAPI` (usuario, tenant, CRUD), `WCMSpaceAPI` (preferencias), `FLUIGC` (toast, modal, loading, datatable), `DatasetFactory` (consulta datasets), API REST de datasets.

> Referencia completa com exemplos: [references/apis-client-side.md](./references/apis-client-side.md)

## Checklist de Producao

- [ ] application.info com todos os campos obrigatorios
- [ ] view.ftl com `super-widget wcm-widget-class fluig-style-guide`
- [ ] data-params referenciando `NomeWidget.instance({...})`
- [ ] IDs com `_${instanceId}` para evitar conflito entre instancias
- [ ] Arquivo .properties para i18n
- [ ] CSS com escopo (prefixar classes com nome da widget)
- [ ] Tratar modo edicao vs visualizacao (isEditMode)
- [ ] WCMSpaceAPI.PageService.UPDATEPREFERENCES para salvar config
- [ ] Mustache templates para renderizar listas
- [ ] try/catch em chamadas AJAX
- [ ] FLUIGC.toast para feedback visual
- [ ] FLUIGC.loading para indicar carregamento

## Prompts Estrategicos Disponiveis

- `criar-superwidget-completa-ftl-js-css.md` - Criacao de SuperWidget completa (FTL/JS/CSS/application.info).
- `diagnosticar-widget-nao-carrega-renderiza.md` - Diagnostico de inicializacao/renderizacao de widget.
- `implementar-widget-dashboard-datatable-dataset.md` - Widget de dashboard/listagem com `FLUIGC.datatable` e dataset API.
- `criar-widget-iniciar-processo-validacao-feedback.md` - Widget para iniciar processo com validacao e feedback.

Use estes prompts para cobrir scaffolding, troubleshoot e widgets de negocio com datasets/processos.
## Skills Relacionadas

- [fluig-datasets](../fluig-datasets/SKILL.md) — Datasets consumidos via API REST ou DatasetFactory
- [fluig-integracoes](../fluig-integracoes/SKILL.md) — REST/SOAP para widgets que consomem APIs externas
- [fluig-formularios](../fluig-formularios/SKILL.md) — Style Guide e componentes HTML reutilizaveis

## Templates Disponiveis

| Template | Descricao |
|---|---|
| `widget-super-base/` | Widget completa: application.info + view.ftl + edit.ftl + JS + CSS |
| `widget-startprocess.js` | JS para widget que inicia processos via WCMAPI |
| `widget-datatable.js` | JS para widget com listagem paginada (FLUIGC.datatable) |

## Recursos Adicionais

- Para templates base, consulte [templates/](./templates/)
- Para exemplos de implementacao real, consulte [examples/](./examples/)
### Exemplos recomendados
- [exemplo_01_widget_datatable_datasetfactory](./examples/exemplo_01_widget_datatable_datasetfactory/): widget de listagem com `FLUIGC.datatable` e consumo de dataset.
- [exemplo_02_widget_iniciar_processo](./examples/exemplo_02_widget_iniciar_processo/): widget de negocio para iniciar processo via `WCMAPI`/SOAP.
- Para referencia de APIs client-side (WCMAPI, FLUIGC, DatasetFactory), consulte [references/apis-client-side.md](./references/apis-client-side.md)
- Para prompts de uso, consulte [prompts/](./prompts/)

---

## Curadoria de Contexto Local

Para buscar exemplos reais no acervo local `Contexto`, consulte [references/contexto-curadoria.md](./references/contexto-curadoria.md).
Abra essa referencia quando a tarefa exigir aderencia a legado/producao ou comparacao com implementacoes existentes.
