(function () { "use strict"; var name = 'adTicketForm'; angular.module('app.directive') .directive('adTicketForm', ['$q', '$timeout', '$state', '$filter', 'tool', 'cfg', 'staticData', 'notification', 'mapHelper', 'adminTicketBridge', 'ticket', 'user', function ($q, $timeout, $state, $filter, tool, cfg, staticData, notification, mapHelper, adminTicketBridge, ticket, user) { return { templateUrl: 'directive/' + name + '/' + name + '.html', scope: {}, controller: 'BaseFormController', link: function (scope, element, attributes, controller) { cfg.debug && console.log(name); scope.devMode = user.roleId; var bridge = controller.bridge = ('admin' === scope.devMode || 'manager' === scope.devMode) ? adminTicketBridge : ticket; /** * @type {TicketFullInfo} */ scope.data = null; scope.tmp = {}; scope.form = { map: { longitude: '', latitude: '' }, link: { user: null, geo: null, tag: {}, geoTag: {} }, /** * * @type {Object.} ex. {headId: Boolean, ...} */ headLess: {} }; scope.patternFloat = /^-?\d+(?:\.\d+)?$/; // updated by "typeahead" directive (typeahead-loading="linkLoading.geo") scope.linkLoading = {geo: false, tag: false}; scope.linkBusy = {geo: false, tag: false, user: false}; scope.statusInfo = null; scope.userRecommend = function (namePart) { var deferred = $q.defer(); bridge.recommend('user', scope.data.ticket.id, namePart).then(function (response) { deferred.resolve(response.data.list); }, function () { deferred.reject(); }); return deferred.promise; }; scope.linkSelect = function (type, $item) { if (null == scope.data) scope.data = {}; if (null == scope.form.link) scope.form.link = {}; scope.form.link[type] = $item; }; scope.linkRecommend = function (type, namePart) { var deferred = $q.defer(); bridge.recommend(type, scope.data.ticket.id, namePart).then(function (response) { deferred.resolve(response.data.list); }, function () { deferred.reject(); }); return deferred.promise; }; var onLinkActionDone = function (type, response) { if (null == scope.data) scope.data = {}; if (null == scope.form.link) scope.form.link = {}; if (null == scope.data.links) scope.data.links = {}; var data = response.data; scope.form.link[type] = null; if ('geo' === type) { scope.data.links.geo = data.links.geo; scope.data.links.geoAttr = data.links.geoAttr; scope.data.recommend = data.recommend; if (data.ticket) { angular.extend(scope.data.ticket, data.ticket); if (data.ticket.address) { geocodeAddress(data.ticket.address); } else { scope.mapTarget = null; } } } if ('tag' === type) { scope.form.link[type] = {}; scope.data.links.tag = data.links.tag; scope.tmp.indexedTagLinks = data.links.tag ? _.indexBy(data.links.tag, 'typeCode') : {}; } if ('user' === type) { scope.data.links.user = data.links.user; } }; var onLinkActionFail = function (response) { if (response.message) controller.notify(response.message, 'warning'); }; scope.onLinkChange = function (type, tagId) { if (scope.form.link[type][tagId]) { scope.linkLink(type, tagId); } else { scope.linkUnlink(type, tagId); } }; scope.linkLink = function (type, tagId) { scope.linkBusy[type] = true; bridge.link(type, scope.data.ticket.id, tagId).then(function (response) { scope.linkBusy[type] = false; onLinkActionDone(type, response); }, function (response) { scope.linkBusy[type] = false; onLinkActionFail(response); }); }; scope.linkUnlink = function (type, id) { scope.linkBusy[type] = true; bridge.unlink(type, scope.data.ticket.id, id).then(function (response) { scope.linkBusy[type] = false; onLinkActionDone(type, response); }, function (response) { scope.linkBusy[type] = false; onLinkActionFail(response); }); }; scope.saveTicket = function (field) { var data; if (null == field) { data = scope.data.ticket; } else { data = {id : scope.data.ticket.id}; data[field] = scope.data.ticket[field]; } return bridge.save(data).then(function (response) { notification.clear('object'); }, function (response) { if (response.message) controller.notify(response.message, 'warning'); if (response.errors) { angular.forEach(response.errors, function (msg, name) { scope.ticketForm.$setError(name, msg); }); } return $q.reject(response); }); }; scope.setStatus = function (status) { bridge.setStatus(scope.data.ticket.id, status).then(function (response) { scope.data.ticket.statusId = status; if ('user' === scope.devMode) { $state.go('menu.user.ticket'); } }, function (response) { if (response.message) controller.notify(response.message, 'warning'); }); }; scope.onGeoAttributeChange = function (attrId, value) { var type = 'geo'; scope.linkBusy[type] = true; bridge.saveGeoAttribute(scope.data.ticket.id, attrId, value).then(function (response) { scope.linkBusy[type] = false; onLinkActionDone(type, response); }, function (response) { scope.linkBusy[type] = false; onLinkActionFail(response); }); }; scope.onAttributeChange = function (attrId, value) { controller.action('saveAttribute', scope.data.ticket.id, attrId, value); }; scope.getDatepickerOptions = function (storageId) { var options = {}; switch (storageId) { case 'datetime': case 'date': options = {minMode: 'day', datepickerMode: 'day'}; break; case 'yearmonth': options = {minMode: 'month', datepickerMode: 'month'}; break; case 'year': options = {minMode: 'year', datepickerMode: 'year'}; break; default: throw new Error('Unknown datetimeStorageId: "' + storageId + '"'); } return options; }; scope.str2date = function (str) { if (null == str) return null; return new Date(str); }; scope.date2str = function (date) { if (null == date) return null; date = date instanceof Date ? date : new Date(date); return $filter('date')(date, 'yyyy-MM-dd HH:mm:ss'); }; var map; scope.mapTarget = undefined; scope.mapAfterInit = function (m) { map = m; cfg.debug && console.log(name, '.mapAfterInit'); if (scope.form.map.latitude && scope.form.map.longitude) { refreshMapPoint(mapHelper.coord2array(scope.form.map)); } }; scope.mapTargetDrop = function (e) { var target = e.get('target'); var coordinates = target.geometry.getCoordinates(); scope.form.map = mapHelper.coord2obj(coordinates); saveFormMap(); }; var geocodeAddress = function (address) { cfg.debug && console.log(name, '.geocodeAddress', address); if ('undefined' === typeof ymaps || null == ymaps.geocode) { return; } ymaps.geocode(address, {results: 1}).then(function (res) { var geoObject = res.geoObjects.get(0); scope.$apply(function () { refreshMapPoint(geoObject.geometry.getCoordinates()); }); }, function (err) { cfg.debug && console.warn(name, err); scope.mapTarget = null; }); }; var refreshMapPoint = function (coordinates) { cfg.debug && console.log(name, '.refreshMapPoint', coordinates); if (coordinates) { map && map.setCenter(coordinates); scope.mapTarget = scope.mapTarget || createMapPoint(); scope.mapTarget.geometry.coordinates = coordinates; var coordObj = mapHelper.coord2obj(coordinates); if (!angular.equals(scope.form.map, coordObj)) { scope.form.map = coordObj; saveFormMap(); } } else { scope.mapTarget = null; } }; var createMapPoint = function () { var point = { geometry: {type: 'Point'} }; if ('undefined' !== typeof ymaps && ymaps.geolocation) { point.geometry.coordinates = mapHelper.coord2array(ymaps.geolocation); } return point; }; scope.onFormMapChange = function () { cfg.debug && console.log(name, '.onFormMapChange', scope.form.map); if (scope.mapTarget) { var coordinates = mapHelper.coord2array(scope.form.map); scope.mapTarget.geometry.coordinates = coordinates; map && map.setCenter(coordinates); } return saveFormMap(); }; var saveFormMap = function () { var data = {id: scope.data.ticket.id}; if (scope.form.map.latitude) data.latitude = scope.form.map.latitude; if (scope.form.map.longitude) data.longitude = scope.form.map.longitude; return controller.action('save', data); }; scope.$on('$destroy', function () { map = null; }); scope.onGroupClick = function (headId) { scope.form.headLess[headId] = !scope.form.headLess[headId]; }; if (attributes[name]) { controller.formAction('read', attributes[name]).then(function (response) { if ('user' === scope.devMode && response.data.ticket.statusId !== staticData.ticketStatusInfo.draft.id) { $state.go('menu.user.ticket'); } scope.form.map.latitude = parseFloat(response.data.ticket.latitude); scope.form.map.longitude = parseFloat(response.data.ticket.longitude); if (scope.form.map.longitude && scope.form.map.latitude) { refreshMapPoint(mapHelper.coord2array(scope.form.map)); } else if (response.data.ticket.address) { geocodeAddress(response.data.ticket.address); } bridge.loadStatusInfo().then(function (data) { scope.statusInfo = data.statusInfo; }); }); } else { controller.formAction('create', attributes[name]).then(function (response) { $state.go('menu.' + user.roleId + '.ticket.edit', {id: response.data.ticket.id}); }); } } }; }]); })();