/**
* @ngdoc directives
* @name Incidentes
* @module s4c.directives.incidentes.incidentes
*
* @description
* `s4c-incidentes` exibe informações sobre incidentes inseridos no Fusion
*
*@example
* <s4c-incidentes></s4c-incidentes>
*
*/
(function () {
'use strict';
angular.module('s4c.components.incidentes')
.directive('s4cIncidentes', s4cIncidentes)
.filter('filtroAgencias', function () {
return function (agencias) {
if (!agencias || agencias.length <= 0) {
return '-';
} else {
var _agencias = _.chain(agencias)
.filter(function (agencia) {
return agencia.ativo;
})
.map('nome')
.value();
if (_agencias.length > 0) {
return _agencias.join(', ');
} else {
return '-';
}
}
};
})
.filter('filtroPrioridades', function () {
return function (prioridades) {
if (prioridades.length <= 0) {
return '-';
} else {
return prioridades.join(', ');
}
};
})
.filter('filtroOrigem', function () {
return function (items, filters) {
if (!filters) {
return items;
}
return _.filter(items, function (incidente) {
if (!incidente.extras) {
return false;
}
var categoriasPermitidas = _.chain(filters.categorias)
.filter(function (categoria) {
return categoria.ativo;
})
.map('id')
.value();
if (categoriasPermitidas.indexOf(incidente.CategoriaIncidenteId) < 0) {
return false;
}
if (incidente.extras.informacoes) {
// Encontrando prioridade:
var prioridade = _.find(incidente.extras.informacoes, function (informacao) {
return informacao.label === 'Prioridade';
});
var criticidade = _.find(incidente.extras.informaceos, function (informacao) {
return informacao.label === 'Criticidade';
});
if (prioridade) {
return filters.prioridades.indexOf(prioridade.valor) > -1;
}
if (criticidade) {
return filters.criticidades.indexOf(criticidade.valor) > -1;
}
}
return false;
});
};
});
incidentesCtrl.$inject = [
'$scope',
'$timeout',
'IncidentesService',
'CommService',
'IncidenteFilter',
'CamadasService',
'MainState',
'IncidentesManager',
'AuthService',
'DetalhamentoManager',
'localize',
'$rootScope'
];
function s4cIncidentes() {
return {
restrict: 'AE',
templateUrl: 'app/directives/incidentes/incidentes.html',
controller: incidentesCtrl,
transclude: true,
scope: {
filters: '=data'
},
link: function ($scope, $elem, $attrs) {
$scope.incidentes = [];
}
};
}
function incidentesCtrl($scope,
$timeout,
IncidentesService,
CommService,
IncidenteFilter,
CamadasService,
MainState,
IncidentesManager,
AuthService,
DetalhamentoManager,
localize,
$rootScope) {
$scope.res = $rootScope.res;
var filterInstance = IncidenteFilter.getInstance('filtro-incidentes');
filterInstance.pagination = {
limit: 5000,
offset: 0,
end: false,
nextPage: function () {
this.offset += this.limit;
return this.begin;
},
reset: function () {
this.offset = 0;
this.end = false;
},
showMore: function () {
this.nextPage();
filterInstance.trigger('filterChanged', filterInstance.origem);
}
};
$scope.showMore = function () {
if (!filterInstance.pagination.end) {
filterInstance.pagination.showMore();
}
}
$scope.incidentes = [];
$scope.pegarCameras = pegarCameras;
$scope.IncidentesManager = IncidentesManager;
/**
* Listener para aplicação da inclusão de incidente na lista de incidentes disparados de outros componentes
*
* @method incidentes_
*
* @param incidente {Object}
*
*/
CommService.on('incidentes_', function (incidente) {
var incidenteAntigo = _obterIncidente(incidente);
if (incidenteAntigo) {
$scope.$apply(function () {
if (_filtrarIncidente(incidente)) {
_.chain(incidente)
.keys()
.each(function (key) {
incidenteAntigo[key] = incidente[key];
})
.value()
parseIncidente(incidenteAntigo);
// Camadas Already do this
// CamadasService.atualizarIconeIncidente(incidente);
} else {
$scope.incidentes = [];
}
});
} else {
if (_filtrarIncidente(incidente)) {
$scope.$apply(function () {
$scope.incidentes.push(parseIncidente(incidente));
});
}
}
DetalhamentoManager.fechar();
});
/**
* Listener para aplicação da remoção de incidente da lista de incidentes disparados de outros componentes
*
* @method removeIncidentes_
*
* @param incidente {Object}
*
*/
CommService.on('removeIncidentes_', function (incidente) {
var incidenteAntigo = _obterIncidente(incidente);
if (incidenteAntigo) {
$scope.$apply(function () {
$scope.incidentes.splice($scope.incidentes.indexOf(incidenteAntigo), 1);
DetalhamentoManager.fechar();
});
}
});
/**
* Listener para aplicação da atualização da lista de incidentes disparados de outros componentes
*
* @method filterChanged
*
*/
IncidenteFilter.getInstance('filtro-incidentes').on('filterChanged', _reloadIncidentes);
/**
* Listener para aplicação do filtro disparados de outros componentes
*
* @method filterChangedMenu
*
* @param array {Array}
*
*/
IncidenteFilter.getInstance('filtro-incidentes').on('filterChangedMenu', function (array) {
var incidentes = null;
var menu = null;
var incidentesList_ = null;
var incidentesAntigos = [];
if (array != null) {
incidentes = array[0];
menu = array[1];
if (incidentes != null && incidentes.length > 0) {
incidentesList_ = $scope.incidentes.concat(incidentes);
} else {
incidentesList_ = $scope.incidentes;
}
}
if (incidentesList_ != null && incidentesList_.length > 0) {
_.each(menu.parentNode.subMenus, function (subMenu) {
if (subMenu.ativo) {
_.each(incidentesList_, function (incidenteLocal) {
if (incidenteLocal.CategoriaIncidenteId == subMenu.categoriaIncidenteId && incidenteLocal.status == subMenu.parentNode.texto) {
incidentesAntigos.push(incidenteLocal);
}
});
}
});
}
if (incidentesAntigos.length == 0 || incidentesAntigos == null) {
filterInstance.pagination.reset();
$scope.incidentes = [];
} else {
filterInstance.pagination.reset();
$scope.incidentes = incidentesAntigos;
}
var novosIncidentes = incidentes;
var incidentesList = null;
if (novosIncidentes != null) {
incidentesList = $scope.incidentes.concat(novosIncidentes);
}
if (novosIncidentes != null && novosIncidentes.length < filterInstance.pagination.limit) {
filterInstance.pagination.end = true;
}
if (incidentesList != null) {
$scope.incidentes = _filterAfterQuery(incidentesList);
}
$scope.nothingFound = (!$scope.incidentes.length);
});
$scope.voarIncidente = function (incidente) {
if (typeof incidente.geojson === 'string') {
incidente.geojson = JSON.parse(incidente.geojson);
}
var point = {
lat: incidente.geojson.coordinates[1],
lng: incidente.geojson.coordinates[0]
};
$scope.pegarCameras(point);
//MainState.managers.MapaManager.voarParaObjeto(incidente);
MainState.managers.MapaManager.piscarVermelho(point);
if (incidente.Poi) {
CamadasService.ativarMenuPoi(incidente.Poi);
} else {
CamadasService.ativarMenuDoIncidente(incidente)
}
};
/**
* Aplica o filtro
*
* @method _filtrarIncidente
*
* @param incidente {Object}
*
*/
function _filtrarIncidente(incidente) {
return IncidenteFilter.getInstance('filtro-incidentes').filtrarIncidente(incidente);
}
/**
* Busca as câmeras próximas ao Incidente
*
* @method pegarCameras
*
* @param ponto {Object}
*
*/
function pegarCameras(ponto) {
IncidentesService
.pegarCamerasProximas(ponto)
.then(function (data) {
if (data.length) {
MainState.managers.IncidentesManager.abrirMosaicoCameras(ponto, data);
}
$scope.camerasProximas = data;
});
}
/**
* Busca Incidente com a chave estrangeira como parâmetro
*
* @method _obterIncidente
*
* @param incidente {Object}
*
* @returns Retorna os Incidentes encontrados
*/
function _obterIncidente(incidente) {
return _.find($scope.incidentes, { chave_estrangeira: incidente.chave_estrangeira });
}
/**
* Atualiza o mapa carregando os novos incidentes
*
* @method _updateCamadasService
*
*/
function _updateCamadasService() {
var filterData = _getFilterData();
var categorias = filterData.categorias;
var statuses = filterData.statuses;
var itensParaDesativar = [];
_.each(categorias, function (categoria) {
_.each(statuses, function (status) {
if (status.ativo && categoria.ativo) {
CamadasService.ativarSubMenuStatusIncidente(categoria.id, status.nome);
} else {
itensParaDesativar.push({
categoriaId: categoria.id,
status: status.nome
});
}
});
});
_.each(itensParaDesativar, function (item) {
CamadasService.desativarSubMenuStatusIncidente(item.categoriaId, item.status, {
origem: 'filtro'
});
});
}
/**
* Retorna os Incidentes com status ativo
*
* @method _filtrarAtivos
*
* @param dataArr {Array} Lista de Incidentes
* @param filterString {String}
*
* @returns Retorna os Incidentes com status ativo
*/
function _filtrarAtivos(dataArr, filterString) {
return _.chain(dataArr)
.filter('ativo')
.map(filterString)
.value();
}
/**
* Aplica o filtro de Gravidades de Incidentes
*
* @method _setQueryGravidadeIncidenteId
*
* @param gravidades {Object}
*
* @returns retorna os Incidentes com o filtro de Gravidades de Incidentes aplicados
*/
function _setQueryGravidadeIncidenteId(gravidades) {
var ativos = _filtrarAtivos(gravidades, 'id');
return (ativos.length) ? { $in: ativos } : null;
}
/**
* Aplica o filtro de tipo de incidentes
*
* @method _setQueryTipoIncidenteId
*
* @param tipoIncidentes {Object}
*
* @returns retorna os Incidentes com o filtro de tipos de incidentes aplicados
*/
function _setQueryTipoIncidenteId(tipoIncidentes) {
var ativos = _filtrarAtivos(tipoIncidentes, 'id');
return (ativos.length) ? { $in: ativos } : null;
}
/**
* Inclui data de início e fim
*
* @method _setQueryTimeWindow
*
* @param timeWindow {Date}
*
* @returns retorna as datas parametrizados no formato de query
*/
function _setQueryTimeWindow(timeWindow) {
return {
$between: [
timeWindow.start,
timeWindow.end
]
};
}
/* Statuses: 1. Aberto 2. Fechado 3. Aberto 24h */
/**
* Inclui os status no objeto que serve de query
* Statuses: 1. Aberto 2. Fechado 3. Aberto 24h
*
* @method _setQueryStatus
*
* @param statuses {String}
*
* @returns retorna os status parametrizados no formato de query
*/
function _setQueryStatus(statuses) {
return { $in: statuses };
}
/**
* Seta os status em um array que será retornado
*
* @method _setStatuses
*
* @param _setStatuses {String}
*
* @returns retorna os status
*/
function _setStatuses(statuses) {
if (statuses.length) {
var arrFilter = [];
if (statuses.indexOf(1) > -1 || statuses.indexOf(3) > -1) {
arrFilter.push("ABERTO");
}
if (statuses.indexOf(2) > -1) {
arrFilter.push("FECHADO");
}
return arrFilter;
} else {
return ["ABERTO"];
}
}
/**
* Retorna os campos de data de início e fim
*
* @method _setQueryCategoria
*
* @param timeWindow {Object}
*
* @returns Retorna os campos de data de início e fim
*/
function _setTimeWindow(timeWindow) {
var newTimeWindow = {
start: timeWindow.start,
end: timeWindow.end
};
newTimeWindow.start = moment(newTimeWindow.start).format();
newTimeWindow.end = moment(newTimeWindow.end).format();
return newTimeWindow;
}
/**
* Aplicação dos filtros de categoria
*
* @method _setQueryCategoria
*
* @param categorias {Object}
*
* @returns retorna os Incidentes com o filtro de Categorias aplicados
*/
function _setQueryCategoria(categorias) {
if (categorias.length) {
return { $in: _filtrarAtivos(categorias, 'id') };
}
return;
}
/**
* Formatação do Objeto que será passado para o backend para aplicação do Filtro
*
* @method setQuery
*
* @returns Objeto com os parâmetros que serão usados para aplicação do filtro
*
*/
function setQuery() {
var filterData = _getFilterData();
var data = {};
var timeWindow = _setTimeWindow(filterData.timeWindow);
var statuses = _setStatuses(_filtrarAtivos(filterData.statuses, 'id'));
data.status = _setQueryStatus(statuses);
data.CategoriaIncidenteId = _setQueryCategoria(filterData.categorias);
data.GravidadeIncidenteId = _setQueryGravidadeIncidenteId(filterData.gravidades);
data.TipoIncidenteId = _setQueryTipoIncidenteId(filterData.tipoIncidentes);
data.inicio = _setQueryTimeWindow(timeWindow);
// Deletes invalid filters
for (var filtro in data) {
if (data.hasOwnProperty(filtro) && (data[filtro] === null) || data[filtro] === undefined) {
delete data[filtro];
}
}
return {
where: data,
include: {
model: 'GrupoUsuarios',
'as': 'GruposUsuarios',
include: {
model: 'Usuario'
},
where: {
id: {
$in: _.chain(filterData.gruposUSuarios)
.filter('ativo')
.map('id')
.value()
}
}
},
order: 'inicio DESC',
limit: filterInstance.pagination.limit,
offset: filterInstance.pagination.offset
};
};
/**
* Retorna os campos do filtro
*
* @method _getFilterData
*
* @returns Retorna os campos do filtro
*
*/
function _getFilterData() {
return {
categorias: IncidenteFilter.getInstance('filtro-incidentes').categorias,
gruposUsuarios: IncidenteFilter.getInstance('filtro-incidentes').gruposUsuarios,
tipoIncidentes: IncidenteFilter.getInstance('filtro-incidentes').tipoIncidentes,
statuses: IncidenteFilter.getInstance('filtro-incidentes').statuses,
gravidades: IncidenteFilter.getInstance('filtro-incidentes').gravidades,
timeWindow: IncidenteFilter.getInstance('filtro-incidentes').dataRange
};
}
/**
* Verifica se o menuCamada já está carregado
*
* @method verificaMenuCarregado
*
*/
function verificaMenuCarregado() {
if (!CamadasService.isLoaded) {
setTimeout(function () {
verificaMenuCarregado();
}, 1000);
} else {
_updateCamadasService();
}
}
/**
* Recarrega a lista de Incidentes
*
* @method _reloadIncidentes
*
* @param origem {Object}
*
*
*/
function _reloadIncidentes(origem) {
if (origem === 'filtro') {
filterInstance.pagination.reset();
$scope.incidentes = [];
}
var query = setQuery();
verificaMenuCarregado();
IncidentesService.findByFilter(query)
.then(function (incidentes) {
var novosIncidentes = incidentes;
var incidentesList = $scope.incidentes.concat(novosIncidentes);
if (novosIncidentes.length < filterInstance.pagination.limit) {
filterInstance.pagination.end = true;
}
$scope.incidentes = _filterAfterQuery(incidentesList);
if ($scope.incidentes != null && $scope.incidentes.length > 0) {
$scope.nothingFound = true;
} else {
$scope.nothingFound = false;
}
});
}
/**
* Filtra os Incidentes pela prioridade
*
* @method _filterAfterQuery
*
* @param incidentes {Object}
*
*
*/
function _filterAfterQuery(incidentes) {
var newIncidentes = _.chain(incidentes).map(parseIncidente).value();
newIncidentes = _filterAberto24h(incidentes);
newIncidentes.forEach(function (obj, index) {
if (obj.extras != null && obj.extras.informacoes != null) {
var prioridade = obj.extras.informacoes.filter(function (item, i) {
if (item.label === 'Prioridade') {
delete obj.extras.informacoes[i];
}
});
}
});
return newIncidentes;
}
//
/**
* Filtra os Incidentes pelo Status
* 1. Aberto 2. Fechado 3. Aberto 24h
*
* @method _formatDataIncidenteToString
*
* @param dataInicio {Object}
* @param dataFim {Object}
*
*/
function _filterAberto24h(incidentes) {
var filterData = _getFilterData();
var statuses = _filtrarAtivos(filterData.statuses, 'id');
var timeWindow = _setTimeWindow(filterData.timeWindow, statuses);
var newIncidentes = incidentes.filter(function (incidente) {
if (!statuses.length) return incidente;
if (incidente.status === 'ABERTO' && statuses.indexOf(1) === -1) {
if (incidente.inicio.isBefore(moment(timeWindow.start))) {
return incidente;
}
} else {
return incidente;
}
});
return newIncidentes;
}
/**
* Faz a formatação da data
*
* @method _formatDataIncidenteToString
*
* @param dataInicio {Object}
* @param dataFim {Object}
*
*/
function _formatDataIncidenteToString(dataInicio, dataFim) {
var dataString = '';
/* Início do incidente menor que a data do Fim */
if (dataInicio.dayOfYear() < dataFim.dayOfYear()) {
dataString = dataInicio.format('HH:mm');
dataString += dataInicio.format(' (MMM D)');
dataString += ' - ';
dataString += dataFim.format('HH:mm');
dataString += dataFim.format(' (MMM D)');
}
/* Início do incidente igual a data do Fim */
if (dataInicio.dayOfYear() === dataFim.dayOfYear()) {
dataString = dataInicio.format('HH:mm');
dataString += ' - ';
dataString += dataFim.format('HH:mm');
}
return dataString;
}
/**
* Faz o parse do Incidente
*
* @method parseIncidente
*
* @param incidente {Object}
*
*/
function parseIncidente(incidente) {
var data = '';
var icons = {
green: '/data-s4c/teste/ic_incidentes_green_26px.svg',
red: '/data-s4c/teste/ic_incidentes_grey_26px.svg',
purple: '/data-s4c/teste/ic_incidentes_purple_24px.svg'
};
incidente.icon = icons.green; // Default icon
/* Formata o Início e o Fim */
if (incidente.inicio) {
incidente.inicio = moment(moment(incidente.inicio).toDate());
}
if (incidente.fim) {
incidente.fim = moment(moment(incidente.fim).toDate());
}
if (incidente.inicio && incidente.fim) {
data = _formatDataIncidenteToString(incidente.inicio, incidente.fim);
}
var gravidades = IncidenteFilter.getInstance('filtro-incidentes').gravidades;
incidente.gravidade = _.find(gravidades, { id: incidente.GravidadeIncidenteId });
if (incidente.status === 'ABERTO') {
incidente.icon = icons.red;
if (incidente.inicio) {
data = incidente.inicio.format('DD/MM/YYYY - HH:mm');
//if (moment().dayOfYear() > incidente.inicio.dayOfYear()) {
// data += incidente.inicio.format(' (MMM D)');
//}
}
if (incidente.inicio.dayOfYear() < moment().dayOfYear()) {
incidente.icon = icons.purple;
incidente.urlIcone = incidente.urlIcone.replace('vermelho', 'purple');
}
}
if (incidente.status === 'FECHADO') {
incidente.urlIcone = incidente.urlIconeFechado || (incidente.TipoIncidente && incidente.TipoIncidente.urlIconeFechado) || incidente.CategoriaIncidente.urlIconeFechado;
if (incidente.fim && incidente.inicio) {
if (moment().dayOfYear() > incidente.fim.dayOfYear()) {
incidente.icon = icons.purple;
incidente.urlIcone = incidente.urlIcone.replace('vermelho', 'purple');
}
}
}
incidente.data = data;
return incidente;
}
/**
* Recarrega a lista de Incidentes
*
* @method initFilter
*
*/
function refreshIncidentes() {
_reloadIncidentes('filtro');
}
/**
* Formata a data de inicio e fim. Para que as datas sejam sempre de as 00:00 de ontem até as 23:59 de hoje
*
* @method _timeSet
*
*
*/
function _timeSet() {
return {
start: moment().subtract(1, 'day').startOf('day').format(),
end: moment().endOf('day').format()
}
};
/**
* Inicializa o filtro
*
* @method initFilter
*
*/
function initFilter() {
IncidenteFilter.getInstance('filtro-incidentes').dataRange = _timeSet();
}
MainState.registerDirective('incidentes', {
refreshIncidentes: refreshIncidentes,
setQuery: setQuery,
initFilter: initFilter
});
//$timeout(function() {
//IncidenteFilter.getInstance('filtro-incidentes').trigger('filterChanged');
//$scope.incidentes = IncidentesService.incidentes;
refreshIncidentes();
//}, 100);
}
}());