Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5b65dfa1f2 | |||
| 1b932127d8 |
@@ -38,12 +38,40 @@
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wso-table td {
|
/* One project row: id (+ config dropdown) / title / owner on the left, move control on the right,
|
||||||
vertical-align: middle;
|
separated by a light horizontal line. */
|
||||||
|
.wso-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 6px 2px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wso-row-main {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wso-id {
|
||||||
|
margin-right: 8px;
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wso-title {
|
||||||
|
margin-right: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wso-owner {
|
||||||
|
color: #999;
|
||||||
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wso-move {
|
.wso-move {
|
||||||
width: 220px;
|
flex: 0 0 auto;
|
||||||
|
margin-left: 12px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
Asset/js/workspaceorg.js
Normal file
26
Asset/js/workspaceorg.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* WorkspaceOrg -- submit the per-project "move to workspace" form when its dropdown changes.
|
||||||
|
*
|
||||||
|
* Kanboard's default CSP is `default-src 'self'` (no 'unsafe-inline' for scripts), so an inline
|
||||||
|
* onchange="" attribute is blocked and does nothing. The change handler must live in an external
|
||||||
|
* script served from 'self', which is what this file is.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
var selects = document.querySelectorAll(".wso-move-form select");
|
||||||
|
|
||||||
|
for (var i = 0; i < selects.length; i++) {
|
||||||
|
selects[i].addEventListener("change", function () {
|
||||||
|
this.form.submit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", init);
|
||||||
|
} else {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -124,8 +124,13 @@ class WorkspaceOrgHelper extends Base
|
|||||||
|
|
||||||
$groups[self::DEFAULT_WORKSPACE] = array();
|
$groups[self::DEFAULT_WORKSPACE] = array();
|
||||||
|
|
||||||
foreach ($this->projectUserRoleModel->getActiveProjectsByUser($this->uid()) as $project_id => $project_name) {
|
// Full project rows (id, name, owner_name, is_active, ...) for the user's active projects,
|
||||||
$groups[$this->workspaceOf($project_id)][] = array('id' => (int) $project_id, 'name' => $project_name);
|
// the same data source the native "My projects" dashboard uses.
|
||||||
|
$ids = $this->projectPermissionModel->getActiveProjectIds($this->uid());
|
||||||
|
$projects = empty($ids) ? array() : $this->projectModel->getQueryColumnStats($ids)->findAll();
|
||||||
|
|
||||||
|
foreach ($projects as $project) {
|
||||||
|
$groups[$this->workspaceOf($project['id'])][] = $project;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($groups as &$list) {
|
foreach ($groups as &$list) {
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ class Plugin extends Base
|
|||||||
$this->hook->on('template:layout:css', array(
|
$this->hook->on('template:layout:css', array(
|
||||||
'template' => 'plugins/WorkspaceOrg/Asset/css/workspaceorg.css',
|
'template' => 'plugins/WorkspaceOrg/Asset/css/workspaceorg.css',
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// Submits the inline "move to workspace" select on change. Must be an external script:
|
||||||
|
// Kanboard's CSP (default-src 'self') blocks inline onchange handlers.
|
||||||
|
$this->hook->on('template:layout:js', array(
|
||||||
|
'template' => 'plugins/WorkspaceOrg/Asset/js/workspaceorg.js',
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHelpers()
|
public function getHelpers()
|
||||||
@@ -53,7 +59,7 @@ class Plugin extends Base
|
|||||||
|
|
||||||
public function getPluginVersion()
|
public function getPluginVersion()
|
||||||
{
|
{
|
||||||
return '0.1.0';
|
return '0.2.1';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPluginHomepage()
|
public function getPluginHomepage()
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ Two people can file the same shared project differently, and neither sees the ot
|
|||||||
|
|
||||||
- Adds a **My workspaces** entry to the dashboard sidebar (next to Overview / My projects /
|
- Adds a **My workspaces** entry to the dashboard sidebar (next to Overview / My projects /
|
||||||
My tasks / My subtasks). Visible to every logged-in user -- no admin rights needed.
|
My tasks / My subtasks). Visible to every logged-in user -- no admin rights needed.
|
||||||
- That page lists your projects **grouped by workspace**, and lets you:
|
- That page lists your projects **grouped by workspace** (each heading shows the project count,
|
||||||
|
e.g. `POLI/UPE (3)`), with each row showing the project **id**, **title** and **owner**, plus a
|
||||||
|
small id dropdown with a "Configure this project" shortcut. From it you can:
|
||||||
- **add / rename / remove** workspaces (each via a small modal, like Kanboard's Tags page);
|
- **add / rename / remove** workspaces (each via a small modal, like Kanboard's Tags page);
|
||||||
- **move a project** to another workspace with an inline dropdown on its row.
|
- **move a project** to another workspace with an inline dropdown on its row.
|
||||||
- Shows a **`[Workspace]`** badge before the project title on the dashboard overview, the
|
- Shows a **`[Workspace]`** badge before the project title on the dashboard overview, the
|
||||||
@@ -53,7 +55,7 @@ build step and no database migration. Reload, then open **My workspaces** from t
|
|||||||
|
|
||||||
AGPL-3.0. See LICENSE.
|
AGPL-3.0. See LICENSE.
|
||||||
|
|
||||||
## More Kanboard plugins by Ruben (drbeco)
|
## More Kanboard plugins by Dr. Bèco
|
||||||
|
|
||||||
All free and AGPL-3.0, at [code.beco.cc](https://code.beco.cc/beco):
|
All free and AGPL-3.0, at [code.beco.cc](https://code.beco.cc/beco):
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<?php foreach ($groups as $workspace => $projects): ?>
|
<?php foreach ($groups as $workspace => $projects): ?>
|
||||||
<div class="wso-group">
|
<div class="wso-group">
|
||||||
<h3 class="wso-group-title">
|
<h3 class="wso-group-title">
|
||||||
<?= $this->text->e($workspace) ?>
|
<?= $this->text->e($workspace) ?> (<?= count($projects) ?>)
|
||||||
<?php if ($workspace !== $default): ?>
|
<?php if ($workspace !== $default): ?>
|
||||||
<span class="wso-group-actions">
|
<span class="wso-group-actions">
|
||||||
<?= $this->modal->medium('edit', t('Rename'), 'WorkspaceOrgController', 'edit', array('plugin' => 'WorkspaceOrg', 'name' => $workspace)) ?>
|
<?= $this->modal->medium('edit', t('Rename'), 'WorkspaceOrgController', 'edit', array('plugin' => 'WorkspaceOrg', 'name' => $workspace)) ?>
|
||||||
@@ -22,27 +22,45 @@
|
|||||||
<?php if (empty($projects)): ?>
|
<?php if (empty($projects)): ?>
|
||||||
<p class="wso-empty"><?= t('(no projects yet)') ?></p>
|
<p class="wso-empty"><?= t('(no projects yet)') ?></p>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<table class="table-striped wso-table">
|
|
||||||
<?php foreach ($projects as $project): ?>
|
<?php foreach ($projects as $project): ?>
|
||||||
<tr>
|
<div class="wso-row">
|
||||||
<td class="wso-project">
|
<div class="wso-row-main">
|
||||||
|
<?php if ($this->user->hasProjectAccess('ProjectViewController', 'show', $project['id'])): ?>
|
||||||
|
<span class="dropdown wso-id">
|
||||||
|
<a href="#" class="dropdown-menu"><strong>#<?= (int) $project['id'] ?></strong> <i class="fa fa-caret-down"></i></a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<?= $this->url->link(t('Configure this project'), 'ProjectViewController', 'show', array('project_id' => $project['id'])) ?>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</span>
|
||||||
|
<?php else: ?>
|
||||||
|
<strong class="wso-id">#<?= (int) $project['id'] ?></strong>
|
||||||
|
<?php endif ?>
|
||||||
|
|
||||||
|
<span class="wso-title">
|
||||||
<?= $this->url->link($this->text->e($project['name']), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?>
|
<?= $this->url->link($this->text->e($project['name']), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?>
|
||||||
</td>
|
</span>
|
||||||
<td class="wso-move">
|
|
||||||
|
<?php if (! empty($project['owner_id'])): ?>
|
||||||
|
<span class="wso-owner"><?= $this->text->e($project['owner_name'] ?: $project['owner_username']) ?></span>
|
||||||
|
<?php endif ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wso-move">
|
||||||
<form method="post" class="wso-move-form" action="<?= $this->url->href('WorkspaceOrgController', 'assign', array('plugin' => 'WorkspaceOrg')) ?>">
|
<form method="post" class="wso-move-form" action="<?= $this->url->href('WorkspaceOrgController', 'assign', array('plugin' => 'WorkspaceOrg')) ?>">
|
||||||
<?= $this->form->csrf() ?>
|
<?= $this->form->csrf() ?>
|
||||||
<input type="hidden" name="project_id" value="<?= (int) $project['id'] ?>">
|
<input type="hidden" name="project_id" value="<?= (int) $project['id'] ?>">
|
||||||
<select name="workspace" onchange="this.form.submit()">
|
<select name="workspace">
|
||||||
<?php foreach ($options as $option): ?>
|
<?php foreach ($options as $option): ?>
|
||||||
<option value="<?= $this->text->e($option) ?>"<?= $option === $workspace ? ' selected="selected"' : '' ?>><?= $this->text->e($option) ?></option>
|
<option value="<?= $this->text->e($option) ?>"<?= $option === $workspace ? ' selected="selected"' : '' ?>><?= $this->text->e($option) ?></option>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</select>
|
</select>
|
||||||
<noscript><button type="submit" class="btn btn-blue"><?= t('Move') ?></button></noscript>
|
<noscript><button type="submit" class="btn btn-blue"><?= t('Move') ?></button></noscript>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
</div>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</table>
|
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user