diff options
author | Frederic Guillot <fred@kanboard.net> | 2016-03-20 15:45:02 -0400 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2016-03-20 15:45:02 -0400 |
commit | f77d6c590bf683377986064113ddddae9ed443c2 (patch) | |
tree | 9ac56f1658814c381cdc161492454143e5d0462a /assets/js/src | |
parent | 787e91ca415ff2282a1b3328c6a1b28b23596ddc (diff) |
Added Markdown editor and Javascript code refactoring
Diffstat (limited to 'assets/js/src')
39 files changed, 975 insertions, 837 deletions
diff --git a/assets/js/src/Accordion.js b/assets/js/src/Accordion.js index d3c17151..f05dc5ff 100644 --- a/assets/js/src/Accordion.js +++ b/assets/js/src/Accordion.js @@ -1,11 +1,11 @@ -function Accordion(app) { +Kanboard.Accordion = function(app) { this.app = app; -} +}; -Accordion.prototype.listen = function() { +Kanboard.Accordion.prototype.listen = function() { $(document).on("click", ".accordion-toggle", function(e) { - e.preventDefault(); var section = $(this).parents(".accordion-section"); + e.preventDefault(); if (section.hasClass("accordion-collapsed")) { section.find(".accordion-content").show(); diff --git a/assets/js/src/App.js b/assets/js/src/App.js index 4cc2c32c..62e091fc 100644 --- a/assets/js/src/App.js +++ b/assets/js/src/App.js @@ -1,75 +1,43 @@ -function App() { - this.board = new Board(this); - this.markdown = new Markdown(); - this.search = new Search(this); - this.swimlane = new Swimlane(this); - this.dropdown = new Dropdown(); - this.tooltip = new Tooltip(this); - this.popover = new Popover(this); - this.task = new Task(this); - this.project = new Project(); - this.subtask = new Subtask(this); - this.column = new Column(this); - this.file = new FileUpload(this); - this.accordion = new Accordion(this); - this.keyboardShortcuts(); - this.task.keyboardShortcuts(); - this.chosen(); - this.poll(); - - // Alert box fadeout - $(".alert-fade-out").delay(5000).fadeOut(800, function() { - $(this).remove(); - }); -} - -App.prototype.listen = function() { - this.project.listen(); - this.popover.listen(); - this.markdown.listen(); - this.tooltip.listen(); - this.dropdown.listen(); - this.search.listen(); - this.task.listen(); - this.swimlane.listen(); - this.subtask.listen(); - this.column.listen(); - this.file.listen(); - this.accordion.listen(); - this.search.focus(); - this.autoComplete(); - this.datePicker(); - this.focus(); +Kanboard.App = function() { + this.controllers = {}; }; -App.prototype.refresh = function() { - $(document).off(); - this.listen(); +Kanboard.App.prototype.get = function(controller) { + return this.controllers[controller]; }; -App.prototype.focus = function() { +Kanboard.App.prototype.execute = function() { + for (var className in Kanboard) { + if (className !== "App") { + var controller = new Kanboard[className](this); + this.controllers[className] = controller; - // Autofocus fields (html5 autofocus works only with page onload) - $("[autofocus]").each(function(index, element) { - $(this).focus(); - }) + if (typeof controller.execute === "function") { + controller.execute(); + } - // Auto-select input fields - $(document).on('focus', '.auto-select', function() { - $(this).select(); - }); + if (typeof controller.listen === "function") { + controller.listen(); + } - // Workaround for chrome - $(document).on('mouseup', '.auto-select', function(e) { - e.preventDefault(); - }); -}; + if (typeof controller.focus === "function") { + controller.focus(); + } -App.prototype.poll = function() { - window.setInterval(this.checkSession, 60000); + if (typeof controller.keyboardShortcuts === "function") { + controller.keyboardShortcuts(); + } + } + } + + this.focus(); + this.chosen(); + this.keyboardShortcuts(); + this.datePicker(); + this.autoComplete(); }; -App.prototype.keyboardShortcuts = function() { +Kanboard.App.prototype.keyboardShortcuts = function() { var self = this; // Submit form @@ -85,31 +53,50 @@ App.prototype.keyboardShortcuts = function() { // Close popover and dropdown Mousetrap.bindGlobal("esc", function() { - self.popover.close(); - self.dropdown.close(); + self.get("Popover").close(); + self.get("Dropdown").close(); }); // Show keyboard shortcut Mousetrap.bind("?", function() { - self.popover.open($("body").data("keyboard-shortcut-url")); + self.get("Popover").open($("body").data("keyboard-shortcut-url")); }); }; -App.prototype.checkSession = function() { - if (! $(".form-login").length) { - $.ajax({ - cache: false, - url: $("body").data("status-url"), - statusCode: { - 401: function() { - window.location = $("body").data("login-url"); - } - } +Kanboard.App.prototype.focus = function() { + // Auto-select input fields + $(document).on('focus', '.auto-select', function() { + $(this).select(); + }); + + // Workaround for chrome + $(document).on('mouseup', '.auto-select', function(e) { + e.preventDefault(); + }); +}; + +Kanboard.App.prototype.chosen = function() { + $(".chosen-select").each(function() { + var searchThreshold = $(this).data("search-threshold"); + + if (searchThreshold === undefined) { + searchThreshold = 10; + } + + $(this).chosen({ + width: "180px", + no_results_text: $(this).data("notfound"), + disable_search_threshold: searchThreshold }); - } + }); + + $(".select-auto-redirect").change(function() { + var regex = new RegExp($(this).data('redirect-regex'), 'g'); + window.location = $(this).data('redirect-url').replace(regex, $(this).val()); + }); }; -App.prototype.datePicker = function() { +Kanboard.App.prototype.datePicker = function() { // Datepicker translation $.datepicker.setDefaults($.datepicker.regional[$("body").data("js-lang")]); @@ -131,7 +118,7 @@ App.prototype.datePicker = function() { }); }; -App.prototype.autoComplete = function() { +Kanboard.App.prototype.autoComplete = function() { $(".autocomplete").each(function() { var input = $(this); var field = input.data("dst-field"); @@ -157,36 +144,33 @@ App.prototype.autoComplete = function() { }); }; -App.prototype.chosen = function() { - $(".chosen-select").each(function() { - var searchThreshold = $(this).data("search-threshold"); - - if (searchThreshold === undefined) { - searchThreshold = 10; - } - - $(this).chosen({ - width: "180px", - no_results_text: $(this).data("notfound"), - disable_search_threshold: searchThreshold - }); - }); - - $(".select-auto-redirect").change(function() { - var regex = new RegExp($(this).data('redirect-regex'), 'g'); - window.location = $(this).data('redirect-url').replace(regex, $(this).val()); - }); +Kanboard.App.prototype.hasId = function(id) { + return !!document.getElementById(id); }; -App.prototype.showLoadingIcon = function() { +Kanboard.App.prototype.showLoadingIcon = function() { $("body").append('<span id="app-loading-icon"> <i class="fa fa-spinner fa-spin"></i></span>'); }; -App.prototype.hideLoadingIcon = function() { +Kanboard.App.prototype.hideLoadingIcon = function() { $("#app-loading-icon").remove(); }; -App.prototype.isVisible = function() { +Kanboard.App.prototype.formatDuration = function(d) { + if (d >= 86400) { + return Math.round(d/86400) + "d"; + } + else if (d >= 3600) { + return Math.round(d/3600) + "h"; + } + else if (d >= 60) { + return Math.round(d/60) + "m"; + } + + return d + "s"; +}; + +Kanboard.App.prototype.isVisible = function() { var property = ""; if (typeof document.hidden !== "undefined") { @@ -205,17 +189,3 @@ App.prototype.isVisible = function() { return true; }; - -App.prototype.formatDuration = function(d) { - if (d >= 86400) { - return Math.round(d/86400) + "d"; - } - else if (d >= 3600) { - return Math.round(d/3600) + "h"; - } - else if (d >= 60) { - return Math.round(d/60) + "m"; - } - - return d + "s"; -}; diff --git a/assets/js/src/AvgTimeColumnChart.js b/assets/js/src/AvgTimeColumnChart.js index 3fe02ea3..803aa2c2 100644 --- a/assets/js/src/AvgTimeColumnChart.js +++ b/assets/js/src/AvgTimeColumnChart.js @@ -1,10 +1,17 @@ -function AvgTimeColumnChart(app) { +Kanboard.AvgTimeColumnChart = function(app) { this.app = app; -} +}; + +Kanboard.AvgTimeColumnChart.prototype.execute = function() { + if (this.app.hasId("analytic-avg-time-column")) { + this.show(); + } +}; -AvgTimeColumnChart.prototype.execute = function() { - var metrics = $("#chart").data("metrics"); - var plots = [$("#chart").data("label")]; +Kanboard.AvgTimeColumnChart.prototype.show = function() { + var chart = $("#chart"); + var metrics = chart.data("metrics"); + var plots = [chart.data("label")]; var categories = []; for (var column_id in metrics) { diff --git a/assets/js/src/Board.js b/assets/js/src/Board.js deleted file mode 100644 index c9cad284..00000000 --- a/assets/js/src/Board.js +++ /dev/null @@ -1,336 +0,0 @@ -function Board(app) { - this.app = app; - this.checkInterval = null; - this.savingInProgress = false; -} - -Board.prototype.execute = function() { - this.app.swimlane.refresh(); - this.restoreColumnViewMode(); - this.compactView(); - this.poll(); - this.keyboardShortcuts(); - this.listen(); - this.dragAndDrop(); - - $(window).on("load", this.columnScrolling); - $(window).resize(this.columnScrolling); -}; - -Board.prototype.poll = function() { - var interval = parseInt($("#board").attr("data-check-interval")); - - if (interval > 0) { - this.checkInterval = window.setInterval(this.check.bind(this), interval * 1000); - } -}; - -Board.prototype.reloadFilters = function(search) { - this.app.showLoadingIcon(); - - $.ajax({ - cache: false, - url: $("#board").data("reload-url"), - contentType: "application/json", - type: "POST", - processData: false, - data: JSON.stringify({ - search: search - }), - success: this.refresh.bind(this), - error: this.app.hideLoadingIcon.bind(this) - }); -}; - -Board.prototype.check = function() { - if (this.app.isVisible() && ! this.savingInProgress) { - var self = this; - this.app.showLoadingIcon(); - - $.ajax({ - cache: false, - url: $("#board").data("check-url"), - statusCode: { - 200: function(data) { self.refresh(data); }, - 304: function () { self.app.hideLoadingIcon(); } - } - }); - } -}; - -Board.prototype.save = function(taskId, columnId, position, swimlaneId) { - var self = this; - this.app.showLoadingIcon(); - this.savingInProgress = true; - - $.ajax({ - cache: false, - url: $("#board").data("save-url"), - contentType: "application/json", - type: "POST", - processData: false, - data: JSON.stringify({ - "task_id": taskId, - "column_id": columnId, - "swimlane_id": swimlaneId, - "position": position - }), - success: function(data) { - self.refresh(data); - this.savingInProgress = false; - }, - error: function() { - self.app.hideLoadingIcon(); - this.savingInProgress = false; - } - }); -}; - -Board.prototype.refresh = function(data) { - $("#board-container").replaceWith(data); - - this.app.refresh(); - this.app.swimlane.refresh(); - this.app.hideLoadingIcon(); - this.listen(); - this.dragAndDrop(); - this.compactView(); - this.restoreColumnViewMode(); - this.columnScrolling(); -}; - -Board.prototype.dragAndDrop = function() { - var self = this; - var params = { - forcePlaceholderSize: true, - tolerance: "pointer", - connectWith: ".board-task-list", - placeholder: "draggable-placeholder", - items: ".draggable-item", - stop: function(event, ui) { - var task = ui.item; - var taskId = task.attr('data-task-id'); - var taskPosition = task.attr('data-position'); - var taskColumnId = task.attr('data-column-id'); - var taskSwimlaneId = task.attr('data-swimlane-id'); - - var newColumnId = task.parent().attr("data-column-id"); - var newSwimlaneId = task.parent().attr('data-swimlane-id'); - var newPosition = task.index() + 1; - - task.removeClass("draggable-item-selected"); - - if (newColumnId != taskColumnId || newSwimlaneId != taskSwimlaneId || newPosition != taskPosition) { - self.changeTaskState(taskId); - self.save(taskId, newColumnId, newPosition, newSwimlaneId); - } - }, - start: function(event, ui) { - ui.item.addClass("draggable-item-selected"); - ui.placeholder.height(ui.item.height()); - } - }; - - if ($.support.touch) { - $(".task-board-sort-handle").css("display", "inline"); - params["handle"] = ".task-board-sort-handle"; - } - - $(".board-task-list").sortable(params); -}; - -Board.prototype.changeTaskState = function(taskId) { - var task = $("div[data-task-id=" + taskId + "]"); - task.addClass('task-board-saving-state'); - task.find('.task-board-saving-icon').show(); -}; - -Board.prototype.listen = function() { - var self = this; - - $(document).on("click", ".task-board-change-assignee", function(e) { - e.preventDefault(); - self.app.popover.open($(this).data('url')); - }); - - $(document).on("click", ".task-board", function(e) { - if (e.target.tagName != "A" && e.target.tagName != "IMG") { - window.location = $(this).data("task-url"); - } - }); - - $(document).on('click', ".filter-toggle-scrolling", function(e) { - e.preventDefault(); - self.toggleCompactView(); - }); - - $(document).on('click', ".filter-toggle-height", function(e) { - e.preventDefault(); - self.toggleColumnScrolling(); - }); - - $(document).on("click", ".board-toggle-column-view", function() { - self.toggleColumnViewMode($(this).data("column-id")); - }); -}; - -Board.prototype.toggleColumnScrolling = function() { - var scrolling = localStorage.getItem("column_scroll"); - - if (scrolling == undefined) { - scrolling = 1; - } - - localStorage.setItem("column_scroll", scrolling == 0 ? 1 : 0); - this.columnScrolling(); -}; - -Board.prototype.columnScrolling = function() { - if (localStorage.getItem("column_scroll") == 0) { - var height = 80; - - $(".filter-max-height").show(); - $(".filter-min-height").hide(); - $(".board-rotation-wrapper").css("min-height", ''); - - $(".board-task-list").each(function() { - var columnHeight = $(this).height(); - - if (columnHeight > height) { - height = columnHeight; - } - }); - - $(".board-task-list").css("min-height", height); - $(".board-task-list").css("height", ''); - } - else { - - $(".filter-max-height").hide(); - $(".filter-min-height").show(); - - if ($(".board-swimlane").length > 1) { - $(".board-task-list").each(function() { - if ($(this).height() > 500) { - $(this).css("height", 500); - } - else { - $(this).css("min-height", 320); // Height of the dropdown menu - $(".board-rotation-wrapper").css("min-height", 320); - } - }); - } - else { - var height = $(window).height() - 170; - - $(".board-task-list").css("height", height); - $(".board-rotation-wrapper").css("min-height", height); - } - } -}; - -Board.prototype.toggleCompactView = function() { - var scrolling = localStorage.getItem("horizontal_scroll") || 1; - localStorage.setItem("horizontal_scroll", scrolling == 0 ? 1 : 0); - this.compactView(); -}; - -Board.prototype.compactView = function() { - if (localStorage.getItem("horizontal_scroll") == 0) { - $(".filter-wide").show(); - $(".filter-compact").hide(); - - $("#board-container").addClass("board-container-compact"); - $("#board th:not(.board-column-header-collapsed)").addClass("board-column-compact"); - } - else { - $(".filter-wide").hide(); - $(".filter-compact").show(); - - $("#board-container").removeClass("board-container-compact"); - $("#board th").removeClass("board-column-compact"); - } -}; - -Board.prototype.toggleCollapsedMode = function() { - var self = this; - this.app.showLoadingIcon(); - - $.ajax({ - cache: false, - url: $('.filter-display-mode:not([style="display: none;"]) a').attr('href'), - success: function(data) { - $('.filter-display-mode').toggle(); - self.refresh(data); - } - }); -}; - -Board.prototype.restoreColumnViewMode = function() { - var self = this; - - $(".board-column-header").each(function() { - var columnId = $(this).data('column-id'); - if (localStorage.getItem("hidden_column_" + columnId)) { - self.hideColumn(columnId); - } - }); -}; - -Board.prototype.toggleColumnViewMode = function(columnId) { - if (localStorage.getItem("hidden_column_" + columnId)) { - this.showColumn(columnId); - } - else { - this.hideColumn(columnId); - } -}; - -Board.prototype.hideColumn = function(columnId) { - $(".board-column-" + columnId + " .board-column-expanded").hide(); - $(".board-column-" + columnId + " .board-column-collapsed").show(); - $(".board-column-header-" + columnId + " .board-column-expanded").hide(); - $(".board-column-header-" + columnId + " .board-column-collapsed").show(); - - $(".board-column-header-" + columnId).each(function() { - $(this).removeClass("board-column-compact"); - $(this).addClass("board-column-header-collapsed"); - }); - - $(".board-column-" + columnId ).each(function() { - $(this).addClass("board-column-task-collapsed"); - }); - - $(".board-column-" + columnId + " .board-rotation").each(function() { - $(this).css("width", $(".board-column-" + columnId + "").height()); - }); - - localStorage.setItem("hidden_column_" + columnId, 1); -}; - -Board.prototype.showColumn = function(columnId) { - $(".board-column-" + columnId + " .board-column-expanded").show(); - $(".board-column-" + columnId + " .board-column-collapsed").hide(); - $(".board-column-header-" + columnId + " .board-column-expanded").show(); - $(".board-column-header-" + columnId + " .board-column-collapsed").hide(); - - $(".board-column-header-" + columnId).removeClass("board-column-header-collapsed"); - $(".board-column-" + columnId).removeClass("board-column-task-collapsed"); - - if (localStorage.getItem("horizontal_scroll") == 0) { - $(".board-column-header-" + columnId).addClass("board-column-compact"); - } - - localStorage.removeItem("hidden_column_" + columnId); -}; - -Board.prototype.keyboardShortcuts = function() { - var self = this; - - Mousetrap.bind("c", function() { self.toggleCompactView(); }); - Mousetrap.bind("s", function() { self.toggleCollapsedMode(); }); - - Mousetrap.bind("n", function() { - self.app.popover.open($("#board").data("task-creation-url")); - }); -}; diff --git a/assets/js/src/BoardCollapsedMode.js b/assets/js/src/BoardCollapsedMode.js new file mode 100644 index 00000000..c33146fe --- /dev/null +++ b/assets/js/src/BoardCollapsedMode.js @@ -0,0 +1,25 @@ +Kanboard.BoardCollapsedMode = function(app) { + this.app = app; +}; + +Kanboard.BoardCollapsedMode.prototype.keyboardShortcuts = function() { + var self = this; + + Mousetrap.bind("s", function() { + self.toggle(); + }); +}; + +Kanboard.BoardCollapsedMode.prototype.toggle = function() { + var self = this; + this.app.showLoadingIcon(); + + $.ajax({ + cache: false, + url: $('.filter-display-mode:not([style="display: none;"]) a').attr('href'), + success: function(data) { + $('.filter-display-mode').toggle(); + self.app.get("BoardDragAndDrop").refresh(data); + } + }); +};
\ No newline at end of file diff --git a/assets/js/src/BoardColumnScrolling.js b/assets/js/src/BoardColumnScrolling.js new file mode 100644 index 00000000..e637180d --- /dev/null +++ b/assets/js/src/BoardColumnScrolling.js @@ -0,0 +1,85 @@ +Kanboard.BoardColumnScrolling = function(app) { + this.app = app; +}; + +Kanboard.BoardColumnScrolling.prototype.execute = function() { + if (this.app.hasId("board")) { + this.render(); + + $(window).on("load", this.render); + $(window).resize(this.render); + } +}; + +Kanboard.BoardColumnScrolling.prototype.listen = function() { + var self = this; + + $(document).on('click', ".filter-toggle-height", function(e) { + e.preventDefault(); + self.toggle(); + }); +}; + +Kanboard.BoardColumnScrolling.prototype.onBoardRendered = function() { + this.render(); +}; + +Kanboard.BoardColumnScrolling.prototype.toggle = function() { + var scrolling = localStorage.getItem("column_scroll"); + + if (scrolling == undefined) { + scrolling = 1; + } + + localStorage.setItem("column_scroll", scrolling == 0 ? 1 : 0); + this.render(); +}; + +Kanboard.BoardColumnScrolling.prototype.render = function() { + var taskList = $(".board-task-list"); + var rotationWrapper = $(".board-rotation-wrapper"); + var filterMax = $(".filter-max-height"); + var filterMin = $(".filter-min-height"); + + if (localStorage.getItem("column_scroll") == 0) { + var height = 80; + + filterMax.show(); + filterMin.hide(); + rotationWrapper.css("min-height", ''); + + taskList.each(function() { + var columnHeight = $(this).height(); + + if (columnHeight > height) { + height = columnHeight; + } + }); + + taskList.css("min-height", height); + taskList.css("height", ''); + } + else { + + filterMax.hide(); + filterMin.show(); + + if ($(".board-swimlane").length > 1) { + taskList.each(function() { + if ($(this).height() > 500) { + $(this).css("height", 500); + } + else { + $(this).css("min-height", 320); // Height of the dropdown menu + rotationWrapper.css("min-height", 320); + } + }); + } + else { + var height = $(window).height() - 170; + + taskList.css("height", height); + rotationWrapper.css("min-height", height); + } + } +}; diff --git a/assets/js/src/BoardColumnView.js b/assets/js/src/BoardColumnView.js new file mode 100644 index 00000000..2da1bdfa --- /dev/null +++ b/assets/js/src/BoardColumnView.js @@ -0,0 +1,79 @@ +Kanboard.BoardColumnView = function(app) { + this.app = app; +}; + +Kanboard.BoardColumnView.prototype.execute = function() { + if (this.app.hasId("board")) { + this.render(); + } +}; + +Kanboard.BoardColumnView.prototype.listen = function() { + var self = this; + + $(document).on("click", ".board-toggle-column-view", function() { + self.toggle($(this).data("column-id")); + }); +}; + +Kanboard.BoardColumnView.prototype.onBoardRendered = function() { + this.render(); +}; + +Kanboard.BoardColumnView.prototype.render = function() { + var self = this; + + $(".board-column-header").each(function() { + var columnId = $(this).data('column-id'); + if (localStorage.getItem("hidden_column_" + columnId)) { + self.hideColumn(columnId); + } + }); +}; + +Kanboard.BoardColumnView.prototype.toggle = function(columnId) { + if (localStorage.getItem("hidden_column_" + columnId)) { + this.showColumn(columnId); + } + else { + this.hideColumn(columnId); + } +}; + +Kanboard.BoardColumnView.prototype.hideColumn = function(columnId) { + $(".board-column-" + columnId + " .board-column-expanded").hide(); + $(".board-column-" + columnId + " .board-column-collapsed").show(); + $(".board-column-header-" + columnId + " .board-column-expanded").hide(); + $(".board-column-header-" + columnId + " .board-column-collapsed").show(); + + $(".board-column-header-" + columnId).each(function() { + $(this).removeClass("board-column-compact"); + $(this).addClass("board-column-header-collapsed"); + }); + + $(".board-column-" + columnId).each(function() { + $(this).addClass("board-column-task-collapsed"); + }); + + $(".board-column-" + columnId + " .board-rotation").each(function() { + $(this).css("width", $(".board-column-" + columnId + "").height()); + }); + + localStorage.setItem("hidden_column_" + columnId, 1); +}; + +Kanboard.BoardColumnView.prototype.showColumn = function(columnId) { + $(".board-column-" + columnId + " .board-column-expanded").show(); + $(".board-column-" + columnId + " .board-column-collapsed").hide(); + $(".board-column-header-" + columnId + " .board-column-expanded").show(); + $(".board-column-header-" + columnId + " .board-column-collapsed").hide(); + + $(".board-column-header-" + columnId).removeClass("board-column-header-collapsed"); + $(".board-column-" + columnId).removeClass("board-column-task-collapsed"); + + if (localStorage.getItem("horizontal_scroll") == 0) { + $(".board-column-header-" + columnId).addClass("board-column-compact"); + } + + localStorage.removeItem("hidden_column_" + columnId); +}; diff --git a/assets/js/src/BoardDragAndDrop.js b/assets/js/src/BoardDragAndDrop.js new file mode 100644 index 00000000..9c0c2aaf --- /dev/null +++ b/assets/js/src/BoardDragAndDrop.js @@ -0,0 +1,103 @@ +Kanboard.BoardDragAndDrop = function(app) { + this.app = app; + this.savingInProgress = false; +}; + +Kanboard.BoardDragAndDrop.prototype.execute = function() { + if (this.app.hasId("board")) { + this.dragAndDrop(); + this.executeListeners(); + } +}; + +Kanboard.BoardDragAndDrop.prototype.dragAndDrop = function() { + var self = this; + var params = { + forcePlaceholderSize: true, + tolerance: "pointer", + connectWith: ".board-task-list", + placeholder: "draggable-placeholder", + items: ".draggable-item", + stop: function(event, ui) { + var task = ui.item; + var taskId = task.attr('data-task-id'); + var taskPosition = task.attr('data-position'); + var taskColumnId = task.attr('data-column-id'); + var taskSwimlaneId = task.attr('data-swimlane-id'); + + var newColumnId = task.parent().attr("data-column-id"); + var newSwimlaneId = task.parent().attr('data-swimlane-id'); + var newPosition = task.index() + 1; + + task.removeClass("draggable-item-selected"); + + if (newColumnId != taskColumnId || newSwimlaneId != taskSwimlaneId || newPosition != taskPosition) { + self.changeTaskState(taskId); + self.save(taskId, newColumnId, newPosition, newSwimlaneId); + } + }, + start: function(event, ui) { + ui.item.addClass("draggable-item-selected"); + ui.placeholder.height(ui.item.height()); + } + }; + + if ($.support.touch) { + $(".task-board-sort-handle").css("display", "inline"); + params["handle"] = ".task-board-sort-handle"; + } + + $(".board-task-list").sortable(params); +}; + +Kanboard.BoardDragAndDrop.prototype.changeTaskState = function(taskId) { + var task = $("div[data-task-id=" + taskId + "]"); + task.addClass('task-board-saving-state'); + task.find('.task-board-saving-icon').show(); +}; + +Kanboard.BoardDragAndDrop.prototype.save = function(taskId, columnId, position, swimlaneId) { + var self = this; + self.app.showLoadingIcon(); + self.savingInProgress = true; + + $.ajax({ + cache: false, + url: $("#board").data("save-url"), + contentType: "application/json", + type: "POST", + processData: false, + data: JSON.stringify({ + "task_id": taskId, + "column_id": columnId, + "swimlane_id": swimlaneId, + "position": position + }), + success: function(data) { + self.refresh(data); + self.savingInProgress = false; + }, + error: function() { + self.app.hideLoadingIcon(); + self.savingInProgress = false; + } + }); +}; + +Kanboard.BoardDragAndDrop.prototype.refresh = function(data) { + $("#board-container").replaceWith(data); + + this.app.hideLoadingIcon(); + this.dragAndDrop(); + this.executeListeners(); +}; + +Kanboard.BoardDragAndDrop.prototype.executeListeners = function() { + for (var className in this.app.controllers) { + var controller = this.app.get(className); + + if (typeof controller.onBoardRendered === "function") { + controller.onBoardRendered(); + } + } +}; diff --git a/assets/js/src/BoardHorizontalScrolling.js b/assets/js/src/BoardHorizontalScrolling.js new file mode 100644 index 00000000..81f188c4 --- /dev/null +++ b/assets/js/src/BoardHorizontalScrolling.js @@ -0,0 +1,53 @@ +Kanboard.BoardHorizontalScrolling = function(app) { + this.app = app; +}; + +Kanboard.BoardHorizontalScrolling.prototype.execute = function() { + if (this.app.hasId("board")) { + this.render(); + } +}; + +Kanboard.BoardHorizontalScrolling.prototype.listen = function() { + var self = this; + + $(document).on('click', ".filter-toggle-scrolling", function(e) { + e.preventDefault(); + self.toggle(); + }); +}; + +Kanboard.BoardHorizontalScrolling.prototype.keyboardShortcuts = function() { + var self = this; + + Mousetrap.bind("c", function() { + self.toggle(); + }); +}; + +Kanboard.BoardHorizontalScrolling.prototype.onBoardRendered = function() { + this.render(); +}; + +Kanboard.BoardHorizontalScrolling.prototype.toggle = function() { + var scrolling = localStorage.getItem("horizontal_scroll") || 1; + localStorage.setItem("horizontal_scroll", scrolling == 0 ? 1 : 0); + this.render(); +}; + +Kanboard.BoardHorizontalScrolling.prototype.render = function() { + if (localStorage.getItem("horizontal_scroll") == 0) { + $(".filter-wide").show(); + $(".filter-compact").hide(); + + $("#board-container").addClass("board-container-compact"); + $("#board th:not(.board-column-header-collapsed)").addClass("board-column-compact"); + } + else { + $(".filter-wide").hide(); + $(".filter-compact").show(); + + $("#board-container").removeClass("board-container-compact"); + $("#board th").removeClass("board-column-compact"); + } +}; diff --git a/assets/js/src/BoardPolling.js b/assets/js/src/BoardPolling.js new file mode 100644 index 00000000..ba38b779 --- /dev/null +++ b/assets/js/src/BoardPolling.js @@ -0,0 +1,33 @@ +Kanboard.BoardPolling = function(app) { + this.app = app; +}; + +Kanboard.BoardPolling.prototype.execute = function() { + if (this.app.hasId("board")) { + var interval = parseInt($("#board").attr("data-check-interval")); + + if (interval > 0) { + window.setInterval(this.check.bind(this), interval * 1000); + } + } +}; + +Kanboard.BoardPolling.prototype.check = function() { + if (this.app.isVisible() && !this.app.get("BoardDragAndDrop").savingInProgress) { + var self = this; + this.app.showLoadingIcon(); + + $.ajax({ + cache: false, + url: $("#board").data("check-url"), + statusCode: { + 200: function(data) { + self.app.get("BoardDragAndDrop").refresh(data); + }, + 304: function () { + self.app.hideLoadingIcon(); + } + } + }); + } +}; diff --git a/assets/js/src/BoardTask.js b/assets/js/src/BoardTask.js new file mode 100644 index 00000000..79c55779 --- /dev/null +++ b/assets/js/src/BoardTask.js @@ -0,0 +1,27 @@ +Kanboard.BoardTask = function(app) { + this.app = app; +}; + +Kanboard.BoardTask.prototype.listen = function() { + var self = this; + + $(document).on("click", ".task-board-change-assignee", function(e) { + e.preventDefault(); + e.stopPropagation(); + self.app.get("Popover").open($(this).data('url')); + }); + + $(document).on("click", ".task-board", function(e) { + if (e.target.tagName != "A" && e.target.tagName != "IMG") { + window.location = $(this).data("task-url"); + } + }); +}; + +Kanboard.BoardTask.prototype.keyboardShortcuts = function() { + var self = this; + + Mousetrap.bind("n", function() { + self.app.get("Popover").open($("#board").data("task-creation-url")); + }); +}; diff --git a/assets/js/src/BurndownChart.js b/assets/js/src/BurndownChart.js index 79199b67..63231d3c 100644 --- a/assets/js/src/BurndownChart.js +++ b/assets/js/src/BurndownChart.js @@ -1,12 +1,20 @@ -function BurndownChart() { -} +Kanboard.BurndownChart = function(app) { + this.app = app; +}; + +Kanboard.BurndownChart.prototype.execute = function() { + if (this.app.hasId("analytic-burndown")) { + this.show(); + } +}; -BurndownChart.prototype.execute = function() { - var metrics = $("#chart").data("metrics"); - var columns = [[$("#chart").data("label-total")]]; +Kanboard.BurndownChart.prototype.show = function() { + var chart = $("#chart"); + var metrics = chart.data("metrics"); + var columns = [[chart.data("label-total")]]; var categories = []; var inputFormat = d3.time.format("%Y-%m-%d"); - var outputFormat = d3.time.format($("#chart").data("date-format")); + var outputFormat = d3.time.format(chart.data("date-format")); for (var i = 0; i < metrics.length; i++) { diff --git a/assets/js/src/Calendar.js b/assets/js/src/Calendar.js index ffb00dcd..20079a38 100644 --- a/assets/js/src/Calendar.js +++ b/assets/js/src/Calendar.js @@ -1,10 +1,16 @@ -function Calendar() { - -} +Kanboard.Calendar = function(app) { + this.app = app; +}; -Calendar.prototype.execute = function() { +Kanboard.Calendar.prototype.execute = function() { var calendar = $('#calendar'); + if (calendar.length == 1) { + this.show(calendar); + } +}; + +Kanboard.Calendar.prototype.show = function(calendar) { calendar.fullCalendar({ lang: $("body").data("js-lang"), editable: true, diff --git a/assets/js/src/Column.js b/assets/js/src/Column.js index 2c8ebbd2..1609ae2c 100644 --- a/assets/js/src/Column.js +++ b/assets/js/src/Column.js @@ -1,12 +1,12 @@ -function Column(app) { +Kanboard.Column = function(app) { this.app = app; -} +}; -Column.prototype.listen = function() { +Kanboard.Column.prototype.listen = function() { this.dragAndDrop(); }; -Column.prototype.dragAndDrop = function() { +Kanboard.Column.prototype.dragAndDrop = function() { var self = this; $(".draggable-row-handle").mouseenter(function() { @@ -36,7 +36,7 @@ Column.prototype.dragAndDrop = function() { }).disableSelection(); }; -Column.prototype.savePosition = function(columnId, position) { +Kanboard.Column.prototype.savePosition = function(columnId, position) { var url = $(".columns-table").data("save-position-url"); var self = this; diff --git a/assets/js/src/CompareHoursColumnChart.js b/assets/js/src/CompareHoursColumnChart.js index bed16144..00786c67 100644 --- a/assets/js/src/CompareHoursColumnChart.js +++ b/assets/js/src/CompareHoursColumnChart.js @@ -1,13 +1,20 @@ -function CompareHoursColumnChart(app) { +Kanboard.CompareHoursColumnChart = function(app) { this.app = app; -} +}; + +Kanboard.CompareHoursColumnChart.prototype.execute = function() { + if (this.app.hasId("analytic-compare-hours")) { + this.show(); + } +}; -CompareHoursColumnChart.prototype.execute = function() { - var metrics = $("#chart").data("metrics"); - var labelOpen = $("#chart").data("label-open"); - var labelClosed = $("#chart").data("label-closed"); - var spent = [$("#chart").data("label-spent")]; - var estimated = [$("#chart").data("label-estimated")]; +Kanboard.CompareHoursColumnChart.prototype.show = function() { + var chart = $("#chart"); + var metrics = chart.data("metrics"); + var labelOpen = chart.data("label-open"); + var labelClosed = chart.data("label-closed"); + var spent = [chart.data("label-spent")]; + var estimated = [chart.data("label-estimated")]; var categories = []; for (var status in metrics) { diff --git a/assets/js/src/CumulativeFlowDiagram.js b/assets/js/src/CumulativeFlowDiagram.js index 61a0847b..b22fd2e9 100644 --- a/assets/js/src/CumulativeFlowDiagram.js +++ b/assets/js/src/CumulativeFlowDiagram.js @@ -1,14 +1,21 @@ -function CumulativeFlowDiagram() { -} +Kanboard.CumulativeFlowDiagram = function(app) { + this.app = app; +}; -CumulativeFlowDiagram.prototype.execute = function() { +Kanboard.CumulativeFlowDiagram.prototype.execute = function() { + if (this.app.hasId("analytic-cfd")) { + this.show(); + } +}; - var metrics = $("#chart").data("metrics"); +Kanboard.CumulativeFlowDiagram.prototype.show = function() { + var chart = $("#chart"); + var metrics = chart.data("metrics"); var columns = []; var groups = []; var categories = []; var inputFormat = d3.time.format("%Y-%m-%d"); - var outputFormat = d3.time.format($("#chart").data("date-format")); + var outputFormat = d3.time.format(chart.data("date-format")); for (var i = 0; i < metrics.length; i++) { diff --git a/assets/js/src/Dropdown.js b/assets/js/src/Dropdown.js index 61738da9..46652ba0 100644 --- a/assets/js/src/Dropdown.js +++ b/assets/js/src/Dropdown.js @@ -1,7 +1,8 @@ -function Dropdown() { -} +Kanboard.Dropdown = function(app) { + this.app = app; +}; -Dropdown.prototype.listen = function() { +Kanboard.Dropdown.prototype.listen = function() { var self = this; $(document).on('click', function() { @@ -46,23 +47,12 @@ Dropdown.prototype.listen = function() { $(this).find('a:visible')[0].click(); // Calling native click() not the jQuery one } }); - - // User mention autocomplete - $('textarea[data-mention-search-url]').textcomplete([{ - match: /(^|\s)@(\w*)$/, - search: function (term, callback) { - var url = $('textarea[data-mention-search-url]').data('mention-search-url'); - $.getJSON(url, { q: term }) - .done(function (resp) { callback(resp); }) - .fail(function () { callback([]); }); - }, - replace: function (value) { - return '$1@' + value + ' '; - }, - cache: true - }], {className: "textarea-dropdown"}); }; -Dropdown.prototype.close = function() { +Kanboard.Dropdown.prototype.close = function() { $("#dropdown").remove(); }; + +Kanboard.Dropdown.prototype.onPopoverOpened = function() { + this.close(); +}; diff --git a/assets/js/src/FileUpload.js b/assets/js/src/FileUpload.js index a8816bcd..f53b9bf8 100644 --- a/assets/js/src/FileUpload.js +++ b/assets/js/src/FileUpload.js @@ -1,10 +1,10 @@ -function FileUpload(app) { +Kanboard.FileUpload = function(app) { this.app = app; this.files = []; this.currentFile = 0; -} +}; -FileUpload.prototype.listen = function() { +Kanboard.FileUpload.prototype.onPopoverOpened = function() { var dropzone = document.getElementById("file-dropzone"); var self = this; @@ -12,7 +12,7 @@ FileUpload.prototype.listen = function() { dropzone.ondragover = dropzone.ondragenter = function(e) { e.stopPropagation(); e.preventDefault(); - } + }; dropzone.ondrop = function(e) { e.stopPropagation(); @@ -20,7 +20,7 @@ FileUpload.prototype.listen = function() { self.files = e.dataTransfer.files; self.show(); $("#file-error-max-size").hide(); - } + }; $(document).on("click", "#file-browser", function(e) { e.preventDefault(); @@ -41,7 +41,7 @@ FileUpload.prototype.listen = function() { } }; -FileUpload.prototype.show = function() { +Kanboard.FileUpload.prototype.show = function() { $("#file-list").remove(); if (this.files.length > 0) { @@ -69,7 +69,7 @@ FileUpload.prototype.show = function() { } }; -FileUpload.prototype.checkFiles = function() { +Kanboard.FileUpload.prototype.checkFiles = function() { var max = parseInt($("#file-dropzone").data("max-size")); for (var i = 0; i < this.files.length; i++) { @@ -84,13 +84,13 @@ FileUpload.prototype.checkFiles = function() { this.uploadFiles(); }; -FileUpload.prototype.uploadFiles = function() { +Kanboard.FileUpload.prototype.uploadFiles = function() { if (this.files.length > 0) { this.uploadFile(this.files[this.currentFile]); } }; -FileUpload.prototype.uploadFile = function(file) { +Kanboard.FileUpload.prototype.uploadFile = function(file) { var dropzone = document.getElementById("file-dropzone"); var url = dropzone.dataset.url; var xhr = new XMLHttpRequest(); @@ -104,21 +104,22 @@ FileUpload.prototype.uploadFile = function(file) { xhr.send(fd); }; -FileUpload.prototype.updateProgress = function(e) { +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) + '%)'); } }; -FileUpload.prototype.transferComplete = function() { +Kanboard.FileUpload.prototype.transferComplete = function() { this.currentFile++; if (this.currentFile < this.files.length) { this.uploadFile(this.files[this.currentFile]); } else { - $("#file-upload-button").prop("disabled", true); - $("#file-upload-button").parent().hide(); + var uploadButton = $("#file-upload-button"); + uploadButton.prop("disabled", true); + uploadButton.parent().hide(); $("#file-done").show(); } }; diff --git a/assets/js/src/Gantt.js b/assets/js/src/Gantt.js index 6f536552..254d8f3c 100644 --- a/assets/js/src/Gantt.js +++ b/assets/js/src/Gantt.js @@ -1,5 +1,5 @@ // Based on jQuery.ganttView v.0.8.8 Copyright (c) 2010 JC Grubbs - jc.grubbs@devmynd.com - MIT License -function Gantt(app) { +Kanboard.Gantt = function(app) { this.app = app; this.data = []; @@ -13,10 +13,16 @@ function Gantt(app) { slideWidth: 1000, vHeaderWidth: 200 }; -} +}; + +Kanboard.Gantt.prototype.execute = function() { + if (this.app.hasId("gantt-chart")) { + this.show(); + } +}; // Save record after a resize or move -Gantt.prototype.saveRecord = function(record) { +Kanboard.Gantt.prototype.saveRecord = function(record) { this.app.showLoadingIcon(); $.ajax({ @@ -31,7 +37,7 @@ Gantt.prototype.saveRecord = function(record) { }; // Build the Gantt chart -Gantt.prototype.execute = function() { +Kanboard.Gantt.prototype.show = function() { this.data = this.prepareData($(this.options.container).data('records')); var minDays = Math.floor((this.options.slideWidth / this.options.cellWidth) + 5); @@ -60,7 +66,7 @@ Gantt.prototype.execute = function() { }; // Render record list on the left -Gantt.prototype.renderVerticalHeader = function() { +Kanboard.Gantt.prototype.renderVerticalHeader = function() { var headerDiv = jQuery("<div>", { "class": "ganttview-vtheader" }); var itemDiv = jQuery("<div>", { "class": "ganttview-vtheader-item" }); var seriesDiv = jQuery("<div>", { "class": "ganttview-vtheader-series" }); @@ -92,7 +98,7 @@ Gantt.prototype.renderVerticalHeader = function() { }; // Render right part of the chart (top header + grid + bars) -Gantt.prototype.renderSlider = function(startDate, endDate) { +Kanboard.Gantt.prototype.renderSlider = function(startDate, endDate) { var slideDiv = jQuery("<div>", {"class": "ganttview-slide-container"}); var dates = this.getDates(startDate, endDate); @@ -105,7 +111,7 @@ Gantt.prototype.renderSlider = function(startDate, endDate) { }; // Render top header (days) -Gantt.prototype.renderHorizontalHeader = function(dates) { +Kanboard.Gantt.prototype.renderHorizontalHeader = function(dates) { var headerDiv = jQuery("<div>", { "class": "ganttview-hzheader" }); var monthsDiv = jQuery("<div>", { "class": "ganttview-hzheader-months" }); var daysDiv = jQuery("<div>", { "class": "ganttview-hzheader-days" }); @@ -135,7 +141,7 @@ Gantt.prototype.renderHorizontalHeader = function(dates) { }; // Render grid -Gantt.prototype.renderGrid = function(dates) { +Kanboard.Gantt.prototype.renderGrid = function(dates) { var gridDiv = jQuery("<div>", { "class": "ganttview-grid" }); var rowDiv = jQuery("<div>", { "class": "ganttview-grid-row" }); @@ -162,7 +168,7 @@ Gantt.prototype.renderGrid = function(dates) { }; // Render bar containers -Gantt.prototype.addBlockContainers = function() { +Kanboard.Gantt.prototype.addBlockContainers = function() { var blocksDiv = jQuery("<div>", { "class": "ganttview-blocks" }); for (var i = 0; i < this.data.length; i++) { @@ -173,7 +179,7 @@ Gantt.prototype.addBlockContainers = function() { }; // Render bars -Gantt.prototype.addBlocks = function(slider, start) { +Kanboard.Gantt.prototype.addBlocks = function(slider, start) { var rows = jQuery("div.ganttview-blocks div.ganttview-block-container", slider); var rowIdx = 0; @@ -219,7 +225,7 @@ Gantt.prototype.addBlocks = function(slider, start) { }; // Get tooltip for vertical header -Gantt.prototype.getVerticalHeaderTooltip = function(record) { +Kanboard.Gantt.prototype.getVerticalHeaderTooltip = function(record) { var tooltip = ""; if (record.type == "task") { @@ -246,7 +252,7 @@ Gantt.prototype.getVerticalHeaderTooltip = function(record) { }; // Get tooltip for bars -Gantt.prototype.getBarTooltip = function(record) { +Kanboard.Gantt.prototype.getBarTooltip = function(record) { var tooltip = ""; if (record.not_defined) { @@ -266,7 +272,7 @@ Gantt.prototype.getBarTooltip = function(record) { }; // Set bar color -Gantt.prototype.setBarColor = function(block, record) { +Kanboard.Gantt.prototype.setBarColor = function(block, record) { if (record.not_defined) { block.addClass("ganttview-block-not-defined"); } @@ -277,7 +283,7 @@ Gantt.prototype.setBarColor = function(block, record) { }; // Setup jquery-ui resizable -Gantt.prototype.listenForBlockResize = function(startDate) { +Kanboard.Gantt.prototype.listenForBlockResize = function(startDate) { var self = this; jQuery("div.ganttview-block", this.options.container).resizable({ @@ -293,7 +299,7 @@ Gantt.prototype.listenForBlockResize = function(startDate) { }; // Setup jquery-ui drag and drop -Gantt.prototype.listenForBlockMove = function(startDate) { +Kanboard.Gantt.prototype.listenForBlockMove = function(startDate) { var self = this; jQuery("div.ganttview-block", this.options.container).draggable({ @@ -309,7 +315,7 @@ Gantt.prototype.listenForBlockMove = function(startDate) { }; // Update the record data and the position on the chart -Gantt.prototype.updateDataAndPosition = function(block, startDate) { +Kanboard.Gantt.prototype.updateDataAndPosition = function(block, startDate) { var container = jQuery("div.ganttview-slide-container", this.options.container); var scroll = container.scrollLeft(); var offset = block.offset().left - container.offset().left - 1 + scroll; @@ -349,7 +355,7 @@ Gantt.prototype.updateDataAndPosition = function(block, startDate) { // Creates a 3 dimensional array [year][month][day] of every day // between the given start and end dates -Gantt.prototype.getDates = function(start, end) { +Kanboard.Gantt.prototype.getDates = function(start, end) { var dates = []; dates[start.getFullYear()] = []; dates[start.getFullYear()][start.getMonth()] = [start]; @@ -374,7 +380,7 @@ Gantt.prototype.getDates = function(start, end) { }; // Convert data to Date object -Gantt.prototype.prepareData = function(data) { +Kanboard.Gantt.prototype.prepareData = function(data) { for (var i = 0; i < data.length; i++) { var start = new Date(data[i].start[0], data[i].start[1] - 1, data[i].start[2], 0, 0, 0, 0); data[i].start = start; @@ -387,7 +393,7 @@ Gantt.prototype.prepareData = function(data) { }; // Get the start and end date from the data provided -Gantt.prototype.getDateRange = function(minDays) { +Kanboard.Gantt.prototype.getDateRange = function(minDays) { var minStart = new Date(); var maxEnd = new Date(); @@ -425,7 +431,7 @@ Gantt.prototype.getDateRange = function(minDays) { }; // Returns the number of day between 2 dates -Gantt.prototype.daysBetween = function(start, end) { +Kanboard.Gantt.prototype.daysBetween = function(start, end) { if (! start || ! end) { return 0; } @@ -441,17 +447,17 @@ Gantt.prototype.daysBetween = function(start, end) { }; // Return true if it's the weekend -Gantt.prototype.isWeekend = function(date) { +Kanboard.Gantt.prototype.isWeekend = function(date) { return date.getDay() % 6 == 0; }; // Clone Date object -Gantt.prototype.cloneDate = function(date) { +Kanboard.Gantt.prototype.cloneDate = function(date) { return new Date(date.getTime()); }; // Add days to a Date object -Gantt.prototype.addDays = function(date, value) { +Kanboard.Gantt.prototype.addDays = function(date, value) { date.setDate(date.getDate() + value * 1); return date; }; @@ -463,7 +469,7 @@ Gantt.prototype.addDays = function(date, value) { * 0 = values are equal * 1 = date1 is greaterthan date2. */ -Gantt.prototype.compareDate = function(date1, date2) { +Kanboard.Gantt.prototype.compareDate = function(date1, date2) { if (isNaN(date1) || isNaN(date2)) { throw new Error(date1 + " - " + date2); } else if (date1 instanceof Date && date2 instanceof Date) { diff --git a/assets/js/src/LeadCycleTimeChart.js b/assets/js/src/LeadCycleTimeChart.js index 9ba4a222..7eee77fc 100644 --- a/assets/js/src/LeadCycleTimeChart.js +++ b/assets/js/src/LeadCycleTimeChart.js @@ -1,20 +1,27 @@ -function LeadCycleTimeChart(app) { +Kanboard.LeadCycleTimeChart = function(app) { this.app = app; -} +}; + +Kanboard.LeadCycleTimeChart.prototype.execute = function() { + if (this.app.hasId("analytic-lead-cycle-time")) { + this.show(); + } +}; -LeadCycleTimeChart.prototype.execute = function() { - var metrics = $("#chart").data("metrics"); - var cycle = [$("#chart").data("label-cycle")]; - var lead = [$("#chart").data("label-lead")]; +Kanboard.LeadCycleTimeChart.prototype.show = function() { + var chart = $("#chart"); + var metrics = chart.data("metrics"); + var cycle = [chart.data("label-cycle")]; + var lead = [chart.data("label-lead")]; var categories = []; var types = {}; - types[$("#chart").data("label-cycle")] = 'area'; - types[$("#chart").data("label-lead")] = 'area-spline'; + types[chart.data("label-cycle")] = 'area'; + types[chart.data("label-lead")] = 'area-spline'; var colors = {}; - colors[$("#chart").data("label-lead")] = '#afb42b'; - colors[$("#chart").data("label-cycle")] = '#4e342e'; + colors[chart.data("label-lead")] = '#afb42b'; + colors[chart.data("label-cycle")] = '#4e342e'; for (var i = 0; i < metrics.length; i++) { cycle.push(parseInt(metrics[i].avg_cycle_time)); diff --git a/assets/js/src/Markdown.js b/assets/js/src/Markdown.js index 50293729..11673eec 100644 --- a/assets/js/src/Markdown.js +++ b/assets/js/src/Markdown.js @@ -1,48 +1,59 @@ -function Markdown() { -} - -Markdown.prototype.showPreview = function(e) { - e.preventDefault(); - - var write = $(".write-area"); - var preview = $(".preview-area"); - var textarea = $("textarea"); - - $("#markdown-write").parent().removeClass("form-tab-selected"); - $("#markdown-preview").parent().addClass("form-tab-selected"); - - var request = $.ajax({ - url: $("body").data("markdown-preview-url"), - contentType: "application/json", - type: "POST", - processData: false, - dataType: "html", - data: JSON.stringify({ - "text": textarea.val() - }) - }); +Kanboard.Markdown = function(app) { + this.app = app; + this.editor = null; +}; - request.done(function(data) { - preview.find(".markdown").html(data) - preview.css("height", textarea.css("height")); - preview.css("width", textarea.css("width")); +Kanboard.Markdown.prototype.onPopoverOpened = function() { + this.listen(); +}; - write.hide(); - preview.show(); - }); +Kanboard.Markdown.prototype.onPopoverClosed = function() { + this.listen(); }; -Markdown.prototype.showWriter = function(e) { - e.preventDefault(); +Kanboard.Markdown.prototype.listen = function() { + var editors = $(".markdown-editor"); - $("#markdown-write").parent().addClass("form-tab-selected"); - $("#markdown-preview").parent().removeClass("form-tab-selected"); + if (this.editor) { + this.destroy(); + } - $(".write-area").show(); - $(".preview-area").hide(); + if (editors.length > 0) { + this.show(editors[0]); + } }; -Markdown.prototype.listen = function() { - $(document).on("click", "#markdown-preview", this.showPreview.bind(this)); - $(document).on("click", "#markdown-write", this.showWriter.bind(this)); +Kanboard.Markdown.prototype.destroy = function() { + var cm = this.editor.codemirror; + var wrapper = cm.getWrapperElement(); + + for (var item in ["toolbar", "statusbar", "sideBySide"]) { + if (this.editor.gui[item]) { + wrapper.parentNode.removeChild(this.editor.gui[item]); + } + } + + cm.toTextArea(); + this.editor = null; +}; + +Kanboard.Markdown.prototype.show = function(textarea) { + var toolbar = ["bold", "italic", "strikethrough", "heading", "|", "unordered-list", "ordered-list", "link", "|", "code", "table"]; + + this.editor = new SimpleMDE({ + element: textarea, + status: false, + toolbarTips: false, + autoDownloadFontAwesome: false, + spellChecker: false, + autosave: { + enabled: false + }, + forceSync: true, + blockStyles: { + italic: "_" + }, + toolbar: textarea.hasAttribute("data-markdown-editor-disable-toolbar") ? false : toolbar, + placeholder: textarea.getAttribute("placeholder") + }); }; diff --git a/assets/js/src/Namespace.js b/assets/js/src/Namespace.js new file mode 100644 index 00000000..6b4b0543 --- /dev/null +++ b/assets/js/src/Namespace.js @@ -0,0 +1,3 @@ +'use strict'; + +var Kanboard = {}; diff --git a/assets/js/src/Notification.js b/assets/js/src/Notification.js new file mode 100644 index 00000000..840ee988 --- /dev/null +++ b/assets/js/src/Notification.js @@ -0,0 +1,9 @@ +Kanboard.Notification = function(app) { + this.app = app; +}; + +Kanboard.Notification.prototype.execute = function() { + $(".alert-fade-out").delay(4000).fadeOut(800, function() { + $(this).remove(); + }); +}; diff --git a/assets/js/src/Popover.js b/assets/js/src/Popover.js index 03716d41..705a035a 100644 --- a/assets/js/src/Popover.js +++ b/assets/js/src/Popover.js @@ -1,35 +1,28 @@ -function Popover(app) { +Kanboard.Popover = function(app) { this.app = app; - this.router = new Router(); - this.router.addRoute('screenshot-zone', Screenshot); -} - -Popover.prototype.isOpen = function() { - return $('#popover-container').size() > 0; }; -Popover.prototype.open = function(link) { +Kanboard.Popover.prototype.listen = function() { var self = this; - self.app.dropdown.close(); - $.get(link, function(content) { - $("body").prepend('<div id="popover-container"><div id="popover-content">' + content + '</div></div>'); - self.afterOpen(); + $(document).on("click", ".popover", function(e) { + self.onClick(e); }); -}; -Popover.prototype.close = function(e) { - if (this.isOpen()) { + $(document).on("click", ".close-popover", function(e) { + self.close(e); + }); - if (e) { - e.preventDefault(); - } + $(document).on("click", "#popover-container", function(e) { + self.close(e); + }); - $('#popover-container').remove(); - } + $(document).on("click", "#popover-content", function(e) { + e.stopPropagation(); + }); }; -Popover.prototype.onClick = function(e) { +Kanboard.Popover.prototype.onClick = function(e) { e.preventDefault(); e.stopPropagation(); @@ -45,19 +38,68 @@ Popover.prototype.onClick = function(e) { } }; -Popover.prototype.listen = function() { - $(document).on("click", ".popover", this.onClick.bind(this)); - $(document).on("click", ".close-popover", this.close.bind(this)); - $(document).on("click", "#popover-container", this.close.bind(this)); - $(document).on("click", "#popover-content", function(e) { e.stopPropagation(); }); +Kanboard.Popover.prototype.isOpen = function() { + return $('#popover-container').size() > 0; }; -Popover.prototype.afterOpen = function() { +Kanboard.Popover.prototype.open = function(link) { var self = this; - var popoverForm = $("#popover-content .popover-form"); - self.app.refresh(); - self.router.dispatch(this.app); + $.get(link, function(content) { + $("body").prepend('<div id="popover-container"><div id="popover-content">' + 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) { + window.location = redirect === 'self' ? window.location.href.split("#")[0] : 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) { @@ -69,7 +111,7 @@ Popover.prototype.afterOpen = function() { url: popoverForm.attr("action"), data: popoverForm.serialize(), success: function(data, textStatus, request) { - self.afterSubmit(data, request, self); + self.ajaxReload(data, request, self); }, beforeSend: function() { var button = $('.popover-form button[type="submit"]'); @@ -88,21 +130,16 @@ Popover.prototype.afterOpen = function() { type: "GET", url: $(this).attr("href"), success: function(data, textStatus, request) { - self.afterSubmit(data, request, self); + self.ajaxReload(data, request, self); } }); }); -}; -Popover.prototype.afterSubmit = function(data, request, self) { - var redirect = request.getResponseHeader("X-Ajax-Redirect"); + // Autofocus fields (html5 autofocus works only with page onload) + $("[autofocus]").each(function() { + $(this).focus(); + }); - if (redirect) { - window.location = redirect === 'self' ? window.location.href.split("#")[0] : redirect; - } - else { - $("#popover-content").html(data); - $("#popover-content input[autofocus]").focus(); - self.afterOpen(); - } + this.app.datePicker(); + this.app.autoComplete(); }; diff --git a/assets/js/src/Project.js b/assets/js/src/Project.js deleted file mode 100644 index 19941f03..00000000 --- a/assets/js/src/Project.js +++ /dev/null @@ -1,28 +0,0 @@ -function Project() { -} - -Project.prototype.listen = function() { - $('.project-change-role').on('change', function() { - $.ajax({ - cache: false, - url: $(this).data('url'), - contentType: "application/json", - type: "POST", - processData: false, - data: JSON.stringify({ - "id": $(this).data('id'), - "role": $(this).val() - }) - }); - }); - - $('#project-creation-form #form-src_project_id').on('change', function() { - var srcProjectId = $(this).val(); - - if (srcProjectId == 0) { - $(".project-creation-options").hide(); - } else { - $(".project-creation-options").show(); - } - }); -}; diff --git a/assets/js/src/ProjectCreation.js b/assets/js/src/ProjectCreation.js new file mode 100644 index 00000000..180eab94 --- /dev/null +++ b/assets/js/src/ProjectCreation.js @@ -0,0 +1,15 @@ +Kanboard.ProjectCreation = function(app) { + this.app = app; +}; + +Kanboard.ProjectCreation.prototype.onPopoverOpened = function() { + $('#project-creation-form #form-src_project_id').on('change', function() { + var srcProjectId = $(this).val(); + + if (srcProjectId == 0) { + $(".project-creation-options").hide(); + } else { + $(".project-creation-options").show(); + } + }); +}; diff --git a/assets/js/src/ProjectPermission.js b/assets/js/src/ProjectPermission.js new file mode 100644 index 00000000..fec666b1 --- /dev/null +++ b/assets/js/src/ProjectPermission.js @@ -0,0 +1,19 @@ +Kanboard.ProjectPermission = function(app) { + this.app = app; +}; + +Kanboard.ProjectPermission.prototype.listen = function() { + $('.project-change-role').on('change', function () { + $.ajax({ + cache: false, + url: $(this).data('url'), + contentType: "application/json", + type: "POST", + processData: false, + data: JSON.stringify({ + "id": $(this).data('id'), + "role": $(this).val() + }) + }); + }); +}; diff --git a/assets/js/src/Router.js b/assets/js/src/Router.js deleted file mode 100644 index ab23c0fd..00000000 --- a/assets/js/src/Router.js +++ /dev/null @@ -1,37 +0,0 @@ -function Router() { - this.routes = {}; -} - -Router.prototype.addRoute = function(id, controller) { - this.routes[id] = controller; -}; - -Router.prototype.dispatch = function(app) { - for (var id in this.routes) { - if (document.getElementById(id)) { - var controller = Object.create(this.routes[id].prototype); - this.routes[id].apply(controller, [app]); - controller.execute(); - break; - } - } -}; - -jQuery(document).ready(function() { - var app = new App(); - var router = new Router(); - router.addRoute('board', Board); - router.addRoute('calendar', Calendar); - router.addRoute('screenshot-zone', Screenshot); - router.addRoute('analytic-task-repartition', TaskRepartitionChart); - router.addRoute('analytic-user-repartition', UserRepartitionChart); - router.addRoute('analytic-cfd', CumulativeFlowDiagram); - router.addRoute('analytic-burndown', BurndownChart); - router.addRoute('analytic-avg-time-column', AvgTimeColumnChart); - router.addRoute('analytic-task-time-column', TaskTimeColumnChart); - router.addRoute('analytic-lead-cycle-time', LeadCycleTimeChart); - router.addRoute('analytic-compare-hours', CompareHoursColumnChart); - router.addRoute('gantt-chart', Gantt); - router.dispatch(app); - app.listen(); -}); diff --git a/assets/js/src/Screenshot.js b/assets/js/src/Screenshot.js index e7430dd7..5c74288b 100644 --- a/assets/js/src/Screenshot.js +++ b/assets/js/src/Screenshot.js @@ -1,13 +1,16 @@ -function Screenshot() { +Kanboard.Screenshot = function(app) { + this.app = app; this.pasteCatcher = null; -} +}; -Screenshot.prototype.execute = function() { - this.initialize(); +Kanboard.Screenshot.prototype.onPopoverOpened = function() { + if (this.app.hasId("screenshot-zone")) { + this.initialize(); + } }; // Setup event listener and workarounds -Screenshot.prototype.initialize = function() { +Kanboard.Screenshot.prototype.initialize = function() { this.destroy(); if (! window.Clipboard) { @@ -40,7 +43,7 @@ Screenshot.prototype.initialize = function() { }; // Destroy contentEditable element -Screenshot.prototype.destroy = function() { +Kanboard.Screenshot.prototype.destroy = function() { if (this.pasteCatcher != null) { document.body.removeChild(this.pasteCatcher); } @@ -53,14 +56,14 @@ Screenshot.prototype.destroy = function() { }; // Set focus on contentEditable element -Screenshot.prototype.setFocus = function() { +Kanboard.Screenshot.prototype.setFocus = function() { if (this.pasteCatcher !== null) { this.pasteCatcher.focus(); } }; // Paste event callback -Screenshot.prototype.pasteHandler = function(e) { +Kanboard.Screenshot.prototype.pasteHandler = function(e) { // Firefox doesn't have the property e.clipboardData.items (only Chrome) if (e.clipboardData && e.clipboardData.items) { @@ -95,7 +98,7 @@ Screenshot.prototype.pasteHandler = function(e) { }; // Parse the input in the paste catcher element -Screenshot.prototype.checkInput = function() { +Kanboard.Screenshot.prototype.checkInput = function() { var child = this.pasteCatcher.childNodes[0]; if (child) { @@ -110,7 +113,7 @@ Screenshot.prototype.checkInput = function() { }; // Creates a new image from a given source -Screenshot.prototype.createImage = function(blob) { +Kanboard.Screenshot.prototype.createImage = function(blob) { var pastedImage = new Image(); pastedImage.src = blob; diff --git a/assets/js/src/Search.js b/assets/js/src/Search.js index 4fbfee46..1fcbc5ef 100644 --- a/assets/js/src/Search.js +++ b/assets/js/src/Search.js @@ -1,18 +1,21 @@ -function Search(app) { +Kanboard.Search = function(app) { this.app = app; - this.keyboardShortcuts(); -} +}; + +Kanboard.Search.prototype.focus = function() { -Search.prototype.focus = function() { // Place cursor at the end when focusing on the search box $(document).on("focus", "#form-search", function() { - if ($("#form-search")[0].setSelectionRange) { - $('#form-search')[0].setSelectionRange($('#form-search').val().length, $('#form-search').val().length); + var input = $("#form-search"); + + if (input[0].setSelectionRange) { + var len = input.val().length * 2; + input[0].setSelectionRange(len, len); } }); }; -Search.prototype.listen = function() { +Kanboard.Search.prototype.listen = function() { var self = this; // Filter helper for search @@ -21,68 +24,51 @@ Search.prototype.listen = function() { var filter = $(this).data("filter"); var appendFilter = $(this).data("append-filter"); + var input = $("#form-search"); if (appendFilter) { - filter = $("#form-search").val() + " " + appendFilter; + filter = input.val() + " " + appendFilter; } - $("#form-search").val(filter); - - if ($('#board').length) { - self.app.board.reloadFilters(filter); - } - else { - $("form.search").submit(); - } + input.val(filter); + $("form.search").submit(); }); }; -Search.prototype.keyboardShortcuts = function() { +Kanboard.Search.prototype.goToView = function(label) { + var link = $(label); + + if (link.length) { + window.location = link.attr('href'); + } +}; + +Kanboard.Search.prototype.keyboardShortcuts = function() { var self = this; // Switch view mode for projects: go to the overview page - Mousetrap.bind("v o", function(e) { - var link = $(".view-overview"); - - if (link.length) { - window.location = link.attr('href'); - } + Mousetrap.bind("v o", function() { + self.goToView(".view-overview"); }); // Switch view mode for projects: go to the board - Mousetrap.bind("v b", function(e) { - var link = $(".view-board"); - - if (link.length) { - window.location = link.attr('href'); - } + Mousetrap.bind("v b", function() { + self.goToView(".view-board"); }); // Switch view mode for projects: go to the calendar - Mousetrap.bind("v c", function(e) { - var link = $(".view-calendar"); - - if (link.length) { - window.location = link.attr('href'); - } + Mousetrap.bind("v c", function() { + self.goToView(".view-calendar"); }); // Switch view mode for projects: go to the listing - Mousetrap.bind("v l", function(e) { - var link = $(".view-listing"); - - if (link.length) { - window.location = link.attr('href'); - } + Mousetrap.bind("v l", function() { + self.goToView(".view-listing"); }); // Switch view mode for projects: go to the gantt chart - Mousetrap.bind("v g", function(e) { - var link = $(".view-gantt"); - - if (link.length) { - window.location = link.attr('href'); - } + Mousetrap.bind("v g", function() { + self.goToView(".view-gantt"); }); // Focus to the search field @@ -99,14 +85,9 @@ Search.prototype.keyboardShortcuts = function() { Mousetrap.bind("r", function(e) { e.preventDefault(); var reset = $(".filter-reset").data("filter"); + var input = $("#form-search"); - $("#form-search").val(reset); - - if ($('#board').length) { - self.app.board.reloadFilters(reset); - } - else { - $("form.search").submit(); - } + input.val(reset); + $("form.search").submit(); }); }; diff --git a/assets/js/src/Session.js b/assets/js/src/Session.js new file mode 100644 index 00000000..c07bc58d --- /dev/null +++ b/assets/js/src/Session.js @@ -0,0 +1,21 @@ +Kanboard.Session = function(app) { + this.app = app; +}; + +Kanboard.Session.prototype.execute = function() { + window.setInterval(this.checkSession, 60000); +}; + +Kanboard.Session.prototype.checkSession = function() { + if (! $(".form-login").length) { + $.ajax({ + cache: false, + url: $("body").data("status-url"), + statusCode: { + 401: function() { + window.location = $("body").data("login-url"); + } + } + }); + } +}; diff --git a/assets/js/src/Subtask.js b/assets/js/src/Subtask.js index 7670095e..d4606643 100644 --- a/assets/js/src/Subtask.js +++ b/assets/js/src/Subtask.js @@ -1,15 +1,14 @@ -function Subtask(app) { +Kanboard.Subtask = function(app) { this.app = app; -} +}; -Subtask.prototype.listen = function() { +Kanboard.Subtask.prototype.listen = function() { var self = this; - this.dragAndDrop(); $(document).on("click", ".subtask-toggle-status", function(e) { - e.preventDefault(); var el = $(this); + e.preventDefault(); $.ajax({ cache: false, @@ -27,8 +26,8 @@ Subtask.prototype.listen = function() { }); $(document).on("click", ".subtask-toggle-timer", function(e) { - e.preventDefault(); var el = $(this); + e.preventDefault(); $.ajax({ cache: false, @@ -41,7 +40,7 @@ Subtask.prototype.listen = function() { }); }; -Subtask.prototype.dragAndDrop = function() { +Kanboard.Subtask.prototype.dragAndDrop = function() { var self = this; $(".draggable-row-handle").mouseenter(function() { @@ -71,7 +70,7 @@ Subtask.prototype.dragAndDrop = function() { }).disableSelection(); }; -Subtask.prototype.savePosition = function(subtaskId, position) { +Kanboard.Subtask.prototype.savePosition = function(subtaskId, position) { var url = $(".subtasks-table").data("save-position-url"); var self = this; diff --git a/assets/js/src/Swimlane.js b/assets/js/src/Swimlane.js index 60dbf41f..f95c6678 100644 --- a/assets/js/src/Swimlane.js +++ b/assets/js/src/Swimlane.js @@ -1,12 +1,43 @@ -function Swimlane(app) { +Kanboard.Swimlane = function(app) { this.app = app; -} +}; + +Kanboard.Swimlane.prototype.execute = function() { + if ($(".swimlanes-table").length) { + this.dragAndDrop(); + } +}; + +Kanboard.Swimlane.prototype.listen = function() { + var self = this; + + $(document).on('click', ".board-swimlane-toggle", function(e) { + e.preventDefault(); + + var swimlaneId = $(this).data('swimlane-id'); + + if (self.isCollapsed(swimlaneId)) { + self.expand(swimlaneId); + } + else { + self.collapse(swimlaneId); + } + }); +}; + +Kanboard.Swimlane.prototype.onBoardRendered = function() { + var swimlaneIds = this.getAllCollapsed(); + + for (var i = 0; i < swimlaneIds.length; i++) { + this.collapse(swimlaneIds[i]); + } +}; -Swimlane.prototype.getStorageKey = function() { +Kanboard.Swimlane.prototype.getStorageKey = function() { return "hidden_swimlanes_" + $("#board").data("project-id"); }; -Swimlane.prototype.expand = function(swimlaneId) { +Kanboard.Swimlane.prototype.expand = function(swimlaneId) { var swimlaneIds = this.getAllCollapsed(); var index = swimlaneIds.indexOf(swimlaneId); @@ -22,7 +53,7 @@ Swimlane.prototype.expand = function(swimlaneId) { $('.show-icon-swimlane-' + swimlaneId).css('display', 'none'); }; -Swimlane.prototype.collapse = function(swimlaneId) { +Kanboard.Swimlane.prototype.collapse = function(swimlaneId) { var swimlaneIds = this.getAllCollapsed(); if (swimlaneIds.indexOf(swimlaneId) < 0) { @@ -36,41 +67,15 @@ Swimlane.prototype.collapse = function(swimlaneId) { $('.show-icon-swimlane-' + swimlaneId).css('display', 'inline'); }; -Swimlane.prototype.isCollapsed = function(swimlaneId) { +Kanboard.Swimlane.prototype.isCollapsed = function(swimlaneId) { return this.getAllCollapsed().indexOf(swimlaneId) > -1; }; -Swimlane.prototype.getAllCollapsed = function() { +Kanboard.Swimlane.prototype.getAllCollapsed = function() { return JSON.parse(localStorage.getItem(this.getStorageKey())) || []; }; -Swimlane.prototype.refresh = function() { - var swimlaneIds = this.getAllCollapsed(); - - for (var i = 0; i < swimlaneIds.length; i++) { - this.collapse(swimlaneIds[i]); - } -}; - -Swimlane.prototype.listen = function() { - var self = this; - self.dragAndDrop(); - - $(document).on('click', ".board-swimlane-toggle", function(e) { - e.preventDefault(); - - var swimlaneId = $(this).data('swimlane-id'); - - if (self.isCollapsed(swimlaneId)) { - self.expand(swimlaneId); - } - else { - self.collapse(swimlaneId); - } - }); -}; - -Swimlane.prototype.dragAndDrop = function() { +Kanboard.Swimlane.prototype.dragAndDrop = function() { var self = this; $(".draggable-row-handle").mouseenter(function() { @@ -100,7 +105,7 @@ Swimlane.prototype.dragAndDrop = function() { }).disableSelection(); }; -Swimlane.prototype.savePosition = function(swimlaneId, position) { +Kanboard.Swimlane.prototype.savePosition = function(swimlaneId, position) { var url = $(".swimlanes-table").data("save-position-url"); var self = this; diff --git a/assets/js/src/Task.js b/assets/js/src/Task.js index cbd7dd56..162386ea 100644 --- a/assets/js/src/Task.js +++ b/assets/js/src/Task.js @@ -1,31 +1,31 @@ -function Task(app) { +Kanboard.Task = function(app) { this.app = app; -} +}; -Task.prototype.keyboardShortcuts = function() { +Kanboard.Task.prototype.keyboardShortcuts = function() { var taskView = $("#task-view"); var self = this; - if (taskView.length) { + if (this.app.hasId("task-view")) { Mousetrap.bind("e", function() { - self.app.popover.open(taskView.data("edit-url")); + self.app.get("Popover").open(taskView.data("edit-url")); }); Mousetrap.bind("c", function() { - self.app.popover.open(taskView.data("comment-url")); + self.app.get("Popover").open(taskView.data("comment-url")); }); Mousetrap.bind("s", function() { - self.app.popover.open(taskView.data("subtask-url")); + self.app.get("Popover").open(taskView.data("subtask-url")); }); Mousetrap.bind("l", function() { - self.app.popover.open(taskView.data("internal-link-url")); + self.app.get("Popover").open(taskView.data("internal-link-url")); }); } }; -Task.prototype.listen = function() { +Kanboard.Task.prototype.onPopoverOpened = function() { var self = this; var reloadingProjectId = 0; @@ -38,11 +38,11 @@ Task.prototype.listen = function() { // Assign to me $(document).on("click", ".assign-me", function(e) { - e.preventDefault(); - var currentId = $(this).data("current-id"); var dropdownId = "#" + $(this).data("target-id"); + e.preventDefault(); + if ($(dropdownId + ' option[value=' + currentId + ']').length) { $(dropdownId).val(currentId); } @@ -65,8 +65,7 @@ Task.prototype.listen = function() { success: function(data, textStatus, request) { reloadingProjectId = 0; $(".loading-icon").hide(); - - self.app.popover.afterSubmit(data, request, self.app.popover); + self.app.get("Popover").ajaxReload(data, request, self.app.get("Popover")); } }); } diff --git a/assets/js/src/TaskRepartitionChart.js b/assets/js/src/TaskRepartitionChart.js index 1b1368dc..621be630 100644 --- a/assets/js/src/TaskRepartitionChart.js +++ b/assets/js/src/TaskRepartitionChart.js @@ -1,7 +1,14 @@ -function TaskRepartitionChart() { -} +Kanboard.TaskRepartitionChart = function(app) { + this.app = app; +}; + +Kanboard.TaskRepartitionChart.prototype.execute = function() { + if (this.app.hasId("analytic-task-repartition")) { + this.show(); + } +}; -TaskRepartitionChart.prototype.execute = function() { +Kanboard.TaskRepartitionChart.prototype.show = function() { var metrics = $("#chart").data("metrics"); var columns = []; diff --git a/assets/js/src/TaskTimeColumnChart.js b/assets/js/src/TaskTimeColumnChart.js index 1ecc486b..9b26d76e 100644 --- a/assets/js/src/TaskTimeColumnChart.js +++ b/assets/js/src/TaskTimeColumnChart.js @@ -1,10 +1,17 @@ -function TaskTimeColumnChart(app) { +Kanboard.TaskTimeColumnChart = function(app) { this.app = app; -} +}; + +Kanboard.TaskTimeColumnChart.prototype.execute = function() { + if (this.app.hasId("analytic-task-time-column")) { + this.show(); + } +}; -TaskTimeColumnChart.prototype.execute = function() { - var metrics = $("#chart").data("metrics"); - var plots = [$("#chart").data("label")]; +Kanboard.TaskTimeColumnChart.prototype.show = function() { + var chart = $("#chart"); + var metrics = chart.data("metrics"); + var plots = [chart.data("label")]; var categories = []; for (var i = 0; i < metrics.length; i++) { diff --git a/assets/js/src/Tooltip.js b/assets/js/src/Tooltip.js index f3ef55f9..376b403a 100644 --- a/assets/js/src/Tooltip.js +++ b/assets/js/src/Tooltip.js @@ -1,10 +1,8 @@ -function Tooltip(app) { +Kanboard.Tooltip = function(app) { this.app = app; -} - -Tooltip.prototype.listen = function() { - var self = this; +}; +Kanboard.Tooltip.prototype.execute = function() { $(".tooltip").tooltip({ track: false, show: false, diff --git a/assets/js/src/UserRepartitionChart.js b/assets/js/src/UserRepartitionChart.js index 4255130a..96c08ab3 100644 --- a/assets/js/src/UserRepartitionChart.js +++ b/assets/js/src/UserRepartitionChart.js @@ -1,7 +1,14 @@ -function UserRepartitionChart() { -} +Kanboard.UserRepartitionChart = function(app) { + this.app = app; +}; + +Kanboard.UserRepartitionChart.prototype.execute = function() { + if (this.app.hasId("analytic-user-repartition")) { + this.show(); + } +}; -UserRepartitionChart.prototype.execute = function() { +Kanboard.UserRepartitionChart.prototype.show = function() { var metrics = $("#chart").data("metrics"); var columns = []; diff --git a/assets/js/src/bootstrap.js b/assets/js/src/bootstrap.js new file mode 100644 index 00000000..d5f3c7ef --- /dev/null +++ b/assets/js/src/bootstrap.js @@ -0,0 +1,4 @@ +jQuery(document).ready(function() { + var app = new Kanboard.App(); + app.execute(); +}); |