Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EZP-28493: Interface improvements when assigning roles to user / groups #170

Merged
merged 1 commit into from
Dec 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 43 additions & 45 deletions src/bundle/Controller/RoleAssignmentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
use eZ\Publish\API\Repository\RoleService;
use eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation;
use eZ\Publish\API\Repository\Values\User\Limitation\SectionLimitation;
use eZ\Publish\API\Repository\Values\User\Limitation\SubtreeLimitation;
use eZ\Publish\API\Repository\Values\User\Role;
Expand Down Expand Up @@ -85,55 +86,17 @@ public function listAction(Role $role): Response

public function createAction(Request $request, Role $role): Response
{
$form = $this->formFactory->createRoleAssignment(
new RoleAssignmentCreateData()
);
$form = $this->formFactory->createRoleAssignment(new RoleAssignmentCreateData());
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
if ($form->isSubmitted()) {
$result = $this->submitHandler->handle($form, function (RoleAssignmentCreateData $data) use ($role) {
$users = $data->getUsers();
$groups = $data->getGroups();
$sections = $data->getSections();
$locations = $data->getLocations();

$limitations = [];

if (empty($sections) && empty($locations)) {
$limitations[] = null;
} else {
if (!empty($sections)) {
$limitation = new SectionLimitation();

foreach ($sections as $section) {
$limitation->limitationValues[] = $section->id;
}

$limitations[] = $limitation;
}

if (!empty($locations)) {
$limitation = new SubtreeLimitation();

foreach ($locations as $location) {
$limitation->limitationValues[] = $location->pathString;
}

$limitations[] = $limitation;
foreach ($this->createLimitations($data) as $limitation) {
foreach ($data->getUsers() as $user) {
$this->roleService->assignRoleToUser($role, $user, $limitation);
}
}

foreach ($limitations as $limitation) {
if (!empty($users)) {
foreach ($users as $user) {
$this->roleService->assignRoleToUser($role, $user, $limitation);
}
}

if (!empty($groups)) {
foreach ($groups as $group) {
$this->roleService->assignRoleToUserGroup($role, $group, $limitation);
}
foreach ($data->getGroups() as $group) {
$this->roleService->assignRoleToUserGroup($role, $group, $limitation);
}
}

Expand Down Expand Up @@ -261,4 +224,39 @@ private function getRoleAssignmentsNumbers(array $roleAssignments): array

return array_combine($roleAssignmentsNumbers, array_fill_keys($roleAssignmentsNumbers, false));
}

/**
* @param RoleAssignmentCreateData $data
*
* @return RoleLimitation[]
*/
private function createLimitations(RoleAssignmentCreateData $data): array
{
$limitations = [];
switch ($data->getLimitationType()) {
case RoleAssignmentCreateData::LIMITATION_TYPE_LOCATION:
$limitation = new SubtreeLimitation();

foreach ($data->getLocations() as $location) {
$limitation->limitationValues[] = $location->pathString;
}

$limitations[] = $limitation;
break;
case RoleAssignmentCreateData::LIMITATION_TYPE_SECTION:
$limitation = new SectionLimitation();

foreach ($data->getSections() as $section) {
$limitation->limitationValues[] = $section->id;
}

$limitations[] = $limitation;
break;
case RoleAssignmentCreateData::LIMITATION_TYPE_NONE:
$limitations[] = null; // this acts as "no limitations"
break;
}

return $limitations;
}
}
43 changes: 28 additions & 15 deletions src/bundle/Resources/public/js/scripts/admin.role_assignment.add.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
(function () {
const btns = document.querySelectorAll('.btn--open-udw');
const udwContainer = document.getElementById('react-udw');
const token = document.querySelector('meta[name="CSRF-Token"]').content;
const siteaccess = document.querySelector('meta[name="SiteAccess"]').content;
(function (global, doc) {
const udwContainer = doc.getElementById('react-udw');
const limitationsRadio = [...doc.querySelectorAll('.ez-limitations__radio')];
const token = doc.querySelector('meta[name="CSRF-Token"]').content;
const siteaccess = doc.querySelector('meta[name="SiteAccess"]').content;
const closeUDW = () => udwContainer.innerHTML = '';
const onConfirm = (form, content) => {
const field = form.querySelector('#role_assignment_locations_value');
field.value = content.map(item => item.ContentInfo.Content._id).join();
const selectSubtreeConfirm = (data) => {
const selectedItems = data.reduce((total, item) => total + `<li>${item.ContentInfo.Content.Name}</li>`, '');

doc.querySelector('#role_assignment_create_locations').value = data.map(item => item.id).join();
doc.querySelector('.ez-limitations__selected-subtree').innerHTML = selectedItems;

closeUDW();
};
const onCancel = () => closeUDW();
const openUDW = (event) => {
const selectSubtree = (event) => {
event.preventDefault();

const form = event.target.closest('form[name=role_assignment]');
ReactDOM.render(React.createElement(eZ.modules.UniversalDiscovery, {
onConfirm: onConfirm.bind(this, form),
onCancel: onCancel,
onConfirm: selectSubtreeConfirm.bind(this),
onCancel: closeUDW,
multiple: true,
restInfo: {token, siteaccess}
}), udwContainer);
};
const toggleDisabledState = () => {
limitationsRadio.forEach(radio => {
const disableNode = doc.querySelector(radio.dataset.disableSelector);
const methodName = radio.checked ? 'removeAttribute' : 'setAttribute';

if (disableNode) {
disableNode[methodName]('disabled', 'disabled');
}
});
};

btns.forEach(btn => btn.addEventListener('click', openUDW, false));
})();
doc.querySelector('.ez-btn--select-subtree').addEventListener('click', selectSubtree, false);
limitationsRadio.forEach(radio => radio.addEventListener('change', toggleDisabledState, false));
})(window, document);
6 changes: 6 additions & 0 deletions src/bundle/Resources/public/scss/_buttons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,9 @@
.btn:disabled {
opacity: .3;
}

.ez-btn--select-subtree {
display: inline-flex;
align-items: center;
justify-content: center;
}
20 changes: 20 additions & 0 deletions src/bundle/Resources/public/scss/_icons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@
.ez-icon {
width: 2rem;
height: 2rem;

&--small {
width: 1rem;
height: 1rem;
}

&--medium {
width: 1.5rem;
height: 1.5rem;
}

&--light {
fill: $ez-white;
}
}

.btn-icon {
Expand Down Expand Up @@ -169,3 +183,9 @@
}
}
}

.ez-btn--select-subtree {
.ez-icon {
margin-right: .5rem;
}
}
8 changes: 4 additions & 4 deletions src/bundle/Resources/translations/menu.en.xliff
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,10 @@
<target state="new">Discard changes</target>
<note>key: role_assignment_create__sidebar_right__cancel</note>
</trans-unit>
<trans-unit id="574bac165f9c298de0c0d06801b68ec7e331658b" resname="role_assignment_create__sidebar_right__create">
<source>Create</source>
<target state="new">Create</target>
<note>key: role_assignment_create__sidebar_right__create</note>
<trans-unit id="63bb349c122da33ab95d2e395ca9a62f8050bf66" resname="role_assignment_create__sidebar_right__save">
<source>Save</source>
<target state="new">Save</target>
<note>key: role_assignment_create__sidebar_right__save</note>
</trans-unit>
<trans-unit id="ec3a03215b15b79b7db72bac312b5e59734ac99c" resname="role_create__sidebar_right__cancel">
<source>Discard changes</source>
Expand Down
25 changes: 25 additions & 0 deletions src/bundle/Resources/translations/role.en.xliff
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
</header>
<body>
<trans-unit id="50fbff4724e8543718a7a0fe08fc1f134bbeb7d6" resname="limitation_type.none">
<source>No limitations</source>
<target state="new">No limitations</target>
<note>key: limitation_type.none</note>
</trans-unit>
<trans-unit id="e4eb27643d4149122e8009b8ca930678eadcd713" resname="limitation_type.section">
<source>Sections</source>
<target state="new">Sections</target>
<note>key: limitation_type.section</note>
</trans-unit>
<trans-unit id="5e91632f7d9ab6e55cf2df01163acebcb1a124d0" resname="limitation_type.subtree">
<source>Subtree</source>
<target state="new">Subtree</target>
<note>key: limitation_type.subtree</note>
</trans-unit>
<trans-unit id="0dbfb3fd5136aa1d54a82ba5e5f399c2908d26f2" resname="locations.select_subtree">
<source>Select Subtree</source>
<target state="new">Select Subtree</target>
<note>key: locations.select_subtree</note>
</trans-unit>
<trans-unit id="d92993cb4cb3690f06c599b5f500a29fa23421c9" resname="policy.add.success">
<source>New policies in role '%role%' created.</source>
<target state="new">New policies in role '%role%' created.</target>
Expand Down Expand Up @@ -231,6 +251,11 @@
<target state="new">Assignments (%count%)</target>
<note>key: role_assignment.view.list.title.count</note>
</trans-unit>
<trans-unit id="5abe6179f254b9bdd5e8680eec4456118980932e" resname="validator.assign_users_or_groups">
<source>Assign User(s) and/or Group(s) to the Role</source>
<target state="new">Assign User(s) and/or Group(s) to the Role</target>
<note>key: validator.assign_users_or_groups</note>
</trans-unit>
</body>
</file>
</xliff>
16 changes: 16 additions & 0 deletions src/bundle/Resources/translations/validators.en.xliff
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file source-language="en" target-language="en" datatype="plaintext" original="not.available">
<header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
</header>
<body>
<trans-unit id="f52d0870dd7bdbff2c2728c2b6ec708aa5cb240b" resname="validator.define_subtree_or_section_limitation">
<source>Define a Subtree or Section limitation</source>
<target state="new">Define a Subtree or Section limitation</target>
<note>key: validator.define_subtree_or_section_limitation</note>
</trans-unit>
</body>
</file>
</xliff>
27 changes: 23 additions & 4 deletions src/bundle/Resources/views/admin/role_assignment/create.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,29 @@
<div class="ez-card__header ez-card__header--secondary">
{{ 'role_assignment.view.add.panel.limitations.title'|trans|desc('Limitations') }}
</div>
<div class="card-body">
{{ form_row(form.sections) }}
{{ form_widget(form.locations.select_content, {'attr': {'class': 'btn btn-secondary btn--open-udw'}}) }}
{% do form.locations.setRendered %}
<div class="card-body ez-limitations">
{{ form_widget(form.limitation_type.none, {'label': 'limitation_type.none'|trans|desc('No limitations'), 'attr': {'class': 'ez-limitations__radio'}, 'label_attr': {'class': 'ez-limitations__label'}}) }}
{% if not form.limitation_type.section.vars.checked %}
{% set sections_attr = {'attr': {'disabled': 'disabled'}} %}
{% else %}
{% set sections_attr = {} %}
{% endif %}
{{ form_widget(form.limitation_type.section, {'label': 'limitation_type.section'|trans|desc('Sections'), 'attr': {'class': 'ez-limitations__radio', 'data-disable-selector': '#' ~ form.sections.vars.id}, 'label_attr': {'class': 'ez-limitations__label'}}) }}
{{ form_widget(form.sections, sections_attr) }}
{{ form_widget(form.limitation_type.location, {'label': 'limitation_type.subtree'|trans|desc('Subtree'), 'attr': {'class': 'ez-limitations__radio', 'data-disable-selector': '#role_assignment_create_locations_select_content'}, 'label_attr': {'class': 'ez-limitations__label'}}) }}
{{ form_widget(form.locations) }}
<button id="role_assignment_create_locations_select_content" class="btn btn-secondary ez-btn--select-subtree"{% if not form.limitation_type.location.vars.checked %} disabled{% endif %}>
<svg class="ez-icon ez-icon--select-subtree ez-icon--medium ez-icon--light">
<use xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="{{ asset('bundles/ezplatformadminui/img/ez-icons.svg') }}#relations"></use>
</svg>
{{ 'locations.select_subtree'|trans|desc('Select Subtree') }}
</button>
<ul class="ez-limitations__selected-subtree mt-4">
{% for location in form.locations.vars.data %}
<li>{{ location.contentInfo.name }}</li>
{% endfor %}
</ul>
</div>
</div>
</section>
Expand Down
Loading