Add show/hide columns on the board

This commit is contained in:
Frederic Guillot 2015-08-15 17:10:42 -04:00
parent fece613c06
commit cea32af406
9 changed files with 394 additions and 166 deletions

View File

@ -3,6 +3,7 @@ Version 1.0.18 (unreleased)
New features:
* Add hide/show columns
* Add Gantt chart for projects
* Add new role "Project Administrator"
* Add login bruteforce protection with captcha and account lockdown

View File

@ -1,7 +1,7 @@
<tr id="swimlane-<?= $swimlane['id'] ?>">
<!-- swimlane toggle -->
<?php if (! $hide_swimlane): ?>
<th>
<th class="board-swimlane-header">
<?php if (! $not_editable && $swimlane['nb_tasks'] > 0): ?>
<a href="#" class="board-swimlane-toggle" data-swimlane-id="<?= $swimlane['id'] ?>">
<i class="fa fa-minus-circle hide-icon-swimlane-<?= $swimlane['id'] ?>"></i>
@ -14,36 +14,45 @@
<!-- column header title -->
<?php foreach ($swimlane['columns'] as $column): ?>
<th class="board-column-header">
<?php if (! $not_editable): ?>
<div class="board-add-icon">
<?= $this->url->link('+', 'taskcreation', 'create', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id']), false, 'popover', t('Add a new task')) ?>
</div>
<?php endif ?>
<?= $this->e($column['title']) ?>
<?php if (! $not_editable && ! empty($column['description'])): ?>
<span class="tooltip pull-right" title='<?= $this->e($this->text->markdown($column['description'])) ?>'>
<i class="fa fa-info-circle"></i>
<th class="board-column-header board-column-header-<?= $column['id'] ?>" data-column-id="<?= $column['id'] ?>">
<div class="board-column-collapsed">
<span title="<?= t('Task count') ?>" class="board-column-header-task-count" title="<?= t('Show this column') ?>">
<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span>
</span>
<?php endif ?>
</div>
<div class="board-column-expanded">
<?php if (! $not_editable): ?>
<div class="board-add-icon">
<?= $this->url->link('+', 'taskcreation', 'create', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id']), false, 'popover', t('Add a new task')) ?>
</div>
<?php endif ?>
<?php if (! empty($column['score'])): ?>
<span class="column-score pull-right" title="<?= t('Score') ?>">
<?= $column['score'] ?>&nbsp;
<span class="board-column-title" data-column-id="<?= $column['id'] ?>" title="<?= t('Hide this column') ?>">
<?= $this->e($column['title']) ?>
</span>
<?php endif ?>
<?php if ($column['task_limit']): ?>
<span title="<?= t('Task limit') ?>" class="task-limit">
(<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span>/<?= $this->e($column['task_limit']) ?>)
</span>
<?php else: ?>
<span title="<?= t('Task count') ?>" class="task-count">
(<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span>)
</span>
<?php endif ?>
<?php if (! $not_editable && ! empty($column['description'])): ?>
<span class="tooltip pull-right" title='<?= $this->e($this->text->markdown($column['description'])) ?>'>
<i class="fa fa-info-circle"></i>
</span>
<?php endif ?>
<?php if (! empty($column['score'])): ?>
<span class="pull-right" title="<?= t('Score') ?>">
<?= $column['score'] ?>&nbsp;
</span>
<?php endif ?>
<?php if ($column['task_limit']): ?>
<span title="<?= t('Task limit') ?>">
(<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span>/<?= $this->e($column['task_limit']) ?>)
</span>
<?php else: ?>
<span title="<?= t('Task count') ?>" class="board-column-header-task-count">
(<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span>)
</span>
<?php endif ?>
</div>
</th>
<?php endforeach ?>
</tr>
@ -54,16 +63,16 @@
<th class="board-swimlane-title">
<?= $this->e($swimlane['name']) ?>
<span title="<?= t('Task count') ?>" class="task-count">
<div title="<?= t('Task count') ?>" class="board-column-header-task-count">
(<span><?= $swimlane['nb_tasks'] ?></span>)
</span>
</div>
</th>
<?php endif ?>
<!-- task list -->
<?php foreach ($swimlane['columns'] as $column): ?>
<td id="column-<?= $column['id'] ?>" class="<?= $column['task_limit'] && $column['nb_tasks'] > $column['task_limit'] ? 'board-task-list-limit' : '' ?>">
<div class="board-task-list" data-column-id="<?= $column['id'] ?>" data-swimlane-id="<?= $swimlane['id'] ?>" data-task-limit="<?= $column['task_limit'] ?>">
<td class="board-column-<?= $column['id'] ?> <?= $column['task_limit'] && $column['nb_tasks'] > $column['task_limit'] ? 'board-task-list-limit' : '' ?>">
<div class="board-task-list board-column-expanded" data-column-id="<?= $column['id'] ?>" data-swimlane-id="<?= $swimlane['id'] ?>" data-task-limit="<?= $column['task_limit'] ?>">
<?php foreach ($column['tasks'] as $task): ?>
<?= $this->render($not_editable ? 'board/task_public' : 'board/task_private', array(
'project' => $project,
@ -73,6 +82,13 @@
)) ?>
<?php endforeach ?>
</div>
<div class="board-column-collapsed">
<div class="board-rotation-wrapper">
<div class="board-column-title board-rotation" data-column-id="<?= $column['id'] ?>" title="<?= t('Show this column') ?>">
<?= $this->e($column['title']) ?>
</div>
</div>
</div>
</td>
<?php endforeach ?>
</tr>

View File

@ -757,6 +757,19 @@ nav .active a {
overflow-x: scroll;
}
#board {
table-layout: fixed;
}
#board th.board-column-header {
width: 240px;
}
#board td {
vertical-align: top;
}
/* compact mode/horizontal scrolling */
.board-container-compact {
overflow-x: initial;
}
@ -767,30 +780,43 @@ nav .active a {
}
}
#board {
table-layout: fixed;
}
#board th {
width: 120px; /* Width of swimlane column */
}
#board th.board-column-header {
width: 240px; /* Width of other columns, in default [horizontal scrolling] view mode */
}
#board th.board-column-header.board-column-compact {
width: initial; /* Do not force the width of the columns in compact view mode */
}
#board th a {
text-decoration: none;
color: #3366CC;
font-size: 150%;
/* show/hide column */
.board-column-collapsed {
display: none;
}
#board td {
vertical-align: top;
td.board-column-task-collapsed {
font-weight: bold;
background-color: #fbfbfb;
}
#board th.board-column-header-collapsed {
width: 28px;
min-width: 28px;
text-align: center;
overflow: hidden;
}
.board-rotation-wrapper {
position: relative;
padding: 8px 4px;
}
.board-rotation {
min-width: 250px;
-webkit-backface-visibility: hidden;
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
transform-origin: 0 100%;
}
/* column header */
@ -800,29 +826,33 @@ nav .active a {
}
.board-add-icon a {
text-decoration: none;
color: #3366CC;
font-size: 150%;
line-height: 70%;
}
.task-count {
.board-add-icon a:focus,
.board-add-icon a:hover {
text-decoration: none;
color: red;
}
.board-column-header-task-count {
color: #999;
font-weight: normal;
}
/* drag and drop */
.draggable-item {
cursor: pointer;
user-select: none;
}
.draggable-placeholder {
border: 2px dashed #000;
background: #fafafa;
height: 70px;
margin-bottom: 10px;
th.board-column-header-collapsed .board-column-header-task-count {
font-size: 0.85em;
}
/* swimlanes */
#board th a.board-swimlane-toggle {
th.board-swimlane-header {
width: 120px;
}
a.board-swimlane-toggle {
font-size: 0.95em;
}
@ -844,6 +874,19 @@ nav .active a {
.board-task-list-limit {
background-color: #DF5353;
}
/* drag and drop */
.draggable-item {
cursor: pointer;
user-select: none;
}
.draggable-placeholder {
border: 2px dashed #000;
background: #fafafa;
height: 70px;
margin-bottom: 10px;
}
/* task inside the board */
.task-board {
position: relative;

View File

@ -162,6 +162,19 @@ th a:hover {
overflow-x: scroll;
}
#board {
table-layout: fixed;
}
#board th.board-column-header {
width: 240px;
}
#board td {
vertical-align: top;
}
/* compact mode/horizontal scrolling */
.board-container-compact {
overflow-x: initial;
}
@ -172,30 +185,43 @@ th a:hover {
}
}
#board {
table-layout: fixed;
}
#board th {
width: 120px; /* Width of swimlane column */
}
#board th.board-column-header {
width: 240px; /* Width of other columns, in default [horizontal scrolling] view mode */
}
#board th.board-column-header.board-column-compact {
width: initial; /* Do not force the width of the columns in compact view mode */
}
#board th a {
text-decoration: none;
color: #3366CC;
font-size: 150%;
/* show/hide column */
.board-column-collapsed {
display: none;
}
#board td {
vertical-align: top;
td.board-column-task-collapsed {
font-weight: bold;
background-color: #fbfbfb;
}
#board th.board-column-header-collapsed {
width: 28px;
min-width: 28px;
text-align: center;
overflow: hidden;
}
.board-rotation-wrapper {
position: relative;
padding: 8px 4px;
}
.board-rotation {
min-width: 250px;
-webkit-backface-visibility: hidden;
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
transform-origin: 0 100%;
}
/* column header */
@ -205,29 +231,33 @@ th a:hover {
}
.board-add-icon a {
text-decoration: none;
color: #3366CC;
font-size: 150%;
line-height: 70%;
}
.task-count {
.board-add-icon a:focus,
.board-add-icon a:hover {
text-decoration: none;
color: red;
}
.board-column-header-task-count {
color: #999;
font-weight: normal;
}
/* drag and drop */
.draggable-item {
cursor: pointer;
user-select: none;
}
.draggable-placeholder {
border: 2px dashed #000;
background: #fafafa;
height: 70px;
margin-bottom: 10px;
th.board-column-header-collapsed .board-column-header-task-count {
font-size: 0.85em;
}
/* swimlanes */
#board th a.board-swimlane-toggle {
th.board-swimlane-header {
width: 120px;
}
a.board-swimlane-toggle {
font-size: 0.95em;
}
@ -249,6 +279,19 @@ th a:hover {
.board-task-list-limit {
background-color: #DF5353;
}
/* drag and drop */
.draggable-item {
cursor: pointer;
user-select: none;
}
.draggable-placeholder {
border: 2px dashed #000;
background: #fafafa;
height: 70px;
margin-bottom: 10px;
}
/* task inside the board */
.task-board {
position: relative;

View File

@ -14,6 +14,19 @@
overflow-x: scroll;
}
#board {
table-layout: fixed;
}
#board th.board-column-header {
width: 240px;
}
#board td {
vertical-align: top;
}
/* compact mode/horizontal scrolling */
.board-container-compact {
overflow-x: initial;
}
@ -24,30 +37,43 @@
}
}
#board {
table-layout: fixed;
}
#board th {
width: 120px; /* Width of swimlane column */
}
#board th.board-column-header {
width: 240px; /* Width of other columns, in default [horizontal scrolling] view mode */
}
#board th.board-column-header.board-column-compact {
width: initial; /* Do not force the width of the columns in compact view mode */
}
#board th a {
text-decoration: none;
color: #3366CC;
font-size: 150%;
/* show/hide column */
.board-column-collapsed {
display: none;
}
#board td {
vertical-align: top;
td.board-column-task-collapsed {
font-weight: bold;
background-color: #fbfbfb;
}
#board th.board-column-header-collapsed {
width: 28px;
min-width: 28px;
text-align: center;
overflow: hidden;
}
.board-rotation-wrapper {
position: relative;
padding: 8px 4px;
}
.board-rotation {
min-width: 250px;
-webkit-backface-visibility: hidden;
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
transform-origin: 0 100%;
}
/* column header */
@ -57,29 +83,33 @@
}
.board-add-icon a {
text-decoration: none;
color: #3366CC;
font-size: 150%;
line-height: 70%;
}
.task-count {
.board-add-icon a:focus,
.board-add-icon a:hover {
text-decoration: none;
color: red;
}
.board-column-header-task-count {
color: #999;
font-weight: normal;
}
/* drag and drop */
.draggable-item {
cursor: pointer;
user-select: none;
}
.draggable-placeholder {
border: 2px dashed #000;
background: #fafafa;
height: 70px;
margin-bottom: 10px;
th.board-column-header-collapsed .board-column-header-task-count {
font-size: 0.85em;
}
/* swimlanes */
#board th a.board-swimlane-toggle {
th.board-swimlane-header {
width: 120px;
}
a.board-swimlane-toggle {
font-size: 0.95em;
}
@ -101,3 +131,16 @@
.board-task-list-limit {
background-color: #DF5353;
}
/* drag and drop */
.draggable-item {
cursor: pointer;
user-select: none;
}
.draggable-placeholder {
border: 2px dashed #000;
background: #fafafa;
height: 70px;
margin-bottom: 10px;
}

File diff suppressed because one or more lines are too long

View File

@ -6,12 +6,13 @@ function Board(app) {
Board.prototype.execute = function() {
this.app.swimlane.refresh();
this.app.swimlane.listen();
this.restoreColumnViewMode();
this.compactView();
this.poll();
this.keyboardShortcuts();
this.resizeColumnHeight();
this.listen();
this.dragAndDrop();
this.compactView();
$(window).resize(this.resizeColumnHeight);
};
@ -72,6 +73,7 @@ Board.prototype.refresh = function(data) {
this.listen();
this.dragAndDrop();
this.compactView();
this.restoreColumnViewMode();
};
Board.prototype.resizeColumnHeight = function() {
@ -112,6 +114,10 @@ Board.prototype.listen = function() {
e.preventDefault();
self.toggleCompactView();
});
$(document).on("click", ".board-column-title", function() {
self.toggleColumnViewMode($(this).data("column-id"));
});
};
Board.prototype.toggleCompactView = function() {
@ -126,7 +132,7 @@ Board.prototype.compactView = function() {
$(".filter-compact").hide();
$("#board-container").addClass("board-container-compact");
$("#board th").addClass("board-column-compact");
$("#board th:not(.board-column-header-collapsed)").addClass("board-column-compact");
}
else {
$(".filter-wide").hide();
@ -151,6 +157,66 @@ Board.prototype.toggleCollapsedMode = function() {
});
};
Board.prototype.restoreColumnViewMode = function() {
var self = this;
$("tr:first th").each(function() {
var columnId = $(this).data('column-id');
if (localStorage.getItem("hidden_column_" + columnId)) {
self.hideColumn(columnId);
}
});
};
Board.prototype.toggleColumnViewMode = function(columnId) {
if (localStorage.getItem("hidden_column_" + columnId)) {
this.showColumn(columnId);
}
else {
this.hideColumn(columnId);
}
};
Board.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() {
var position = $(".board-swimlane").position();
$(".board-column-task-collapsed").height($(window).height() - position.top);
$(this).css("width", $(".board-column-" + columnId + "").height());
});
localStorage.setItem("hidden_column_" + columnId, 1);
};
Board.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);
};
Board.prototype.keyboardShortcuts = function() {
var self = this;

View File

@ -0,0 +1,11 @@
Show and hide columns on the board
==================================
You can hide or display columns very easily on the board:
![Board with hidden columns](http://kanboard.net/screenshots/documentation/board-hide-show-column.png)
- To hide a column, just click on the column title
- To show a hidden column, click on the vertical title
When a column is hidden the number of tasks is displayed at the top.

View File

@ -13,8 +13,9 @@ Using Kanboard
### Using the board
- [Board, Calendar and List views](project-views.markdown)
- [Collapsed and expended mode](board-collapsed-expanded.markdown)
- [Collapsed and expanded mode](board-collapsed-expanded.markdown)
- [Horizontal scrolling and compact mode](board-horizontal-scrolling-and-compact-view.markdown)
- [Show and hide columns](board-show-hide-columns.makrdown)
### Working with projects