Move assets to seperate subfolders

This commit is contained in:
Frederic Guillot
2015-01-25 13:09:54 -05:00
parent 0812ceedde
commit 746a3f8d23
44 changed files with 717 additions and 1414 deletions

159
assets/js/src/analytic.js Normal file
View File

@@ -0,0 +1,159 @@
Kanboard.Analytic = (function() {
return {
Init: function() {
if (Kanboard.Exists("analytic-task-repartition")) {
Kanboard.Analytic.TaskRepartition.Init();
}
else if (Kanboard.Exists("analytic-user-repartition")) {
Kanboard.Analytic.UserRepartition.Init();
}
else if (Kanboard.Exists("analytic-cfd")) {
Kanboard.Analytic.CFD.Init();
}
}
};
})();
Kanboard.Analytic.CFD = (function() {
function fetchData()
{
jQuery.getJSON($("#chart").attr("data-url"), function(data) {
drawGraph(data.metrics, data.labels, data.columns);
});
}
function drawGraph(metrics, labels, columns)
{
var series = prepareSeries(metrics, labels);
var svg = dimple.newSvg("#chart", "100%", 380);
var chart = new dimple.chart(svg, series);
var x = chart.addCategoryAxis("x", labels['day']);
x.addOrderRule("Date");
chart.addMeasureAxis("y", labels['total']);
var s = chart.addSeries(labels['column'], dimple.plot.area);
s.addOrderRule(columns.reverse());
chart.addLegend(10, 10, 500, 30, "left");
chart.draw();
}
function prepareSeries(metrics, labels)
{
var series = [];
for (var i = 0; i < metrics.length; i++) {
var row = {};
row[labels['column']] = metrics[i]['column_title'];
row[labels['day']] = metrics[i]['day'];
row[labels['total']] = metrics[i]['total'];
series.push(row);
}
return series;
}
return {
Init: fetchData
};
})();
Kanboard.Analytic.TaskRepartition = (function() {
function fetchData()
{
jQuery.getJSON($("#chart").attr("data-url"), function(data) {
drawGraph(data.metrics, data.labels);
});
}
function drawGraph(metrics, labels)
{
var series = prepareSeries(metrics, labels);
var svg = dimple.newSvg("#chart", "100%", 350);
var chart = new dimple.chart(svg, series);
chart.addMeasureAxis("p", labels["nb_tasks"]);
var ring = chart.addSeries(labels["column_title"], dimple.plot.pie);
ring.innerRadius = "50%";
chart.addLegend(0, 0, 100, "100%", "left");
chart.draw();
}
function prepareSeries(metrics, labels)
{
var series = [];
for (var i = 0; i < metrics.length; i++) {
var serie = {};
serie[labels["nb_tasks"]] = metrics[i]["nb_tasks"];
serie[labels["column_title"]] = metrics[i]["column_title"];
series.push(serie);
}
return series;
}
return {
Init: fetchData
};
})();
Kanboard.Analytic.UserRepartition = (function() {
function fetchData()
{
jQuery.getJSON($("#chart").attr("data-url"), function(data) {
drawGraph(data.metrics, data.labels);
});
}
function drawGraph(metrics, labels)
{
var series = prepareSeries(metrics, labels);
var svg = dimple.newSvg("#chart", "100%", 350);
var chart = new dimple.chart(svg, series);
chart.addMeasureAxis("p", labels["nb_tasks"]);
var ring = chart.addSeries(labels["user"], dimple.plot.pie);
ring.innerRadius = "50%";
chart.addLegend(0, 0, 100, "100%", "left");
chart.draw();
}
function prepareSeries(metrics, labels)
{
var series = [];
for (var i = 0; i < metrics.length; i++) {
var serie = {};
serie[labels["nb_tasks"]] = metrics[i]["nb_tasks"];
serie[labels["user"]] = metrics[i]["user"];
series.push(serie);
}
return series;
}
return {
Init: fetchData
};
})();

