move select via external JS (CSP fix); rows show id/owner/config + ws counts
This commit is contained in:
@@ -38,12 +38,40 @@
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.wso-table td {
|
||||
vertical-align: middle;
|
||||
/* One project row: id (+ config dropdown) / title / owner on the left, move control on the right,
|
||||
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 {
|
||||
width: 220px;
|
||||
flex: 0 0 auto;
|
||||
margin-left: 12px;
|
||||
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();
|
||||
|
||||
foreach ($this->projectUserRoleModel->getActiveProjectsByUser($this->uid()) as $project_id => $project_name) {
|
||||
$groups[$this->workspaceOf($project_id)][] = array('id' => (int) $project_id, 'name' => $project_name);
|
||||
// Full project rows (id, name, owner_name, is_active, ...) for the user's active projects,
|
||||
// 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) {
|
||||
|
||||
@@ -27,6 +27,12 @@ class Plugin extends Base
|
||||
$this->hook->on('template:layout:css', array(
|
||||
'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()
|
||||
@@ -53,7 +59,7 @@ class Plugin extends Base
|
||||
|
||||
public function getPluginVersion()
|
||||
{
|
||||
return '0.1.0';
|
||||
return '0.2.0';
|
||||
}
|
||||
|
||||
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 /
|
||||
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);
|
||||
- **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
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<?php foreach ($groups as $workspace => $projects): ?>
|
||||
<div class="wso-group">
|
||||
<h3 class="wso-group-title">
|
||||
<?= $this->text->e($workspace) ?>
|
||||
<?= $this->text->e($workspace) ?> (<?= count($projects) ?>)
|
||||
<?php if ($workspace !== $default): ?>
|
||||
<span class="wso-group-actions">
|
||||
<?= $this->modal->medium('edit', t('Rename'), 'WorkspaceOrgController', 'edit', array('plugin' => 'WorkspaceOrg', 'name' => $workspace)) ?>
|
||||
@@ -22,27 +22,45 @@
|
||||
<?php if (empty($projects)): ?>
|
||||
<p class="wso-empty"><?= t('(no projects yet)') ?></p>
|
||||
<?php else: ?>
|
||||
<table class="table-striped wso-table">
|
||||
<?php foreach ($projects as $project): ?>
|
||||
<tr>
|
||||
<td class="wso-project">
|
||||
<?php foreach ($projects as $project): ?>
|
||||
<div class="wso-row">
|
||||
<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'])) ?>
|
||||
</td>
|
||||
<td class="wso-move">
|
||||
<form method="post" class="wso-move-form" action="<?= $this->url->href('WorkspaceOrgController', 'assign', array('plugin' => 'WorkspaceOrg')) ?>">
|
||||
<?= $this->form->csrf() ?>
|
||||
<input type="hidden" name="project_id" value="<?= (int) $project['id'] ?>">
|
||||
<select name="workspace" onchange="this.form.submit()">
|
||||
<?php foreach ($options as $option): ?>
|
||||
<option value="<?= $this->text->e($option) ?>"<?= $option === $workspace ? ' selected="selected"' : '' ?>><?= $this->text->e($option) ?></option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
<noscript><button type="submit" class="btn btn-blue"><?= t('Move') ?></button></noscript>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</table>
|
||||
</span>
|
||||
|
||||
<?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')) ?>">
|
||||
<?= $this->form->csrf() ?>
|
||||
<input type="hidden" name="project_id" value="<?= (int) $project['id'] ?>">
|
||||
<select name="workspace">
|
||||
<?php foreach ($options as $option): ?>
|
||||
<option value="<?= $this->text->e($option) ?>"<?= $option === $workspace ? ' selected="selected"' : '' ?>><?= $this->text->e($option) ?></option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
<noscript><button type="submit" class="btn btn-blue"><?= t('Move') ?></button></noscript>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
|
||||
Reference in New Issue
Block a user