Rewrite component to change user/group role

This commit is contained in:
Frederic Guillot 2016-12-09 20:35:40 -05:00
parent 86d04bc0ef
commit 67d01951f5
13 changed files with 233 additions and 144 deletions

View File

@ -5,6 +5,8 @@ New features:
Improvements:
* Rewrite ui component that change user/group roles
Bug fixes:
* Fix wrong controller name on project activity page when using filters

View File

@ -132,7 +132,7 @@ class ProjectPermissionController extends BaseController
if (! empty($project) && ! empty($values) && $this->projectUserRoleModel->changeUserRole($project['id'], $values['id'], $values['role'])) {
$this->response->json(array('status' => 'ok'));
} else {
$this->response->json(array('status' => 'error'));
$this->response->json(array('status' => 'error'), 500);
}
}

View File

@ -0,0 +1,61 @@
<div class="page-header">
<h2><?= t('Allowed Groups') ?></h2>
</div>
<?php if (empty($groups)): ?>
<div class="alert"><?= t('No group have been allowed specifically.') ?></div>
<?php else: ?>
<table class="table-scrolling">
<tr>
<th class="column-50"><?= t('Group') ?></th>
<th><?= t('Role') ?></th>
<?php if ($project['is_private'] == 0): ?>
<th class="column-15"><?= t('Actions') ?></th>
<?php endif ?>
</tr>
<?php foreach ($groups as $group): ?>
<tr>
<td><?= $this->text->e($group['name']) ?></td>
<td>
<?= $this->app->component('project-select-role', array(
'roles' => $roles,
'role' => $group['role'],
'id' => $group['id'],
'url' => $this->url->to('ProjectPermissionController', 'changeGroupRole', array('project_id' => $project['id'])),
)) ?>
</td>
<td>
<i class="fa fa-trash-o" aria-hidden="true"></i>
<?= $this->url->link(t('Remove'), 'ProjectPermissionController', 'removeGroup', array('project_id' => $project['id'], 'group_id' => $group['id']), true) ?>
</td>
</tr>
<?php endforeach ?>
</table>
<?php endif ?>
<?php if ($project['is_private'] == 0): ?>
<div class="listing">
<form method="post" action="<?= $this->url->href('ProjectPermissionController', 'addGroup', array('project_id' => $project['id'])) ?>" autocomplete="off" class="form-inline">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
<?= $this->form->hidden('group_id', $values) ?>
<?= $this->form->hidden('external_id', $values) ?>
<?= $this->form->label(t('Group Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array(
'required',
'placeholder="'.t('Enter group name...').'"',
'title="'.t('Enter group name...').'"',
'data-dst-field="group_id"',
'data-dst-extra-field="external_id"',
'data-search-url="'.$this->url->href('GroupAjaxController', 'autocomplete').'"',
),
'autocomplete') ?>
<?= $this->form->select('role', $roles, $values, $errors) ?>
<button type="submit" class="btn btn-blue"><?= t('Add') ?></button>
</form>
</div>
<?php endif ?>

View File

