summaryrefslogtreecommitdiff
path: root/assets/js/src
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2016-03-20 15:45:02 -0400
committerFrederic Guillot <fred@kanboard.net>2016-03-20 15:45:02 -0400
commitf77d6c590bf683377986064113ddddae9ed443c2 (patch)
tree9ac56f1658814c381cdc161492454143e5d0462a /assets/js/src
parent787e91ca415ff2282a1b3328c6a1b28b23596ddc (diff)
Added Markdown editor and Javascript code refactoring
Diffstat (limited to 'assets/js/src')
-rw-r--r--assets/js/src/Accordion.js8
-rw-r--r--assets/js/src/App.js198
-rw-r--r--assets/js/src/AvgTimeColumnChart.js17
-rw-r--r--assets/js/src/Board.js336
-rw-r--r--assets/js/src/BoardCollapsedMode.js25
-rw-r--r--assets/js/src/BoardColumnScrolling.js85
-rw-r--r--assets/js/src/BoardColumnView.js79
-rw-r--r--assets/js/src/BoardDragAndDrop.js103
-rw-r--r--assets/js/src/BoardHorizontalScrolling.js53
-rw-r--r--assets/js/src/BoardPolling.js33
-rw-r--r--assets/js/src/BoardTask.js27
-rw-r--r--assets/js/src/BurndownChart.js20
-rw-r--r--assets/js/src/Calendar.js14
-rw-r--r--assets/js/src/Column.js10
-rw-r--r--assets/js/src/CompareHoursColumnChart.js23
-rw-r--r--assets/js/src/CumulativeFlowDiagram.js17
-rw-r--r--assets/js/src/Dropdown.js28
-rw-r--r--assets/js/src/FileUpload.js27
-rw-r--r--assets/js/src/Gantt.js54
-rw-r--r--assets/js/src/LeadCycleTimeChart.js27
-rw-r--r--assets/js/src/Markdown.js89
-rw-r--r--assets/js/src/Namespace.js3
-rw-r--r--assets/js/src/Notification.js9
-rw-r--r--assets/js/src/Popover.js123
-rw-r--r--assets/js/src/Project.js28
-rw-r--r--assets/js/src/ProjectCreation.js15
-rw-r--r--assets/js/src/ProjectPermission.js19
-rw-r--r--assets/js/src/Router.js37
-rw-r--r--assets/js/src/Screenshot.js23
-rw-r--r--assets/js/src/Search.js91
-rw-r--r--assets/js/src/Session.js21
-rw-r--r--assets/js/src/Subtask.js15
-rw-r--r--assets/js/src/Swimlane.js75
-rw-r--r--assets/js/src/Task.js25
-rw-r--r--assets/js/src/TaskRepartitionChart.js13
-rw-r--r--assets/js/src/TaskTimeColumnChart.js17
-rw-r--r--assets/js/src/Tooltip.js8
-rw-r--r--assets/js/src/UserRepartitionChart.js13
-rw-r--r--assets/js/src/bootstrap.js4
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">&nbsp;<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();
+});