Guest User

Untitled

a guest
Aug 22nd, 2018
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 49.39 KB | None | 0 0
  1. angular.module('priooo')
  2. .service('Api', ['$http', 'appConstants', 'Misc', 'Session', 'Debug', function($http, appConstants, Misc, Session, Debug) {
  3. var absolutePath = Misc.getServerPath();
  4. absolutePath += "rest-public/";
  5. var etags = {};
  6. var allowed = {};
  7.  
  8. function buildURI(uri, addTeamId) {
  9. var path = absolutePath;
  10. var authObj = Session.get('authObj');
  11. var api = false;
  12.  
  13. if(uri.indexOf('api/') > -1){
  14. api = true;
  15. path = path.replace("rest-public/", "api/");
  16. uri = uri.slice(4, uri.length)
  17. }
  18.  
  19. if(!authObj) return path + uri;
  20.  
  21. if(addTeamId === true && !api && authObj.team.id > 0 && !uri.startsWith("users/") && !uri.startsWith("tasks/") && !uri.startsWith("backlogitems/") && !uri.startsWith("comments/")) {
  22. if(uri.indexOf("?") > -1) {
  23. var uri_parts = uri.split("?");
  24. uri_parts[0] += "/" + authObj.team.id;
  25. uri = uri_parts.join("?");
  26. }
  27. else {
  28. uri += "/" + authObj.team.id;
  29. }
  30. }
  31.  
  32. if(uri.indexOf("?") < 0)
  33. return path + uri + "?token=" + authObj.AccessToken;
  34. else
  35. return path + uri + "&token=" + authObj.AccessToken;
  36. }
  37.  
  38. $http.defaults.headers.post["Content-Type"] = "application/json";
  39. $http.defaults.timeout = 5000;
  40.  
  41. this.Get = function (uri, callback, error, skipEtag) {
  42. var skipEtag = (skipEtag===true);
  43. /*if(etags.hasOwnProperty(uri)) {
  44. $http.defaults.headers.common['If-None-Match'] = etags[uri]; //Set previously cached ETag
  45. }*/
  46.  
  47. return $http.get(buildURI(uri, true), (etags.hasOwnProperty(uri) && !skipEtag) ? { headers: {'If-None-Match': etags[uri]} } : {}).then(function(response) {
  48. console.log('uri: ', uri);
  49. console.log('response: ', response);
  50. if(callback && typeof callback === 'function') {
  51. if(response.headers("etag")) {
  52. etags[uri] = response.headers("etag");
  53. }
  54. if(response.headers("allow")) {
  55. allowed[uri] = response.headers("allow");
  56. }
  57. callback(response.data);
  58. }
  59. }, function(response){ errorException(response, error); });
  60. };
  61.  
  62. this.Post = function () { // uri, object, callback, error || uri, object, headers, callback, error
  63. var args = Array.prototype.slice.call(arguments);
  64. var uri = args.shift();
  65. var object = JSON.stringify(args.shift() || {});
  66. var headers = {};
  67. if(args.length == 3) {
  68. headers = args.shift();
  69. }
  70. var callback = args.shift();
  71. var error = args.shift();
  72.  
  73. return $http.post(buildURI(uri), object, {
  74. headers: headers,
  75. transformRequest: angular.identity,
  76. }).then(function(response){
  77. if(callback && typeof callback === 'function') {
  78. etags[uri] = response.headers("etag");
  79. callback(response.data);
  80. }
  81. }, function(response){ errorException(response, error); });
  82. };
  83.  
  84. this.Put = function (uri, object, callback, error) {
  85. if(object == null) object = {};
  86. return $http.put(buildURI(uri), JSON.stringify(object)).then(function(response){
  87. if(callback && typeof callback === 'function') {
  88. etags[uri] = response.headers("etag");
  89. callback(response.data);
  90. }
  91. }, function(response){ errorException(response, error); });
  92. };
  93.  
  94. this.Delete = function (uri, callback, error) {
  95. return $http({url:buildURI(uri), method: "delete" }).then(function(response){
  96. if(callback && typeof callback === 'function') {
  97. etags[uri] = response.headers("etag");
  98. callback(response.data);
  99. }
  100. }, function(response){ errorException(response, error); });
  101. };
  102.  
  103. var errorException = function (response, callback) {
  104. if(response.status != 304) {
  105. var status = (response.status > 0) ? " " + response.status + " error" : "n unknown error";
  106. if(response.status == 404 || response.status == 500) {
  107. var config = response.config;
  108. var debug = " url["+config.url+"] method["+config.method+"]";
  109. if(config.data && config.data != "") debug += " data["+config.data+"]";
  110. Debug.warn("A" + status + " occurred, please notify a system administrator!" + '\n' + debug);
  111. }
  112. else{
  113. Debug.info("A" + status + " occured.", response);
  114. }
  115.  
  116. if(callback && typeof callback === 'function') {
  117. callback(response.data, response.status, response.statusText);
  118. }
  119. }
  120. };
  121.  
  122. //Getters
  123. this.errorException = errorException;
  124. this.absolutePath = absolutePath;
  125. this.etags = etags;
  126.  
  127. this.flushCache = function() {
  128. etags = {};
  129. allowed = {};
  130. };
  131.  
  132. this.getAllowed = function(path) {
  133. if(path == undefined)
  134. return allowed;
  135. else
  136. return allowed[path] || false;
  137. };
  138.  
  139. }]).service('Poller', ['Api', 'appConstants', 'Debug','$timeout', '$rootScope', function(Api, appConstants, Debug, $timeout, $rootScope) {
  140. var data = {};
  141. this.createPollerObject = function(uri, callback) {
  142. this.uri = uri;
  143. this.waiting = true;
  144. this.pollerInterval = appConstants["poller.interval"];
  145. this.fired = 0;
  146. this.errorList = [];
  147. this.addError = function() {
  148. this.errorList.push({
  149. time: (new Date()).getTime(),
  150. fired: this.fired
  151. });
  152. if(this.errorList.length > 10)
  153. this.errorList.shift();
  154. };
  155. this.getLastError = function() {
  156. return this.errorList[this.errorList.length-1];
  157. };
  158. this.ai = {
  159. list: [],
  160. avg: 0,
  161. push: function(obj) {
  162. this.list.push(obj);
  163. if(this.list.length == 5) {
  164. var tmp = 0;
  165. for (var i = this.list.length - 1; i >= 0; i--) {
  166. tmp += this.list[i];
  167. }
  168. this.avg = Math.round((tmp / this.list.length) / 100 ) * 100;
  169. this.list = [];
  170. return this.avg;
  171. }
  172. }
  173. };
  174. this.started = function() {return (this.poller) ? true : false;};
  175. this.stop = function() {
  176. if(!this.started()) return;
  177.  
  178. this.ai.list = [];
  179. this.ai.avg = 0;
  180. if(this.waiting)
  181. clearTimeout(this.poller);
  182. else
  183. clearInterval(this.poller);
  184. this.waiting = true;
  185. delete this.poller;
  186. };
  187. this.fn = function(runOnce) {
  188. var runOnce = !!runOnce;
  189. var poller = data[uri];
  190. Api.Get(uri, callback, function() {
  191. poller.addError();
  192.  
  193. var e = 0;
  194. for(x in poller.errorList) {
  195. var y = poller.errorList[x];
  196. if(poller.fired == y.fired || poller.fired-1 == y.fired || poller.fired-2 == y.fired)
  197. e++;
  198. }
  199. Debug.info("Encountered unhandeled exception, poller["+uri+"] eventId["+poller.fired+"] retries["+e+"]");
  200. if(e < 3) return;
  201.  
  202. Debug.warn("Max retries reached. Stopping poller ["+uri+"]", poller);
  203.  
  204. runOnce = true;
  205. data[uri].stop();
  206. }).then(function() {
  207. $rootScope.$broadcast('poller-ran');
  208. if(runOnce) return;
  209. poller.fired++;
  210.  
  211. var p = data[uri];
  212. if(p && p.waiting)
  213. p.start();
  214. });
  215. };
  216. this.run = function() {
  217. this.fn(true);
  218. };
  219. this.start = function() {
  220. if(this.started() && !this.waiting) return;
  221.  
  222. if(this.waiting) {
  223. var now = new Date().getTime();
  224. if(this.lastPolled) {
  225. var timeBetweenLastPolledAndNow = now - this.lastPolled;
  226. var interval = this.ai.push(timeBetweenLastPolledAndNow);
  227. if(interval > 0 && interval > this.pollerInterval) {
  228. this.setInterval(interval, false);
  229. this.waitForResponse(false);
  230. return;
  231. }
  232. }
  233. this.poller = setTimeout(this.fn, this.pollerInterval);
  234. this.lastPolled = now;
  235. }
  236. else
  237. this.poller = setInterval(this.fn, this.pollerInterval);
  238. };
  239. this.setInterval = function(interval, restart) {
  240. var restart = (!restart || restart === false) ? false : true;
  241. Debug.info("Interval for " + this.uri + " changed to [" + interval + "] restart ["+restart+"]");
  242. this.pollerInterval = interval;
  243. if(restart)
  244. this.restart();
  245. };
  246. this.waitForResponse = function(bool) {
  247. this.stop();
  248. delete this.lastPolled;
  249. this.waiting = !!bool;
  250. if(bool != this.waiting)
  251. Debug.info("waitForResponse for " + this.uri + " changed to: " + bool);
  252. this.start();
  253. };
  254. this.restart = function() {
  255. this.stop();
  256. this.start();
  257. };
  258. },
  259. this.changeInterval = function(uri, interval) {
  260. data[uri].waitForResponse(true);
  261. data[uri].setInterval(interval, false);
  262. },
  263. this.add = function (uri, callback, autoStart, interval) {
  264. var poller = new this.createPollerObject(uri, callback);
  265. data[uri] = poller;
  266. if(!!autoStart)
  267. poller.fn();
  268. if(interval && interval > 1500)
  269. poller.setInterval(interval);
  270. return poller;
  271. },
  272. this.remove = function (uri) {
  273. data[uri].stop();
  274. delete data[uri];
  275. },
  276. this.get = function (uri) {
  277. return data[uri];
  278. },
  279. this.getAll = function () {
  280. var list = [];
  281. for(uri in data) {
  282. list.push(uri);
  283. }
  284. return list;
  285. };
  286. this.waitFor = function(uri, callback){
  287. if(typeof uri === "string"){
  288. var poller = data[uri];
  289.  
  290. Debug.log("Waiting for poller for uri ["+uri+"]");
  291. var retries = 5;
  292. check = function(){
  293. if(!poller.fired > 0 && retries > -1){
  294. retries--;
  295. Debug.log("Poller ["+uri+"]hasn't fired, retrying with ["+retries+"]");
  296. $timeout(check,500);
  297. }
  298. else if(poller.fired > 0){
  299. Debug.log("Poller ["+uri+"]has fired ["+poller.fired+"]");
  300. callback();
  301. }
  302. };
  303. check();
  304. }
  305. else if(Array.isArray(uri)){
  306. var isLoaded = [];
  307. for(x in uri){
  308. var poller = data[uri[x]];
  309. var retries = 5;
  310.  
  311. check = function(){
  312. if(!poller.fired > 0 && retries > -1){
  313. retries--;
  314.  
  315. Debug.log("Poller ["+uri[x]+"] hasn't fired, retrying with ["+retries+"]");
  316. $timeout(check,500);
  317. }
  318. else if(poller.fired > 0){
  319. Debug.log("Poller ["+uri[x]+"] has fired ["+poller.fired+"]");
  320.  
  321. var obj = {};
  322. obj[poller] = true
  323. isLoaded.push(obj);
  324. }
  325. };
  326. check();
  327. }
  328.  
  329. if(isLoaded.length == uri.length){
  330. callback();
  331. }
  332. };
  333. };
  334. }]).service('Notification', ['$rootScope', '$timeout', function($rootScope, $timeout) {
  335. Tinycon.setOptions({
  336. background: '#f03d25'
  337. });
  338. this.list = [];
  339. this.count = 0;
  340. this.add = function(icon, title, msg, fn) {
  341. var obj = {
  342. icon: icon,
  343. title: title,
  344. message: (msg) ? msg : false,
  345. fn: (fn) ? fn: false,
  346. time: new Date().getTime()
  347. };
  348. this.list.unshift(obj);
  349. obj.id = this.list.length;
  350. this.count++;
  351.  
  352. Tinycon.setBubble(this.count);
  353. };
  354. this.get = function(id) {
  355. for (var i = 0; i < this.list.length; i++) {
  356. var notification = this.list[i];
  357. if(notification.id == id) {
  358. if(notification.fn) {
  359. $timeout(function(){
  360. notification.fn.apply(this, notification);
  361. }, 50);
  362. }
  363. return notification;
  364. }
  365. }
  366.  
  367. return false;
  368. };
  369. this.resetCount = function() {
  370. Tinycon.setBubble(0);
  371. this.count = 0;
  372. };
  373. this.getCount = function() {
  374. return this.count;
  375. };
  376. this.getLatest = function(amount) {
  377. if(amount < 1) amount = 1;
  378. return this.list.slice(0, amount);
  379. };
  380. }]).service('Cookies', ['Debug','Misc', '$cookies', function(Debug, Misc, $cookies) {
  381. var date = new Date();
  382. date.setDate(date.getDate() + 7);
  383. this.options = {
  384. expires: date,
  385. path: '/'
  386. };
  387. this.get = function(key) {
  388. return $cookies.getObject(key);
  389. };
  390. this.set = function(key, value) {
  391. if(key == 'authObj'){ // Default time for login is 24h
  392. var d = new Date();
  393. d.setDate(d.getDate() + 1);
  394.  
  395. $cookies.putObject(key, value, {
  396. expires: d,
  397. path: '/'
  398. });
  399. }
  400. else {
  401. $cookies.putObject(key, value, this.options);
  402. }
  403. };
  404. this.remove = function(key) {
  405. $cookies.remove(key, {path: '/'});
  406. };
  407. this.clear = function() {
  408. for(key in $cookies.getAll()) {
  409. if(!key.startsWith("_"))
  410. this.remove(key);
  411. }
  412. };
  413. }]).service('Session', ['Debug', function(Debug) {
  414. this.get = function(key) {
  415. //Debug.log(key, sessionStorage.getItem(key), sessionStorage.getItem(key) == null, sessionStorage.getItem(key) == "null");
  416. return JSON.parse(sessionStorage.getItem(key));
  417. };
  418. this.set = function(key, value) {
  419. sessionStorage.setItem(key, JSON.stringify(value));
  420. };
  421. this.remove = function(key) {
  422. sessionStorage.removeItem(key);
  423. };
  424. this.clear = function() {
  425. sessionStorage.clear();
  426. };
  427. }]).service('DateUtil', function() {
  428. this.nextMonth = function(date) {
  429. return new Date(date.getFullYear(), date.getMonth()+1, 0);
  430. };
  431. this.nextQuarter = function(date) {
  432. return new Date(date.getFullYear(), (Math.floor(date.getMonth() / 3)+1)*3, 0);
  433. };
  434. this.nextYear = function(date) {
  435. return new Date(date.getFullYear()+1, 0, 0);
  436. };
  437. this.getMonth = function(time) {
  438. var date = new Date(time);
  439. var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
  440. return months[date.getMonth()];
  441. };
  442. this.getQuarter = function(time) {
  443. var date = new Date(time);
  444. var Q = ["Q1", "Q2", "Q3", "Q4"];
  445. return Q[Math.floor(date.getMonth() / 3)];
  446. };
  447. this.format = function(t) {
  448. var time = new Date(t);
  449. return time.getDate() + "-" + (time.getMonth()+1) + "-" + time.getFullYear();
  450. };
  451. }).filter('ucfirst', function() {
  452. return function(s) {
  453. return (angular.isString(s) && s.length > 0) ? s[0].toUpperCase() + s.substr(1).toLowerCase() : s;
  454. };
  455. }).filter('tagString', function() {
  456. return function(tagList) {
  457. if(!tagList || tagList.length == 0) return;
  458.  
  459. var returnStr = "";
  460. for(x in tagList) {
  461. returnStr += tagList[x].name + ", ";
  462. }
  463. if(returnStr.length > 0)
  464. return returnStr.substring(0, returnStr.length-2);
  465. else
  466. return "";
  467. };
  468. }).filter('tagFilter', function() {
  469. return function(backlogitems, $scope) {
  470. if(backlogitems.length < 1) return [];
  471. var filter = $scope.filteredTags;
  472. var returnList;
  473.  
  474. returnList = [];
  475. for(x in backlogitems) {
  476. var pbi = backlogitems[x];
  477. var remove = 0;
  478.  
  479. if(pbi.tags){
  480. for(y in pbi.tags) {
  481. if(filter.indexOf(pbi.tags[y].name) != -1) {
  482. remove++;
  483. };
  484. };
  485. };
  486. if(remove >= filter.length){
  487. returnList.push(pbi);
  488. };
  489. };
  490. return returnList;
  491. };
  492. })
  493. .filter("containsTag", function() {
  494. return function (tags, tag) {
  495. for(x in tags) {
  496. if(tag.name==tags[x].name)
  497. return true;
  498. }
  499. return false;
  500. };
  501. }).service('Debug', function() {
  502. var level = 0;
  503. var inGroup = false;
  504. this.getLevel = function() {
  505. return level;
  506. };
  507. this.setLevel = function(l) {
  508. l = Math.min(3, Math.max(0, l));
  509. console.info(this.head() + " Setting DEBUG level to ["+l+"]");
  510. level = l;
  511. };
  512. this.head = function() { return moment().format("DD-MM-YYYY HH:mm:ss") + " -"; },
  513. this.log = function() {
  514. if(level < 3) return;
  515. var args = arguments || [];
  516. var func = window.console.log;
  517. if(!inGroup)
  518. Array.prototype.unshift.call(args, this.head());
  519. try {
  520. func.apply(window.console, args);
  521. } catch (e) {
  522. for(var a in args)
  523. console.log(args[a]);
  524. };
  525. };
  526. this.group = function() {
  527. var args = arguments || [];
  528. var title = Array.prototype.shift.call(args);
  529. inGroup = true;
  530. window.console.group(this.head() + " " + title);
  531.  
  532. if(args.length > 0) { //Loop through args and close group after...
  533. for(var a in args)
  534. console.log(args[a]);
  535. this.groupEnd();
  536. }
  537. };
  538. this.groupEnd = function() {
  539. inGroup = false;
  540. window.console.groupEnd();
  541. };
  542. this.info = function() {
  543. if(level < 2) return;
  544. var args = arguments || [];
  545. var func = window.console.info;
  546. if(!inGroup)
  547. Array.prototype.unshift.call(args, this.head());
  548. try {
  549. func.apply(window.console, args);
  550. } catch (e) {
  551. for(var a in args)
  552. console.info(args[a]);
  553. };
  554. };
  555. this.warn = function(a) {
  556. if(level < 1) return;
  557. var args = arguments || [];
  558. var func = window.console.warn;
  559. if(!inGroup)
  560. Array.prototype.unshift.call(args, this.head());
  561. try {
  562. func.apply(window.console, args);
  563. } catch (e) {
  564. for(var a in args)
  565. console.warn(args[a]);
  566. };
  567. };
  568. this.error = function(a) {
  569. var args = arguments || [];
  570. var func = window.console.error;
  571. if(!inGroup)
  572. Array.prototype.unshift.call(args, this.head());
  573. try {
  574. func.apply(window.console, args);
  575. } catch (e) {
  576. for(var a in args)
  577. console.error(args[a]);
  578. };
  579. };
  580. })
  581. .service('ConditionChecker', ['$rootScope', "Debug", "$state", function($rootScope, Debug, $state) {
  582. var ConditionChecker = this;
  583.  
  584. function log(message){
  585. Debug.log("[ Condition Checker ] - " + message);
  586. }
  587.  
  588. function singlePossibility(condition, item){
  589. var possible = true;
  590.  
  591. if(condition["role"]){
  592. if(!(ConditionChecker.isRole(condition["role"]["role"]))){
  593. possible = false;
  594. }
  595. }
  596.  
  597. if(condition["amountIs"]){
  598. for(var name in condition["amountIs"]){
  599. if( !(ConditionChecker.amount({name:name, operator: '==', amount:condition["amountIs"][name]})) ){
  600. possible = false;
  601. }
  602. }
  603. }
  604.  
  605. if(condition["seen"]){
  606. var expectedAmount = condition["seen"]["seen"];
  607. var actualAmount = item.amountSeen || 0;
  608. log("Seen itself ? Expected: " + expectedAmount + " Actual: " + actualAmount);
  609. if(actualAmount > expectedAmount ){
  610. possible = false;
  611. }
  612. }
  613.  
  614. return possible;
  615. }
  616.  
  617. function checkCondition(condition, item){
  618. var met = true;
  619. var type = condition["OR"] ? "OR" : "AND";
  620.  
  621. if(type === "OR"){
  622. met = false;
  623.  
  624. for (var property in condition["OR"]) {
  625. if (condition["OR"].hasOwnProperty(property)) {
  626. var sub = condition["OR"][property];
  627.  
  628. if(checkSingleCondition(sub, item)){
  629. met = true;
  630. break;
  631. }
  632. }
  633. }
  634. }
  635. else {
  636. met = checkSingleCondition(condition, item);
  637. }
  638.  
  639. return met;
  640. }
  641.  
  642. function checkSingleCondition(condition, item){
  643. if(condition["amountIs"]){
  644. for(var name in condition["amountIs"]){
  645. if( !(ConditionChecker.amount({name:name, operator: '==', amount:condition["amountIs"][name]})) ){
  646. return false;
  647. }
  648. }
  649. }
  650.  
  651. if(condition["amountLess"]){
  652. for(var name in condition["amountLess"]){
  653. if( !(ConditionChecker.amount({name:name, operator: '<', amount:condition["amountLess"][name]})) ){
  654. return false;
  655. }
  656. }
  657. }
  658.  
  659. if(condition["amountMore"]){
  660. for(var name in condition["amountMore"]){
  661. if( !(ConditionChecker.amount({name:name, operator: '>', amount:condition["amountMore"][name]})) ){
  662. return false;
  663. }
  664. }
  665. }
  666.  
  667. if(condition["balloon"]){
  668. var balloons = condition["balloon"];
  669. for(var x in balloons){
  670. if(!(ConditionChecker.hasSeenBalloon(balloons[x]))){
  671. return false;
  672. }
  673. }
  674. }
  675.  
  676. if(condition["role"]){
  677. if(!(ConditionChecker.isRole(condition["role"]["role"]))){
  678. return false;
  679. }
  680. }
  681.  
  682.  
  683. if(condition["state"]){
  684. if(!(ConditionChecker.activeState(condition["state"]["state"]))){
  685. return false;
  686. }
  687. }
  688.  
  689. if(condition["seen"]){
  690. var expectedAmount = condition["seen"]["seen"];
  691. var actualAmount = item.amountSeen || 0;
  692.  
  693. if(actualAmount > expectedAmount ){
  694. return false;
  695. }
  696. }
  697.  
  698. return true;
  699. }
  700.  
  701. this.canContinue = function(conditions, item){
  702. var possible = true;
  703.  
  704. if(conditions && !(conditions.length))
  705. return false;
  706.  
  707. for(var i=0; i < conditions.length; i++){
  708. var condition = conditions[i];
  709. var type = condition["OR"] ? "OR" : "AND";
  710.  
  711. if(type === "OR"){
  712. var sPossible = false;
  713.  
  714. for (var property in condition["OR"]) {
  715. if (condition["OR"].hasOwnProperty(property)) {
  716. var sub = condition["OR"][property];
  717.  
  718. if(singlePossibility(sub, item)){
  719. sPossible = true;
  720. }
  721. }
  722. }
  723.  
  724. if(!sPossible){
  725. possible = false;
  726. }
  727. }
  728. else {
  729. if(!(singlePossibility(condition, item))){
  730. possible = false;
  731. }
  732. }
  733. }
  734.  
  735. return possible;
  736. };
  737. this.execute = function(conditions, item){
  738. var met = true;
  739.  
  740. if(conditions && !(conditions.length))
  741. return false;
  742.  
  743. for(var i=0; i < conditions.length; i++){
  744. var condition = conditions[i];
  745.  
  746. if(!checkCondition(condition, item)){
  747. met = false;
  748. }
  749. }
  750.  
  751. return met;
  752. };
  753. this.amount = function(condition){
  754. var name = condition.name.toLowerCase();
  755. var amount = condition.amount;
  756. var operator = condition.operator;
  757. var expression;
  758.  
  759. switch(name){
  760. case 'backlogitems':
  761. expression = $rootScope[name].length;
  762. break;
  763. case 'backlogitems_status_concept':
  764. case 'backlogitems_status_refinement':
  765. case 'backlogitems_status_ready':
  766. var backlogitemsWithStatus = 0;
  767. var status = name.split("_")[name.split("_").length-1].toLowerCase();
  768.  
  769. for(x=0; x < $rootScope.backlogitems.length; x++){
  770. var pbi = $rootScope.backlogitems[x];
  771.  
  772. if(pbi.status.name.toLowerCase() === status){
  773. backlogitemsWithStatus++;
  774. }
  775. };
  776. expression = backlogitemsWithStatus;
  777. break;
  778. case 'goals':
  779. case 'epics':
  780. if($rootScope["epics"] && $rootScope["epics"].length == 1 && $rootScope["epics"][0].id == 0){
  781. // Sometimes a 'no-goal'/'no-epic' pops up in $rootScope, they appear with id 0, we do not count these so decrease by one
  782. expression = $rootScope["epics"].length-1;
  783. }
  784. else {
  785. expression = $rootScope["epics"].length;
  786. }
  787. case 'tags':
  788. expression = Object.keys($rootScope[name]).length;
  789. break;
  790. case 'sprints_future':
  791. expression = $rootScope.sprints.future.length;
  792. break;
  793. case 'sprints_historic':
  794. expression = $rootScope.sprints.historic.length;
  795. break;
  796. case 'sprints_current':
  797. expression = $rootScope.sprints.current.active === undefined ? 0 : $rootScope.sprints.current.active;
  798. break;
  799. }
  800. log("Amount " + name + "... Actual: " + expression + " " + operator + " " + amount + " (expected)");
  801. switch(operator){
  802. case '>':
  803. return expression > amount;
  804. case '<':
  805. return expression < amount;
  806. case '==':
  807. return expression == amount;
  808. }
  809. };
  810. this.activeState = function(stateName){
  811. var actualState = $state.current.name;
  812. log("Active state checking... expected: " + stateName + " actual: " + actualState);
  813. return actualState == stateName;
  814. };
  815. this.isRole = function(roleId){
  816. //return $rootScope.authObj.role.id == roleId;
  817. var role = $rootScope.authObj.role.id === 4 ? 1 : $rootScope.authObj.role.id;
  818. log("Role, expected: "+roleId+" actual: " + role);
  819.             return role == roleId;
  820. };
  821. this.hasSeenBalloon = function(name){
  822. log("Has seen balloon " + name + " ? " + $rootScope.balloons[name] && $rootScope.balloons[name].amountSeen > 0);
  823. return $rootScope.balloons[name] && $rootScope.balloons[name].amountSeen > 0;
  824. };
  825. }]).service('SweetAlert', function() {
  826. this.defaultSettings = {
  827. confirmButtonColor: "#449d44"
  828. };
  829. this.Input = function(option, callback) {
  830. var options = angular.copy(this.defaultSettings);
  831. options.showCancelButton = true;
  832. options.type = "input";
  833. for(x in option) options[x] = option[x];
  834.  
  835. if($('.confirm-all')) $('.confirm-all').remove();
  836. swal(options, callback);
  837. };
  838. this.Confirm = function(option, callback) {
  839. var options = angular.copy(this.defaultSettings);
  840. options.showCancelButton = true;
  841. options.type = "warning";
  842. options.title = "Are you sure?";
  843. for(x in option) options[x] = option[x];
  844.  
  845. if($('.confirm-all')) $('.confirm-all').remove();
  846. swal(options, callback);
  847. };
  848. this.Info = function(option, callback) {
  849. var options = angular.copy(this.defaultSettings);
  850. options.type = "info";
  851. for(x in option) options[x] = option[x];
  852.  
  853. if($('.confirm-all')) $('.confirm-all').remove();
  854. swal(options, callback);
  855. };
  856. this.Success = function(option, callback) {
  857. var options = angular.copy(this.defaultSettings);
  858. options.type = "success";
  859. for(x in option) options[x] = option[x];
  860.  
  861. if($('.confirm-all')) $('.confirm-all').remove();
  862. swal(options, callback);
  863. };
  864. this.Warning = function(option, callback) {
  865. var options = angular.copy(this.defaultSettings);
  866. options.type = "warning";
  867. for(x in option) options[x] = option[x];
  868.  
  869. if($('.confirm-all')) $('.confirm-all').remove();
  870. swal(options, callback);
  871. };
  872. this.Error = function(option, callback) {
  873. var options = angular.copy(this.defaultSettings);
  874. options.type = "error";
  875. for(x in option) options[x] = option[x];
  876.  
  877. if($('.confirm-all')) $('.confirm-all').remove();
  878. swal(options, callback);
  879. };
  880. }).filter('markDown', function() {
  881. return function(input) {
  882. if(!input) return;
  883. input = input.replace(/(?:\r\n|\r|\n)/g, '<br />');
  884.  
  885. input = input.replace(/\[(.*?)\]\((.+?)\)/g, function(matchStr ,var1 ,var2) {
  886. if(var2.startsWith("http")){
  887. return '<a target="_blank" href="'+var2+'" alt="'+var1+'">'+var1+'</a>';
  888. }
  889. else {
  890. return '<a ui-sref="'+var2+'" alt="'+var1+'">'+var1+'</a>';
  891. }
  892. });
  893.  
  894. return input;
  895. };
  896. }).factory('backlogitemService', ['$rootScope', 'Api', 'SweetAlert', 'Poller', '$uibModal', 'Debug', function($rootScope, Api, SweetAlert, Poller, $uibModal, Debug) {
  897. return {
  898. getExpanded : function(biid, callback){
  899. Api.Get("backlogitems/"+biid+"?expanded=all", function(result) {
  900. for(var x=0; x < result.backlogitem.tasks.length; x++){
  901. var task = result.backlogitem.tasks[x];
  902. task.name = htmlDecode(task.name);
  903. }
  904.  
  905. if(!result.backlogitem.description) result.backlogitem.description = "";
  906. if(!result.backlogitem.acceptance_criteria) result.backlogitem.acceptance_criteria = "";
  907.  
  908. result.backlogitem.getDate = function(key) {
  909. return moment(this[key], "YYYY-MM-DD HH:mm:ss").valueOf();
  910. };
  911.  
  912. callback(result.backlogitem);
  913. });
  914. },
  915. clone : function(pbi, event){
  916. event.stopPropagation();
  917. var biid = pbi.id ? pbi.id : pbi.biid;
  918.  
  919. Api.Post("api/backlogitems/clone/" + biid, false, function(){
  920. SweetAlert.Success({
  921. title: "Success",
  922. text : "Your duplicated backlogitem has been placed on the bottom of the backlog."
  923. });
  924. Poller.get("api/backlogs/"+$rootScope.authObj.backlog.id+"/items").run();
  925. Poller.get("api/subscriptions/"+$rootScope.authObj.subscription.id+"/products/"+ $rootScope.authObj.product.id).run();
  926. });
  927. },
  928. edit : function(pbi, event){
  929. event.stopPropagation();
  930. var biid = pbi.id ? pbi.id : pbi.biid;
  931.  
  932. $rootScope.editPBImodal = $uibModal.open({
  933. controller: "BacklogitemCtrl",
  934. templateUrl: 'views/modals/editBacklogitem.html',
  935. backdrop: false,
  936. resolve : {
  937. biid : function(){
  938. return biid;
  939. }
  940. },
  941. windowClass: "fullscreen-modal",
  942. });
  943. },
  944. delete : function(pbi, event){
  945. event.stopPropagation();
  946. var biid = pbi.id ? pbi.id : pbi.biid;
  947.  
  948. SweetAlert.Confirm({title: "Are you sure you want to delete this backlogitem?", text: pbi.name}, function(boolean) {
  949. Debug.info("Removing backlogitem ["+biid+"]", boolean);
  950. if (boolean == true) {
  951. Api.Delete("backlogitems/"+biid, function(result) {
  952. for(x in $rootScope.backlogitems)
  953. if($rootScope.backlogitems[x].id == biid)
  954. $rootScope.backlogitems.splice(x, 1);
  955. for(x in $rootScope.sprints.current.backlogitems)
  956. if($rootScope.sprints.current.backlogitems[x].id == biid)
  957. $rootScope.sprints.current.backlogitems.splice(x, 1);
  958.  
  959. Poller.get("api/backlogs/"+$rootScope.authObj.backlog.id+"/items").run();
  960. Poller.get("api/subscriptions/"+$rootScope.authObj.subscription.id+"/products/"+ $rootScope.authObj.product.id).run();
  961. });
  962. }
  963. });
  964. },
  965. split : function(pbi, event){
  966. event.stopPropagation();
  967. var biid = pbi.id ? pbi.id : pbi.biid;
  968.  
  969. $rootScope.splitPBImodal = $uibModal.open({
  970. templateUrl: 'views/splitBacklogitem.html',
  971. controller: 'SplitPBIctrl',
  972. backdrop: 'static',
  973. size: 'lg',
  974. resolve : {
  975. biid : function(){
  976. return biid;
  977. }
  978. }
  979. });
  980. },
  981. add : function(epicId){
  982. $rootScope.addPBImodal = $uibModal.open({
  983. templateUrl: 'views/modals/addBacklogitem.html',
  984. controller: 'AddBacklogitemCtrl',
  985. backdrop: false,
  986. resolve : { // Resolve 'injects' value (item & type) as a ctrl dependency, like $scope, SweetAlert, etc!
  987. epicId : function(){
  988. return epicId;
  989. }
  990. },
  991. windowClass: "fullscreen-modal"
  992. })
  993. }
  994. }
  995. }]).factory('authService', ['$rootScope', '$http', 'Idle', '$state', 'Misc', 'Session', 'Api', 'Debug', 'appConstants', 'Cookies',
  996. function($rootScope, $http, Idle, $state, Misc, Session, Api, Debug, appConstants, Cookies) {
  997.  
  998. this.getPermissions = function(path) {
  999. var permissions = {c:false, r:true, u:false, d:false};
  1000. var methods = Api.getAllowed(path);
  1001. if(methods) {
  1002. methods = methods.split(",");
  1003. methods.splice(-2); //Remove options and head;
  1004. for(i in methods) {
  1005. if(methods[i] == "POST")
  1006. permissions.c = true;
  1007. if(methods[i] == "GET")
  1008. permissions.r = true;
  1009. if(methods[i] == "PUT")
  1010. permissions.u = true;
  1011. if(methods[i] == "DELETE")
  1012. permissions.d = true;
  1013. }
  1014. }
  1015. return permissions;
  1016. };
  1017. this.hasAccess = function(path, type) {
  1018. var permissions = this.getPermissions(path);
  1019. switch(type) {
  1020. case "c":
  1021. case "create":
  1022. return permissions.c;
  1023. break;
  1024. case "r":
  1025. case "read":
  1026. return permissions.r;
  1027. break;
  1028. case "u":
  1029. case "update":
  1030. return permissions.u;
  1031. break;
  1032. case "d":
  1033. case "delete":
  1034. return permissions.d;
  1035. break;
  1036. default:
  1037. return false;
  1038. };
  1039. };
  1040. return {
  1041. getPermissions: this.getPermissions,
  1042. hasAccess: this.hasAccess,
  1043. hasSubscriptionOwnerPermissions: function() {
  1044. return $rootScope.authObj.role.id === 4;
  1045. },
  1046. hasProductownerPermissions: function() {
  1047. return $rootScope.authObj.role.id === 1 || $rootScope.authObj.role.id === 4;
  1048. },
  1049. hasStakeholderPermissions: function() {
  1050. return $rootScope.authObj.role.id === 3;
  1051. },
  1052. hasDeveloperPermissions: function() {
  1053. return $rootScope.authObj.role.id === 2;
  1054. },
  1055. login: function(email, password, callback) {
  1056. if(email != "anonymous") {
  1057. Api.Post("api/login", {loginDetails: {email: email, password: password}}, function(response) {
  1058. if(response && response.loginDetails) {
  1059. var data = response.loginDetails;
  1060. data.user.email = email;
  1061. data.user = Misc.populateMember(data.user);
  1062. Cookies.set('authObj', data);
  1063. Session.set('authObj', data);
  1064. $state.go(data.user.pref_state);
  1065.  
  1066. $rootScope.logoRoll();
  1067. if($rootScope.loginModal)
  1068. $rootScope.loginModal.close();
  1069. //if(data.user.firstLogin)
  1070. // $rootScope.showTipsAndTricks();
  1071. }
  1072. }, function(data, status) {
  1073. var errorMessage = "An unknown error occurred...";
  1074. if(data && data.loginDetails && data.loginDetails.result)
  1075. errorMessage = data.loginDetails.result;
  1076.  
  1077. if(data && data.login)
  1078. errorMessage = data;
  1079.  
  1080. callback(errorMessage, status);
  1081. });
  1082. }
  1083. },
  1084. updateUser: function(data) {
  1085. var authObj = Session.get('authObj') || Cookies.get('authObj');
  1086.  
  1087. for(x in data) {
  1088. if(data.hasOwnProperty(x))
  1089. authObj['user'][x] = data[x];
  1090. }
  1091. Cookies.set('authObj', authObj);
  1092. Session.set('authObj', authObj);
  1093. },
  1094. getUser: function() {
  1095. var authObj = Session.get('authObj') || Cookies.get('authObj');
  1096. if(authObj != null && authObj != "null") {
  1097. authObj.getName = function() { return this.user.firstname + " " + this.user.lastname; };
  1098. return authObj;
  1099. }
  1100. return false;
  1101. },
  1102. loggedin: function(redirect) {
  1103. var authObj = Session.get('authObj') || Cookies.get('authObj');
  1104. if(authObj != null && authObj != "null") {
  1105. Session.set('authObj', authObj);
  1106. $rootScope.authObj = authObj;
  1107. return true;
  1108. }
  1109. else if(redirect) {
  1110. $state.go("landingspage");
  1111. }
  1112. return false;
  1113. },
  1114. logout: function() {
  1115. $rootScope.permissions = undefined;
  1116.  
  1117. $rootScope.backlogitems = undefined;
  1118. $rootScope.sprints = undefined;
  1119. $rootScope.theme = 0;
  1120. $rootScope.members = undefined;
  1121. $rootScope.tags = undefined;
  1122. $rootScope.roles = undefined;
  1123. $rootScope.notifications = undefined;
  1124. $rootScope.balloons = undefined;
  1125. $rootScope.epics = undefined;
  1126. $rootScope.goals = undefined;
  1127. $rootScope.backlogHealth = undefined;
  1128.  
  1129. appConstants.init = 0;
  1130. Api.flushCache();
  1131. Session.clear();
  1132. Cookies.clear();
  1133. Idle.unwatch();
  1134. }
  1135. };
  1136. }]).factory('md5', ['Debug', function (Debug) {
  1137.  
  1138. function md5cycle(x, k) {
  1139. var a = x[0], b = x[1], c = x[2], d = x[3];
  1140.  
  1141. a = ff(a, b, c, d, k[0], 7, -680876936);
  1142. d = ff(d, a, b, c, k[1], 12, -389564586);
  1143. c = ff(c, d, a, b, k[2], 17, 606105819);
  1144. b = ff(b, c, d, a, k[3], 22, -1044525330);
  1145. a = ff(a, b, c, d, k[4], 7, -176418897);
  1146. d = ff(d, a, b, c, k[5], 12, 1200080426);
  1147. c = ff(c, d, a, b, k[6], 17, -1473231341);
  1148. b = ff(b, c, d, a, k[7], 22, -45705983);
  1149. a = ff(a, b, c, d, k[8], 7, 1770035416);
  1150. d = ff(d, a, b, c, k[9], 12, -1958414417);
  1151. c = ff(c, d, a, b, k[10], 17, -42063);
  1152. b = ff(b, c, d, a, k[11], 22, -1990404162);
  1153. a = ff(a, b, c, d, k[12], 7, 1804603682);
  1154. d = ff(d, a, b, c, k[13], 12, -40341101);
  1155. c = ff(c, d, a, b, k[14], 17, -1502002290);
  1156. b = ff(b, c, d, a, k[15], 22, 1236535329);
  1157.  
  1158. a = gg(a, b, c, d, k[1], 5, -165796510);
  1159. d = gg(d, a, b, c, k[6], 9, -1069501632);
  1160. c = gg(c, d, a, b, k[11], 14, 643717713);
  1161. b = gg(b, c, d, a, k[0], 20, -373897302);
  1162. a = gg(a, b, c, d, k[5], 5, -701558691);
  1163. d = gg(d, a, b, c, k[10], 9, 38016083);
  1164. c = gg(c, d, a, b, k[15], 14, -660478335);
  1165. b = gg(b, c, d, a, k[4], 20, -405537848);
  1166. a = gg(a, b, c, d, k[9], 5, 568446438);
  1167. d = gg(d, a, b, c, k[14], 9, -1019803690);
  1168. c = gg(c, d, a, b, k[3], 14, -187363961);
  1169. b = gg(b, c, d, a, k[8], 20, 1163531501);
  1170. a = gg(a, b, c, d, k[13], 5, -1444681467);
  1171. d = gg(d, a, b, c, k[2], 9, -51403784);
  1172. c = gg(c, d, a, b, k[7], 14, 1735328473);
  1173. b = gg(b, c, d, a, k[12], 20, -1926607734);
  1174.  
  1175. a = hh(a, b, c, d, k[5], 4, -378558);
  1176. d = hh(d, a, b, c, k[8], 11, -2022574463);
  1177. c = hh(c, d, a, b, k[11], 16, 1839030562);
  1178. b = hh(b, c, d, a, k[14], 23, -35309556);
  1179. a = hh(a, b, c, d, k[1], 4, -1530992060);
  1180. d = hh(d, a, b, c, k[4], 11, 1272893353);
  1181. c = hh(c, d, a, b, k[7], 16, -155497632);
  1182. b = hh(b, c, d, a, k[10], 23, -1094730640);
  1183. a = hh(a, b, c, d, k[13], 4, 681279174);
  1184. d = hh(d, a, b, c, k[0], 11, -358537222);
  1185. c = hh(c, d, a, b, k[3], 16, -722521979);
  1186. b = hh(b, c, d, a, k[6], 23, 76029189);
  1187. a = hh(a, b, c, d, k[9], 4, -640364487);
  1188. d = hh(d, a, b, c, k[12], 11, -421815835);
  1189. c = hh(c, d, a, b, k[15], 16, 530742520);
  1190. b = hh(b, c, d, a, k[2], 23, -995338651);
  1191.  
  1192. a = ii(a, b, c, d, k[0], 6, -198630844);
  1193. d = ii(d, a, b, c, k[7], 10, 1126891415);
  1194. c = ii(c, d, a, b, k[14], 15, -1416354905);
  1195. b = ii(b, c, d, a, k[5], 21, -57434055);
  1196. a = ii(a, b, c, d, k[12], 6, 1700485571);
  1197. d = ii(d, a, b, c, k[3], 10, -1894986606);
  1198. c = ii(c, d, a, b, k[10], 15, -1051523);
  1199. b = ii(b, c, d, a, k[1], 21, -2054922799);
  1200. a = ii(a, b, c, d, k[8], 6, 1873313359);
  1201. d = ii(d, a, b, c, k[15], 10, -30611744);
  1202. c = ii(c, d, a, b, k[6], 15, -1560198380);
  1203. b = ii(b, c, d, a, k[13], 21, 1309151649);
  1204. a = ii(a, b, c, d, k[4], 6, -145523070);
  1205. d = ii(d, a, b, c, k[11], 10, -1120210379);
  1206. c = ii(c, d, a, b, k[2], 15, 718787259);
  1207. b = ii(b, c, d, a, k[9], 21, -343485551);
  1208.  
  1209. x[0] = add32(a, x[0]);
  1210. x[1] = add32(b, x[1]);
  1211. x[2] = add32(c, x[2]);
  1212. x[3] = add32(d, x[3]);
  1213.  
  1214. }
  1215.  
  1216. function cmn(q, a, b, x, s, t) {
  1217. a = add32(add32(a, q), add32(x, t));
  1218. return add32((a << s) | (a >>> (32 - s)), b);
  1219. }
  1220.  
  1221. function ff(a, b, c, d, x, s, t) {
  1222. return cmn((b & c) | ((~b) & d), a, b, x, s, t);
  1223. }
  1224.  
  1225. function gg(a, b, c, d, x, s, t) {
  1226. return cmn((b & d) | (c & (~d)), a, b, x, s, t);
  1227. }
  1228.  
  1229. function hh(a, b, c, d, x, s, t) {
  1230. return cmn(b ^ c ^ d, a, b, x, s, t);
  1231. }
  1232.  
  1233. function ii(a, b, c, d, x, s, t) {
  1234. return cmn(c ^ (b | (~d)), a, b, x, s, t);
  1235. }
  1236.  
  1237. function md51(s) {
  1238. txt = '';
  1239. var n = s.length,
  1240. state = [1732584193, -271733879, -1732584194, 271733878], i;
  1241. for (i=64; i<=s.length; i+=64) {
  1242. md5cycle(state, md5blk(s.substring(i-64, i)));
  1243. }
  1244. s = s.substring(i-64);
  1245. var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
  1246. for (i=0; i<s.length; i++)
  1247. tail[i>>2] |= s.charCodeAt(i) << ((i%4) << 3);
  1248. tail[i>>2] |= 0x80 << ((i%4) << 3);
  1249. if (i > 55) {
  1250. md5cycle(state, tail);
  1251. for (i=0; i<16; i++) tail[i] = 0;
  1252. }
  1253. tail[14] = n*8;
  1254. md5cycle(state, tail);
  1255. return state;
  1256. }
  1257.  
  1258. /* there needs to be support for Unicode here,
  1259. * unless we pretend that we can redefine the MD-5
  1260. * algorithm for multi-byte characters (perhaps
  1261. * by adding every four 16-bit characters and
  1262. * shortening the sum to 32 bits). Otherwise
  1263. * I suggest performing MD-5 as if every character
  1264. * was two bytes--e.g., 0040 0025 = @%--but then
  1265. * how will an ordinary MD-5 sum be matched?
  1266. * There is no way to standardize text to something
  1267. * like UTF-8 before transformation; speed cost is
  1268. * utterly prohibitive. The JavaScript standard
  1269. * itself needs to look at this: it should start
  1270. * providing access to strings as preformed UTF-8
  1271. * 8-bit unsigned value arrays.
  1272. */
  1273. function md5blk(s) { /* I figured global was faster. */
  1274. var md5blks = [], i; /* Andy King said do it this way. */
  1275. for (i=0; i<64; i+=4) {
  1276. md5blks[i>>2] = s.charCodeAt(i)
  1277. + (s.charCodeAt(i+1) << 8)
  1278. + (s.charCodeAt(i+2) << 16)
  1279. + (s.charCodeAt(i+3) << 24);
  1280. }
  1281. return md5blks;
  1282. }
  1283.  
  1284. var hex_chr = '0123456789abcdef'.split('');
  1285.  
  1286. function rhex(n) {
  1287. var s='', j=0;
  1288. for(; j<4; j++)
  1289. s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
  1290. return s;
  1291. }
  1292.  
  1293. function hex(x) {
  1294. for (var i=0; i<x.length; i++)
  1295. x[i] = rhex(x[i]);
  1296. return x.join('');
  1297. }
  1298.  
  1299. function md5(s) {
  1300. return hex(md51(s));
  1301. }
  1302.  
  1303. /* this function is much faster,
  1304. so if possible we use it. Some IEs
  1305. are the only ones I know of that
  1306. need the idiotic second function,
  1307. generated by an if clause. */
  1308.  
  1309. function add32(a, b) {
  1310. return (a + b) & 0xFFFFFFFF;
  1311. }
  1312.  
  1313. if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') {
  1314. Debug.info('Incapable browser detected...');
  1315. function add32(x, y) {
  1316. var lsw = (x & 0xFFFF) + (y & 0xFFFF),
  1317. msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  1318. return (msw << 16) | (lsw & 0xFFFF);
  1319. }
  1320. }
  1321.  
  1322.  
  1323.  
  1324. return {
  1325. encode: function (input, forceLowerCase) {
  1326. input = (forceLowerCase === false) ? input : input.toLowerCase(); //Defaults to true
  1327. return hex(md51(input));
  1328. }
  1329. };
  1330. }]).factory('Base64', function () {
  1331. var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  1332.  
  1333. return {
  1334. encode: function (input) {
  1335. var output = "";
  1336. var chr1, chr2, chr3 = "";
  1337. var enc1, enc2, enc3, enc4 = "";
  1338. var i = 0;
  1339.  
  1340. do {
  1341. chr1 = input.charCodeAt(i++);
  1342. chr2 = input.charCodeAt(i++);
  1343. chr3 = input.charCodeAt(i++);
  1344.  
  1345. enc1 = chr1 >> 2;
  1346. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  1347. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  1348. enc4 = chr3 & 63;
  1349.  
  1350. if (isNaN(chr2)) {
  1351. enc3 = enc4 = 64;
  1352. } else if (isNaN(chr3)) {
  1353. enc4 = 64;
  1354. }
  1355.  
  1356. output = output +
  1357. keyStr.charAt(enc1) +
  1358. keyStr.charAt(enc2) +
  1359. keyStr.charAt(enc3) +
  1360. keyStr.charAt(enc4);
  1361. chr1 = chr2 = chr3 = "";
  1362. enc1 = enc2 = enc3 = enc4 = "";
  1363. } while (i < input.length);
  1364.  
  1365. return output;
  1366. },
  1367.  
  1368. decode: function (input) {
  1369. var output = "";
  1370. var chr1, chr2, chr3 = "";
  1371. var enc1, enc2, enc3, enc4 = "";
  1372. var i = 0;
  1373.  
  1374. // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
  1375. var base64test = /[^A-Za-z0-9\+\/\=]/g;
  1376. if (base64test.exec(input)) {
  1377. console.error("There were invalid base64 characters in the input text.\n" +
  1378. "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
  1379. "Expect errors in decoding.");
  1380. }
  1381. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  1382.  
  1383. do {
  1384. enc1 = keyStr.indexOf(input.charAt(i++));
  1385. enc2 = keyStr.indexOf(input.charAt(i++));
  1386. enc3 = keyStr.indexOf(input.charAt(i++));
  1387. enc4 = keyStr.indexOf(input.charAt(i++));
  1388.  
  1389. chr1 = (enc1 << 2) | (enc2 >> 4);
  1390. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  1391. chr3 = ((enc3 & 3) << 6) | enc4;
  1392.  
  1393. output = output + String.fromCharCode(chr1);
  1394.  
  1395. if (enc3 != 64) {
  1396. output = output + String.fromCharCode(chr2);
  1397. }
  1398. if (enc4 != 64) {
  1399. output = output + String.fromCharCode(chr3);
  1400. }
  1401.  
  1402. chr1 = chr2 = chr3 = "";
  1403. enc1 = enc2 = enc3 = enc4 = "";
  1404.  
  1405. } while (i < input.length);
  1406.  
  1407. return output;
  1408. }
  1409. };
  1410. }).service('Misc', ['appConstants', 'Debug', 'md5', function(appConstants, Debug, md5) {
  1411. this.populateMember = function(member) {
  1412. if(member.firstname == undefined || member.lastname == undefined) {
  1413. member.avatar = "images/avatar-placeholder.png";
  1414. }
  1415. else {
  1416. member.fullname = member.firstname + " " + member.lastname;
  1417. var bits = member.fullname.split(" "); //Strange method right? It's 'cus of surname prefixes!
  1418. member.initials = (bits[0].charAt(0) + bits[bits.length-1].charAt(0)).toUpperCase();
  1419. var i = getNum(bits[0].charAt(0)) + getNum(bits[bits.length-1].charAt(0));
  1420. var colors = ["#f44336", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5", "#2196f3", "#03a9f4", "#00bcd4", "#009688", "#4caf50", "#8bc34a", "#cddc39", "#ffeb3b", "#ffc107", "#ff9800", "#ff5722", "#795548", "#9e9e9e", "#607d8b"];
  1421. member.color = colors[Math.floor(colors.length / 52 * i)];
  1422. function getNum(a) { return parseInt(a, 36)-9; };
  1423.  
  1424. member.avatar = 'https://gravatar.com/avatar/' + md5.encode(member.email) + '?d=blank';
  1425. }
  1426. return member;
  1427. };
  1428. this.getStage = function() {
  1429. var stage = appConstants.stage;
  1430. if(!stage) {
  1431. switch (window.location.origin.split("//")[1]) {
  1432. case "priooo.com":
  1433. stage = "PRD";
  1434. break;
  1435. case "test.priooo.com":
  1436. stage = "TST";
  1437. break;
  1438. case "demo.priooo.com":
  1439. stage = "ACC";
  1440. break;
  1441. case "demo":
  1442. case "localhost":
  1443. case "priooo.dev":
  1444. case "localhost:8081":
  1445. case "localhost:8080":
  1446. case "demo:8081":
  1447. case "dev":
  1448. stage = "LOC";
  1449. break;
  1450. default:
  1451. stage = "PRD";
  1452. break;
  1453. }
  1454. }
  1455. return stage;
  1456. };
  1457. this.isDemo = function(){
  1458. return window.location.origin.split("//")[1] === "demo.priooo.com" || window.location.origin.split("//")[1] === "demo" || window.location.origin.split("//")[1] === "demo:8081"
  1459. };
  1460. this.getServerPath = function() {
  1461. var absolutePath = appConstants.server;
  1462. if(!absolutePath) {
  1463. absolutePath = window.location.origin;
  1464. if(absolutePath.indexOf('priooo.dev') >= 0)
  1465. absolutePath = "http://localhost:8080";
  1466. if(this.getStage() == "LOC")
  1467. absolutePath += "/iaf4asap";
  1468.  
  1469. }
  1470. if(absolutePath && absolutePath.slice(-1) != "/") absolutePath += "/";
  1471. return absolutePath;
  1472. };
  1473. this.getUserAgent = function(){
  1474. var ua = window.navigator.userAgent;
  1475.  
  1476. var msie = ua.indexOf('MSIE ');
  1477. if (msie > 0) {
  1478. // IE 10 or older => return version number
  1479. return 'Internet Explorer ' + parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
  1480. }
  1481.  
  1482. var trident = ua.indexOf('Trident/');
  1483. if (trident > 0) {
  1484. // IE 11 => return version number
  1485. var rv = ua.indexOf('rv:');
  1486. return 'Internet Explorer ' + parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);;
  1487. }
  1488.  
  1489. var edge = ua.indexOf('Edge/');
  1490. if (edge > 0) {
  1491. // Edge (IE 12+) => return version number
  1492. return 'Edge';
  1493. }
  1494.  
  1495. if((navigator.userAgent.indexOf("Opera") || navigator.userAgent.indexOf('OPR')) != -1 ) {
  1496. return 'Opera';
  1497. }
  1498.  
  1499. if(navigator.userAgent.indexOf("Chrome") != -1 ){
  1500. return 'Chrome';
  1501. }
  1502.  
  1503. if(navigator.userAgent.indexOf("Safari") != -1){
  1504. return 'Safari';
  1505. }
  1506.  
  1507. if(navigator.userAgent.indexOf("Firefox") != -1 ){
  1508. return 'Firefox';
  1509. }
  1510.  
  1511. // other browser
  1512. return 'Unknown';
  1513. };
  1514. this.isMobile = function() {
  1515. return ( navigator.userAgent.match(/Android/i)
  1516. || navigator.userAgent.match(/webOS/i)
  1517. || navigator.userAgent.match(/iPhone/i)
  1518. || navigator.userAgent.match(/iPad/i)
  1519. || navigator.userAgent.match(/iPod/i)
  1520. || navigator.userAgent.match(/BlackBerry/i)
  1521. || navigator.userAgent.match(/Windows Phone/i)
  1522. ) ? true : false;
  1523. };
  1524. this.compare_version = function(v1, v2, operator) {
  1525. // See for more info: http://locutus.io/php/info/version_compare/
  1526.  
  1527. var i, x, compare = 0;
  1528. var vm = {
  1529. 'dev': -6,
  1530. 'alpha': -5,
  1531. 'a': -5,
  1532. 'beta': -4,
  1533. 'b': -4,
  1534. 'RC': -3,
  1535. 'rc': -3,
  1536. '#': -2,
  1537. 'p': 1,
  1538. 'pl': 1
  1539. };
  1540.  
  1541. var _prepVersion = function (v) {
  1542. v = ('' + v).replace(/[_\-+]/g, '.');
  1543. v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.');
  1544. return (!v.length ? [-8] : v.split('.'));
  1545. };
  1546. var _numVersion = function (v) {
  1547. return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10));
  1548. };
  1549.  
  1550. v1 = _prepVersion(v1);
  1551. v2 = _prepVersion(v2);
  1552. x = Math.max(v1.length, v2.length);
  1553. for (i = 0; i < x; i++) {
  1554. if (v1[i] === v2[i]) {
  1555. continue;
  1556. }
  1557. v1[i] = _numVersion(v1[i]);
  1558. v2[i] = _numVersion(v2[i]);
  1559. if (v1[i] < v2[i]) {
  1560. compare = -1;
  1561. break;
  1562. } else if (v1[i] > v2[i]) {
  1563. compare = 1;
  1564. break;
  1565. }
  1566. }
  1567. if (!operator) {
  1568. return compare;
  1569. }
  1570.  
  1571. switch (operator) {
  1572. case '>':
  1573. case 'gt':
  1574. return (compare > 0);
  1575. case '>=':
  1576. case 'ge':
  1577. return (compare >= 0);
  1578. case '<=':
  1579. case 'le':
  1580. return (compare <= 0);
  1581. case '===':
  1582. case '=':
  1583. case 'eq':
  1584. return (compare === 0);
  1585. case '<>':
  1586. case '!==':
  1587. case 'ne':
  1588. return (compare !== 0);
  1589. case '':
  1590. case '<':
  1591. case 'lt':
  1592. return (compare < 0);
  1593. default:
  1594. return null;
  1595. }
  1596. };
  1597. }]).service('Alert', ['$timeout', 'Session', function($timeout, Session) {
  1598. this.add = function(level, message, non_repeditive) {
  1599. if(non_repeditive === true)
  1600. if(this.checkIfExists(message))
  1601. return;
  1602.  
  1603. var type;
  1604. switch(level) {
  1605. case "info":
  1606. case 1:
  1607. type = "fa fa-info";
  1608. break;
  1609. case "warning":
  1610. case 2:
  1611. type = "fa fa-warning";
  1612. break;
  1613. case "severe":
  1614. case 3:
  1615. type = "fa fa-times";
  1616. break;
  1617. default:
  1618. type = "fa fa-info";
  1619. break;
  1620. }
  1621. var list = this.get(true);
  1622. var obj = {
  1623. type: type,
  1624. message: message,
  1625. time: new Date().getTime()
  1626. };
  1627. list.unshift(obj);
  1628. obj.id = list.length;
  1629. Session.set("Alert", list);
  1630. //sessionStorage.setItem("Alert", JSON.stringify(list));
  1631. };
  1632. this.get = function(preserveList) {
  1633. //var list = JSON.parse(sessionStorage.getItem("Alert"));
  1634. var list = Session.get("Alert");
  1635. if(preserveList == undefined) Session.set("Alert", []); //sessionStorage.setItem("Alert", JSON.stringify([])); //Clear after retreival
  1636. return (list != null) ? list : [];
  1637. };
  1638. this.getCount = function() {
  1639. return this.get(true).length || 0;
  1640. };
  1641. this.checkIfExists = function(message) {
  1642. var list = this.get(true);
  1643. if(list.length > 0) {
  1644. for (var i = 0; i < list.length; i++) {
  1645. if(list[i].message == message) {
  1646. return true;
  1647. }
  1648. }
  1649. }
  1650. return false;
  1651. };
  1652. }]).config(['$httpProvider', function($httpProvider) {
  1653. $httpProvider.interceptors.push(['$rootScope', 'appConstants', '$q', '$location', 'Session', 'Misc', 'Debug', function($rootScope, appConstants, $q, $location, Session, Misc, Debug) {
  1654. return {
  1655. responseError: function(rejection) {
  1656. if(rejection.config && rejection.config.url && rejection.config.url.indexOf(Misc.getServerPath()) < 0) return;
  1657. switch (rejection.status) {
  1658. case -1:
  1659. //idle on back iets van resume polling?!?!?
  1660. //console.log(appConstants.init, rejection);
  1661. //Debug.warn("Something odd happened?!?!");
  1662. //registerError(rejection);
  1663. /*sessionStorage.setItem("authObj", null);
  1664. if(appConstants.init == 1) {
  1665. if(rejection.config.headers["Authorization"] != undefined) {
  1666. Alert.add(1, "Wrong password...", true);
  1667. }
  1668. }
  1669. if(appConstants.init == 2) {
  1670. if($location.path().indexOf("login") < 0)
  1671. sessionStorage.setItem('location', $location.path() || "status");
  1672. Alert.add(1, "Connection to the server was lost, please reauthenticate!", true);
  1673. }
  1674. $location.path("login");*/
  1675. break;
  1676. case 401:
  1677. if(rejection.config.url.indexOf('/login') > -1) break;
  1678. appConstants.init = 0;
  1679. Session.clear();
  1680. //var deferred = $q.defer();
  1681. //$rootScope.$broadcast('event:auth-loginRequired', rejection);
  1682. $location.path("logout");
  1683. //return deferred.promise;
  1684. break;
  1685. case 403:
  1686. //$rootScope.$broadcast('event:auth-forbidden', rejection);
  1687. break;
  1688. }
  1689. // otherwise, default behaviour
  1690. return $q.reject(rejection);
  1691. }
  1692. };
  1693. }]);
  1694. }]);
Add Comment
Please, Sign In to add comment