http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/lib/ng-mask.min.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/lib/ng-mask.min.js b/falcon-ui/app/js/lib/ng-mask.min.js new file mode 100644 index 0000000..71c1c6d --- /dev/null +++ b/falcon-ui/app/js/lib/ng-mask.min.js @@ -0,0 +1 @@ +!function(){"use strict";angular.module("ngMask",[])}(),function(){"use strict";angular.module("ngMask").directive("mask",["$log","$timeout","MaskService",function(a,b,c){return{restrict:"A",require:"ngModel",compile:function(d,e){function f(a){"number"==typeof a&&(b.cancel(g),g=b(function(){var b=a+1,c=d[0];if(c.setSelectionRange)c.focus(),c.setSelectionRange(a,b);else if(c.createTextRange){var e=c.createTextRange();e.collapse(!0),e.moveEnd("character",b),e.moveStart("character",a),e.select()}}))}if(!e.mask||!e.ngModel)return void a.info("Mask and ng-model attributes are required!");var g,h,i=c.create();return{pre:function(a,b,c){h=i.generateRegex({mask:c.mask,repeat:c.repeat||c.maskRepeat,clean:"true"===(c.clean||c.maskClean),limit:"true"===(c.limit||c.maskLimit||"true"),restrict:c.restrict||c.maskRestrict||"select",validate:"true"===(c.validate||c.maskValidate||"true"),model:c.ngModel,value:c.ngValue})},post:function(b,c,d,e){h.then(function(){function d(b){b=b||"";var c=i.getVie wValue(b),d=g.maskWithoutOptionals||"",h=c.withDivisors(!0),j=c.withoutDivisors(!0);try{var k=i.getRegex(h.length-1),l=i.getRegex(d.length-1),m=k.test(h)||l.test(h),n=b.length-h.length===1,o=d.length-h.length>0;if("accept"!==g.restrict)if("select"!==g.restrict||m&&!n)"reject"!==g.restrict||m||(c=i.removeWrongPositions(h),h=c.withDivisors(!0),j=c.withoutDivisors(!0));else{var p=b[b.length-1],q=h[h.length-1];p!==q&&o&&(h+=p);var r=i.getFirstWrongPosition(h);angular.isDefined(r)&&f(r)}g.limit||(h=c.withDivisors(!1),j=c.withoutDivisors(!1)),g.validate&&e.$dirty&&(l.test(h)||e.$isEmpty(e.$modelValue)?e.$setValidity("mask",!0):e.$setValidity("mask",!1)),b!==h&&(e.$setViewValue(angular.copy(h),"input"),e.$render())}catch(s){throw a.error("[mask - parseViewValue]"),s}return g.clean?j:h}var g=i.getOptions();e.$parsers.push(d),c.on("click input paste keyup",function(){d(c.val()),b.$apply()});var h=b.$watch(b.ngModel,function(a){angular.isDefined(a)&&(d(a),h())});g.value&&b.$evalAsync(function (){e.$setViewValue(angular.copy(g.value),"input"),e.$render()})})}}}}}])}(),function(){"use strict";angular.module("ngMask").factory("MaskService",["$q","OptionalService","UtilService",function(a,b,c){function d(){function d(a,b){var c;try{var d=t[a],e=C[d],f=h(a);e?c="("+e.source+")":(i(a)||(z.push(a),A[a]=d),c="(\\"+d+")")}catch(g){throw g}return(f||b)&&(c+="?"),new RegExp(c)}function e(a,b){var c,f;try{var g=d(a,b);c=g;var i=h(a),j=g.source;if(i&&u>a+1){var k=e(a+1,!0).elementOptionalRegex();j+=k.source}f=new RegExp(j)}catch(l){throw l}return{elementRegex:function(){return c},elementOptionalRegex:function(){return f}}}function f(c){var d=a.defer();s=c;try{var f=c.mask,g=c.repeat;g&&(f=Array(parseInt(g)+1).join(f)),w=b.getOptionals(f).fromMaskWithoutOptionals(),s.maskWithoutOptionals=t=b.removeOptionals(f),u=t.length;for(var h,i=0;u>i;i++){var l=e(i),m=l.elementRegex(),n=l.elementOptionalRegex(),o=h?h.source+n.source:n.source;o=new RegExp(o),h=h?h.source+m.source:m.source,h=new Re gExp(h),B.push(o)}j(),v=k(t).length,d.resolve({options:s,divisors:z,divisorElements:A,optionalIndexes:w,optionalDivisors:x,optionalDivisorsCombinations:y})}catch(p){throw d.reject(p),p}return d.promise}function g(a){var b;try{b=B[a]?B[a].source:""}catch(c){throw c}return new RegExp("^"+b+"$")}function h(a){return c.inArray(a,w)}function i(a){return c.inArray(a,z)}function j(){function a(a,b){return a-b}for(var b=z.sort(a),c=w.sort(a),d=0;d<b.length;d++)for(var e=b[d],f=1;f<=c.length;f++){var g=c[f-1];if(g>=e)break;x[e]=x[e]?x[e].concat(e-f):[e-f],A[e-f]=A[e]}}function k(a){try{if(z.length>0&&a){for(var b=Object.keys(A),d=[],e=b.length-1;e>=0;e--){var f=A[b[e]];f&&d.push(f)}d=c.uniqueArray(d);var g=new RegExp("[\\"+d.join("\\")+"]","g");return a.replace(g,"")}return a}catch(h){throw h}}function l(a,b){function d(a,b){for(var c=b,d=0;d<a.length;d++){var e=a[d];e<c.length&&c.splice(e,0,A[e])}return c}var e=a,f=z.filter(function(a){var d=Object.keys(x).map(function(a){return parseInt(a) });return!c.inArray(a,b)&&!c.inArray(a,d)});return angular.isArray(a)&&angular.isArray(b)?(e=d(f,e),e=d(b,e)):e}function m(a){var b=a.split(""),d=!0;if(w.length>0){for(var e=[],f=Object.keys(x),h=0;h<f.length;h++){var i=x[f[h]];e.push(i)}0===y.length&&c.lazyProduct(e,function(){y.push(Array.prototype.slice.call(arguments))});for(var h=y.length-1;h>=0;h--){var j=angular.copy(b);j=l(j,y[h]);var k=j.join(""),m=g(t.length-1);if(m.test(k)){d=!1,b=j;break}}}return d&&(b=l(b,z)),b.join("")}function n(){return s}function o(a){try{var b=k(a),c=m(b);return{withDivisors:function(a){return a?c.substr(0,u):c},withoutDivisors:function(a){return a?b.substr(0,v):b}}}catch(d){throw d}}function p(a,b){var c=[];if(!a)return 0;for(var d=0;d<a.length;d++){var e=g(d),f=a.substr(0,d+1);if(e&&!e.test(f)&&(c.push(d),b))break}return c}function q(a){return p(a,!0)[0]}function r(a){var b=p(a,!1),c=a;for(var d in b){var e=b[d],f=a.split("");f.splice(e,1),c=f.join("")}return o(c)}var s,t,u=0,v=0,w=[],x={},y=[],z =[],A={},B=[],C={9:/[0-9]/,8:/[0-8]/,7:/[0-7]/,6:/[0-6]/,5:/[0-5]/,4:/[0-4]/,3:/[0-3]/,2:/[0-2]/,1:/[0-1]/,0:/[0]/,"*":/./,w:/\w/,W:/\W/,d:/\d/,D:/\D/,s:/\s/,S:/\S/,b:/\b/,A:/[A-Z]/,a:/[a-z]/,Z:/[A-ZÃÃÃÃÃÃÃÃẼÃÃÃĨÃÃÃÃÃÃÃŨ]/,z:/[a-zçáà ãâéèêẽÃìĩîóòôõúùũüû]/,"@":/[a-zA-Z]/,"#":/[a-zA-Zçáà ãâéèêẽÃìĩîóòôõúùũüûÃÃÃÃÃÃÃÃẼÃÃÃĨÃÃÃÃÃÃÃŨ]/,"%":/[0-9a-zA-Zçáà ãâéèêẽÃìĩîóòôõúùũüûÃÃÃÃÃÃÃÃẼÃÃÃĨÃÃÃÃÃÃÃŨ]/};return{getViewValue:o,generateRegex:f,getRegex:g,getOptions:n,removeDivisors:k,getFirstWrongPosition:q,removeWrongPositions:r}}return{create:d}}])}(),function(){"use strict";angular.module("ngMask").factory("OptionalService",[function(){function a(a){var c=[];try{for(var d=/\?/g,e=[];null!=(e=d.exec(a));)c.push(e.index-1)}catch(f){throw f}return{fromMask:function(){return c},fromMaskWithoutOptionals:function(){return b(c)}}}function b(a){for(var b=[],c=0;c<a.length;c+ +)b.push(a[c]-c);return b}function c(a){var b;try{b=a.replace(/\?/g,"")}catch(c){throw c}return b}return{removeOptionals:c,getOptionals:a}}])}(),function(){"use strict";angular.module("ngMask").factory("UtilService",[function(){function a(a,b,c){function d(h){var i=a[h],j=g[h];if(h===f)for(var k=0;j>k;++k)e[h]=i[k],b.apply(c,e);else for(var k=0;j>k;++k)e[h]=i[k],d(h+1);e.pop()}c||(c=this);for(var e=[],f=a.length-1,g=[],h=a.length;h--;)g[h]=a[h].length;d(0)}function b(a,b){var c;try{c=b.indexOf(a)>-1}catch(d){throw d}return c}function c(a){for(var b={},c=[],d=0,e=a.length;e>d;++d)b.hasOwnProperty(a[d])||(c.push(a[d]),b[a[d]]=1);return c}return{lazyProduct:a,inArray:b,uniqueArray:c}}])}(); \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/lib/popover.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/lib/popover.js b/falcon-ui/app/js/lib/popover.js new file mode 100644 index 0000000..e26c870 --- /dev/null +++ b/falcon-ui/app/js/lib/popover.js @@ -0,0 +1,463 @@ +(function(window, angular, undefined){ + 'use strict'; + + var module = angular.module('nsPopover', []); + var $el = angular.element; + var isDef = angular.isDefined; + var $popovers = []; + var globalId = 0; + + module.provider('nsPopover', function () { + var defaults = { + template: '', + theme: 'ns-popover-list-theme', + plain: 'false', + trigger: 'click', + triggerPrevent: true, + angularEvent: '', + scopeEvent: '', + container: 'body', + placement: 'bottom|left', + timeout: 1.5, + hideOnInsideClick: false, + hideOnOutsideClick: true, + hideOnButtonClick: true, + mouseRelative: '', + popupDelay: 0 + }; + + this.setDefaults = function(newDefaults) { + angular.extend(defaults, newDefaults); + }; + + this.$get = function () { + return { + getDefaults: function () { + return defaults; + } + }; + }; + }); + + module.directive('nsPopover', ['nsPopover','$rootScope','$timeout','$templateCache','$q','$http','$compile','$document','$parse', + function(nsPopover, $rootScope, $timeout, $templateCache, $q, $http, $compile, $document, $parse) { + return { + restrict: 'A', + scope: true, + link: function(scope, elm, attrs) { + var defaults = nsPopover.getDefaults(); + + var options = { + template: attrs.nsPopoverTemplate || defaults.template, + theme: attrs.nsPopoverTheme || defaults.theme, + plain: toBoolean(attrs.nsPopoverPlain || defaults.plain), + trigger: attrs.nsPopoverTrigger || defaults.trigger, + triggerPrevent: attrs.nsPopoverTriggerPrevent || defaults.triggerPrevent, + angularEvent: attrs.nsPopoverAngularEvent || defaults.angularEvent, + scopeEvent: attrs.nsPopoverScopeEvent || defaults.scopeEvent, + container: attrs.nsPopoverContainer || defaults.container, + placement: attrs.nsPopoverPlacement || defaults.placement, + timeout: attrs.nsPopoverTimeout || defaults.timeout, + hideOnInsideClick: toBoolean(attrs.nsPopoverHideOnInsideClick || defaults.hideOnInsideClick), + hideOnOutsideClick: toBoolean(attrs.nsPopoverHideOnOutsideClick || defaults.hideOnOutsideClick), + hideOnButtonClick: toBoolean(attrs.nsPopoverHideOnButtonClick || defaults.hideOnButtonClick), + mouseRelative: attrs.nsPopoverMouseRelative, + popupDelay: attrs.nsPopoverPopupDelay || defaults.popupDelay, + group: attrs.nsPopoverGroup + }; + + if (options.mouseRelative) { + options.mouseRelativeX = options.mouseRelative.indexOf('x') !== -1; + options.mouseRelativeY = options.mouseRelative.indexOf('y') !== -1; + } + + var displayer_ = { + id_: undefined, + + /** + * Set the display property of the popover to 'block' after |delay| milliseconds. + * + * @param delay {Number} The time (in seconds) to wait before set the display property. + * @param e {Event} The event which caused the popover to be shown. + */ + display: function(delay, e) { + // Disable popover if ns-popover value is false + if ($parse(attrs.nsPopover)(scope) === false) { + return; + } + + $timeout.cancel(displayer_.id_); + + if (!isDef(delay)) { + delay = 0; + } + + // hide any popovers being displayed + if (options.group) { + $rootScope.$broadcast('ns:popover:hide', options.group); + } + + displayer_.id_ = $timeout(function() { + $popover.isOpen = true; + $popover.css('display', 'block'); + + // position the popover accordingly to the defined placement around the + // |elm|. + var elmRect = getBoundingClientRect(elm[0]); + + // If the mouse-relative options is specified we need to adjust the + // element client rect to the current mouse coordinates. + if (options.mouseRelative) { + elmRect = adjustRect(elmRect, options.mouseRelativeX, options.mouseRelativeY, e); + } + + move($popover, placement_, align_, elmRect, $triangle); + + if (options.hideOnInsideClick) { + // Hide the popover without delay on the popover click events. + $popover.on('click', insideClickHandler); + } + if (options.hideOnOutsideClick) { + // Hide the popover without delay on outside click events. + $document.on('click', outsideClickHandler); + } + if (options.hideOnButtonClick) { + // Hide the popover without delay on the button click events. + elm.on('click', buttonClickHandler); + } + }, delay*1000); + }, + + cancel: function() { + $timeout.cancel(displayer_.id_); + } + }; + + var hider_ = { + id_: undefined, + + /** + * Set the display property of the popover to 'none' after |delay| milliseconds. + * + * @param delay {Number} The time (in seconds) to wait before set the display property. + */ + hide: function(delay) { + $timeout.cancel(hider_.id_); + + // delay the hiding operation for 1.5s by default. + if (!isDef(delay)) { + delay = 1.5; + } + + hider_.id_ = $timeout(function() { + $popover.off('click', insideClickHandler); + $document.off('click', outsideClickHandler); + elm.off('click', buttonClickHandler); + $popover.isOpen = false; + displayer_.cancel(); + $popover.css('display', 'none'); + }, delay*1000); + }, + + cancel: function() { + $timeout.cancel(hider_.id_); + } + }; + + var $container = $document.find(options.container); + if (!$container.length) { + $container = $document.find('body'); + } + + var $triangle; + var placement_; + var align_; + + globalId += 1; + + var $popover = $el('<div id="nspopover-' + globalId +'"></div>'); + $popovers.push($popover); + + var match = options.placement + .match(/^(top|bottom|left|right)$|((top|bottom)\|(center|left|right)+)|((left|right)\|(center|top|bottom)+)/); + + if (!match) { + throw new Error('"' + options.placement + '" is not a valid placement or has a invalid combination of placements.'); + } + + placement_ = match[6] || match[3] || match[1]; + align_ = match[7] || match[4] || match[2] || 'center'; + + $q.when(loadTemplate(options.template, options.plain)).then(function(template) { + template = angular.isString(template) ? + template : + template.data && angular.isString(template.data) ? + template.data : + ''; + + $popover.html(template); + + if (options.theme) { + $popover.addClass(options.theme); + } + + // Add classes that identifies the placement and alignment of the popver + // which allows the customization of the popover based on its position. + $popover + .addClass('ns-popover-' + placement_ + '-placement') + .addClass('ns-popover-' + align_ + '-align'); + + $compile($popover)(scope); + + scope.$on('$destroy', function() { + $popover.remove(); + }); + + scope.hidePopover = function() { + hider_.hide(0); + }; + + scope.$on('ns:popover:hide', function(ev, group) { + if (options.group === group) { + scope.hidePopover(); + } + }); + + $popover + .css('position', 'absolute') + .css('display', 'none'); + + //search for the triangle element - works in ie8+ + $triangle = $popover[0].querySelectorAll('.triangle'); + //if the element is found, then convert it to an angular element + if($triangle.length){ + $triangle = $el($triangle); + } + + $container.append($popover); + }); + + if (options.angularEvent) { + $rootScope.$on(options.angularEvent, function() { + hider_.cancel(); + displayer_.display(options.popupDelay); + }); + } else if (options.scopeEvent) { + scope.$on(options.scopeEvent, function() { + hider_.cancel(); + displayer_.display($popover, options.popupDelay); + }); + } else { + elm.on(options.trigger, function(e) { + if (false !== options.triggerPrevent) { + e.preventDefault(); + } + hider_.cancel(); + displayer_.display(options.popupDelay, e); + }); + } + + elm + .on('mouseout', function() { + hider_.hide(options.timeout); + }) + .on('mouseover', function() { + hider_.cancel(); + }); + + $popover + .on('mouseout', function(e) { + hider_.hide(options.timeout); + }) + .on('mouseover', function() { + hider_.cancel(); + }); + + /** + * Move the popover to the |placement| position of the object located on the |rect|. + * + * @param popover {Object} The popover object to be moved. + * @param placement {String} The relative position to move the popover - top | bottom | left | right. + * @param align {String} The way the popover should be aligned - center | left | right. + * @param rect {ClientRect} The ClientRect of the object to move the popover around. + * @param triangle {Object} The element that contains the popover's triangle. This can be null. + */ + function move(popover, placement, align, rect, triangle) { + var popoverRect = getBoundingClientRect(popover[0]); + var top, left; + + var positionX = function() { + if (align === 'center') { + return Math.round(rect.left + rect.width/2 - popoverRect.width/2); + } else if(align === 'right') { + return rect.right - popoverRect.width; + } + return rect.left; + }; + + var positionY = function() { + if (align === 'center') { + return Math.round(rect.top + rect.height/2 - popoverRect.height/2); + } else if(align === 'bottom') { + return rect.bottom - popoverRect.height; + } + return rect.top; + }; + + if (placement === 'top') { + top = rect.top - popoverRect.height; + left = positionX(); + } else if (placement === 'right') { + top = positionY(); + left = rect.right; + } else if (placement === 'bottom') { + top = rect.bottom; + left = positionX(); + } else if (placement === 'left') { + top = positionY(); + left = rect.left - popoverRect.width; + } + + popover + .css('top', top.toString() + 'px') + .css('left', left.toString() + 'px'); + + if (triangle) { + if (placement === 'top' || placement === 'bottom') { + left = rect.left + rect.width / 2 - left; + triangle.css('left', left.toString() + 'px'); + } else { + top = rect.top + rect.height / 2 - top; + triangle.css('top', top.toString() + 'px'); + } + } + } + + /** + * Adjust a rect accordingly to the given x and y mouse positions. + * + * @param rect {ClientRect} The rect to be adjusted. + */ + function adjustRect(rect, adjustX, adjustY, ev) { + // if pageX or pageY is defined we need to lock the popover to the given + // x and y position. + // clone the rect, so we can manipulate its properties. + var localRect = { + bottom: rect.bottom, + height: rect.height, + left: rect.left, + right: rect.right, + top: rect.top, + width: rect.width + }; + + if (adjustX) { + localRect.left = ev.pageX; + localRect.right = ev.pageX; + localRect.width = 0; + } + + if (adjustY) { + localRect.top = ev.pageY; + localRect.bottom = ev.pageY; + localRect.height = 0; + } + + return localRect; + } + + function getBoundingClientRect(elm) { + var w = window; + var doc = document.documentElement || document.body.parentNode || document.body; + var x = (isDef(w.pageXOffset)) ? w.pageXOffset : doc.scrollLeft; + var y = (isDef(w.pageYOffset)) ? w.pageYOffset : doc.scrollTop; + var rect = elm.getBoundingClientRect(); + + // ClientRect class is immutable, so we need to return a modified copy + // of it when the window has been scrolled. + if (x || y) { + return { + bottom:rect.bottom+y, + left:rect.left + x, + right:rect.right + x, + top:rect.top + y, + height:rect.height, + width:rect.width + }; + } + return rect; + } + + function toBoolean(value) { + if (value && value.length !== 0) { + var v = ("" + value).toLowerCase(); + value = (v == 'true'); + } else { + value = false; + } + return value; + } + + /** + * Load the given template in the cache if it is not already loaded. + * + * @param template The URI of the template to be loaded. + * @returns {String} A promise that the template will be loaded. + * @remarks If the template is null or undefined a empty string will be returned. + */ + function loadTemplate(template, plain) { + if (!template) { + return ''; + } + + if (angular.isString(template) && plain) { + return template; + } + + return $templateCache.get(template) || $http.get(template, { cache : true }); + } + + function insideClickHandler() { + if ($popover.isOpen) { + hider_.hide(0); + } + } + + function outsideClickHandler(e) { + if ($popover.isOpen && e.target !== elm[0]) { + var id = $popover[0].id; + if (!isInPopover(e.target)) { + hider_.hide(0); + } + } + + function isInPopover(el) { + if (el.id === id) { + return true; + } + + var parent = angular.element(el).parent()[0]; + + if (!parent) { + return false; + } + + if (parent.id === id) { + return true; + } + else { + return isInPopover(parent); + } + } + } + + function buttonClickHandler() { + if ($popover.isOpen) { + hider_.hide(0); + } + } + } + }; + } + ]); +})(window, window.angular); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/services/common/date-helper.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/services/common/date-helper.js b/falcon-ui/app/js/services/common/date-helper.js new file mode 100644 index 0000000..b1f4b52 --- /dev/null +++ b/falcon-ui/app/js/services/common/date-helper.js @@ -0,0 +1,81 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +(function () { + 'use strict'; + + angular.module('dateHelper', []) + .factory('DateHelper', function () { + + var formatDigit = function(digit){ + if(digit<10){ + digit = "0"+digit; + } + return digit; + }; + + var dateHelper = {}; + + dateHelper.importDate = function (date, tz) { + if (!tz || tz === 'UTC') { + tz = "GMT+00:00"; + } + var rawDate = Date.parse(date); + var tzN = parseInt(tz.slice(3)); + var tzDate = new Date (rawDate + (3600000*tzN)); + + return new Date( + tzDate.getUTCFullYear(), + tzDate.getUTCMonth(), + tzDate.getUTCDate(), + tzDate.getUTCHours(), + tzDate.getUTCMinutes(), + 0, 0); + + }; + + dateHelper.createISO = function (date, time, tz) { + var UTC = new Date( + Date.UTC( + date.getUTCFullYear(), + date.getUTCMonth(), + date.getUTCDate(), + time.getHours(), + time.getMinutes(), + 0, 0 + ) + ).toUTCString() + tz.slice(3), + UTCRaw = Date.parse(UTC); + + var dateWithSecs = new Date(UTCRaw).toISOString(); + + return dateWithSecs.slice(0, -8) + "Z"; + + }; + + //i.e. 2015-09-10T16:35:21.235Z + dateHelper.createISOString = function (date, time) { + var result = date.getFullYear() + "-" + formatDigit(date.getMonth()+1) + "-" + formatDigit(date.getDate()) + + "T" + formatDigit(time.getHours()) + ":" + formatDigit(time.getMinutes()) + "Z"; + return result; + }; + + return dateHelper; + + }); + +})(); http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/services/common/falcon-api.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/services/common/falcon-api.js b/falcon-ui/app/js/services/common/falcon-api.js index cfb1ddc..a0b1bb7 100644 --- a/falcon-ui/app/js/services/common/falcon-api.js +++ b/falcon-ui/app/js/services/common/falcon-api.js @@ -17,112 +17,395 @@ */ (function () { 'use strict'; - + var falconModule = angular.module('app.services.falcon', ['app.services.x2js', 'ngCookies']); - falconModule.factory('Falcon', ["$http", "X2jsService", function ($http, X2jsService) { - - var Falcon = {}, - NUMBER_OF_RESULTS = 50; - - function buildURI(uri) { - var paramSeparator = (uri.indexOf('?') !== -1) ? '&' : '?'; - uri = uri + paramSeparator + 'user.name=ambari-qa'; - return uri; - } - - //-------------Server RESPONSE----------------------// - Falcon.responses = { - display:true, - queue:[], - count: {pending: 0, success:0, error:0}, - multiRequest: {cluster:0, feed:0, process:0}, - listLoaded: {cluster:false, feed:false, process:false} - }; - - Falcon.logRequest = function () { - Falcon.responses.count.pending = Falcon.responses.count.pending + 1; - - }; - Falcon.logResponse = function (type, messageObject, entityType, hide) { - if(type === 'success') { - if(!hide) { - var message = { success: true, status: messageObject.status, message: messageObject.message, requestId: messageObject.requestId}; - Falcon.responses.queue.push(message); - Falcon.responses.count.success = Falcon.responses.count.success +1; - } - Falcon.responses.count.pending = Falcon.responses.count.pending -1; - } - if(type === 'error') { - - if(messageObject.slice(0,6) !== "Cannot") { - var errorMessage = X2jsService.xml_str2json(messageObject), - message = { success: false, status: errorMessage.result.status, message: errorMessage.result.message, requestId: errorMessage.result.requestId}; - } - else { - var message = { success: false, status: "No connection", message: messageObject, requestId: "no ID"}; - } - Falcon.responses.queue.push(message); - Falcon.responses.count.error = Falcon.responses.count.error +1; - Falcon.responses.count.pending = Falcon.responses.count.pending -1; + falconModule.factory('Falcon', ["$http", "X2jsService", "$location", '$rootScope', '$cookieStore', '$timeout', + function ($http, X2jsService, $location, $rootScope, $cookieStore, $timeout) { + + var Falcon = {}, + NUMBER_OF_ENTITIES = 10, + NUMBER_OF_INSTANCES = 11; // 10 + 1 for next page + + function buildURI(uri) { + if ($rootScope.ambariView()) { + uri = uri.substring(2); + uri = $rootScope.serviceURI + uri; + } else { + if(!$rootScope.secureMode){ + uri = add_user(uri); + } + } + console.log(uri); + return uri; } - if(entityType !== false) { - entityType = entityType.toLowerCase(); - Falcon.responses.multiRequest[entityType] = Falcon.responses.multiRequest[entityType] - 1; + + function add_user(uri) { + var userToken = $cookieStore.get('userToken'); + var paramSeparator = (uri.indexOf('?') !== -1) ? '&' : '?'; + uri = uri + paramSeparator + 'user.name=' + userToken.user; + return uri; } - - }; - Falcon.removeMessage = function (index) { - if(Falcon.responses.queue[index].success) { Falcon.responses.count.success = Falcon.responses.count.success -1; } - else { Falcon.responses.count.error = Falcon.responses.count.error -1; } - Falcon.responses.queue.splice(index, 1); - }; - // serverResponse: null, - // success: null - - //-------------METHODS-----------------------------// - Falcon.getServerVersion = function () { - return $http.get(buildURI('../api/admin/version')); - }; - Falcon.getServerStack = function () { - return $http.get(buildURI('../api/admin/stack')); - }; - Falcon.postValidateEntity = function (xml, type) { - return $http.post(buildURI('../api/entities/validate/' + type), xml, { headers: {'Content-Type': 'text/plain'} }); - }; - Falcon.postSubmitEntity = function (xml, type) { - return $http.post(buildURI('../api/entities/submit/' + type), xml, { headers: {'Content-Type': 'text/plain'} }); - }; - Falcon.postUpdateEntity = function (xml, type, name) { - return $http.post(buildURI('../api/entities/update/' + type + '/' + name), xml, { headers: {'Content-Type': 'text/plain'} }); - }; - - Falcon.postScheduleEntity = function (type, name) { - return $http.post(buildURI('../api/entities/schedule/' + type + '/' + name)); - }; - Falcon.postSuspendEntity = function (type, name) { - return $http.post(buildURI('../api/entities/suspend/' + type + '/' + name)); - }; - Falcon.postResumeEntity = function (type, name) { - return $http.post(buildURI('../api/entities/resume/' + type + '/' + name)); - }; - - Falcon.deleteEntity = function (type, name) { - return $http.delete(buildURI('../api/entities/delete/' + type + '/' + name)); - }; - - Falcon.getEntities = function (type) { - return $http.get(buildURI('../api/entities/list/' + type + '?fields=status,tags&numResults=' + NUMBER_OF_RESULTS)); - }; - - Falcon.getEntityDefinition = function (type, name) { - return $http.get(buildURI('../api/entities/definition/' + type + '/' + name), { headers: {'Accept': 'text/plain'} }); - }; - - - //----------------------------------------------// - return Falcon; - - }]); + + //response Order + Falcon.orderBy = { + enable: false, + name: "asc" + }; + + //-------------Server RESPONSE----------------------// + Falcon.responses = { + display: true, + queue: [], + count: {pending: 0, success: 0, error: 0}, + multiRequest: {cluster: 0, feed: 0, process: 0}, + listLoaded: {cluster: false, feed: false, process: false} + }; + + Falcon.logRequest = function () { + Falcon.responses.count.pending = Falcon.responses.count.pending + 1; + }; + + Falcon.responses.showAll = false; + Falcon.responses.isVisible = false; + + Falcon.hide = function () { + Falcon.hideTimeout = $timeout(function () { + $(".notifs").fadeOut(300); + }, 5000); + }; + + Falcon.responses.unreaded = 0; + Falcon.notify = function (showAll) { + $(".notifs").stop(); + $timeout.cancel(Falcon.hideTimeout); + + if (showAll) { + Falcon.responses.unreaded = 0; + if (Falcon.responses.isVisible) { + Falcon.responses.isVisible = false; + $(".notifs").fadeOut(300); + } else { + Falcon.responses.isVisible = true; + $(".notifs").hide(); + $(".notifs").fadeIn(300); + } + Falcon.responses.showAll = true; + } else { + Falcon.responses.unreaded++; + Falcon.responses.isVisible = false; + $(".notifs").stop(); + $(".notifs").hide(); + $(".notifs").fadeIn(300); + $(".notifs").fadeOut(300); + $(".notifs").fadeIn(300); + $(".notifs").fadeOut(300); + $(".notifs").fadeIn(300); + Falcon.hide(); + Falcon.responses.showAll = false; + } + }; + + Falcon.hideNotifs = function () { + $(".notifs").stop(); + $timeout.cancel(Falcon.hideTimeout); + Falcon.responses.isVisible = false; + $(".notifs").fadeOut(300); + Falcon.responses.queue.forEach(function(notifMsg) { + notifMsg.readed = true; + }); + }; + + Falcon.logResponse = function (type, messageObject, entityType, hide) { + if (type === 'success') { + if (!hide) { + var response = { + success: true, + type: "success", + status: messageObject.status, + message: messageObject.message, + requestId: messageObject.requestId, + readed: false + }; + Falcon.responses.queue.push(response); + Falcon.responses.count.success = Falcon.responses.count.success + 1; + Falcon.notify(false); + } + Falcon.responses.count.pending = Falcon.responses.count.pending - 1; + } + if (type === 'cancel') { + if (!hide) { + var response = { + success: true, + type: "cancel", + status: messageObject.state, + state: messageObject.state, + message: messageObject.message, + model: messageObject.model, + readed: false + }; + Falcon.responses.queue.push(response); + Falcon.notify(false); + return; + } + } + if (type === 'error') { + if (messageObject.status !== undefined) { + var response = { + success: false, + type: "error", + status: messageObject.status, + message: messageObject.message, + requestId: messageObject.requestId, + readed: false + }; + } else { + if (messageObject.slice(0, 6) !== "Cannot") { + var errorMessage = X2jsService.xml_str2json(messageObject); + var response = { + success: false, + type: "error", + status: errorMessage.result ? errorMessage.result.status : 'error', + message: errorMessage.result ? errorMessage.result.message : 'Unexpected Error', + requestId: errorMessage.result ? errorMessage.result.requestId : 0, + readed: false + }; + } + else { + var response = { + success: false, + type: "error", + status: "No connection", + message: messageObject, + requestId: "no ID", + readed: false + }; + } + } + if (hide) { + Falcon.responses.count.pending = Falcon.responses.count.pending - 1; + return; //>> just takes out the pending request and returns from the func + } + Falcon.responses.queue.push(response); + Falcon.responses.count.error = Falcon.responses.count.error + 1; + Falcon.responses.count.pending = Falcon.responses.count.pending - 1; + Falcon.notify(false); + } + if (type === 'warning') { + if (!hide) { + var response = { + success: true, + type: "warning", + status: messageObject.status, + message: messageObject.message, + model: '', + readed: false + }; + Falcon.responses.queue.push(response); + Falcon.notify(false); + return; + } + } + if (entityType && entityType !== false) { + entityType = entityType.toLowerCase(); + Falcon.responses.multiRequest[entityType] = Falcon.responses.multiRequest[entityType] - 1; + } + + }; + Falcon.removeMessage = function (index) { + if (index === -1) { + index = Falcon.responses.queue.length - 1; + } + if (Falcon.responses.queue[index].success) { + Falcon.responses.count.success = Falcon.responses.count.success - 1; + } + else { + Falcon.responses.count.error = Falcon.responses.count.error - 1; + } + Falcon.responses.queue.splice(index, 1); + }; + + + Falcon.errorMessage = function (message) { + var response = { + type: "error", + message: message, + readed: false + }; + Falcon.responses.queue.push(response); + Falcon.notify(false); + }; + Falcon.warningMessage = function (message) { + var response = { + type: "warning", + message: message, + readed: false + }; + Falcon.responses.queue.push(response); + Falcon.notify(false); + }; + + //-------------METHODS-----------------------------// + + Falcon.getServerConfig = function () { + return $http.get('../api/admin/version?user.name=falcon'); + }; + + Falcon.getServerStack = function () { + return $http.get(buildURI('../api/admin/stack')); + }; + + Falcon.clearUser = function () { + return $http.get('../api/admin/clearuser?user.name=falcon'); + }; + + Falcon.getCurrentUser = function () { + return $http.get('../api/admin/getuser'); + }; + + Falcon.postValidateEntity = function (xml, type) { + return $http.post(buildURI('../api/entities/validate/' + type), xml, {headers: {'Content-Type': 'text/plain'}}); + }; + Falcon.postSubmitEntity = function (xml, type) { + return $http.post(buildURI('../api/entities/submit/' + type), xml, {headers: {'Content-Type': 'text/plain'}}); + }; + Falcon.postUpdateEntity = function (xml, type, name) { + return $http.post(buildURI('../api/entities/update/' + type + '/' + name), xml, {headers: {'Content-Type': 'text/plain'}}); + }; + + Falcon.postScheduleEntity = function (type, name) { + return $http.post(buildURI('../api/entities/schedule/' + type + '/' + name)); + }; + Falcon.postSuspendEntity = function (type, name) { + return $http.post(buildURI('../api/entities/suspend/' + type + '/' + name)); + }; + Falcon.postResumeEntity = function (type, name) { + return $http.post(buildURI('../api/entities/resume/' + type + '/' + name)); + }; + + Falcon.deleteEntity = function (type, name) { + return $http.delete(buildURI('../api/entities/delete/' + type + '/' + name)); + }; + + Falcon.getEntities = function (type) { + return $http.get(buildURI('../api/entities/list/' + type + '?fields=status,tags&numResults=' + NUMBER_OF_ENTITIES)); + }; + + Falcon.getEntityDefinition = function (type, name) { + return $http.get(buildURI('../api/entities/definition/' + type + '/' + name), {headers: {'Accept': 'text/plain'}}); + }; + + Falcon.searchEntities = function (name, tags, entityType, offset, order) { + var searchUrl = "../api/entities/list/"; + if (entityType !== undefined && entityType !== "") { + if (entityType === "mirror") { + if (tags === undefined || tags === "") { + tags = "_falcon_mirroring_type"; + } else { + tags += ",_falcon_mirroring_type"; + } + searchUrl += "process"; + } else { + searchUrl += entityType; + } + } else { + //searchUrl += "all"; + //searchUrl += "schedulable"; + searchUrl += "feed,process"; + } + searchUrl += "?fields=clusters,tags,status"; + if (name !== undefined && name !== "") { + if (name !== "*") { + searchUrl += "&nameseq=" + name; + } + } + if (tags !== undefined && tags !== "") { + searchUrl += "&tagkeys=" + tags; + } + if (offset !== undefined && offset !== "") { + searchUrl += '&offset=' + offset + '&numResults=' + NUMBER_OF_ENTITIES; + } + if (Falcon.orderBy.enable) { + searchUrl += '&orderBy=name&sortOrder=' + Falcon.orderBy.name; + } + return $http.get(buildURI(searchUrl)); + }; + + Falcon.searchInstances = function (type, name, offset, start, end, status, orderBy, sortOrder) { + //var searchUrl = "../api/instance/running/" + type + "/" + name + "?colo=*"; + //var searchUrl = "../api/instance/list/" + type + "/" + name + "?colo=*"; + var searchUrl = "../api/instance/logs/" + type + "/" + name + "?colo=*"; + if (start !== undefined && start !== "") { + searchUrl += "&start=" + start; + } + if (end !== undefined && end !== "") { + searchUrl += "&end=" + end; + } + if (status !== undefined && status !== "") { + searchUrl += "&filterBy=STATUS:" + status; + } + if (orderBy !== undefined && orderBy !== "") { + searchUrl += "&orderBy=" + orderBy; + } else { + searchUrl += "&orderBy=startTime"; + } + if (sortOrder !== undefined && sortOrder !== "") { + searchUrl += "&sortOrder=" + sortOrder; + } + searchUrl += '&offset=' + offset + '&numResults=' + NUMBER_OF_INSTANCES; + return $http.get(buildURI(searchUrl)); + }; + + Falcon.getInstanceLog = function (logUrl) { + return $http.get(buildURI(logUrl), {headers: {'Accept': 'text/plain'}}); + }; + + Falcon.postResumeInstance = function (entityType, entityName, start, end) { + return $http.post(buildURI('../api/instance/resume/' + entityType + '/' + entityName + '?colo=*&start=' + start + '&end=' + end)); + }; + + Falcon.postSuspendInstance = function (entityType, entityName, start, end) { + return $http.post(buildURI('../api/instance/suspend/' + entityType + '/' + entityName + '?colo=*&start=' + start + '&end=' + end)); + }; + + Falcon.postKillInstance = function (entityType, entityName, start, end) { + return $http.post(buildURI('../api/instance/kill/' + entityType + '/' + entityName + '?colo=*&start=' + start + '&end=' + end)); + }; + + Falcon.postReRunInstance = function (entityType, entityName, start, end) { + return $http.post(buildURI('../api/instance/rerun/' + entityType + '/' + entityName + '?colo=*&start=' + start + '&end=' + end)); + }; + + Falcon.getEntityDependencies = function (type, name) { + return $http.get(buildURI('../api/entities/dependencies/' + type + '/' + name)); + }; + + Falcon.getInstanceVertices = function (value) { + return $http.get(buildURI('../api/metadata/lineage/vertices?key=name&value=' + value)); + }; + + Falcon.getInstanceVerticesDirection = function (id, direction) { + return $http.get(buildURI('../api/metadata/lineage/vertices/' + id + '/' + direction)); + }; + + Falcon.getInstanceVerticesProps = function (id) { + return $http.get(buildURI('../api/metadata/lineage/vertices/properties/' + id + '?relationships=true')); + }; + + //----------------------------------------------// + Falcon.getInstancesSummary = function (type, mode, from, to) { + return $http.get(buildURI('../api/instance/summary/' + type + '/' + mode + '?start=' + from + '&end=' + to)); + }; + Falcon.getTopEntities = function (entityType, from, to) { + return $http.get(buildURI('../api/entities/top/' + entityType + '?start=' + from + '&end=' + to)); + }; + //----------------------------------------------// + Falcon.postSubmitRecipe = function (recipe) { + return $http.post(buildURI('../api/entities/prepareAndSubmitRecipe'), recipe, {headers: {'Content-Type': 'text/plain'}}); + }; + + return Falcon; + + }]); })(); http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/services/common/server-api.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/services/common/server-api.js b/falcon-ui/app/js/services/common/server-api.js new file mode 100644 index 0000000..9224179 --- /dev/null +++ b/falcon-ui/app/js/services/common/server-api.js @@ -0,0 +1,88 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +(function () { + 'use strict'; + + var app = angular.module('app.services.server', ['app.services']); + + app.factory('ServerAPI', [ + "Falcon", "$q", + function (Falcon, $q) { + + var ServerAPI = {}; + + ServerAPI.getServerConfig = function(){ + var deffered = $q.defer(); + Falcon.logRequest(); + Falcon.getServerConfig().success(function (data) { + Falcon.logResponse('success', data, false, true); + ServerAPI.data = data; + deffered.resolve(); + }).error(function (err) { + Falcon.logResponse('error', err); + deffered.resolve(); + }); + return deffered.promise; + }; + + ServerAPI.setOptions = function(username){ + var deffered = $q.defer(); + Falcon.logRequest(); + Falcon.setOptions(username).success(function (data) { + Falcon.logResponse('success', data, false, true); + deffered.resolve(); + }).error(function (err) { + Falcon.logResponse('error', err); + deffered.resolve(); + }); + return deffered.promise; + }; + + ServerAPI.clearUser = function(){ + var deffered = $q.defer(); + Falcon.logRequest(); + Falcon.clearUser().success(function (data) { + Falcon.logResponse('success', data, false, true); + ServerAPI.setted = data; + deffered.resolve(); + }).error(function (err) { + Falcon.logResponse('error', err); + deffered.resolve(); + }); + return deffered.promise; + }; + + ServerAPI.getCurrentUser = function(){ + var deffered = $q.defer(); + Falcon.logRequest(); + Falcon.getCurrentUser().success(function (data) { + Falcon.logResponse('success', data, false, true); + ServerAPI.user = data; + deffered.resolve(); + }).error(function (err) { + Falcon.logResponse('error', err); + deffered.resolve(); + }); + return deffered.promise; + }; + + return ServerAPI; + + }]); + +}()); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/services/common/validation-service.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/services/common/validation-service.js b/falcon-ui/app/js/services/common/validation-service.js index 461f073..ff2f4ef 100644 --- a/falcon-ui/app/js/services/common/validation-service.js +++ b/falcon-ui/app/js/services/common/validation-service.js @@ -24,7 +24,7 @@ var checkMessages = { name: { patternInvalid: "The name has an invalid format.", - unavailable: "The name you chose is not available", + unavailable: "The name you choosed is not available", empty: "You need to specify a name" }, colo: { @@ -55,29 +55,95 @@ empty: "You need to provide a provider", patternInvalid: "The provider has an invalid format. " }, + acl: { + owner: { + empty: "You need to provide an owner", + patternInvalid: "The Owner has an invalid format. " + }, + group: { + empty: "You need to provide a group", + patternInvalid: "The Group has an invalid format. "}, + permission: { + empty: "You need to provide a Permission", + patternInvalid: "The Permission has an invalid format. " + } + }, engine: { empty: "You need to select an engine" }, cluster: { empty: "You need to select a cluster" }, feed: { empty: "You need to select a feed" }, - date: { empty: "You need to select a date" }, - number: { empty: "You need to provide a number" }, + date: { + empty: "You need to select a date", + startAfterEnd: "Start date must be before end date.", + patternInvalid: "The start Date has an invalid format. " + }, + number: { + empty: "You need to provide a number", + patternInvalid: "The number needs to be one or two digits " + }, option: { empty: "You need to select an option" }, - user: { empty: "Please enter your user name." }, - password: { empty: "Please enter your password." }, - engineName: { patternInvalid: "The name has an invalid format." } + user: { + empty: "Please enter your user name.", + patternInvalid: "The User has an invalid format." + }, + password: { + empty: "Please enter your password.", + patternInvalid: "The Password has an invalid format." + }, + email: { + patternInvalid: "The email is invalid." + }, + allocationNumber: { + empty: "You need to provide a number", + patternInvalid: "The number you provided is invalid " + }, + permission: { + empty: "You need to provide a Permission", + patternInvalid: "The Permission has an invalid format. " + }, + url: { + empty: "You need to provide a URL", + patternInvalid: "The URL has an invalid format. " + }, + databases: { + empty: "You need to provide the databases", + patternInvalid: "The Databases have an invalid format. " + }, + database: { + empty: "You need to provide the database", + patternInvalid: "The database has an invalid format. " + }, + tables: { + empty: "You need to provide the tables", + patternInvalid: "The tables have an invalid format. " + }, + s3: { + empty: "You need to provide a S3 URL", + patternInvalid: "The URL has an invalid format. It needs to start with 's3' and end with '.amazonaws.com'" + }, + azure: { + empty: "You need to provide an Azure URL", + patternInvalid: "The URL has an invalid format. It needs to end with '.blob.core.windows.net'" + } }, checkPatterns = { - name: new RegExp("^(([a-zA-Z]([\\-a-zA-Z0-9])*){1,39})$"), - id: new RegExp("^(([a-zA-Z]([\\-a-zA-Z0-9])*){1,39})$"), + name: new RegExp("^[a-zA-Z0-9-_]{1,60}$"), + id: new RegExp("^(([a-zA-Z]([\\-a-zA-Z0-9_])*){1,39})$"), password: new RegExp("^(([a-zA-Z]([\\-a-zA-Z0-9])*){1,39})$"), freeText: new RegExp("^([\\sa-zA-Z0-9]){1,40}$"), - alpha: new RegExp("^([a-zA-Z0-9]){1,100}$"), - commaSeparated: new RegExp("/^[a-zA-Z0-9,]{1,80}$"), - unixId: new RegExp("^([a-z_][a-z0-9-_\\.\\-]{0,30})$"), - unixPermissions: new RegExp("^((([0-7]){1,4})|(\\*))$"), + textarea: new RegExp("^([\\sa-zA-Z0-9,]){1,100}$"), + alpha: new RegExp("^([a-zA-Z0-9-_]){1,100}$"), + commaSeparated: new RegExp("^[a-zA-Z0-9,]{1,80}$"), + unixId: new RegExp("^([a-zA-Z_][a-zA-Z0-9-_\\.\\-]{0,30})$"), + unixPermissions: new RegExp("^((([x0-7]){1,5})|(\\*))$"), osPath: new RegExp("^[^\\0 ]+$"), - twoDigits: new RegExp("^([0-9]){1,2}$"), + twoDigits: new RegExp("^([0-9]){1,4}$"), //>> requirement change to 4 digits, just to dont change all inputs that reference this tableUri: new RegExp("^[^\\0]+$"), - versionNumbers: new RegExp("^[0-9]{1,2}\\.[0-9]{1,2}\\.[0-9]{1,2}$") + versionNumbers: new RegExp("^[0-9]{1,2}\\.[0-9]{1,2}\\.[0-9]{1,2}$"), + url: new RegExp("^[^\\0 ]+\\.[a-zA-Z0-9]{1,3}$"), + number: new RegExp("^([-0-9]){1,40}$"), + email: new RegExp("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$"), + s3: new RegExp("^s3[a-zA-Z0-9._%+-:\\/]+\\.amazonaws.com$"), + azure: new RegExp("^[a-zA-Z0-9._%+-:@\\/]+\\.blob.core.windows.net$") }; function acceptOnlyNumber(evt) { @@ -85,10 +151,12 @@ key = theEvent.keyCode || theEvent.which, BACKSPACE = 8, DEL = 46, + ENTER = 13, ARROW_KEYS = {left: 37, right: 39}, + TAB = 9, regex = /[0-9]|\./; - if (key === BACKSPACE || key === DEL || key === ARROW_KEYS.left || key === ARROW_KEYS.right) { + if (key === BACKSPACE || key === DEL || key === ARROW_KEYS.left || key === ARROW_KEYS.right || key === TAB || key === ENTER) { return true; } http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/services/entity/entity-factory.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/services/entity/entity-factory.js b/falcon-ui/app/js/services/entity/entity-factory.js index c64ad98..82848c0 100644 --- a/falcon-ui/app/js/services/entity/entity-factory.js +++ b/falcon-ui/app/js/services/entity/entity-factory.js @@ -19,7 +19,17 @@ 'use strict'; var module = angular.module('app.services.entity.factory', []); - module.factory('EntityFactory', [function () { + var userName; + + module.factory('EntityFactory', ["$cookieStore", function ($cookieStore) { + + + if($cookieStore.get('userToken') !== null &&$cookieStore.get('userToken') !== undefined ){ + userName = $cookieStore.get('userToken').user; + }else{ + userName = ""; + } + return { newFeed: function () { return new Feed(); @@ -88,32 +98,39 @@ this.customProperties = [new Entry(null, null)]; this.storage = new Storage(); this.clusters = [new Cluster('source', true)]; - this.timezone = null; + this.timezone = ""; } function ACL() { - this.owner = null; - this.group = null; - this.permission = '*'; + this.owner = userName; + this.group = 'users'; + this.permission = '0x755'; } function Schema() { - this.location = null; - this.provider = null; + this.location = undefined; + this.provider = undefined; } function feedProperties() { return [ - new Entry('queueName', 'default'), + new Entry('queueName', ''), new Entry('jobPriority', ''), - new Entry('timeout', new Frequency(1, 'hours')), - new Entry('parallel', 3), - new Entry('maxMaps', 8), - new Entry('mapBandwidthKB', 1024) + new Entry('timeout', ''), + new Entry('parallel', ''), + new Entry('maxMaps', ''), + new Entry('mapBandwidthKB', '') ]; } + /*new Entry('queueName', 'default'), + new Entry('jobPriority', ''), + new Entry('timeout', new Frequency(1, 'hours')), + new Entry('parallel', 3), + new Entry('maxMaps', 8), + new Entry('mapBandwidthKB', 1024)*/ + function feedCustomProperties() { return [ new Entry(null, null) @@ -139,6 +156,10 @@ this.fileSystem = new FileSystem(); this.catalog = new Catalog(); } + function clusterStorage() { + this.fileSystem = new clusterFileSystem(); + this.catalog = new Catalog(); + } function Catalog() { this.active = false; @@ -154,6 +175,10 @@ this.active = true; this.locations = [new Location('data','/'), new Location('stats','/'), new Location('meta','/')]; } + function clusterFileSystem() { + this.active = false; + this.locations = [ new Location('data',''), new Location('stats',''), new Location('meta','') ]; + } function Location(type, path) { this.type = type; @@ -163,13 +188,13 @@ function Cluster(type, selected) { // this.name = null; - this.name = ""; + this.name = ""; this.type = type; this.selected = selected; this.retention = new Frequency(null, 'hours'); this.retention.action = 'delete'; this.validity = new Validity(); - this.storage = new Storage(); + this.storage = new clusterStorage(); } function Validity() { @@ -179,8 +204,8 @@ } function DateAndTime() { - this.date = ""; - this.time = currentTime(); + this.date = new Date(); + this.time = new Date(); this.opened = false; } @@ -197,7 +222,7 @@ this.name = null; this.tags = [new Entry(null, null)]; this.workflow = new Workflow(); - this.timezone = null; + this.timezone = ""; this.frequency = new Frequency(null, 'hours'); this.parallel = 1; this.order = ""; @@ -205,6 +230,7 @@ this.clusters = [new Cluster('source', true)]; this.inputs = []; this.outputs = []; + this.ACL = new ACL(); /* this.name = 'P'; @@ -220,8 +246,8 @@ } function Workflow() { - this.name = null; - this.engine = null; + this.name = ""; + this.engine = ""; this.version = ''; this.path = '/'; } @@ -241,7 +267,7 @@ function Output() { this.name = null; - this.feed = null; + this.feed = ""; this.outputInstance = null; } http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/services/entity/entity-model.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/services/entity/entity-model.js b/falcon-ui/app/js/services/entity/entity-model.js index 3398af2..48fa617 100644 --- a/falcon-ui/app/js/services/entity/entity-model.js +++ b/falcon-ui/app/js/services/entity/entity-model.js @@ -17,19 +17,19 @@ */ (function () { 'use strict'; - var module = angular.module('app.services.entity.model', []); + var module = angular.module('app.services.entity.model', ['ngCookies']); - module.factory('EntityModel', ["X2jsService", function(X2jsService) { + module.factory('EntityModel', ["X2jsService", "$cookieStore", function(X2jsService, $cookieStore) { - var EntityModel = {}; + var EntityModel = {}, userName; EntityModel.json = null; - EntityModel.detailsPageModel = null; + EntityModel.detailsPageModel = null; EntityModel.identifyType = function(json) { - if(json.feed) { EntityModel.type = "feed"; } - else if(json.cluster) { EntityModel.type = "cluster"; } - else if(json.process) { EntityModel.type = "process"; } + if(json && json.feed) { EntityModel.type = "feed"; } + else if(json && json.cluster) { EntityModel.type = "cluster"; } + else if(json && json.process) { EntityModel.type = "process"; } else { EntityModel.type = 'Type not recognized'; } }; @@ -38,72 +38,160 @@ return EntityModel.identifyType(EntityModel.json); }; - EntityModel.clusterModel = { - cluster:{ - tags: "", - interfaces:{ - interface:[ - { - _type:"readonly", - _endpoint:"hftp://sandbox.hortonworks.com:50070", - _version:"2.2.0" - }, - { - _type:"write", - _endpoint:"hdfs://sandbox.hortonworks.com:8020", - _version:"2.2.0" - - }, - { - _type:"execute", - _endpoint:"sandbox.hortonworks.com:8050", - _version:"2.2.0" - - }, - { - _type:"workflow", - _endpoint:"http://sandbox.hortonworks.com:11000/oozie/", - _version:"4.0.0" - - }, - { - _type:"messaging", - _endpoint:"tcp://sandbox.hortonworks.com:61616?daemon=true", - _version:"5.1.6" - - } - ] + if($cookieStore.get('userToken')){ + userName = $cookieStore.get('userToken').user; + } else { + userName = ""; + } + + EntityModel.defaultValues = { + cluster: { + cluster:{ + tags: "", + interfaces:{ + interface:[ + { + _type:"readonly", + _endpoint:"hftp://sandbox.hortonworks.com:50070", + _version:"2.2.0" + }, + { + _type:"write", + _endpoint:"hdfs://sandbox.hortonworks.com:8020", + _version:"2.2.0" + + }, + { + _type:"execute", + _endpoint:"sandbox.hortonworks.com:8050", + _version:"2.2.0" + + }, + { + _type:"workflow", + _endpoint:"http://sandbox.hortonworks.com:11000/oozie/", + _version:"4.0.0" + + }, + { + _type:"messaging", + _endpoint:"tcp://sandbox.hortonworks.com:61616?daemon=true", + _version:"5.1.6" + + } + ] + }, + locations:{ + location:[ + {_name: "staging", _path: ""}, + {_name: "temp", _path: ""}, + {_name: "working", _path: ""}, + {"_name":"","_path":""} //>> to compare + ] + }, + ACL: { + _owner: userName, + _group: "users", + _permission: "0x755" + }, + properties: { + property: [ + { _name: "", _value: ""} + ] + }, + _xmlns:"uri:falcon:cluster:0.1", + _name: undefined, + _description: undefined, + _colo: undefined + } + }, + MirrorUIModel: { + name: undefined, + tags: { + newTag: { value:"", key:"" }, + tagsArray: [{ key:"_falcon_mirroring_type", value:"HDFS" }], + tagsString: "" }, - locations:{ - location:[ - {_name: "staging", _path: ""}, - {_name: "temp", _path: ""}, - {_name: "working", _path: ""} - ] + formType: "HDFS", + runOn: "target", + source: { + location: "HDFS", + cluster: "", + url: "", + path: "", + hiveDatabaseType: "databases", + hiveDatabases: "", + hiveDatabase: "", + hiveTables: "" }, - ACL: { - _owner: "", - _group: "", - _permission: "" + target: { + location: "HDFS", + cluster: "", + url: "", + path: "" + }, + alerts: { + alert: { email: "" }, + alertsArray: [] }, - properties: { - property: [ - { _name: "", _value: ""} - ] + validity: { + start: (function () { var d = new Date(); d.setHours(0); d.setMinutes(0); d.setSeconds(0); return d; }()), + startTime: new Date(), + end: "", + endTime: new Date(), + tz: "GMT+00:00", + startISO: "", + endISO: "" }, - _xmlns:"uri:falcon:cluster:0.1", - _name:"", - _description:"", - _colo:"" + frequency: { + number: 5, + unit: 'minutes' + }, + allocation: { + hdfs:{ + maxMaps: "5", + maxBandwidth: "100" + }, + hive:{ + maxMapsDistcp: "1", + maxMapsMirror: "5", + maxMapsEvents: "-1", + maxBandwidth: "100" + } + }, + hiveOptions: { + source:{ + stagingPath: "", + hiveServerToEndpoint: "" + }, + target:{ + stagingPath: "", + hiveServerToEndpoint: "" + } + }, + retry: { + policy:"periodic", + delay: { + unit: "minutes", + number: 30 + }, + attempts: 3 + }, + acl: { + owner: userName, + group: "users", + permissions: "0x755" + } } }; + EntityModel.clusterModel = {}; //>> gets copied at bottom from defaultValues EntityModel.feedModel = { feed: { tags: "", groups: "", frequency: "", - timezone: "", + /*timezone: "GMT+00:00",*/ "late-arrival": { "_cut-off": "" }, @@ -134,9 +222,9 @@ }] }, ACL: { - _owner: "", - _group: "", - _permission: "" + _owner: userName, + _group: "users", + _permission: "0x755" }, schema: { _location: "/none", @@ -148,8 +236,229 @@ } }; + EntityModel.datasetModel = { + toImportModel: undefined, + UIModel: {}, + HDFS: { + process: { + tags: "", + clusters: { + cluster: [{ + validity: { + _start: "2015-03-13T00:00Z", + _end: "2016-12-30T00:00Z" + }, + _name: "primaryCluster" + }] + }, + parallel: "1", + order: "LAST_ONLY", + frequency: "minutes(5)", + timezone: "UTC", + properties: { + property: [ + { + _name: "oozie.wf.subworkflow.classpath.inheritance", + _value: "true" + }, + { + _name: "distcpMaxMaps", + _value: "5" + }, + { + _name: "distcpMapBandwidth", + _value: "100" + }, + { + _name: "drSourceDir", + _value: "/user/hrt_qa/dr/test/srcCluster/input" + }, + { + _name: "drTargetDir", + _value: "/user/hrt_qa/dr/test/targetCluster/input" + }, + { + _name: "drTargetClusterFS", + _value: "hdfs://240.0.0.10:8020" + }, + { + _name: "drSourceClusterFS", + _value: "hdfs://240.0.0.10:8020" + }, + { + _name: "drNotificationReceivers", + _value: "" + }, + { + _name: "targetCluster", + _value: "" + }, + { + _name: "sourceCluster", + _value: "" + } + ] + }, + workflow: { + _name: "hdfs-dr-workflow", + _engine: "oozie", + _path: "/apps/data-mirroring/workflows/hdfs-replication-workflow.xml", + _lib: "" + }, + retry: { + _policy: "periodic", + _delay: "minutes(30)", + _attempts: "3" + }, + ACL: { + _owner: "hrt_qa", + _group: "users", + _permission: "0x755" + }, + _xmlns: "uri:falcon:process:0.1", + _name: "hdfs-replication-adtech" + } + }, + HIVE: { + process: { + tags: "", + clusters: { + cluster: [{ + validity: { + _start: "2015-03-14T00:00Z", + _end: "2016-12-30T00:00Z" + }, + _name: "primaryCluster" + }] + }, + parallel: "1", + order: "LAST_ONLY", + frequency: "minutes(3)", + timezone: "UTC", + properties: { + property: [ + { + _name: "oozie.wf.subworkflow.classpath.inheritance", + _value: "true" + }, + { + _name: "distcpMaxMaps", + _value: "1" + }, + { + _name: "distcpMapBandwidth", + _value: "100" + }, + { + _name: "targetCluster", + _value: "backupCluster" + }, + { + _name: "sourceCluster", + _value: "primaryCluster" + }, + { + _name: "targetHiveServer2Uri", + _value: "hive2://240.0.0.11:10000" + }, + { + _name: "sourceHiveServer2Uri", + _value: "hive2://240.0.0.10:10000" + }, + { + _name: "sourceStagingPath", + _value: "/apps/falcon/primaryCluster/staging" + }, + { + _name: "targetStagingPath", + _value: "/apps/falcon/backupCluster/staging" + }, + { + _name: "targetNN", + _value: "hdfs://240.0.0.11:8020" + }, + { + _name: "sourceNN", + _value: "hdfs://240.0.0.10:8020" + }, + { + _name: "sourceServicePrincipal", + _value: "hive" + }, + { + _name: "targetServicePrincipal", + _value: "hive" + }, + { + _name: "targetMetastoreUri", + _value: "thrift://240.0.0.11:9083" + }, + { + _name: "sourceMetastoreUri", + _value: "thrift://240.0.0.10:9083" + }, + { + _name: "sourceTable", + _value: "" + }, + { + _name: "sourceDatabase", + _value: "" + }, + { + _name: "maxEvents", + _value: "-1" + }, + { + _name: "replicationMaxMaps", + _value: "5" + }, + { + _name: "clusterForJobRun", + _value: "primaryCluster" + }, + { + _name: "clusterForJobRunWriteEP", + _value: "hdfs://240.0.0.10:8020" + }, + { + _name: "drJobName", + _value: "hive-disaster-recovery-sowmya-1" + }, + { + _name: "drNotificationReceivers", + _value: "NA" + } + ] + }, + workflow: { + _name: "falcon-dr-hive-workflow", + _engine: "oozie", + _path: "/apps/data-mirroring/workflows/hive-disaster-recovery-workflow.xml", + _lib: "" + }, + retry: { + _policy: "periodic", + _delay: "minutes(30)", + _attempts: "3" + }, + ACL: { + _owner: "hrt_qa", + _group: "users", + _permission: "0x755" + }, + _xmlns: "uri:falcon:process:0.1", + _name: "hive-disaster-recovery-sowmya-1" + } + } + + }; + + angular.copy(EntityModel.defaultValues.cluster, EntityModel.clusterModel); + angular.copy(EntityModel.defaultValues.MirrorUIModel, EntityModel.datasetModel.UIModel); + return EntityModel; }]); -})(); \ No newline at end of file +})(); http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/services/entity/entity-serializer.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/services/entity/entity-serializer.js b/falcon-ui/app/js/services/entity/entity-serializer.js index b7d723e..284c30f 100644 --- a/falcon-ui/app/js/services/entity/entity-serializer.js +++ b/falcon-ui/app/js/services/entity/entity-serializer.js @@ -20,11 +20,31 @@ var module = angular.module('app.services.entity.serializer', ['app.services.json.transformer', 'app.services', - 'app.services.entity.factory']); + 'app.services.entity.factory', + 'app.services.entity.model']); module.factory('EntitySerializer', - ['EntityFactory', 'JsonTransformerFactory', 'X2jsService', - function(EntityFactory, JsonTransformerFactory, X2jsService) { + ['EntityFactory', 'JsonTransformerFactory', 'X2jsService', 'DateHelper', 'EntityModel', + function(EntityFactory, JsonTransformerFactory, X2jsService, DateHelper, EntityModel) { + + var feedTz, processTz; //>> this is due the weird way feed and process forms are made// only way i found to pass tz + //>> was creating this variables and duplicating import timeanddateostring functions + + + function timeAndDateToStringFeed(input) { + return DateHelper.createISO(input.date, input.time, feedTz); + } + function importDateFeed (input) { + return DateHelper.importDate(input, feedTz); + } + function timeAndDateToStringProcess(input) { + //return DateHelper.createISO(input.date, input.time, processTz); + return DateHelper.createISOString(input.date, input.time); + } + function importDateProcess (input) { + return DateHelper.importDate(input, processTz); + } + return { preSerialize: function(feed, type) { @@ -85,28 +105,7 @@ return String("00" + n).slice(-2); } - function timeAndDateToString(input) { - if(input.date !== "") { - var dateComponent = - input.date.getFullYear() + '-' + - pad(input.date.getMonth()+1) + '-' + - pad(input.date.getDate()); - } - else { - var dateComponent = ""; - } - - if(input.time !== "") { - var timeComponent = - pad(input.time.getHours()) + ':' + - pad(input.time.getMinutes()); - } - else { - var timeComponent = "00:00"; - } - return dateComponent + 'T' + timeComponent + 'Z'; - } function emptyElement() {return {};} @@ -128,8 +127,8 @@ var clusterTransform = transformerFactory .transform('name', '_name') .transform('type', '_type') - .transform('validity.start', 'validity._start', timeAndDateToString) - .transform('validity.end', 'validity._end', timeAndDateToString) + .transform('validity.start', 'validity._start', (function () { feedTz = feed.timezone; return timeAndDateToStringFeed; }())) + .transform('validity.end', 'validity._end', timeAndDateToStringFeed) .transform('retention', 'retention._limit', frequencyToString) .transform('retention.action', 'retention._action') .transform('storage.fileSystem', 'locations.location', function(fileSystem) { @@ -190,8 +189,8 @@ var clusterTransform = transformerFactory .transform('name', '_name') - .transform('validity.start', 'validity._start', timeAndDateToString) - .transform('validity.end', 'validity._end', timeAndDateToString); + .transform('validity.start', 'validity._start', (function () { processTz = process.timezone; return timeAndDateToStringProcess; }())) + .transform('validity.end', 'validity._end', timeAndDateToStringProcess); var inputTransform = transformerFactory .transform('name', '_name') @@ -207,6 +206,9 @@ var transform = transformerFactory .transform('name', 'process._name') .transform('tags', 'process.tags', keyValuePairs) + + + .transform('clusters', 'process.clusters.cluster', function(clusters) { return clusters.map(function(cluster) { return clusterTransform.apply(cluster, {}); @@ -238,7 +240,11 @@ .transform('workflow.path', 'process.workflow._path') .transform('retry.policy', 'process.retry._policy') .transform('retry.delay', 'process.retry._delay', frequencyToString) - .transform('retry.attempts', 'process.retry._attempts'); + .transform('retry.attempts', 'process.retry._attempts') + .transform('ACL', 'process.ACL', emptyElement) + .transform('ACL.owner', 'process.ACL._owner') + .transform('ACL.group', 'process.ACL._group') + .transform('ACL.permission', 'process.ACL._permission'); return transform.apply(process, new EntityModel('process')); @@ -246,16 +252,17 @@ } function preDeserializeFeed(feedModel, transformerFactory) { + var feed = EntityFactory.newFeed(); feed.storage.fileSystem.active = false; var clusterTransform = transformerFactory .transform('_name', 'name') .transform('_type', 'type') - .transform('validity._start', 'validity.start.date', parseDate) - .transform('validity._start', 'validity.start.time', parseTime) - .transform('validity._end', 'validity.end.date', parseDate) - .transform('validity._end', 'validity.end.time', parseTime) + .transform('validity._start', 'validity.start.date', (function () { feedTz = feedModel.feed.timezone; return importDateFeed; }())) + .transform('validity._start', 'validity.start.time', importDateFeed) + .transform('validity._end', 'validity.end.date', importDateFeed) + .transform('validity._end', 'validity.end.time', importDateFeed) .transform('retention._limit', 'retention', parseFrequency) .transform('retention._action', 'retention.action') .transform('locations', 'storage.fileSystem.active', parseBoolean) @@ -285,21 +292,21 @@ .transform('table', 'storage.catalog.active', parseBoolean) .transform('table._uri', 'storage.catalog.catalogTable.uri') .transform('clusters.cluster', 'clusters', parseClusters(clusterTransform)) - .transform('timezone', 'timezone') - ; + .transform('timezone', 'timezone'); return transform.apply(angular.copy(feedModel.feed), feed); } function preDeserializeProcess(processModel, transformerFactory) { + var process = EntityFactory.newProcess(); var clusterTransform = transformerFactory .transform('_name', 'name') - .transform('validity._start', 'validity.start.date', parseDate) - .transform('validity._start', 'validity.start.time', parseTime) - .transform('validity._end', 'validity.end.date', parseDate) - .transform('validity._end', 'validity.end.time', parseTime); + .transform('validity._start', 'validity.start.date', (function () { processTz = processModel.process.timezone; return importDateProcess; }())) + .transform('validity._start', 'validity.start.time', importDateProcess) + .transform('validity._end', 'validity.end.date', importDateProcess) + .transform('validity._end', 'validity.end.time', importDateProcess); var inputTransform = transformerFactory .transform('_name', 'name') @@ -328,7 +335,10 @@ .transform('retry._delay','retry.delay', parseFrequency) .transform('clusters.cluster', 'clusters', parseClusters(clusterTransform)) .transform('inputs.input', 'inputs', parseInputs(inputTransform)) - .transform('outputs.output', 'outputs', parseOutputs(outputTransform)); + .transform('outputs.output', 'outputs', parseOutputs(outputTransform)) + .transform('ACL._owner','ACL.owner') + .transform('ACL._group','ACL.group') + .transform('ACL._permission','ACL.permission'); function parseClusters(transform) { http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/services/entity/search-entity.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/services/entity/search-entity.js b/falcon-ui/app/js/services/entity/search-entity.js new file mode 100644 index 0000000..d62541d --- /dev/null +++ b/falcon-ui/app/js/services/entity/search-entity.js @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +(function () { + 'use strict'; + + var app = angular.module('app.services.entity', ['app.services']); + + app.factory('EntityFalcon', [ + "Falcon", "$q", + function (Falcon, $q) { + + var EntityFalcon = {}; + + EntityFalcon.searchEntities = function(name, tags, entityType, offset){ + var deffered = $q.defer(); + Falcon.logRequest(); + Falcon.searchEntities(name, tags, entityType, offset).success(function (data) { + Falcon.logResponse('success', data, false, true); + data.totalResults = parseInt(data.totalResults); + + if(!data.entity){ + data.entity = []; + } + if (data.entity.name) { //is an object + data.entity = [data.entity]; + } + data.entity.forEach(function(entity) { + if(entity.tags && typeof entity.tags.tag === 'string'){ + entity.tags.tag = [entity.tags.tag]; + } + if(entity.clusters && typeof entity.clusters.cluster === 'string'){ + entity.clusters.cluster = [entity.clusters.cluster]; + } + }); + EntityFalcon.data = data; + deffered.resolve(); + }).error(function (err) { + Falcon.logResponse('error', err); + deffered.resolve(); + }); + return deffered.promise; + }; + + return EntityFalcon; + + }]); + +}()); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/services/entity/search-instance.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/services/entity/search-instance.js b/falcon-ui/app/js/services/entity/search-instance.js new file mode 100644 index 0000000..dc56cfc --- /dev/null +++ b/falcon-ui/app/js/services/entity/search-instance.js @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +(function () { + 'use strict'; + + var app = angular.module('app.services.instance', ['app.services']); + + app.factory('InstanceFalcon', [ + "Falcon", "$q", + function (Falcon, $q) { + + var InstanceFalcon = {}; + + InstanceFalcon.searchInstances = function(type, name, offset, start, end, status, orderBy, sortOrder){ + var deffered = $q.defer(); + Falcon.logRequest(); + Falcon.searchInstances(type, name, offset, start, end, status, orderBy, sortOrder).success(function (data) { + Falcon.logResponse('success', data, false, true); + if(data.instances === undefined){ + data.instances = []; + } + InstanceFalcon.data = data; + deffered.resolve(); + }).error(function (err) { + Falcon.logResponse('error', err); + deffered.resolve(); + }); + return deffered.promise; + }; + + return InstanceFalcon; + + }]); + +}()); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/falcon/blob/86180d93/falcon-ui/app/js/services/services.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/services/services.js b/falcon-ui/app/js/services/services.js index 98235d3..93d0482 100644 --- a/falcon-ui/app/js/services/services.js +++ b/falcon-ui/app/js/services/services.js @@ -17,16 +17,32 @@ */ (function () { 'use strict'; - - angular.module('app.services', [ - 'app.services.falcon', - 'app.services.fileapi', + + var services = angular.module('app.services', [ + 'app.services.falcon', + 'app.services.fileapi', 'app.services.json.transformer', 'app.services.x2js', - 'app.services.validation', + 'app.services.validation', + 'app.services.entity', 'app.services.entity.serializer', 'app.services.entity.factory', - 'app.services.entity.model' + 'app.services.entity.model', + 'app.services.instance', + 'app.services.server' ]); -})(); + services.factory('SpinnersFlag', function () { + return { + show: false, + backShow: false + }; + }); + services.factory('SpinnersFlag', function () { + return { + show: false, + backShow: false + }; + }); + +}());