@ -5,125 +5,21 @@
<?php if ($project['is_everybody_allowed']): ?>
<div class="alert"><?= t('Everybody have access to this project.') ?></div>
<?php else: ?>
<?= $this->render('project_permission/users', array(
'project' => $project,
'roles' => $roles,
'users' => $users,
'errors' => $errors,
'values' => $values,
)) ?>
<?php if (empty($users)): ?>
<div class="alert"><?= t('No user have been allowed specifically.') ?></div>
<?php else: ?>
<table class="table-scrolling">
<tr>
<th class="column-50"><?= t('User') ?></th>
<th><?= t('Role') ?></th>
<?php if ($project['is_private'] == 0): ?>
<th class="column-15"><?= t('Actions') ?></th>
<?php endif ?>
</tr>
<?php foreach ($users as $user): ?>
<tr>
<td><?= $this->text->e($user['name'] ?: $user['username']) ?></td>
<td>
<?= $this->form->select(
'role-'.$user['id'],
$roles,
array('role-'.$user['id'] => $user['role']),
array(),
array('data-url="'.$this->url->href('ProjectPermissionController', 'changeUserRole', array('project_id' => $project['id'])).'"', 'data-id="'.$user['id'].'"'),
'project-change-role'
) ?>
</td>
<td>
<?= $this->url->link(t('Remove'), 'ProjectPermissionController', 'removeUser', array('project_id' => $project['id'], 'user_id' => $user['id']), true) ?>
</td>
</tr>
<?php endforeach ?>
</table>
<?php endif ?>
<?php if ($project['is_private'] == 0): ?>
<div class="listing">
<form method="post" action="<?= $this->url->href('ProjectPermissionController', 'addUser', array('project_id' => $project['id'])) ?>" autocomplete="off" class="form-inline">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
<?= $this->form->hidden('user_id', $values) ?>
<?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array(
'required',
'placeholder="'.t('Enter user name...').'"',
'title="'.t('Enter user name...').'"',
'data-dst-field="user_id"',
'data-search-url="'.$this->url->href('UserAjaxController', 'autocomplete').'"',
),
'autocomplete') ?>
<?= $this->form->select('role', $roles, $values, $errors) ?>
<button type="submit" class="btn btn-blue"><?= t('Add') ?></button>
</form>
</div>
<?php endif ?>
<div class="page-header">
<h2><?= t('Allowed Groups') ?></h2>
</div>
<?php if (empty($groups)): ?>
<div class="alert"><?= t('No group have been allowed specifically.') ?></div>
<?php else: ?>
<table class="table-scrolling">
<tr>
<th class="column-50"><?= t('Group') ?></th>
<th><?= t('Role') ?></th>
<?php if ($project['is_private'] == 0): ?>
<th class="column-15"><?= t('Actions') ?></th>
<?php endif ?>
</tr>
<?php foreach ($groups as $group): ?>
<tr>
<td><?= $this->text->e($group['name']) ?></td>
<td>
<?= $this->form->select(
'role-'.$group['id'],
$roles,
array('role-'.$group['id'] => $group['role']),
array(),
array('data-url="'.$this->url->href('ProjectPermissionController', 'changeGroupRole', array('project_id' => $project['id'])).'"', 'data-id="'.$group['id'].'"'),
'project-change-role'
) ?>
</td>
<td>
<?= $this->url->link(t('Remove'), 'ProjectPermissionController', 'removeGroup', array('project_id' => $project['id'], 'group_id' => $group['id']), true) ?>
</td>
</tr>
<?php endforeach ?>
</table>
<?php endif ?>
<?php if ($project['is_private'] == 0): ?>
<div class="listing">
<form method="post" action="<?= $this->url->href('ProjectPermissionController', 'addGroup', array('project_id' => $project['id'])) ?>" autocomplete="off" class="form-inline">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
<?= $this->form->hidden('group_id', $values) ?>
<?= $this->form->hidden('external_id', $values) ?>
<?= $this->form->label(t('Group Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array(
'required',
'placeholder="'.t('Enter group name...').'"',
'title="'.t('Enter group name...').'"',
'data-dst-field="group_id"',
'data-dst-extra-field="external_id"',
'data-search-url="'.$this->url->href('GroupAjaxController', 'autocomplete').'"',
),
'autocomplete') ?>
<?= $this->form->select('role', $roles, $values, $errors) ?>
<button type="submit" class="btn btn-blue"><?= t('Add') ?></button>
</form>
</div>
<?php endif ?>
<?= $this->render('project_permission/groups', array(
'project' => $project,
'roles' => $roles,
'groups' => $groups,
'errors' => $errors,
'values' => $values,
)) ?>
<?php endif ?>
<?php if ($project['is_private'] == 0): ?>

View File

