",footer:"",closeButton:"",form:"",inputs:{text:"",textarea:"",email:"",select:"",checkbox:"",date:"",time:"",number:"",password:""}},o={locale:"en",backdrop:"static",animate:!0,className:null,closeButton:!0,show:!0,container:"body"},p={};p.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback.call(this):!0},p.dialog(a)},p.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,!1)},a.buttons.confirm.callback=function(){return a.callback.call(this,!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return p.dialog(a)},p.prompt=function(){var a,d,e,f,h,i,k;if(f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show,a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback.call(this,c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":h.val(a.value);break;case"select":var o={};if(k=a.inputOptions||[],!b.isArray(k))throw new Error("Please pass an array of input options");if(!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(o[d.group]||(o[d.group]=b("").attr("label",d.group)),e=o[d.group]),e.append("")}),g(o,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var q=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b(""),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(q,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),a.pattern&&h.attr("pattern",a.pattern),a.maxlength&&h.attr("maxlength",a.maxlength),f.append(h),f.on("submit",function(a){a.preventDefault(),a.stopPropagation(),e.find(".btn-primary").click()}),e=p.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},p.dialog=function(a){a=h(a);var d=b(n.dialog),f=d.find(".modal-dialog"),i=d.find(".modal-body"),j=a.buttons,k="",l={onEscape:a.onEscape};if(b.fn.modal===c)throw new Error("$.fn.modal is not defined; please double check you have included the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ for more details.");if(g(j,function(a,b){k+="",l[a]=b.callback}),i.find(".bootbox-body").html(a.message),a.animate===!0&&d.addClass("fade"),a.className&&d.addClass(a.className),"large"===a.size?f.addClass("modal-lg"):"small"===a.size&&f.addClass("modal-sm"),a.title&&i.before(n.header),a.closeButton){var m=b(n.closeButton);a.title?d.find(".modal-header").prepend(m):m.css("margin-top","-10px").prependTo(i)}return a.title&&d.find(".modal-title").html(a.title),k.length&&(i.after(n.footer),d.find(".modal-footer").html(k)),d.on("hidden.bs.modal",function(a){a.target===this&&d.remove()}),d.on("shown.bs.modal",function(){d.find(".btn-primary:first").focus()}),"static"!==a.backdrop&&d.on("click.dismiss.bs.modal",function(a){d.children(".modal-backdrop").length&&(a.currentTarget=d.children(".modal-backdrop").get(0)),a.target===a.currentTarget&&d.trigger("escape.close.bb")}),d.on("escape.close.bb",function(a){l.onEscape&&e(a,d,l.onEscape)}),d.on("click",".modal-footer button",function(a){var c=b(this).data("bb-handler");e(a,d,l[c])}),d.on("click",".bootbox-close-button",function(a){e(a,d,l.onEscape)}),d.on("keyup",function(a){27===a.which&&d.trigger("escape.close.bb")}),b(a.container).append(d),d.modal({backdrop:a.backdrop?"static":!1,keyboard:!1,show:!1}),a.show&&d.modal("show"),d},p.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(o,a)},p.hideAll=function(){return b(".bootbox").modal("hide"),p};var q={bg_BG:{OK:"Ок",CANCEL:"Отказ",CONFIRM:"Потвърждавам"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},cs:{OK:"OK",CANCEL:"Zrušit",CONFIRM:"Potvrdit"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},el:{OK:"Εντάξει",CANCEL:"Ακύρωση",CONFIRM:"Επιβεβαίωση"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},et:{OK:"OK",CANCEL:"Katkesta",CONFIRM:"OK"},fa:{OK:"قبول",CANCEL:"لغو",CONFIRM:"تایید"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},he:{OK:"אישור",CANCEL:"ביטול",CONFIRM:"אישור"},hu:{OK:"OK",CANCEL:"Mégsem",CONFIRM:"Megerősít"},hr:{OK:"OK",CANCEL:"Odustani",CONFIRM:"Potvrdi"},id:{OK:"OK",CANCEL:"Batal",CONFIRM:"OK"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},ja:{OK:"OK",CANCEL:"キャンセル",CONFIRM:"確認"},lt:{OK:"Gerai",CANCEL:"Atšaukti",CONFIRM:"Patvirtinti"},lv:{OK:"Labi",CANCEL:"Atcelt",CONFIRM:"Apstiprināt"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},pt:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Confirmar"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},sq:{OK:"OK",CANCEL:"Anulo",CONFIRM:"Prano"},sv:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},th:{OK:"ตกลง",CANCEL:"ยกเลิก",CONFIRM:"ยืนยัน"},tr:{OK:"Tamam",CANCEL:"İptal",CONFIRM:"Onayla"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return p.addLocale=function(a,c){return b.each(["OK","CANCEL","CONFIRM"],function(a,b){if(!c[b])throw new Error("Please supply a translation for '"+b+"'")}),q[a]={OK:c.OK,CANCEL:c.CANCEL,CONFIRM:c.CONFIRM},p},p.removeLocale=function(a){return delete q[a],p},p.setLocale=function(a){return p.setDefaults("locale",a)},p.init=function(c){return a(c||b)},p});
\ No newline at end of file
diff --git a/quartz-manager/src/main/resources/static/js/lib/http-auth-interceptor.js b/quartz-manager/src/main/resources/static/js/lib/http-auth-interceptor.js
new file mode 100644
index 0000000..76a3181
--- /dev/null
+++ b/quartz-manager/src/main/resources/static/js/lib/http-auth-interceptor.js
@@ -0,0 +1,141 @@
+/*global angular:true, browser:true */
+
+/**
+ * @license HTTP Auth Interceptor Module for AngularJS
+ * (c) 2012 Witold Szczerba
+ * License: MIT
+ */
+
+(function () {
+ 'use strict';
+
+ angular.module('http-auth-interceptor', ['http-auth-interceptor-buffer'])
+
+ .factory('authService', ['$rootScope','httpBuffer', function($rootScope, httpBuffer) {
+ return {
+ /**
+ * Call this function to indicate that authentication was successful and trigger a
+ * retry of all deferred requests.
+ * @param data an optional argument to pass on to $broadcast which may be useful for
+ * example if you need to pass through details of the user that was logged in
+ * @param configUpdater an optional transformation function that can modify the
+ * requests that are retried after having logged in. This can be used for example
+ * to add an authentication token. It must return the request.
+ */
+ loginConfirmed: function(data, configUpdater) {
+ var updater = configUpdater || function(config) {return config;};
+ $rootScope.$broadcast('event:auth-loginConfirmed', data);
+ httpBuffer.retryAll(updater);
+ },
+
+ /**
+ * Call this function to indicate that authentication should not proceed.
+ * All deferred requests will be abandoned or rejected (if reason is provided).
+ * @param data an optional argument to pass on to $broadcast.
+ * @param reason if provided, the requests are rejected; abandoned otherwise.
+ */
+ loginCancelled: function(data, reason) {
+ httpBuffer.rejectAll(reason);
+ $rootScope.$broadcast('event:auth-loginCancelled', data);
+ }
+ };
+ }])
+
+ /**
+ * $http interceptor.
+ * On 401 response (without 'ignoreAuthModule' option) stores the request
+ * and broadcasts 'event:auth-loginRequired'.
+ * On 403 response (without 'ignoreAuthModule' option) discards the request
+ * and broadcasts 'event:auth-forbidden'.
+ */
+ .config(['$httpProvider', function($httpProvider) {
+ $httpProvider.interceptors.push(['$rootScope', '$q', 'httpBuffer', function($rootScope, $q, httpBuffer) {
+ return {
+ responseError: function(rejection) {
+ var config = rejection.config || {};
+ if (!config.ignoreAuthModule) {
+ switch (rejection.status) {
+ case 401:
+ var deferred = $q.defer();
+ var bufferLength = httpBuffer.append(config, deferred);
+ if (bufferLength === 1)
+ $rootScope.$broadcast('event:auth-loginRequired', rejection);
+ return deferred.promise;
+ case 403:
+ $rootScope.$broadcast('event:auth-forbidden', rejection);
+ break;
+ }
+ }
+ // otherwise, default behaviour
+ return $q.reject(rejection);
+ }
+ };
+ }]);
+ }]);
+
+ /**
+ * Private module, a utility, required internally by 'http-auth-interceptor'.
+ */
+ angular.module('http-auth-interceptor-buffer', [])
+
+ .factory('httpBuffer', ['$injector', function($injector) {
+ /** Holds all the requests, so they can be re-requested in future. */
+ var buffer = [];
+
+ /** Service initialized later because of circular dependency problem. */
+ var $http;
+
+ function retryHttpRequest(config, deferred) {
+ function successCallback(response) {
+ deferred.resolve(response);
+ }
+ function errorCallback(response) {
+ deferred.reject(response);
+ }
+ $http = $http || $injector.get('$http');
+ $http(config).then(successCallback, errorCallback);
+ }
+
+ return {
+ /**
+ * Appends HTTP request configuration object with deferred response attached to buffer.
+ * @return {Number} The new length of the buffer.
+ */
+ append: function(config, deferred) {
+ return buffer.push({
+ config: config,
+ deferred: deferred
+ });
+ },
+
+ /**
+ * Abandon or reject (if reason provided) all the buffered requests.
+ */
+ rejectAll: function(reason) {
+ if (reason) {
+ for (var i = 0; i < buffer.length; ++i) {
+ buffer[i].deferred.reject(reason);
+ }
+ }
+ buffer = [];
+ },
+
+ /**
+ * Retries all the buffered requests clears the buffer.
+ */
+ retryAll: function(updater) {
+ for (var i = 0; i < buffer.length; ++i) {
+ var _cfg = updater(buffer[i].config);
+ if (_cfg !== false)
+ retryHttpRequest(_cfg, buffer[i].deferred);
+ }
+ buffer = [];
+ }
+ };
+ }]);
+})();
+
+/* commonjs package manager support (eg componentjs) */
+if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports){
+ module.exports = 'http-auth-interceptor';
+}
\ No newline at end of file
diff --git a/quartz-manager/src/main/resources/static/js/lib/http-auth-interceptor.min.js b/quartz-manager/src/main/resources/static/js/lib/http-auth-interceptor.min.js
new file mode 100644
index 0000000..167529a
--- /dev/null
+++ b/quartz-manager/src/main/resources/static/js/lib/http-auth-interceptor.min.js
@@ -0,0 +1 @@
+!function(){"use strict";angular.module("http-auth-interceptor",["http-auth-interceptor-buffer"]).factory("authService",["$rootScope","httpBuffer",function($rootScope,httpBuffer){return{loginConfirmed:function(data,configUpdater){var updater=configUpdater||function(config){return config};$rootScope.$broadcast("event:auth-loginConfirmed",data),httpBuffer.retryAll(updater)},loginCancelled:function(data,reason){httpBuffer.rejectAll(reason),$rootScope.$broadcast("event:auth-loginCancelled",data)}}}]).config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(["$rootScope","$q","httpBuffer",function($rootScope,$q,httpBuffer){return{responseError:function(rejection){var config=rejection.config||{};if(!config.ignoreAuthModule)switch(rejection.status){case 401:var deferred=$q.defer(),bufferLength=httpBuffer.append(config,deferred);return 1===bufferLength&&$rootScope.$broadcast("event:auth-loginRequired",rejection),deferred.promise;case 403:$rootScope.$broadcast("event:auth-forbidden",rejection)}return $q.reject(rejection)}}}])}]),angular.module("http-auth-interceptor-buffer",[]).factory("httpBuffer",["$injector",function($injector){function retryHttpRequest(config,deferred){function successCallback(response){deferred.resolve(response)}function errorCallback(response){deferred.reject(response)}$http=$http||$injector.get("$http"),$http(config).then(successCallback,errorCallback)}var $http,buffer=[];return{append:function(config,deferred){return buffer.push({config:config,deferred:deferred})},rejectAll:function(reason){if(reason)for(var i=0;i
-
@@ -15,10 +15,16 @@
+
+
+
+
+
+
@@ -33,6 +39,9 @@
+
+
+
diff --git a/quartz-manager/src/main/resources/templates/layouts/standard.html b/quartz-manager/src/main/resources/templates/layouts/standard.html
index 706653f..b3a2d4d 100644
--- a/quartz-manager/src/main/resources/templates/layouts/standard.html
+++ b/quartz-manager/src/main/resources/templates/layouts/standard.html
@@ -57,5 +57,21 @@
+
+
+