This commit is contained in:
Andrey Cunha 2026-03-10 23:32:02 -03:00
parent b32415212f
commit 9a0ef21ec8
63 changed files with 4412 additions and 637 deletions

View File

View File

@ -0,0 +1,17 @@
!SESSION 2026-03-10 22:22:11.116 -----------------------------------------------
eclipse.buildId=4.13.0.I20190916-1045
java.version=1.8.0_481
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=pt_BR
Framework arguments: -product org.eclipse.epp.package.jee.product
Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product
!ENTRY org.eclipse.egit.ui 2 0 2026-03-10 22:22:42.782
!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git
user global configuration and to define the default location to store repositories: 'C:\Users\Home'. If this is
not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and
EGit might behave differently since they see different configuration options.
This warning can be switched off on the Team > Git > Confirmations and Warnings preference page.
!ENTRY org.eclipse.ui.navigator.resources 4 0 2026-03-10 22:23:03.536
!MESSAGE Could not acquire INavigatorContentService: Project Explorer not found.

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
version=1

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.debug.ui.PREF_LAUNCH_PERSPECTIVES=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\r\n<launchPerspectives/>\r\n

View File

@ -0,0 +1,7 @@
content_assist_proposals_background=255,255,255
content_assist_proposals_foreground=0,0,0
eclipse.preferences.version=1
org.eclipse.jdt.ui.formatterprofiles.version=17
spelling_locale_initialized=true
useAnnotationsPrefPage=true
useQuickDiffPrefPage=true

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.jsch.core.hasChangedDefaultWin32SshHome=true

View File

@ -0,0 +1,2 @@
areThereWebServices=false
eclipse.preferences.version=1

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.m2e.discovery.pref.projects=

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
mylyn.attention.migrated=true

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.mylyn.monitor.activity.tracking.enabled.checked=true

View File

@ -0,0 +1,4 @@
eclipse.preferences.version=1
migrated.task.repositories.secure.store=true
org.eclipse.mylyn.tasks.ui.filters.nonmatching=true
org.eclipse.mylyn.tasks.ui.filters.nonmatching.encouraged=true

View File

@ -0,0 +1,2 @@
activeuserprofiles=DESKTOP-0E2LAA6;Team
eclipse.preferences.version=1

View File

@ -0,0 +1,5 @@
PROBLEMS_FILTERS_MIGRATE=true
eclipse.preferences.version=1
platformState=1772394940336
quickStart=false
tipsAndTricks=true

View File

@ -0,0 +1,4 @@
//org.eclipse.ui.commands/state/org.eclipse.ui.navigator.resources.nested.changeProjectPresentation/org.eclipse.ui.commands.radioState=false
//org.eclipse.ui.commands/state/org.eclipse.wst.xml.views.XPathView.processor.xpathprocessor/org.eclipse.ui.commands.radioState=xpath10
PLUGINS_NOT_ACTIVATED_ON_STARTUP=;org.eclipse.m2e.discovery;
eclipse.preferences.version=1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<typeInfoHistroy/>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<qualifiedTypeNameHistroy/>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<section name="Workbench">
<section name="org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart">
<item key="group_libraries" value="true"/>
<item key="layout" value="2"/>
<item key="rootMode" value="1"/>
<item key="linkWithEditor" value="false"/>
<item key="memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#x0D;&#x0A;&lt;packageExplorer group_libraries=&quot;1&quot; layout=&quot;2&quot; linkWithEditor=&quot;0&quot; rootMode=&quot;1&quot; workingSetName=&quot;Aggregate for window 1773192162956&quot;&gt;&#x0D;&#x0A;&lt;customFilters userDefinedPatternsEnabled=&quot;false&quot;&gt;&#x0D;&#x0A;&lt;xmlDefinedFilters&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.StaticsFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.buildship.ui.packageexplorer.filter.gradle.buildfolder&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer_patternFilterId_RemoteSystemsConnections&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.mylyn.java.ui.MembersFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.NonSharedProjectsFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.internal.ui.PackageExplorer.EmptyInnerPackageFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.m2e.MavenModuleFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.buildship.ui.packageexplorer.filter.gradle.subProject&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.ClosedProjectsFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.EmptyLibraryContainerFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.PackageDeclarationFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.pde.ui.BinaryProjectFilter1&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.LocalTypesFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.pde.ui.ExternalPluginLibrariesFilter1&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.FieldsFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer_patternFilterId_RemoteSystemsTempFiles&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.NonJavaProjectsFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer_patternFilterId_.*&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.SyntheticMembersFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.ContainedLibraryFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.internal.ui.PackageExplorer.HideInnerClassFilesFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.DeprecatedMembersFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.ImportDeclarationFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.NonJavaElementFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.LibraryFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.CuAndClassFileFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.internal.ui.PackageExplorer.EmptyPackageFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.NonPublicFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;/xmlDefinedFilters&gt;&#x0D;&#x0A;&lt;/customFilters&gt;&#x0D;&#x0A;&lt;/packageExplorer&gt;"/>
</section>
</section>

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<section name="Workbench">
</section>

View File

