Changes for page KanbanMacro

Last modified by XWiki Demo Admin on 2026/06/09 11:38

From version 1.1
edited by XWiki Demo Admin
on 2026/05/28 16:13
Change comment: Install extension [org.xwiki.contrib:macro-kanban/1.2.3]
To version 2.1
edited by XWiki Demo Admin
on 2026/06/09 11:38
Change comment: Install extension [org.xwiki.contrib:macro-kanban/1.4.3]

Summary

Details

Page properties
Content
... ... @@ -2,7 +2,7 @@
2 2  The macro can take the JSON of the kanban either from the content of the macro or from an URL. There is also the [[xwiki:Macros.AWMKanbanMacro]] allowing to display a kanban board from AppWithinMinutes data.
3 3  
4 4  ##{{{
5 -{{kanban width="30%" source="" updateService="" addBoardButton="true" addItemButton="true" removeBoardButton="true" removeBoardItem="true"}}
5 +{{kanban width="30%" source="" updateService="" addBoardButton="true" addItemButton="true" removeBoardButton="true" addRemoveButton="true"}}
6 6  [
7 7   {"id":"board1","title":"To Do","color":"red","item":[{"title":"Item 1"},{"title":"Item 2"}]},
8 8   {"id":"board2","title":"Working","color":"blue","item":[{"title":"Item 3"},{"title":"Item 4"}]},
... ... @@ -19,7 +19,7 @@
19 19  * ##addBoardButton## display the add Board button (default true)
20 20  * ##addItemButton## display the add Item button (default true)
21 21  * ##removeBoardButton## display the remove Board button (default true)
22 -* ##removeBoardItem## allow removing Item by drag and dropping them out of a board (default true)
22 +* ##addRemoveButton## allow removing Item by drag and dropping them out of a board (default true)
23 23  
24 24  == Example ==
25 25  
XWiki.JavaScriptExtension[0]
Code
... ... @@ -27,7 +27,7 @@
27 27   * jKanban
28 28   * Vanilla Javascript plugin for manage kanban boards
29 29   *
30 - * @site: http://www.riccardotartaglia.it/jkanban/
30 + * @url: http://www.riccardotartaglia.it/jkanban/
31 31   * @author: Riccardo Tartaglia
32 32   */
33 33  
... ... @@ -51,7 +51,13 @@
51 51   gutter: '15px',
52 52   widthBoard: '250px',
53 53   responsive: '700',
54 - colors: ["yellow", "green", "blue", "red", "orange"],
54 + colors: {
55 + 'green': '#8C4',
56 + 'blue':'#0AC',
57 + 'orange':'#F91',
58 + 'yellow':'#FC3',
59 + 'red':'#E43'
60 + },
55 55   boards: [],
56 56   dragBoards: true,
57 57   addItemButton: false,
... ... @@ -291,9 +291,9 @@
291 291   allClasses.map(function (value) {
292 292   headerBoard.classList.add(value);
293 293   });
294 - if (board.color !== '' && board.color !== undefined) {
295 - headerBoard.classList.add("kanban-header-" + board.color);
296 - }
300 + // We want to keep backward compatibility with the old "color" property so we don't break existing boards.
301 + color = defaults.colors[board.color] ? defaults.colors[board.color] : board.color;
302 + headerBoard.style.background = color;
297 297   titleBoard = document.createElement('div');
298 298   titleBoard.classList.add('kanban-title-board');
299 299   titleBoard.innerHTML = board.title;
... ... @@ -328,14 +328,12 @@
328 328   nodeItem.dropfn = itemKanban.drop;
329 329   nodeItem.dataset.eid = itemKanban.id;
330 330  
331 - var nodeItemTitle = document.createElement('div');
337 + var nodeItemTitle = document.createElement(itemKanban.url ? 'a' : 'div');
332 332   nodeItemTitle.classList.add('kanban-item-title');
333 333   nodeItemTitle.innerHTML = itemKanban.title;
334 334   nodeItemTitle.clickfn = itemKanban.click;
335 335   if (itemKanban.url) {
336 - nodeItemTitle.addEventListener('click', function (e) {
337 - location = this.url;
338 - }.bindAsEventListener(itemKanban));
342 + nodeItemTitle.href = itemKanban.url;
339 339   } else {
340 340   // add click handler of item
341 341   __onclickHandler(nodeItemTitle);
XWiki.StyleSheetExtension[0]
Code
... ... @@ -79,6 +79,8 @@
79 79  
80 80  .kanban-item-title {
81 81   margin: 5px;
82 + word-wrap: break-word;
83 + overflow-wrap: break-word;
82 82  }
83 83  
84 84  .kanban-item:hover {
... ... @@ -111,26 +111,6 @@
111 111   font-weight: bold;
112 112  }
113 113  
114 -.kanban-header-yellow {
115 - background: #FC3;
116 -}
117 -
118 -.kanban-header-orange {
119 - background: #F91;
120 -}
121 -
122 -.kanban-header-blue {
123 - background: #0AC;
124 -}
125 -
126 -.kanban-header-red {
127 - background: #E43;
128 -}
129 -
130 -.kanban-header-green {
131 - background: #8C4;
132 -}
133 -
134 134  .kanban-addboard {
135 135   float: left;
136 136   margin: 30px;
XWiki.WikiMacroClass[0]
Macro code
... ... @@ -16,7 +16,7 @@
16 16  <script type="text/javascript">
17 17  require.config({
18 18   paths: {
19 - jkanban: '$xwiki.getURL("Macros.KanbanMacro", "jsx", "language=${xcontext.language}")'
19 + jkanban: '$xwiki.getURL("Macros.KanbanMacro", "jsx", "language=${xcontext.locale}")'
20 20   }
21 21  });
22 22  require(['jquery','jkanban'], function(jQuery) {
... ... @@ -34,16 +34,16 @@
34 34   var posting = jQuery.post( updateService, { page : page, nb : counter, content : newBoards } );
35 35   posting.success(function(data) {
36 36   if (data.indexOf("SUCCESS")>=0 && data.indexOf("SUCCESS")<10) {
37 - #set($success = $escapetool.json($services.localization.render("kanban.update.success")))
37 + #set($success = $escapetool.javascript($services.localization.render("kanban.update.success")))
38 38   new XWiki.widgets.Notification('$success', 'info', '20');
39 39   currentBoards = newBoards;
40 40   } else {
41 - #set($error = $escapetool.json($services.localization.render("kanban.update.error")))
41 + #set($error = $escapetool.javascript($services.localization.render("kanban.update.error")))
42 42   new XWiki.widgets.Notification('$error', 'error', '20');
43 43   }
44 44   });
45 45   posting.error(function(xhr,status,error) {
46 - #set($error = $escapetool.json($services.localization.render("kanban.update.error")))
46 + #set($error = $escapetool.javascript($services.localization.render("kanban.update.error")))
47 47   new XWiki.widgets.Notification('$error', 'error', '20');
48 48   });
49 49  
... ... @@ -110,25 +110,6 @@
110 110   });
111 111  
112 112   },
113 - colorClick: function (el, boardId) {
114 - console.log("in color click");
115 - var board = jQuery(el.parentNode).attr("data-id");
116 - var boardJSON = kanban.getBoardJSON(board);
117 - var currentColor = boardJSON.color;
118 - console.log("Current color " + currentColor);
119 - var index = kanban.options.colors.findIndex(function (element) {
120 - return (element == currentColor)
121 - }) + 1;
122 - console.log("Next index " + index);
123 - if (index >= kanban.options.colors.length)
124 - index = 0;
125 - var nextColor = kanban.options.colors[index];
126 - console.log("Next color " + nextColor);
127 - boardJSON.color = nextColor;
128 - jQuery(el).removeClass("kanban-header-" + currentColor);
129 - jQuery(el).addClass("kanban-header-" + nextColor);
130 - kanban.onChange();
131 - },
132 132   removeClick: function (el, boardId) {
133 133   if (confirm("Do you want to delete this board?")) {
134 134   console.log("Delete board");
... ... @@ -173,12 +173,37 @@
173 173   + boardId + '</value></property>'
174 174   jQuery.ajax({ url: restURL, type: 'PUT', data: data, contentType: "application/xml",
175 175   success: function(result) {
176 - #set($success = $escapetool.json($services.localization.render("kanban.update.success")))
157 + #set($success = $escapetool.javascript($services.localization.render("kanban.update.success")))
177 177   new XWiki.widgets.Notification('$success', 'info', '20');
178 178   },
179 179   error: function(result) {
180 - #set($error = $escapetool.json($services.localization.render("kanban.update.error")))
181 - new XWiki.widgets.Notification('$error', 'error', '20');
161 + // This is a workaround for XWIKI-20704. Remove this section of code when the parent
162 + // of this project will greater or equal than the fix version of the issue.
163 + // --- START ---
164 + let regex = /\/objects\/([^\/]+)\/0\/properties\/([^\/]+)/;
165 + let match = restURL.match(regex);
166 + let params = {
167 + outputSyntax: 'plain',
168 + docRef: currentdoc.documentReference.toString(),
169 + className: match[1],
170 + propertyName: match[2]
171 + };
172 + jQuery.ajax({
173 + url: new XWiki.Document(XWiki.Model.resolve('Macros.KanbanWorkaroundService', XWiki.EntityType.DOCUMENT, XWiki.currentDocument.getDocumentReference())).getURL('get', jQuery.param(params)),
174 + type: 'GET',
175 + success: function(result) {
176 + if (result.status === boardId) {
177 + new XWiki.widgets.Notification('$success', 'info', '20');
178 + } else {
179 + #set($error = $escapetool.javascript($services.localization.render("kanban.update.error")))
180 + new XWiki.widgets.Notification('$error', 'error', '20');
181 + }
182 + },
183 + error: function() {
184 + new XWiki.widgets.Notification('$error', 'error', '20');
185 + }
186 + });
187 + // --- END ---
182 182   }
183 183   });
184 184   },
... ... @@ -192,8 +192,8 @@
192 192  #if($xcontext.macro.params.removeBoardButton)
193 193   removeBoardButton: ${xcontext.macro.params.removeBoardButton},
194 194  #end
195 -#if($xcontext.macro.params.removeItemButton)
196 - removeItemButton: ${xcontext.macro.params.removeItemButton},
201 +#if($xcontext.macro.params.addRemoveButton)
202 + addRemoveButton: ${xcontext.macro.params.addRemoveButton},
197 197  #end
198 198   boards: boards
199 199   });
... ... @@ -210,7 +210,7 @@
210 210   initKanban(data, updateService);
211 211   });
212 212   getdata.error(function(xhr,status,error) {
213 - #set($error = $escapetool.json($services.localization.render("kanban.load.error")))
219 + #set($error = $escapetool.javascript($services.localization.render("kanban.load.error")))
214 214   new XWiki.widgets.Notification('$error', 'error', '20');
215 215   });
216 216   #elseif($xcontext.macro.content)