(function () { 'use strict'; app.IndexCtrl = IndexCtrl; angular.module('app.controller').controller('IndexCtrl', IndexCtrl); IndexCtrl.$inject = ['$location', '$rootScope', '$scope', '$controller', 'cfg', 'searchBridge', 'query', 'attribute']; function IndexCtrl($location, $rootScope, $scope, $controller, cfg, searchBridge, query, attribute) { cfg.debug && console.log('IndexCtrl'); angular.extend(this, $controller('AbstractDirectiveController', {$scope: $scope})); this.bridge = searchBridge; var self = this; var locationSearch; $scope.attribute = attribute; $scope.form = { /** * @type {{pageCount: Number, currentPageIndex: Number}} */ pagination: {pageCount: 0, currentPageIndex: 0}, sortAttributeId: undefined, /** * * @type {Object.} ex. {tagId: Boolean, ...} */ tag: {}, /** * @type {Object.} ex. {tagId: {}, ...} */ attr: {}, /** * * @type {Object.} ex. {groupId: Boolean, ...} */ more: {}, /** * * @type {Object.} ex. {groupId: Boolean, ...} */ headMore: {} }; /** * @type {Object.} ex. {typeCode: tagGroup, ...} */ $scope.originalTags = {}; /** * @type {Array.} ex. ["9", "24"] */ $scope.localityTagIds = []; /** * @type {Object.} ex. {typeCode: tagList, ...} */ var filteredTagCache = {}; $scope.linkBusy = { tag: false }; var getLocationSearch = function () { var search; try { search = _.reduce($location.search(), function (search, value, key) { return (search ? search + '&' : '') + key + '=' + value; }, ''); search = query.decode(search); } catch (e) { search = {}; } return prepareSearch(search); }; var prepareSearch = function (search) { var search = angular.extend({}, search); var result = { client: angular.extend({}, search), server: { tagList: search, sortAttributeId: (null == search.sr) ? null : search.sr } }; delete result.server.tagList.sr; delete result.server.tagList.pg; return result; }; var onLocationChange = function () { var search = getLocationSearch(); cfg.debug && console.log('IndexCtrl.onLocationChange ', search); if ('/' === $location.path() && !angular.equals(locationSearch.server, search.server)) { cfg.debug && console.log('IndexCtrl.onLocationChange load', search); locationSearch = search; refresh(); } }; var refresh = function () { cfg.debug && console.log('IndexCtrl.refresh ', locationSearch); $scope.linkBusy.tag = true; self.action('tagList', locationSearch.server.tagList, locationSearch.server.sortAttributeId).then(function (response) { $scope.linkBusy.tag = false; $scope.originalTags = _.indexBy(response.data.tags, 'typeCode'); $scope.data = response.data; $scope.data.originalTicketList = $scope.data.tickets || []; $scope.data.tickets = []; $scope.form.sortAttributeId = (null == response.data.sortAttributeId) ? null : parseInt(response.data.sortAttributeId, 10); $scope.form.pagination.pageCount = ($scope.data && $scope.data.originalTicketList) ? Math.ceil($scope.data.originalTicketList.length / 10) : 0; $scope.form.pagination.currentPageIndex = (locationSearch.client.pg > 0 && locationSearch.client.pg < $scope.form.pagination.currentPageIndex) ? locationSearch.client.pg : 0; filteredTagCache = {}; prepareTagList($scope.data.tags); prepareTicketList($scope.data.originalTicketList); $scope.paginationChange(); var search = formTags2Search(); if (!angular.equals(locationSearch.server, search.server)) { cfg.debug && console.log('IndexCtrl.refresh reload', search); $location.search(query.encode(search.client)); } }, function () { $scope.linkBusy.tag = false; $scope.data = {}; }); }; var prepareTagList = function (tagList) { $scope.data.localityTag = null; $scope.data.collapsedTags = []; $scope.data.tags = []; $scope.form.tag = {}; var leftGroupIdx = 0; angular.forEach(tagList, function (group) { group.showCollapsed = false; angular.forEach(group.list, function (tag) { var loValue, hiValue, typeCode; if (tag.selected && 'y' === tag.collapsed) { group.showCollapsed = true; } if (null == tag.dataType) { $scope.form.tag[tag.id] = !!tag.selected; } else { if ('numeric' === tag.dataType) { typeCode = 'n'; loValue = tag.valueLowNumeric; hiValue = tag.valueHighNumeric; } else if ('datetime' === tag.dataType) { typeCode = 'd'; loValue = tag.valueLowDatetime; hiValue = tag.valueHighDatetime; } $scope.form.attr[tag.id] = { tag: tag, tp: typeCode, lo: attribute.toNative(tag, loValue), hi: attribute.toNative(tag, hiValue) }; } }); if ('locality' === group.typeCode) { $scope.localityTagIds = _.pluck(group.list, 'id'); } if (group.showCollapsed) { $scope.data.collapsedTags.push(group); } else if ('locality' === group.typeCode) { $scope.data.localityTag = group; } else { $scope.data.tags.push(group); if (leftGroupIdx < 3 && !(group.typeCode in $scope.form.headMore)) { $scope.form.headMore[group.typeCode] = true; } ++leftGroupIdx; } }); }; var prepareTicketList = function (ticketList) { angular.forEach(ticketList, function (ticket) { ticket.typeCode2Group = {}; ticket.attributeCode2Tag = {}; angular.forEach(ticket.tags, function (group) { ticket.typeCode2Group[group.typeCode] = group; angular.forEach(group.list, function (tag) { if (tag.attributeCode) ticket.attributeCode2Tag[tag.attributeCode] = tag; }); }); ticket.mainTagsJoined = _.reduce(['rootgeo', 'estatetype', 'submissiontype'], function (str, type) { if (ticket.typeCode2Group[type]) { return (str ? str + ', ' : '') + $scope.joinTagNames(ticket.typeCode2Group[type].list); } return str; }, ''); }); }; var unbindList = []; unbindList.push($rootScope.$on('$locationChangeSuccess', onLocationChange)); $scope.onLocalityChange = function (type, tagId, value) { // uncheck other localities _.forOwn($scope.localityTagIds, function (id) { $scope.form.tag[id] = (id == tagId); }); $scope.onLinkChange(type, tagId, value); }; $scope.onLinkChange = function (type, tagId, value) { cfg.debug && console.log('IndexCtrl.onLinkChange', type, tagId, value); $scope.form.pagination.currentPageIndex = 0; var search = formTags2Search(); if (!angular.equals(locationSearch, search)) { $location.search(query.encode(search.client)); } }; $scope.onSortChange = function (attributeId) { cfg.debug && console.log('IndexCtrl.onSortChange', attributeId); $scope.form.sortAttributeId = parseInt(attributeId, 10); var search = formTags2Search(); if (!angular.equals(locationSearch, search)) { $location.search(query.encode(search.client)); } }; $scope.onGroupClick = function (group) { $scope.form.headMore[group.typeCode] = !$scope.form.headMore[group.typeCode]; }; /** * * @param {Array} input * @param {Object.<{typeCode: String, list: Array}>} group * @return {*} */ $scope.tagListFilter = function (input, group) { // return original group if more button has been pressed if ($scope.form.more[group.typeCode]) { return $scope.originalTags[group.typeCode].list; } // return group with filtered list of tags if (filteredTagCache[group.typeCode]) { return filteredTagCache[group.typeCode]; } // filter selected tags and some unselected fo fit 7 var i, length, resultLen = 0, result = []; var selectedCount = 0, nonSelectedLen = 0, nonSelectedAllow; if (group.list.length > 7) { for (i = 0, length = group.list.length; i < length; ++i) { if (group.list[i].selected) { ++selectedCount; } } nonSelectedAllow = 7 - selectedCount; for (i = 0, length = group.list.length; i < length && resultLen < 7; ++i) { if (group.list[i].selected) { result.push(group.list[i]); ++resultLen; } else if (nonSelectedLen < nonSelectedAllow) { result.push(group.list[i]); ++nonSelectedLen; ++resultLen; } } } else { result = group.list; } filteredTagCache[group.typeCode] = result; return result; }; $scope.onMoreClick = function (typeCode) { $scope.form.more[typeCode] = !$scope.form.more[typeCode]; }; var formTags2Search = function () { var search = {}; angular.forEach($scope.form.tag, function (value, id) { if (false !== value) { search[id] = value; } }); angular.forEach($scope.form.attr, function (value, id) { if (null != value && (null != value.lo || null != value.hi)) { search[id] = {tp: value.tp, lo: attribute.toAPI(value.tag, value.lo), hi: attribute.toAPI(value.tag, value.hi)}; } }); if ($scope.form.pagination) { search.pg = +$scope.form.pagination.currentPageIndex || 0 ; } if ($scope.form.sortAttributeId) { search.sr = $scope.form.sortAttributeId; } return prepareSearch(search); }; $scope.patternFloat = /^-?\d+(?:\.\d+)?$/; $scope.joinTagNames = function (list) { return _.pluck(list, 'name').join(', '); }; $scope.paginationChange = function () { cfg.debug && console.log('IndexCtrl.paginationChange'); var pageIdx = $scope.form.pagination.currentPageIndex || 0; $scope.data.tickets = $scope.data.originalTicketList.slice(pageIdx * 10, pageIdx * 10 + 10); $location.search('pg', pageIdx); }; $scope.$on('$destroy', function () { cfg.debug && console.log('IndexCtrl.$destroy'); angular.forEach(unbindList, function (fn) { fn(); }); }); locationSearch = getLocationSearch(); refresh(); } })();