Refactored modal popups for repositories to make them general. [fix 1269]

This commit is contained in:
Matej Zrimšek 2017-06-05 14:09:04 +02:00
parent 5aba15e220
commit 2c6ad4aa05
5 changed files with 87 additions and 71 deletions

View file

@ -90,8 +90,7 @@ function animateLoading(start){
* Optional parameter options for spin.js options.
*/
function animateSpinner(el, start, options) {
// If overlaying the whole page,
// put the spinner in the middle of the page
// If overlaying the whole page, put the spinner in the middle of the page
var overlayPage = false;
if (_.isUndefined(el) || el === null) {
overlayPage = true;
@ -123,6 +122,30 @@ function animateSpinner(el, start, options) {
}
}
/**
* Automatic handling of show/hide spinner.
* @param {boolean} redirection Whether page is refreshed/redirected on success
* @param {boolean} onElement Whether spinner is fixed on the center of fn
* element or it's positions on the center of whole page
*/
$.fn.animateSpinner = function(redirection, onElement) {
redirection = _.isUndefined(redirection) ? false : redirection;
onElement = _.isUndefined(onElement) ? false : onElement;
$(this)
.on('ajax:beforeSend', function() {
onElement ? animateSpinner($(this)) : animateSpinner();
})
.on('ajax:error', function(e, data) {
animateSpinner(null, false);
})
.on('ajax:success', function(e, data) {
if (!redirection) {
animateSpinner(null, false);
}
});
}
/*
* Prevents user from accidentally leaving page when server is busy
* and notifies him with a message.

View file

@ -1,68 +1,6 @@
(function() {
'use strict';
/**
* Show modal on link click and handle its' validation
* @param {object} $linkToModals Link objects for opening the modal
* @param {string} modalID Modal ID
*/
function initializeModal($linkToModal, modalID) {
$linkToModal
.on('ajax:beforeSend', function() {
animateSpinner();
})
.on('ajax:success', function(e, data) {
// Add and show modal
$('body').append($.parseHTML(data.html));
$(modalID).modal('show', {
backdrop: true,
keyboard: false
});
validateRenameForm($(modalID));
// Remove modal when it gets closed
$(modalID).on('hidden.bs.modal', function() {
$(modalID).remove();
});
})
.on('ajax:error', function() {
// TODO
})
.on('ajax:complete', function() {
animateSpinner(null, false);
});
}
/**
* Rename form validation
* @param {object} $modal Modal object
*/
function validateRenameForm($modal) {
if ($modal) {
var form = $modal.find('form');
form
.on('ajax:success', function(ev, data) {
animateSpinner(form, true);
$(location).attr('href', data.url);
})
.on('ajax:error', function(e, error) {
var msg = JSON.parse(error.responseText);
if ('name' in msg) {
renderFormError(e,
$modal.find('#repository_name'),
msg.name.toString(),
true);
} else {
renderFormError(e,
$modal.find('#repository_name'),
error.statusText,
true);
}
});
}
}
initializeModal($('.delete-repo-option'), '#delete-repo-modal');
initializeModal($('.rename-repo-option'), '#rename-repo-modal');
$('.delete-repo-option').initializeModal('#delete-repo-modal');
$('.rename-repo-option').initializeModal('#rename-repo-modal');
})();

View file

@ -60,6 +60,7 @@ var renderFormError = function(ev, input, errMsgs, clearErr, errAttributes) {
// Don't submit form
ev.preventDefault();
ev.stopPropagation();
ev.stopImmediatePropagation();
}
};
@ -67,11 +68,11 @@ var renderFormError = function(ev, input, errMsgs, clearErr, errAttributes) {
* Render errors specified in JSON format for many form elements.
*/
$.fn.renderFormErrors = function(modelName, errors, clear, ev) {
clear = ((typeof clear) === 'undefined') ? true : clear;
if (clear || _.isUndefined(clear)) {
clear = _.isUndefined(clear) ? true : clear;
if (clear) {
this.clearFormErrors();
}
var form = $(this);
var $form = $(this);
$.each(errors, function(field, messages) {
// Special exception for file uploads in steps and results
if (field === 'assets.file') {
@ -80,7 +81,7 @@ $.fn.renderFormErrors = function(modelName, errors, clear, ev) {
field = 'asset_attribute';
}
var types = 'input, file, select, textarea';
var $input = $(_.filter(form.find(types), function(el) {
var $input = $(_.filter($form.find(types), function(el) {
var name = $(el).attr('name');
if (name) {
return name.match(new RegExp(modelName + '\\[' + field + '\\(?'));

View file

@ -239,3 +239,57 @@ $.fn.checkboxTreeLogic = function(dependencies, checkAll) {
});
}).trigger('change');
};
/**
* Show modal on link click and handle its' submition and validation.
*
* On link click it gets HTTP reponse with modal partial, shows it, and then on
* submit gets JSON response, displays errors if any or either refreshes the
* page or redirects it (if 'url' parameter is specified in JSON response).
* @param {string} modalID Modal ID
* @param {object} $fn Link objects for opening the modal (can have more
* links for same modal)
*/
$.fn.initializeModal = function(modalID) {
/**
* Popup modal validator
* @param {object} $modal Modal object
*/
function modalResponse($modal) {
var $modalForm = $modal.find('form');
$modalForm
.on('ajax:success', function(ev, data) {
if (_.isUndefined(data)) {
location.reload();
} else {
$(location).attr('href', data.url);
}
})
.on('ajax:error', function(e, data) {
$(this).renderFormErrors('repository', data.responseJSON);
})
.animateSpinner(true);
}
var $linksToModal = $(this);
$linksToModal
.on('ajax:success', function(e, data) {
// Add and show modal
$('body').append($.parseHTML(data.html));
$(modalID).modal('show', {
backdrop: true,
keyboard: false
});
modalResponse($(modalID));
// Remove modal when it gets closed
$(modalID).on('hidden.bs.modal', function() {
$(modalID).remove();
});
})
.on('ajax:error', function() {
// TODO
})
.animateSpinner();
};

View file

@ -123,7 +123,7 @@ Rails.application.routes.draw do
as: 'file_expired'
resources :teams do
resources :repositories, only: [:index, :destroy, :update] do
resources :repositories, only: %i(index destroy update) do
get 'destroy_modal', to: 'repositories#destroy_modal',
defaults: { format: 'json' }
get 'rename_modal', to: 'repositories#rename_modal',