Refactoring/rewrite of modal boxes handling

This commit is contained in:
Frederic Guillot
2017-01-02 17:01:27 -05:00
parent d49ce63e51
commit 3833c12ccc
173 changed files with 1526 additions and 1654 deletions

View File

@@ -2,6 +2,7 @@ Kanboard.BoardTask = function(app) {
this.app = app;
};
// TODO: rewrite this code
Kanboard.BoardTask.prototype.listen = function() {
var self = this;

View File

@@ -2,6 +2,7 @@ Kanboard.Dropdown = function(app) {
this.app = app;
};
// TODO: rewrite this code
Kanboard.Dropdown.prototype.listen = function() {
var self = this;
@@ -9,10 +10,6 @@ Kanboard.Dropdown.prototype.listen = function() {
self.close();
});
$(document).on('click', '#popover-content', function() {
self.close();
});
$(document).on('click', '.dropdown-menu', function(e) {
e.preventDefault();
e.stopImmediatePropagation();
@@ -56,7 +53,3 @@ Kanboard.Dropdown.prototype.listen = function() {
Kanboard.Dropdown.prototype.close = function() {
$("#dropdown").remove();
};
Kanboard.Dropdown.prototype.onPopoverOpened = function() {
this.close();
};

View File

@@ -1,125 +0,0 @@
Kanboard.FileUpload = function(app) {
this.app = app;
this.files = [];
this.currentFile = 0;
};
Kanboard.FileUpload.prototype.onPopoverOpened = function() {
var dropzone = document.getElementById("file-dropzone");
var self = this;
if (dropzone) {
dropzone.ondragover = dropzone.ondragenter = function(e) {
e.stopPropagation();
e.preventDefault();
};
dropzone.ondrop = function(e) {
e.stopPropagation();
e.preventDefault();
self.files = e.dataTransfer.files;
self.show();
$("#file-error-max-size").hide();
};
$(document).on("click", "#file-browser", function(e) {
e.preventDefault();
$("#file-form-element").get(0).click();
});
$(document).on("click", "#file-upload-button", function(e) {
e.preventDefault();
self.currentFile = 0;
self.checkFiles();
});
$("#file-form-element").change(function() {
self.files = document.getElementById("file-form-element").files;
self.show();
$("#file-error-max-size").hide();
});
}
};
Kanboard.FileUpload.prototype.show = function() {
$("#file-list").remove();
if (this.files.length > 0) {
$("#file-upload-button").prop("disabled", false);
$("#file-dropzone-inner").hide();
var ul = jQuery("<ul>", {"id": "file-list"});
for (var i = 0; i < this.files.length; i++) {
var percentage = jQuery("<span>", {"id": "file-percentage-" + i}).append("(0%)");
var progress = jQuery("<progress>", {"id": "file-progress-" + i, "value": 0});
var li = jQuery("<li>", {"id": "file-label-" + i})
.append(progress)
.append("&nbsp;")
.append(this.files[i].name)
.append("&nbsp;")
.append(percentage);
ul.append(li);
}
$("#file-dropzone").append(ul);
} else {
$("#file-dropzone-inner").show();
}
};
Kanboard.FileUpload.prototype.checkFiles = function() {
var max = parseInt($("#file-dropzone").data("max-size"));
for (var i = 0; i < this.files.length; i++) {
if (this.files[i].size > max) {
$("#file-error-max-size").show();
$("#file-label-" + i).addClass("file-error");
$("#file-upload-button").prop("disabled", true);
return;
}
}
this.uploadFiles();
};
Kanboard.FileUpload.prototype.uploadFiles = function() {
if (this.files.length > 0) {
this.uploadFile(this.files[this.currentFile]);
}
};
Kanboard.FileUpload.prototype.uploadFile = function(file) {
var dropzone = document.getElementById("file-dropzone");
var url = dropzone.dataset.url;
var xhr = new XMLHttpRequest();
var fd = new FormData();
xhr.upload.addEventListener("progress", this.updateProgress.bind(this));
xhr.upload.addEventListener("load", this.transferComplete.bind(this));
xhr.open("POST", url, true);
fd.append('files[]', file);
xhr.send(fd);
};
Kanboard.FileUpload.prototype.updateProgress = function(e) {
if (e.lengthComputable) {
$("#file-progress-" + this.currentFile).val(e.loaded / e.total);
$("#file-percentage-" + this.currentFile).text('(' + Math.floor((e.loaded / e.total) * 100) + '%)');
}
};
Kanboard.FileUpload.prototype.transferComplete = function() {
this.currentFile++;
if (this.currentFile < this.files.length) {
this.uploadFile(this.files[this.currentFile]);
} else {
var uploadButton = $("#file-upload-button");
uploadButton.prop("disabled", true);
uploadButton.parent().hide();
$("#file-done").show();
}
};

View File

@@ -1,161 +0,0 @@
Kanboard.Popover = function(app) {
this.app = app;
};
Kanboard.Popover.prototype.listen = function() {
var self = this;
$(document).on("click", ".popover", function(e) {
self.onClick(e);
});
$(document).on("click", ".close-popover", function(e) {
self.close(e);
});
$(document).on("click", "#popover-close-button", function(e) {
self.close(e);
});
$(document).on("click", "#popover-content", function(e) {
e.stopPropagation();
});
};
Kanboard.Popover.prototype.onClick = function(e) {
e.preventDefault();
e.stopPropagation();
var target = e.currentTarget || e.target;
var link = target.getAttribute("href");
if (! link) {
link = target.getAttribute("data-href");
}
if (link) {
this.open(link);
}
};
Kanboard.Popover.prototype.isOpen = function() {
return $('#popover-container').size() > 0;
};
Kanboard.Popover.prototype.open = function(link) {
var self = this;
if (!self.isOpen()) {
$.get(link, function(content) {
$("body").prepend(
'<div id="popover-container">' +
'<div id="popover-content">' +
'<div id="popover-content-header"><a href="#" id="popover-close-button"><i class="fa fa-times"></i></a></div>' +
content +
'</div>' +
'</div>'
);
self.executeOnOpenedListeners();
});
}
};
Kanboard.Popover.prototype.close = function(e) {
if (this.isOpen()) {
if (e) {
e.preventDefault();
}
$("#popover-container").remove();
this.executeOnClosedListeners();
}
};
Kanboard.Popover.prototype.ajaxReload = function(data, request, self) {
var redirect = request.getResponseHeader("X-Ajax-Redirect");
if (redirect === 'self') {
window.location.reload();
} else if (redirect && redirect.indexOf('#') > -1) {
window.location = redirect.split('#')[0];
} else if (redirect) {
window.location = redirect;
} else {
$("#popover-content").html(data);
$("#popover-content input[autofocus]").focus();
self.executeOnOpenedListeners();
}
};
Kanboard.Popover.prototype.executeOnOpenedListeners = function() {
for (var className in this.app.controllers) {
var controller = this.app.get(className);
if (typeof controller.onPopoverOpened === "function") {
controller.onPopoverOpened();
}
}
this.afterOpen();
};
Kanboard.Popover.prototype.executeOnClosedListeners = function() {
for (var className in this.app.controllers) {
var controller = this.app.get(className);
if (typeof controller.onPopoverClosed === "function") {
controller.onPopoverClosed();
}
}
};
Kanboard.Popover.prototype.afterOpen = function() {
var self = this;
var popoverForm = $("#popover-content .popover-form");
// Submit forms with Ajax request
if (popoverForm) {
popoverForm.on("submit", function(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: popoverForm.attr("action"),
data: popoverForm.serialize(),
success: function(data, textStatus, request) {
self.ajaxReload(data, request, self);
},
beforeSend: function() {
var button = $('.popover-form button[type="submit"]');
button.html('<i class="fa fa-spinner fa-pulse"></i> ' + button.html());
button.attr("disabled", true);
}
});
});
}
// Submit link with Ajax request
$(document).on("click", ".popover-link", function(e) {
e.preventDefault();
$.ajax({
type: "GET",
url: $(this).attr("href"),
success: function(data, textStatus, request) {
self.ajaxReload(data, request, self);
}
});
});
// Autofocus fields (html5 autofocus works only with page onload)
$("#popover-content input[autofocus]").each(function() {
$(this).focus();
});
this.app.datePicker();
this.app.autoComplete();
this.app.tagAutoComplete();
KB.render();
};

View File

@@ -1,134 +0,0 @@
Kanboard.Screenshot = function(app) {
this.app = app;
this.pasteCatcher = null;
};
Kanboard.Screenshot.prototype.onPopoverOpened = function() {
if (this.app.hasId("screenshot-zone")) {
this.initialize();
}
};
// Setup event listener and workarounds
Kanboard.Screenshot.prototype.initialize = function() {
this.destroy();
if (! window.Clipboard) {
// Create a contenteditable element
this.pasteCatcher = document.createElement("div");
this.pasteCatcher.id = "screenshot-pastezone";
this.pasteCatcher.contentEditable = "true";
// Insert the content editable at the top to avoid scrolling down in the board view
this.pasteCatcher.style.opacity = 0;
this.pasteCatcher.style.position = "fixed";
this.pasteCatcher.style.top = 0;
this.pasteCatcher.style.right = 0;
this.pasteCatcher.style.width = 0;
document.body.insertBefore(this.pasteCatcher, document.body.firstChild);
// Set focus on the contenteditable element
this.pasteCatcher.focus();
// Set the focus when clicked anywhere in the document
document.addEventListener("click", this.setFocus.bind(this));
// Set the focus when clicked in screenshot dropzone (popover)
document.getElementById("screenshot-zone").addEventListener("click", this.setFocus.bind(this));
}
window.addEventListener("paste", this.pasteHandler.bind(this));
};
// Destroy contentEditable element
Kanboard.Screenshot.prototype.destroy = function() {
if (this.pasteCatcher !== null) {
document.body.removeChild(this.pasteCatcher);
}
else if (document.getElementById("screenshot-pastezone")) {
document.body.removeChild(document.getElementById("screenshot-pastezone"));
}
document.removeEventListener("click", this.setFocus.bind(this));
this.pasteCatcher = null;
};
// Set focus on contentEditable element
Kanboard.Screenshot.prototype.setFocus = function() {
if (this.pasteCatcher !== null) {
this.pasteCatcher.focus();
}
};
// Paste event callback
Kanboard.Screenshot.prototype.pasteHandler = function(e) {
// Firefox doesn't have the property e.clipboardData.items (only Chrome)
if (e.clipboardData && e.clipboardData.items) {
var items = e.clipboardData.items;
if (items) {
for (var i = 0; i < items.length; i++) {
// Find an image in pasted elements
if (items[i].type.indexOf("image") !== -1) {
var blob = items[i].getAsFile();
// Get the image as base64 data
var reader = new FileReader();
var self = this;
reader.onload = function(event) {
self.createImage(event.target.result);
};
reader.readAsDataURL(blob);
}
}
}
}
else {
// Handle Firefox
setTimeout(this.checkInput.bind(this), 100);
}
};
// Parse the input in the paste catcher element
Kanboard.Screenshot.prototype.checkInput = function() {
var child = this.pasteCatcher.childNodes[0];
if (child) {
// If the user pastes an image, the src attribute
// will represent the image as a base64 encoded string.
if (child.tagName === "IMG") {
this.createImage(child.src);
}
}
this.pasteCatcher.innerHTML = "";
};
// Creates a new image from a given source
Kanboard.Screenshot.prototype.createImage = function(blob) {
var pastedImage = new Image();
pastedImage.src = blob;
// Send the image content to the form variable
pastedImage.onload = function() {
var sourceSplit = blob.split("base64,");
var sourceString = sourceSplit[1];
$("input[name=screenshot]").val(sourceString);
};
var zone = document.getElementById("screenshot-zone");
zone.innerHTML = "";
zone.className = "screenshot-pasted";
zone.appendChild(pastedImage);
this.destroy();
this.initialize();
};

View File

@@ -15,6 +15,7 @@ Kanboard.Search.prototype.focus = function() {
});
};
// TODO: rewrite this code
Kanboard.Search.prototype.listen = function() {
$(document).on("click", ".filter-helper", function (e) {
e.preventDefault();

View File

@@ -2,9 +2,9 @@ Kanboard.Task = function(app) {
this.app = app;
};
// TODO: rewrite this code
Kanboard.Task.prototype.onPopoverOpened = function() {
var self = this;
var reloadingProjectId = 0;
self.renderColorPicker();
@@ -19,29 +19,6 @@ Kanboard.Task.prototype.onPopoverOpened = function() {
$(dropdownId).val(currentId);
}
});
// Reload page when a destination project is changed
$(document).on("change", "select.task-reload-project-destination", function() {
if (reloadingProjectId > 0) {
$(this).val(reloadingProjectId);
}
else {
reloadingProjectId = $(this).val();
var url = $(this).data("redirect").replace(/PROJECT_ID/g, reloadingProjectId);
$(".loading-icon").show();
$.ajax({
type: "GET",
url: url,
success: function(data, textStatus, request) {
reloadingProjectId = 0;
$(".loading-icon").hide();
self.app.get("Popover").ajaxReload(data, request, self.app.get("Popover"));
}
});
}
});
};
Kanboard.Task.prototype.renderColorPicker = function() {