saçvar painel selecionado

This commit is contained in:
Luiz Silva 2026-01-03 15:43:28 -03:00
parent a0dd05b518
commit 65118f2838
4 changed files with 170 additions and 0 deletions

View file

@ -3,6 +3,7 @@
package main
import (
"net/url"
"regexp"
"strings"
"syscall/js"
@ -23,12 +24,128 @@ func main() {
js.Global().Set("__eli_nps_wasm_decidir", js.FuncOf(decidir))
js.Global().Set("__eli_nps_wasm_cooldown_ativo", js.FuncOf(cooldownAtivo))
js.Global().Set("__eli_nps_wasm_set_cooldown", js.FuncOf(setCooldown))
js.Global().Set("__eli_nps_wasm_painel_init", js.FuncOf(painelInit))
js.Global().Set("__eli_nps_wasm_ready", true)
// Mantém o módulo vivo.
select {}
}
func painelInit(this js.Value, args []js.Value) any {
// Painel: persistência de filtros no localStorage.
// Regras (.agent): lógica no WASM (Go). Aqui é best-effort e fail-open.
//
// - Salva: produto selecionado + checkbox "baixas".
// - Restaura: se a URL não tiver parâmetros e houver valor salvo,
// redireciona para /painel?produto=...&baixas=1.
//
// Importante: não roda fora do /painel.
loc := js.Global().Get("location")
if loc.IsUndefined() || loc.IsNull() {
return nil
}
path := loc.Get("pathname").String()
if path == "" || !strings.HasPrefix(path, "/painel") {
return nil
}
storage := js.Global().Get("localStorage")
if storage.IsUndefined() || storage.IsNull() {
return nil
}
const keyProd = "eli_nps_painel_produto"
const keyBaixas = "eli_nps_painel_baixas"
// Aguarda o DOM estar pronto para conseguirmos acessar o form/option list.
doc := js.Global().Get("document")
if doc.IsUndefined() || doc.IsNull() {
return nil
}
handler := js.FuncOf(func(this js.Value, args []js.Value) any {
// Best-effort: evita exceptions se APIs não existirem.
defer func() { _ = recover() }()
form := doc.Call("querySelector", `form[action="/painel"]`)
if form.IsUndefined() || form.IsNull() {
return nil
}
sel := form.Call("querySelector", `select[name="produto"]`)
chk := form.Call("querySelector", `input[name="baixas"]`)
// Helper: verifica se option existe.
optionExists := func(selectEl js.Value, value string) bool {
if selectEl.IsUndefined() || selectEl.IsNull() {
return false
}
opts := selectEl.Get("options")
ln := opts.Get("length").Int()
for i := 0; i < ln; i++ {
opt := opts.Index(i)
if opt.Get("value").String() == value {
return true
}
}
return false
}
persist := func() {
if !sel.IsUndefined() && !sel.IsNull() {
v := strings.TrimSpace(sel.Get("value").String())
if v != "" {
storage.Call("setItem", keyProd, v)
}
}
baixas := "0"
if !chk.IsUndefined() && !chk.IsNull() && chk.Get("checked").Truthy() {
baixas = "1"
}
storage.Call("setItem", keyBaixas, baixas)
}
// Restaura/redirect apenas se não há query string.
s := loc.Get("search").String()
if strings.TrimSpace(s) == "" {
storedProd := strings.TrimSpace(storage.Call("getItem", keyProd).String())
storedBaixas := strings.TrimSpace(storage.Call("getItem", keyBaixas).String())
if storedProd != "" && optionExists(sel, storedProd) {
q := "?produto=" + url.QueryEscape(storedProd)
if storedBaixas == "1" {
q += "&baixas=1"
}
loc.Call("replace", path+q)
return nil
}
// Se só baixas estiver setado, aplica também.
if storedBaixas == "1" {
loc.Call("replace", path+"?baixas=1")
return nil
}
}
// Liga listeners para persistência.
onSubmit := js.FuncOf(func(this js.Value, args []js.Value) any { persist(); return nil })
onChange := js.FuncOf(func(this js.Value, args []js.Value) any { persist(); return nil })
form.Call("addEventListener", "submit", onSubmit)
form.Call("addEventListener", "change", onChange)
return nil
})
// DOMContentLoaded
readyState := doc.Get("readyState").String()
if readyState != "loading" {
// Se o WASM foi carregado depois do DOM pronto (comum no painel),
// rodamos imediatamente.
handler.Invoke()
} else {
doc.Call("addEventListener", "DOMContentLoaded", handler)
}
return nil
}
func cooldownAtivo(this js.Value, args []js.Value) any {
if len(args) < 1 {
return false