diff options
-rw-r--r-- | app/Auth/Ldap.php | 1 | ||||
-rw-r--r-- | app/Model/TaskLink.php | 3 | ||||
-rw-r--r-- | app/Template/task/show.php | 2 | ||||
-rw-r--r-- | app/Template/tasklink/show.php | 4 | ||||
-rw-r--r-- | app/constants.php | 1 | ||||
-rw-r--r-- | assets/css/app.css | 14 | ||||
-rw-r--r-- | assets/css/src/board.css | 12 | ||||
-rw-r--r-- | assets/css/src/task.css | 2 | ||||
-rw-r--r-- | assets/js/app.js | 6 | ||||
-rw-r--r-- | assets/js/src/board.js | 6 | ||||
-rw-r--r-- | config.default.php | 4 | ||||
-rw-r--r-- | docs/ldap-authentication.markdown | 9 |
12 files changed, 37 insertions, 27 deletions
diff --git a/app/Auth/Ldap.php b/app/Auth/Ldap.php index e9bb5815..376d16f6 100644 --- a/app/Auth/Ldap.php +++ b/app/Auth/Ldap.php @@ -29,6 +29,7 @@ class Ldap extends Base */ public function authenticate($username, $password) { + $username = LDAP_USERNAME_CASE_SENSITIVE ? $username : strtolower($username); $result = $this->findUser($username, $password); if (is_array($result)) { diff --git a/app/Model/TaskLink.php b/app/Model/TaskLink.php index c712e5a8..85ad2737 100644 --- a/app/Model/TaskLink.php +++ b/app/Model/TaskLink.php @@ -50,7 +50,8 @@ class TaskLink extends Base Link::TABLE.'.label', Task::TABLE.'.title', Task::TABLE.'.is_active', - Task::TABLE.'.project_id' + Task::TABLE.'.project_id', + Task::TABLE.'.column_id' ) ->eq(self::TABLE.'.task_id', $task_id) ->join(Link::TABLE, 'id', 'link_id') diff --git a/app/Template/task/show.php b/app/Template/task/show.php index 1ff2ef43..60243537 100644 --- a/app/Template/task/show.php +++ b/app/Template/task/show.php @@ -1,7 +1,7 @@ <?= $this->render('task/details', array('task' => $task, 'project' => $project)) ?> <?= $this->render('task/time', array('task' => $task, 'values' => $values, 'date_format' => $date_format, 'date_formats' => $date_formats)) ?> <?= $this->render('task/show_description', array('task' => $task)) ?> -<?= $this->render('tasklink/show', array('task' => $task, 'links' => $links)) ?> +<?= $this->render('tasklink/show', array('task' => $task, 'links' => $links, 'columns_list' => $columns_list)) ?> <?= $this->render('subtask/show', array('task' => $task, 'subtasks' => $subtasks)) ?> <?= $this->render('task/timesheet', array('task' => $task)) ?> <?= $this->render('file/show', array('task' => $task, 'files' => $files)) ?> diff --git a/app/Template/tasklink/show.php b/app/Template/tasklink/show.php index ca4e4383..f759be5e 100644 --- a/app/Template/tasklink/show.php +++ b/app/Template/tasklink/show.php @@ -5,7 +5,8 @@ <table class="table-fixed" id="links"> <tr> <th class="column-30"><?= t('Label') ?></th> - <th class="column-60"><?= t('Task') ?></th> + <th class="column-40"><?= t('Task') ?></th> + <th class="column-20"><?= t('Column') ?></th> <?php if (! isset($not_editable)): ?> <th><?= t('Action') ?></th> <?php endif ?> @@ -22,6 +23,7 @@ $link['is_active'] ? '' : 'task-link-closed' ) ?> </td> + <td><?= $columns_list[$link['column_id']] ?></td> <td> <?= $this->a(t('Remove'), 'tasklink', 'confirm', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> </td> diff --git a/app/constants.php b/app/constants.php index 064e0211..39ab5470 100644 --- a/app/constants.php +++ b/app/constants.php @@ -36,6 +36,7 @@ defined('LDAP_USER_PATTERN') or define('LDAP_USER_PATTERN', ''); defined('LDAP_ACCOUNT_FULLNAME') or define('LDAP_ACCOUNT_FULLNAME', 'displayname'); defined('LDAP_ACCOUNT_EMAIL') or define('LDAP_ACCOUNT_EMAIL', 'mail'); defined('LDAP_ACCOUNT_ID') or define('LDAP_ACCOUNT_ID', ''); +defined('LDAP_USERNAME_CASE_SENSITIVE') or define('LDAP_USERNAME_CASE_SENSITIVE', false); // Google authentication defined('GOOGLE_AUTH') or define('GOOGLE_AUTH', false); diff --git a/assets/css/app.css b/assets/css/app.css index de7525ed..f1a383be 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -727,11 +727,6 @@ nav .active a { font-size: 0.95em; } -.filter-on { - font-weight: bold; - color: #333; -} - /* public board */ .public-board { margin-top: 5px; @@ -745,13 +740,14 @@ nav .active a { /* board table */ #board-container { - overflow-x: auto; + overflow-x: scroll; + padding-bottom: 150px; /* Space to avoid dropdown menu truncated */ } #board td, #board th { - min-width: 230px; - max-width: 230px; + min-width: 240px; + max-width: 240px; } #board th a { @@ -898,7 +894,7 @@ a.task-board-nobody { .task-board-icons span { opacity: 0.5; - margin-left: 5px; + margin-left: 2px; } .task-board-icons a:hover, diff --git a/assets/css/src/board.css b/assets/css/src/board.css index 00e0ad7c..52f871f7 100644 --- a/assets/css/src/board.css +++ b/assets/css/src/board.css @@ -3,11 +3,6 @@ font-size: 0.95em; } -.filter-on { - font-weight: bold; - color: #333; -} - /* public board */ .public-board { margin-top: 5px; @@ -21,13 +16,14 @@ /* board table */ #board-container { - overflow-x: auto; + overflow-x: scroll; + padding-bottom: 150px; /* Space to avoid dropdown menu truncated */ } #board td, #board th { - min-width: 230px; - max-width: 230px; + min-width: 240px; + max-width: 240px; } #board th a { diff --git a/assets/css/src/task.css b/assets/css/src/task.css index 7942d8d3..b7a5cb9c 100644 --- a/assets/css/src/task.css +++ b/assets/css/src/task.css @@ -97,7 +97,7 @@ a.task-board-nobody { .task-board-icons span { opacity: 0.5; - margin-left: 5px; + margin-left: 2px; } .task-board-icons a:hover, diff --git a/assets/js/app.js b/assets/js/app.js index d1cf810c..892f153d 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -148,9 +148,9 @@ Kanboard.SetStorageItem(d(),"expanded")});$(".filter-collapse-link").click(funct (Kanboard.GetStorageItem(d())||"expanded")?f():e()}function k(){$(".column").sortable({delay:300,distance:5,connectWith:".column",placeholder:"draggable-placeholder",stop:function(a,b){n(b.item.attr("data-task-id"),b.item.parent().attr("data-column-id"),b.item.index()+1,b.item.parent().attr("data-swimlane-id"))}});$("#board").on("click",".task-board-popover",a);$("#board").on("click",".task-board",function(){window.location=$(this).data("task-url")});$(".task-board-tooltip").tooltip({track:!1,position:{my:"left-20 top", at:"center bottom+9",using:function(a,b){$(this).css(a);var c=b.target.left+b.target.width/2-b.element.left-20;$("<div>").addClass("tooltip-arrow").addClass(b.vertical).addClass(0==c?"align-left":"align-right").appendTo(this)}},content:function(a){if(a=$(this).attr("data-href")){var b=this;$.get(a,function p(a){$(".ui-tooltip-content:visible").html(a);a=$(".ui-tooltip:visible");a.css({top:"",left:""});a.children(".tooltip-arrow").remove();var c=$(b).tooltip("option","position");c.of=$(b);a.position(c); $("#tooltip-subtasks a").not(".popover").click(function(a){a.preventDefault();a.stopPropagation();$(this).hasClass("popover-subtask-restriction")?(Kanboard.OpenPopover($(this).attr("href")),$(b).tooltip("close")):$.get($(this).attr("href"),p)})});return'<i class="fa fa-refresh fa-spin fa-2x"></i>'}}}).on("mouseenter",function(){var a=this;$(this).tooltip("open");$(".ui-tooltip").on("mouseleave",function(){$(a).tooltip("close")})}).on("mouseleave focusout",function(a){a.stopImmediatePropagation(); -var b=this;setTimeout(function(){$(".ui-tooltip:hover").length||$(b).tooltip("close")},100)});var b=parseInt($("#board").attr("data-check-interval"));0<b&&(l=window.setInterval(m,1E3*b))}function n(a,b,c,d){clearInterval(l);$.ajax({cache:!1,url:$("#board").attr("data-save-url"),contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({task_id:a,column_id:b,swimlane_id:d,position:c}),success:function(a){$("#board").remove();$("#main").append(a);Kanboard.InitAfterAjax();k();h(); -g()}})}function m(){Kanboard.IsVisible()&&$.ajax({cache:!1,url:$("#board").attr("data-check-url"),statusCode:{200:function(a){$("#board").remove();$("#main").append(a);Kanboard.InitAfterAjax();clearInterval(l);k();h();g()}}})}function h(){var a=$("#form-user_id").val(),b=$("#form-category_id").val(),c=$("#more-filters option[value=filter-due-date]").is(":selected"),d=$("#more-filters option[value=filter-recent]").is(":selected"),e=$("#board").data("project-id");$("[data-task-id]").each(function(e, -g){var k=g.getAttribute("data-owner-id"),f=g.getAttribute("data-due-date"),m=g.getAttribute("data-category-id"),h=g.matches(".task-board-recent");g.style.display=k!=a&&-1!=a?"none":"block";!c||""!=f&&"0"!=f||(g.style.display="none");m!=b&&-1!=b&&(g.style.display="none");d&&!h&&(g.style.display="none")});Kanboard.SetStorageItem("board_filter_"+e+"_form-user_id",a);Kanboard.SetStorageItem("board_filter_"+e+"_form-category_id",b);Kanboard.SetStorageItem("board_filter_"+e+"_filter-due-date",~~c);Kanboard.SetStorageItem("board_filter_"+ +var b=this;setTimeout(function(){$(".ui-tooltip:hover").length||$(b).tooltip("close")},100)});var b=parseInt($("#board").attr("data-check-interval"));0<b&&(l=window.setInterval(m,1E3*b))}function n(a,b,c,d){clearInterval(l);$.ajax({cache:!1,url:$("#board").attr("data-save-url"),contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({task_id:a,column_id:b,swimlane_id:d,position:c}),success:function(a){$("#board-container").remove();$("#main").append(a);Kanboard.InitAfterAjax(); +k();h();g()}})}function m(){Kanboard.IsVisible()&&$.ajax({cache:!1,url:$("#board").attr("data-check-url"),statusCode:{200:function(a){$("#board-container").remove();$("#main").append(a);Kanboard.InitAfterAjax();clearInterval(l);k();h();g()}}})}function h(){var a=$("#form-user_id").val(),b=$("#form-category_id").val(),c=$("#more-filters option[value=filter-due-date]").is(":selected"),d=$("#more-filters option[value=filter-recent]").is(":selected"),e=$("#board").data("project-id");$("[data-task-id]").each(function(e, +g){var k=g.getAttribute("data-owner-id"),f=g.getAttribute("data-due-date"),m=g.getAttribute("data-category-id"),h=$(g).hasClass("task-board-recent");g.style.display=k!=a&&-1!=a?"none":"block";!c||""!=f&&"0"!=f||(g.style.display="none");m!=b&&-1!=b&&(g.style.display="none");d&&!h&&(g.style.display="none")});Kanboard.SetStorageItem("board_filter_"+e+"_form-user_id",a);Kanboard.SetStorageItem("board_filter_"+e+"_form-category_id",b);Kanboard.SetStorageItem("board_filter_"+e+"_filter-due-date",~~c);Kanboard.SetStorageItem("board_filter_"+ e+"_filter-recent",~~d)}function q(){var a=$("#board").data("project-id");$("#form-user_id").chosen({width:"180px"});$("#form-category_id").chosen({width:"200px"});$("#more-filters").chosen({width:"30%"});$(".apply-filters").change(function(a){h()});$("#form-user_id").val(Kanboard.GetStorageItem("board_filter_"+a+"_form-user_id")||-1);$("#form-user_id").trigger("chosen:updated");$("#form-category_id").val(Kanboard.GetStorageItem("board_filter_"+a+"_form-category_id")||-1);$("#form-category_id").trigger("chosen:updated"); +Kanboard.GetStorageItem("board_filter_"+a+"_filter-due-date")&&$("#more-filters option[value=filter-due-date]").attr("selected",!0);+Kanboard.GetStorageItem("board_filter_"+a+"_filter-recent")&&$("#more-filters option[value=filter-recent]").attr("selected",!0);$("#more-filters").trigger("chosen:updated");h()}var l=null;jQuery(document).ready(function(){Kanboard.Exists("board")&&(k(),q(),b(),c())})}(); Kanboard.Calendar=function(){function a(a){var b=$("#calendar").data("save-url")||$("#user-calendar").data("save-url");$.ajax({cache:!1,url:b,contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({task_id:a.id,date_due:a.start.format()})})}function c(){var a=$("#user-calendar"),b=a.data("check-url"),c={start:a.fullCalendar("getView").start.format(),end:a.fullCalendar("getView").end.format(),user_id:a.data("user-id")},d;for(d in c)b+="&"+d+"="+c[d];$.getJSON(b,function(b){a.fullCalendar("removeEvents"); diff --git a/assets/js/src/board.js b/assets/js/src/board.js index 05c4b90a..75c44f2e 100644 --- a/assets/js/src/board.js +++ b/assets/js/src/board.js @@ -235,7 +235,7 @@ Kanboard.Board = (function() { "position": position }), success: function(data) { - $("#board").remove(); + $("#board-container").remove(); $("#main").append(data); Kanboard.InitAfterAjax(); board_load_events(); @@ -254,7 +254,7 @@ Kanboard.Board = (function() { url: $("#board").attr("data-check-url"), statusCode: { 200: function(data) { - $("#board").remove(); + $("#board-container").remove(); $("#main").append(data); Kanboard.InitAfterAjax(); board_unload_events(); @@ -281,7 +281,7 @@ Kanboard.Board = (function() { var ownerId = item.getAttribute("data-owner-id"); var dueDate = item.getAttribute("data-due-date"); var categoryId = item.getAttribute("data-category-id"); - var recent = item.matches(".task-board-recent"); + var recent = $(item).hasClass("task-board-recent"); if (ownerId != selectedUserId && selectedUserId != -1) { item.style.display = "none"; diff --git a/config.default.php b/config.default.php index c6b4599b..ab3e3b8c 100644 --- a/config.default.php +++ b/config.default.php @@ -85,6 +85,10 @@ define('LDAP_ACCOUNT_EMAIL', 'mail'); // Example for OpenLDAP: 'uid' define('LDAP_ACCOUNT_ID', 'samaccountname'); +// By default Kanboard lowercase the ldap username to avoid duplicate users (the database is case sensitive) +// Set to true if you want to preserve the case +define('LDAP_USERNAME_CASE_SENSITIVE', false); + // Enable/disable Google authentication define('GOOGLE_AUTH', false); diff --git a/docs/ldap-authentication.markdown b/docs/ldap-authentication.markdown index 0428d8e0..2428194d 100644 --- a/docs/ldap-authentication.markdown +++ b/docs/ldap-authentication.markdown @@ -76,6 +76,15 @@ define('LDAP_ACCOUNT_FULLNAME', 'displayname'); // Name of an attribute of the user account object which should be used as the email of the user. define('LDAP_ACCOUNT_EMAIL', 'mail'); + +// Name of an attribute of the user account object which should be used as the id of the user. +// Example for ActiveDirectory: 'samaccountname' +// Example for OpenLDAP: 'uid' +define('LDAP_ACCOUNT_ID', 'samaccountname'); + +// By default Kanboard lowercase the ldap username to avoid duplicate users (the database is case sensitive) +// Set to true if you want to preserve the case +define('LDAP_USERNAME_CASE_SENSITIVE', false); ``` ### LDAP bind type |