182
assets/js/src/base.js Normal file
View File

@@ -0,0 +1,182 @@
// Common functions
var Kanboard = (function() {
return {
// Return true if the element#id exists
Exists: function(id) {
if (document.getElementById(id)) {
return true;
}
return false;
},
// Display a popup
Popover: function(e, callback) {
e.preventDefault();
e.stopPropagation();
var link = e.target.getAttribute("href");
if (! link) {
link = e.target.getAttribute("data-href");
}
if (link) {
$.get(link, function(content) {
$("body").append('<div id="popover-container"><div id="popover-content">' + content + '</div></div>');
$("#popover-container").click(function() {
$(this).remove();
});
$("#popover-content").click(function(e) {
e.stopPropagation();
});
if (callback) {
callback();
}
});
}
},
// Return true if the page is visible
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;
},
// Save preferences in local storage
SetStorageItem: function(key, value) {
if (typeof(Storage) !== "undefined") {
localStorage.setItem(key, value);
}
},
GetStorageItem: function(key) {
if (typeof(Storage) !== "undefined") {
return localStorage.getItem(key);
}
return '';
},
// Generate Markdown preview
MarkdownPreview: function(e) {
e.preventDefault();
var link = $(this);
var nav = $(this).closest("ul");
var write = $(".write-area");
var preview = $(".preview-area");
var textarea = $("textarea");
var request = $.ajax({
url: "?controller=app&action=preview",
contentType: "application/json",
type: "POST",
processData: false,
dataType: "html",
data: JSON.stringify({
"text": textarea.val()
})
});
request.done(function(data) {
nav.find("li").removeClass("form-tab-selected");
link.parent().addClass("form-tab-selected");
preview.find(".markdown").html(data)
preview.css("height", textarea.css("height"));
preview.css("width", textarea.css("width"));
write.hide();
preview.show();
});
},
// Show the Markdown textarea
MarkdownWriter: function(e) {
e.preventDefault();
$(this).closest("ul").find("li").removeClass("form-tab-selected")
$(this).parent().addClass("form-tab-selected");
$(".write-area").show();
$(".preview-area").hide();
},
// Check session and redirect to the login page if not logged
CheckSession: function() {
if (! $(".form-login").length) {
$.ajax({
cache: false,
url: $("body").data("status-url"),
statusCode: {
401: function(data) {
window.location = $("body").data("login-url");
}
}
});
}
},
// Common init
Init: function() {
// Datepicker
$(".form-date").datepicker({
showOtherMonths: true,
selectOtherMonths: true,
dateFormat: 'yy-mm-dd',
constrainInput: false
});
// Project select box
$("#board-selector").chosen({
width: 180
});
$("#board-selector").change(function() {
window.location = $(this).attr("data-board-url").replace(/%d/g, $(this).val());
});
// Markdown Preview for textareas
$("#markdown-preview").click(Kanboard.MarkdownPreview);
$("#markdown-write").click(Kanboard.MarkdownWriter);
// Check the session every 60s
window.setInterval(Kanboard.CheckSession, 60000);
// Auto-select input fields
$(".auto-select").focus(function() {
$(this).select();
});
}
};
})();

256
assets/js/src/board.js Normal file
View File

