att
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
application.type=widget
|
||||
application.code=wdtransf
|
||||
application.title=wdtransf
|
||||
application.description=wdtransf
|
||||
application.fluig.version=null
|
||||
application.category=SYSTEM
|
||||
application.renderer=freemarker
|
||||
developer.code=Andrey Cunha
|
||||
developer.name=Andrey cunha
|
||||
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=wdtransf
|
||||
application.resource.js.1=/resources/js/wdtransf.js
|
||||
application.resource.css.2=/resources/css/wdtransf.css
|
||||
hash=4a16315e9e66fa7d797b3f6b1fb365b69f9a4ce2
|
||||
@@ -0,0 +1,5 @@
|
||||
<div id="MyWidget_${instanceId}" class="super-widget wcm-widget-class fluig-style-guide" data-params="WdTransfWidget.instance()">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
<div id="MyWidget_${instanceId}" class="super-widget wcm-widget-class fluig-style-guide wdtransf-widget" data-params="WdTransfWidget.instance()">
|
||||
<div class="wdtransf-shell">
|
||||
<div class="wdtransf-head">
|
||||
<div>
|
||||
<h3 class="wdtransf-title">Monitor de Transferencias</h3>
|
||||
<p class="wdtransf-subtitle">Fonte: dataset <strong>transferenciav2</strong></p>
|
||||
</div>
|
||||
<span class="wdtransf-updated" data-role="updatedAt">Atualizando...</span>
|
||||
</div>
|
||||
|
||||
<div class="wdtransf-filters row">
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<label class="wdtransf-label">Busca</label>
|
||||
<input type="text" class="form-control" data-role="search" placeholder="WKNumProces, requesterName, ufOrigem, ufDestino..." />
|
||||
</div>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<label class="wdtransf-label">Atividade</label>
|
||||
<select class="form-control" data-role="activityFilter"></select>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-12 wdtransf-actions">
|
||||
<button type="button" class="btn btn-primary" data-action="reload">Atualizar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wdtransf-message" data-role="message" style="display:none;"></div>
|
||||
|
||||
<div class="wdtransf-kpis row">
|
||||
<div class="col-md-3 col-sm-6">
|
||||
<div class="wdtransf-kpi">
|
||||
<div class="wdtransf-kpi-label">Total carregado</div>
|
||||
<div class="wdtransf-kpi-value" data-role="kpiTotal">0</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-6">
|
||||
<div class="wdtransf-kpi">
|
||||
<div class="wdtransf-kpi-label">Em transito</div>
|
||||
<div class="wdtransf-kpi-value" data-role="kpiTransit">0</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-4">
|
||||
<div class="wdtransf-kpi">
|
||||
<div class="wdtransf-kpi-label">Aguard. recebimento</div>
|
||||
<div class="wdtransf-kpi-value" data-role="kpiPendingReceipt">0</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-4">
|
||||
<div class="wdtransf-kpi">
|
||||
<div class="wdtransf-kpi-label">Em problema</div>
|
||||
<div class="wdtransf-kpi-value" data-role="kpiProblem">0</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-4">
|
||||
<div class="wdtransf-kpi">
|
||||
<div class="wdtransf-kpi-label">Finalizadas</div>
|
||||
<div class="wdtransf-kpi-value" data-role="kpiDone">0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wdtransf-panel">
|
||||
<div class="wdtransf-panel-title">Funil por etapa</div>
|
||||
<div class="wdtransf-stage-list" data-role="stageBars"></div>
|
||||
</div>
|
||||
|
||||
<div class="wdtransf-panel">
|
||||
<div class="wdtransf-panel-title">Detalhes das transferencias</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-condensed table-striped wdtransf-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Processo</th>
|
||||
<th>Solicitante</th>
|
||||
<th>Origem</th>
|
||||
<th>Destino</th>
|
||||
<th>Data abertura</th>
|
||||
<th>Atividade</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-role="tableBody">
|
||||
<tr>
|
||||
<td colspan="6">Carregando dados...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="wdtransf-pagination">
|
||||
<div class="wdtransf-pagination-info" data-role="pageInfo">Exibindo 0 de 0</div>
|
||||
<div class="wdtransf-pagination-controls">
|
||||
<button type="button" class="btn btn-default btn-sm" data-action="prevPage">Anterior</button>
|
||||
<span class="wdtransf-page-status" data-role="pageStatus">Pagina 0 de 0</span>
|
||||
<button type="button" class="btn btn-default btn-sm" data-action="nextPage">Proxima</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jboss-web>
|
||||
<context-root>/wdtransf</context-root>
|
||||
<disable-cross-context>false</disable-cross-context>
|
||||
</jboss-web>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
version="3.0">
|
||||
<session-config>
|
||||
<session-timeout>
|
||||
30
|
||||
</session-timeout>
|
||||
</session-config>
|
||||
</web-app>
|
||||
@@ -0,0 +1,277 @@
|
||||
.wdtransf-widget .wdtransf-shell {
|
||||
background: #f4f7fb;
|
||||
border: 1px solid #d8e3ee;
|
||||
border-radius: 12px;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-title {
|
||||
margin: 0;
|
||||
color: #0f4a77;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-subtitle {
|
||||
margin: 4px 0 0;
|
||||
color: #5a6c7f;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-updated {
|
||||
color: #4f6274;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-label {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
color: #3e5a73;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-filters {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-filters .form-control {
|
||||
height: 36px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-actions {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 6px;
|
||||
padding-top: 18px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-message {
|
||||
margin-bottom: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 8px 10px;
|
||||
font-size: 12px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-message.is-info {
|
||||
background: #e8f1fb;
|
||||
color: #1d4f7d;
|
||||
border-color: #bed6ee;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-message.is-success {
|
||||
background: #e8f6ea;
|
||||
color: #2b6a3b;
|
||||
border-color: #bde0c3;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-message.is-warning {
|
||||
background: #fff5e8;
|
||||
color: #8f6219;
|
||||
border-color: #f0d8b5;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-message.is-danger {
|
||||
background: #fdecec;
|
||||
color: #9a2f2f;
|
||||
border-color: #e8b8b8;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-kpis {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-kpi {
|
||||
background: #ffffff;
|
||||
border: 1px solid #dbe6f1;
|
||||
border-radius: 10px;
|
||||
padding: 10px 12px;
|
||||
min-height: 72px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-kpi-label {
|
||||
color: #4b647b;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-kpi-value {
|
||||
margin-top: 4px;
|
||||
color: #0f4a77;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-panel {
|
||||
background: #ffffff;
|
||||
border: 1px solid #dbe6f1;
|
||||
border-radius: 10px;
|
||||
padding: 10px 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-panel-title {
|
||||
color: #1a537f;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-stage-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-stage-item {
|
||||
display: grid;
|
||||
grid-template-columns: 180px 1fr 62px;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-stage-label {
|
||||
color: #3f5d75;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-stage-bar-wrap {
|
||||
background: #edf2f7;
|
||||
border: 1px solid #d5e0eb;
|
||||
border-radius: 999px;
|
||||
height: 14px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-stage-bar {
|
||||
background: linear-gradient(90deg, #2f84bf 0%, #0f5b91 100%);
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-stage-value {
|
||||
text-align: right;
|
||||
color: #244d70;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-table thead th {
|
||||
background: #eef4fb;
|
||||
color: #3f5d75;
|
||||
font-size: 11px;
|
||||
border-bottom: 1px solid #d6e1ed;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-table tbody td {
|
||||
font-size: 12px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-pagination {
|
||||
margin-top: 10px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid #e1e9f2;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-pagination-info {
|
||||
color: #536b81;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-pagination-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-page-status {
|
||||
min-width: 110px;
|
||||
text-align: center;
|
||||
color: #2d5679;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-status {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-status.is-progress {
|
||||
color: #1d6095;
|
||||
background: #e8f2fb;
|
||||
border-color: #c3dbef;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-status.is-problem {
|
||||
color: #a53333;
|
||||
background: #feecec;
|
||||
border-color: #efb9b9;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-status.is-done {
|
||||
color: #2f6f41;
|
||||
background: #e9f8ed;
|
||||
border-color: #bfe4c7;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-status.is-cancel {
|
||||
color: #8c651f;
|
||||
background: #fff5e8;
|
||||
border-color: #f0dcba;
|
||||
}
|
||||
|
||||
.wdtransf-widget.is-loading .wdtransf-panel,
|
||||
.wdtransf-widget.is-loading .wdtransf-kpi {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.wdtransf-widget .wdtransf-head {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-actions {
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-stage-item {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.wdtransf-widget .wdtransf-stage-value {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
@@ -0,0 +1,570 @@
|
||||
var WdTransfWidget = SuperWidget.extend({
|
||||
datasetName: "transferenciav2",
|
||||
pageSize: 10,
|
||||
batchSize: 1000,
|
||||
currentPage: 1,
|
||||
rowsCache: [],
|
||||
isIncrementalLoading: false,
|
||||
loadOffset: 0,
|
||||
batchToken: 0,
|
||||
lastChunkMarker: "",
|
||||
noPagingMode: false,
|
||||
|
||||
stageDefs: [
|
||||
{ label: "Solicitacao", activities: ["0", "1"] },
|
||||
{ label: "Aprovacao", activities: ["4"] },
|
||||
{ label: "Emissao NFe", activities: ["6"] },
|
||||
{ label: "Coleta", activities: ["31"] },
|
||||
{ label: "Entrega", activities: ["57"] },
|
||||
{ label: "Recebimento", activities: ["18"] },
|
||||
{ label: "Consultar Entrada", activities: ["99"] },
|
||||
{ label: "Verificar Problema", activities: ["24", "104"] },
|
||||
{ label: "Finalizada", activities: ["96", "101"] },
|
||||
{ label: "Cancelada", activities: ["39", "60"] }
|
||||
],
|
||||
|
||||
bindings: {
|
||||
local: {},
|
||||
global: {}
|
||||
},
|
||||
|
||||
init: function() {
|
||||
this.$widget = $("#MyWidget_" + this.instanceId);
|
||||
this.bindEvents();
|
||||
this.populateActivityFilter();
|
||||
this.currentPage = 1;
|
||||
this.loadData();
|
||||
},
|
||||
|
||||
bindEvents: function() {
|
||||
var self = this;
|
||||
|
||||
self.$widget.on("click", "[data-action='reload']", function() {
|
||||
self.currentPage = 1;
|
||||
self.loadData();
|
||||
});
|
||||
|
||||
self.$widget.on("change", "[data-role='activityFilter']", function() {
|
||||
self.currentPage = 1;
|
||||
self.render();
|
||||
});
|
||||
|
||||
self.$widget.on("keypress", "[data-role='search']", function(e) {
|
||||
if (e.which === 13) {
|
||||
e.preventDefault();
|
||||
self.currentPage = 1;
|
||||
self.render();
|
||||
}
|
||||
});
|
||||
|
||||
self.$widget.on("click", "[data-action='prevPage']", function() {
|
||||
self.setPage(self.currentPage - 1);
|
||||
});
|
||||
|
||||
self.$widget.on("click", "[data-action='nextPage']", function() {
|
||||
self.setPage(self.currentPage + 1);
|
||||
});
|
||||
},
|
||||
|
||||
populateActivityFilter: function() {
|
||||
var added = {};
|
||||
var options = ["<option value=''>Todas</option>"];
|
||||
|
||||
for (var i = 0; i < this.stageDefs.length; i++) {
|
||||
var stage = this.stageDefs[i];
|
||||
for (var j = 0; j < stage.activities.length; j++) {
|
||||
var code = String(stage.activities[j]);
|
||||
if (added[code]) continue;
|
||||
added[code] = true;
|
||||
options.push(
|
||||
"<option value='" + this.escapeHtml(code) + "'>" +
|
||||
this.escapeHtml(code + " - " + this.getActivityLabel(code)) +
|
||||
"</option>"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.$widget.find("[data-role='activityFilter']").html(options.join(""));
|
||||
},
|
||||
|
||||
loadData: function() {
|
||||
this.batchToken++;
|
||||
this.rowsCache = [];
|
||||
this.currentPage = 1;
|
||||
this.loadOffset = 0;
|
||||
this.lastChunkMarker = "";
|
||||
this.noPagingMode = false;
|
||||
this.isIncrementalLoading = true;
|
||||
|
||||
this.setLoading(true);
|
||||
this.setMessage("Carregando solicitacoes...", "info");
|
||||
this.render();
|
||||
this.loadNextBatch(this.batchToken);
|
||||
},
|
||||
|
||||
loadNextBatch: function(token) {
|
||||
var self = this;
|
||||
if (token !== self.batchToken) return;
|
||||
|
||||
self.fetchDatasetBatch(self.batchSize, self.loadOffset, function(err, rows) {
|
||||
if (token !== self.batchToken) return;
|
||||
|
||||
if (err) {
|
||||
self.isIncrementalLoading = false;
|
||||
self.setLoading(false);
|
||||
self.render();
|
||||
self.setMessage("Erro ao carregar dataset: " + err, "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
rows = rows || [];
|
||||
if (!rows.length) {
|
||||
self.isIncrementalLoading = false;
|
||||
self.setLoading(false);
|
||||
self.render();
|
||||
self.setMessage("Dados carregados: " + self.formatNumber(self.rowsCache.length) + " registro(s).", "success");
|
||||
return;
|
||||
}
|
||||
|
||||
var chunkMarker = self.buildChunkMarker(rows[0]);
|
||||
if (self.loadOffset > 0 && chunkMarker && chunkMarker === self.lastChunkMarker) {
|
||||
self.isIncrementalLoading = false;
|
||||
self.setLoading(false);
|
||||
self.render();
|
||||
self.setMessage("Paginacao do dataset nao evoluiu (sqlStart/offset). Verifique suporte no ambiente.", "warning");
|
||||
return;
|
||||
}
|
||||
|
||||
self.lastChunkMarker = chunkMarker;
|
||||
self.rowsCache = self.rowsCache.concat(rows);
|
||||
self.loadOffset += rows.length;
|
||||
self.render();
|
||||
self.setMessage("Carregando solicitacoes... " + self.formatNumber(self.rowsCache.length) + " registro(s).", "info");
|
||||
|
||||
if (self.noPagingMode) {
|
||||
self.isIncrementalLoading = false;
|
||||
self.setLoading(false);
|
||||
self.render();
|
||||
self.setMessage("Dados carregados: " + self.formatNumber(self.rowsCache.length) + " registro(s).", "success");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rows.length < self.batchSize) {
|
||||
self.isIncrementalLoading = false;
|
||||
self.setLoading(false);
|
||||
self.render();
|
||||
self.setMessage("Dados carregados: " + self.formatNumber(self.rowsCache.length) + " registro(s).", "success");
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
self.loadNextBatch(token);
|
||||
}, 0);
|
||||
});
|
||||
},
|
||||
|
||||
fetchDatasetBatch: function(limit, offset, callback) {
|
||||
var self = this;
|
||||
if (self.noPagingMode && offset > 0) {
|
||||
callback(null, []);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof DatasetFactory !== "undefined" && typeof DatasetFactory.getDataset === "function" &&
|
||||
typeof ConstraintType !== "undefined" && typeof DatasetFactory.createConstraint === "function") {
|
||||
var constraints = self.noPagingMode ? null : self.buildFactoryPagingConstraints(limit, offset);
|
||||
var ds = DatasetFactory.getDataset(self.datasetName, null, constraints, null);
|
||||
var rows = (ds && ds.values) ? ds.values : [];
|
||||
|
||||
// Fallback para datasets (card/form) que nao suportam sqlLimit/sqlStart como MUST.
|
||||
if (!rows.length && offset === 0 && !self.noPagingMode) {
|
||||
var dsNoPaging = DatasetFactory.getDataset(self.datasetName, null, null, null);
|
||||
var rowsNoPaging = (dsNoPaging && dsNoPaging.values) ? dsNoPaging.values : [];
|
||||
if (rowsNoPaging.length) {
|
||||
self.noPagingMode = true;
|
||||
callback(null, rowsNoPaging);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
callback(null, rows);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
// fallback REST
|
||||
}
|
||||
|
||||
this.fetchDatasetBatchViaRest(limit, offset, callback);
|
||||
},
|
||||
|
||||
buildFactoryPagingConstraints: function(limit, offset) {
|
||||
var constraints = [];
|
||||
constraints.push(DatasetFactory.createConstraint("sqlLimit", String(limit), String(limit), ConstraintType.MUST));
|
||||
constraints.push(DatasetFactory.createConstraint("sqlStart", String(offset), String(offset), ConstraintType.MUST));
|
||||
constraints.push(DatasetFactory.createConstraint("offset", String(offset), String(offset), ConstraintType.MUST));
|
||||
constraints.push(DatasetFactory.createConstraint("sqlOffset", String(offset), String(offset), ConstraintType.MUST));
|
||||
return constraints;
|
||||
},
|
||||
|
||||
fetchDatasetBatchViaRest: function(limit, offset, callback) {
|
||||
var self = this;
|
||||
if (self.noPagingMode && offset > 0) {
|
||||
callback(null, []);
|
||||
return;
|
||||
}
|
||||
|
||||
function readRows(resp) {
|
||||
if (resp && resp.content && resp.content.values) return resp.content.values;
|
||||
if (resp && resp.values) return resp.values;
|
||||
return [];
|
||||
}
|
||||
|
||||
function request(usePaging, done) {
|
||||
var constraints = usePaging ? self.buildRestPagingConstraints(limit, offset) : [];
|
||||
$.ajax({
|
||||
url: "/api/public/ecm/dataset/datasets",
|
||||
type: "POST",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
dataType: "json",
|
||||
data: JSON.stringify({
|
||||
name: self.datasetName,
|
||||
fields: [],
|
||||
constraints: constraints,
|
||||
order: []
|
||||
})
|
||||
}).done(function(resp) {
|
||||
done(null, readRows(resp) || []);
|
||||
}).fail(function(xhr) {
|
||||
var detail = xhr && (xhr.responseText || xhr.statusText || xhr.status);
|
||||
done(detail || "falha na API REST de datasets", []);
|
||||
});
|
||||
}
|
||||
|
||||
request(!self.noPagingMode, function(err, rows) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rows.length && offset === 0 && !self.noPagingMode) {
|
||||
request(false, function(err2, rows2) {
|
||||
if (err2) {
|
||||
callback(err2);
|
||||
return;
|
||||
}
|
||||
if (rows2.length) {
|
||||
self.noPagingMode = true;
|
||||
}
|
||||
callback(null, rows2 || []);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, rows || []);
|
||||
});
|
||||
},
|
||||
|
||||
buildRestPagingConstraints: function(limit, offset) {
|
||||
return [
|
||||
{ _field: "sqlLimit", _initialValue: String(limit), _finalValue: String(limit), _type: 1 },
|
||||
{ _field: "sqlStart", _initialValue: String(offset), _finalValue: String(offset), _type: 1 },
|
||||
{ _field: "offset", _initialValue: String(offset), _finalValue: String(offset), _type: 1 },
|
||||
{ _field: "sqlOffset", _initialValue: String(offset), _finalValue: String(offset), _type: 1 }
|
||||
];
|
||||
},
|
||||
|
||||
buildChunkMarker: function(row) {
|
||||
if (!row) return "";
|
||||
var id = this.pick(row, ["metadata#id", "id", "WKNumProces", "processInstanceId"]);
|
||||
var state = this.pick(row, ["activity", "WKNumState", "state"]);
|
||||
return (id || "-") + "|" + (state || "-");
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var rows = this.getFilteredRows(this.rowsCache);
|
||||
this.renderKpis(rows);
|
||||
this.renderStageBars(rows);
|
||||
this.renderTable(rows);
|
||||
this.renderUpdatedAt();
|
||||
},
|
||||
|
||||
getFilteredRows: function(rows) {
|
||||
var out = [];
|
||||
var search = $.trim(String(this.$widget.find("[data-role='search']").val() || "")).toLowerCase();
|
||||
var activityFilter = $.trim(String(this.$widget.find("[data-role='activityFilter']").val() || ""));
|
||||
|
||||
for (var i = 0; i < (rows || []).length; i++) {
|
||||
var row = rows[i] || {};
|
||||
var activityCode = this.getActivityCode(row);
|
||||
|
||||
if (activityFilter && activityCode !== activityFilter) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (search) {
|
||||
var base = this.extractRow(row);
|
||||
var blob = [
|
||||
base.processo,
|
||||
base.solicitante,
|
||||
base.origem,
|
||||
base.destino,
|
||||
base.dataAbertura,
|
||||
base.atividadeCode
|
||||
].join(" ").toLowerCase();
|
||||
|
||||
if (blob.indexOf(search) === -1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
out.push(row);
|
||||
}
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
renderKpis: function(rows) {
|
||||
var total = rows.length;
|
||||
var transit = this.countByActivities(rows, ["31", "57"]);
|
||||
var pendingReceipt = this.countByActivities(rows, ["18"]);
|
||||
var problem = this.countByActivities(rows, ["24", "104"]);
|
||||
var done = this.countByActivities(rows, ["96", "101"]);
|
||||
|
||||
this.$widget.find("[data-role='kpiTotal']").text(this.formatNumber(total));
|
||||
this.$widget.find("[data-role='kpiTransit']").text(this.formatNumber(transit));
|
||||
this.$widget.find("[data-role='kpiPendingReceipt']").text(this.formatNumber(pendingReceipt));
|
||||
this.$widget.find("[data-role='kpiProblem']").text(this.formatNumber(problem));
|
||||
this.$widget.find("[data-role='kpiDone']").text(this.formatNumber(done));
|
||||
},
|
||||
|
||||
renderStageBars: function(rows) {
|
||||
var total = rows.length;
|
||||
var html = [];
|
||||
|
||||
for (var i = 0; i < this.stageDefs.length; i++) {
|
||||
var stage = this.stageDefs[i];
|
||||
var count = this.countByActivities(rows, stage.activities);
|
||||
var percent = total > 0 ? ((count * 100) / total) : 0;
|
||||
|
||||
html.push(
|
||||
"<div class='wdtransf-stage-item'>" +
|
||||
"<span class='wdtransf-stage-label'>" + this.escapeHtml(stage.label) + "</span>" +
|
||||
"<div class='wdtransf-stage-bar-wrap'>" +
|
||||
"<div class='wdtransf-stage-bar' style='width:" + percent.toFixed(2) + "%;'></div>" +
|
||||
"</div>" +
|
||||
"<span class='wdtransf-stage-value'>" + this.formatNumber(count) + "</span>" +
|
||||
"</div>"
|
||||
);
|
||||
}
|
||||
|
||||
this.$widget.find("[data-role='stageBars']").html(html.join(""));
|
||||
},
|
||||
|
||||
renderTable: function(rows) {
|
||||
var html = [];
|
||||
var totalRows = rows.length;
|
||||
var totalPages = totalRows > 0 ? Math.ceil(totalRows / this.pageSize) : 1;
|
||||
|
||||
if (this.currentPage > totalPages) {
|
||||
this.currentPage = totalPages;
|
||||
}
|
||||
if (this.currentPage < 1) {
|
||||
this.currentPage = 1;
|
||||
}
|
||||
|
||||
var startIndex = totalRows > 0 ? ((this.currentPage - 1) * this.pageSize) : 0;
|
||||
var endIndex = totalRows > 0 ? Math.min(startIndex + this.pageSize, totalRows) : 0;
|
||||
var pageRows = rows.slice(startIndex, endIndex);
|
||||
|
||||
if (!totalRows) {
|
||||
var emptyMsg = this.isIncrementalLoading ?
|
||||
"Carregando dados..." :
|
||||
"Nenhum registro para os filtros informados.";
|
||||
html.push("<tr><td colspan='6'>" + this.escapeHtml(emptyMsg) + "</td></tr>");
|
||||
this.$widget.find("[data-role='tableBody']").html(html.join(""));
|
||||
this.renderPagination(0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < pageRows.length; i++) {
|
||||
var base = this.extractRow(pageRows[i]);
|
||||
html.push(
|
||||
"<tr>" +
|
||||
"<td>" + this.escapeHtml(base.processo) + "</td>" +
|
||||
"<td>" + this.escapeHtml(base.solicitante) + "</td>" +
|
||||
"<td>" + this.escapeHtml(base.origem) + "</td>" +
|
||||
"<td>" + this.escapeHtml(base.destino) + "</td>" +
|
||||
"<td>" + this.escapeHtml(base.dataAbertura) + "</td>" +
|
||||
"<td>" + this.escapeHtml(base.atividadeCode) + "</td>" +
|
||||
"</tr>"
|
||||
);
|
||||
}
|
||||
|
||||
this.$widget.find("[data-role='tableBody']").html(html.join(""));
|
||||
this.renderPagination(totalRows, totalPages, startIndex + 1, endIndex);
|
||||
},
|
||||
|
||||
renderPagination: function(totalRows, totalPages, firstRow, lastRow) {
|
||||
var info = "Exibindo " + this.formatNumber(firstRow) + "-" + this.formatNumber(lastRow) +
|
||||
" de " + this.formatNumber(totalRows);
|
||||
if (totalRows === 0) {
|
||||
info = "Exibindo 0-0 de 0";
|
||||
}
|
||||
|
||||
this.$widget.find("[data-role='pageInfo']").text(info);
|
||||
this.$widget.find("[data-role='pageStatus']").text(
|
||||
"Pagina " + this.formatNumber(this.currentPage) + " de " +
|
||||
this.formatNumber(totalPages || 1) +
|
||||
(this.isIncrementalLoading ? " (carregando...)" : "")
|
||||
);
|
||||
|
||||
var disablePrev = (this.currentPage <= 1 || totalRows === 0);
|
||||
var disableNext = (this.currentPage >= (totalPages || 1) && !this.isIncrementalLoading) || totalRows === 0;
|
||||
this.$widget.find("[data-action='prevPage']").prop("disabled", disablePrev);
|
||||
this.$widget.find("[data-action='nextPage']").prop("disabled", disableNext);
|
||||
},
|
||||
|
||||
setPage: function(page) {
|
||||
var n = parseInt(page, 10);
|
||||
if (isNaN(n)) return;
|
||||
if (n < 1) n = 1;
|
||||
var totalPages = Math.ceil(this.getFilteredRows(this.rowsCache).length / this.pageSize) || 1;
|
||||
if (n > totalPages) {
|
||||
if (this.isIncrementalLoading) {
|
||||
this.setMessage("Aguarde: ainda carregando mais registros...", "info");
|
||||
return;
|
||||
}
|
||||
n = totalPages;
|
||||
}
|
||||
this.currentPage = n;
|
||||
this.render();
|
||||
},
|
||||
|
||||
extractRow: function(row) {
|
||||
var activityCode = this.getActivityCode(row);
|
||||
var solicitante = this.pick(row, ["requesterName"]) || "-";
|
||||
var origem = this.pick(row, ["ufOrigem"]) || "-";
|
||||
var destino = this.pick(row, ["ufDestino"]) || "-";
|
||||
return {
|
||||
processo: this.pick(row, ["WKNumProces"]) || "-",
|
||||
solicitante: solicitante,
|
||||
origem: origem,
|
||||
destino: destino,
|
||||
dataAbertura: this.formatDate(this.pick(row, ["dataAbertura"])) || "-",
|
||||
atividadeCode: activityCode || "-",
|
||||
atividadeLabel: this.getActivityLabel(activityCode)
|
||||
};
|
||||
},
|
||||
|
||||
getActivityCode: function(row) {
|
||||
var raw = this.pick(row, ["Activity", "activity", "WKNumState", "state", "statusAtividade"]);
|
||||
var text = $.trim(String(raw || ""));
|
||||
if (!text) return "";
|
||||
var parsed = parseInt(text, 10);
|
||||
return isNaN(parsed) ? text : String(parsed);
|
||||
},
|
||||
|
||||
getActivityLabel: function(code) {
|
||||
var map = {
|
||||
"0": "Solicitacao",
|
||||
"1": "Solicitacao",
|
||||
"4": "Aprovacao",
|
||||
"6": "Emissao NFe",
|
||||
"18": "Recebimento",
|
||||
"24": "Verificar Problema",
|
||||
"31": "Coleta",
|
||||
"39": "Cancelada",
|
||||
"57": "Entrega",
|
||||
"60": "Cancelada",
|
||||
"99": "Consultar Entrada",
|
||||
"96": "Finalizada",
|
||||
"101": "Finalizada",
|
||||
"104": "Problema de Lancamento"
|
||||
};
|
||||
|
||||
return map[String(code || "")] || "Nao mapeada";
|
||||
},
|
||||
|
||||
countByActivities: function(rows, activities) {
|
||||
var set = {};
|
||||
for (var i = 0; i < activities.length; i++) {
|
||||
set[String(activities[i])] = true;
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
for (var j = 0; j < rows.length; j++) {
|
||||
var code = this.getActivityCode(rows[j]);
|
||||
if (set[String(code)]) count++;
|
||||
}
|
||||
return count;
|
||||
},
|
||||
|
||||
pick: function(row, keys) {
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var value = row[keys[i]];
|
||||
if (value !== null && value !== undefined && String(value).trim() !== "") {
|
||||
return String(value).trim();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
||||
formatDate: function(value) {
|
||||
var text = $.trim(String(value || ""));
|
||||
if (!text) return "";
|
||||
|
||||
var iso = /^(\d{4})-(\d{2})-(\d{2})/.exec(text);
|
||||
if (iso) {
|
||||
return iso[3] + "/" + iso[2] + "/" + iso[1];
|
||||
}
|
||||
return text;
|
||||
},
|
||||
|
||||
formatNumber: function(value) {
|
||||
var n = Number(value || 0);
|
||||
if (isNaN(n)) return "0";
|
||||
return n.toLocaleString("pt-BR");
|
||||
},
|
||||
|
||||
renderUpdatedAt: function() {
|
||||
var now = new Date();
|
||||
var stamp = now.toLocaleDateString("pt-BR") + " " + now.toLocaleTimeString("pt-BR");
|
||||
this.$widget.find("[data-role='updatedAt']").text("Atualizado em: " + stamp);
|
||||
},
|
||||
|
||||
setLoading: function(isLoading) {
|
||||
this.$widget.toggleClass("is-loading", !!isLoading);
|
||||
if (isLoading) {
|
||||
this.setMessage("Carregando dados...", "info");
|
||||
}
|
||||
},
|
||||
|
||||
setMessage: function(text, type) {
|
||||
var $msg = this.$widget.find("[data-role='message']");
|
||||
$msg.removeClass("is-info is-success is-warning is-danger");
|
||||
|
||||
if (!text) {
|
||||
$msg.hide().text("");
|
||||
return;
|
||||
}
|
||||
|
||||
var className = "is-info";
|
||||
if (type === "success") className = "is-success";
|
||||
if (type === "warning") className = "is-warning";
|
||||
if (type === "danger") className = "is-danger";
|
||||
|
||||
$msg.addClass(className).text(text).show();
|
||||
},
|
||||
|
||||
escapeHtml: function(text) {
|
||||
return String(text == null ? "" : text)
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user