var app = angular.module('em7frontend', [
'ui.router', 'ui.bootstrap', 'infinite-scroll', 'syn-auth', 'grf.uploader',
'ui.multiselect', 'gt.select', 'gt.dropdown'
]);
app.config(function($stateProvider, $urlRouterProvider){
$stateProvider
.state('login', {
url: '/login',
requireLogin: false,
selectServer: false,
views: {
"root": {
templateUrl: 'partials/login.html',
controller: LoginCtrl
}
}
})
.state('loginto', {
url: '/loginto',
requireLogin: false,
selectServer: true,
views: {
"root": {
templateUrl: 'partials/login.html',
controller: LoginCtrl
}
}
})
.state('console', {
url: '/console',
requireLogin: true,
views: {
'root': {
templateUrl: 'partials/console.html',
controller: CtrlConsole
},
}
})
//*
.state('workplaces', {
url: '/workplaces',
requireLogin: true,
views: {
"root": {
templateUrl: 'partials/workplaces.html',
controller: WorkplacesCtrl,
resolve: WorkplacesCtrl.resolve
}
}
})
.state('wp', {
url: '/workplaces/:wpid',
requireLogin: true,
views: {
'root': {
templateUrl: 'partials/wp-base.html',
controller: function($scope, $stateParams, $location, $state, wps) {
if ( !$scope.workplaces ) {
$scope.setWPS(wps);
}
$scope.wpid = $stateParams.wpid;
if ( $scope.workplaces && $stateParams.wpid ) {
angular.forEach($scope.workplaces, function(wp) {
if ( wp.ID == $stateParams.wpid ) {
$scope.setWorkplace(wp);
}
});
}
// $scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
// $scope.section = null;
// if ( toState.name.match(/^wp\./i) ) {
// var p = event.currentScope.$parent.$parent.$parent,
// nameArr = toState.name.split('.');
// $scope.section = nameArr[1].split('-')[0];
// $scope.subSection = nameArr[1].split('-')[1] || null;
// }
// });
},
resolve: WorkplacesCtrl.resolve
}
}
})
.state('wp.contacts', {
url:'/contacts',
requireLogin: true,
views: {
'topbar': {
templateUrl: 'partials/topbar/contacts.html',
controller: 'ContactsSidebarMenuCtrl',
resolve: ContactsSidebarMenuCtrlResolve
},
'content': { templateUrl: 'partials/sidebar-main-layuot.html' },
'contentsidebar@wp.contacts': {
templateUrl: 'partials/contacts-sidebar.html',
controller: 'ContactsSidebarMenuCtrl',
resolve: ContactsSidebarMenuCtrlResolve
},
'contentmain@wp.contacts': {
templateUrl: 'partials/contacts-blank.html',
controller: 'ContactsSidebarMenuCtrl',
resolve: ContactsSidebarMenuCtrlResolve
}
}
})
.state('wp.contacts.group', {
url:'/:placement/:gid',
requireLogin: true,
views: {
'topbar': {
templateUrl: 'partials/topbar/search.html'
},
'content': { templateUrl: 'partials/sidebar-main-layuot.html' },
'contentsidebar@wp.contacts.group': {
templateUrl: 'partials/contacts-sidebar.html',
controller: 'ContactsSidebarMenuCtrl',
resolve: ContactsSidebarMenuCtrlResolve
},
'contentmain@wp.contacts': {
templateUrl: 'partials/contacts.html',
controller: 'ContactsCtrl'
}
}
})
.state('wp.templates', {
url: '/templates',
requireLogin: true,
views: {
'topbar': {
templateUrl: 'partials/topbar/search.html'
},
'content': { templateUrl: 'partials/sidebar-main-layuot.html' },
'contentsidebar@wp.templates': {
templateUrl: 'partials/content-sidebar.html',
controller: 'SidebarMenuCtrl'
},
'contentmain@wp.templates': {
templateUrl: 'partials/templates.html',
controller: TemplatesCtrl
}
}
})
.state('wp.templates-subfolder', {
url: '/templates/folder/:folder',
requireLogin: true,
views: {
'topbar': {
templateUrl: 'partials/topbar/search.html'
},
'content': { templateUrl: 'partials/sidebar-main-layuot.html' },
'contentsidebar@wp.templates-subfolder': {
templateUrl: 'partials/content-sidebar.html',
controller: 'SidebarMenuCtrl'
},
'contentmain@wp.templates-subfolder': {
templateUrl: 'partials/templates.html',
controller: TemplatesCtrl
}
}
})
.state('wp.templates-trash', {
url: '/templates/trash',
requireLogin: true,
views: {
'topbar': {
templateUrl: 'partials/topbar/search.html'
},
'content': { templateUrl: 'partials/sidebar-main-layuot.html' },
'contentsidebar@wp.templates-trash': {
templateUrl: 'partials/content-sidebar.html',
controller: 'SidebarMenuCtrl'
},
'contentmain@wp.templates-trash': {
templateUrl: 'partials/templates.html',
controller: TemplatesCtrl
}
}
})
.state('wp.templates.edit', {
url: '/:template/edit',
requireLogin: true,
views: {
// 'contentsidebar': {
// //templateUrl: 'partials/content-sidebar.html'
// template: 'contentsidebar!'
// },
// 'contentmain': {
// template: 'contentmain!'
// // templateUrl: 'partials/templates.html',
// // controller: TemplatesCtrl
// },
// 'content@wp': {
// template: 'CONTENT!'
// }
'topbar@wp': {
//template: 'top!'
templateUrl: 'partials/topbar/editor.html'
},
'content@wp': {
//template: 'content!'
templateUrl: 'partials/editor-template.html',
controller: 'TemplateEditorCtrl',
resolve: TemplateEditorResolve
}
}
})
.state('wp.templates.restore', {
url: '/:template/restore',
requireLogin: true,
views: {
'content@wp': {
template: '',
controller: function($scope, $stateParams, emAuth, synConn, $location){
synConn
.http({
uri: 'wp/{wpId}/settings/Templates/'+$stateParams.template
})
.success(function(tpl){
tpl.CategoryID = 0;
synConn
.http({
method: 'PUT',
headers: {
'Content-Type': 'application/json; charset=UTF-8'
},
uri: 'wp/{wpId}/settings/Templates/'+$stateParams.template,
data: JSON.stringify(tpl)
})
.success(function(data){
$location.path('/workplaces/'+emAuth.workplace.ID+'/templates');
})
.error(function(err, status, headers, config){
console.log(arguments);
});
})
.error(function(err, status, headers, config){
console.log(arguments);
});
}
}
}
})
.state('wp.templates.delete', {
url: '/:template/delete',
requireLogin: true,
views: {
'content@wp': {
template: '',
controller: function($scope, $stateParams, emAuth, synConn, $location){
// synConn
// .http({
// uri: 'wp/{wpId}/settings/Templates/'+$stateParams.template
// })
// .success(function(tpl){
// tpl.CategoryID = -1;
synConn
.http({
method: 'PUT',
headers: {
'Content-Type': 'application/json; charset=UTF-8'
},
uri: 'wp/{wpId}/settings/Templates/'+$stateParams.template,
data: JSON.stringify({ CategoryID: -1 })
})
.success(function(data){
$location.path('/workplaces/'+emAuth.workplace.ID+'/templates');
})
.error(function(err, status, headers, config){
console.log(arguments);
});
// })
// .error(function(err, status, headers, config){
// debugger;
// console.log('TEMPLATE ERR');
// console.log(arguments);
// });
}
}
}
})
.state('wp.outbox', {
url: '/outbox',
requireLogin: true,
views: {
'topbar': {
templateUrl: 'partials/topbar/sending-search.html'
},
'content': {
templateUrl: 'partials/sidebar-main-layuot.html'
},
'contentsidebar@wp.outbox': {
templateUrl: 'partials/content-sidebar.html',
controller: 'SidebarMenuCtrl'
},
'contentmain@wp.outbox': {
templateUrl: 'partials/outbox.html',
controller: EmailsCtrl
}
}
})
.state('wp.outbox.item', {
url: '/:id',
requireLogin: true,
views: {
'itemdetails@wp.outbox': {
templateUrl: 'partials/email-item-details.html',
controller: 'EmailsItemDetailsCtrl'
}
}
})
.state('wp.outbox.item.subview', {
url: '/:subview',
requireLogin: true,
views: {
'itemdetails@wp.outbox': {
templateUrl: 'partials/email-item-details.html',
controller: 'EmailsItemDetailsCtrl'
}
}
})
.state('wp.outbox-trash', {
url: '/outbox/trash',
requireLogin: true,
views: {
'topbar': {
templateUrl: 'partials/topbar/sending-search.html'
},
'content': {
templateUrl: 'partials/sidebar-main-layuot.html'
},
'contentsidebar@wp.outbox-trash': {
templateUrl: 'partials/content-sidebar.html',
controller: 'SidebarMenuCtrl'
},
'contentmain@wp.outbox-trash': {
templateUrl: 'partials/outbox.html',
controller: EmailsCtrl
}
}
})
.state('wp.drafts', {
url: '/drafts',
requireLogin: true,
views: {
'topbar': {
templateUrl: 'partials/topbar/search.html'
},
'content': { templateUrl: 'partials/sidebar-main-layuot.html' },
'contentsidebar@wp.drafts': {
templateUrl: 'partials/content-sidebar.html',
controller: 'SidebarMenuCtrl'
},
'contentmain@wp.drafts': {
templateUrl: 'partials/drafts.html',
controller: DraftsCtrl
}
}
})
.state('wp.drafts-trash', {
url: '/drafts/trash',
requireLogin: true,
views: {
'topbar': {
templateUrl: 'partials/topbar/search.html'
},
'content': { templateUrl: 'partials/sidebar-main-layuot.html' },
'contentsidebar@wp.drafts-trash': {
templateUrl: 'partials/content-sidebar.html',
controller: 'SidebarMenuCtrl'
},
'contentmain@wp.drafts-trash': {
templateUrl: 'partials/drafts.html',
controller: DraftsCtrl
}
}
})
.state('wp.drafts.edit', {
url: '/:draft/edit',
requireLogin: true,
views: {
'topbar@wp': {
//template: 'top!'
templateUrl: 'partials/topbar/editor.html'
},
'content@wp': {
//template: 'content!'
templateUrl: 'partials/editor-draft.html',
controller: 'DraftEditorCtrl',
resolve: DraftEditorResolve
}
}
})
.state('logout', {
url: '/logout',
requireLogin: false,
views: {
"root": {
template: '
',
controller: function($scope, $window, synConn){
synConn.logout();
$scope.setUserName(null);
$scope.setWorkplace(null);
window.location.hash = '#/login';
}
}
}
})
//*/
$urlRouterProvider.otherwise('/login');
});
app.run(function($rootScope, $location, emAuth, emsLoadingBar) {
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
$rootScope.isCollapsed = true;
$rootScope.selectServer = toState.selectServer;
setTimeout(function(){
emsLoadingBar.enabled = true;
}, 5000);
if ( toState.requireLogin && !emAuth.isAuthenticated() ) {
event.preventDefault();
$location.path('/login');
} else {
if ( typeof toParams.gid !== 'undefined' ) {
$rootScope.gid = toParams.gid;
}
$rootScope.section = null;
if ( toState.name.match(/^wp\./i) ) {
var nameArr = toState.name.split('.');
$rootScope.section = nameArr[1].split('-')[0];
$rootScope.subSection = nameArr[1].split('-')[1] || null;
$rootScope.uiSection = ($rootScope.section == 'contacts') ? 'Contacts' : 'Emails';
}
}
});
});
app.factory('emAuth', function(){
var auth = {},
authenticated = true,
rememberMe = true,
ls = window.localStorage;
function getItem(key) {
var v = ls.getItem(key);
if ( v && v.indexOf('__JSON__') === 0 ) {
v = v.substr(8);
return ( v === 'undefined' ) ? undefined : JSON.parse(v);
}
return v;
}
if ( rememberMe ) {
auth = {
'host': getItem('host'),
'port': getItem('port'),
'email': getItem('email'),
'password': getItem('password'),
'workplace': getItem('workplace'),
'userName': getItem('userName'),
'secure': getItem('secure')
};
}
return {
setAuthenticated: function(a) {
authenticated = a;
},
isAuthenticated: function() {
return authenticated;
},
set: function(key, value) {
auth[key] = value;
if ( rememberMe ) {
if ( typeof value !== 'string' ) {
value = '__JSON__'+JSON.stringify(value);
}
// console.log('key: '+typeof key);
// console.log(key);
// console.log('value: '+typeof value);
// console.log(value);
ls.setItem(key, value);
}
return this;
},
get: function(key) {
return auth[key];
}
};
});
app.factory('emGroups', function(emAuth, synConn){
var that = new Emmi();
that.cache = {
//id: {...group...}
};
function getGroup(gid, done) {
if ( ['object', 'string', 'number'].indexOf(typeof gid) == -1 ) {
return done({ ID: -1, GroupName: 'GROUP ERROR' });
}
if ( typeof that.cache[gid] === 'object' && that.cache[gid] !== null ) {
done(that.cache[gid]);
} else if ( that.cache[gid] === null ) {
that.once('group'+gid, done);
} else {
that.cache[gid] = null;
synConn
.http({ uri: 'wp/{wpId}/settings/Groups/'+gid+'/' })
.success(function(data){
that.cache[gid] = data;
that.emit('group'+gid, data);
done(data);
})
.error(function(err, status, headers, config){
delete that.cache[gid];
that.emit('group'+gid);
done({ ID: gid, GroupName: 'GROUP DELETED' });
});
}
}
that.resolve = function(groupsArr, done) {
if ( typeof groupsArr === 'string' ) {
try {
groupsArr = JSON.parse(groupsArr);
} catch ( e ){
return done(e);
}
}
var resolveCount = groupsArr.length,
resolved = [];
if ( resolveCount === 0 ) { return done(null, resolved); }
for (var gid, i = 0; i < groupsArr.length; i++) {
gid = (typeof groupsArr[i] === 'string') ? parseInt(groupsArr[i], 10) : groupsArr[i];
getGroup(gid, function(data){
resolved[this.i] = data;
resolveCount -= 1;
if ( resolveCount <= 0 ) {
return done(null, resolved);
}
}.bind({ i: i, gid: gid }));
}
};
that.getGroup = getGroup;
return that;
});
app.factory('emAccounts', function(emAuth, synConn){
var that = new Emmi();
that.cache = {
//id: {...group...}
};
function getAcc(aid, done) {
var deleted = { ID: -1, AccountName: 'DELETED' };
if ( isNaN(aid) ) {
return done(deleted);
}
if ( typeof that.cache[aid] === 'object' && that.cache[aid] !== null ) {
done(that.cache[aid]);
} else if ( that.cache[aid] === null ) {
that.once('group'+aid, done);
} else {
that.cache[aid] = null;
synConn
.http({ uri: 'wp/{wpId}/settings/Account/'+aid+'/' })
.success(function(data){
that.cache[aid] = data;
that.emit('group'+aid, data);
done(data);
})
.error(function(err, status, headers, config){
delete that.cache[aid];
that.emit('group'+aid);
return done(deleted);
});
}
}
that.resolve = function(accsArr, done) {
if ( typeof accsArr === 'string' ) {
try {
accsArr = JSON.parse(accsArr);
} catch ( e ){
return done(e);
}
}
var resolveCount = accsArr.length,
resolved = [];
if ( resolveCount === 0 ) { return done(null, resolved); }
for (var aid, i = 0; i < accsArr.length; i++) {
aid = accsArr[i];
getAcc(aid, function(data){
resolved[this.i] = data;
resolveCount -= 1;
if ( resolveCount <= 0 ) {
return done(null, resolved);
}
}.bind({ i: i, aid: aid }));
}
};
return that;
});
app.factory('emUtils', function(synConn){
var that = {};
that.supplant = function (str, o) {
return str.replace(
/\{([^{}]*)\}/g,
function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
that.shrinkAssetURLs = function(src, baseURL) {
var base = synConn.getBaseURL();
base = base.substring(0, base.length-1);
base += baseURL;
var baseLength = base.length;
function replacer(match, p1, p2, p3, p4) {
var url = p3;
if ( url.match(/^\w+:\/\//) ) {
if ( url.indexOf(base) === 0 ) {
return p1+url.substr(baseLength)+p4;
}
}
return p1+url+p4;
}
return src
.replace(/(\b(?:src|url|background)=(\\\'|"))(.*?)(\2)/ig, replacer)
.replace(/(\burl\(([\\\'"]{0,1}))(.*?)(\2\))/ig, replacer);
}
that.expandAssetURLs = function(src, baseURL) {
var base = synConn.getBaseURL();
base = base.substring(0, base.length-1);
base += baseURL;
function replacer(match, p1, p2, p3, p4) {
var url = p3;
if ( url.match(/^\w+:\/\//) ) {
return p1+url+p4;
}
if ( base[base.length-1] !== '/' && url[0] !== '/' ) { base += '/'; }
url = base+url;
return p1+url+p4;
}
return src
.replace(/(\b(?:src|url|background)=(\\\'|"))(.*?)(\2)/ig, replacer)
.replace(/(\burl\(([\\\'"]{0,1}))(.*?)(\2\))/ig, replacer);
}
that.unpackEmailSource = function(src) {
function uintToString(uintArray) {
var encodedString = String.fromCharCode.apply(null, uintArray),
decodedString = decodeURIComponent(escape(encodedString));
return decodedString;
}
if ( src && src[0] === 'X' ) {
var intArr = [];
angular.forEach(src.substr(2, src.length-3).match(/(.{1,2})/g), function(s){
intArr.push(parseInt(s, 16));
});
src = uintToString(intArr);
}
return src;
};
that.timeLogToDate = function(long_datetime) {
// - bits 0..5 = Seconds (0..59) - 6
// - bits 6..11 = Minutes (0..59) - 6
// - bits 12..16 = Hours (0..23) - 5
// - bits 17..21 = Day-1 (0..31) - 5
// - bits 22..25 = Month-1 (0..11) - 4
// - bits 26..38 = Year (0..4095) - 13
var x = goog.math.Long.fromNumber(long_datetime);
/*
function TTimeLogBits.ToDateTime: TDateTime;
begin
if Value=0 then
result := 0 else
result := EncodeDate(
(Value shr (6+6+5+5+4)) and 4095, // year
1+(Int64Rec(Value).Lo shr (6+6+5+5)) and 15, // month
1+(Int64Rec(Value).Lo shr (6+6+5)) and 31)+ // day
EncodeTime(
(Int64Rec(Value).Lo shr (6+6)) and 31, // hour
(Int64Rec(Value).Lo shr 6) and 63, // min
Int64Rec(Value).Lo and 63, 0); // sec, msec
end;
*/
var d = new Date();
d.setFullYear( ((x.high_ << 6) + (x.low_ >> (6+6+5+5+4)) ).toString(10) );
d.setMonth( (x.low_ >> (6+6+5+5)) & 0xf );
d.setDate( (x.low_ >> (6+6+5)) & 0x1f );
d.setHours( (x.low_ >> (6+6)) & 0x1f );
d.setMinutes((x.low_ >> 6) & 0x3f );
d.setSeconds( x.low_ & 0x3f );
d.setMilliseconds(0);
return d;
};
that.UUID = (function(){
return function b(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,b)};
})();
return that;
});
app.factory('emCategories', function($q, synConn, emAuth){
var that = {
categories: null,
get: function(id) {
var d = $q.defer();
if ( !this.categories ) {
getCategories(function(err, cats){
that.categories = {};
angular.forEach(cats, function(o){
that.categories[o.ID] = o.Name;
});
d.resolve(that.categories[id]);
});
} else {
d.resolve(that.categories[id]);
}
return d.promise;
},
getAll: function(){
var d = $q.defer();
if ( !that.categories ) {
getCategories(function(err, cats){
that.categories = {};
angular.forEach(cats, function(o){
that.categories[o.ID] = o.Name;
});
d.resolve(that.categories);
});
} else {
d.resolve(that.categories);
}
return d.promise;
}
};
function getCategories(done) {
synConn
.http({ uri: 'wp/{wpId}/settings/TemplateCategory?Select=*' })
.success(function(data){
var cats = ( typeof data.rowCount !== 'undefined' ) ? [] : data;
done(null, cats);
})
.error(function(err, status, headers, config){
done(err);
});
}
return that;
});
app.directive('ckEditor', [function () {
return {
scope: {
'ckSource': '='
},
link: function ($scope, elm, attrs) {
var item;
function logError(err){
console.error(typeof err);
}
// attrs.$observe('ngModel', function(value) {
// console.log('ngModel has changed value to ' + value);
// });
var ck = CKEDITOR.replace(elm[0], {
startupFocus : true,
width: 'auto',
height: 400,
customConfig: '../../../js/custom_config.js'
});
function gotBody(body) {
if ( CKEDITOR.status === 'loaded' ) {
ck.setData(body);
} else {
CKEDITOR.on( 'instanceReady', function( evt ) {
ck.setData(body);
});
}
ck.on('change', function(){
item.setBody(ck.getData());
});
}
function gotItem(it) {
item = it;
window.item = item;
var body = it.getBody();
if ( body.then ) {
body.then(gotBody, logError);
} else {
gotBody(body);
}
}
$scope.$watch('ckSource', function(src) {
if ( src ) {
if ( src.then ) {
src.then(gotItem, logError);
} else {
gotItem(src);
}
}
});
// ck.on('pasteState', function () {
// $scope.$apply(function () {
// $scope.ckSource = ck.getData();
// //ngModel.$setViewValue(ck.getData());
// });
// });
// ngModel.$render = function (value) {
// ck.setData(ngModel.$modelValue);
// };
}
};
}]);
app.directive('emNobubble', function() {
return function(scope, element, attrs) {
$(element).click(function(event) {
event.stopPropagation();
});
}
});
app.directive('emNodefault', function() {
return function(scope, element, attrs) {
$(element).click(function(event) {
event.preventDefault();
});
}
});
// em-loading-bar
app
.factory('emsLoadingBar', function($rootScope, grfCreateTransport, $timeout){
var that = new Emmi();
that.enabled = false;
that.currentProgress = 0;
var iv = null;
var dur = 2 * 60 * 1000; // 2 minutes
// t: current time, b: begInnIng value, c: change In value, d: duration
function easeOutExpo(t, b, c, d) {
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
}
that.setProgress = function(p) {
that.currentProgress = p;
that.emit('progress', p);
};
that.enable = function() {
that.enabled = true;
};
function runSlowIncrementer() {
var t = 0;
iv = setInterval(function() {
t += 1000;
if ( t >= dur ) {
that.end();
} else {
var p = Math.round(easeOutExpo(t, 60, 40, dur));
that.setProgress( p );
}
}, 1000);
};
that.start = function() {
if ( !that.enabled ) { return; }
that.setProgress(0);
if ( iv ) {
clearInterval(iv);
iv = null;
}
// quickly filling up to 60% filling
iv = setInterval(function(){
that.setProgress(that.currentProgress + 10);
if ( that.currentProgress >= 60 ) {
clearInterval(iv);
iv = null;
runSlowIncrementer();
}
}, 200);
};
that.stop = function() {
if ( !that.enabled ) { return; }
clearInterval(iv);
iv = null;
that.setProgress(100);
$timeout(function() {
that.setProgress(0);
}, 1000);
};
return that;
})
.directive('emdLoadingbar', function($rootScope, emsLoadingBar) {
window.emsLB = emsLoadingBar;
return {
retrict: 'AE',
template: '',
replace: true,
link: function($scope, el, attrs, controller) {
emsLoadingBar.on('progress', function(p){
function move() {
var st = el[0].style,
s = 'translate3d('+( p-100 )+'%, 0, 0)';
if ( typeof st.webkitTransform !== 'undefined' ) st.webkitTransform = s;
if ( typeof st.MozTransform !== 'undefined' ) st.MozTransform = s;
if ( typeof st.transform !== 'undefined' ) st.transform = s;
}
if ( p == 0 ) {
el.hide();
setTimeout(function(){
move();
el.show();
}, 1)
} else {
move();
}
});
}
};
});
app.filter('capitalize', function() {
return function(input, scope) {
return (typeof input !== 'string') ? input : input.substring(0,1).toUpperCase()+input.substring(1);
}
});