@ -0,0 +1,54 @@
<?php if (empty($users)): ?>
<div class="alert"><?= t('No user have been allowed specifically.') ?></div>
<?php else: ?>
<table class="table-scrolling">
<tr>
<th class="column-50"><?= t('User') ?></th>
<th><?= t('Role') ?></th>
<?php if ($project['is_private'] == 0): ?>
<th class="column-15"><?= t('Actions') ?></th>
<?php endif ?>
</tr>
<?php foreach ($users as $user): ?>
<tr>
<td><?= $this->text->e($user['name'] ?: $user['username']) ?></td>
<td>
<?= $this->app->component('project-select-role', array(
'roles' => $roles,
'role' => $user['role'],
'id' => $user['id'],
'url' => $this->url->to('ProjectPermissionController', 'changeUserRole', array('project_id' => $project['id'])),
)) ?>
</td>
<td>
<i class="fa fa-trash-o" aria-hidden="true"></i>
<?= $this->url->link(t('Remove'), 'ProjectPermissionController', 'removeUser', array('project_id' => $project['id'], 'user_id' => $user['id']), true) ?>
</td>
</tr>
<?php endforeach ?>
</table>
<?php endif ?>
<?php if ($project['is_private'] == 0): ?>
<div class="listing">
<form method="post" action="<?= $this->url->href('ProjectPermissionController', 'addUser', array('project_id' => $project['id'])) ?>" autocomplete="off" class="form-inline">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
<?= $this->form->hidden('user_id', $values) ?>
<?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array(
'required',
'placeholder="'.t('Enter user name...').'"',
'title="'.t('Enter user name...').'"',
'data-dst-field="user_id"',
'data-search-url="'.$this->url->href('UserAjaxController', 'autocomplete').'"',
),
'autocomplete') ?>
<?= $this->form->select('role', $roles, $values, $errors) ?>
<button type="submit" class="btn btn-blue"><?= t('Add') ?></button>
</form>
</div>
<?php endif ?>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,72 @@
KB.component('project-select-role', function (containerElement, options) {
var isLoading = false;
var isSuccess = false;
var isError = false;
var componentElement;
function onChange(element) {
isLoading = true;
options.role = element.value;
replaceComponentElement();
updateRole();
}
function updateRole() {
KB.http.postJson(options.url, {
id: options.id,
role: options.role
}).success(function () {
isLoading = false;
isSuccess = true;
replaceComponentElement();
}).error(function () {
isLoading = false;
isSuccess = false;
isError = true;
replaceComponentElement();
});
}
function replaceComponentElement() {
KB.dom(componentElement).remove();
componentElement = buildComponentElement();
containerElement.appendChild(componentElement);
}
function buildComponentElement() {
var roles = [];
var container = KB.dom('div');
for (var role in options.roles) {
if (options.roles.hasOwnProperty(role)) {
var item = {value: role, text: options.roles[role]};
if (options.role === role) {
item.selected = 'selected';
}
roles.push(item);
}
}
container.add(KB.dom('select').change(onChange).for('option', roles).build());
if (isLoading) {
container.text(' ');
container.add(KB.dom('i').attr('class', 'fa fa-spinner fa-pulse fa-fw').build());
} else if (isSuccess) {
container.text(' ');
container.add(KB.dom('i').attr('class', 'fa fa-check fa-fw icon-fade-out icon-success').build());
} else if (isError) {
container.text(' ');
container.add(KB.dom('i').attr('class', 'fa fa-check fa-fw icon-fade-out icon-error').build());
}
return container.build();
}
this.render = function () {
componentElement = buildComponentElement();
containerElement.appendChild(componentElement);
};
});

View File

@ -122,11 +122,11 @@ KB.component('task-move-position', function (containerElement, options) {
var columnId = getColumnId();
var container = KB.dom('div').attr('id', 'form-tasks');
options.board.forEach(function(swimlane) {
options.board.forEach(function (swimlane) {
if (swimlaneId === swimlane.id) {
swimlane.columns.forEach(function(column) {
swimlane.columns.forEach(function (column) {
if (columnId === column.id) {
column.tasks.forEach(function(task) {
column.tasks.forEach(function (task) {
tasks.push({'value': task.position, 'text': '#' + task.id + ' - ' + task.title});
});
}

View File

@ -1,19 +0,0 @@
Kanboard.ProjectPermission = function(app) {
this.app = app;
};
Kanboard.ProjectPermission.prototype.listen = function() {
$('.project-change-role').on('change', function () {
$.ajax({
cache: false,
url: $(this).data('url'),
contentType: "application/json",
type: "POST",
processData: false,
data: JSON.stringify({
"id": $(this).data('id'),
"role": $(this).val()
})
});
});
};

17
assets/sass/_icon.sass Normal file
View File

@ -0,0 +1,17 @@
@import variables
.icon-success
color: icon-color('success')
.icon-error
color: icon-color('error')
.icon-fade-out
opacity: 1
animation: icon-fadeout 5s linear forwards
@keyframes icon-fadeout
0%
opacity: 1
100%
opacity: 0

View File

@ -19,6 +19,8 @@ $button-hover-border-colors: ('default': #bbb, 'red': #b0281a, 'blue': #3079ed)
$font-sizes: ('normal': 1.0em, 'tiny': 0.7em, 'small': 0.8em, 'compact': 0.9em, 'medium': 1.2em, 'large': 1.4em, 'xlarge': 1.6em, 'title': 1.5em)
$icon-colors: ('success': #468847, 'error': #b94a48)
$text-font: 'Helvetica Neue', Helvetica, Arial, sans-serif
$board-task-limit-color: #DF5353
@ -34,6 +36,9 @@ $board-task-limit-color: #DF5353
@function bg-color($key: 'primary')
@return map-get($background-colors, $key)
@function icon-color($key)
@return map-get($icon-colors, $key)
@function alert-color($key)
@return map-get($alert-colors, $key)

View File

@ -6,6 +6,7 @@
@import table_drag_and_drop
@import form
@import input_addon
@import icon
@import alert
@import button
@import tooltip