@ -0,0 +1 @@
2026-03-10 22:22:42,342 [Worker-1: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read.

View File

@ -0,0 +1,43 @@
<configuration scan="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%date [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>OFF</level> <!-- change to DEBUG to mimic '-consolelog' behaviour -->
</filter>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${org.eclipse.m2e.log.dir}/0.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<FileNamePattern>${org.eclipse.m2e.log.dir}/%i.log</FileNamePattern>
<MinIndex>1</MinIndex>
<MaxIndex>10</MaxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>100MB</MaxFileSize>
</triggeringPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%date [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<appender name="EclipseLog" class="org.eclipse.m2e.logback.appender.EclipseLogAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
</appender>
<appender name="MavenConsoleLog" class="org.eclipse.m2e.logback.appender.MavenConsoleAppender">
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
<appender-ref ref="EclipseLog" />
<appender-ref ref="MavenConsoleLog" />
</root>
<logger name="com.ning.http.client" level="INFO" />
</configuration>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<setup:Workspace
xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI"
xmlns:setup="http://www.eclipse.org/oomph/setup/1.0"
name="workspace"/>

View File

@ -0,0 +1,2 @@
#Cached timestamps
#Tue Mar 10 22:40:30 GFT 2026

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<section name="Workbench">
</section>

View File

@ -0,0 +1,6 @@
#Tue Mar 10 22:22:35 GFT 2026
0.Path=C\:\\Program Files\\Git\\bin\\sh.exe
0.Name=Git Bash
0.Args=--login -i
0.Translate=true
0.Icon=C\:\\Program Files\\Git\\mingw64\\share\\git\\git-for-windows.ico

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<section name="Workbench">
<section name="BasicNewProjectResourceWizard">
</section>
<section name="SmartImportWizard">
<item key="SmartImportRootWizardPage.STORE_HIDE_ALREADY_OPEN" value="false"/>
<item key="SmartImportRootWizardPage.STORE_CLOSE_IMPORTED" value="false"/>
<item key="SmartImportRootWizardPage.STORE_NESTED_PROJECTS" value="true"/>
<item key="SmartImportRootWizardPage.STORE_CONFIGURE_NATURES" value="true"/>
<list key="org.eclipse.ui.internal.wizards.datatransfer.SmartImportRootWizardPage.knownSources">
<item value="C:\Python\Fluig Ginseng\fluig\checklist\fluig\Auditoria_checklist"/>
</list>
</section>
</section>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<state reopen="true"/>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<section name="Workbench">
<section name="ImportExportAction">
</section>
<section name="NewWizardAction">
</section>
<section name="org.eclipse.ui.internal.QuickAccess">
<item key="dialogHeight" value="-1"/>
<item key="dialogWidth" value="-1"/>
<list key="orderedElements">
</list>
<list key="orderedProviders">
</list>
<list key="textEntries">
</list>
<list key="textArray">
</list>
</section>
</section>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<workingSetManager>
<workingSet editPageId="org.eclipse.jdt.internal.ui.DynamicSourcesWorkingSet" factoryID="org.eclipse.ui.internal.WorkingSetFactory" id="1773192158489_0" label="Java Main Sources" name="Java Main Sources"/>
<workingSet editPageId="org.eclipse.jdt.internal.ui.DynamicSourcesWorkingSet" factoryID="org.eclipse.ui.internal.WorkingSetFactory" id="1773192158505_1" label="Java Test Sources" name="Java Test Sources"/>
<workingSet aggregate="true" factoryID="org.eclipse.ui.internal.WorkingSetFactory" id="1773192162956_2" label="Window Working Set" name="Aggregate for window 1773192162956"/>
</workingSetManager>

View File

@ -0,0 +1,3 @@
#Tue Mar 10 22:22:34 GFT 2026
org.eclipse.core.runtime=2
org.eclipse.platform=4.13.0.v20190916-1045

18
Auditoria_checklist/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,18 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "totvs_language_debug",
"request": "launch",
"name": "TOTVS Language Debug",
"program": "${command:AskForProgramName}",
"cwb": "${workspaceFolder}",
"smartclientBin": "../totvs/bin/smartclient/smartclient.exe",
"isMultiSession": true,
"enableTableSync": true,
"extendFeatures": {
"charDetails": false
}
}
]
}

View File

@ -1,4 +1,17 @@
{
"version": "1.0.0",
"configurations": []
"configurations": [
{
"id": "38vwmxmgns5mmld4ck8m7zjfmvikvg",
"name": "Fluig",
"host": "comerciode188006.fluig.cloudtotvs.com.br",
"ssl": true,
"port": 443,
"username": "andrey.cunha",
"password": "eyJpdiI6ImNlMGI3YWJjZDRkYjk2NWU2MjA1YTllN2QxMThjZGIzIiwic2FsdCI6ImQzN2E4NWI4NTQxYTY1NzJmYzg2NTZkNTgyOGZlYmNiIiwidGV4dCI6IjgyOThmYjgzZDdjMjI0MDc5NGYzNDExNzM5YTY1YjBhIn0=",
"userCode": "andrey.cunha",
"confirmExporting": false,
"companyId": 1
}
]
}

Binary file not shown.

View File

@ -1,11 +1,7 @@
<div id="dashConforme_${instanceId}" class="super-widget wcm-widget-class fluig-style-guide" data-params="DashConforme.instance()">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Top Inconformidades</h3>
</div>
<div class="panel-body">
<div class="dconf-card">
<div class="dconf-title">Atingimento por Loja</div>
<canvas id="graficoConforme_${instanceId}" height="120"></canvas>
</div>
</div>
</div>

View File