@@ -0,0 +1,256 @@
Kanboard.Board = (function() {
var checkInterval = null;
function on_popover(e)
{
Kanboard.Popover(e, Kanboard.Init);
}
// Setup the board
function board_load_events()
{
// Drag and drop
$(".column").sortable({
delay: 300,
distance: 5,
connectWith: ".column",
placeholder: "draggable-placeholder",
stop: function(event, ui) {
board_save(
ui.item.attr('data-task-id'),
ui.item.parent().attr("data-column-id"),
ui.item.index() + 1,
ui.item.parent().attr('data-swimlane-id')
);
}
});
// Assignee change
$(".assignee-popover").click(Kanboard.Popover);
// Category change
$(".category-popover").click(Kanboard.Popover);
// Task edit popover
$(".task-edit-popover").click(on_popover);
$(".task-creation-popover").click(on_popover);
// Description popover
$(".task-description-popover").click(on_popover);
// Tooltips
$(".task-board-tooltip").tooltip({
track: 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 == 0 ? "align-left" : "align-right")
.appendTo(this);
}
},
content: function(e) {
var href = $(this).attr('data-href');
if (! href) {
return;
}
var _this = this;
$.get(href, function setTooltipContent(data) {
$('.ui-tooltip-content:visible').html(data);
var tooltip = $('.ui-tooltip:visible');
// 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);
// Toggle subtasks status
$('#tooltip-subtasks a').click(function(e) {
e.preventDefault();
e.stopPropagation();
$.get($(this).attr('href'), setTooltipContent);
});
});
return '<i class="fa fa-refresh fa-spin fa-2x"></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);
});
// Redirect to the task details page
$("[data-task-url]").each(function() {
$(this).click(function() {
window.location = $(this).attr("data-task-url");
});
});
// Automatic refresh
var interval = parseInt($("#board").attr("data-check-interval"));
if (interval > 0) {
checkInterval = window.setInterval(board_check, interval * 1000);
}
}
// Stop events
function board_unload_events()
{
$("[data-task-url]").off();
clearInterval(checkInterval);
}
// Save and refresh the board
function board_save(taskId, columnId, position, swimlaneId)
{
board_unload_events();
$.ajax({
cache: false,
url: $("#board").attr("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) {
$("#board").remove();
$("#main").append(data);
board_load_events();
filter_apply();
}
});
}
// Check if a board have been changed by someone else
function board_check()
{
if (Kanboard.IsVisible()) {
$.ajax({
cache: false,
url: $("#board").attr("data-check-url"),
statusCode: {
200: function(data) {
$("#board").remove();
$("#main").append(data);
board_unload_events();
board_load_events();
filter_apply();
}
}
});
}
}
// Apply user or date filter (change tasks opacity)
function filter_apply()
{
var selectedUserId = $("#form-user_id").val();
var selectedCategoryId = $("#form-category_id").val();
var filterDueDate = $("#filter-due-date").hasClass("filter-on");
var projectId = $('#board').data('project-id');
$("[data-task-id]").each(function(index, item) {
var ownerId = item.getAttribute("data-owner-id");
var dueDate = item.getAttribute("data-due-date");
var categoryId = item.getAttribute("data-category-id");
if (ownerId != selectedUserId && selectedUserId != -1) {
item.style.opacity = "0.2";
}
else {
item.style.opacity = "1.0";
}
if (filterDueDate && (dueDate == "" || dueDate == "0")) {
item.style.opacity = "0.2";
}
if (categoryId != selectedCategoryId && selectedCategoryId != -1) {
item.style.opacity = "0.2";
}
});
// Save filter settings
Kanboard.SetStorageItem("board_filter_" + projectId + "_form-user_id", selectedUserId);
Kanboard.SetStorageItem("board_filter_" + projectId + "_form-category_id", selectedCategoryId);
Kanboard.SetStorageItem("board_filter_" + projectId + "_filter-due-date", ~~(filterDueDate));
}
// Load filter events
function filter_load_events()
{
var projectId = $('#board').data('project-id');
$("#form-user_id").change(filter_apply);
$("#form-category_id").change(filter_apply);
$("#filter-due-date").click(function(e) {
$(this).toggleClass("filter-on");
filter_apply();
e.preventDefault();
});
// Get and set filters from localStorage
$("#form-user_id").val(Kanboard.GetStorageItem("board_filter_" + projectId + "_form-user_id") || -1);
$("#form-category_id").val(Kanboard.GetStorageItem("board_filter_" + projectId + "_form-category_id") || -1);
if (+Kanboard.GetStorageItem("board_filter_" + projectId + "_filter-due-date")) {
$("#filter-due-date").addClass("filter-on");
} else {
$("#filter-due-date").removeClass("filter-on");
}
filter_apply();
}
return {
Init: function() {
board_load_events();
filter_load_events();
}
};
})();

