Fix issues with the new structure and better restoreCursor

pull/1/head
yflory 5 years ago
parent 2e81605c95
commit 0b5f76d471

@ -89,6 +89,7 @@
@button-size: 50px; @button-size: 50px;
#kanban-addboard { #kanban-addboard {
order: 2;
margin: 30px; margin: 30px;
border: 1px solid; border: 1px solid;
width: @button-size; width: @button-size;

@ -99,7 +99,13 @@ define([
} else { } else {
verbose("Initializing with boards content " + boards); verbose("Initializing with boards content " + boards);
} }
boards = defaultBoards;
// XXX TODO
/*
Delete a board ==> remove from array, delete the data + delete the items
Delete an item ==> remove from array + delete the item data
*/
// Remove any existing elements // Remove any existing elements
$(".kanban-container-outer").remove(); $(".kanban-container-outer").remove();
@ -133,21 +139,23 @@ define([
verbose("An edit is already active"); verbose("An edit is already active");
//return; //return;
} }
kanban.inEditMode = true; var eid = $(el).attr('data-eid');
$(el).find('button').remove(); kanban.inEditMode = eid;
var name = $(el).text(); var name = $(el).text();
$(el).html(''); $(el).html('');
// Add input
var $input = getInput().val(name).appendTo(el).focus(); var $input = getInput().val(name).appendTo(el).focus();
$input[0].select(); $input[0].select();
var save = function () { var save = function () {
// Store the value // Store the value
var name = $input.val(); var name = $input.val();
// Remove the input // Remove the input
$(el).text(name); $(el).text(name);
// Save the value for the correct board // Save the value for the correct board
var board = $(el).closest('.kanban-board').attr("data-id"); var item = kanban.getItemJSON(eid);
var pos = kanban.findElementPosition(el.parentNode); item.title = name;
kanban.getBoardJSON(board).item[pos].title = name;
kanban.onChange(); kanban.onChange();
// Unlock edit mode // Unlock edit mode
kanban.inEditMode = false; kanban.inEditMode = false;
@ -182,11 +190,14 @@ define([
verbose("An edit is already active"); verbose("An edit is already active");
//return; //return;
} }
kanban.inEditMode = true; var boardId = $(el).closest('.kanban-board').attr("data-id");
kanban.inEditMode = boardId;
var name = $(el).text(); var name = $(el).text();
$(el).html(''); $(el).html('');
var $input = getInput().val(name).appendTo(el).focus(); var $input = getInput().val(name).appendTo(el).focus();
$input[0].select(); $input[0].select();
var save = function () { var save = function () {
// Store the value // Store the value
var name = $input.val(); var name = $input.val();
@ -196,8 +207,7 @@ define([
// Remove the input // Remove the input
$(el).text(name); $(el).text(name);
// Save the value for the correct board // Save the value for the correct board
var board = $(el.parentNode.parentNode).attr("data-id"); kanban.getBoardJSON(boardId).title = name;
kanban.getBoardJSON(board).title = name;
kanban.onChange(); kanban.onChange();
// Unlock edit mode // Unlock edit mode
kanban.inEditMode = false; kanban.inEditMode = false;
@ -294,7 +304,7 @@ define([
verbose("An edit is already active"); verbose("An edit is already active");
//return; //return;
} }
kanban.inEditMode = true; kanban.inEditMode = "new";
// create a form to enter element // create a form to enter element
var boardId = $(el.parentNode.parentNode).attr("data-id"); var boardId = $(el.parentNode.parentNode).attr("data-id");
var $item = $('<div>', {'class': 'kanban-item new-item'}); var $item = $('<div>', {'class': 'kanban-item new-item'});
@ -305,7 +315,9 @@ define([
$item.remove(); $item.remove();
kanban.inEditMode = false; kanban.inEditMode = false;
if (!$input.val()) { return; } if (!$input.val()) { return; }
var id = Hash.createChannelId();
kanban.addElement(boardId, { kanban.addElement(boardId, {
"id": id,
"title": $input.val(), "title": $input.val(),
}); });
}; };
@ -336,20 +348,20 @@ define([
$(addBoardDefault).attr('title', Messages.kanban_addBoard); $(addBoardDefault).attr('title', Messages.kanban_addBoard);
addBoardDefault.addEventListener('click', function () { addBoardDefault.addEventListener('click', function () {
if (framework.isReadOnly()) { return; } if (framework.isReadOnly()) { return; }
var counter = 1; /*var counter = 1;
// Get the new board id // Get the new board id
var boardExists = function (b) { return b.id === "board" + counter; }; var boardExists = function (b) { return b.id === "board" + counter; };
while (kanban.options.boards.some(boardExists)) { counter++; } while (kanban.options.boards.some(boardExists)) { counter++; }
*/
var id = Hash.createChannelId();
kanban.addBoards([{ kanban.addBoard({
"id": "board" + counter, "id": id,
"title": Messages.kanban_newBoard, "title": Messages.kanban_newBoard,
"color": COLORS[Math.floor(Math.random()*COLORS.length)], // random color "color": COLORS[Math.floor(Math.random()*COLORS.length)], // random color
"item": [{ "item": []
"title": Messages._getKey('kanban_item', [1]), });
}]
}]);
kanban.onChange(); kanban.onChange();
}); });
@ -403,86 +415,73 @@ define([
$container.addClass('cp-app-readonly'); $container.addClass('cp-app-readonly');
}); });
var getSelectedElement = function () {
var node = document.getSelection().anchorNode;
return (node.nodeType === 3 ? node.parentNode : node);
};
var getCursor = function () { var getCursor = function () {
if (!kanban || !kanban.inEditMode) { return; } if (!kanban || !kanban.inEditMode) { return; }
try { try {
var el = getSelectedElement(); var id = kanban.inEditMode;
var input = $(el).is('input') ? el : $(el).find('input')[0]; var newBoard;
if (!input) { return; } var $el = $container.find('[data-id="'+id+'"]');
var $input = $(input); if (id === "new") {
$el = $container.find('.kanban-item.new-item');
var pos; newBoard = $el.closest('.kanban-board').attr('data-id');
var $item = $(el).closest('.kanban-item'); } else if (!$el.length) {
if ($item.length) { $el = $container.find('[data-eid="'+id+'"]');
pos = kanban.findElementPosition($item[0]);
} }
var board = $input.closest('.kanban-board').attr('data-id'); if (!$el.length) { return; }
var $input = $el.find('input');
if (!$input.length) { return; }
var input = $input[0];
var val = ($input.val && $input.val()) || ''; var val = ($input.val && $input.val()) || '';
var start = input.selectionStart; var start = input.selectionStart;
var end = input.selectionEnd; var end = input.selectionEnd;
var json = kanban.getBoardJSON(id) || kanban.getItemJSON(id);
var boardEl = kanban.options.boards.find(function (b) { // XXX only title for now...
return b.id === board; var oldVal = json && json.title;
});
var oldVal = ((pos ? boardEl.item[pos] : boardEl) || {}).title;
return { return {
board: board, id: id,
pos: pos, newBoard: newBoard,
value: val, value: val,
start: start, start: start,
end: end, end: end,
oldValue: oldVal oldValue: oldVal
}; };
} catch (e) { } catch (e) {
console.error(e);
return {}; return {};
} }
}; };
var restoreCursor = function (data) { var restoreCursor = function (data) {
try { try {
var boardEl = kanban.options.boards.find(function (b) { var id = data.id;
return b.id === data.board;
});
if (!boardEl) { return; }
var $board = $('.kanban-board[data-id="'+data.board+'"');
// Editing a board title... // An item was being added: add a new item
if (!data.pos && $board.length) { if (id === "new" && !data.oldValue) {
if (boardEl.title !== data.oldValue) { return; } var $newBoard = $('.kanban-board[data-id="'+data.newBoard+'"]');
$board.find('.kanban-title-board').click(); $newBoard.find('.kanban-title-button.fa-plus').click();
var $boardInput = $board.find('.kanban-title-board input'); var $newInput = $newBoard.find('.kanban-item:last-child input');
$boardInput.val(data.value);
$boardInput[0].selectionStart = data.start;
$boardInput[0].selectionEnd = data.end;
return;
}
// Editing a deleted board title: abort
if (!data.pos) {
return;
}
// An item was added: add a new item
if (!data.oldValue) {
$board.find('.kanban-title-button.fa-plus').click();
var $newInput = $board.find('.kanban-item:last-child input');
$newInput.val(data.value); $newInput.val(data.value);
$newInput[0].selectionStart = data.start; $newInput[0].selectionStart = data.start;
$newInput[0].selectionEnd = data.end; $newInput[0].selectionEnd = data.end;
return; return;
} }
// An item was edited: click on the correct item // Edit a board title or a card title
var newVal = boardEl.item[data.pos]; var $el = $container.find('.kanban-board[data-id="'+id+'"]');
if (!newVal || newVal.title !== data.oldValue) { return; } if (!$el.length) {
var $el = $('.kanban-board[data-id="' + data.board + '"]') $el = $container.find('.kanban-item[data-eid="'+id+'"]');
.find('.kanban-item:nth-child('+(data.pos + 1)+')'); }
$el.find('.kanban-item-text').click(); if (!$el.length) { return; }
var json = kanban.getBoardJSON(id) || kanban.getItemJSON(id);
// if the value was changed by a remote user, abort
if (data.oldValue !== json.title) { return; }
// Editing a board title...
$el.find('.kanban-title-board, .kanban-item-text').click();
var $input = $el.find('input'); var $input = $el.find('input');
if ($input.length) { if ($input.length) {
$input.val(data.value); $input.val(data.value);
@ -490,6 +489,7 @@ define([
$input[0].selectionEnd = data.end; $input[0].selectionEnd = data.end;
} }
} catch (e) { } catch (e) {
console.error(e);
return; return;
} }
}; };
@ -509,6 +509,7 @@ define([
if (Sortify(currentContent) !== Sortify(remoteContent)) { if (Sortify(currentContent) !== Sortify(remoteContent)) {
var cursor = getCursor(); var cursor = getCursor();
console.error(cursor);
verbose("Content is different.. Applying content"); verbose("Content is different.. Applying content");
kanban.setBoards(remoteContent); kanban.setBoards(remoteContent);
kanban.inEditMode = false; kanban.inEditMode = false;

@ -45,7 +45,6 @@
this.drake = ''; this.drake = '';
this.drakeBoard = ''; this.drakeBoard = '';
this.addItemButton = false; this.addItemButton = false;
this.buttonContent = '+';
defaults = { defaults = {
element: '', element: '',
gutter: '15px', gutter: '15px',
@ -60,7 +59,6 @@
}, },
dragBoards: true, dragBoards: true,
addItemButton: false, addItemButton: false,
buttonContent: '+',
readOnly: false, readOnly: false,
dragEl: function (el, source) {}, dragEl: function (el, source) {},
dragendEl: function (el) {}, dragendEl: function (el) {},
@ -230,22 +228,14 @@ console.log(source, target, sourceId, targetId, board1, board2);
} }
}; };
this.addElement = function (boardID, element) { var getElementNode = function (element) {
// add Element to JSON
var boardJSON = __findBoardJSON(boardID);
boardJSON.item.push({
title: element.title
});
var board = self.element.querySelector('[data-id="' + boardID + '"] .kanban-drag');
var nodeItem = document.createElement('div'); var nodeItem = document.createElement('div');
nodeItem.classList.add('kanban-item'); nodeItem.classList.add('kanban-item');
if (element.id) { nodeItem.dataset.eid = element.id;
nodeItem.setAttribute('data-eid', element.id)
}
var nodeItemText = document.createElement('div'); var nodeItemText = document.createElement('div');
nodeItemText.classList.add('kanban-item-text'); nodeItemText.classList.add('kanban-item-text');
nodeItemText.innerHTML = element.title; nodeItemText.dataset.eid = element.id;
nodeItemText.innerText = element.title;
nodeItem.appendChild(nodeItemText); nodeItem.appendChild(nodeItemText);
//add function //add function
nodeItem.clickfn = element.click; nodeItem.clickfn = element.click;
@ -253,8 +243,21 @@ console.log(source, target, sourceId, targetId, board1, board2);
nodeItem.dragendfn = element.dragend; nodeItem.dragendfn = element.dragend;
nodeItem.dropfn = element.drop; nodeItem.dropfn = element.drop;
__onclickHandler(nodeItemText); __onclickHandler(nodeItemText);
__onColorClickHandler(nodeItem, "item"); //__onColorClickHandler(nodeItem, "item");
board.appendChild(nodeItem); return nodeItem;
};
this.addElement = function (boardID, element) {
// add Element to JSON
var boardJSON = __findBoardJSON(boardID);
boardJSON.item.push(element.id);
self.options.boards.items = self.options.boards.items || {};
self.options.boards.items[element.id] = element;
var board = self.element.querySelector('[data-id="' + boardID + '"] .kanban-drag');
board.appendChild(getElementNode(element));
// send event that board has changed // send event that board has changed
self.onChange(); self.onChange();
return self; return self;
@ -266,15 +269,90 @@ console.log(source, target, sourceId, targetId, board1, board2);
return self; return self;
}; };
var getBoardNode = function (board) {
this.addBoards = function(boards) { var boards = self.options.boards;
var boardWidth = self.options.widthBoard; var boardWidth = self.options.widthBoard;
var addButton = self.options.addItemButton; //create node
var buttonContent = self.options.buttonContent; var boardNode = document.createElement('div');
boardNode.dataset.id = board.id;
boardNode.classList.add('kanban-board');
//set style
if (self.options.responsivePercentage) {
boardNode.style.width = boardWidth + '%';
} else {
boardNode.style.width = boardWidth;
}
boardNode.style.marginLeft = self.options.gutter;
boardNode.style.marginRight = self.options.gutter;
// header board
var headerBoard = document.createElement('header');
if (board.class !== '' && board.class !== undefined) {
var allClasses = board.class.split(",");
} else {
allClasses = [];
}
headerBoard.classList.add('kanban-board-header');
allClasses.map(function (value) {
headerBoard.classList.add(value);
});
if (board.color !== '' && board.color !== undefined) {
// XXX color
headerBoard.classList.add("kanban-header-" + board.color);
}
titleBoard = document.createElement('div');
titleBoard.classList.add('kanban-title-board');
titleBoard.innerText = board.title;
titleBoard.clickfn = board.boardTitleClick;
__onboardTitleClickHandler(titleBoard);
headerBoard.appendChild(titleBoard);
//content board
var contentBoard = document.createElement('main');
contentBoard.classList.add('kanban-drag');
//add drag to array for dragula
self.boardContainer.push(contentBoard);
(board.item || []).forEach(function (itemkey) {
//create item
var itemKanban = boards.items[itemkey];
if (!itemKanban) { return; } // XXX clean invalid data
var nodeItem = getElementNode(itemKanban);
contentBoard.appendChild(nodeItem);
});
//footer board
var footerBoard = document.createElement('footer');
footerBoard.classList.add('kanban-board-footer');
//add button
var addBoardItem = document.createElement('button');
$(addBoardItem).addClass("kanban-title-button btn btn-default fa fa-plus");
footerBoard.appendChild(addBoardItem);
__onAddItemClickHandler(addBoardItem);
//board assembly
boardNode.appendChild(headerBoard);
boardNode.appendChild(contentBoard);
boardNode.appendChild(footerBoard);
return boardNode;
};
this.addBoard = function (board) {
if (!board || !board.id) { return; }
var boards = self.options.boards;
boards.data = boards.data || {};
boards.list = boards.list || [];
// If it already there, abort
boards.data[board.id] = board;
if (boards.list.indexOf(board.id) !== -1) { return; }
boards.list.push(board.id);
var boardNode = getBoardNode(board);
self.container.appendChild(boardNode);
};
this.addBoards = function() {
//for on all the boards //for on all the boards
var old = self.options.boards; var boards = self.options.boards;
boards.list = boards.list || []; boards.list = boards.list || [];
boards.data = boards.data || {}; boards.data = boards.data || {};
for (var index in boards.list) { for (var index in boards.list) {
@ -283,111 +361,8 @@ console.log(source, target, sourceId, targetId, board1, board2);
var board = boards.data[boardkey]; var board = boards.data[boardkey];
if (!board) { continue; } // XXX clean invalid data if (!board) { continue; } // XXX clean invalid data
// Remote changes, we had to reset our data var boardNode = getBoardNode(board);
if (old !== boards && old.list.indexOf(boardKey === -1)) {
old.list.push(boardKey);
}
//create node
var boardNode = document.createElement('div');
boardNode.dataset.id = board.id;
boardNode.classList.add('kanban-board');
//set style
if (self.options.responsivePercentage) {
boardNode.style.width = boardWidth + '%';
} else {
boardNode.style.width = boardWidth;
}
boardNode.style.marginLeft = self.options.gutter;
boardNode.style.marginRight = self.options.gutter;
// header board
var headerBoard = document.createElement('header');
if (board.class !== '' && board.class !== undefined) {
var allClasses = board.class.split(",");
} else {
allClasses = [];
}
headerBoard.classList.add('kanban-board-header');
allClasses.map(function (value) {
headerBoard.classList.add(value);
});
if (board.color !== '' && board.color !== undefined) {
/*
headerBoard._jscLinkedInstance = undefined;
jscolorL = new jscolor(headerBoard,{showOnClick: false, valueElement:undefined});
jscolorL.fromString(board.color);
headerBoard._jscLinkedInstance = undefined;
*/
// XXX fixed list of color: use class?
headerBoard.classList.add("kanban-header-" + board.color);
}
titleBoard = document.createElement('div');
titleBoard.classList.add('kanban-title-board');
titleBoard.innerHTML = board.title;
//titleBoard.setAttribute('title', board.title);
titleBoard.clickfn = board.boardTitleClick;
__onboardTitleClickHandler(titleBoard);
headerBoard.appendChild(titleBoard);
//__onColorClickHandler(headerBoard, "board"); // XXX color
// add button to the board
/* // XXX delete board button ==> removed
var btn = document.createElement("BUTTON");
btn.setAttribute("class", "kanban-title-button btn btn-default btn-xs fa fa-times");
headerBoard.appendChild(btn);
__onButtonClickHandler(btn, board.id);
*/
//content board
var contentBoard = document.createElement('main');
contentBoard.classList.add('kanban-drag');
//add drag to array for dragula
self.boardContainer.push(contentBoard);
(board.item || []).forEach(function (itemkey) {
//create item
var itemKanban = boards.items[itemkey];
if (!itemKanban) { return; } // XXX clean invalid data
var nodeItem = document.createElement('div');
nodeItem.classList.add('kanban-item');
nodeItem.dataset.eid = itemKanban.id;
var nodeItemText = document.createElement('div');
nodeItemText.classList.add('kanban-item-text');
nodeItemText.dataset.eid = itemKanban.id;
nodeItemText.innerHTML = itemKanban.title;
nodeItem.appendChild(nodeItemText);
//add function
nodeItemText.clickfn = itemKanban.click;
nodeItemText.dragfn = itemKanban.drag;
nodeItemText.dragendfn = itemKanban.dragend;
nodeItemText.dropfn = itemKanban.drop;
//add click handler of item
__onclickHandler(nodeItemText);
/*
// XXX color handle color differently
if (itemKanban.color !== '' && itemKanban.color !== undefined) {
jscolorL = new jscolor(nodeItem,{
showOnClick: false, valueElement:undefined
});
jscolorL.fromString(itemKanban.color);
}*/
//__onColorClickHandler(nodeItem, "item"); // XXX color
contentBoard.appendChild(nodeItem);
});
//footer board
var footerBoard = document.createElement('footer');
footerBoard.classList.add('kanban-board-footer');
//add button
var addBoardItem = document.createElement('button');
$(addBoardItem).addClass("kanban-title-button btn btn-default fa fa-plus");
footerBoard.appendChild(addBoardItem);
__onAddItemClickHandler(addBoardItem);
//board assembly
boardNode.appendChild(headerBoard);
boardNode.appendChild(contentBoard);
boardNode.appendChild(footerBoard);
//board add //board add
self.container.appendChild(boardNode); self.container.appendChild(boardNode);
} }
@ -400,16 +375,12 @@ console.log(source, target, sourceId, targetId, board1, board2);
this.setBoards = function (boards) { this.setBoards = function (boards) {
//self.element //self.element
for (var boardkey in this.options.boards.list) { for (var i in this.options.boards.list) {
//var board = this.options.boards[boardkey]; var boardkey = boards.list[i];
this.removeBoard(boardKey); this.removeBoard(boardkey);
} }
this.options.boards = { this.options.boards = boards;
list: [], this.addBoards();
data: boards.data || {},
items: boards.items || {}
};
this.addBoards(boards);
} }
this.findBoard = function (id) { this.findBoard = function (id) {
@ -472,6 +443,9 @@ console.log(source, target, sourceId, targetId, board1, board2);
this.getBoardJSON = function (id) { this.getBoardJSON = function (id) {
return __findBoardJSON(id); return __findBoardJSON(id);
} }
this.getItemJSON = function (id) {
return (self.options.boards.items || {})[id];
};
//PRIVATE FUNCTION //PRIVATE FUNCTION
function __extendDefaults(source, properties) { function __extendDefaults(source, properties) {
@ -499,7 +473,7 @@ console.log(source, target, sourceId, targetId, board1, board2);
self.container = boardContainer; self.container = boardContainer;
//add boards //add boards
self.addBoards(self.options.boards); self.addBoards();
//appends to container //appends to container
self.element.appendChild(boardContainerOuter); self.element.appendChild(boardContainerOuter);

Loading…
Cancel
Save