Fix UI and realtime issues with kanban
This commit is contained in:
parent
365b32d378
commit
f0512bbb1d
@ -84,16 +84,27 @@
|
|||||||
.tools_unselectable();
|
.tools_unselectable();
|
||||||
}
|
}
|
||||||
|
|
||||||
.kanban-removeboard {
|
.kanban-additem, .kanban-remove-item {
|
||||||
float: right;
|
float: right;
|
||||||
margin: 10px;
|
background: #EEE;
|
||||||
|
padding: .25rem .5rem;
|
||||||
|
line-height: 1;
|
||||||
|
&:hover {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
/* margin: 10px;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: #eee;
|
background: #eee;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
.tools_unselectable();
|
.tools_unselectable(); */
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanban-additem {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.kanban-header-yellow {
|
.kanban-header-yellow {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
define([
|
define([
|
||||||
'jquery',
|
'jquery',
|
||||||
|
'json.sortify',
|
||||||
'/bower_components/nthen/index.js',
|
'/bower_components/nthen/index.js',
|
||||||
'/common/sframe-common.js',
|
'/common/sframe-common.js',
|
||||||
'/common/sframe-app-framework.js',
|
'/common/sframe-app-framework.js',
|
||||||
@ -12,6 +13,7 @@ define([
|
|||||||
'css!/kanban/jkanban.css',
|
'css!/kanban/jkanban.css',
|
||||||
], function (
|
], function (
|
||||||
$,
|
$,
|
||||||
|
Sortify,
|
||||||
nThen,
|
nThen,
|
||||||
SFCommon,
|
SFCommon,
|
||||||
Framework,
|
Framework,
|
||||||
@ -25,6 +27,23 @@ define([
|
|||||||
var verbose = function (x) { console.log(x); };
|
var verbose = function (x) { console.log(x); };
|
||||||
verbose = function () {}; // comment out to enable verbose logging
|
verbose = function () {}; // comment out to enable verbose logging
|
||||||
|
|
||||||
|
var addRemoveItemButton = function (framework, kanban) {
|
||||||
|
var $container = $(kanban.element);
|
||||||
|
$container.find('.kanban-remove-item').remove();
|
||||||
|
$container.find('.kanban-board .kanban-item').each(function (i, el) {
|
||||||
|
var pos = kanban.findElementPosition(el);
|
||||||
|
var board = kanban.options.boards.find(function (b) {
|
||||||
|
return b.id === $(el.parentNode.parentNode).attr('data-id');
|
||||||
|
});
|
||||||
|
$('<button>', {'class': 'kanban-remove-item btn btn-default'}).click(function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
board.item.splice(pos, 1);
|
||||||
|
$(el).remove();
|
||||||
|
kanban.onChange();
|
||||||
|
}).text('🗙').appendTo($(el));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Kanban code
|
// Kanban code
|
||||||
var initKanban = function (framework, boards) {
|
var initKanban = function (framework, boards) {
|
||||||
var defaultBoards = [{
|
var defaultBoards = [{
|
||||||
@ -78,9 +97,13 @@ define([
|
|||||||
element: '#cp-app-kanban-content',
|
element: '#cp-app-kanban-content',
|
||||||
gutter: '15px',
|
gutter: '15px',
|
||||||
widthBoard: '300px',
|
widthBoard: '300px',
|
||||||
|
buttonContent: '🗙',
|
||||||
onChange: function () {
|
onChange: function () {
|
||||||
verbose("Board object has changed");
|
verbose("Board object has changed");
|
||||||
framework.localChange();
|
framework.localChange();
|
||||||
|
if (kanban) {
|
||||||
|
addRemoveItemButton(framework, kanban);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
click: function (el) {
|
click: function (el) {
|
||||||
if (kanban.inEditMode) {
|
if (kanban.inEditMode) {
|
||||||
@ -182,40 +205,42 @@ define([
|
|||||||
kanban.onChange();
|
kanban.onChange();
|
||||||
|
|
||||||
},
|
},
|
||||||
removeClick: function (el) {
|
buttonClick: function (el, boardId, e) {
|
||||||
|
e.stopPropagation();
|
||||||
UI.confirm(Messages.kanban_deleteBoard, function (yes) {
|
UI.confirm(Messages.kanban_deleteBoard, function (yes) {
|
||||||
if (!yes) { return; }
|
if (!yes) { return; }
|
||||||
verbose("Delete board");
|
verbose("Delete board");
|
||||||
var boardName = $(el.parentNode.parentNode).attr("data-id");
|
//var boardName = $(el.parentNode.parentNode).attr("data-id");
|
||||||
for (var index in kanban.options.boards) {
|
for (var index in kanban.options.boards) {
|
||||||
if (kanban.options.boards[index].id === boardName) {
|
if (kanban.options.boards[index].id === boardId) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
kanban.options.boards.splice(index, 1);
|
kanban.options.boards.splice(index, 1);
|
||||||
kanban.removeBoard(boardName);
|
kanban.removeBoard(boardId);
|
||||||
kanban.onChange();
|
kanban.onChange();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
buttonClick: function (el, boardId, e) {
|
addItemClick: function (el) {
|
||||||
e.stopPropagation();
|
|
||||||
if (kanban.inEditMode) {
|
if (kanban.inEditMode) {
|
||||||
verbose("An edit is already active");
|
verbose("An edit is already active");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
kanban.inEditMode = true;
|
kanban.inEditMode = true;
|
||||||
// create a form to enter element
|
// create a form to enter element
|
||||||
|
var boardId = $(el.parentNode.parentNode).attr("data-id");
|
||||||
var $item = $('<div>', {'class': 'kanban-item'});
|
var $item = $('<div>', {'class': 'kanban-item'});
|
||||||
var $input = getInput().val(name).appendTo($item);
|
var $input = getInput().val(name).appendTo($item);
|
||||||
kanban.addForm(boardId, $item[0]);
|
kanban.addForm(boardId, $item[0]);
|
||||||
$input.focus();
|
$input.focus();
|
||||||
var save = function () {
|
var save = function () {
|
||||||
$item.remove();
|
$item.remove();
|
||||||
|
kanban.inEditMode = false;
|
||||||
|
if (!$input.val()) { return; }
|
||||||
kanban.addElement(boardId, {
|
kanban.addElement(boardId, {
|
||||||
"title": $input.val(),
|
"title": $input.val(),
|
||||||
});
|
});
|
||||||
kanban.inEditMode = false;
|
|
||||||
};
|
};
|
||||||
$input.blur(save);
|
$input.blur(save);
|
||||||
$input.keydown(function (e) {
|
$input.keydown(function (e) {
|
||||||
@ -236,7 +261,7 @@ define([
|
|||||||
},
|
},
|
||||||
addItemButton: true,
|
addItemButton: true,
|
||||||
boards: boards,
|
boards: boards,
|
||||||
dragcancelEl: function (el, boardId) {
|
/*dragcancelEl: function (el, boardId) {
|
||||||
var pos = kanban.findElementPosition(el);
|
var pos = kanban.findElementPosition(el);
|
||||||
UI.confirm(Messages.kanban_deleteItem, function (yes) {
|
UI.confirm(Messages.kanban_deleteItem, function (yes) {
|
||||||
if (!yes) { return; }
|
if (!yes) { return; }
|
||||||
@ -251,7 +276,7 @@ define([
|
|||||||
$(el).remove();
|
$(el).remove();
|
||||||
kanban.onChange();
|
kanban.onChange();
|
||||||
});
|
});
|
||||||
}
|
}*/
|
||||||
});
|
});
|
||||||
|
|
||||||
var addBoardDefault = document.getElementById('kanban-addboard');
|
var addBoardDefault = document.getElementById('kanban-addboard');
|
||||||
@ -259,9 +284,8 @@ define([
|
|||||||
var counter = 1;
|
var counter = 1;
|
||||||
|
|
||||||
// Get the new board id
|
// Get the new board id
|
||||||
while (kanban.options.boards.indexOf("board" + counter) !== -1) {
|
var boardExists = function (b) { return b.id === "board" + counter; };
|
||||||
counter++;
|
while (kanban.options.boards.some(boardExists)) { counter++; }
|
||||||
}
|
|
||||||
|
|
||||||
kanban.addBoards([{
|
kanban.addBoards([{
|
||||||
"id": "board" + counter,
|
"id": "board" + counter,
|
||||||
@ -280,24 +304,32 @@ define([
|
|||||||
// Start of the main loop
|
// Start of the main loop
|
||||||
var andThen2 = function (framework) {
|
var andThen2 = function (framework) {
|
||||||
|
|
||||||
var kanban = initKanban(framework);
|
var kanban;
|
||||||
|
|
||||||
framework.onContentUpdate(function (newContent) {
|
framework.onContentUpdate(function (newContent) {
|
||||||
|
// Init if needed
|
||||||
|
if (!kanban) {
|
||||||
|
kanban = initKanban(framework, (newContent || {}).content);
|
||||||
|
addRemoveItemButton(framework, kanban);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Need to update the content
|
// Need to update the content
|
||||||
verbose("Content should be updated to " + newContent);
|
verbose("Content should be updated to " + newContent);
|
||||||
var currentContent = kanban.getBoardsJSON();
|
var currentContent = kanban.getBoardsJSON();
|
||||||
var remoteContent = newContent.content;
|
var remoteContent = newContent.content;
|
||||||
|
|
||||||
if (currentContent !== remoteContent) {
|
if (Sortify(currentContent) !== Sortify(remoteContent)) {
|
||||||
// reinit kanban (TODO: optimize to diff only)
|
// reinit kanban (TODO: optimize to diff only)
|
||||||
verbose("Content is different.. Applying content");
|
verbose("Content is different.. Applying content");
|
||||||
kanban.setBoards(remoteContent);
|
kanban.setBoards(remoteContent);
|
||||||
kanban.inEditMode = false;
|
kanban.inEditMode = false;
|
||||||
|
addRemoveItemButton(framework, kanban);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
framework.setContentGetter(function () {
|
framework.setContentGetter(function () {
|
||||||
// var content = $("#cp-app-kanban-content").val();
|
if (!kanban) { return; }
|
||||||
var content = kanban.getBoardsJSON();
|
var content = kanban.getBoardsJSON();
|
||||||
verbose("Content current value is " + content);
|
verbose("Content current value is " + content);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -67,7 +67,7 @@
|
|||||||
boardTitleclick: function (el, boardId) {},
|
boardTitleclick: function (el, boardId) {},
|
||||||
buttonClick: function (el, boardId) {},
|
buttonClick: function (el, boardId) {},
|
||||||
colorClick: function (el, boardId) {},
|
colorClick: function (el, boardId) {},
|
||||||
removeClick: function (el, boardId) {},
|
addItemClick: function (el, boardId) {},
|
||||||
onChange: function () {}
|
onChange: function () {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -257,13 +257,6 @@
|
|||||||
if (self.options.boards !== boards)
|
if (self.options.boards !== boards)
|
||||||
self.options.boards.push(board);
|
self.options.boards.push(board);
|
||||||
|
|
||||||
//add width to container
|
|
||||||
/*if (self.container.style.width === '') {
|
|
||||||
self.container.style.width = parseInt(boardWidth) + (parseInt(self.options.gutter) * 2) + 'px';
|
|
||||||
} else {
|
|
||||||
self.container.style.width = parseInt(self.container.style.width) + parseInt(boardWidth) + (parseInt(self.options.gutter) * 2) + 'px';
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//create node
|
//create node
|
||||||
var boardNode = document.createElement('div');
|
var boardNode = document.createElement('div');
|
||||||
boardNode.dataset.id = board.id;
|
boardNode.dataset.id = board.id;
|
||||||
@ -325,12 +318,12 @@
|
|||||||
}
|
}
|
||||||
//footer board
|
//footer board
|
||||||
var footerBoard = document.createElement('footer');
|
var footerBoard = document.createElement('footer');
|
||||||
//remove button
|
//add button
|
||||||
var removeBoard = document.createElement('div');
|
var addBoardItem = document.createElement('button');
|
||||||
$(removeBoard).text("-")
|
$(addBoardItem).text("+")
|
||||||
$(removeBoard).addClass("kanban-removeboard");
|
$(addBoardItem).addClass("kanban-additem btn btn-default");
|
||||||
footerBoard.appendChild(removeBoard);
|
footerBoard.appendChild(addBoardItem);
|
||||||
__onRemoveClickHandler(removeBoard);
|
__onAddItemClickHandler(addBoardItem);
|
||||||
|
|
||||||
//board assembly
|
//board assembly
|
||||||
boardNode.appendChild(headerBoard);
|
boardNode.appendChild(headerBoard);
|
||||||
@ -347,9 +340,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setBoards = function (boards) {
|
this.setBoards = function (boards) {
|
||||||
for (var boardkey in boards) {
|
self.element
|
||||||
// single board
|
for (var boardkey in this.options.boards) {
|
||||||
var board = boards[boardkey];
|
var board = this.options.boards[boardkey];
|
||||||
this.removeBoard(board.id);
|
this.removeBoard(board.id);
|
||||||
}
|
}
|
||||||
this.options.boards = [];
|
this.options.boards = [];
|
||||||
@ -478,10 +471,10 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function __onRemoveClickHandler(nodeItem, clickfn) {
|
function __onAddItemClickHandler(nodeItem, clickfn) {
|
||||||
nodeItem.addEventListener('click', function (e) {
|
nodeItem.addEventListener('click', function (e) {
|
||||||
e.preventDefault;
|
e.preventDefault;
|
||||||
self.options.removeClick(this);
|
self.options.addItemClick(this);
|
||||||
if (typeof (this.clickfn) === 'function')
|
if (typeof (this.clickfn) === 'function')
|
||||||
this.clickfn(this);
|
this.clickfn(this);
|
||||||
});
|
});
|
||||||
@ -489,6 +482,7 @@
|
|||||||
|
|
||||||
function __onButtonClickHandler(nodeItem, boardId) {
|
function __onButtonClickHandler(nodeItem, boardId) {
|
||||||
nodeItem.addEventListener('click', function (e) {
|
nodeItem.addEventListener('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
e.preventDefault;
|
e.preventDefault;
|
||||||
self.options.buttonClick(this, boardId, e);
|
self.options.buttonClick(this, boardId, e);
|
||||||
// if(typeof(this.clickfn) === 'function')
|
// if(typeof(this.clickfn) === 'function')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user