103
assets/js/src/calendar.js Normal file
View File

@@ -0,0 +1,103 @@
Kanboard.Calendar = (function() {
// Show the empty calendar
function show_calendar()
{
var calendar = $("#calendar");
var translations = calendar.data("translations");
calendar.fullCalendar({
editable: true,
eventLimit: true,
header: {
left: 'prev,next today',
center: 'title',
right: ''
},
eventDrop: move_calendar_event,
monthNames: [translations.January, translations.February, translations.March, translations.April, translations.May, translations.June, translations.July, translations.August, translations.September, translations.October, translations.November, translations.December],
monthNamesShort: [translations.Jan, translations.Feb, translations.Mar, translations.Apr, translations.May, translations.Jun, translations.Jul, translations.Aug, translations.Sep, translations.Oct, translations.Nov, translations.Dec],
buttonText: {today: translations.Today},
dayNames: [translations.Sunday, translations.Monday, translations.Tuesday, translations.Wednesday, translations.Thursday, translations.Friday, translations.Saturday],
dayNamesShort: [translations.Sun, translations.Mon, translations.Tue, translations.Wed, translations.Thu, translations.Fri, translations.Sat]
});
}
// Save the new due date for a moved task
function move_calendar_event(calendar_event)
{
$.ajax({
cache: false,
url: $("#calendar").data("save-url"),
contentType: "application/json",
type: "POST",
processData: false,
data: JSON.stringify({
"task_id": calendar_event.id,
"date_due": calendar_event.start.format()
})
});
}
// Refresh the calendar events
function refresh_calendar(filters)
{
var calendar = $("#calendar");
var url = calendar.data("check-url");
var params = {
"start": calendar.fullCalendar('getView').start.format(),
"end": calendar.fullCalendar('getView').end.format()
}
jQuery.extend(params, filters);
for (var key in params) {
url += "&" + key + "=" + params[key];
}
$.getJSON(url, function(events) {
calendar.fullCalendar('removeEvents');
calendar.fullCalendar('addEventSource', events);
calendar.fullCalendar('rerenderEvents');
});
}
// Restore saved filters
function load_filters()
{
var filters = Kanboard.GetStorageItem('calendar_filters');
if (filters !== "undefined" && filters !== "") {
filters = JSON.parse(filters);
for (var filter in filters) {
$("select[name=" + filter + "]").val(filters[filter]);
}
}
refresh_calendar(filters || {});
$('.calendar-filter').change(apply_filters);
}
// Apply filters on change
function apply_filters()
{
var filters = {};
$('.calendar-filter').each(function(index, element) {
filters[$(this).attr("name")] = $(this).val();
});
Kanboard.SetStorageItem("calendar_filters", JSON.stringify(filters));
refresh_calendar(filters);
}
return {
Init: function() {
show_calendar();
load_filters();
}
};
})();

18
assets/js/src/init.js Normal file
View File

@@ -0,0 +1,18 @@
// Initialization
$(function() {
Kanboard.Init();
if (Kanboard.Exists("board")) {
Kanboard.Board.Init();
}
else if (Kanboard.Exists("calendar")) {
Kanboard.Calendar.Init();
}
else if (Kanboard.Exists("task-section")) {
Kanboard.Task.Init();
}
else if (Kanboard.Exists("analytic-section")) {
Kanboard.Analytic.Init();
}
});

13
assets/js/src/task.js Normal file
View File

@@ -0,0 +1,13 @@
// Task related functions
Kanboard.Task = (function() {
return {
Init: function() {
// Image preview for attachments
$(".file-popover").click(Kanboard.Popover);
}
};
})();