summaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2016-05-18 20:34:36 -0400
committerFrederic Guillot <fred@kanboard.net>2016-05-18 20:34:36 -0400
commit0830fe22b777e419e42cfb3349e61098be9e4127 (patch)
tree83ed2f651d30478357f7c07e8e3a8310891cbadd /assets
parent0378b5fcf9538eb3d4eac6356015f11da894880e (diff)
Minor Gantt chart improvements
* Task do not open anymore in a new window on the Gantt chart * Do not display task progress for tasks with no start/end date
Diffstat (limited to 'assets')
-rw-r--r--assets/js/app.min.js2683
-rw-r--r--assets/js/src/Gantt.js34
2 files changed, 19 insertions, 2698 deletions
diff --git a/assets/js/app.min.js b/assets/js/app.min.js
index 11c54259..e94c77ed 100644
--- a/assets/js/app.min.js
+++ b/assets/js/app.min.js
@@ -1,2681 +1,2 @@
-'use strict';
-
-var Kanboard = {};
-
-Kanboard.Accordion = function(app) {
- this.app = app;
-};
-
-Kanboard.Accordion.prototype.listen = function() {
- $(document).on("click", ".accordion-toggle", function(e) {
- var section = $(this).parents(".accordion-section");
- e.preventDefault();
-
- if (section.hasClass("accordion-collapsed")) {
- section.find(".accordion-content").show();
- section.removeClass("accordion-collapsed");
- } else {
- section.find(".accordion-content").hide();
- section.addClass("accordion-collapsed");
- }
- });
-};
-
-Kanboard.App = function() {
- this.controllers = {};
-};
-
-Kanboard.App.prototype.get = function(controller) {
- return this.controllers[controller];
-};
-
-Kanboard.App.prototype.execute = function() {
- for (var className in Kanboard) {
- if (className !== "App") {
- var controller = new Kanboard[className](this);
- this.controllers[className] = controller;
-
- if (typeof controller.execute === "function") {
- controller.execute();
- }
-
- if (typeof controller.listen === "function") {
- controller.listen();
- }
-
- if (typeof controller.focus === "function") {
- controller.focus();
- }
-
- if (typeof controller.keyboardShortcuts === "function") {
- controller.keyboardShortcuts();
- }
- }
- }
-
- this.focus();
- this.chosen();
- this.keyboardShortcuts();
- this.datePicker();
- this.autoComplete();
-};
-
-Kanboard.App.prototype.keyboardShortcuts = function() {
- var self = this;
-
- // Submit form
- Mousetrap.bindGlobal("mod+enter", function() {
- var forms = $("form");
-
- if (forms.length == 1) {
- forms.submit();
- } else if (forms.length > 1) {
- if (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA') {
- $(document.activeElement).parents("form").submit();
- } else if (self.get("Popover").isOpen()) {
- $("#popover-container form").submit();
- }
- }
- });
-
- // Open board selector
- Mousetrap.bind("b", function(e) {
- e.preventDefault();
- $('#board-selector').trigger('chosen:open');
- });
-
- // Close popover and dropdown
- Mousetrap.bindGlobal("esc", function() {
- self.get("Popover").close();
- self.get("Dropdown").close();
- });
-
- // Show keyboard shortcut
- Mousetrap.bind("?", function() {
- self.get("Popover").open($("body").data("keyboard-shortcut-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());
- });
-};
-
-Kanboard.App.prototype.datePicker = function() {
- // Datepicker translation
- $.datepicker.setDefaults($.datepicker.regional[$("body").data("js-lang")]);
-
- // Datepicker
- $(".form-date").datepicker({
- showOtherMonths: true,
- selectOtherMonths: true,
- dateFormat: 'yy-mm-dd',
- constrainInput: false
- });
-
- // Datetime picker
- $(".form-datetime").datetimepicker({
- controlType: 'select',
- oneLine: true,
- dateFormat: 'yy-mm-dd',
- // timeFormat: 'h:mm tt',
- constrainInput: false
- });
-};
-
-Kanboard.App.prototype.autoComplete = function() {
- $(".autocomplete").each(function() {
- var input = $(this);
- var field = input.data("dst-field");
- var extraField = input.data("dst-extra-field");
-
- if ($('#form-' + field).val() == '') {
- input.parent().find("button[type=submit]").attr('disabled','disabled');
- }
-
- input.autocomplete({
- source: input.data("search-url"),
- minLength: 1,
- select: function(event, ui) {
- $("input[name=" + field + "]").val(ui.item.id);
-
- if (extraField) {
- $("input[name=" + extraField + "]").val(ui.item[extraField]);
- }
-
- input.parent().find("button[type=submit]").removeAttr('disabled');
- }
- });
- });
-};
-
-Kanboard.App.prototype.hasId = function(id) {
- return !!document.getElementById(id);
-};
-
-Kanboard.App.prototype.showLoadingIcon = function() {
- $("body").append('<span id="app-loading-icon">&nbsp;<i class="fa fa-spinner fa-spin"></i></span>');
-};
-
-Kanboard.App.prototype.hideLoadingIcon = function() {
- $("#app-loading-icon").remove();
-};
-
-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") {
- property = "visibilityState";
- } else if (typeof document.mozHidden !== "undefined") {
- property = "mozVisibilityState";
- } else if (typeof document.msHidden !== "undefined") {
- property = "msVisibilityState";
- } else if (typeof document.webkitHidden !== "undefined") {
- property = "webkitVisibilityState";
- }
-
- if (property != "") {
- return document[property] == "visible";
- }
-
- return true;
-};
-
-Kanboard.AvgTimeColumnChart = function(app) {
- this.app = app;
-};
-
-Kanboard.AvgTimeColumnChart.prototype.execute = function() {
- if (this.app.hasId("analytic-avg-time-column")) {
- this.show();
- }
-};
-
-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) {
- plots.push(metrics[column_id].average);
- categories.push(metrics[column_id].title);
- }
-
- c3.generate({
- data: {
- columns: [plots],
- type: 'bar'
- },
- bar: {
- width: {
- ratio: 0.5
- }
- },
- axis: {
- x: {
- type: 'category',
- categories: categories
- },
- y: {
- tick: {
- format: this.app.formatDuration
- }
- }
- },
- legend: {
- show: false
- }
- });
-};
-
-Kanboard.BoardCollapsedMode = function(app) {
- this.app = app;
-};
-
-Kanboard.BoardCollapsedMode.prototype.keyboardShortcuts = function() {
- var self = this;
-
- if (self.app.hasId("board")) {
- 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);
- }
- });
-};
-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);
- }
- }
-};
-
-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);
-};
-
-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();
- }
- }
-};
-
-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;
-
- if (self.app.hasId("board")) {
- 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");
- }
-};
-
-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();
- }
- }
- });
- }
-};
-
-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;
-
- if (self.app.hasId("board")) {
- Mousetrap.bind("n", function () {
- self.app.get("Popover").open($("#board").data("task-creation-url"));
- });
- }
-};
-
-Kanboard.BurndownChart = function(app) {
- this.app = app;
-};
-
-Kanboard.BurndownChart.prototype.execute = function() {
- if (this.app.hasId("analytic-burndown")) {
- this.show();
- }
-};
-
-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"));
-
- for (var i = 0; i < metrics.length; i++) {
-
- for (var j = 0; j < metrics[i].length; j++) {
-
- if (i == 0) {
- columns.push([metrics[i][j]]);
- }
- else {
- columns[j + 1].push(metrics[i][j]);
-
- if (j > 0) {
-
- if (columns[0][i] == undefined) {
- columns[0].push(0);
- }
-
- columns[0][i] += metrics[i][j];
- }
-
- if (j == 0) {
- categories.push(outputFormat(inputFormat.parse(metrics[i][j])));
- }
- }
- }
- }
-
- c3.generate({
- data: {
- columns: columns
- },
- axis: {
- x: {
- type: 'category',
- categories: categories
- }
- }
- });
-};
-
-Kanboard.Calendar = function(app) {
- this.app = app;
-};
-
-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,
- eventLimit: true,
- defaultView: "month",
- header: {
- left: 'prev,next today',
- center: 'title',
- right: 'month,agendaWeek,agendaDay'
- },
- eventDrop: function(event) {
- $.ajax({
- cache: false,
- url: calendar.data("save-url"),
- contentType: "application/json",
- type: "POST",
- processData: false,
- data: JSON.stringify({
- "task_id": event.id,
- "date_due": event.start.format()
- })
- });
- },
- viewRender: function() {
- var url = calendar.data("check-url");
- var params = {
- "start": calendar.fullCalendar('getView').start.format(),
- "end": calendar.fullCalendar('getView').end.format()
- };
-
- for (var key in params) {
- url += "&" + key + "=" + params[key];
- }
-
- $.getJSON(url, function(events) {
- calendar.fullCalendar('removeEvents');
- calendar.fullCalendar('addEventSource', events);
- calendar.fullCalendar('rerenderEvents');
- });
- }
- });
-};
-
-Kanboard.Column = function(app) {
- this.app = app;
-};
-
-Kanboard.Column.prototype.listen = function() {
- this.dragAndDrop();
-};
-
-Kanboard.Column.prototype.dragAndDrop = function() {
- var self = this;
-
- $(".draggable-row-handle").mouseenter(function() {
- $(this).parent().parent().addClass("draggable-item-hover");
- }).mouseleave(function() {
- $(this).parent().parent().removeClass("draggable-item-hover");
- });
-
- $(".columns-table tbody").sortable({
- forcePlaceholderSize: true,
- handle: "td:first i",
- helper: function(e, ui) {
- ui.children().each(function() {
- $(this).width($(this).width());
- });
-
- return ui;
- },
- stop: function(event, ui) {
- var column = ui.item;
- column.removeClass("draggable-item-selected");
- self.savePosition(column.data("column-id"), column.index() + 1);
- },
- start: function(event, ui) {
- ui.item.addClass("draggable-item-selected");
- }
- }).disableSelection();
-};
-
-Kanboard.Column.prototype.savePosition = function(columnId, position) {
- var url = $(".columns-table").data("save-position-url");
- var self = this;
-
- this.app.showLoadingIcon();
-
- $.ajax({
- cache: false,
- url: url,
- contentType: "application/json",
- type: "POST",
- processData: false,
- data: JSON.stringify({
- "column_id": columnId,
- "position": position
- }),
- complete: function() {
- self.app.hideLoadingIcon();
- }
- });
-};
-
-Kanboard.CompareHoursColumnChart = function(app) {
- this.app = app;
-};
-
-Kanboard.CompareHoursColumnChart.prototype.execute = function() {
- if (this.app.hasId("analytic-compare-hours")) {
- this.show();
- }
-};
-
-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) {
- spent.push(parseFloat(metrics[status].time_spent));
- estimated.push(parseFloat(metrics[status].time_estimated));
- categories.push(status == 'open' ? labelOpen : labelClosed);
- }
-
- c3.generate({
- data: {
- columns: [spent, estimated],
- type: 'bar'
- },
- bar: {
- width: {
- ratio: 0.2
- }
- },
- axis: {
- x: {
- type: 'category',
- categories: categories
- }
- },
- legend: {
- show: true
- }
- });
-};
-
-Kanboard.CumulativeFlowDiagram = function(app) {
- this.app = app;
-};
-
-Kanboard.CumulativeFlowDiagram.prototype.execute = function() {
- if (this.app.hasId("analytic-cfd")) {
- this.show();
- }
-};
-
-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"));
-
- for (var i = 0; i < metrics.length; i++) {
-
- for (var j = 0; j < metrics[i].length; j++) {
-
- if (i == 0) {
- columns.push([metrics[i][j]]);
-
- if (j > 0) {
- groups.push(metrics[i][j]);
- }
- }
- else {
-
- columns[j].push(metrics[i][j]);
-
- if (j == 0) {
- categories.push(outputFormat(inputFormat.parse(metrics[i][j])));
- }
- }
- }
- }
-
- c3.generate({
- data: {
- columns: columns,
- type: 'area-spline',
- groups: [groups]
- },
- axis: {
- x: {
- type: 'category',
- categories: categories
- }
- }
- });
-};
-
-Kanboard.Dropdown = function(app) {
- this.app = app;
-};
-
-Kanboard.Dropdown.prototype.listen = function() {
- var self = this;
-
- $(document).on('click', function() {
- self.close();
- });
-
- $(document).on('click', '.dropdown-menu', function(e) {
- e.preventDefault();
- e.stopImmediatePropagation();
- self.close();
-
- var submenu = $(this).next('ul');
- var offset = $(this).offset();
-
- // Clone the submenu outside of the column to avoid clipping issue with overflow
- $("body").append(jQuery("<div>", {"id": "dropdown"}));
- submenu.clone().appendTo("#dropdown");
-
- var clone = $("#dropdown ul");
- clone.addClass('dropdown-submenu-open');
-
- var submenuHeight = clone.outerHeight();
- var submenuWidth = clone.outerWidth();
-
- if (offset.top + submenuHeight - $(window).scrollTop() < $(window).height() || $(window).scrollTop() + offset.top < submenuHeight) {
- clone.css('top', offset.top + $(this).height());
- }
- else {
- clone.css('top', offset.top - submenuHeight - 5);
- }
-
- if (offset.left + submenuWidth > $(window).width()) {
- clone.css('left', offset.left - submenuWidth + $(this).outerWidth());
- }
- else {
- clone.css('left', offset.left);
- }
- });
-
- $(document).on('click', '.dropdown-submenu-open li', function(e) {
- if ($(e.target).is('li')) {
- $(this).find('a:visible')[0].click(); // Calling native click() not the jQuery one
- }
- });
-};
-
-Kanboard.Dropdown.prototype.close = function() {
- $("#dropdown").remove();
-};
-
-Kanboard.Dropdown.prototype.onPopoverOpened = function() {
- this.close();
-};
-
-Kanboard.FileUpload = function(app) {
- this.app = app;
- this.files = [];
- this.currentFile = 0;
-};
-
-Kanboard.FileUpload.prototype.onPopoverOpened = function() {
- var dropzone = document.getElementById("file-dropzone");
- var self = this;
-
- if (dropzone) {
- dropzone.ondragover = dropzone.ondragenter = function(e) {
- e.stopPropagation();
- e.preventDefault();
- };
-
- dropzone.ondrop = function(e) {
- e.stopPropagation();
- e.preventDefault();
- self.files = e.dataTransfer.files;
- self.show();
- $("#file-error-max-size").hide();
- };
-
- $(document).on("click", "#file-browser", function(e) {
- e.preventDefault();
- $("#file-form-element").get(0).click();
- });
-
- $(document).on("click", "#file-upload-button", function(e) {
- e.preventDefault();
- self.currentFile = 0;
- self.checkFiles();
- });
-
- $("#file-form-element").change(function() {
- self.files = document.getElementById("file-form-element").files;
- self.show();
- $("#file-error-max-size").hide();
- });
- }
-};
-
-Kanboard.FileUpload.prototype.show = function() {
- $("#file-list").remove();
-
- if (this.files.length > 0) {
- $("#file-upload-button").prop("disabled", false);
- $("#file-dropzone-inner").hide();
-
- var ul = jQuery("<ul>", {"id": "file-list"});
-
- for (var i = 0; i < this.files.length; i++) {
- var percentage = jQuery("<span>", {"id": "file-percentage-" + i}).append("(0%)");
- var progress = jQuery("<progress>", {"id": "file-progress-" + i, "value": 0});
- var li = jQuery("<li>", {"id": "file-label-" + i})
- .append(progress)
- .append("&nbsp;")
- .append(this.files[i].name)
- .append("&nbsp;")
- .append(percentage);
-
- ul.append(li);
- }
-
- $("#file-dropzone").append(ul);
- } else {
- $("#file-dropzone-inner").show();
- }
-};
-
-Kanboard.FileUpload.prototype.checkFiles = function() {
- var max = parseInt($("#file-dropzone").data("max-size"));
-
- for (var i = 0; i < this.files.length; i++) {
- if (this.files[i].size > max) {
- $("#file-error-max-size").show();
- $("#file-label-" + i).addClass("file-error");
- $("#file-upload-button").prop("disabled", true);
- return;
- }
- }
-
- this.uploadFiles();
-};
-
-Kanboard.FileUpload.prototype.uploadFiles = function() {
- if (this.files.length > 0) {
- this.uploadFile(this.files[this.currentFile]);
- }
-};
-
-Kanboard.FileUpload.prototype.uploadFile = function(file) {
- var dropzone = document.getElementById("file-dropzone");
- var url = dropzone.dataset.url;
- var xhr = new XMLHttpRequest();
- var fd = new FormData();
-
- xhr.upload.addEventListener("progress", this.updateProgress.bind(this));
- xhr.upload.addEventListener("load", this.transferComplete.bind(this));
-
- xhr.open("POST", url, true);
- fd.append('files[]', file);
- xhr.send(fd);
-};
-
-Kanboard.FileUpload.prototype.updateProgress = function(e) {
- if (e.lengthComputable) {
- $("#file-progress-" + this.currentFile).val(e.loaded / e.total);
- $("#file-percentage-" + this.currentFile).text('(' + Math.floor((e.loaded / e.total) * 100) + '%)');
- }
-};
-
-Kanboard.FileUpload.prototype.transferComplete = function() {
- this.currentFile++;
-
- if (this.currentFile < this.files.length) {
- this.uploadFile(this.files[this.currentFile]);
- } else {
- var uploadButton = $("#file-upload-button");
- uploadButton.prop("disabled", true);
- uploadButton.parent().hide();
- $("#file-done").show();
- }
-};
-
-// Based on jQuery.ganttView v.0.8.8 Copyright (c) 2010 JC Grubbs - jc.grubbs@devmynd.com - MIT License
-Kanboard.Gantt = function(app) {
- this.app = app;
- this.data = [];
-
- this.options = {
- container: "#gantt-chart",
- showWeekends: true,
- allowMoves: true,
- allowResizes: true,
- cellWidth: 21,
- cellHeight: 31,
- slideWidth: 1000,
- vHeaderWidth: 200
- };
-};
-
-Kanboard.Gantt.prototype.execute = function() {
- if (this.app.hasId("gantt-chart")) {
- this.show();
- }
-};
-
-// Save record after a resize or move
-Kanboard.Gantt.prototype.saveRecord = function(record) {
- this.app.showLoadingIcon();
-
- $.ajax({
- cache: false,
- url: $(this.options.container).data("save-url"),
- contentType: "application/json",
- type: "POST",
- processData: false,
- data: JSON.stringify(record),
- complete: this.app.hideLoadingIcon.bind(this)
- });
-};
-
-// Build the Gantt chart
-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);
- var range = this.getDateRange(minDays);
- var startDate = range[0];
- var endDate = range[1];
- var container = $(this.options.container);
- var chart = jQuery("<div>", { "class": "ganttview" });
-
- chart.append(this.renderVerticalHeader());
- chart.append(this.renderSlider(startDate, endDate));
- container.append(chart);
-
- jQuery("div.ganttview-grid-row div.ganttview-grid-row-cell:last-child", container).addClass("last");
- jQuery("div.ganttview-hzheader-days div.ganttview-hzheader-day:last-child", container).addClass("last");
- jQuery("div.ganttview-hzheader-months div.ganttview-hzheader-month:last-child", container).addClass("last");
-
- if (! $(this.options.container).data('readonly')) {
- this.listenForBlockResize(startDate);
- this.listenForBlockMove(startDate);
- }
- else {
- this.options.allowResizes = false;
- this.options.allowMoves = false;
- }
-};
-
-// Render record list on the left
-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" });
-
- for (var i = 0; i < this.data.length; i++) {
- var content = jQuery("<span>")
- .append(jQuery("<i>", {"class": "fa fa-info-circle tooltip", "title": this.getVerticalHeaderTooltip(this.data[i])}))
- .append("&nbsp;");
-
- if (this.data[i].type == "task") {
- content.append(jQuery("<a>", {"href": this.data[i].link, "title": this.data[i].title}).append(this.data[i].title));
- }
- else {
- content
- .append(jQuery("<a>", {"href": this.data[i].board_link, "target": "_blank", "title": $(this.options.container).data("label-board-link")}).append('<i class="fa fa-th"></i>'))
- .append("&nbsp;")
- .append(jQuery("<a>", {"href": this.data[i].gantt_link, "target": "_blank", "title": $(this.options.container).data("label-gantt-link")}).append('<i class="fa fa-sliders"></i>'))
- .append("&nbsp;")
- .append(jQuery("<a>", {"href": this.data[i].link, "target": "_blank"}).append(this.data[i].title));
- }
-
- seriesDiv.append(jQuery("<div>", {"class": "ganttview-vtheader-series-name"}).append(content));
- }
-
- itemDiv.append(seriesDiv);
- headerDiv.append(itemDiv);
-
- return headerDiv;
-};
-
-// Render right part of the chart (top header + grid + bars)
-Kanboard.Gantt.prototype.renderSlider = function(startDate, endDate) {
- var slideDiv = jQuery("<div>", {"class": "ganttview-slide-container"});
- var dates = this.getDates(startDate, endDate);
-
- slideDiv.append(this.renderHorizontalHeader(dates));
- slideDiv.append(this.renderGrid(dates));
- slideDiv.append(this.addBlockContainers());
- this.addBlocks(slideDiv, startDate);
-
- return slideDiv;
-};
-
-// Render top header (days)
-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" });
- var totalW = 0;
-
- for (var y in dates) {
- for (var m in dates[y]) {
- var w = dates[y][m].length * this.options.cellWidth;
- totalW = totalW + w;
-
- monthsDiv.append(jQuery("<div>", {
- "class": "ganttview-hzheader-month",
- "css": { "width": (w - 1) + "px" }
- }).append($.datepicker.regional[$("body").data('js-lang')].monthNames[m] + " " + y));
-
- for (var d in dates[y][m]) {
- daysDiv.append(jQuery("<div>", { "class": "ganttview-hzheader-day" }).append(dates[y][m][d].getDate()));
- }
- }
- }
-
- monthsDiv.css("width", totalW + "px");
- daysDiv.css("width", totalW + "px");
- headerDiv.append(monthsDiv).append(daysDiv);
-
- return headerDiv;
-};
-
-// Render grid
-Kanboard.Gantt.prototype.renderGrid = function(dates) {
- var gridDiv = jQuery("<div>", { "class": "ganttview-grid" });
- var rowDiv = jQuery("<div>", { "class": "ganttview-grid-row" });
-
- for (var y in dates) {
- for (var m in dates[y]) {
- for (var d in dates[y][m]) {
- var cellDiv = jQuery("<div>", { "class": "ganttview-grid-row-cell" });
- if (this.options.showWeekends && this.isWeekend(dates[y][m][d])) {
- cellDiv.addClass("ganttview-weekend");
- }
- rowDiv.append(cellDiv);
- }
- }
- }
- var w = jQuery("div.ganttview-grid-row-cell", rowDiv).length * this.options.cellWidth;
- rowDiv.css("width", w + "px");
- gridDiv.css("width", w + "px");
-
- for (var i = 0; i < this.data.length; i++) {
- gridDiv.append(rowDiv.clone());
- }
-
- return gridDiv;
-};
-
-// Render bar containers
-Kanboard.Gantt.prototype.addBlockContainers = function() {
- var blocksDiv = jQuery("<div>", { "class": "ganttview-blocks" });
-
- for (var i = 0; i < this.data.length; i++) {
- blocksDiv.append(jQuery("<div>", { "class": "ganttview-block-container" }));
- }
-
- return blocksDiv;
-};
-
-// Render bars
-Kanboard.Gantt.prototype.addBlocks = function(slider, start) {
- var rows = jQuery("div.ganttview-blocks div.ganttview-block-container", slider);
- var rowIdx = 0;
-
- for (var i = 0; i < this.data.length; i++) {
- var series = this.data[i];
- var size = this.daysBetween(series.start, series.end) + 1;
- var offset = this.daysBetween(start, series.start);
- var text = jQuery("<div>", {"class": "ganttview-block-text"});
-
- var block = jQuery("<div>", {
- "class": "ganttview-block tooltip" + (this.options.allowMoves ? " ganttview-block-movable" : ""),
- "title": this.getBarTooltip(series),
- "css": {
- "width": ((size * this.options.cellWidth) - 9) + "px",
- "margin-left": (offset * this.options.cellWidth) + "px"
- }
- }).append(text);
-
- if (size >= 2) {
- text.append(series.progress);
- }
-
- block.data("record", series);
- this.setBarColor(block, series);
-
- if (series.progress != "0%") {
- block.append(jQuery("<div>", {
- "css": {
- "z-index": 0,
- "position": "absolute",
- "top": 0,
- "bottom": 0,
- "background-color": series.color.border,
- "width": series.progress,
- "opacity": 0.4
- }
- }));
- }
-
- jQuery(rows[rowIdx]).append(block);
- rowIdx = rowIdx + 1;
- }
-};
-
-// Get tooltip for vertical header
-Kanboard.Gantt.prototype.getVerticalHeaderTooltip = function(record) {
- var tooltip = "";
-
- if (record.type == "task") {
- tooltip = "<strong>" + record.column_title + "</strong> (" + record.progress + ")<br/>" + record.title;
- }
- else {
- var types = ["project-manager", "project-member"];
-
- for (var index in types) {
- var type = types[index];
- if (! jQuery.isEmptyObject(record.users[type])) {
- var list = jQuery("<ul>");
-
- for (var user_id in record.users[type]) {
- if (user_id) {
- list.append(jQuery("<li>").append(record.users[type][user_id]));
- }
- }
-
- tooltip += "<p><strong>" + $(this.options.container).data("label-" + type) + "</strong></p>" + list[0].outerHTML;
- }
- }
- }
-
- return tooltip;
-};
-
-// Get tooltip for bars
-Kanboard.Gantt.prototype.getBarTooltip = function(record) {
- var tooltip = "";
-
- if (record.not_defined) {
- tooltip = $(this.options.container).data("label-not-defined");
- }
- else {
- if (record.type == "task") {
- tooltip = "<strong>" + record.progress + "</strong><br/>" +
- $(this.options.container).data("label-assignee") + " " + (record.assignee ? record.assignee : '') + "<br/>";
- }
-
- tooltip += $(this.options.container).data("label-start-date") + " " + $.datepicker.formatDate('yy-mm-dd', record.start) + "<br/>";
- tooltip += $(this.options.container).data("label-end-date") + " " + $.datepicker.formatDate('yy-mm-dd', record.end);
- }
-
- return tooltip;
-};
-
-// Set bar color
-Kanboard.Gantt.prototype.setBarColor = function(block, record) {
- if (record.not_defined) {
- block.addClass("ganttview-block-not-defined");
- }
- else {
- block.css("background-color", record.color.background);
- block.css("border-color", record.color.border);
- }
-};
-
-// Setup jquery-ui resizable
-Kanboard.Gantt.prototype.listenForBlockResize = function(startDate) {
- var self = this;
-
- jQuery("div.ganttview-block", this.options.container).resizable({
- grid: this.options.cellWidth,
- handles: "e,w",
- delay: 300,
- stop: function() {
- var block = jQuery(this);
- self.updateDataAndPosition(block, startDate);
- self.saveRecord(block.data("record"));
- }
- });
-};
-
-// Setup jquery-ui drag and drop
-Kanboard.Gantt.prototype.listenForBlockMove = function(startDate) {
- var self = this;
-
- jQuery("div.ganttview-block", this.options.container).draggable({
- axis: "x",
- delay: 300,
- grid: [this.options.cellWidth, this.options.cellWidth],
- stop: function() {
- var block = jQuery(this);
- self.updateDataAndPosition(block, startDate);
- self.saveRecord(block.data("record"));
- }
- });
-};
-
-// Update the record data and the position on the chart
-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;
- var record = block.data("record");
-
- // Restore color for defined block
- record.not_defined = false;
- this.setBarColor(block, record);
-
- // Set new start date
- var daysFromStart = Math.round(offset / this.options.cellWidth);
- var newStart = this.addDays(this.cloneDate(startDate), daysFromStart);
- record.start = newStart;
-
- // Set new end date
- var width = block.outerWidth();
- var numberOfDays = Math.round(width / this.options.cellWidth) - 1;
- record.end = this.addDays(this.cloneDate(newStart), numberOfDays);
-
- if (record.type === "task" && numberOfDays > 0) {
- jQuery("div.ganttview-block-text", block).text(record.progress);
- }
-
- // Update tooltip
- block.attr("title", this.getBarTooltip(record));
-
- block.data("record", record);
-
- // Remove top and left properties to avoid incorrect block positioning,
- // set position to relative to keep blocks relative to scrollbar when scrolling
- block
- .css("top", "")
- .css("left", "")
- .css("position", "relative")
- .css("margin-left", offset + "px");
-};
-
-// Creates a 3 dimensional array [year][month][day] of every day
-// between the given start and end dates
-Kanboard.Gantt.prototype.getDates = function(start, end) {
- var dates = [];
- dates[start.getFullYear()] = [];
- dates[start.getFullYear()][start.getMonth()] = [start];
- var last = start;
-
- while (this.compareDate(last, end) == -1) {
- var next = this.addDays(this.cloneDate(last), 1);
-
- if (! dates[next.getFullYear()]) {
- dates[next.getFullYear()] = [];
- }
-
- if (! dates[next.getFullYear()][next.getMonth()]) {
- dates[next.getFullYear()][next.getMonth()] = [];
- }
-
- dates[next.getFullYear()][next.getMonth()].push(next);
- last = next;
- }
-
- return dates;
-};
-
-// Convert data to Date object
-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;
-
- var end = new Date(data[i].end[0], data[i].end[1] - 1, data[i].end[2], 0, 0, 0, 0);
- data[i].end = end;
- }
-
- return data;
-};
-
-// Get the start and end date from the data provided
-Kanboard.Gantt.prototype.getDateRange = function(minDays) {
- var minStart = new Date();
- var maxEnd = new Date();
-
- for (var i = 0; i < this.data.length; i++) {
- var start = new Date();
- start.setTime(Date.parse(this.data[i].start));
-
- var end = new Date();
- end.setTime(Date.parse(this.data[i].end));
-
- if (i == 0) {
- minStart = start;
- maxEnd = end;
- }
-
- if (this.compareDate(minStart, start) == 1) {
- minStart = start;
- }
-
- if (this.compareDate(maxEnd, end) == -1) {
- maxEnd = end;
- }
- }
-
- // Insure that the width of the chart is at least the slide width to avoid empty
- // whitespace to the right of the grid
- if (this.daysBetween(minStart, maxEnd) < minDays) {
- maxEnd = this.addDays(this.cloneDate(minStart), minDays);
- }
-
- // Always start one day before the minStart
- minStart.setDate(minStart.getDate() - 1);
-
- return [minStart, maxEnd];
-};
-
-// Returns the number of day between 2 dates
-Kanboard.Gantt.prototype.daysBetween = function(start, end) {
- if (! start || ! end) {
- return 0;
- }
-
- var count = 0, date = this.cloneDate(start);
-
- while (this.compareDate(date, end) == -1) {
- count = count + 1;
- this.addDays(date, 1);
- }
-
- return count;
-};
-
-// Return true if it's the weekend
-Kanboard.Gantt.prototype.isWeekend = function(date) {
- return date.getDay() % 6 == 0;
-};
-
-// Clone Date object
-Kanboard.Gantt.prototype.cloneDate = function(date) {
- return new Date(date.getTime());
-};
-
-// Add days to a Date object
-Kanboard.Gantt.prototype.addDays = function(date, value) {
- date.setDate(date.getDate() + value * 1);
- return date;
-};
-
-/**
- * Compares the first date to the second date and returns an number indication of their relative values.
- *
- * -1 = date1 is lessthan date2
- * 0 = values are equal
- * 1 = date1 is greaterthan 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) {
- return (date1 < date2) ? -1 : (date1 > date2) ? 1 : 0;
- } else {
- throw new TypeError(date1 + " - " + date2);
- }
-};
-
-Kanboard.LeadCycleTimeChart = function(app) {
- this.app = app;
-};
-
-Kanboard.LeadCycleTimeChart.prototype.execute = function() {
- if (this.app.hasId("analytic-lead-cycle-time")) {
- this.show();
- }
-};
-
-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';
-
- var colors = {};
- 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));
- lead.push(parseInt(metrics[i].avg_lead_time));
- categories.push(metrics[i].day);
- }
-
- c3.generate({
- data: {
- columns: [
- lead,
- cycle
- ],
- types: types,
- colors: colors
- },
- axis: {
- x: {
- type: 'category',
- categories: categories
- },
- y: {
- tick: {
- format: this.app.formatDuration
- }
- }
- }
- });
-};
-
-Kanboard.Markdown = function(app) {
- this.app = app;
- this.editor = null;
-};
-
-Kanboard.Markdown.prototype.onPopoverOpened = function() {
- this.listen();
-};
-
-Kanboard.Markdown.prototype.onPopoverClosed = function() {
- this.listen();
-};
-
-Kanboard.Markdown.prototype.listen = function() {
- var editors = $(".markdown-editor");
-
- if (this.editor) {
- this.destroy();
- }
-
- if (editors.length > 0) {
- this.show(editors[0]);
- }
-};
-
-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")
- });
-};
-
-Kanboard.Notification = function(app) {
- this.app = app;
-};
-
-Kanboard.Notification.prototype.execute = function() {
- $(".alert-fade-out").delay(4000).fadeOut(800, function() {
- $(this).remove();
- });
-};
-
-Kanboard.Popover = function(app) {
- this.app = app;
-};
-
-Kanboard.Popover.prototype.listen = function() {
- var self = this;
-
- $(document).on("click", ".popover", function(e) {
- self.onClick(e);
- });
-
- $(document).on("click", ".close-popover", function(e) {
- self.close(e);
- });
-
- $(document).on("click", "#popover-container", function(e) {
- self.close(e);
- });
-
- $(document).on("click", "#popover-content", function(e) {
- e.stopPropagation();
- });
-};
-
-Kanboard.Popover.prototype.onClick = function(e) {
- e.preventDefault();
- e.stopPropagation();
-
- var target = e.currentTarget || e.target;
- var link = target.getAttribute("href");
-
- if (! link) {
- link = target.getAttribute("data-href");
- }
-
- if (link) {
- this.open(link);
- }
-};
-
-Kanboard.Popover.prototype.isOpen = function() {
- return $('#popover-container').size() > 0;
-};
-
-Kanboard.Popover.prototype.open = function(link) {
- var self = this;
-
- if (!self.isOpen()) {
- $.get(link, function(content) {
- $("body").prepend('<div id="popover-container"><div id="popover-content">' + content + '</div></div>');
- self.executeOnOpenedListeners();
- });
- }
-};
-
-Kanboard.Popover.prototype.close = function(e) {
- if (this.isOpen()) {
- if (e) {
- e.preventDefault();
- }
-
- $("#popover-container").remove();
- this.executeOnClosedListeners();
- }
-};
-
-Kanboard.Popover.prototype.ajaxReload = function(data, request, self) {
- var redirect = request.getResponseHeader("X-Ajax-Redirect");
-
- if (redirect === 'self') {
- window.location.reload();
- } else if (redirect && redirect.indexOf('#') > -1) {
- window.location = redirect.split('#')[0];
- } else if (redirect) {
- window.location = redirect;
- } else {
- $("#popover-content").html(data);
- $("#popover-content input[autofocus]").focus();
- self.executeOnOpenedListeners();
- }
-};
-
-Kanboard.Popover.prototype.executeOnOpenedListeners = function() {
- for (var className in this.app.controllers) {
- var controller = this.app.get(className);
-
- if (typeof controller.onPopoverOpened === "function") {
- controller.onPopoverOpened();
- }
- }
-
- this.afterOpen();
-};
-
-Kanboard.Popover.prototype.executeOnClosedListeners = function() {
- for (var className in this.app.controllers) {
- var controller = this.app.get(className);
-
- if (typeof controller.onPopoverClosed === "function") {
- controller.onPopoverClosed();
- }
- }
-};
-
-Kanboard.Popover.prototype.afterOpen = function() {
- var self = this;
- var popoverForm = $("#popover-content .popover-form");
-
- // Submit forms with Ajax request
- if (popoverForm) {
- popoverForm.on("submit", function(e) {
- e.preventDefault();
-
- $.ajax({
- type: "POST",
- url: popoverForm.attr("action"),
- data: popoverForm.serialize(),
- success: function(data, textStatus, request) {
- self.ajaxReload(data, request, self);
- },
- beforeSend: function() {
- var button = $('.popover-form button[type="submit"]');
- button.html('<i class="fa fa-spinner fa-pulse"></i> ' + button.html());
- button.attr("disabled", true);
- }
- });
- });
- }
-
- // Submit link with Ajax request
- $(document).on("click", ".popover-link", function(e) {
- e.preventDefault();
-
- $.ajax({
- type: "GET",
- url: $(this).attr("href"),
- success: function(data, textStatus, request) {
- self.ajaxReload(data, request, self);
- }
- });
- });
-
- // Autofocus fields (html5 autofocus works only with page onload)
- $("[autofocus]").each(function() {
- $(this).focus();
- });
-
- this.app.datePicker();
- this.app.autoComplete();
-};
-
-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();
- }
- });
-};
-
-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()
- })
- });
- });
-};
-
-Kanboard.Screenshot = function(app) {
- this.app = app;
- this.pasteCatcher = null;
-};
-
-Kanboard.Screenshot.prototype.onPopoverOpened = function() {
- if (this.app.hasId("screenshot-zone")) {
- this.initialize();
- }
-};
-
-// Setup event listener and workarounds
-Kanboard.Screenshot.prototype.initialize = function() {
- this.destroy();
-
- if (! window.Clipboard) {
-
- // Create a contenteditable element
- this.pasteCatcher = document.createElement("div");
- this.pasteCatcher.id = "screenshot-pastezone";
- this.pasteCatcher.contentEditable = "true";
-
- // Insert the content editable at the top to avoid scrolling down in the board view
- this.pasteCatcher.style.opacity = 0;
- this.pasteCatcher.style.position = "fixed";
- this.pasteCatcher.style.top = 0;
- this.pasteCatcher.style.right = 0;
- this.pasteCatcher.style.width = 0;
-
- document.body.insertBefore(this.pasteCatcher, document.body.firstChild);
-
- // Set focus on the contenteditable element
- this.pasteCatcher.focus();
-
- // Set the focus when clicked anywhere in the document
- document.addEventListener("click", this.setFocus.bind(this));
-
- // Set the focus when clicked in screenshot dropzone (popover)
- document.getElementById("screenshot-zone").addEventListener("click", this.setFocus.bind(this));
- }
-
- window.addEventListener("paste", this.pasteHandler.bind(this));
-};
-
-// Destroy contentEditable element
-Kanboard.Screenshot.prototype.destroy = function() {
- if (this.pasteCatcher != null) {
- document.body.removeChild(this.pasteCatcher);
- }
- else if (document.getElementById("screenshot-pastezone")) {
- document.body.removeChild(document.getElementById("screenshot-pastezone"));
- }
-
- document.removeEventListener("click", this.setFocus.bind(this));
- this.pasteCatcher = null;
-};
-
-// Set focus on contentEditable element
-Kanboard.Screenshot.prototype.setFocus = function() {
- if (this.pasteCatcher !== null) {
- this.pasteCatcher.focus();
- }
-};
-
-// Paste event callback
-Kanboard.Screenshot.prototype.pasteHandler = function(e) {
- // Firefox doesn't have the property e.clipboardData.items (only Chrome)
- if (e.clipboardData && e.clipboardData.items) {
-
- var items = e.clipboardData.items;
-
- if (items) {
-
- for (var i = 0; i < items.length; i++) {
-
- // Find an image in pasted elements
- if (items[i].type.indexOf("image") !== -1) {
-
- var blob = items[i].getAsFile();
-
- // Get the image as base64 data
- var reader = new FileReader();
- var self = this;
- reader.onload = function(event) {
- self.createImage(event.target.result);
- };
-
- reader.readAsDataURL(blob);
- }
- }
- }
- }
- else {
-
- // Handle Firefox
- setTimeout(this.checkInput.bind(this), 100);
- }
-};
-
-// Parse the input in the paste catcher element
-Kanboard.Screenshot.prototype.checkInput = function() {
- var child = this.pasteCatcher.childNodes[0];
-
- if (child) {
- // If the user pastes an image, the src attribute
- // will represent the image as a base64 encoded string.
- if (child.tagName === "IMG") {
- this.createImage(child.src);
- }
- }
-
- this.pasteCatcher.innerHTML = "";
-};
-
-// Creates a new image from a given source
-Kanboard.Screenshot.prototype.createImage = function(blob) {
- var pastedImage = new Image();
- pastedImage.src = blob;
-
- // Send the image content to the form variable
- pastedImage.onload = function() {
- var sourceSplit = blob.split("base64,");
- var sourceString = sourceSplit[1];
- $("input[name=screenshot]").val(sourceString);
- };
-
- var zone = document.getElementById("screenshot-zone");
- zone.innerHTML = "";
- zone.className = "screenshot-pasted";
- zone.appendChild(pastedImage);
-
- this.destroy();
- this.initialize();
-};
-
-Kanboard.Search = function(app) {
- this.app = app;
-};
-
-Kanboard.Search.prototype.focus = function() {
-
- // Place cursor at the end when focusing on the search box
- $(document).on("focus", "#form-search", function() {
- var input = $("#form-search");
-
- if (input[0].setSelectionRange) {
- var len = input.val().length * 2;
- input[0].setSelectionRange(len, len);
- }
- });
-};
-
-Kanboard.Search.prototype.listen = function() {
- $(document).on("click", ".filter-helper", function (e) {
- e.preventDefault();
-
- var filter = $(this).data("filter");
- var appendFilter = $(this).data("append-filter");
- var uniqueFilter = $(this).data("unique-filter");
- var input = $("#form-search");
-
- if (uniqueFilter) {
- var attribute = uniqueFilter.substr(0, uniqueFilter.indexOf(':'));
- filter = input.val().replace(new RegExp('(' + attribute + ':[#a-z0-9]+)', 'g'), '');
- filter = filter.replace(new RegExp('(' + attribute + ':"(.+)")', 'g'), '');
- filter = filter.trim();
- filter += ' ' + uniqueFilter;
- } else if (appendFilter) {
- filter = input.val() + " " + appendFilter;
- }
-
- input.val(filter);
- $("form.search").submit();
- });
-};
-
-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() {
- self.goToView(".view-overview");
- });
-
- // Switch view mode for projects: go to the board
- Mousetrap.bind("v b", function() {
- self.goToView(".view-board");
- });
-
- // Switch view mode for projects: go to the calendar
- Mousetrap.bind("v c", function() {
- self.goToView(".view-calendar");
- });
-
- // Switch view mode for projects: go to the listing
- Mousetrap.bind("v l", function() {
- self.goToView(".view-listing");
- });
-
- // Switch view mode for projects: go to the gantt chart
- Mousetrap.bind("v g", function() {
- self.goToView(".view-gantt");
- });
-
- // Focus to the search field
- Mousetrap.bind("f", function(e) {
- e.preventDefault();
- var input = document.getElementById("form-search");
-
- if (input) {
- input.focus();
- }
- });
-
- // Reset to the search field
- Mousetrap.bind("r", function(e) {
- e.preventDefault();
- var reset = $(".filter-reset").data("filter");
- var input = $("#form-search");
-
- input.val(reset);
- $("form.search").submit();
- });
-};
-
-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");
- }
- }
- });
- }
-};
-
-Kanboard.Subtask = function(app) {
- this.app = app;
-};
-
-Kanboard.Subtask.prototype.listen = function() {
- var self = this;
- this.dragAndDrop();
-
- $(document).on("click", ".subtask-toggle-status", function(e) {
- var el = $(this);
- e.preventDefault();
-
- $.ajax({
- cache: false,
- url: el.attr("href"),
- success: function(data) {
- if (el.hasClass("subtask-refresh-table")) {
- $(".subtasks-table").replaceWith(data);
- } else {
- el.replaceWith(data);
- }
-
- self.dragAndDrop();
- }
- });
- });
-
- $(document).on("click", ".subtask-toggle-timer", function(e) {
- var el = $(this);
- e.preventDefault();
-
- $.ajax({
- cache: false,
- url: el.attr("href"),
- success: function(data) {
- $(".subtasks-table").replaceWith(data);
- self.dragAndDrop();
- }
- });
- });
-};
-
-Kanboard.Subtask.prototype.dragAndDrop = function() {
- var self = this;
-
- $(".draggable-row-handle").mouseenter(function() {
- $(this).parent().parent().addClass("draggable-item-hover");
- }).mouseleave(function() {
- $(this).parent().parent().removeClass("draggable-item-hover");
- });
-
- $(".subtasks-table tbody").sortable({
- forcePlaceholderSize: true,
- handle: "td:first i",
- helper: function(e, ui) {
- ui.children().each(function() {
- $(this).width($(this).width());
- });
-
- return ui;
- },
- stop: function(event, ui) {
- var subtask = ui.item;
- subtask.removeClass("draggable-item-selected");
- self.savePosition(subtask.data("subtask-id"), subtask.index() + 1);
- },
- start: function(event, ui) {
- ui.item.addClass("draggable-item-selected");
- }
- }).disableSelection();
-};
-
-Kanboard.Subtask.prototype.savePosition = function(subtaskId, position) {
- var url = $(".subtasks-table").data("save-position-url");
- var self = this;
-
- this.app.showLoadingIcon();
-
- $.ajax({
- cache: false,
- url: url,
- contentType: "application/json",
- type: "POST",
- processData: false,
- data: JSON.stringify({
- "subtask_id": subtaskId,
- "position": position
- }),
- complete: function() {
- self.app.hideLoadingIcon();
- }
- });
-};
-
-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]);
- }
-};
-
-Kanboard.Swimlane.prototype.getStorageKey = function() {
- return "hidden_swimlanes_" + $("#board").data("project-id");
-};
-
-Kanboard.Swimlane.prototype.expand = function(swimlaneId) {
- var swimlaneIds = this.getAllCollapsed();
- var index = swimlaneIds.indexOf(swimlaneId);
-
- if (index > -1) {
- swimlaneIds.splice(index, 1);
- }
-
- localStorage.setItem(this.getStorageKey(), JSON.stringify(swimlaneIds));
-
- $('.board-swimlane-columns-' + swimlaneId).css('display', 'table-row');
- $('.board-swimlane-tasks-' + swimlaneId).css('display', 'table-row');
- $('.hide-icon-swimlane-' + swimlaneId).css('display', 'inline');
- $('.show-icon-swimlane-' + swimlaneId).css('display', 'none');
-};
-
-Kanboard.Swimlane.prototype.collapse = function(swimlaneId) {
- var swimlaneIds = this.getAllCollapsed();
-
- if (swimlaneIds.indexOf(swimlaneId) < 0) {
- swimlaneIds.push(swimlaneId);
- localStorage.setItem(this.getStorageKey(), JSON.stringify(swimlaneIds));
- }
-
- $('.board-swimlane-columns-' + swimlaneId + ':not(:first-child)').css('display', 'none');
- $('.board-swimlane-tasks-' + swimlaneId).css('display', 'none');
- $('.hide-icon-swimlane-' + swimlaneId).css('display', 'none');
- $('.show-icon-swimlane-' + swimlaneId).css('display', 'inline');
-};
-
-Kanboard.Swimlane.prototype.isCollapsed = function(swimlaneId) {
- return this.getAllCollapsed().indexOf(swimlaneId) > -1;
-};
-
-Kanboard.Swimlane.prototype.getAllCollapsed = function() {
- return JSON.parse(localStorage.getItem(this.getStorageKey())) || [];
-};
-
-Kanboard.Swimlane.prototype.dragAndDrop = function() {
- var self = this;
-
- $(".draggable-row-handle").mouseenter(function() {
- $(this).parent().parent().addClass("draggable-item-hover");
- }).mouseleave(function() {
- $(this).parent().parent().removeClass("draggable-item-hover");
- });
-
- $(".swimlanes-table tbody").sortable({
- forcePlaceholderSize: true,
- handle: "td:first i",
- helper: function(e, ui) {
- ui.children().each(function() {
- $(this).width($(this).width());
- });
-
- return ui;
- },
- stop: function(event, ui) {
- var swimlane = ui.item;
- swimlane.removeClass("draggable-item-selected");
- self.savePosition(swimlane.data("swimlane-id"), swimlane.index() + 1);
- },
- start: function(event, ui) {
- ui.item.addClass("draggable-item-selected");
- }
- }).disableSelection();
-};
-
-Kanboard.Swimlane.prototype.savePosition = function(swimlaneId, position) {
- var url = $(".swimlanes-table").data("save-position-url");
- var self = this;
-
- this.app.showLoadingIcon();
-
- $.ajax({
- cache: false,
- url: url,
- contentType: "application/json",
- type: "POST",
- processData: false,
- data: JSON.stringify({
- "swimlane_id": swimlaneId,
- "position": position
- }),
- complete: function() {
- self.app.hideLoadingIcon();
- }
- });
-};
-
-Kanboard.Task = function(app) {
- this.app = app;
-};
-
-Kanboard.Task.prototype.keyboardShortcuts = function() {
- var taskView = $("#task-view");
- var self = this;
-
- if (this.app.hasId("task-view")) {
- Mousetrap.bind("e", function() {
- self.app.get("Popover").open(taskView.data("edit-url"));
- });
-
- Mousetrap.bind("d", function() {
- self.app.get("Popover").open(taskView.data("description-url"));
- });
-
- Mousetrap.bind("c", function() {
- self.app.get("Popover").open(taskView.data("comment-url"));
- });
-
- Mousetrap.bind("s", function() {
- self.app.get("Popover").open(taskView.data("subtask-url"));
- });
-
- Mousetrap.bind("l", function() {
- self.app.get("Popover").open(taskView.data("internal-link-url"));
- });
- }
-};
-
-Kanboard.Task.prototype.onPopoverOpened = function() {
- var self = this;
- var reloadingProjectId = 0;
-
- // Change color
- $(document).on("click", ".color-square", function() {
- $(".color-square-selected").removeClass("color-square-selected");
- $(this).addClass("color-square-selected");
- $("#form-color_id").val($(this).data("color-id"));
- });
-
- // Assign to me
- $(document).on("click", ".assign-me", function(e) {
- var currentId = $(this).data("current-id");
- var dropdownId = "#" + $(this).data("target-id");
-
- e.preventDefault();
-
- if ($(dropdownId + ' option[value=' + currentId + ']').length) {
- $(dropdownId).val(currentId);
- }
- });
-
- // Reload page when a destination project is changed
- $(document).on("change", "select.task-reload-project-destination", function() {
- if (reloadingProjectId > 0) {
- $(this).val(reloadingProjectId);
- }
- else {
- reloadingProjectId = $(this).val();
- var url = $(this).data("redirect").replace(/PROJECT_ID/g, reloadingProjectId);
-
- $(".loading-icon").show();
-
- $.ajax({
- type: "GET",
- url: url,
- success: function(data, textStatus, request) {
- reloadingProjectId = 0;
- $(".loading-icon").hide();
- self.app.get("Popover").ajaxReload(data, request, self.app.get("Popover"));
- }
- });
- }
- });
-};
-
-Kanboard.TaskRepartitionChart = function(app) {
- this.app = app;
-};
-
-Kanboard.TaskRepartitionChart.prototype.execute = function() {
- if (this.app.hasId("analytic-task-repartition")) {
- this.show();
- }
-};
-
-Kanboard.TaskRepartitionChart.prototype.show = function() {
- var metrics = $("#chart").data("metrics");
- var columns = [];
-
- for (var i = 0; i < metrics.length; i++) {
- columns.push([metrics[i].column_title, metrics[i].nb_tasks]);
- }
-
- c3.generate({
- data: {
- columns: columns,
- type : 'donut'
- }
- });
-};
-
-Kanboard.TaskTimeColumnChart = function(app) {
- this.app = app;
-};
-
-Kanboard.TaskTimeColumnChart.prototype.execute = function() {
- if (this.app.hasId("analytic-task-time-column")) {
- this.show();
- }
-};
-
-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++) {
- plots.push(metrics[i].time_spent);
- categories.push(metrics[i].title);
- }
-
- c3.generate({
- data: {
- columns: [plots],
- type: 'bar'
- },
- bar: {
- width: {
- ratio: 0.5
- }
- },
- axis: {
- x: {
- type: 'category',
- categories: categories
- },
- y: {
- tick: {
- format: this.app.formatDuration
- }
- }
- },
- legend: {
- show: false
- }
- });
-};
-
-Kanboard.Tooltip = function(app) {
- this.app = app;
-};
-
-Kanboard.Tooltip.prototype.onBoardRendered = function() {
- this.execute();
-};
-
-Kanboard.Tooltip.prototype.execute = function() {
- $(".tooltip").tooltip({
- track: false,
- show: false,
- hide: false,
- position: {
- my: 'left-20 top',
- at: 'center bottom+9',
- using: function(position, feedback) {
-
- $(this).css(position);
-
- var arrow_pos = feedback.target.left + feedback.target.width / 2 - feedback.element.left - 20;
-
- $("<div>")
- .addClass("tooltip-arrow")
- .addClass(feedback.vertical)
- .addClass(arrow_pos < 1 ? "align-left" : "align-right")
- .appendTo(this);
- }
- },
- content: function() {
- var _this = this;
- var href = $(this).attr('data-href');
-
- if (! href) {
- return '<div class="markdown">' + $(this).attr("title") + '</div>';
- }
-
- $.get(href, function setTooltipContent(data) {
- var tooltip = $('.ui-tooltip:visible');
-
- $('.ui-tooltip-content:visible').html(data);
-
- // Clear previous position, it interferes with the updated position computation
- tooltip.css({ top: '', left: '' });
-
- // Remove arrow, it will be added when repositionning
- tooltip.children('.tooltip-arrow').remove();
-
- // Reposition the tooltip
- var position = $(_this).tooltip("option", "position");
- position.of = $(_this);
- tooltip.position(position);
- });
-
- return '<i class="fa fa-spinner fa-spin"></i>';
- }
- })
- .on("mouseenter", function() {
- var _this = this;
- $(this).tooltip("open");
-
- $(".ui-tooltip").on("mouseleave", function() {
- $(_this).tooltip('close');
- });
- }).on("mouseleave focusout", function(e) {
- e.stopImmediatePropagation();
- var _this = this;
-
- setTimeout(function() {
- if (! $(".ui-tooltip:hover").length) {
- $(_this).tooltip("close");
- }
- }, 100);
- });
-};
-
-Kanboard.UserRepartitionChart = function(app) {
- this.app = app;
-};
-
-Kanboard.UserRepartitionChart.prototype.execute = function() {
- if (this.app.hasId("analytic-user-repartition")) {
- this.show();
- }
-};
-
-Kanboard.UserRepartitionChart.prototype.show = function() {
- var metrics = $("#chart").data("metrics");
- var columns = [];
-
- for (var i = 0; i < metrics.length; i++) {
- columns.push([metrics[i].user, metrics[i].nb_tasks]);
- }
-
- c3.generate({
- data: {
- columns: columns,
- type : 'donut'
- }
- });
-};
-
-jQuery(document).ready(function() {
- var app = new Kanboard.App();
- app.execute();
-});
+"use strict";var Kanboard={};Kanboard.Accordion=function(t){this.app=t},Kanboard.Accordion.prototype.listen=function(){$(document).on("click",".accordion-toggle",function(t){var e=$(this).parents(".accordion-section");t.preventDefault(),e.hasClass("accordion-collapsed")?(e.find(".accordion-content").show(),e.removeClass("accordion-collapsed")):(e.find(".accordion-content").hide(),e.addClass("accordion-collapsed"))})},Kanboard.App=function(){this.controllers={}},Kanboard.App.prototype.get=function(t){return this.controllers[t]},Kanboard.App.prototype.execute=function(){for(var t in Kanboard)if("App"!==t){var e=new Kanboard[t](this);this.controllers[t]=e,"function"==typeof e.execute&&e.execute(),"function"==typeof e.listen&&e.listen(),"function"==typeof e.focus&&e.focus(),"function"==typeof e.keyboardShortcuts&&e.keyboardShortcuts()}this.focus(),this.chosen(),this.keyboardShortcuts(),this.datePicker(),this.autoComplete()},Kanboard.App.prototype.keyboardShortcuts=function(){var t=this;Mousetrap.bindGlobal("mod+enter",function(){var e=$("form");1==e.length?e.submit():e.length>1&&("INPUT"===document.activeElement.tagName||"TEXTAREA"===document.activeElement.tagName?$(document.activeElement).parents("form").submit():t.get("Popover").isOpen()&&$("#popover-container form").submit())}),Mousetrap.bind("b",function(t){t.preventDefault(),$("#board-selector").trigger("chosen:open")}),Mousetrap.bindGlobal("esc",function(){t.get("Popover").close(),t.get("Dropdown").close()}),Mousetrap.bind("?",function(){t.get("Popover").open($("body").data("keyboard-shortcut-url"))})},Kanboard.App.prototype.focus=function(){$(document).on("focus",".auto-select",function(){$(this).select()}),$(document).on("mouseup",".auto-select",function(t){t.preventDefault()})},Kanboard.App.prototype.chosen=function(){$(".chosen-select").each(function(){var t=$(this).data("search-threshold");void 0===t&&(t=10),$(this).chosen({width:"180px",no_results_text:$(this).data("notfound"),disable_search_threshold:t})}),$(".select-auto-redirect").change(function(){var t=new RegExp($(this).data("redirect-regex"),"g");window.location=$(this).data("redirect-url").replace(t,$(this).val())})},Kanboard.App.prototype.datePicker=function(){$.datepicker.setDefaults($.datepicker.regional[$("body").data("js-lang")]),$(".form-date").datepicker({showOtherMonths:!0,selectOtherMonths:!0,dateFormat:"yy-mm-dd",constrainInput:!1}),$(".form-datetime").datetimepicker({controlType:"select",oneLine:!0,dateFormat:"yy-mm-dd",constrainInput:!1})},Kanboard.App.prototype.autoComplete=function(){$(".autocomplete").each(function(){var t=$(this),e=t.data("dst-field"),o=t.data("dst-extra-field");""==$("#form-"+e).val()&&t.parent().find("button[type=submit]").attr("disabled","disabled"),t.autocomplete({source:t.data("search-url"),minLength:1,select:function(a,n){$("input[name="+e+"]").val(n.item.id),o&&$("input[name="+o+"]").val(n.item[o]),t.parent().find("button[type=submit]").removeAttr("disabled")}})})},Kanboard.App.prototype.hasId=function(t){return!!document.getElementById(t)},Kanboard.App.prototype.showLoadingIcon=function(){$("body").append('<span id="app-loading-icon">&nbsp;<i class="fa fa-spinner fa-spin"></i></span>')},Kanboard.App.prototype.hideLoadingIcon=function(){$("#app-loading-icon").remove()},Kanboard.App.prototype.formatDuration=function(t){return t>=86400?Math.round(t/86400)+"d":t>=3600?Math.round(t/3600)+"h":t>=60?Math.round(t/60)+"m":t+"s"},Kanboard.App.prototype.isVisible=function(){var t="";return"undefined"!=typeof document.hidden?t="visibilityState":"undefined"!=typeof document.mozHidden?t="mozVisibilityState":"undefined"!=typeof document.msHidden?t="msVisibilityState":"undefined"!=typeof document.webkitHidden&&(t="webkitVisibilityState"),""!=t?"visible"==document[t]:!0},Kanboard.AvgTimeColumnChart=function(t){this.app=t},Kanboard.AvgTimeColumnChart.prototype.execute=function(){this.app.hasId("analytic-avg-time-column")&&this.show()},Kanboard.AvgTimeColumnChart.prototype.show=function(){var t=$("#chart"),e=t.data("metrics"),o=[t.data("label")],a=[];for(var n in e)o.push(e[n].average),a.push(e[n].title);c3.generate({data:{columns:[o],type:"bar"},bar:{width:{ratio:.5}},axis:{x:{type:"category",categories:a},y:{tick:{format:this.app.formatDuration}}},legend:{show:!1}})},Kanboard.BoardCollapsedMode=function(t){this.app=t},Kanboard.BoardCollapsedMode.prototype.keyboardShortcuts=function(){var t=this;t.app.hasId("board")&&Mousetrap.bind("s",function(){t.toggle()})},Kanboard.BoardCollapsedMode.prototype.toggle=function(){var t=this;this.app.showLoadingIcon(),$.ajax({cache:!1,url:$('.filter-display-mode:not([style="display: none;"]) a').attr("href"),success:function(e){$(".filter-display-mode").toggle(),t.app.get("BoardDragAndDrop").refresh(e)}})},Kanboard.BoardColumnScrolling=function(t){this.app=t},Kanboard.BoardColumnScrolling.prototype.execute=function(){this.app.hasId("board")&&(this.render(),$(window).on("load",this.render),$(window).resize(this.render))},Kanboard.BoardColumnScrolling.prototype.listen=function(){var t=this;$(document).on("click",".filter-toggle-height",function(e){e.preventDefault(),t.toggle()})},Kanboard.BoardColumnScrolling.prototype.onBoardRendered=function(){this.render()},Kanboard.BoardColumnScrolling.prototype.toggle=function(){var t=localStorage.getItem("column_scroll");void 0==t&&(t=1),localStorage.setItem("column_scroll",0==t?1:0),this.render()},Kanboard.BoardColumnScrolling.prototype.render=function(){var t=$(".board-task-list"),e=$(".board-rotation-wrapper"),o=$(".filter-max-height"),a=$(".filter-min-height");if(0==localStorage.getItem("column_scroll")){var n=80;o.show(),a.hide(),e.css("min-height",""),t.each(function(){var t=$(this).height();t>n&&(n=t)}),t.css("min-height",n),t.css("height","")}else if(o.hide(),a.show(),$(".board-swimlane").length>1)t.each(function(){$(this).height()>500?$(this).css("height",500):($(this).css("min-height",320),e.css("min-height",320))});else{var n=$(window).height()-170;t.css("height",n),e.css("min-height",n)}},Kanboard.BoardColumnView=function(t){this.app=t},Kanboard.BoardColumnView.prototype.execute=function(){this.app.hasId("board")&&this.render()},Kanboard.BoardColumnView.prototype.listen=function(){var t=this;$(document).on("click",".board-toggle-column-view",function(){t.toggle($(this).data("column-id"))})},Kanboard.BoardColumnView.prototype.onBoardRendered=function(){this.render()},Kanboard.BoardColumnView.prototype.render=function(){var t=this;$(".board-column-header").each(function(){var e=$(this).data("column-id");localStorage.getItem("hidden_column_"+e)&&t.hideColumn(e)})},Kanboard.BoardColumnView.prototype.toggle=function(t){localStorage.getItem("hidden_column_"+t)?this.showColumn(t):this.hideColumn(t)},Kanboard.BoardColumnView.prototype.hideColumn=function(t){$(".board-column-"+t+" .board-column-expanded").hide(),$(".board-column-"+t+" .board-column-collapsed").show(),$(".board-column-header-"+t+" .board-column-expanded").hide(),$(".board-column-header-"+t+" .board-column-collapsed").show(),$(".board-column-header-"+t).each(function(){$(this).removeClass("board-column-compact"),$(this).addClass("board-column-header-collapsed")}),$(".board-column-"+t).each(function(){$(this).addClass("board-column-task-collapsed")}),$(".board-column-"+t+" .board-rotation").each(function(){$(this).css("width",$(".board-column-"+t).height())}),localStorage.setItem("hidden_column_"+t,1)},Kanboard.BoardColumnView.prototype.showColumn=function(t){$(".board-column-"+t+" .board-column-expanded").show(),$(".board-column-"+t+" .board-column-collapsed").hide(),$(".board-column-header-"+t+" .board-column-expanded").show(),$(".board-column-header-"+t+" .board-column-collapsed").hide(),$(".board-column-header-"+t).removeClass("board-column-header-collapsed"),$(".board-column-"+t).removeClass("board-column-task-collapsed"),0==localStorage.getItem("horizontal_scroll")&&$(".board-column-header-"+t).addClass("board-column-compact"),localStorage.removeItem("hidden_column_"+t)},Kanboard.BoardDragAndDrop=function(t){this.app=t,this.savingInProgress=!1},Kanboard.BoardDragAndDrop.prototype.execute=function(){this.app.hasId("board")&&(this.dragAndDrop(),this.executeListeners())},Kanboard.BoardDragAndDrop.prototype.dragAndDrop=function(){var t=this,e={forcePlaceholderSize:!0,tolerance:"pointer",connectWith:".board-task-list",placeholder:"draggable-placeholder",items:".draggable-item",stop:function(e,o){var a=o.item,n=a.attr("data-task-id"),r=a.attr("data-position"),i=a.attr("data-column-id"),s=a.attr("data-swimlane-id"),d=a.parent().attr("data-column-id"),l=a.parent().attr("data-swimlane-id"),p=a.index()+1;a.removeClass("draggable-item-selected"),d==i&&l==s&&p==r||(t.changeTaskState(n),t.save(n,d,p,l))},start:function(t,e){e.item.addClass("draggable-item-selected"),e.placeholder.height(e.item.height())}};$.support.touch&&($(".task-board-sort-handle").css("display","inline"),e.handle=".task-board-sort-handle"),$(".board-task-list").sortable(e)},Kanboard.BoardDragAndDrop.prototype.changeTaskState=function(t){var e=$("div[data-task-id="+t+"]");e.addClass("task-board-saving-state"),e.find(".task-board-saving-icon").show()},Kanboard.BoardDragAndDrop.prototype.save=function(t,e,o,a){var n=this;n.app.showLoadingIcon(),n.savingInProgress=!0,$.ajax({cache:!1,url:$("#board").data("save-url"),contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({task_id:t,column_id:e,swimlane_id:a,position:o}),success:function(t){n.refresh(t),n.savingInProgress=!1},error:function(){n.app.hideLoadingIcon(),n.savingInProgress=!1}})},Kanboard.BoardDragAndDrop.prototype.refresh=function(t){$("#board-container").replaceWith(t),this.app.hideLoadingIcon(),this.dragAndDrop(),this.executeListeners()},Kanboard.BoardDragAndDrop.prototype.executeListeners=function(){for(var t in this.app.controllers){var e=this.app.get(t);"function"==typeof e.onBoardRendered&&e.onBoardRendered()}},Kanboard.BoardHorizontalScrolling=function(t){this.app=t},Kanboard.BoardHorizontalScrolling.prototype.execute=function(){this.app.hasId("board")&&this.render()},Kanboard.BoardHorizontalScrolling.prototype.listen=function(){var t=this;$(document).on("click",".filter-toggle-scrolling",function(e){e.preventDefault(),t.toggle()})},Kanboard.BoardHorizontalScrolling.prototype.keyboardShortcuts=function(){var t=this;t.app.hasId("board")&&Mousetrap.bind("c",function(){t.toggle()})},Kanboard.BoardHorizontalScrolling.prototype.onBoardRendered=function(){this.render()},Kanboard.BoardHorizontalScrolling.prototype.toggle=function(){var t=localStorage.getItem("horizontal_scroll")||1;localStorage.setItem("horizontal_scroll",0==t?1:0),this.render()},Kanboard.BoardHorizontalScrolling.prototype.render=function(){0==localStorage.getItem("horizontal_scroll")?($(".filter-wide").show(),$(".filter-compact").hide(),$("#board-container").addClass("board-container-compact"),$("#board th:not(.board-column-header-collapsed)").addClass("board-column-compact")):($(".filter-wide").hide(),$(".filter-compact").show(),$("#board-container").removeClass("board-container-compact"),$("#board th").removeClass("board-column-compact"))},Kanboard.BoardPolling=function(t){this.app=t},Kanboard.BoardPolling.prototype.execute=function(){if(this.app.hasId("board")){var t=parseInt($("#board").attr("data-check-interval"));t>0&&window.setInterval(this.check.bind(this),1e3*t)}},Kanboard.BoardPolling.prototype.check=function(){if(this.app.isVisible()&&!this.app.get("BoardDragAndDrop").savingInProgress){var t=this;this.app.showLoadingIcon(),$.ajax({cache:!1,url:$("#board").data("check-url"),statusCode:{200:function(e){t.app.get("BoardDragAndDrop").refresh(e)},304:function(){t.app.hideLoadingIcon()}}})}},Kanboard.BoardTask=function(t){this.app=t},Kanboard.BoardTask.prototype.listen=function(){var t=this;$(document).on("click",".task-board-change-assignee",function(e){e.preventDefault(),e.stopPropagation(),t.app.get("Popover").open($(this).data("url"))}),$(document).on("click",".task-board",function(t){"A"!=t.target.tagName&&"IMG"!=t.target.tagName&&(window.location=$(this).data("task-url"))})},Kanboard.BoardTask.prototype.keyboardShortcuts=function(){var t=this;t.app.hasId("board")&&Mousetrap.bind("n",function(){t.app.get("Popover").open($("#board").data("task-creation-url"))})},Kanboard.BurndownChart=function(t){this.app=t},Kanboard.BurndownChart.prototype.execute=function(){this.app.hasId("analytic-burndown")&&this.show()},Kanboard.BurndownChart.prototype.show=function(){for(var t=$("#chart"),e=t.data("metrics"),o=[[t.data("label-total")]],a=[],n=d3.time.format("%Y-%m-%d"),r=d3.time.format(t.data("date-format")),i=0;i<e.length;i++)for(var s=0;s<e[i].length;s++)0==i?o.push([e[i][s]]):(o[s+1].push(e[i][s]),s>0&&(void 0==o[0][i]&&o[0].push(0),o[0][i]+=e[i][s]),0==s&&a.push(r(n.parse(e[i][s]))));c3.generate({data:{columns:o},axis:{x:{type:"category",categories:a}}})},Kanboard.Calendar=function(t){this.app=t},Kanboard.Calendar.prototype.execute=function(){var t=$("#calendar");1==t.length&&this.show(t)},Kanboard.Calendar.prototype.show=function(t){t.fullCalendar({lang:$("body").data("js-lang"),editable:!0,eventLimit:!0,defaultView:"month",header:{left:"prev,next today",center:"title",right:"month,agendaWeek,agendaDay"},eventDrop:function(e){$.ajax({cache:!1,url:t.data("save-url"),contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({task_id:e.id,date_due:e.start.format()})})},viewRender:function(){var e=t.data("check-url"),o={start:t.fullCalendar("getView").start.format(),end:t.fullCalendar("getView").end.format()};for(var a in o)e+="&"+a+"="+o[a];$.getJSON(e,function(e){t.fullCalendar("removeEvents"),t.fullCalendar("addEventSource",e),t.fullCalendar("rerenderEvents")})}})},Kanboard.Column=function(t){this.app=t},Kanboard.Column.prototype.listen=function(){this.dragAndDrop()},Kanboard.Column.prototype.dragAndDrop=function(){var t=this;$(".draggable-row-handle").mouseenter(function(){$(this).parent().parent().addClass("draggable-item-hover")}).mouseleave(function(){$(this).parent().parent().removeClass("draggable-item-hover")}),$(".columns-table tbody").sortable({forcePlaceholderSize:!0,handle:"td:first i",helper:function(t,e){return e.children().each(function(){$(this).width($(this).width())}),e},stop:function(e,o){var a=o.item;a.removeClass("draggable-item-selected"),t.savePosition(a.data("column-id"),a.index()+1)},start:function(t,e){e.item.addClass("draggable-item-selected")}}).disableSelection()},Kanboard.Column.prototype.savePosition=function(t,e){var o=$(".columns-table").data("save-position-url"),a=this;this.app.showLoadingIcon(),$.ajax({cache:!1,url:o,contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({column_id:t,position:e}),complete:function(){a.app.hideLoadingIcon()}})},Kanboard.CompareHoursColumnChart=function(t){this.app=t},Kanboard.CompareHoursColumnChart.prototype.execute=function(){this.app.hasId("analytic-compare-hours")&&this.show()},Kanboard.CompareHoursColumnChart.prototype.show=function(){var t=$("#chart"),e=t.data("metrics"),o=t.data("label-open"),a=t.data("label-closed"),n=[t.data("label-spent")],r=[t.data("label-estimated")],i=[];for(var s in e)n.push(parseFloat(e[s].time_spent)),r.push(parseFloat(e[s].time_estimated)),i.push("open"==s?o:a);c3.generate({data:{columns:[n,r],type:"bar"},bar:{width:{ratio:.2}},axis:{x:{type:"category",categories:i}},legend:{show:!0}})},Kanboard.CumulativeFlowDiagram=function(t){this.app=t},Kanboard.CumulativeFlowDiagram.prototype.execute=function(){this.app.hasId("analytic-cfd")&&this.show()},Kanboard.CumulativeFlowDiagram.prototype.show=function(){for(var t=$("#chart"),e=t.data("metrics"),o=[],a=[],n=[],r=d3.time.format("%Y-%m-%d"),i=d3.time.format(t.data("date-format")),s=0;s<e.length;s++)for(var d=0;d<e[s].length;d++)0==s?(o.push([e[s][d]]),d>0&&a.push(e[s][d])):(o[d].push(e[s][d]),0==d&&n.push(i(r.parse(e[s][d]))));c3.generate({data:{columns:o,type:"area-spline",groups:[a]},axis:{x:{type:"category",categories:n}}})},Kanboard.Dropdown=function(t){this.app=t},Kanboard.Dropdown.prototype.listen=function(){var t=this;$(document).on("click",function(){t.close()}),$(document).on("click",".dropdown-menu",function(e){e.preventDefault(),e.stopImmediatePropagation(),t.close();var o=$(this).next("ul"),a=$(this).offset();$("body").append(jQuery("<div>",{id:"dropdown"})),o.clone().appendTo("#dropdown");var n=$("#dropdown ul");n.addClass("dropdown-submenu-open");var r=n.outerHeight(),i=n.outerWidth();a.top+r-$(window).scrollTop()<$(window).height()||$(window).scrollTop()+a.top<r?n.css("top",a.top+$(this).height()):n.css("top",a.top-r-5),a.left+i>$(window).width()?n.css("left",a.left-i+$(this).outerWidth()):n.css("left",a.left)}),$(document).on("click",".dropdown-submenu-open li",function(t){$(t.target).is("li")&&$(this).find("a:visible")[0].click()})},Kanboard.Dropdown.prototype.close=function(){$("#dropdown").remove()},Kanboard.Dropdown.prototype.onPopoverOpened=function(){this.close()},Kanboard.FileUpload=function(t){this.app=t,this.files=[],this.currentFile=0},Kanboard.FileUpload.prototype.onPopoverOpened=function(){var t=document.getElementById("file-dropzone"),e=this;t&&(t.ondragover=t.ondragenter=function(t){t.stopPropagation(),t.preventDefault()},t.ondrop=function(t){t.stopPropagation(),t.preventDefault(),e.files=t.dataTransfer.files,e.show(),$("#file-error-max-size").hide()},$(document).on("click","#file-browser",function(t){t.preventDefault(),$("#file-form-element").get(0).click()}),$(document).on("click","#file-upload-button",function(t){t.preventDefault(),e.currentFile=0,e.checkFiles()}),$("#file-form-element").change(function(){e.files=document.getElementById("file-form-element").files,e.show(),$("#file-error-max-size").hide()}))},Kanboard.FileUpload.prototype.show=function(){if($("#file-list").remove(),this.files.length>0){$("#file-upload-button").prop("disabled",!1),$("#file-dropzone-inner").hide();for(var t=jQuery("<ul>",{id:"file-list"}),e=0;e<this.files.length;e++){var o=jQuery("<span>",{id:"file-percentage-"+e}).append("(0%)"),a=jQuery("<progress>",{id:"file-progress-"+e,value:0}),n=jQuery("<li>",{id:"file-label-"+e}).append(a).append("&nbsp;").append(this.files[e].name).append("&nbsp;").append(o);t.append(n)}$("#file-dropzone").append(t)}else $("#file-dropzone-inner").show()},Kanboard.FileUpload.prototype.checkFiles=function(){for(var t=parseInt($("#file-dropzone").data("max-size")),e=0;e<this.files.length;e++)if(this.files[e].size>t)return $("#file-error-max-size").show(),$("#file-label-"+e).addClass("file-error"),void $("#file-upload-button").prop("disabled",!0);this.uploadFiles()},Kanboard.FileUpload.prototype.uploadFiles=function(){this.files.length>0&&this.uploadFile(this.files[this.currentFile])},Kanboard.FileUpload.prototype.uploadFile=function(t){var e=document.getElementById("file-dropzone"),o=e.dataset.url,a=new XMLHttpRequest,n=new FormData;a.upload.addEventListener("progress",this.updateProgress.bind(this)),a.upload.addEventListener("load",this.transferComplete.bind(this)),a.open("POST",o,!0),n.append("files[]",t),a.send(n)},Kanboard.FileUpload.prototype.updateProgress=function(t){t.lengthComputable&&($("#file-progress-"+this.currentFile).val(t.loaded/t.total),$("#file-percentage-"+this.currentFile).text("("+Math.floor(t.loaded/t.total*100)+"%)"))},Kanboard.FileUpload.prototype.transferComplete=function(){if(this.currentFile++,this.currentFile<this.files.length)this.uploadFile(this.files[this.currentFile]);else{var t=$("#file-upload-button");t.prop("disabled",!0),t.parent().hide(),$("#file-done").show()}},Kanboard.Gantt=function(t){this.app=t,this.data=[],this.options={container:"#gantt-chart",showWeekends:!0,allowMoves:!0,allowResizes:!0,cellWidth:21,cellHeight:31,slideWidth:1e3,vHeaderWidth:200}},Kanboard.Gantt.prototype.execute=function(){this.app.hasId("gantt-chart")&&this.show()},Kanboard.Gantt.prototype.saveRecord=function(t){this.app.showLoadingIcon(),$.ajax({cache:!1,url:$(this.options.container).data("save-url"),contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify(t),complete:this.app.hideLoadingIcon.bind(this)})},Kanboard.Gantt.prototype.show=function(){this.data=this.prepareData($(this.options.container).data("records"));var t=Math.floor(this.options.slideWidth/this.options.cellWidth+5),e=this.getDateRange(t),o=e[0],a=e[1],n=$(this.options.container),r=jQuery("<div>",{"class":"ganttview"});r.append(this.renderVerticalHeader()),r.append(this.renderSlider(o,a)),n.append(r),jQuery("div.ganttview-grid-row div.ganttview-grid-row-cell:last-child",n).addClass("last"),jQuery("div.ganttview-hzheader-days div.ganttview-hzheader-day:last-child",n).addClass("last"),jQuery("div.ganttview-hzheader-months div.ganttview-hzheader-month:last-child",n).addClass("last"),$(this.options.container).data("readonly")?(this.options.allowResizes=!1,this.options.allowMoves=!1):(this.listenForBlockResize(o),this.listenForBlockMove(o))},Kanboard.Gantt.prototype.renderVerticalHeader=function(){for(var t=jQuery("<div>",{"class":"ganttview-vtheader"}),e=jQuery("<div>",{"class":"ganttview-vtheader-item"}),o=jQuery("<div>",{"class":"ganttview-vtheader-series"}),a=0;a<this.data.length;a++){var n=jQuery("<span>").append(jQuery("<i>",{"class":"fa fa-info-circle tooltip",title:this.getVerticalHeaderTooltip(this.data[a])})).append("&nbsp;");"task"==this.data[a].type?n.append(jQuery("<a>",{href:this.data[a].link,title:this.data[a].title}).append(this.data[a].title)):n.append(jQuery("<a>",{href:this.data[a].board_link,title:$(this.options.container).data("label-board-link")}).append('<i class="fa fa-th"></i>')).append("&nbsp;").append(jQuery("<a>",{href:this.data[a].gantt_link,title:$(this.options.container).data("label-gantt-link")}).append('<i class="fa fa-sliders"></i>')).append("&nbsp;").append(jQuery("<a>",{href:this.data[a].link}).append(this.data[a].title)),o.append(jQuery("<div>",{"class":"ganttview-vtheader-series-name"}).append(n))}return e.append(o),t.append(e),t},Kanboard.Gantt.prototype.renderSlider=function(t,e){var o=jQuery("<div>",{"class":"ganttview-slide-container"}),a=this.getDates(t,e);return o.append(this.renderHorizontalHeader(a)),o.append(this.renderGrid(a)),o.append(this.addBlockContainers()),this.addBlocks(o,t),o},Kanboard.Gantt.prototype.renderHorizontalHeader=function(t){var e=jQuery("<div>",{"class":"ganttview-hzheader"}),o=jQuery("<div>",{"class":"ganttview-hzheader-months"}),a=jQuery("<div>",{"class":"ganttview-hzheader-days"}),n=0;for(var r in t)for(var i in t[r]){var s=t[r][i].length*this.options.cellWidth;n+=s,o.append(jQuery("<div>",{"class":"ganttview-hzheader-month",css:{width:s-1+"px"}}).append($.datepicker.regional[$("body").data("js-lang")].monthNames[i]+" "+r));for(var d in t[r][i])a.append(jQuery("<div>",{"class":"ganttview-hzheader-day"}).append(t[r][i][d].getDate()))}return o.css("width",n+"px"),a.css("width",n+"px"),e.append(o).append(a),e},Kanboard.Gantt.prototype.renderGrid=function(t){var e=jQuery("<div>",{"class":"ganttview-grid"}),o=jQuery("<div>",{"class":"ganttview-grid-row"});for(var a in t)for(var n in t[a])for(var r in t[a][n]){var i=jQuery("<div>",{"class":"ganttview-grid-row-cell"});this.options.showWeekends&&this.isWeekend(t[a][n][r])&&i.addClass("ganttview-weekend"),o.append(i)}var s=jQuery("div.ganttview-grid-row-cell",o).length*this.options.cellWidth;o.css("width",s+"px"),e.css("width",s+"px");for(var d=0;d<this.data.length;d++)e.append(o.clone());return e},Kanboard.Gantt.prototype.addBlockContainers=function(){for(var t=jQuery("<div>",{"class":"ganttview-blocks"}),e=0;e<this.data.length;e++)t.append(jQuery("<div>",{"class":"ganttview-block-container"}));return t},Kanboard.Gantt.prototype.addBlocks=function(t,e){for(var o=jQuery("div.ganttview-blocks div.ganttview-block-container",t),a=0,n=0;n<this.data.length;n++){var r=this.data[n],i=this.daysBetween(r.start,r.end)+1,s=this.daysBetween(e,r.start),d=jQuery("<div>",{"class":"ganttview-block-text"}),l=jQuery("<div>",{"class":"ganttview-block tooltip"+(this.options.allowMoves?" ganttview-block-movable":""),title:this.getBarTooltip(r),css:{width:i*this.options.cellWidth-9+"px","margin-left":s*this.options.cellWidth+"px"}}).append(d);i>=2&&d.append(r.progress),l.data("record",r),this.setBarColor(l,r),jQuery(o[a]).append(l),a+=1}},Kanboard.Gantt.prototype.getVerticalHeaderTooltip=function(t){var e="";if("task"==t.type)e="<strong>"+t.column_title+"</strong> ("+t.progress+")<br/>"+t.title;else{var o=["project-manager","project-member"];for(var a in o){var n=o[a];if(!jQuery.isEmptyObject(t.users[n])){var r=jQuery("<ul>");for(var i in t.users[n])i&&r.append(jQuery("<li>").append(t.users[n][i]));e+="<p><strong>"+$(this.options.container).data("label-"+n)+"</strong></p>"+r[0].outerHTML}}}return e},Kanboard.Gantt.prototype.getBarTooltip=function(t){var e="";return t.not_defined?e=$(this.options.container).data("label-not-defined"):("task"==t.type&&(e="<strong>"+t.progress+"</strong><br/>"+$(this.options.container).data("label-assignee")+" "+(t.assignee?t.assignee:"")+"<br/>"),e+=$(this.options.container).data("label-start-date")+" "+$.datepicker.formatDate("yy-mm-dd",t.start)+"<br/>",e+=$(this.options.container).data("label-end-date")+" "+$.datepicker.formatDate("yy-mm-dd",t.end)),e},Kanboard.Gantt.prototype.setBarColor=function(t,e){e.not_defined?t.addClass("ganttview-block-not-defined"):(t.css("background-color",e.color.background),t.css("border-color",e.color.border),"0%"!=e.progress&&t.append(jQuery("<div>",{css:{"z-index":0,position:"absolute",top:0,bottom:0,"background-color":e.color.border,width:e.progress,opacity:.4}})))},Kanboard.Gantt.prototype.listenForBlockResize=function(t){var e=this;jQuery("div.ganttview-block",this.options.container).resizable({grid:this.options.cellWidth,handles:"e,w",delay:300,stop:function(){var o=jQuery(this);e.updateDataAndPosition(o,t),e.saveRecord(o.data("record"))}})},Kanboard.Gantt.prototype.listenForBlockMove=function(t){var e=this;jQuery("div.ganttview-block",this.options.container).draggable({axis:"x",delay:300,grid:[this.options.cellWidth,this.options.cellWidth],stop:function(){var o=jQuery(this);e.updateDataAndPosition(o,t),e.saveRecord(o.data("record"))}})},Kanboard.Gantt.prototype.updateDataAndPosition=function(t,e){var o=jQuery("div.ganttview-slide-container",this.options.container),a=o.scrollLeft(),n=t.offset().left-o.offset().left-1+a,r=t.data("record");r.not_defined=!1,this.setBarColor(t,r);var i=Math.round(n/this.options.cellWidth),s=this.addDays(this.cloneDate(e),i);r.start=s;var d=t.outerWidth(),l=Math.round(d/this.options.cellWidth)-1;r.end=this.addDays(this.cloneDate(s),l),"task"===r.type&&l>0&&jQuery("div.ganttview-block-text",t).text(r.progress),t.attr("title",this.getBarTooltip(r)),t.data("record",r),t.css("top","").css("left","").css("position","relative").css("margin-left",n+"px")},Kanboard.Gantt.prototype.getDates=function(t,e){var o=[];o[t.getFullYear()]=[],o[t.getFullYear()][t.getMonth()]=[t];for(var a=t;-1==this.compareDate(a,e);){var n=this.addDays(this.cloneDate(a),1);o[n.getFullYear()]||(o[n.getFullYear()]=[]),o[n.getFullYear()][n.getMonth()]||(o[n.getFullYear()][n.getMonth()]=[]),o[n.getFullYear()][n.getMonth()].push(n),a=n}return o},Kanboard.Gantt.prototype.prepareData=function(t){for(var e=0;e<t.length;e++){var o=new Date(t[e].start[0],t[e].start[1]-1,t[e].start[2],0,0,0,0);t[e].start=o;var a=new Date(t[e].end[0],t[e].end[1]-1,t[e].end[2],0,0,0,0);t[e].end=a}return t},Kanboard.Gantt.prototype.getDateRange=function(t){for(var e=new Date,o=new Date,a=0;a<this.data.length;a++){var n=new Date;n.setTime(Date.parse(this.data[a].start));var r=new Date;r.setTime(Date.parse(this.data[a].end)),0==a&&(e=n,o=r),1==this.compareDate(e,n)&&(e=n),-1==this.compareDate(o,r)&&(o=r)}return this.daysBetween(e,o)<t&&(o=this.addDays(this.cloneDate(e),t)),e.setDate(e.getDate()-1),[e,o]},Kanboard.Gantt.prototype.daysBetween=function(t,e){if(!t||!e)return 0;for(var o=0,a=this.cloneDate(t);-1==this.compareDate(a,e);)o+=1,this.addDays(a,1);return o},Kanboard.Gantt.prototype.isWeekend=function(t){return t.getDay()%6==0},Kanboard.Gantt.prototype.cloneDate=function(t){return new Date(t.getTime())},Kanboard.Gantt.prototype.addDays=function(t,e){return t.setDate(t.getDate()+1*e),t},Kanboard.Gantt.prototype.compareDate=function(t,e){if(isNaN(t)||isNaN(e))throw new Error(t+" - "+e);if(t instanceof Date&&e instanceof Date)return e>t?-1:t>e?1:0;throw new TypeError(t+" - "+e)},Kanboard.LeadCycleTimeChart=function(t){this.app=t},Kanboard.LeadCycleTimeChart.prototype.execute=function(){this.app.hasId("analytic-lead-cycle-time")&&this.show()},Kanboard.LeadCycleTimeChart.prototype.show=function(){var t=$("#chart"),e=t.data("metrics"),o=[t.data("label-cycle")],a=[t.data("label-lead")],n=[],r={};r[t.data("label-cycle")]="area",r[t.data("label-lead")]="area-spline";var i={};i[t.data("label-lead")]="#afb42b",i[t.data("label-cycle")]="#4e342e";for(var s=0;s<e.length;s++)o.push(parseInt(e[s].avg_cycle_time)),a.push(parseInt(e[s].avg_lead_time)),n.push(e[s].day);c3.generate({data:{columns:[a,o],types:r,colors:i},axis:{x:{type:"category",categories:n},y:{tick:{format:this.app.formatDuration}}}})},Kanboard.Markdown=function(t){this.app=t,this.editor=null},Kanboard.Markdown.prototype.onPopoverOpened=function(){this.listen()},Kanboard.Markdown.prototype.onPopoverClosed=function(){this.listen()},Kanboard.Markdown.prototype.listen=function(){var t=$(".markdown-editor");this.editor&&this.destroy(),t.length>0&&this.show(t[0])},Kanboard.Markdown.prototype.destroy=function(){var t=this.editor.codemirror,e=t.getWrapperElement();for(var o in["toolbar","statusbar","sideBySide"])this.editor.gui[o]&&e.parentNode.removeChild(this.editor.gui[o]);t.toTextArea(),this.editor=null},Kanboard.Markdown.prototype.show=function(t){var e=["bold","italic","strikethrough","heading","|","unordered-list","ordered-list","link","|","code","table"];this.editor=new SimpleMDE({element:t,status:!1,toolbarTips:!1,autoDownloadFontAwesome:!1,spellChecker:!1,autosave:{enabled:!1},forceSync:!0,blockStyles:{italic:"_"},toolbar:t.hasAttribute("data-markdown-editor-disable-toolbar")?!1:e,placeholder:t.getAttribute("placeholder")})},Kanboard.Notification=function(t){this.app=t},Kanboard.Notification.prototype.execute=function(){$(".alert-fade-out").delay(4e3).fadeOut(800,function(){$(this).remove()})},Kanboard.Popover=function(t){this.app=t},Kanboard.Popover.prototype.listen=function(){var t=this;$(document).on("click",".popover",function(e){t.onClick(e)}),$(document).on("click",".close-popover",function(e){t.close(e)}),$(document).on("click","#popover-container",function(e){t.close(e)}),$(document).on("click","#popover-content",function(t){t.stopPropagation()})},Kanboard.Popover.prototype.onClick=function(t){t.preventDefault(),t.stopPropagation();var e=t.currentTarget||t.target,o=e.getAttribute("href");o||(o=e.getAttribute("data-href")),o&&this.open(o)},Kanboard.Popover.prototype.isOpen=function(){return $("#popover-container").size()>0},Kanboard.Popover.prototype.open=function(t){var e=this;e.isOpen()||$.get(t,function(t){$("body").prepend('<div id="popover-container"><div id="popover-content">'+t+"</div></div>"),e.executeOnOpenedListeners()})},Kanboard.Popover.prototype.close=function(t){this.isOpen()&&(t&&t.preventDefault(),$("#popover-container").remove(),this.executeOnClosedListeners())},Kanboard.Popover.prototype.ajaxReload=function(t,e,o){var a=e.getResponseHeader("X-Ajax-Redirect");"self"===a?window.location.reload():a&&a.indexOf("#")>-1?window.location=a.split("#")[0]:a?window.location=a:($("#popover-content").html(t),$("#popover-content input[autofocus]").focus(),o.executeOnOpenedListeners())},Kanboard.Popover.prototype.executeOnOpenedListeners=function(){for(var t in this.app.controllers){var e=this.app.get(t);"function"==typeof e.onPopoverOpened&&e.onPopoverOpened()}this.afterOpen()},Kanboard.Popover.prototype.executeOnClosedListeners=function(){for(var t in this.app.controllers){var e=this.app.get(t);
+"function"==typeof e.onPopoverClosed&&e.onPopoverClosed()}},Kanboard.Popover.prototype.afterOpen=function(){var t=this,e=$("#popover-content .popover-form");e&&e.on("submit",function(o){o.preventDefault(),$.ajax({type:"POST",url:e.attr("action"),data:e.serialize(),success:function(e,o,a){t.ajaxReload(e,a,t)},beforeSend:function(){var t=$('.popover-form button[type="submit"]');t.html('<i class="fa fa-spinner fa-pulse"></i> '+t.html()),t.attr("disabled",!0)}})}),$(document).on("click",".popover-link",function(e){e.preventDefault(),$.ajax({type:"GET",url:$(this).attr("href"),success:function(e,o,a){t.ajaxReload(e,a,t)}})}),$("[autofocus]").each(function(){$(this).focus()}),this.app.datePicker(),this.app.autoComplete()},Kanboard.ProjectCreation=function(t){this.app=t},Kanboard.ProjectCreation.prototype.onPopoverOpened=function(){$("#project-creation-form #form-src_project_id").on("change",function(){var t=$(this).val();0==t?$(".project-creation-options").hide():$(".project-creation-options").show()})},Kanboard.ProjectPermission=function(t){this.app=t},Kanboard.ProjectPermission.prototype.listen=function(){$(".project-change-role").on("change",function(){$.ajax({cache:!1,url:$(this).data("url"),contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({id:$(this).data("id"),role:$(this).val()})})})},Kanboard.Screenshot=function(t){this.app=t,this.pasteCatcher=null},Kanboard.Screenshot.prototype.onPopoverOpened=function(){this.app.hasId("screenshot-zone")&&this.initialize()},Kanboard.Screenshot.prototype.initialize=function(){this.destroy(),window.Clipboard||(this.pasteCatcher=document.createElement("div"),this.pasteCatcher.id="screenshot-pastezone",this.pasteCatcher.contentEditable="true",this.pasteCatcher.style.opacity=0,this.pasteCatcher.style.position="fixed",this.pasteCatcher.style.top=0,this.pasteCatcher.style.right=0,this.pasteCatcher.style.width=0,document.body.insertBefore(this.pasteCatcher,document.body.firstChild),this.pasteCatcher.focus(),document.addEventListener("click",this.setFocus.bind(this)),document.getElementById("screenshot-zone").addEventListener("click",this.setFocus.bind(this))),window.addEventListener("paste",this.pasteHandler.bind(this))},Kanboard.Screenshot.prototype.destroy=function(){null!=this.pasteCatcher?document.body.removeChild(this.pasteCatcher):document.getElementById("screenshot-pastezone")&&document.body.removeChild(document.getElementById("screenshot-pastezone")),document.removeEventListener("click",this.setFocus.bind(this)),this.pasteCatcher=null},Kanboard.Screenshot.prototype.setFocus=function(){null!==this.pasteCatcher&&this.pasteCatcher.focus()},Kanboard.Screenshot.prototype.pasteHandler=function(t){if(t.clipboardData&&t.clipboardData.items){var e=t.clipboardData.items;if(e)for(var o=0;o<e.length;o++)if(-1!==e[o].type.indexOf("image")){var a=e[o].getAsFile(),n=new FileReader,r=this;n.onload=function(t){r.createImage(t.target.result)},n.readAsDataURL(a)}}else setTimeout(this.checkInput.bind(this),100)},Kanboard.Screenshot.prototype.checkInput=function(){var t=this.pasteCatcher.childNodes[0];t&&"IMG"===t.tagName&&this.createImage(t.src),this.pasteCatcher.innerHTML=""},Kanboard.Screenshot.prototype.createImage=function(t){var e=new Image;e.src=t,e.onload=function(){var e=t.split("base64,"),o=e[1];$("input[name=screenshot]").val(o)};var o=document.getElementById("screenshot-zone");o.innerHTML="",o.className="screenshot-pasted",o.appendChild(e),this.destroy(),this.initialize()},Kanboard.Search=function(t){this.app=t},Kanboard.Search.prototype.focus=function(){$(document).on("focus","#form-search",function(){var t=$("#form-search");if(t[0].setSelectionRange){var e=2*t.val().length;t[0].setSelectionRange(e,e)}})},Kanboard.Search.prototype.listen=function(){$(document).on("click",".filter-helper",function(t){t.preventDefault();var e=$(this).data("filter"),o=$(this).data("append-filter"),a=$(this).data("unique-filter"),n=$("#form-search");if(a){var r=a.substr(0,a.indexOf(":"));e=n.val().replace(new RegExp("("+r+":[#a-z0-9]+)","g"),""),e=e.replace(new RegExp("("+r+':"(.+)")',"g"),""),e=e.trim(),e+=" "+a}else o&&(e=n.val()+" "+o);n.val(e),$("form.search").submit()})},Kanboard.Search.prototype.goToView=function(t){var e=$(t);e.length&&(window.location=e.attr("href"))},Kanboard.Search.prototype.keyboardShortcuts=function(){var t=this;Mousetrap.bind("v o",function(){t.goToView(".view-overview")}),Mousetrap.bind("v b",function(){t.goToView(".view-board")}),Mousetrap.bind("v c",function(){t.goToView(".view-calendar")}),Mousetrap.bind("v l",function(){t.goToView(".view-listing")}),Mousetrap.bind("v g",function(){t.goToView(".view-gantt")}),Mousetrap.bind("f",function(t){t.preventDefault();var e=document.getElementById("form-search");e&&e.focus()}),Mousetrap.bind("r",function(t){t.preventDefault();var e=$(".filter-reset").data("filter"),o=$("#form-search");o.val(e),$("form.search").submit()})},Kanboard.Session=function(t){this.app=t},Kanboard.Session.prototype.execute=function(){window.setInterval(this.checkSession,6e4)},Kanboard.Session.prototype.checkSession=function(){$(".form-login").length||$.ajax({cache:!1,url:$("body").data("status-url"),statusCode:{401:function(){window.location=$("body").data("login-url")}}})},Kanboard.Subtask=function(t){this.app=t},Kanboard.Subtask.prototype.listen=function(){var t=this;this.dragAndDrop(),$(document).on("click",".subtask-toggle-status",function(e){var o=$(this);e.preventDefault(),$.ajax({cache:!1,url:o.attr("href"),success:function(e){o.hasClass("subtask-refresh-table")?$(".subtasks-table").replaceWith(e):o.replaceWith(e),t.dragAndDrop()}})}),$(document).on("click",".subtask-toggle-timer",function(e){var o=$(this);e.preventDefault(),$.ajax({cache:!1,url:o.attr("href"),success:function(e){$(".subtasks-table").replaceWith(e),t.dragAndDrop()}})})},Kanboard.Subtask.prototype.dragAndDrop=function(){var t=this;$(".draggable-row-handle").mouseenter(function(){$(this).parent().parent().addClass("draggable-item-hover")}).mouseleave(function(){$(this).parent().parent().removeClass("draggable-item-hover")}),$(".subtasks-table tbody").sortable({forcePlaceholderSize:!0,handle:"td:first i",helper:function(t,e){return e.children().each(function(){$(this).width($(this).width())}),e},stop:function(e,o){var a=o.item;a.removeClass("draggable-item-selected"),t.savePosition(a.data("subtask-id"),a.index()+1)},start:function(t,e){e.item.addClass("draggable-item-selected")}}).disableSelection()},Kanboard.Subtask.prototype.savePosition=function(t,e){var o=$(".subtasks-table").data("save-position-url"),a=this;this.app.showLoadingIcon(),$.ajax({cache:!1,url:o,contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({subtask_id:t,position:e}),complete:function(){a.app.hideLoadingIcon()}})},Kanboard.Swimlane=function(t){this.app=t},Kanboard.Swimlane.prototype.execute=function(){$(".swimlanes-table").length&&this.dragAndDrop()},Kanboard.Swimlane.prototype.listen=function(){var t=this;$(document).on("click",".board-swimlane-toggle",function(e){e.preventDefault();var o=$(this).data("swimlane-id");t.isCollapsed(o)?t.expand(o):t.collapse(o)})},Kanboard.Swimlane.prototype.onBoardRendered=function(){for(var t=this.getAllCollapsed(),e=0;e<t.length;e++)this.collapse(t[e])},Kanboard.Swimlane.prototype.getStorageKey=function(){return"hidden_swimlanes_"+$("#board").data("project-id")},Kanboard.Swimlane.prototype.expand=function(t){var e=this.getAllCollapsed(),o=e.indexOf(t);o>-1&&e.splice(o,1),localStorage.setItem(this.getStorageKey(),JSON.stringify(e)),$(".board-swimlane-columns-"+t).css("display","table-row"),$(".board-swimlane-tasks-"+t).css("display","table-row"),$(".hide-icon-swimlane-"+t).css("display","inline"),$(".show-icon-swimlane-"+t).css("display","none")},Kanboard.Swimlane.prototype.collapse=function(t){var e=this.getAllCollapsed();e.indexOf(t)<0&&(e.push(t),localStorage.setItem(this.getStorageKey(),JSON.stringify(e))),$(".board-swimlane-columns-"+t+":not(:first-child)").css("display","none"),$(".board-swimlane-tasks-"+t).css("display","none"),$(".hide-icon-swimlane-"+t).css("display","none"),$(".show-icon-swimlane-"+t).css("display","inline")},Kanboard.Swimlane.prototype.isCollapsed=function(t){return this.getAllCollapsed().indexOf(t)>-1},Kanboard.Swimlane.prototype.getAllCollapsed=function(){return JSON.parse(localStorage.getItem(this.getStorageKey()))||[]},Kanboard.Swimlane.prototype.dragAndDrop=function(){var t=this;$(".draggable-row-handle").mouseenter(function(){$(this).parent().parent().addClass("draggable-item-hover")}).mouseleave(function(){$(this).parent().parent().removeClass("draggable-item-hover")}),$(".swimlanes-table tbody").sortable({forcePlaceholderSize:!0,handle:"td:first i",helper:function(t,e){return e.children().each(function(){$(this).width($(this).width())}),e},stop:function(e,o){var a=o.item;a.removeClass("draggable-item-selected"),t.savePosition(a.data("swimlane-id"),a.index()+1)},start:function(t,e){e.item.addClass("draggable-item-selected")}}).disableSelection()},Kanboard.Swimlane.prototype.savePosition=function(t,e){var o=$(".swimlanes-table").data("save-position-url"),a=this;this.app.showLoadingIcon(),$.ajax({cache:!1,url:o,contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({swimlane_id:t,position:e}),complete:function(){a.app.hideLoadingIcon()}})},Kanboard.Task=function(t){this.app=t},Kanboard.Task.prototype.keyboardShortcuts=function(){var t=$("#task-view"),e=this;this.app.hasId("task-view")&&(Mousetrap.bind("e",function(){e.app.get("Popover").open(t.data("edit-url"))}),Mousetrap.bind("d",function(){e.app.get("Popover").open(t.data("description-url"))}),Mousetrap.bind("c",function(){e.app.get("Popover").open(t.data("comment-url"))}),Mousetrap.bind("s",function(){e.app.get("Popover").open(t.data("subtask-url"))}),Mousetrap.bind("l",function(){e.app.get("Popover").open(t.data("internal-link-url"))}))},Kanboard.Task.prototype.onPopoverOpened=function(){var t=this,e=0;$(document).on("click",".color-square",function(){$(".color-square-selected").removeClass("color-square-selected"),$(this).addClass("color-square-selected"),$("#form-color_id").val($(this).data("color-id"))}),$(document).on("click",".assign-me",function(t){var e=$(this).data("current-id"),o="#"+$(this).data("target-id");t.preventDefault(),$(o+" option[value="+e+"]").length&&$(o).val(e)}),$(document).on("change","select.task-reload-project-destination",function(){if(e>0)$(this).val(e);else{e=$(this).val();var o=$(this).data("redirect").replace(/PROJECT_ID/g,e);$(".loading-icon").show(),$.ajax({type:"GET",url:o,success:function(o,a,n){e=0,$(".loading-icon").hide(),t.app.get("Popover").ajaxReload(o,n,t.app.get("Popover"))}})}})},Kanboard.TaskRepartitionChart=function(t){this.app=t},Kanboard.TaskRepartitionChart.prototype.execute=function(){this.app.hasId("analytic-task-repartition")&&this.show()},Kanboard.TaskRepartitionChart.prototype.show=function(){for(var t=$("#chart").data("metrics"),e=[],o=0;o<t.length;o++)e.push([t[o].column_title,t[o].nb_tasks]);c3.generate({data:{columns:e,type:"donut"}})},Kanboard.TaskTimeColumnChart=function(t){this.app=t},Kanboard.TaskTimeColumnChart.prototype.execute=function(){this.app.hasId("analytic-task-time-column")&&this.show()},Kanboard.TaskTimeColumnChart.prototype.show=function(){for(var t=$("#chart"),e=t.data("metrics"),o=[t.data("label")],a=[],n=0;n<e.length;n++)o.push(e[n].time_spent),a.push(e[n].title);c3.generate({data:{columns:[o],type:"bar"},bar:{width:{ratio:.5}},axis:{x:{type:"category",categories:a},y:{tick:{format:this.app.formatDuration}}},legend:{show:!1}})},Kanboard.Tooltip=function(t){this.app=t},Kanboard.Tooltip.prototype.onBoardRendered=function(){this.execute()},Kanboard.Tooltip.prototype.execute=function(){$(".tooltip").tooltip({track:!1,show:!1,hide:!1,position:{my:"left-20 top",at:"center bottom+9",using:function(t,e){$(this).css(t);var o=e.target.left+e.target.width/2-e.element.left-20;$("<div>").addClass("tooltip-arrow").addClass(e.vertical).addClass(1>o?"align-left":"align-right").appendTo(this)}},content:function(){var t=this,e=$(this).attr("data-href");return e?($.get(e,function(e){var o=$(".ui-tooltip:visible");$(".ui-tooltip-content:visible").html(e),o.css({top:"",left:""}),o.children(".tooltip-arrow").remove();var a=$(t).tooltip("option","position");a.of=$(t),o.position(a)}),'<i class="fa fa-spinner fa-spin"></i>'):'<div class="markdown">'+$(this).attr("title")+"</div>"}}).on("mouseenter",function(){var t=this;$(this).tooltip("open"),$(".ui-tooltip").on("mouseleave",function(){$(t).tooltip("close")})}).on("mouseleave focusout",function(t){t.stopImmediatePropagation();var e=this;setTimeout(function(){$(".ui-tooltip:hover").length||$(e).tooltip("close")},100)})},Kanboard.UserRepartitionChart=function(t){this.app=t},Kanboard.UserRepartitionChart.prototype.execute=function(){this.app.hasId("analytic-user-repartition")&&this.show()},Kanboard.UserRepartitionChart.prototype.show=function(){for(var t=$("#chart").data("metrics"),e=[],o=0;o<t.length;o++)e.push([t[o].user,t[o].nb_tasks]);c3.generate({data:{columns:e,type:"donut"}})},jQuery(document).ready(function(){var t=new Kanboard.App;t.execute()}); \ No newline at end of file
diff --git a/assets/js/src/Gantt.js b/assets/js/src/Gantt.js
index 02005bca..96479d36 100644
--- a/assets/js/src/Gantt.js
+++ b/assets/js/src/Gantt.js
@@ -81,11 +81,11 @@ Kanboard.Gantt.prototype.renderVerticalHeader = function() {
}
else {
content
- .append(jQuery("<a>", {"href": this.data[i].board_link, "target": "_blank", "title": $(this.options.container).data("label-board-link")}).append('<i class="fa fa-th"></i>'))
+ .append(jQuery("<a>", {"href": this.data[i].board_link, "title": $(this.options.container).data("label-board-link")}).append('<i class="fa fa-th"></i>'))
.append("&nbsp;")
- .append(jQuery("<a>", {"href": this.data[i].gantt_link, "target": "_blank", "title": $(this.options.container).data("label-gantt-link")}).append('<i class="fa fa-sliders"></i>'))
+ .append(jQuery("<a>", {"href": this.data[i].gantt_link, "title": $(this.options.container).data("label-gantt-link")}).append('<i class="fa fa-sliders"></i>'))
.append("&nbsp;")
- .append(jQuery("<a>", {"href": this.data[i].link, "target": "_blank"}).append(this.data[i].title));
+ .append(jQuery("<a>", {"href": this.data[i].link}).append(this.data[i].title));
}
seriesDiv.append(jQuery("<div>", {"class": "ganttview-vtheader-series-name"}).append(content));
@@ -205,20 +205,6 @@ Kanboard.Gantt.prototype.addBlocks = function(slider, start) {
block.data("record", series);
this.setBarColor(block, series);
- if (series.progress != "0%") {
- block.append(jQuery("<div>", {
- "css": {
- "z-index": 0,
- "position": "absolute",
- "top": 0,
- "bottom": 0,
- "background-color": series.color.border,
- "width": series.progress,
- "opacity": 0.4
- }
- }));
- }
-
jQuery(rows[rowIdx]).append(block);
rowIdx = rowIdx + 1;
}
@@ -281,6 +267,20 @@ Kanboard.Gantt.prototype.setBarColor = function(block, record) {
else {
block.css("background-color", record.color.background);
block.css("border-color", record.color.border);
+
+ if (record.progress != "0%") {
+ block.append(jQuery("<div>", {
+ "css": {
+ "z-index": 0,
+ "position": "absolute",
+ "top": 0,
+ "bottom": 0,
+ "background-color": record.color.border,
+ "width": record.progress,
+ "opacity": 0.4
+ }
+ }));
+ }
}
};