@ -1,3 +1,25 @@
div[id^="dashConforme_"] canvas {
max-height: 420px;
div[id^="dashConforme_"] .dconf-card {
background: #ececed;
border-radius: 24px;
padding: 10px 14px;
min-height: 230px;
}
div[id^="dashConforme_"] .dconf-title {
color: #004a6a;
font-size: 18px;
font-weight: 800;
text-align: center;
margin-bottom: 4px;
}
div[id^="dashConforme_"] canvas {
min-height: 165px;
max-height: 180px;
}
@media (max-width: 1300px) {
div[id^="dashConforme_"] .dconf-title {
font-size: 24px;
}
}

View File

@ -3,147 +3,127 @@ var DashConforme = SuperWidget.extend({
chart: null,
init: function () {
var self = this;
this.renderAmostra();
this.render([]);
window.addEventListener("dashboardData", function (e) {
self.render(e.detail || []);
});
},
render: function (dados) {
var mapa = {};
dados.forEach(function (item) {
var lista = String(item.listaNaoConforme || "").trim();
if(!lista){
return;
var loja = String(item.loja || "Sem loja").trim();
if (!mapa[loja]) {
mapa[loja] = { total: 0, conforme: 0 };
}
lista.split("|").forEach(function(indicador){
var chave = String(indicador || "").trim();
if(!chave){
return;
mapa[loja].total += 1;
if (normalizaStatus(item) === "CONFORME") {
mapa[loja].conforme += 1;
}
if(!mapa[chave]){
mapa[chave] = 0;
}
mapa[chave] += 1;
});
});
var pares = Object.keys(mapa).map(function(k){
return {nome:k,valor:mapa[k]};
var pares = Object.keys(mapa).map(function (nome) {
var total = mapa[nome].total;
var pct = total ? (mapa[nome].conforme / total) * 100 : 0;
return { nome: nome, pct: Number(pct.toFixed(2)) };
});
pares.sort(function (a, b) {
return b.valor - a.valor;
return b.pct - a.pct;
});
pares = pares.slice(0,10);
if (!pares.length) {
pares = [{ nome: "Aguardando filtro", pct: 0 }];
}
var labels = pares.map(function (p) { return p.nome; });
var valores = pares.map(function(p){ return p.valor; });
if(!labels.length){
labels = ["Aguardando filtro"];
valores = [0];
}
var valores = pares.map(function (p) { return p.pct; });
var ctx = document.getElementById("graficoConforme_" + this.instanceId);
if(!ctx){
return;
if (!ctx) return;
if (this.chart) this.chart.destroy();
var valueLabelsPlugin = {
id: "valueLabelsPlugin",
afterDatasetsDraw: function (chart) {
var c = chart.ctx;
c.save();
c.font = "700 10px Arial";
c.textAlign = "center";
chart.data.datasets.forEach(function (dataset, datasetIndex) {
var meta = chart.getDatasetMeta(datasetIndex);
meta.data.forEach(function (bar, index) {
var value = dataset.data[index];
if (value == null || Number(value) === 0) return;
var y = bar.y - 4;
var baseline = "bottom";
if (y < chart.chartArea.top + 12) {
y = bar.y + 10;
baseline = "top";
}
if(this.chart){
this.chart.destroy();
c.textBaseline = baseline;
c.fillStyle = baseline === "top" ? "#ffffff" : "#111111";
c.fillText(String(value).replace(".", ",") + "%", bar.x, y);
});
});
c.restore();
}
};
this.chart = new Chart(ctx, {
type: "bar",
plugins: [valueLabelsPlugin],
data: {
labels: labels,
datasets: [{
label:"Ocorrências",
data: valores,
backgroundColor:"#f39c12"
backgroundColor: "#0a5d82"
}]
},
options: {
responsive: true,
maintainAspectRatio:false,
indexAxis:"x",
plugins:{
legend:{display:false},
tooltip:{
callbacks:{
title:function(items){
if(labels.length === 1 && labels[0] === "Aguardando filtro"){
return "Aguardando filtro";
}
return items && items.length ? labels[items[0].dataIndex] : "";
}
}
layout: {
padding: {
top: 14
}
},
plugins: { legend: { display: false } },
scales: {
x: {
ticks: {
autoSkip: false,
maxRotation:35,
minRotation:0,
maxRotation: 28,
minRotation: 10,
callback: function (value, index) {
var txt = labels[index] || "";
return txt.length > 38 ? txt.substring(0,38) + "..." : txt;
return txt.length > 22 ? txt.substring(0, 22) + "..." : txt;
}
}
},
y: {
beginAtZero: true,
precision:0
max: 100,
ticks: {
callback: function (value) {
return value + "%";
}
}
}
});
},
renderAmostra:function(){
var ctx = document.getElementById("graficoConforme_"+this.instanceId);
if(!ctx){
return;
}
if(this.chart){
this.chart.destroy();
}
this.chart = new Chart(ctx,{
type:"bar",
data:{
labels:["Aguardando filtro"],
datasets:[{
label:"Ocorrências",
data:[0],
backgroundColor:"#cfd8dc"
}]
},
options:{
responsive:true,
maintainAspectRatio:false,
plugins:{legend:{display:false}},
scales:{
x:{ticks:{autoSkip:false,maxRotation:0,minRotation:0}},
y:{beginAtZero:true,precision:0}
}
}
});
}
});
function normalizaStatus(item) {
return String(item.saidaAnalise || item.status || "").trim().toUpperCase();
}

View File

@ -1,83 +1,52 @@
var DashData = SuperWidget.extend({
init: function () {
console.log("DashData carregado");
var self = this;
window.addEventListener("dashboardFiltro", function (e) {
console.log("DashData recebeu filtros:",e.detail);
self.carregar(e.detail);
self.carregar(e.detail || {});
});
this.carregar({});
},
carregar: function (filtros) {
console.log("Consultando dataset...", filtros);
var self=this;
$.ajax({
url: "/api/public/ecm/dataset/search",
type: "POST",
contentType: "application/json",
data: JSON.stringify({
datasetId: "ds_dashboard_checklist"
}),
success: function (res) {
console.log("Resposta dataset:",res);
var dados=res.content || [];
console.log("Quantidade registros:", dados.length);
// FILTRO POR LOJA
if(filtros.loja){
dados = dados.filter(function(item){
return normalizaTexto(item.loja) === normalizaTexto(filtros.loja);
});
}
// FILTRO POR DATA
if(filtros.dataInicio || filtros.dataFim){
dados = dados.filter(function(item){
var dataInicioAuditoria = normalizaData(item.dataAuditoria);
var dataLimite = normalizaData(item.dataLimite);
var inicioFiltro = normalizaData(filtros.dataInicio);
var fimFiltro = normalizaData(filtros.dataFim);
// Mantem quando data de auditoria OU data limite estiver na faixa filtrada
return dataNaFaixa(dataInicioAuditoria, inicioFiltro, fimFiltro) ||
dataNaFaixa(dataLimite, inicioFiltro, fimFiltro);
});
}
// Mantem somente auditorias com status final (evita divergencia entre total e KPIs)
var antesStatus = dados.length;
dados = dados.filter(function(item){
var dados = (res.content || []).filter(function (item) {
var st = normalizaTexto(item.saidaAnalise || item.status || "");
return st === "CONFORME" || st === "NAO_CONFORME";
});
console.log("Registros com status final:", dados.length, "de", antesStatus);
// Ordena por data de auditoria mais recente
dados = dados.filter(function (item) {
if (!matchMulti(item.ciclo, filtros.ciclo)) {
return false;
}
if (!matchMulti(item.regional, filtros.regional)) {
return false;
}
var sup = item.responsavelLoja;
if (!matchMulti(sup, filtros.supervisao)) {
return false;
}
if (filtros.dataInicio || filtros.dataFim) {
var dataAuditoria = normalizaData(item.dataAuditoria);
var dataLimite = normalizaData(item.dataLimite);
var inicio = normalizaData(filtros.dataInicio);
var fim = normalizaData(filtros.dataFim);
return dataNaFaixa(dataAuditoria, inicio, fim) || dataNaFaixa(dataLimite, inicio, fim);
}
return true;
});
dados.sort(function (a, b) {
var da = normalizaData(a.dataAuditoria);
var db = normalizaData(b.dataAuditoria);
@ -86,16 +55,12 @@ var DashData = SuperWidget.extend({
return 0;
});
console.log("Registros filtrados:", dados);
window.dispatchEvent(
new CustomEvent("dashboardData",{detail:dados})
);
window.dispatchEvent(new CustomEvent("dashboardData", { detail: dados }));
},
error: function () {
window.dispatchEvent(new CustomEvent("dashboardData", { detail: [] }));
}
});
}
});
@ -105,19 +70,26 @@ function normalizaTexto(valor){
}
function normalizaData(valor) {
var v = String(valor || "").trim();
return v;
return String(valor || "").trim();
}
function dataNaFaixa(data, inicio, fim) {
if(!data){
return false;
}
if(inicio && data < inicio){
return false;
}
if(fim && data > fim){
return false;
}
if (!data) return false;
if (inicio && data < inicio) return false;
if (fim && data > fim) return false;
return true;
}
function matchMulti(valorAtual, selecionados) {
if (!selecionados || !selecionados.length) {
return true;
}
var atual = normalizaTexto(valorAtual);
for (var i = 0; i < selecionados.length; i++) {
if (atual === normalizaTexto(selecionados[i])) {
return true;
}
}
return false;
}

View File

@ -2,8 +2,8 @@
class="super-widget wcm-widget-class fluig-style-guide"
data-params="DashGrafico.instance()">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div style="height:260px; max-width:360px; margin:0 auto;">
<canvas id="grafico_${instanceId}"></canvas>
<div class="dgf-card">
<div class="dgf-title">Atingimento por Regional</div>
<canvas id="grafico_${instanceId}" height="120"></canvas>
</div>
</div>

View File

@ -1 +1,25 @@
/* Coloque aqui seu codigo CSS */
div[id^="dashGrafico_"] .dgf-card {
background: #ececed;
border-radius: 24px;
padding: 10px 14px;
min-height: 230px;
}
div[id^="dashGrafico_"] .dgf-title {
color: #004a6a;
font-size: 18px;
font-weight: 800;
text-align: center;
margin-bottom: 4px;
}
div[id^="dashGrafico_"] canvas {
min-height: 165px;
max-height: 180px;
}
@media (max-width: 1300px) {
div[id^="dashGrafico_"] .dgf-title {
font-size: 24px;
}
}

View File

@ -3,89 +3,147 @@ var DashGrafico = SuperWidget.extend({
chart: null,
init: function () {
var self = this;
this.renderAmostra();
this.render([]);
window.addEventListener("dashboardData", function (e) {
self.render(e.detail);
self.render(e.detail || []);
});
},
render: function (dados) {
var mapa = {};
var conforme=dados.filter(function(i){
return normalizaStatus(i)=="CONFORME";
}).length;
dados.forEach(function (item) {
var regiao = String(item.regional || "Sem regiao").trim();
if (!mapa[regiao]) {
mapa[regiao] = { total: 0, conforme: 0, naoConforme: 0 };
}
mapa[regiao].total += 1;
if (normalizaStatus(item) === "CONFORME") {
mapa[regiao].conforme += 1;
} else {
mapa[regiao].naoConforme += 1;
}
});
var nao=dados.filter(function(i){
return normalizaStatus(i)=="NAO_CONFORME";
}).length;
var labels = Object.keys(mapa).sort(function (a, b) { return a.localeCompare(b); });
if (!labels.length) {
labels = ["Aguardando filtro"];
this.plot(labels, [0], [0]);
return;
}
var ctx=document.getElementById("grafico_"+this.instanceId);
var atingimento = labels.map(function (l) {
var r = mapa[l];
return r.total ? Number(((r.conforme / r.total) * 100).toFixed(2)) : 0;
});
var ncMedio = labels.map(function (l) {
var r = mapa[l];
return r.total ? Number(((r.naoConforme / r.total) * 100).toFixed(2)) : 0;
});
this.plot(labels, atingimento, ncMedio);
},
plot: function (labels, atingimento, ncMedio) {
var canvas = document.getElementById("grafico_" + this.instanceId);
if (!canvas) return;
if (this.chart) {
this.chart.destroy();
}
this.chart=new Chart(ctx,{
var valueLabelsPlugin = {
id: "valueLabelsPlugin",
afterDatasetsDraw: function (chart) {
var c = chart.ctx;
c.save();
c.font = "700 10px Arial";
c.textAlign = "center";
type:'doughnut',
chart.data.datasets.forEach(function (dataset, datasetIndex) {
var meta = chart.getDatasetMeta(datasetIndex);
meta.data.forEach(function (bar, index) {
var value = dataset.data[index];
if (value == null || Number(value) === 0) return;
var y = bar.y - 4;
var baseline = "bottom";
if (y < chart.chartArea.top + 12) {
y = bar.y + 10;
baseline = "top";
}
c.textBaseline = baseline;
c.fillStyle = baseline === "top" ? "#ffffff" : "#111111";
c.fillText(String(value).replace(".", ",") + "%", bar.x, y);
});
});
c.restore();
}
};
this.chart = new Chart(canvas, {
type: "bar",
plugins: [valueLabelsPlugin],
data: {
labels:["Conforme ("+conforme+")","Não Conforme ("+nao+")"],
datasets:[{
data:[conforme,nao],
backgroundColor:["#2ecc71","#e74c3c"]
}]
labels: labels,
datasets: [
{
label: "Atingimento (%)",
data: atingimento,
backgroundColor: "#0a5d82"
},
{
label: "Nao conforme (%)",
data: ncMedio,
backgroundColor: "#88a5b8"
}
]
},
options: {
responsive: true,
maintainAspectRatio:false,
cutout:"48%"
layout: {
padding: {
top: 14
}
},
plugins: {
legend: {
position: "top"
}
},
scales: {
x: {
ticks: {
autoSkip: false,
maxRotation: 20,
minRotation: 0,
callback: function (value, index) {
var txt = labels[index] || "";
return txt.length > 18 ? txt.substring(0, 18) + "..." : txt;
}
}
},
y: {
beginAtZero: true,
max: 100,
ticks: {
callback: function (value) {
return value + "%";
}
}
}
}
}
});
}
});
function normalizaStatus(item) {
var raw = item.saidaAnalise || item.status || "";
return String(raw).trim().toUpperCase();
return String(item.saidaAnalise || item.status || "").trim().toUpperCase();
}
},
renderAmostra:function(){
var ctx=document.getElementById("grafico_"+this.instanceId);
if(!ctx){
return;
}
if(this.chart){
this.chart.destroy();
}
this.chart=new Chart(ctx,{
type:'doughnut',
data:{
labels:["Conforme (0)","Não Conforme (0)"],
datasets:[{
data:[1,0],
backgroundColor:["#cfd8dc","#eceff1"]
}]
},
options:{
responsive:true,
maintainAspectRatio:false,
cutout:"48%",
plugins:{
tooltip:{enabled:false}
}
}
});
}
});

View File

@ -1,44 +1,21 @@
<div id="dashKPI_${instanceId}"
class="super-widget wcm-widget-class fluig-style-guide"
data-params="DashKPI.instance()">
<div class="row">
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-body">
<h4>Total Auditorias</h4>
<h2 id="kpi_total_${instanceId}">0</h2>
</div>
</div>
<div class="dkpi-grid">
<div class="dkpi-card">
<div class="dkpi-title">Atingimento | Geral | CP</div>
<div id="kpi_pct_${instanceId}" class="dkpi-big">0,00%</div>
<div class="dkpi-label">AUDITORIA</div>
</div>
<div class="col-md-3">
<div class="panel panel-success">
<div class="panel-body">
<h4>Conformes</h4>
<h2 id="kpi_ok_${instanceId}">0</h2>
<div class="dkpi-card">
<div class="dkpi-title">Total de Auditorias | Geral | CP</div>
<div class="dkpi-total-row">
<div class="dkpi-bar-bg">
<div id="kpi_total_bar_${instanceId}" class="dkpi-bar-fill"></div>
</div>
<div id="kpi_total_${instanceId}" class="dkpi-total">0</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="panel panel-danger">
<div class="panel-body">
<h4>Não Conformes</h4>
<h2 id="kpi_nok_${instanceId}">0</h2>
</div>
</div>
</div>
<div class="col-md-3">
<div class="panel panel-info">
<div class="panel-body">
<h4>% Conformidade</h4>
<h2 id="kpi_pct_${instanceId}">0%</h2>
</div>
</div>
</div>
</div>
</div>

View File

@ -1 +1,84 @@
/* Coloque aqui seu codigo CSS */
div[id^="dashKPI_"] .dkpi-grid {
display: grid;
grid-template-columns: 1fr 1.4fr;
gap: 4px;
}
div[id^="dashKPI_"] .dkpi-card {
background: #ececed;
border-radius: 18px;
padding: 8px 12px;
min-height: 120px;
}
div[id^="dashKPI_"] .dkpi-title {
color: #004a6a;
font-size: 14px;
font-weight: 800;
margin-bottom: 4px;
line-height: 1.08;
}
div[id^="dashKPI_"] .dkpi-big {
font-size: 20px;
font-weight: 800;
text-align: center;
margin-top: 2px;
margin-bottom: 2px;
}
div[id^="dashKPI_"] .dkpi-label {
text-align: center;
color: #44525a;
font-size: 11px;
font-weight: 700;
}
div[id^="dashKPI_"] .dkpi-total-row {
display: flex;
align-items: center;
gap: 10px;
margin-top: 6px;
}
div[id^="dashKPI_"] .dkpi-bar-bg {
flex: 1;
height: 30px;
border-radius: 4px;
background: #e0e5ea;
overflow: hidden;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}
div[id^="dashKPI_"] .dkpi-bar-fill {
width: 0;
height: 100%;
background: linear-gradient(180deg, #1f6f95 0%, #095777 100%);
transition: width 280ms ease;
}
div[id^="dashKPI_"] .dkpi-total {
min-width: 44px;
font-size: 16px;
font-weight: 800;
color: #111111;
text-align: right;
}
@media (max-width: 1300px) {
div[id^="dashKPI_"] .dkpi-grid {
grid-template-columns: 1fr;
}
div[id^="dashKPI_"] .dkpi-title {
font-size: 16px;
}
div[id^="dashKPI_"] .dkpi-big {
font-size: 28px;
}
div[id^="dashKPI_"] .dkpi-total {
font-size: 22px;
}
}

View File

@ -1,36 +1,27 @@
var DashKPI = SuperWidget.extend({
init: function () {
var self = this;
window.addEventListener("dashboardData", function (e) {
self.calcular(e.detail);
self.calcular(e.detail || []);
});
},
calcular: function (dados) {
var total = dados.length;
var conformes = dados.filter(function (i) {
return normalizaStatus(i)=="CONFORME";
return normalizaStatus(i) === "CONFORME";
}).length;
var nao=dados.filter(function(i){
return normalizaStatus(i)=="NAO_CONFORME";
}).length;
var pct= total ? Math.round((conformes/total)*100) : 0;
var pct = total ? (conformes / total) * 100 : 0;
var pctTxt = pct.toFixed(2).replace(".", ",") + "%";
$("#kpi_total_" + this.instanceId).text(total);
$("#kpi_ok_"+this.instanceId).text(conformes);
$("#kpi_nok_"+this.instanceId).text(nao);
$("#kpi_pct_"+this.instanceId).text(pct+"%");
$("#kpi_pct_" + this.instanceId).text(pctTxt);
var largura = total ? Math.max(12, Math.min(100, pct)) : 0;
$("#kpi_total_bar_" + this.instanceId).css("width", largura + "%");
}
});

View File

@ -3,16 +3,8 @@ class="super-widget wcm-widget-class fluig-style-guide"
data-params="DashRegional.instance()">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Não Conformes por Regional</h3>
</div>
<div class="panel-body">
<canvas id="graficoRegional_${instanceId}" height="120"></canvas>
<div class="drg-card">
<div class="drg-title">Auditorias Realizadas</div>
<canvas id="graficoRegionalTotal_${instanceId}" height="120"></canvas>
</div>
</div>
</div>

View File

@ -1,12 +1,25 @@
div[id^="dashRegional_"] {
position: relative !important;
z-index: 1;
div[id^="dashRegional_"] .drg-card {
background: #ececed;
border-radius: 24px;
padding: 10px 14px;
min-height: 230px;
}
div[id^="dashRegional_"] .panel {
overflow: hidden;
div[id^="dashRegional_"] .drg-title {
color: #004a6a;
font-size: 18px;
font-weight: 800;
text-align: center;
margin-bottom: 4px;
}
div[id^="dashRegional_"] canvas {
max-height: 260px;
min-height: 165px;
max-height: 180px;
}
@media (max-width: 1300px) {
div[id^="dashRegional_"] .drg-title {
font-size: 22px;
}
}

View File

@ -1,102 +1,112 @@
var DashRegional = SuperWidget.extend({
chart:null,
chartTotal: null,
init: function () {
var self = this;
this.renderAmostra();
this.render([]);
window.addEventListener("dashboardData", function (e) {
self.render(e.detail);
self.render(e.detail || []);
});
},
render: function (dados) {
var mapa = {};
// soma nao conformes por regional
dados.forEach(function(i){
var regional=i.regional || "Sem regional";
if(!mapa[regional]) mapa[regional]=0;
mapa[regional]+=parseInt(i.qtdNaoConforme||0,10) || 0;
dados.forEach(function (item) {
var regiao = String(item.regional || "Sem regiao").trim();
if (!mapa[regiao]) {
mapa[regiao] = 0;
}
mapa[regiao] += 1;
});
// transformar em arrays
var labels = Object.keys(mapa);
var valores=Object.values(mapa);
if (!labels.length) {
labels=["Aguardando filtro"];
valores=[0];
}
// canvas
var ctx=document.getElementById("graficoRegional_"+this.instanceId);
if(this.chart){
this.chart.destroy();
}
// criar gráfico
this.chart=new Chart(ctx,{
type:'bar',
data:{
labels:labels,
datasets:[{
label:"Não conformes",
data:valores,
backgroundColor:"#e74c3c"
}]
},
options:{
responsive:true,
plugins:{
legend:{display:false}
}
}
});
},
renderAmostra:function(){
var ctx=document.getElementById("graficoRegional_"+this.instanceId);
if(!ctx){
this.renderGrafico(["Aguardando filtro"], [0]);
return;
}
if(this.chart){
this.chart.destroy();
labels.sort(function (a, b) {
return a.localeCompare(b);
});
var totais = labels.map(function (l) { return mapa[l]; });
this.renderGrafico(labels, totais);
},
renderGrafico: function (labels, totais) {
var ctxTotal = document.getElementById("graficoRegionalTotal_" + this.instanceId);
if (!ctxTotal) return;
if (this.chartTotal) this.chartTotal.destroy();
var valueLabelsPlugin = {
id: "valueLabelsPlugin",
afterDatasetsDraw: function (chart) {
var ctx = chart.ctx;
ctx.save();
ctx.font = "700 10px Arial";
ctx.textAlign = "center";
chart.data.datasets.forEach(function (dataset, datasetIndex) {
var meta = chart.getDatasetMeta(datasetIndex);
meta.data.forEach(function (bar, index) {
var value = dataset.data[index];
if (value == null) return;
var y = bar.y - 4;
var baseline = "bottom";
if (y < chart.chartArea.top + 12) {
y = bar.y + 10;
baseline = "top";
}
this.chart=new Chart(ctx,{
type:'bar',
ctx.textBaseline = baseline;
ctx.fillStyle = baseline === "top" ? "#ffffff" : "#111111";
ctx.fillText(String(value), bar.x, y);
});
});
ctx.restore();
}
};
this.chartTotal = new Chart(ctxTotal, {
type: "bar",
plugins: [valueLabelsPlugin],
data: {
labels:["Aguardando filtro"],
labels: labels,
datasets: [{
label:"Não conformes",
data:[0],
backgroundColor:"#cfd8dc"
data: totais,
backgroundColor: "#0a5d82"
}]
},
options: {
responsive: true,
plugins:{legend:{display:false}}
layout: {
padding: {
top: 14
}
},
plugins: { legend: { display: false } },
scales: {
x: {
ticks: {
autoSkip: false,
maxRotation: 22,
minRotation: 0,
callback: function (value, index) {
var txt = labels[index] || "";
return txt.length > 18 ? txt.substring(0, 18) + "..." : txt;
}
}
},
y: { beginAtZero: true, precision: 0 }
}
}
});
}
});

View File

@ -1,16 +1,18 @@
<div id="dashTabela_${instanceId}"
class="super-widget wcm-widget-class fluig-style-guide"
data-params="DashTabela.instance()">
<div class="dtb-card">
<div class="dtb-title">Detalhe das Auditorias</div>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Data Início</th>
<th>Data Limite</th>
<th>Data Inicio</th>
<th>Prazo</th>
<th>Ciclo</th>
<th>Auditor</th>
<th>Responsável Loja</th>
<th>Analista</th>
<th>Gestor</th>
<th>Loja</th>
<th>Status</th>
</tr>
@ -21,12 +23,12 @@ data-params="DashTabela.instance()">
<td colspan="7" class="text-center">Aguardando filtro...</td>
</tr>
</tbody>
</table>
</div>
<div class="dash-table-footer">
<div class="dash-page-size">
<label for="page_size_${instanceId}">Itens por página</label>
<label for="page_size_${instanceId}">Itens por pagina</label>
<select id="page_size_${instanceId}" class="form-control input-sm">
<option value="5" selected>5</option>
<option value="10">10</option>
@ -37,8 +39,8 @@ data-params="DashTabela.instance()">
<div id="page_info_${instanceId}" class="dash-page-info">Aguardando filtro</div>
<div class="dash-page-actions">
<button id="page_prev_${instanceId}" type="button" class="btn btn-default btn-sm">Anterior</button>
<button id="page_next_${instanceId}" type="button" class="btn btn-default btn-sm">Próxima</button>
<button id="page_next_${instanceId}" type="button" class="btn btn-default btn-sm">Proxima</button>
</div>
</div>
</div>
</div>

View File

@ -1,8 +1,26 @@
div[id^="dashTabela_"] .dtb-card {
background: #ececed;
border-radius: 34px;
padding: 16px 20px;
}
div[id^="dashTabela_"] .dtb-title {
color: #004a6a;
font-size: 34px;
font-weight: 800;
text-align: center;
margin-bottom: 10px;
}
div[id^="dashTabela_"] table th,
div[id^="dashTabela_"] table td {
vertical-align: top;
}
div[id^="dashTabela_"] table th {
color: #0a4f70;
}
div[id^="dashTabela_"] table th:nth-child(1),
div[id^="dashTabela_"] table td:nth-child(1),
div[id^="dashTabela_"] table th:nth-child(2),
@ -23,7 +41,7 @@ div[id^="dashTabela_"] .dash-table-footer {
justify-content: space-between;
gap: 10px;
padding-top: 8px;
border-top: 1px solid #eee;
border-top: 1px solid #d4d9dd;
}
div[id^="dashTabela_"] .dash-page-size {
@ -44,10 +62,20 @@ div[id^="dashTabela_"] .dash-page-size select {
div[id^="dashTabela_"] .dash-page-info {
font-size: 12px;
color: #666;
color: #44525a;
}
div[id^="dashTabela_"] .dash-page-actions {
display: flex;
gap: 6px;
}
@media (max-width: 1300px) {
div[id^="dashTabela_"] .dtb-title {
font-size: 24px;
}
div[id^="dashTabela_"] .dash-table-footer {
flex-wrap: wrap;
}
}

View File

@ -1,34 +1,35 @@
<div id="filtroDash_${instanceId}"
class="super-widget wcm-widget-class fluig-style-guide"
data-params="FiltroDash.instance()">
<div class="fdash-wrap">
<div class="fdash-title">AUDITORIAS DE LOJA - IAF 2026</div>
<div class="row">
<div class="fdash-filters-row">
<div class="fdash-filter-card">
<div class="fdash-filter-label">CICLO</div>
<div id="chips_ciclo_${instanceId}" class="fdash-chips"></div>
</div>
<div class="fdash-filter-card">
<div class="fdash-filter-label">REGIONAL</div>
<div id="chips_regional_${instanceId}" class="fdash-chips"></div>
</div>
<div class="fdash-filter-card">
<div class="fdash-filter-label">GESTOR</div>
<div id="chips_supervisao_${instanceId}" class="fdash-chips"></div>
</div>
</div>
<div class="col-md-3">
<label>Data início</label>
<div class="fdash-actions">
<div class="fdash-date">
<label for="dtInicio_${instanceId}">Data inicio</label>
<input type="date" class="form-control" id="dtInicio_${instanceId}">
</div>
<div class="col-md-3">
<label>Data fim</label>
<div class="fdash-date">
<label for="dtFim_${instanceId}">Data fim</label>
<input type="date" class="form-control" id="dtFim_${instanceId}">
</div>
<div class="col-md-4">
<label>Filial</label>
<input class="form-control" id="filial_${instanceId}" list="filial_list_${instanceId}" placeholder="Todas">
<datalist id="filial_list_${instanceId}">
<option value="Todas"></option>
</datalist>
<button type="button" id="limpar_${instanceId}" class="btn btn-default">Limpar</button>
<button type="button" id="filtrar_${instanceId}" class="btn btn-primary">Aplicar filtros</button>
</div>
<div class="col-md-2">
<label>&nbsp;</label>
<button type="button" class="btn btn-primary btn-block" data-filtrar>
Filtrar
</button>
</div>
</div>
</div>

View File

@ -1,7 +1,131 @@
div[id^="filtroDash_"] input[list] {
padding-right: 30px;
div[id^="filtroDash_"] .fdash-wrap {
background: #9d9d9f;
border-radius: 16px;
padding: 12px;
color: #ffffff;
}
div[id^="filtroDash_"] .btn[data-filtrar] {
font-weight: 600;
div[id^="filtroDash_"] .fdash-title {
text-align: center;
font-size: 30px;
line-height: 1.12;
font-weight: 800;
margin-bottom: 10px;
letter-spacing: 0.5px;
}
div[id^="filtroDash_"] .fdash-filters-row {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 8px;
}
div[id^="filtroDash_"] .fdash-filter-card {
background: #ececed;
border-radius: 12px;
padding: 8px;
}
div[id^="filtroDash_"] .fdash-filter-label {
color: #004a6a;
font-size: 15px;
font-weight: 800;
margin-bottom: 6px;
}
div[id^="filtroDash_"] .fdash-chips {
display: flex;
flex-wrap: wrap;
gap: 5px;
min-height: 36px;
}
div[id^="filtroDash_"] .fdash-chip {
border: 1px solid #0a4f70;
background: #0a5d82;
color: #ffffff;
padding: 3px 8px;
border-radius: 6px;
font-weight: 700;
font-size: 12px;
cursor: pointer;
}
div[id^="filtroDash_"] .fdash-chip.is-off {
background: #f0f3f5;
color: #1c4a62;
}
div[id^="filtroDash_"] .fdash-actions {
display: flex;
align-items: flex-end;
justify-content: center;
gap: 8px;
margin-top: 8px;
}
div[id^="filtroDash_"] .fdash-date {
min-width: 160px;
}
div[id^="filtroDash_"] .fdash-date label {
margin: 0 0 2px 0;
color: #ffffff;
font-weight: 700;
font-size: 12px;
}
div[id^="filtroDash_"] .fdash-date input {
border-radius: 8px;
height: 34px;
font-size: 13px;
}
div[id^="filtroDash_"] .fdash-actions .btn {
font-weight: 700;
border-radius: 8px;
min-height: 34px;
padding: 6px 12px;
font-size: 13px;
}
div[id^="filtroDash_"] .fdash-actions button[id^="limpar_"] {
background: #e6ebef;
border-color: #c7d2da;
color: #1c4a62;
}
div[id^="filtroDash_"] .fdash-actions button[id^="filtrar_"] {
background: #0a5d82;
border-color: #0a4f70;
color: #ffffff;
}
div[id^="filtroDash_"] .fdash-actions button[id^="filtrar_"]:hover,
div[id^="filtroDash_"] .fdash-actions button[id^="filtrar_"]:focus {
background: #084d6c;
border-color: #083f58;
}
@media (max-width: 1300px) {
div[id^="filtroDash_"] .fdash-title {
font-size: 24px;
}
div[id^="filtroDash_"] .fdash-filters-row {
grid-template-columns: 1fr;
}
div[id^="filtroDash_"] .fdash-filter-label {
font-size: 14px;
}
div[id^="filtroDash_"] .fdash-chip {
font-size: 12px;
}
div[id^="filtroDash_"] .fdash-actions {
flex-wrap: wrap;
justify-content: flex-start;
}
}

View File

@ -1,111 +1,139 @@
var FiltroDash = SuperWidget.extend({
lojasCarregadas:[],
dadosBase: [],
selecionados: {
ciclo: {},
regional: {},
supervisao: {}
},
init: function () {
console.log("FiltroDash carregado");
this.carregarLojas();
},
bindings: {
local:{
'filtrar': ['click_filtrar']
}
},
carregarLojas: function(){
var self = this;
var dataList = $("#filial_list_"+this.instanceId);
this.carregarBase(function () {
self.renderFiltros();
self.aplicar();
});
$("#filtrar_" + this.instanceId).on("click", function () {
self.aplicar();
});
$("#limpar_" + this.instanceId).on("click", function () {
self.limpar();
});
},
carregarBase: function (done) {
var self = this;
$.ajax({
url: "/api/public/ecm/dataset/search",
type: "POST",
contentType: "application/json",
data: JSON.stringify({
datasetId: "ds_lojas_api",
constraints: [],
fields: [],
order: []
datasetId: "ds_dashboard_checklist"
}),
success: function (response) {
self.dadosBase = (response.content || []).filter(function (item) {
var st = normalizaTexto(item.saidaAnalise || item.status || "");
return st === "CONFORME" || st === "NAO_CONFORME";
});
done();
},
error: function () {
self.dadosBase = [];
done();
}
});
},
var dados = response.content || [];
self.lojasCarregadas = dados.map(function(loja){
return String(loja.LOJA || "").trim();
}).filter(function(v){ return !!v; });
renderFiltros: function () {
var ciclos = this.valoresUnicos(function (x) { return x.ciclo; });
var regionais = this.valoresUnicos(function (x) { return x.regional; });
var supervisoes = this.valoresUnicos(function (x) { return x.responsavelLoja; });
self.lojasCarregadas.sort(function(a,b){
this.renderChips("ciclo", ciclos, "#chips_ciclo_" + this.instanceId);
this.renderChips("regional", regionais, "#chips_regional_" + this.instanceId);
this.renderChips("supervisao", supervisoes, "#chips_supervisao_" + this.instanceId);
},
valoresUnicos: function (getter) {
var mapa = {};
this.dadosBase.forEach(function (item) {
var v = String(getter(item) || "").trim();
if (!v) {
return;
}
mapa[v] = true;
});
return Object.keys(mapa).sort(function (a, b) {
return a.localeCompare(b);
});
self.lojasCarregadas.forEach(function(loja){
dataList.append(
'<option value="'+loja+'"></option>'
);
});
}
});
},
filtrar:function(){
renderChips: function (tipo, valores, alvoSelector) {
var self = this;
var alvo = $(alvoSelector);
alvo.empty();
console.log("Filtrar clicado");
if (!valores.length) {
alvo.append('<span class="text-muted">Sem dados</span>');
return;
}
var lojaDigitada = String($("#filial_"+this.instanceId).val() || "").trim();
valores.forEach(function (valor) {
var chip = $("<button>")
.attr("type", "button")
.addClass("fdash-chip")
.addClass("is-off")
.attr("data-tipo", tipo)
.attr("data-valor", valor)
.text(valor);
var filtros = {
chip.on("click", function () {
var bucket = self.selecionados[tipo];
if (bucket[valor]) {
delete bucket[valor];
chip.addClass("is-off");
} else {
bucket[valor] = true;
chip.removeClass("is-off");
}
self.aplicar();
});
dataInicio: $("#dtInicio_"+this.instanceId).val(),
dataFim: $("#dtFim_"+this.instanceId).val(),
loja: this.resolverLoja(lojaDigitada)
alvo.append(chip);
});
},
limpar: function () {
this.selecionados = {
ciclo: {},
regional: {},
supervisao: {}
};
console.log("Filtros enviados:", filtros);
window.dispatchEvent(
new CustomEvent("dashboardFiltro",{detail:filtros})
);
$("#dtInicio_" + this.instanceId).val("");
$("#dtFim_" + this.instanceId).val("");
$("#filtroDash_" + this.instanceId + " .fdash-chip").addClass("is-off");
this.aplicar();
},
resolverLoja:function(lojaDigitada){
if(!lojaDigitada){
return "";
}
var buscado = lojaDigitada.toUpperCase();
if(buscado === "TODAS" || buscado === "TODOS"){
return "";
}
var lojas = this.lojasCarregadas || [];
for(var i=0;i<lojas.length;i++){
if(lojas[i].toUpperCase() === buscado){
return lojas[i];
}
}
for(var j=0;j<lojas.length;j++){
if(lojas[j].toUpperCase().indexOf(buscado) >= 0){
return lojas[j];
}
}
return lojaDigitada;
aplicar: function () {
var filtros = {
dataInicio: $("#dtInicio_" + this.instanceId).val(),
dataFim: $("#dtFim_" + this.instanceId).val(),
ciclo: Object.keys(this.selecionados.ciclo),
regional: Object.keys(this.selecionados.regional),
supervisao: Object.keys(this.selecionados.supervisao)
};
window.dispatchEvent(new CustomEvent("dashboardFiltro", { detail: filtros }));
}
});
function normalizaTexto(valor) {
return String(valor || "").trim().toUpperCase();
}