From 03bca8e9043a783aa5aaed01a250a1a26806f2f7 Mon Sep 17 00:00:00 2001 From: "Dhaval.Rajpara" Date: Mon, 9 Sep 2024 14:59:33 +0530 Subject: [PATCH] RANGER-4833 : Upgrade from Bootbox.js to Bootprompt.js Signed-off-by: Dhaval.Rajpara --- .../webapp/libs/bower/bootbox/js/bootbox.js | 1246 ----------------- .../libs/bower/bootprompt/bootprompt.js | 1138 +++++++++++++++ .../src/main/webapp/scripts/Init.js | 8 +- .../src/main/webapp/scripts/routers/Router.js | 41 +- .../webapp/scripts/utils/XALangSupport.js | 57 - .../src/main/webapp/scripts/utils/XAUtils.js | 26 +- .../permissions/ModulePermsTableLayout.js | 1 - .../scripts/views/service/ServiceCreate.js | 22 +- 8 files changed, 1192 insertions(+), 1347 deletions(-) delete mode 100644 security-admin/src/main/webapp/libs/bower/bootbox/js/bootbox.js create mode 100644 security-admin/src/main/webapp/libs/bower/bootprompt/bootprompt.js diff --git a/security-admin/src/main/webapp/libs/bower/bootbox/js/bootbox.js b/security-admin/src/main/webapp/libs/bower/bootbox/js/bootbox.js deleted file mode 100644 index e27cf404c7..0000000000 --- a/security-admin/src/main/webapp/libs/bower/bootbox/js/bootbox.js +++ /dev/null @@ -1,1246 +0,0 @@ -/*! @preserve - * bootbox.js - * version: 5.5.3 - * author: Nick Payne - * license: MIT - * http://bootboxjs.com/ - */ -(function (root, factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // AMD - define(['jquery'], factory); - } else if (typeof exports === 'object') { - // Node, CommonJS-like - module.exports = factory(require('jquery')); - } else { - // Browser globals (root is window) - root.bootbox = factory(root.jQuery); - } -}(this, function init($, undefined) { - 'use strict'; - - // Polyfills Object.keys, if necessary. - // @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys - if (!Object.keys) { - Object.keys = (function () { - var hasOwnProperty = Object.prototype.hasOwnProperty, - hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'), - dontEnums = [ - 'toString', - 'toLocaleString', - 'valueOf', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'constructor' - ], - dontEnumsLength = dontEnums.length; - - return function (obj) { - if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) { - throw new TypeError('Object.keys called on non-object'); - } - - var result = [], prop, i; - - for (prop in obj) { - if (hasOwnProperty.call(obj, prop)) { - result.push(prop); - } - } - - if (hasDontEnumBug) { - for (i = 0; i < dontEnumsLength; i++) { - if (hasOwnProperty.call(obj, dontEnums[i])) { - result.push(dontEnums[i]); - } - } - } - - return result; - }; - }()); - } - - var exports = {}; - - var VERSION = '5.5.3'; - exports.VERSION = VERSION; - - var locales = { - en : { - OK : 'OK', - CANCEL : 'Cancel', - CONFIRM : 'OK' - } - }; - - var templates = { - dialog: - '', - header: - '', - footer: - '', - closeButton: - '', - form: - '
', - button: - '', - option: - '', - promptMessage: - '
', - inputs: { - text: - '', - textarea: - '', - email: - '', - select: - '', - checkbox: - '
', - radio: - '
', - date: - '', - time: - '', - number: - '', - password: - '', - range: - '' - } - }; - - - var defaults = { - // default language - locale: 'en', - // show backdrop or not. Default to static so user has to interact with dialog - backdrop: 'static', - // animate the modal in/out - animate: true, - // additional class string applied to the top level dialog - className: null, - // whether or not to include a close button - closeButton: true, - // show the dialog immediately by default - show: true, - // dialog container - container: 'body', - // default value (used by the prompt helper) - value: '', - // default input type (used by the prompt helper) - inputType: 'text', - // switch button order from cancel/confirm (default) to confirm/cancel - swapButtonOrder: false, - // center modal vertically in page - centerVertical: false, - // Append "multiple" property to the select when using the "prompt" helper - multiple: false, - // Automatically scroll modal content when height exceeds viewport height - scrollable: false, - // whether or not to destroy the modal on hide - reusable: false, - // the element that triggered the dialog opening - relatedTarget: null - }; - - - // PUBLIC FUNCTIONS - // ************************************************************************************************************* - - // Return all currently registered locales, or a specific locale if "name" is defined - exports.locales = function (name) { - return name ? locales[name] : locales; - }; - - - // Register localized strings for the OK, CONFIRM, and CANCEL buttons - exports.addLocale = function (name, values) { - $.each(['OK', 'CANCEL', 'CONFIRM'], function (_, v) { - if (!values[v]) { - throw new Error('Please supply a translation for "' + v + '"'); - } - }); - - locales[name] = { - OK: values.OK, - CANCEL: values.CANCEL, - CONFIRM: values.CONFIRM - }; - - return exports; - }; - - - // Remove a previously-registered locale - exports.removeLocale = function (name) { - if (name !== 'en') { - delete locales[name]; - } - else { - throw new Error('"en" is used as the default and fallback locale and cannot be removed.'); - } - - return exports; - }; - - - // Set the default locale - exports.setLocale = function (name) { - return exports.setDefaults('locale', name); - }; - - - // Override default value(s) of Bootbox. - exports.setDefaults = function () { - var values = {}; - - if (arguments.length === 2) { - // allow passing of single key/value... - values[arguments[0]] = arguments[1]; - } else { - // ... and as an object too - values = arguments[0]; - } - - $.extend(defaults, values); - - return exports; - }; - - - // Hides all currently active Bootbox modals - exports.hideAll = function () { - $('.bootbox').modal('hide'); - - return exports; - }; - - - // Allows the base init() function to be overridden - exports.init = function (_$) { - return init(_$ || $); - }; - - - // CORE HELPER FUNCTIONS - // ************************************************************************************************************* - - // Core dialog function - exports.dialog = function (options) { - if ($.fn.modal === undefined) { - throw new Error( - '"$.fn.modal" is not defined; please double check you have included ' + - 'the Bootstrap JavaScript library. See https://getbootstrap.com/docs/4.4/getting-started/javascript/ ' + - 'for more details.' - ); - } - - options = sanitize(options); - - if ($.fn.modal.Constructor.VERSION) { - options.fullBootstrapVersion = $.fn.modal.Constructor.VERSION; - var i = options.fullBootstrapVersion.indexOf('.'); - options.bootstrap = options.fullBootstrapVersion.substring(0, i); - } - else { - // Assuming version 2.3.2, as that was the last "supported" 2.x version - options.bootstrap = '2'; - options.fullBootstrapVersion = '2.3.2'; - console.warn('Bootbox will *mostly* work with Bootstrap 2, but we do not officially support it. Please upgrade, if possible.'); - } - - var dialog = $(templates.dialog); - var innerDialog = dialog.find('.modal-dialog'); - var body = dialog.find('.modal-body'); - var header = $(templates.header); - var footer = $(templates.footer); - var buttons = options.buttons; - - var callbacks = { - onEscape: options.onEscape - }; - - body.find('.bootbox-body').html(options.message); - - // Only attempt to create buttons if at least one has - // been defined in the options object - if (getKeyLength(options.buttons) > 0) { - each(buttons, function (key, b) { - var button = $(templates.button); - button.data('bb-handler', key); - button.addClass(b.className); - - switch (key) { - case 'ok': - case 'confirm': - button.addClass('bootbox-accept'); - break; - - case 'cancel': - button.addClass('bootbox-cancel'); - break; - } - - button.html(b.label); - footer.append(button); - - callbacks[key] = b.callback; - }); - - body.after(footer); - } - - if (options.animate === true) { - dialog.addClass('fade'); - } - - if (options.className) { - dialog.addClass(options.className); - } - - if (options.size) { - // Requires Bootstrap 3.1.0 or higher - if (options.fullBootstrapVersion.substring(0, 3) < '3.1') { - console.warn('"size" requires Bootstrap 3.1.0 or higher. You appear to be using ' + options.fullBootstrapVersion + '. Please upgrade to use this option.'); - } - - switch (options.size) { - case 'small': - case 'sm': - innerDialog.addClass('modal-sm'); - break; - - case 'large': - case 'lg': - innerDialog.addClass('modal-lg'); - break; - - case 'extra-large': - case 'xl': - innerDialog.addClass('modal-xl'); - - // Requires Bootstrap 4.2.0 or higher - if (options.fullBootstrapVersion.substring(0, 3) < '4.2') { - console.warn('Using size "xl"/"extra-large" requires Bootstrap 4.2.0 or higher. You appear to be using ' + options.fullBootstrapVersion + '. Please upgrade to use this option.'); - } - break; - } - } - - if (options.scrollable) { - innerDialog.addClass('modal-dialog-scrollable'); - - // Requires Bootstrap 4.3.0 or higher - if (options.fullBootstrapVersion.substring(0, 3) < '4.3') { - console.warn('Using "scrollable" requires Bootstrap 4.3.0 or higher. You appear to be using ' + options.fullBootstrapVersion + '. Please upgrade to use this option.'); - } - } - - if (options.title) { - body.before(header); - dialog.find('.modal-title').html(options.title); - } - - if (options.closeButton) { - var closeButton = $(templates.closeButton); - - if (options.title) { - if (options.bootstrap > 3) { - dialog.find('.modal-header').append(closeButton); - } - else { - dialog.find('.modal-header').prepend(closeButton); - } - } else { - closeButton.prependTo(body); - } - } - - if (options.centerVertical) { - innerDialog.addClass('modal-dialog-centered'); - - // Requires Bootstrap 4.0.0-beta.3 or higher - if (options.fullBootstrapVersion < '4.0.0') { - console.warn('"centerVertical" requires Bootstrap 4.0.0-beta.3 or higher. You appear to be using ' + options.fullBootstrapVersion + '. Please upgrade to use this option.'); - } - } - - // Bootstrap event listeners; these handle extra - // setup & teardown required after the underlying - // modal has performed certain actions. - - if(!options.reusable) { - // make sure we unbind any listeners once the dialog has definitively been dismissed - dialog.one('hide.bs.modal', { dialog: dialog }, unbindModal); - } - - if (options.onHide) { - if ($.isFunction(options.onHide)) { - dialog.on('hide.bs.modal', options.onHide); - } - else { - throw new Error('Argument supplied to "onHide" must be a function'); - } - } - - if(!options.reusable) { - dialog.one('hidden.bs.modal', { dialog: dialog }, destroyModal); - } - - if (options.onHidden) { - if ($.isFunction(options.onHidden)) { - dialog.on('hidden.bs.modal', options.onHidden); - } - else { - throw new Error('Argument supplied to "onHidden" must be a function'); - } - } - - if (options.onShow) { - if ($.isFunction(options.onShow)) { - dialog.on('show.bs.modal', options.onShow); - } - else { - throw new Error('Argument supplied to "onShow" must be a function'); - } - } - - dialog.one('shown.bs.modal', { dialog: dialog }, focusPrimaryButton); - - if (options.onShown) { - if ($.isFunction(options.onShown)) { - dialog.on('shown.bs.modal', options.onShown); - } - else { - throw new Error('Argument supplied to "onShown" must be a function'); - } - } - - // Bootbox event listeners; used to decouple some - // behaviours from their respective triggers - - if (options.backdrop === true) { - // A boolean true/false according to the Bootstrap docs - // should show a dialog the user can dismiss by clicking on - // the background. - // We always only ever pass static/false to the actual - // $.modal function because with "true" we can't trap - // this event (the .modal-backdrop swallows it) - // However, we still want to sort-of respect true - // and invoke the escape mechanism instead - dialog.on('click.dismiss.bs.modal', function (e) { - // @NOTE: the target varies in >= 3.3.x releases since the modal backdrop - // moved *inside* the outer dialog rather than *alongside* it - if (dialog.children('.modal-backdrop').length) { - e.currentTarget = dialog.children('.modal-backdrop').get(0); - } - - if (e.target !== e.currentTarget) { - return; - } - - dialog.trigger('escape.close.bb'); - }); - } - - dialog.on('escape.close.bb', function (e) { - // the if statement looks redundant but it isn't; without it - // if we *didn't* have an onEscape handler then processCallback - // would automatically dismiss the dialog - if (callbacks.onEscape) { - processCallback(e, dialog, callbacks.onEscape); - } - }); - - - dialog.on('click', '.modal-footer button:not(.disabled)', function (e) { - var callbackKey = $(this).data('bb-handler'); - - if (callbackKey !== undefined) { - // Only process callbacks for buttons we recognize: - processCallback(e, dialog, callbacks[callbackKey]); - } - }); - - dialog.on('click', '.bootbox-close-button', function (e) { - // onEscape might be falsy but that's fine; the fact is - // if the user has managed to click the close button we - // have to close the dialog, callback or not - processCallback(e, dialog, callbacks.onEscape); - }); - - dialog.on('keyup', function (e) { - if (e.which === 27) { - dialog.trigger('escape.close.bb'); - } - }); - - // the remainder of this method simply deals with adding our - // dialog element to the DOM, augmenting it with Bootstrap's modal - // functionality and then giving the resulting object back - // to our caller - - $(options.container).append(dialog); - - dialog.modal({ - backdrop: options.backdrop, - keyboard: false, - show: false - }); - - if (options.show) { - dialog.modal('show', options.relatedTarget); - } - - return dialog; - }; - - - // Helper function to simulate the native alert() behavior. **NOTE**: This is non-blocking, so any - // code that must happen after the alert is dismissed should be placed within the callback function - // for this alert. - exports.alert = function () { - var options; - - options = mergeDialogOptions('alert', ['ok'], ['message', 'callback'], arguments); - - // @TODO: can this move inside exports.dialog when we're iterating over each - // button and checking its button.callback value instead? - if (options.callback && !$.isFunction(options.callback)) { - throw new Error('alert requires the "callback" property to be a function when provided'); - } - - // override the ok and escape callback to make sure they just invoke - // the single user-supplied one (if provided) - options.buttons.ok.callback = options.onEscape = function () { - if ($.isFunction(options.callback)) { - return options.callback.call(this); - } - - return true; - }; - - return exports.dialog(options); - }; - - - // Helper function to simulate the native confirm() behavior. **NOTE**: This is non-blocking, so any - // code that must happen after the confirm is dismissed should be placed within the callback function - // for this confirm. - exports.confirm = function () { - var options; - - options = mergeDialogOptions('confirm', ['cancel', 'confirm'], ['message', 'callback'], arguments); - - // confirm specific validation; they don't make sense without a callback so make - // sure it's present - if (!$.isFunction(options.callback)) { - throw new Error('confirm requires a callback'); - } - - // overrides; undo anything the user tried to set they shouldn't have - options.buttons.cancel.callback = options.onEscape = function () { - return options.callback.call(this, false); - }; - - options.buttons.confirm.callback = function () { - return options.callback.call(this, true); - }; - - return exports.dialog(options); - }; - - - // Helper function to simulate the native prompt() behavior. **NOTE**: This is non-blocking, so any - // code that must happen after the prompt is dismissed should be placed within the callback function - // for this prompt. - exports.prompt = function () { - var options; - var promptDialog; - var form; - var input; - var shouldShow; - var inputOptions; - - // we have to create our form first otherwise - // its value is undefined when gearing up our options - // @TODO this could be solved by allowing message to - // be a function instead... - form = $(templates.form); - - // prompt defaults are more complex than others in that - // users can override more defaults - options = mergeDialogOptions('prompt', ['cancel', 'confirm'], ['title', 'callback'], arguments); - - if (!options.value) { - options.value = defaults.value; - } - - if (!options.inputType) { - options.inputType = defaults.inputType; - } - - // capture the user's show value; we always set this to false before - // spawning the dialog to give us a chance to attach some handlers to - // it, but we need to make sure we respect a preference not to show it - shouldShow = (options.show === undefined) ? defaults.show : options.show; - - // This is required prior to calling the dialog builder below - we need to - // add an event handler just before the prompt is shown - options.show = false; - - // Handles the 'cancel' action - options.buttons.cancel.callback = options.onEscape = function () { - return options.callback.call(this, null); - }; - - // Prompt submitted - extract the prompt value. This requires a bit of work, - // given the different input types available. - options.buttons.confirm.callback = function () { - var value; - - if (options.inputType === 'checkbox') { - value = input.find('input:checked').map(function () { - return $(this).val(); - }).get(); - } else if (options.inputType === 'radio') { - value = input.find('input:checked').val(); - } - else { - if (input[0].checkValidity && !input[0].checkValidity()) { - // prevents button callback from being called - return false; - } else { - if (options.inputType === 'select' && options.multiple === true) { - value = input.find('option:selected').map(function () { - return $(this).val(); - }).get(); - } - else { - value = input.val(); - } - } - } - - return options.callback.call(this, value); - }; - - // prompt-specific validation - if (!options.title) { - throw new Error('prompt requires a title'); - } - - if (!$.isFunction(options.callback)) { - throw new Error('prompt requires a callback'); - } - - if (!templates.inputs[options.inputType]) { - throw new Error('Invalid prompt type'); - } - - // create the input based on the supplied type - input = $(templates.inputs[options.inputType]); - - switch (options.inputType) { - case 'text': - case 'textarea': - case 'email': - case 'password': - input.val(options.value); - - if (options.placeholder) { - input.attr('placeholder', options.placeholder); - } - - if (options.pattern) { - input.attr('pattern', options.pattern); - } - - if (options.maxlength) { - input.attr('maxlength', options.maxlength); - } - - if (options.required) { - input.prop({ 'required': true }); - } - - if (options.rows && !isNaN(parseInt(options.rows))) { - if (options.inputType === 'textarea') { - input.attr({ 'rows': options.rows }); - } - } - - break; - - - case 'date': - case 'time': - case 'number': - case 'range': - input.val(options.value); - - if (options.placeholder) { - input.attr('placeholder', options.placeholder); - } - - if (options.pattern) { - input.attr('pattern', options.pattern); - } - - if (options.required) { - input.prop({ 'required': true }); - } - - // These input types have extra attributes which affect their input validation. - // Warning: For most browsers, date inputs are buggy in their implementation of 'step', so - // this attribute will have no effect. Therefore, we don't set the attribute for date inputs. - // @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date#Setting_maximum_and_minimum_dates - if (options.inputType !== 'date') { - if (options.step) { - if (options.step === 'any' || (!isNaN(options.step) && parseFloat(options.step) > 0)) { - input.attr('step', options.step); - } - else { - throw new Error('"step" must be a valid positive number or the value "any". See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-step for more information.'); - } - } - } - - if (minAndMaxAreValid(options.inputType, options.min, options.max)) { - if (options.min !== undefined) { - input.attr('min', options.min); - } - if (options.max !== undefined) { - input.attr('max', options.max); - } - } - - break; - - - case 'select': - var groups = {}; - inputOptions = options.inputOptions || []; - - if (!$.isArray(inputOptions)) { - throw new Error('Please pass an array of input options'); - } - - if (!inputOptions.length) { - throw new Error('prompt with "inputType" set to "select" requires at least one option'); - } - - // placeholder is not actually a valid attribute for select, - // but we'll allow it, assuming it might be used for a plugin - if (options.placeholder) { - input.attr('placeholder', options.placeholder); - } - - if (options.required) { - input.prop({ 'required': true }); - } - - if (options.multiple) { - input.prop({ 'multiple': true }); - } - - each(inputOptions, function (_, option) { - // assume the element to attach to is the input... - var elem = input; - - if (option.value === undefined || option.text === undefined) { - throw new Error('each option needs a "value" property and a "text" property'); - } - - // ... but override that element if this option sits in a group - - if (option.group) { - // initialise group if necessary - if (!groups[option.group]) { - groups[option.group] = $('').attr('label', option.group); - } - - elem = groups[option.group]; - } - - var o = $(templates.option); - o.attr('value', option.value).text(option.text); - elem.append(o); - }); - - each(groups, function (_, group) { - input.append(group); - }); - - // safe to set a select's value as per a normal input - input.val(options.value); - - break; - - - case 'checkbox': - var checkboxValues = $.isArray(options.value) ? options.value : [options.value]; - inputOptions = options.inputOptions || []; - - if (!inputOptions.length) { - throw new Error('prompt with "inputType" set to "checkbox" requires at least one option'); - } - - // checkboxes have to nest within a containing element, so - // they break the rules a bit and we end up re-assigning - // our 'input' element to this container instead - input = $('
'); - - each(inputOptions, function (_, option) { - if (option.value === undefined || option.text === undefined) { - throw new Error('each option needs a "value" property and a "text" property'); - } - - var checkbox = $(templates.inputs[options.inputType]); - - checkbox.find('input').attr('value', option.value); - checkbox.find('label').append('\n' + option.text); - - // we've ensured values is an array so we can always iterate over it - each(checkboxValues, function (_, value) { - if (value === option.value) { - checkbox.find('input').prop('checked', true); - } - }); - - input.append(checkbox); - }); - break; - - - case 'radio': - // Make sure that value is not an array (only a single radio can ever be checked) - if (options.value !== undefined && $.isArray(options.value)) { - throw new Error('prompt with "inputType" set to "radio" requires a single, non-array value for "value"'); - } - - inputOptions = options.inputOptions || []; - - if (!inputOptions.length) { - throw new Error('prompt with "inputType" set to "radio" requires at least one option'); - } - - // Radiobuttons have to nest within a containing element, so - // they break the rules a bit and we end up re-assigning - // our 'input' element to this container instead - input = $('
'); - - // Radiobuttons should always have an initial checked input checked in a "group". - // If value is undefined or doesn't match an input option, select the first radiobutton - var checkFirstRadio = true; - - each(inputOptions, function (_, option) { - if (option.value === undefined || option.text === undefined) { - throw new Error('each option needs a "value" property and a "text" property'); - } - - var radio = $(templates.inputs[options.inputType]); - - radio.find('input').attr('value', option.value); - radio.find('label').append('\n' + option.text); - - if (options.value !== undefined) { - if (option.value === options.value) { - radio.find('input').prop('checked', true); - checkFirstRadio = false; - } - } - - input.append(radio); - }); - - if (checkFirstRadio) { - input.find('input[type="radio"]').first().prop('checked', true); - } - break; - } - - // now place it in our form - form.append(input); - - form.on('submit', function (e) { - e.preventDefault(); - // Fix for SammyJS (or similar JS routing library) hijacking the form post. - e.stopPropagation(); - - // @TODO can we actually click *the* button object instead? - // e.g. buttons.confirm.click() or similar - promptDialog.find('.bootbox-accept').trigger('click'); - }); - - if ($.trim(options.message) !== '') { - // Add the form to whatever content the user may have added. - var message = $(templates.promptMessage).html(options.message); - form.prepend(message); - options.message = form; - } - else { - options.message = form; - } - - // Generate the dialog - promptDialog = exports.dialog(options); - - // clear the existing handler focusing the submit button... - promptDialog.off('shown.bs.modal', focusPrimaryButton); - - // ...and replace it with one focusing our input, if possible - promptDialog.on('shown.bs.modal', function () { - // need the closure here since input isn't - // an object otherwise - input.focus(); - }); - - if (shouldShow === true) { - promptDialog.modal('show'); - } - - return promptDialog; - }; - - - // INTERNAL FUNCTIONS - // ************************************************************************************************************* - - // Map a flexible set of arguments into a single returned object - // If args.length is already one just return it, otherwise - // use the properties argument to map the unnamed args to - // object properties. - // So in the latter case: - // mapArguments(["foo", $.noop], ["message", "callback"]) - // -> { message: "foo", callback: $.noop } - function mapArguments(args, properties) { - var argn = args.length; - var options = {}; - - if (argn < 1 || argn > 2) { - throw new Error('Invalid argument length'); - } - - if (argn === 2 || typeof args[0] === 'string') { - options[properties[0]] = args[0]; - options[properties[1]] = args[1]; - } else { - options = args[0]; - } - - return options; - } - - - // Merge a set of default dialog options with user supplied arguments - function mergeArguments(defaults, args, properties) { - return $.extend( - // deep merge - true, - // ensure the target is an empty, unreferenced object - {}, - // the base options object for this type of dialog (often just buttons) - defaults, - // args could be an object or array; if it's an array properties will - // map it to a proper options object - mapArguments( - args, - properties - ) - ); - } - - - // This entry-level method makes heavy use of composition to take a simple - // range of inputs and return valid options suitable for passing to bootbox.dialog - function mergeDialogOptions(className, labels, properties, args) { - var locale; - if (args && args[0]) { - locale = args[0].locale || defaults.locale; - var swapButtons = args[0].swapButtonOrder || defaults.swapButtonOrder; - - if (swapButtons) { - labels = labels.reverse(); - } - } - - // build up a base set of dialog properties - var baseOptions = { - className: 'bootbox-' + className, - buttons: createLabels(labels, locale) - }; - - // Ensure the buttons properties generated, *after* merging - // with user args are still valid against the supplied labels - return validateButtons( - // merge the generated base properties with user supplied arguments - mergeArguments( - baseOptions, - args, - // if args.length > 1, properties specify how each arg maps to an object key - properties - ), - labels - ); - } - - - // Checks each button object to see if key is valid. - // This function will only be called by the alert, confirm, and prompt helpers. - function validateButtons(options, buttons) { - var allowedButtons = {}; - each(buttons, function (key, value) { - allowedButtons[value] = true; - }); - - each(options.buttons, function (key) { - if (allowedButtons[key] === undefined) { - throw new Error('button key "' + key + '" is not allowed (options are ' + buttons.join(' ') + ')'); - } - }); - - return options; - } - - - - // From a given list of arguments, return a suitable object of button labels. - // All this does is normalise the given labels and translate them where possible. - // e.g. "ok", "confirm" -> { ok: "OK", cancel: "Annuleren" } - function createLabels(labels, locale) { - var buttons = {}; - - for (var i = 0, j = labels.length; i < j; i++) { - var argument = labels[i]; - var key = argument.toLowerCase(); - var value = argument.toUpperCase(); - - buttons[key] = { - label: getText(value, locale) - }; - } - - return buttons; - } - - - - // Get localized text from a locale. Defaults to 'en' locale if no locale - // provided or a non-registered locale is requested - function getText(key, locale) { - var labels = locales[locale]; - - return labels ? labels[key] : locales.en[key]; - } - - - - // Filter and tidy up any user supplied parameters to this dialog. - // Also looks for any shorthands used and ensures that the options - // which are returned are all normalized properly - function sanitize(options) { - var buttons; - var total; - - if (typeof options !== 'object') { - throw new Error('Please supply an object of options'); - } - - if (!options.message) { - throw new Error('"message" option must not be null or an empty string.'); - } - - // make sure any supplied options take precedence over defaults - options = $.extend({}, defaults, options); - - //make sure backdrop is either true, false, or 'static' - if (!options.backdrop) { - options.backdrop = (options.backdrop === false || options.backdrop === 0) ? false : 'static'; - } else { - options.backdrop = typeof options.backdrop === 'string' && options.backdrop.toLowerCase() === 'static' ? 'static' : true; - } - - // no buttons is still a valid dialog but it's cleaner to always have - // a buttons object to iterate over, even if it's empty - if (!options.buttons) { - options.buttons = {}; - } - - buttons = options.buttons; - - total = getKeyLength(buttons); - - each(buttons, function (key, button, index) { - if ($.isFunction(button)) { - // short form, assume value is our callback. Since button - // isn't an object it isn't a reference either so re-assign it - button = buttons[key] = { - callback: button - }; - } - - // before any further checks make sure by now button is the correct type - if ($.type(button) !== 'object') { - throw new Error('button with key "' + key + '" must be an object'); - } - - if (!button.label) { - // the lack of an explicit label means we'll assume the key is good enough - button.label = key; - } - - if (!button.className) { - var isPrimary = false; - if (options.swapButtonOrder) { - isPrimary = index === 0; - } - else { - isPrimary = index === total - 1; - } - - if (total <= 2 && isPrimary) { - // always add a primary to the main option in a one or two-button dialog - button.className = 'btn-primary'; - } else { - // adding both classes allows us to target both BS3 and BS4 without needing to check the version - button.className = 'btn-secondary btn-default'; - } - } - }); - - return options; - } - - - // Returns a count of the properties defined on the object - function getKeyLength(obj) { - return Object.keys(obj).length; - } - - - // Tiny wrapper function around jQuery.each; just adds index as the third parameter - function each(collection, iterator) { - var index = 0; - $.each(collection, function (key, value) { - iterator(key, value, index++); - }); - } - - - function focusPrimaryButton(e) { - e.data.dialog.find('.bootbox-accept').first().trigger('focus'); - } - - - function destroyModal(e) { - // ensure we don't accidentally intercept hidden events triggered - // by children of the current dialog. We shouldn't need to handle this anymore, - // now that Bootstrap namespaces its events, but still worth doing. - if (e.target === e.data.dialog[0]) { - e.data.dialog.remove(); - } - } - - - function unbindModal(e) { - if (e.target === e.data.dialog[0]) { - e.data.dialog.off('escape.close.bb'); - e.data.dialog.off('click'); - } - } - - - // Handle the invoked dialog callback - function processCallback(e, dialog, callback) { - e.stopPropagation(); - e.preventDefault(); - - // by default we assume a callback will get rid of the dialog, - // although it is given the opportunity to override this - - // so, if the callback can be invoked and it *explicitly returns false* - // then we'll set a flag to keep the dialog active... - var preserveDialog = $.isFunction(callback) && callback.call(dialog, e) === false; - - // ... otherwise we'll bin it - if (!preserveDialog) { - dialog.modal('hide'); - } - } - - // Validate `min` and `max` values based on the current `inputType` value - function minAndMaxAreValid(type, min, max) { - var result = false; - var minValid = true; - var maxValid = true; - - if (type === 'date') { - if (min !== undefined && !(minValid = dateIsValid(min))) { - console.warn('Browsers which natively support the "date" input type expect date values to be of the form "YYYY-MM-DD" (see ISO-8601 https://www.iso.org/iso-8601-date-and-time-format.html). Bootbox does not enforce this rule, but your min value may not be enforced by this browser.'); - } - else if (max !== undefined && !(maxValid = dateIsValid(max))) { - console.warn('Browsers which natively support the "date" input type expect date values to be of the form "YYYY-MM-DD" (see ISO-8601 https://www.iso.org/iso-8601-date-and-time-format.html). Bootbox does not enforce this rule, but your max value may not be enforced by this browser.'); - } - } - else if (type === 'time') { - if (min !== undefined && !(minValid = timeIsValid(min))) { - throw new Error('"min" is not a valid time. See https://www.w3.org/TR/2012/WD-html-markup-20120315/datatypes.html#form.data.time for more information.'); - } - else if (max !== undefined && !(maxValid = timeIsValid(max))) { - throw new Error('"max" is not a valid time. See https://www.w3.org/TR/2012/WD-html-markup-20120315/datatypes.html#form.data.time for more information.'); - } - } - else { - if (min !== undefined && isNaN(min)) { - minValid = false; - throw new Error('"min" must be a valid number. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-min for more information.'); - } - - if (max !== undefined && isNaN(max)) { - maxValid = false; - throw new Error('"max" must be a valid number. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-max for more information.'); - } - } - - if (minValid && maxValid) { - if (max <= min) { - throw new Error('"max" must be greater than "min". See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-max for more information.'); - } - else { - result = true; - } - } - - return result; - } - - function timeIsValid(value) { - return /([01][0-9]|2[0-3]):[0-5][0-9]?:[0-5][0-9]/.test(value); - } - - function dateIsValid(value) { - return /(\d{4})-(\d{2})-(\d{2})/.test(value); - } - - // The Bootbox object - return exports; -})); \ No newline at end of file diff --git a/security-admin/src/main/webapp/libs/bower/bootprompt/bootprompt.js b/security-admin/src/main/webapp/libs/bower/bootprompt/bootprompt.js new file mode 100644 index 0000000000..a9e923ef57 --- /dev/null +++ b/security-admin/src/main/webapp/libs/bower/bootprompt/bootprompt.js @@ -0,0 +1,1138 @@ +/** + * bootprompt.js + * license: MIT + * http://github.com/lddubeau/bootprompt + * bootprompt@6.0.2 +*/ + + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('bootstrap'), require('jquery')) : + typeof define === 'function' && define.amd ? define(['exports', 'bootstrap', 'jquery'], factory) : + (global = global || self, factory(global.bootprompt = {}, null, global.$)); +}(this, function (exports, bootstrap, $) { 'use strict'; + + $ = $ && $.hasOwnProperty('default') ? $['default'] : $; + + var __assign = (undefined && undefined.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __generator = (undefined && undefined.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } + }; + var __values = (undefined && undefined.__values) || function (o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; + if (m) return m.call(o); + return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + }; + // We use this to keep versync happy. + var version = "6.0.2"; + // But export this. + /** Bootprompt's version */ + var VERSION = version; + var LOCALE_FIELDS = ["OK", "CANCEL", "CONFIRM"]; + var definedLocales = Object.create(null); + var templates = { + dialog: "
", + header: "
", + footer: "
", + closeButton: "\n", + form: "
", + button: "", + option: "", + promptMessage: "
", + inputs: { + text: "", + textarea: "", + email: "", + select: "", + checkbox: "
", + radio: "
", + date: "", + time: "", + number: "", + password: "", + range: "", + }, + }; + var currentLocale = "en"; + var animate = true; + function locales(name) { + return name !== undefined ? definedLocales[name] : definedLocales; + } + /** + * Register a locale. + * + * @param name The name of the locale. + * + * @param values The locale specification, which determines how to translate + * each field. + * + * @throws {Error} If a field is missing from ``values``. + */ + function addLocale(name, values) { + var e_1, _a; + try { + for (var LOCALE_FIELDS_1 = __values(LOCALE_FIELDS), LOCALE_FIELDS_1_1 = LOCALE_FIELDS_1.next(); !LOCALE_FIELDS_1_1.done; LOCALE_FIELDS_1_1 = LOCALE_FIELDS_1.next()) { + var field = LOCALE_FIELDS_1_1.value; + if (typeof values[field] !== "string") { + throw new Error("Please supply a translation for \"" + field + "\""); + } + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (LOCALE_FIELDS_1_1 && !LOCALE_FIELDS_1_1.done && (_a = LOCALE_FIELDS_1.return)) _a.call(LOCALE_FIELDS_1); + } + finally { if (e_1) throw e_1.error; } + } + definedLocales[name] = values; + } + /** + * Remove a locale. Removing an unknown locale is a no-op. + * + * @param name The name of the locale. + * + * @throws {Error} If ``name`` is ``"en"``. This locale cannot be removed. + */ + function removeLocale(name) { + if (name !== "en") { + delete definedLocales[name]; + } + else { + throw new Error("\"en\" is used as the default and fallback locale and cannot be removed."); + } + } + /** + * Set the default locale. Note that this function does not check whether the + * locale is known. + */ + function setLocale(name) { + currentLocale = name; + } + /** + * Set the ``animate`` flag. When the flag is on, the modals produced by this + * library are animated. When off, they are not animated. + * + * **NOTE**: The reason this function exists is to be able to turn off + * animations during testing. Having the animations turned on can turn simple + * tests into complicated afairs because it takes a while for a modal to show + * up or be removed. We do not recommend using this function in production. + */ + function setAnimate(value) { + animate = value; + } + /** + * Hide all modals created with bootprompt. + */ + function hideAll() { + $(".bootprompt").modal("hide"); + } + // + // CORE HELPER FUNCTIONS + // + // tslint:disable-next-line:no-any + var fnModal = $.fn.modal; + /* istanbul ignore if: we do not test with incorrect environments. */ + if (fnModal === undefined) { + 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."); + } + /* istanbul ignore if: we do not test with incorrect environments. */ + if (!fnModal.Constructor.VERSION) { + throw new Error("Bootprompt cannot determine the version of Bootstrap used"); + } + var fullBootstrapVersion = fnModal.Constructor.VERSION; + var bootstrapVersion = Number(fullBootstrapVersion.substring(0, fullBootstrapVersion.indexOf("."))); + /* istanbul ignore if: we do not test with incorrect environments. */ + if (bootstrapVersion < 3) { + throw new Error("Bootprompt does not work with Bootstrap 2 and lower."); + } + /** + * This is a general-purpose function allowing to create custom dialogs. + * + * @param options The options that govern how the dialog is created. + * + * @returns The jQuery object which models the dialog. + */ + // tslint:disable-next-line:max-func-body-length cyclomatic-complexity + function dialog(options) { + var e_2, _a, e_3, _b; + var finalOptions = sanitize(options); + var $modal = $(templates.dialog); + var modal = $modal[0]; + var innerDialog = modal.getElementsByClassName("modal-dialog")[0]; + var body = modal.getElementsByClassName("modal-body")[0]; + var footer = $(templates.footer)[0]; + var callbacks = { + onEscape: finalOptions.onEscape, + onClose: finalOptions.onClose, + }; + if (callbacks.onEscape === undefined) { + callbacks.onEscape = true; + } + var buttons = finalOptions.buttons, backdrop = finalOptions.backdrop, className = finalOptions.className, closeButton = finalOptions.closeButton, message = finalOptions.message, size = finalOptions.size, title = finalOptions.title; + // tslint:disable-next-line:no-non-null-assertion + var bpBody = body.getElementsByClassName("bootprompt-body")[0]; + if (typeof message === "string") { + // tslint:disable-next-line:no-inner-html + bpBody.innerHTML = message; + } + else { + // tslint:disable-next-line:no-inner-html + bpBody.innerHTML = ""; + $(bpBody).append(message); + } + var hadButtons = false; + // tslint:disable-next-line:forin + for (var key in buttons) { + hadButtons = true; + var b = buttons[key]; + var $button = $(templates.button); + var button = $button[0]; + $button.data("bp-handler", key); + try { + // On IE10/11 it is not possible to just do x.classList.add(a, b, c). + for (var _c = __values(b.className.split(" ")), _d = _c.next(); !_d.done; _d = _c.next()) { + var cl = _d.value; + button.classList.add(cl); + } + } + catch (e_2_1) { e_2 = { error: e_2_1 }; } + finally { + try { + if (_d && !_d.done && (_a = _c.return)) _a.call(_c); + } + finally { if (e_2) throw e_2.error; } + } + switch (key) { + case "ok": + case "confirm": + button.classList.add("bootprompt-accept"); + break; + case "cancel": + button.classList.add("bootprompt-cancel"); + break; + default: + } + // tslint:disable-next-line:no-inner-html + button.innerHTML = b.label; + footer.appendChild(button); + callbacks[key] = b.callback; + } + // Only attempt to create buttons if at least one has been defined in the + // options object. + if (hadButtons) { + // tslint:disable-next-line:no-non-null-assertion + body.parentNode.insertBefore(footer, body.nextSibling); + } + if (finalOptions.animate === true) { + modal.classList.add("fade"); + } + if (className !== undefined) { + try { + // On IE10/11 it is not possible to just do x.classList.add(a, b, c). + for (var _e = __values(className.split(" ")), _f = _e.next(); !_f.done; _f = _e.next()) { + var cl = _f.value; + modal.classList.add(cl); + } + } + catch (e_3_1) { e_3 = { error: e_3_1 }; } + finally { + try { + if (_f && !_f.done && (_b = _e.return)) _b.call(_e); + } + finally { if (e_3) throw e_3.error; } + } + } + if (size !== undefined) { + // Requires Bootstrap 3.1.0 or higher + /* istanbul ignore if: we don't systematically test with old versions */ + if (fullBootstrapVersion.substring(0, 3) < "3.1") { + // tslint:disable-next-line:no-console + console.warn("\"size\" requires Bootstrap 3.1.0 or higher. You appear to be using " + fullBootstrapVersion + ". Please upgrade to use this option."); + } + switch (size) { + case "large": + innerDialog.classList.add("modal-lg"); + break; + case "small": + innerDialog.classList.add("modal-sm"); + break; + default: + var q = size; + throw new Error("unknown size value: " + q); + } + } + if (title !== undefined) { + // tslint:disable-next-line:no-non-null-assertion + body.parentNode.insertBefore($(templates.header)[0], body); + var modalTitle = modal.getElementsByClassName("modal-title")[0]; + if (typeof title === "string") { + // tslint:disable-next-line:no-inner-html + modalTitle.innerHTML = title; + } + else { + // tslint:disable-next-line:no-inner-html + modalTitle.innerHTML = ""; + $(modalTitle).append(title); + } + } + if (closeButton === true) { + var closeButtonEl = $(templates.closeButton)[0]; + if (title !== undefined) { + var modalHeader = modal.getElementsByClassName("modal-header")[0]; + /* istanbul ignore else: we don't systematically test on old versions */ + if (bootstrapVersion > 3) { + modalHeader.appendChild(closeButtonEl); + } + else { + modalHeader.insertBefore(closeButtonEl, modalHeader.firstChild); + } + } + else { + body.insertBefore(closeButtonEl, body.firstChild); + } + } + if (finalOptions.centerVertical !== undefined) { + // Requires Bootstrap 4.0.0 or higher + /* istanbul ignore if: we don't systematically test with old versions */ + if (fullBootstrapVersion < "4.0.0") { + // tslint:disable-next-line:no-console + console.warn("\"centerVertical\" requires Bootstrap 4.0.0 or higher. You appear to be using " + fullBootstrapVersion + ". Please upgrade to use this option."); + } + innerDialog.classList.add("modal-dialog-centered"); + } + // Bootstrap event listeners; these handle extra setup & teardown required + // after the underlying modal has performed certain actions. + $modal.one("hidden.bs.modal", function () { + $modal.off("escape.close.bp"); + $modal.off("click"); + $modal.remove(); + }); + $modal.one("shown.bs.modal", function () { + // tslint:disable-next-line:no-non-null-assertion + $(modal.querySelector(".btn-primary")).trigger("focus"); + }); + // Bootprompt event listeners; used to decouple some + // behaviours from their respective triggers + if (backdrop !== "static") { + // A boolean true/false according to the Bootstrap docs + // should show a dialog the user can dismiss by clicking on + // the background. + // We always only ever pass static/false to the actual + // $.modal function because with "true" we can't trap + // this event (the .modal-backdrop swallows it) + // However, we still want to sort of respect true + // and invoke the escape mechanism instead + $modal.on("click.dismiss.bs.modal", function (e) { + // The target varies in 3.3.x releases since the modal backdrop moved + // *inside* the outer dialog rather than *alongside* it + var backdrops = modal.getElementsByClassName("modal-backdrop"); + var target = backdrops.length !== 0 ? + /* istanbul ignore next: we don't systematically test with 3.3.x */ + backdrops[0] : + e.currentTarget; + if (e.target !== target) { + return; + } + $modal.trigger("escape.close.bp"); + }); + } + $modal.on("escape.close.bp", function (e) { + // the if statement looks redundant but it isn't; without it + // if we *didn't* have an onEscape handler then processCallback + // would automatically dismiss the dialog + if (callbacks.onEscape === true || + typeof callbacks.onEscape === "function") { + processCallback(e, $modal, callbacks.onEscape); + } + }); + $modal.on("click", ".modal-footer button", function (e) { + var callbackKey = $(this).data("bp-handler"); + processCallback(e, $modal, callbacks[callbackKey]); + }); + $modal.on("click", ".bootprompt-close-button", function (e) { + // onEscape might be falsy but that's fine; the fact is + // if the user has managed to click the close button we + // have to close the dialog, callback or not + processCallback(e, $modal, callbacks.onClose); + }); + $modal.on("keyup", function (e) { + if (e.which === 27) { + $modal.trigger("escape.close.bp"); + } + }); + // The interface defined for $ messes up type inferrence so we have to assert + // the type here. + $(finalOptions.container).append($modal); + $modal.modal({ + backdrop: (backdrop === true || backdrop === "static") ? "static" : false, + keyboard: false, + show: false, + }); + if (finalOptions.show === true) { + $modal.modal("show"); + } + return $modal; + } + function _alert(options, callback) { + var finalOptions = mergeDialogOptions("alert", ["ok"], options, callback); + var finalCallback = finalOptions.callback; + // tslint:disable-next-line:no-suspicious-comment + // @TODO: can this move inside exports.dialog when we're iterating over each + // button and checking its button.callback value instead? + if (finalCallback !== undefined && typeof finalCallback !== "function") { + throw new Error("alert requires callback property to be a function when \ +provided"); + } + var customCallback = function () { + return typeof finalCallback === "function" ? + finalCallback.call(this) : true; + }; + finalOptions.buttons.ok.callback = customCallback; + setupEscapeAndCloseCallbacks(finalOptions, customCallback); + return dialog(finalOptions); + } + function alert(messageOrOptions, callback) { + return _alert(typeof messageOrOptions === "string" ? + { message: messageOrOptions } : + messageOrOptions, callback); + } + /** + * Specialized function that provides a dialog similar to the one provided by + * the DOM ``alert()`` function. + * + * **NOTE**: This function is non-blocking, so any code that must happen after + * the dialog is dismissed should await the promise returned by this function. + * + * @param messageOrOptions The message to display, or an object specifying the + * options for the dialog. + * + * @returns A promise that resolves once the dialog has been dismissed. + */ + function alert$(messageOrOptions) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, new Promise(function (resolve) { + _alert(typeof messageOrOptions === "string" ? + { message: messageOrOptions } : messageOrOptions, undefined) + .one("hidden.bs.modal", function () { + resolve(); + }); + })]; + }); + }); + } + function _confirm(options, callback) { + var finalOptions = mergeDialogOptions("confirm", ["cancel", "confirm"], options, callback); + var finalCallback = finalOptions.callback, buttons = finalOptions.buttons; + // confirm specific validation; they don't make sense without a callback so + // make sure it's present + if (typeof finalCallback !== "function") { + throw new Error("confirm requires a callback"); + } + var cancelCallback = function () { + return finalCallback.call(this, false); + }; + buttons.cancel.callback = cancelCallback; + setupEscapeAndCloseCallbacks(finalOptions, cancelCallback); + buttons.confirm.callback = + function () { + return finalCallback.call(this, true); + }; + return dialog(finalOptions); + } + function confirm(messageOrOptions, callback) { + return _confirm(typeof messageOrOptions === "string" ? + { message: messageOrOptions } : + messageOrOptions, callback); + } + /** + * Specialized function that provides a dialog similar to the one provided by + * the DOM ``confirm()`` function. + * + * **NOTE**: This function is non-blocking, so any code that must happen after + * the dialog is dismissed should await the promise returned by this function. + * + * @param messageOrOptions The message to display, or an object specifying the + * options for the dialog. + * + * @returns A promise that resolves once the dialog has been dismissed. + */ + function confirm$(messageOrOptions) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, new Promise(function (resolve) { + var options = typeof messageOrOptions === "string" ? + { message: messageOrOptions } : messageOrOptions; + var callback = options.callback; + var result = null; + _confirm(options, function (value) { + result = value; + if (callback !== undefined) { + return callback.call(this, result); + } + }).one("hidden.bs.modal", function () { + resolve(result); + }); + })]; + }); + }); + } + function setupTextualInput(input, options) { + var value = options.value, placeholder = options.placeholder, pattern = options.pattern, maxlength = options.maxlength, required = options.required; + // tslint:disable-next-line:no-non-null-assertion + input.val(value); + if (placeholder !== undefined) { + input.attr("placeholder", placeholder); + } + if (pattern !== undefined) { + input.attr("pattern", pattern); + } + if (maxlength !== undefined) { + input.attr("maxlength", maxlength); + } + if (required === true) { + input.prop({ required: true }); + } + } + function setupNumberLikeInput(input, options) { + var value = options.value, placeholder = options.placeholder, pattern = options.pattern, required = options.required, inputType = options.inputType; + if (value !== undefined) { + input.val(String(value)); + } + if (placeholder !== undefined) { + input.attr("placeholder", placeholder); + } + if (pattern !== undefined) { + input.attr("pattern", pattern); + } + if (required === true) { + input.prop({ required: true }); + } + // These input types have extra attributes which affect their input + // validation. Warning: For most browsers, date inputs are buggy in their + // implementation of 'step', so this attribute will have no + // effect. Therefore, we don't set the attribute for date inputs. @see + // tslint:disable-next-line:max-line-length + // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date#Setting_maximum_and_minimum_dates + if (inputType !== "date") { + var step = options.step; + if (step !== undefined) { + var stepNumber = Number(step); + if (step === "any" || (!isNaN(stepNumber) && stepNumber > 0)) { + input.attr("step", step); + } + else { + throw new Error("\"step\" must be a valid positive number or the value \"any\". See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-step for more information."); + } + } + } + validateMinOrMaxValue(input, "min", options); + validateMinOrMaxValue(input, "max", options); + } + function validateInputOptions(inputOptions) { + var e_4, _a; + try { + for (var inputOptions_1 = __values(inputOptions), inputOptions_1_1 = inputOptions_1.next(); !inputOptions_1_1.done; inputOptions_1_1 = inputOptions_1.next()) { + var _b = inputOptions_1_1.value, value = _b.value, text = _b.text; + if (value === undefined || text === undefined) { + throw new Error("each option needs a \"value\" and a \"text\" property"); + } + if (typeof value === "number") { + throw new Error("bootprompt does not allow numbers for \"value\" in inputOptions"); + } + } + } + catch (e_4_1) { e_4 = { error: e_4_1 }; } + finally { + try { + if (inputOptions_1_1 && !inputOptions_1_1.done && (_a = inputOptions_1.return)) _a.call(inputOptions_1); + } + finally { if (e_4) throw e_4.error; } + } + } + function setupSelectInput(input, options) { + var e_5, _a; + var inputOptions = options.inputOptions !== undefined ? + options.inputOptions : []; + if (!Array.isArray(inputOptions)) { + throw new Error("Please pass an array of input options"); + } + if (inputOptions.length === 0) { + throw new Error("prompt with select requires at least one option \ +value"); + } + var required = options.required, multiple = options.multiple; + if (required === true) { + input.prop({ required: true }); + } + if (multiple === true) { + input.prop({ multiple: true }); + } + validateInputOptions(inputOptions); + var firstValue; + var groups = Object.create(null); + try { + for (var inputOptions_2 = __values(inputOptions), inputOptions_2_1 = inputOptions_2.next(); !inputOptions_2_1.done; inputOptions_2_1 = inputOptions_2.next()) { + var _b = inputOptions_2_1.value, value = _b.value, text = _b.text, group = _b.group; + // assume the element to attach to is the input... + var elem = input[0]; + // ... but override that element if this option sits in a group + if (group !== undefined && group !== "") { + var groupEl = groups[group]; + if (groupEl === undefined) { + groups[group] = groupEl = document.createElement("optgroup"); + groupEl.setAttribute("label", group); + } + elem = groupEl; + } + var o = $(templates.option); + o.attr("value", value).text(text); + elem.appendChild(o[0]); + if (firstValue === undefined) { + firstValue = value; + } + } + } + catch (e_5_1) { e_5 = { error: e_5_1 }; } + finally { + try { + if (inputOptions_2_1 && !inputOptions_2_1.done && (_a = inputOptions_2.return)) _a.call(inputOptions_2); + } + finally { if (e_5) throw e_5.error; } + } + // Conditions are such that an undefined firstValue here is an internal error. + /* istanbul ignore if: we cannot cause this intentionally */ + if (firstValue === undefined) { + throw new Error("firstValue cannot be undefined at this point"); + } + // tslint:disable-next-line:forin + for (var groupName in groups) { + input.append(groups[groupName]); + } + input.val(options.value !== undefined ? options.value : firstValue); + } + function setupCheckbox(input, options, inputTemplate) { + var e_6, _a; + var checkboxValues = Array.isArray(options.value) ? options.value : [options.value]; + var inputOptions = options.inputOptions !== undefined ? + options.inputOptions : []; + if (inputOptions.length === 0) { + throw new Error("prompt with checkbox requires options"); + } + validateInputOptions(inputOptions); + try { + for (var inputOptions_3 = __values(inputOptions), inputOptions_3_1 = inputOptions_3.next(); !inputOptions_3_1.done; inputOptions_3_1 = inputOptions_3.next()) { + var _b = inputOptions_3_1.value, value = _b.value, text = _b.text; + var checkbox = $(inputTemplate); + checkbox.find("input").attr("value", value); + checkbox.find("label").append("\n" + text); + if (checkboxValues.indexOf(value) !== -1) { + checkbox.find("input").prop("checked", true); + } + input.append(checkbox); + } + } + catch (e_6_1) { e_6 = { error: e_6_1 }; } + finally { + try { + if (inputOptions_3_1 && !inputOptions_3_1.done && (_a = inputOptions_3.return)) _a.call(inputOptions_3); + } + finally { if (e_6) throw e_6.error; } + } + } + function setupRadio(input, options, inputTemplate) { + var e_7, _a; + // Make sure that value is not an array (only a single radio can ever be + // checked) + var initialValue = options.value; + if (initialValue !== undefined && Array.isArray(initialValue)) { + throw new Error("prompt with radio requires a single, non-array value for \"value\"."); + } + var inputOptions = options.inputOptions !== undefined ? + options.inputOptions : []; + if (inputOptions.length === 0) { + throw new Error("prompt with radio requires options"); + } + validateInputOptions(inputOptions); + // Radiobuttons should always have an initial checked input checked in a + // "group". If value is undefined or doesn't match an input option, + // select the first radiobutton + var checkFirstRadio = true; + try { + for (var inputOptions_4 = __values(inputOptions), inputOptions_4_1 = inputOptions_4.next(); !inputOptions_4_1.done; inputOptions_4_1 = inputOptions_4.next()) { + var _b = inputOptions_4_1.value, value = _b.value, text = _b.text; + var radio = $(inputTemplate); + radio.find("input").attr("value", value); + radio.find("label").append("\n" + text); + if (initialValue !== undefined && value === initialValue) { + radio.find("input").prop("checked", true); + checkFirstRadio = false; + } + input.append(radio); + } + } + catch (e_7_1) { e_7 = { error: e_7_1 }; } + finally { + try { + if (inputOptions_4_1 && !inputOptions_4_1.done && (_a = inputOptions_4.return)) _a.call(inputOptions_4); + } + finally { if (e_7) throw e_7.error; } + } + if (checkFirstRadio) { + input.find("input[type='radio']").first().prop("checked", true); + } + } + // tslint:disable-next-line:max-func-body-length + function _prompt(options, callback) { + // prompt defaults are more complex than others in that users can override + // more defaults + var finalOptions = mergeDialogOptions("prompt", ["cancel", "confirm"], options, callback); + if (typeof finalOptions.value === "number") { + throw new Error("bootprompt does not allow numbers as values"); + } + // capture the user's show value; we always set this to false before spawning + // the dialog to give us a chance to attach some handlers to it, but we need + // to make sure we respect a preference not to show it + var shouldShow = finalOptions.show === undefined ? true : finalOptions.show; + // This is required prior to calling the dialog builder below - we need to add + // an event handler just before the prompt is shown + finalOptions.show = false; + // prompt-specific validation + if (finalOptions.title === undefined || finalOptions.title === "") { + throw new Error("prompt requires a title"); + } + var finalCallback = finalOptions.callback, buttons = finalOptions.buttons; + if (typeof finalCallback !== "function") { + throw new Error("prompt requires a callback"); + } + if (finalOptions.inputType === undefined) { + finalOptions.inputType = "text"; + } + var inputTemplate = templates.inputs[finalOptions.inputType]; + var input; + switch (finalOptions.inputType) { + case "text": + case "textarea": + case "email": + case "password": + input = $(inputTemplate); + setupTextualInput(input, finalOptions); + break; + case "date": + case "time": + case "number": + case "range": + input = $(inputTemplate); + setupNumberLikeInput(input, finalOptions); + break; + case "select": + input = $(inputTemplate); + setupSelectInput(input, finalOptions); + break; + case "checkbox": + // checkboxes have to nest within a containing element + input = $("
"); + setupCheckbox(input, finalOptions, inputTemplate); + break; + case "radio": + // radio buttons have to nest within a containing element + // tslint:disable-next-line:no-jquery-raw-elements + input = $("
"); + setupRadio(input, finalOptions, inputTemplate); + break; + default: + // The type assertion is needed in TS 3.2.4 which is the latest version + // that typedoc currently runs. *grumble*... + // tslint:disable-next-line:no-unnecessary-type-assertion + var q = finalOptions.inputType; + throw new Error("Unknown input type: " + q); + } + var cancelCallback = function () { + return finalCallback.call(this, null); + }; + buttons.cancel.callback = cancelCallback; + setupEscapeAndCloseCallbacks(finalOptions, cancelCallback); + // Prompt submitted - extract the prompt value. This requires a bit of work, + // given the different input types available. + // tslint:disable-next-line:no-non-null-assertion + buttons.confirm.callback = function () { + var value; + switch (finalOptions.inputType) { + case "checkbox": + value = input.find("input:checked") + .map(function () { + return $(this).val(); + }).get(); + break; + case "radio": + value = input.find("input:checked").val(); + break; + default: + var rawInput = input[0]; + if (rawInput.checkValidity !== undefined && !rawInput.checkValidity()) { + // prevents button callback from being called + return false; + } + if (finalOptions.inputType === "select" && + finalOptions.multiple === true) { + value = input.find("option:selected") + .map(function () { + return $(this).val(); + }).get(); + } + else { + value = input.val(); + } + } + // TS type inferrence fails here. + // tslint:disable-next-line:no-any + return finalCallback.call(this, value); + }; + var form = $(templates.form); + form.append(input); + var message = finalOptions.message; + if (typeof message === "string" && message.trim() !== "") { + // Add the form to whatever content the user may have added. + // tslint:disable-next-line:no-inner-html + form.prepend($(templates.promptMessage).html(message)); + } + finalOptions.message = form; + // Generate the dialog + var promptDialog = dialog(finalOptions); + form.on("submit", function (e) { + e.preventDefault(); + // Fix for SammyJS (or similar JS routing library) hijacking the form post. + e.stopPropagation(); + // tslint:disable-next-line:no-suspicious-comment + // @TODO can we actually click *the* button object instead? + // e.g. buttons.confirm.click() or similar + promptDialog.find(".bootprompt-accept").trigger("click"); + }); + // clear the existing handler focusing the submit button... + // ...and replace it with one focusing our input, if possible + promptDialog.off("shown.bs.modal").on("shown.bs.modal", function () { + input.focus(); + }); + if (shouldShow === true) { + promptDialog.modal("show"); + } + return promptDialog; + } + // tslint:disable-next-line:max-func-body-length + function prompt(messageOrOptions, callback) { + return _prompt(typeof messageOrOptions === "string" ? + { title: messageOrOptions } : + messageOrOptions, callback); + } + function prompt$(messageOrOptions) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, new Promise(function (resolve) { + var options = typeof messageOrOptions === "string" ? + // tslint:disable-next-line:no-object-literal-type-assertion + { title: messageOrOptions } : messageOrOptions; + var callback = options.callback; + var result = null; + _prompt(options, function (value) { + result = value; + if (callback !== undefined) { + // We assert the type of callback because TS's type inference fails + // here. + // tslint:disable-next-line:no-any + return callback.call(this, result); + } + }).one("hidden.bs.modal", function () { + resolve(result); + }); + })]; + }); + }); + } + // + // INTERNAL FUNCTIONS + // + function setupEscapeAndCloseCallbacks(options, callback) { + var onEscape = options.onEscape, onClose = options.onClose; + options.onEscape = (onEscape === undefined || onEscape === true) ? + callback : + function (ev) { + if (onEscape === false || onEscape.call(this, ev) === false) { + return false; + } + return callback.call(this, ev); + }; + options.onClose = onClose === undefined ? + callback : + function (ev) { + if (onClose.call(this, ev) === false) { + return false; + } + return callback.call(this, ev); + }; + } + /** + * Get localized text from a locale. Defaults to ``en`` locale if no locale + * provided or a non-registered locale is requested. + * + * @param key The field to get from the locale. + * + * @param locale The locale name. + * + * @returns The field from the locale. + */ + function getText(key, locale) { + var labels = definedLocales[locale]; + return labels !== undefined ? labels[key] : definedLocales.en[key]; + } + /** + * + * Make buttons from a series of labels. All this does is normalise the given + * labels and translate them where possible. + * + * @param labels The button labels. + * + * @param locale A locale name. + * + * @returns The created buttons. + * + */ + function makeButtons(labels, locale) { + var e_8, _a; + var buttons = Object.create(null); + try { + for (var labels_1 = __values(labels), labels_1_1 = labels_1.next(); !labels_1_1.done; labels_1_1 = labels_1.next()) { + var label = labels_1_1.value; + buttons[label.toLowerCase()] = { + label: getText(label.toUpperCase(), locale), + }; + } + } + catch (e_8_1) { e_8 = { error: e_8_1 }; } + finally { + try { + if (labels_1_1 && !labels_1_1.done && (_a = labels_1.return)) _a.call(labels_1); + } + finally { if (e_8) throw e_8.error; } + } + return buttons; + } + /** + * Produce a DialogOptions object from the options, or arguments passed to the + * specialized functions (alert, confirm, prompt). + * + * @param kind The kind of specialized function that was called. + * + * @param labels The button labels that the specialized function uses. + * + * @param options: The first argument of the specialized functions is either an + * options object, or a string. The value of that first argument must be passed + * here. + * + * @returns Options to pass to [[dialog]]. + */ + function mergeDialogOptions(kind, labels, options, callback) { + // An earlier implementation was building a hash from ``buttons``. However, + // the ``buttons`` array is very small. Profiling in other projects have shown + // that for very small arrays, there's no benefit to creating a table for + // lookup. + // + // An earlier implementation was also performing the check on the merged + // options (the return value of this function) but that was pointless as it is + // not possible to add invalid buttons with makeButtons. + // + for (var key in options.buttons) { + // tslint:disable-next-line:no-any + if (labels.indexOf(key) === -1) { + throw new Error("button key \"" + key + "\" is not allowed (options are " + labels.join(" ") + ")"); + } + } + var locale = options.locale, swapButtonOrder = options.swapButtonOrder; + return $.extend(true, // deep merge + Object.create(null), { + className: "bootprompt-" + kind, + buttons: makeButtons(swapButtonOrder === true ? labels.slice().reverse() : + labels, locale !== undefined ? locale : currentLocale), + }, options, { callback: callback }); + } + // Filter and tidy up any user supplied parameters to this dialog. + // Also looks for any shorthands used and ensures that the options + // which are returned are all normalized properly + function sanitize(options) { + if (typeof options !== "object") { + throw new Error("Please supply an object of options"); + } + if (options.message === undefined) { + throw new Error("Please specify a message"); + } + var finalOptions = __assign({ locale: currentLocale, backdrop: "static", animate: animate, closeButton: true, show: true, container: document.body }, options); + // no buttons is still a valid dialog but it's cleaner to always have + // a buttons object to iterate over, even if it's empty + var buttons = finalOptions.buttons; + if (buttons === undefined) { + buttons = finalOptions.buttons = Object.create(null); + } + var total = Object.keys(buttons).length; + var index = 0; + // tslint:disable-next-line:forin + for (var key in buttons) { + var button = buttons[key]; + if (typeof button === "function") { + // short form, assume value is our callback. Since button + // isn't an object it isn't a reference either so re-assign it + button = buttons[key] = { + callback: button, + }; + } + // before any further checks make sure by now button is the correct type + if (typeof button !== "object") { + throw new Error("button with key \"" + key + "\" must be an object"); + } + if (button.label === undefined) { + // the lack of an explicit label means we'll assume the key is good enough + button.label = key; + } + if (button.className === undefined) { + var isPrimary = index === (finalOptions.swapButtonOrder === true ? 0 : total - 1); + // always add a primary to the main option in a one or two-button dialog + button.className = (total <= 2 && isPrimary) ? + "btn-primary" : + "btn-secondary btn-default"; + } + index++; + } + // TS cannot infer that we have SanitizedDialogOptions at this point. + return finalOptions; + } + function throwMaxMinError(name) { + throw new Error("\"max\" must be greater than \"min\". See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-" + name + " for more information."); + } + // Handle the invoked dialog callback + function processCallback(e, $forDialog, callback) { + e.stopPropagation(); + e.preventDefault(); + // By default we assume a callback will get rid of the dialog, although it is + // given the opportunity to override this so, if the callback can be invoked + // and it *explicitly returns false* then we keep the dialog active... + // otherwise we'll bin it + if (!(typeof callback === "function" && + callback.call($forDialog, e) === false)) { + $forDialog.modal("hide"); + } + } + // Helper function, since the logic for validating min and max attributes is + // almost identical + function validateMinOrMaxValue(input, name, options) { + var value = options[name]; + if (value === undefined) { + return; + } + var compareValue = options[name === "min" ? "max" : "min"]; + input.attr(name, value); + var min = options.min, max = options.max; + // Type inference fails to realize the real type of value... + switch (options.inputType) { + case "date": + /* istanbul ignore if: we don't test the positive case */ + if (!/(\d{4})-(\d{2})-(\d{2})/.test(value)) { + // tslint:disable-next-line:no-console + console.warn("Browsers which natively support the \"date\" input type expect date values to be of the form \"YYYY-MM-DD\" (see ISO-8601 https://www.iso.org/iso-8601-date-and-time-format.html). Bootprompt does not enforce this rule, but your " + name + " value may not be enforced by this browser."); + } + break; + case "time": + if (!/([01][0-9]|2[0-3]):[0-5][0-9]?:[0-5][0-9]/.test(value)) { + throw new Error("\"" + name + "\" is not a valid time. See https://www.w3.org/TR/2012/WD-html-markup-20120315/datatypes.html#form.data.time for more information."); + } + // tslint:disable-next-line:no-non-null-assertion + if (!(compareValue === undefined || max > min)) { + return throwMaxMinError(name); + } + break; + default: + // Yes we force the string into isNaN. It works. + if (isNaN(value)) { + throw new Error("\"" + name + "\" must be a valid number. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-" + name + " for more information."); + } + var minNumber = Number(min); + var maxNumber = Number(max); + // tslint:disable-next-line:no-non-null-assertion + if (!(compareValue === undefined || maxNumber > minNumber) && + // Yes we force the string into isNaN. It works. + !isNaN(compareValue)) { + return throwMaxMinError(name); + } + } + } + // Register the default locale + addLocale("en", { + OK: "OK", + CANCEL: "Cancel", + CONFIRM: "OK", + }); + + exports.VERSION = VERSION; + exports.addLocale = addLocale; + exports.alert = alert; + exports.alert$ = alert$; + exports.confirm = confirm; + exports.confirm$ = confirm$; + exports.dialog = dialog; + exports.hideAll = hideAll; + exports.locales = locales; + exports.prompt = prompt; + exports.prompt$ = prompt$; + exports.removeLocale = removeLocale; + exports.setAnimate = setAnimate; + exports.setLocale = setLocale; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); +//# sourceMappingURL=bootprompt.js.map \ No newline at end of file diff --git a/security-admin/src/main/webapp/scripts/Init.js b/security-admin/src/main/webapp/scripts/Init.js index 5909f93a9f..bff79b3c46 100644 --- a/security-admin/src/main/webapp/scripts/Init.js +++ b/security-admin/src/main/webapp/scripts/Init.js @@ -83,9 +83,6 @@ require.config({ 'select2': { deps: ['jquery', 'bootstrap'] }, - 'bootbox': { - deps: ['jquery'] - }, 'esprima': { 'exports': 'esprima' }, @@ -95,6 +92,9 @@ require.config({ 'Backgrid.ColumnManager' : { deps: ['backbone', 'backgrid', 'underscore', 'jquery'] }, + 'bootprompt': { + deps: ['jquery', 'bootstrap'] + }, }, paths: { @@ -134,7 +134,6 @@ require.config({ 'jquery-toggles': '../libs/bower/jquery-toggles/js/toggles.min', 'tag-it': '../libs/bower/tag-it/js/tag-it', 'select2': '../libs/bower/select2/select2', - 'bootbox': '../libs/bower/bootbox/js/bootbox', 'visualsearch': '../libs/other/visualsearch/js/visualsearch', 'globalize': '../libs/bower/globalize/lib/globalize', /* handlebars from the require handlerbars plugin below */ @@ -145,6 +144,7 @@ require.config({ 'esprima': '../libs/bower/esprima/esprima', 'tmpl': '../templates', 'Backgrid.ColumnManager': '../libs/other/backgrid-column-manager/Backgrid.ColumnManager.min', + 'bootprompt' : '../libs/bower/bootprompt/bootprompt', }, hbs: { diff --git a/security-admin/src/main/webapp/scripts/routers/Router.js b/security-admin/src/main/webapp/scripts/routers/Router.js index 448659eb2a..753477fc05 100644 --- a/security-admin/src/main/webapp/scripts/routers/Router.js +++ b/security-admin/src/main/webapp/scripts/routers/Router.js @@ -23,9 +23,9 @@ 'utils/XALangSupport', 'models/VAppState', 'utils/XAUtils', - 'bootbox' + 'bootprompt' ], -function(Backbone, Marionette, localization, MAppState, XAUtil, bootbox){ +function(Backbone, Marionette, localization, MAppState, XAUtil, bootprompt){ 'use strict'; return Backbone.Marionette.AppRouter.extend({ @@ -97,22 +97,29 @@ function(Backbone, Marionette, localization, MAppState, XAUtil, bootbox){ callbackArgs = arguments; var formStatus = $('.form-horizontal').find('.dirtyField').length > 0 ? true : false if (window._preventNavigation && formStatus) { - bootbox.dialog(window._preventNavigationMsg, [{ - "label": "Stay on this page!", - "class": "btn-success btn-sm", - "callback": function() { - router.navigate(MAppState.get('previousFragment'), { - trigger: false - }); + bootprompt.dialog( + { + message: window._preventNavigationMsg, + buttons: { + noclose: { + "label" : localization.tt('btn.stayOnPage'), + "className" : "btn-success btn-sm", + "callback": function() { + router.navigate(MAppState.get('previousFragment'), { + trigger: false + }); + } + }, + cancel: { + "label" : localization.tt('btn.leavePage'), + "className" : "btn-danger btn-sm", + "callback": function() { + XAUtil.allowNavigation(); + proceedWithCallback(); + } + } } - }, { - "label": "Leave this page", - "class": "btn-danger btn-sm", - "callback": function() { - XAUtil.allowNavigation(); - proceedWithCallback(); - } - }]); + }); } else { proceedWithCallback(); diff --git a/security-admin/src/main/webapp/scripts/utils/XALangSupport.js b/security-admin/src/main/webapp/scripts/utils/XALangSupport.js index 1f8a08944b..9df967cece 100644 --- a/security-admin/src/main/webapp/scripts/utils/XALangSupport.js +++ b/security-admin/src/main/webapp/scripts/utils/XALangSupport.js @@ -81,63 +81,6 @@ define(['require','modules/Vent','globalize','modules/globalize/message/en'],fun localization.getDaysOfWeek = function(label){ return Globalize.culture().calendars.standard.days.namesAbbr; } - - localization.chooseCulture = function(culture){ - var dfd = $.Deferred(); - dfd.done(function(validationMessages){ - require([ 'validationEngine'],function(){ - setCulture(culture); - validationMessages.setupMessages(); - vent.trigger('Layouts:rerender'); - }); - }); - switch(culture){ - case "pt-BR" : - require(['gblMessages/message/pt-BR'], function() { - require([ 'validationEngineEn' ],function(validationMessages){ - dfd.resolve(validationMessages); - console.log('Language Changed to pt-BR'); - }); - $.fn.datepicker.dates['pt-BR'] = { - days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"], - daysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"], - daysMin: ["Do", "Se", "Te", "Qu", "Qu", "Se", "Sa", "Do"], - months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], - monthsShort: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"], - today: "Hoje", - clear: "Limpar" - }; - bootbox.setLocale('pt-BR'); - }); - break; - case "es" : - require(['gblMessages/message/es'], function() { - require([ 'validationEngineEn' ],function(validationMessages){ - dfd.resolve(validationMessages); - console.log('Language Changed to es'); - }); - $.fn.datepicker.dates['es'] = { - days: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"], - daysShort: ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb", "Dom"], - daysMin: ["Do", "Lu", "Ma", "Mi", "Ju", "Vi", "Sa", "Do"], - months: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"], - monthsShort: ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"], - today: "Hoy" - }; - bootbox.setLocale('es'); - }); - break; - default : - require(['gblMessages/message/en'], function() { - require([ 'validationEngineEn' ],function(validationMessages){ - dfd.resolve(validationMessages); - console.log('Language Changed to en'); - }); - bootbox.setLocale('en'); - }); - break; - } - } localization.formatDate = function(val,format){ if(!val) return ""; diff --git a/security-admin/src/main/webapp/scripts/utils/XAUtils.js b/security-admin/src/main/webapp/scripts/utils/XAUtils.js index fc3ff5b5d4..31d9a04ff2 100644 --- a/security-admin/src/main/webapp/scripts/utils/XAUtils.js +++ b/security-admin/src/main/webapp/scripts/utils/XAUtils.js @@ -24,7 +24,7 @@ define(function(require) { var localization = require('utils/XALangSupport'); var XAUtils = {}; var notify = require('bootstrap-notify'); - var bootbox = require('bootbox'); + var bootprompt = require('bootprompt'); var moment = require('moment'); // /////////////////////////////////////////////////////// @@ -348,7 +348,7 @@ define(function(require) { e.preventDefault(); e.stopImmediatePropagation(); - bootbox.dialog( + bootprompt.dialog( { message: msg, buttons: { @@ -387,35 +387,35 @@ define(function(require) { }; /** - * Bootbox wrapper for alert + * Bootprompt wrapper for alert * * @param {Object} * params - The params */ XAUtils.alertPopup = function(params) { - bootbox.hideAll(); + bootprompt.hideAll(); if (params.callback == undefined) { - bootbox.alert(params.msg); + bootprompt.alert(params.msg); } else { - bootbox.alert(params.msg, params.callback); + bootprompt.alert(params.msg, params.callback); } }; //Alert box with time set XAUtils.alertBoxWithTimeSet = function(msg) { - var alert = bootbox.alert(msg); + var alert = bootprompt.alert(msg); return(setTimeout(function(){alert.modal('hide'); }, 4000)); } /** - * Bootbox wrapper for confirm + * Bootprompt wrapper for confirm * * @param {Object} * params - The params */ XAUtils.confirmPopup = function(params) { - bootbox.hideAll(); - bootbox.confirm(params.msg, function(result) { + bootprompt.hideAll(); + bootprompt.confirm(params.msg, function(result) { if (result) { params.callback(); } @@ -1975,7 +1975,7 @@ define(function(require) { if (timeLeft == 0 ) { clearTimeout(timerId); if (!moment().isAfter(moment(idleTimeVal))) { - bootbox.hideAll() + bootprompt.hideAll() } else { localStorage.setItem('idleTimerLoggedOut', 'false'); XAUtils.idleActivityLogout(); @@ -1987,7 +1987,7 @@ define(function(require) { localStorage.setItem('idleTimerLoggedOut', 'false'); XAUtils.idleActivityLogout(); } else if (!moment().isAfter(moment(idleTimeVal))) { - bootbox.hideAll() + bootprompt.hideAll() clearTimeout(timerId); } else { $.find('#Timer')[0].innerHTML ='Time left : '+ timeLeft + ' seconds remaining'; @@ -1995,7 +1995,7 @@ define(function(require) { } } } - bootbox.dialog({ + bootprompt.dialog({ title: 'Session Expiration Warning', message: '' + localization.tt('dialogMsg.idleTimeOutMsg') +'
'+ $elem + '
', closeButton: false, diff --git a/security-admin/src/main/webapp/scripts/views/permissions/ModulePermsTableLayout.js b/security-admin/src/main/webapp/scripts/views/permissions/ModulePermsTableLayout.js index f53bb724ef..26f60bbdd3 100644 --- a/security-admin/src/main/webapp/scripts/views/permissions/ModulePermsTableLayout.js +++ b/security-admin/src/main/webapp/scripts/views/permissions/ModulePermsTableLayout.js @@ -37,7 +37,6 @@ define(function(require){ require('backgrid-filter'); require('backgrid-paginator'); - require('bootbox'); var ModulePermsTableLayout = Backbone.Marionette.Layout.extend( /** @lends ModulePermsTableLayout */ diff --git a/security-admin/src/main/webapp/scripts/views/service/ServiceCreate.js b/security-admin/src/main/webapp/scripts/views/service/ServiceCreate.js index b980b0a705..7995776732 100644 --- a/security-admin/src/main/webapp/scripts/views/service/ServiceCreate.js +++ b/security-admin/src/main/webapp/scripts/views/service/ServiceCreate.js @@ -31,7 +31,7 @@ define(function(require){ var XAEnums = require('utils/XAEnums'); var XALinks = require('modules/XALinks'); var localization = require('utils/XALangSupport'); - var bootbox = require('bootbox'); + var bootprompt = require('bootprompt'); var ServiceForm = require('views/service/ServiceForm'); var RangerServiceDef = require('models/RangerServiceDef'); @@ -249,25 +249,29 @@ define(function(require){ }]; } var msgHtml = 'Connection Failed.
'+msResponse.msgDesc; - bootbox.dialog({ + bootprompt.dialog({ message : msgHtml, buttons: popupBtnOpts }); } else { - bootbox.alert("Connection Failed."); + bootprompt.alert("Connection Failed."); } } else { - bootbox.alert("Connection Failed."); + bootprompt.alert("Connection Failed."); } } else { - bootbox.alert("Connected Successfully."); + bootprompt.alert("Connected Successfully."); } }, error: function (msResponse, options) { - if(msResponse.status === 419){ - XAUtil.defaultErrorHandler(options , msResponse); - } - bootbox.alert("Connection Failed."); + if(msResponse.status === 419){ + XAUtil.defaultErrorHandler(options , msResponse); + } + if(msResponse && msResponse.responseJSON && msResponse.responseJSON.msgDesc) { + bootprompt.alert(msResponse.responseJSON.msgDesc) + } else { + bootprompt.alert("Connection Failed."); + } } }); },