Merge branch 'admin-permissionsgroup-templates' into 'master'

Improve permissionsgroup page in admin templates

See merge request Chill-Projet/chill-bundles!504
This commit is contained in:
Mathieu Jaumotte 2023-04-21 15:36:00 +00:00
commit 01f2697b8d
17 changed files with 215 additions and 134 deletions

View File

@ -41,7 +41,6 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use function array_key_exists;
@ -213,7 +212,7 @@ final class ActivityController extends AbstractController
$form = $this->createForm(ActivityType::class, $entity, [
'center' => $this->centerResolver->resolveCenters($entity)[0] ?? null,
'role' => new Role('CHILL_ACTIVITY_UPDATE'),
'role' => 'CHILL_ACTIVITY_UPDATE',
'activityType' => $entity->getActivityType(),
'accompanyingPeriod' => $accompanyingPeriod,
]);
@ -442,7 +441,7 @@ final class ActivityController extends AbstractController
$form = $this->createForm(ActivityType::class, $entity, [
'center' => $this->centerResolver->resolveCenters($entity)[0] ?? null,
'role' => new Role('CHILL_ACTIVITY_CREATE'),
'role' => 'CHILL_ACTIVITY_CREATE',
'activityType' => $entity->getActivityType(),
'accompanyingPeriod' => $accompanyingPeriod,
]);

View File

@ -106,6 +106,9 @@ CHILL_ACTIVITY_SEE_DETAILS: Voir le détail des échanges
CHILL_ACTIVITY_DELETE: Supprimer un échange
CHILL_ACTIVITY_STATS: Statistique des échanges
CHILL_ACTIVITY_LIST: Liste des échanges
CHILL_ACTIVITY_CREATE_PERSON: Créer un échange lié à un usager
CHILL_ACTIVITY_CREATE_ACCOMPANYING_COURSE: Créer un échange lié à un parcours
CHILL_ACTIVITY_FULL: Voir les détails, créer, supprimer et mettre à jour un échange
# admin
Activities: Échanges

View File

@ -27,9 +27,7 @@
</form>
</td>
<td>
<a href="{{ chill_path_add_return_path('chill_crud_docgen_template_edit', { 'id': entity.id }) }}" class="btn btn-edit">
{{ 'Edit'|trans }}
</a>
<a href="{{ chill_path_add_return_path('chill_crud_docgen_template_edit', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'Edit'|trans }}"></a>
</td>
</tr>
{% endfor %}

View File

@ -5,14 +5,14 @@
{% block admin_content %}
<h1>{{ 'Document category list' | trans }}</h1>
<table class="table">
<table class="table table-bordered border-dark align-middle">
<thead>
<tr>
<th>{{ 'Creator bundle id' | trans }}</th>
<th>{{ 'Internal id inside creator bundle' | trans }}</th>
<th>{{ 'Document class' | trans }}</th>
<th>{{ 'Name' | trans }}</th>
<th>{{ 'Actions' | trans }}</th>
<th class="w-25">{{ 'Actions' | trans }}</th>
</tr>
</thead>
<tbody>
@ -23,7 +23,7 @@
<td>{{ document_category.documentClass }}</td>
<td>{{ document_category.name | localize_translatable_string}}</td>
<td>
<td class="text-end">
<a href="{{ path('document_category_show', {'bundleId': document_category.bundleId, 'idInsideBundle': document_category.idInsideBundle}) }}"
class="btn btn-show" title="{{ 'show' | trans }}"></a>
<a href="{{ path('document_category_edit', {'bundleId': document_category.bundleId, 'idInsideBundle': document_category.idInsideBundle}) }}"

View File

@ -88,6 +88,7 @@ class ComposedRoleScopeType extends AbstractType
])
->add('scope', EntityType::class, [
'class' => Scope::class,
'placeholder' => 'Choose amongst scopes',
'choice_label' => static function (Scope $scope) use ($translatableStringHelper) {
return $translatableStringHelper->localize($scope->getName());
},

View File

@ -375,6 +375,12 @@ span.dt {
font-weight: bolder;
background-color: var(--bs-chill-light-gray);
}
/// help text
.help-text {
margin-top: 0.25rem;
font-size: 0.875em;
color: var(--bs-gray);
}
/*

View File

@ -1,3 +1,11 @@
/// mixin to set sticky area on bottom when scrolling
@mixin sticky-bottom {
position: sticky;
bottom: 0;
margin-top: 4em;
z-index: 1000;
}
ul.record_actions {
display: flex;
flex-direction: row;
@ -53,16 +61,30 @@ ul.record_actions {
}
}
}
.sticky-form {
background-color: $white;
padding-top: 1.25em;
margin: -1em;
box-shadow: 0 -20px 20px -20px rgba($chill-gray, .5);
@include sticky-bottom;
.sticky-form-buttons {
position: initial;
bottom: unset;
margin-top: unset;
z-index: unset;
}
}
.sticky-form-buttons {
margin-top: 4em;
background-color: $beige;
position: sticky;
bottom: 0.3em;
text-align: center;
display: flex;
padding: 0.8em 1.6em;
border-radius: 0;
z-index: 1000;
display: flex;
background-color: $beige;
text-align: center;
padding: 0.8em 1.6em;
border-radius: 0;
@include sticky-bottom;
bottom: 0.3em;
}
/// EXCEPTIONS

View File

@ -1,7 +1,7 @@
{% set formId = crudMainFormId|default('crud_main_form') %}
{% block crud_content_header %}
<h1>{{ ('crud.'~crud_name~'.title_edit')|trans }}</h1>
<h1 class="mb-5">{{ ('crud.'~crud_name~'.title_edit')|trans }}</h1>
{% endblock crud_content_header %}
{% block crud_content_form %}

View File

@ -14,7 +14,7 @@
{% endblock %}
{% else %}
{% block table_entities %}
<table class="table table-bordered border-dark">
<table class="table table-bordered border-dark align-middle">
<thead>
<tr>
{% block table_entities_thead_tr %}

View File

@ -3,93 +3,130 @@
{% block title %}{{ 'PermissionsGroup "%name%" edit'|trans( { '%name%': entity.name } ) }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'PermissionsGroup "%name%" edit'|trans( { '%name%': entity.name } ) }}</h1>
<div class="container-xxl">
<div class="row">
<h2>{{ 'Details'|trans }}</h2>
<h1 class="mb-4">{{ 'PermissionsGroup "%name%" edit'|trans( { '%name%': entity.name } ) }}</h1>
{{ form_start(edit_form) }}
{{ form_row(edit_form.name) }}
{% if edit_form.flags is defined %}
{{ form_row(edit_form.flags) }}
{% endif %}
{{ form_row(edit_form.submit, { 'attr': { 'class': 'btn btn-chill-green' } } ) }}
{{ form_end(edit_form) }}
<h2>{{ 'Details'|trans }}</h2>
<h2>{{ 'Grant those permissions'|trans }} :</h2>
{{ form_start(edit_form) }}
{{ form_row(edit_form.name) }}
{% if edit_form.flags is defined %}
{{ form_row(edit_form.flags) }}
{% endif %}
{{ form_row(edit_form.submit, { 'attr': { 'class': 'btn btn-save float-end' } } ) }}
{{ form_end(edit_form) }}
{%- if entity.getRoleScopes|length > 0 -%}
{% for title, role_scopes in role_scopes_sorted %}
<h2 class="mb-5">{{ 'Grant those permissions'|trans }} :</h2>
<h3>{{ title|default("Unclassified")|trans }}</h3>
{%- if entity.getRoleScopes|length > 0 -%}
{% for title, role_scopes in role_scopes_sorted %}
<table class="striped rounded">
<thead>
<h3>{{ title|default("Unclassified")|trans }}</h3>
<table class="table table-bordered border-dark align-middle mb-5">
<thead>
<tr>
<th>{{ 'Circle'|trans }}</th>
<th class="w-75">{{ 'Role'|trans }}</th>
<th>{{ 'Actions'|trans }}</th>
</tr>
</thead>
<tbody>
{% for role_scope in role_scopes %}
<tr>
<th>{{ 'Role'|trans }}</th>
<th>{{ 'Circle'|trans }}</th>
<th>{{ 'Actions'|trans }}</th>
</tr>
</thead>
<tbody>
{% for role_scope in role_scopes %}
<tr>
<td>
<span class="role_scope role">{{ role_scope.role|trans }}</span>
{% if expanded_roles[role_scope.role]|length > 1 %}
<br/>
<small>{{ 'Which implies'|trans }}&nbsp;: {% for role in expanded_roles[role_scope.role] %}{{ role|trans }}{% if not loop.last %}, {% endif %}{% endfor %}</small>
<td style="width: 7em">
{%- if role_scope.scope is not null -%}
<span class="role_scope scope">
{{ role_scope.scope.name|localize_translatable_string }}
</span>
{%- else -%}
<small><i>N/A</i></small>
{%- endif -%}
</td>
<td>
<span class="role_scope role">{{ role_scope.role|trans }}</span>
{% if expanded_roles[role_scope.role]|length > 1 %}
<div class="help-text">
<span style="text-decoration: underline dotted;">{{ 'Which implies'|trans }}&nbsp;:</span>
{% for role in expanded_roles[role_scope.role] %}
{% if role != role_scope.role %}
{{ role|trans }}
{% if not loop.last %}, {% endif %}
{% endif %}
{% endfor %}
</div>
{% endif %}
</td>
<td>
{%- if role_scope.scope is not null -%}
<span class="role_scope scope">
{{ role_scope.scope.name|localize_translatable_string }}
</span>
{%- else -%}
<em>N/A</em>
{%- endif -%}
</td>
<td>
{{ form_start(delete_role_scopes_form[role_scope.id]) }}
{{ form_widget(delete_role_scopes_form[role_scope.id].submit, { 'attr': { 'class': 'btn btn-chill-red' } } ) }}
{{ form_end(delete_role_scopes_form[role_scope.id]) }}
</td>
</tr>
</td>
<td style="width: 7em">
{{ form_start(delete_role_scopes_form[role_scope.id]) }}
{{ form_widget(delete_role_scopes_form[role_scope.id].submit, { 'attr': { 'class': 'btn btn-remove' } } ) }}
{{ form_end(delete_role_scopes_form[role_scope.id]) }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endfor %}
{% endfor %}
</tbody>
</table>
{% endfor %}
{%- else -%}
<p>{{ 'This group does not provide any permission'|trans }}</p>
{%- endif -%}
{%- else -%}
<p>{{ 'This group does not provide any permission'|trans }}</p>
{%- endif -%}
</div>
<div class="row sticky-form">
<div class="mt-5">
<h2>{{ 'Grant new permissions'|trans }}</h2>
{{ form_start(add_role_scopes_form) }}
{{ form_errors(add_role_scopes_form) }}
{{ form_row(add_role_scopes_form.composed_role_scope.role) }}
{{ form_row(add_role_scopes_form.composed_role_scope.scope) }}
<div class="input-group">
{{ form_widget(add_role_scopes_form.composed_role_scope.role, { 'attr': { 'class': 'w-50' }}) }}
{{ form_widget(add_role_scopes_form.composed_role_scope.scope) }}
</div>
<div id="role_scope_legend" class="help-text mb-3">{{ 'Help to pick role and scope'|trans }}</div>
<ul class="record_actions sticky-form-buttons">
<li>
{{ form_row(add_role_scopes_form.submit, { 'attr' : { 'class': 'btn btn-create' } } ) }}
</li>
<li>
<a href="{{ path('admin_permissionsgroup_show', { 'id': entity.id }) }}" class="btn btn-cancel">{{ 'Cancel'|trans }}</a>
</li>
<li>
<li class="cancel">
<a href="{{ path('admin_permissionsgroup') }}" class="btn btn-cancel">
{{ 'Back to the list'|trans }}
</a>
<a href="{{ path('admin_permissionsgroup_show', { 'id': entity.id }) }}" class="btn btn-misc">{{ 'Cancel'|trans }}</a>
</li>
<li>
{{ form_widget(add_role_scopes_form.submit, { 'attr' : { 'class': 'btn btn-create' } } ) }}
</li>
</ul>
{{ form_end(add_role_scopes_form) }}
</div>
</div>
{% endblock %}
{% block js %}
<script>
// An event listener give contextual legend when choosing an option.
const select = document.getElementById('form_composed_role_scope_role');
const legend = document.getElementById('role_scope_legend');
select.addEventListener('change', function() {
const option = this.options[this.selectedIndex];
const hasScope = option.getAttribute('data-has-scope');
legend.style.display = 'block';
if (hasScope === '0') {
legend.innerText = '{{ 'The role does not need scope'|trans }}';
} else if (hasScope === '1') {
legend.innerText = '{{ 'The role need scope'|trans }}';
} else {
legend.innerText = '{{ 'Help to pick role and scope'|trans }}';
}
});
</script>
{% endblock %}

View File

@ -5,7 +5,7 @@
{% block admin_content -%}
<h1>{{ 'Permissions group list'|trans }}</h1>
<table class="records_list">
<table class="table table-bordered border-dark align-middle">
<thead>
<tr>
<th>{{ 'Name'|trans }}</th>

View File

@ -10,8 +10,6 @@
{% if form.flags is defined %}
{{ form_row(form.flags) }}
{% endif %}
{{ form_row(form.submit, { 'attr': { 'class': 'btn btn-chill-green' } } ) }}
{{ form_end(form) }}
<ul class="record_actions sticky-form-buttons">
<li class='cancel'>
@ -19,5 +17,10 @@
{{ 'Back to the list'|trans }}
</a>
</li>
<li>
{{ form_widget(form.submit, { 'attr': { 'class': 'btn btn-create' } } ) }}
</li>
</ul>
{{ form_end(form) }}
{% endblock %}

View File

@ -3,44 +3,52 @@
{% block title %}{{ 'Permission group "%name%"'|trans({ '%name%': entity.name }) }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Permission group "%name%"'|trans({ '%name%': entity.name }) }}</h1>
<h1 class="mb-4">{{ 'Permission group "%name%"'|trans({ '%name%': entity.name }) }}</h1>
<table class="record_properties">
<table class="table table-bordered border-dark align-middle">
<tbody>
<tr>
<th>{{ 'Name'|trans }}</th>
<td>{{ entity.name }}</td>
<td class="w-25">{{ entity.name }}</td>
</tr>
</tbody>
</table>
{% if role_scopes_sorted|length > 0 %}
<h2>{{ 'Grant those permissions'|trans }}&nbsp;:</h2>
<h2 class="mb-5">{{ 'Grant those permissions'|trans }}&nbsp;:</h2>
{% for title, role_scopes in role_scopes_sorted %}
<h3>{{ title|default('Unclassified')|trans }}</h3>
<table class="striped rounded">
<table class="table table-bordered border-dark align-middle mb-5">
<thead>
<tr>
<th class="w-25">{{ 'Circle'|trans }}</th>
<th>{{ 'Role'|trans }}</th>
<th>{{ 'Circle'|trans }}</th>
</tr>
</thead>
<tbody>
{% for role_scope in role_scopes %}
<tr>
<td>
{{ role_scope.role|trans }}
{% if expanded_roles[role_scope.role]|length > 1 %}
<br/>
<small>{{ 'Which implies'|trans }}&nbsp;: {% for role in expanded_roles[role_scope.role] %}{{ role|trans }}{% if not loop.last %}, {% endif %}{% endfor %}</small>
{% endif %}
</td>
<td>{%- if role_scope.scope is not null -%}
{{ role_scope.scope.name|localize_translatable_string }}
<td style="width: 7em">{%- if role_scope.scope is not null -%}
{{ role_scope.scope.name|localize_translatable_string }}
{%- else -%}
<em>N/A</em>
{%- endif -%}
<small><i>N/A</i></small>
{%- endif -%}
</td>
<td>
<span class="role_scope role">{{ role_scope.role|trans }}</span>
{% if expanded_roles[role_scope.role]|length > 1 %}
<div class="help-text">
<span style="text-decoration: underline dotted;">{{ 'Which implies'|trans }}&nbsp;:</span>
{% for role in expanded_roles[role_scope.role] %}
{% if role != role_scope.role %}
{{ role|trans }}
{% if not loop.last %}, {% endif %}
{% endif %}
{% endfor %}
</div>
{% endif %}
</td>
</tr>
{% endfor %}
@ -57,17 +65,15 @@
{% endif %}
<ul class="record_actions sticky-form-buttons">
<li class="cancel">
<a href="{{ path('admin_permissionsgroup') }}" class="btn btn-cancel">
{{ 'Back to the list'|trans }}
</a>
</li>
<li>
<a href="{{ path('admin_permissionsgroup_edit', { 'id': entity.id }) }}" class="btn btn-edit">
{{ 'Edit'|trans }}
</a>
</li>
<li>
<a href="{{ path('admin_permissionsgroup') }}" class="btn btn-cancel">
{{ 'Back to the list'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -4,10 +4,10 @@
{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
{% block crud_content_after_form %}
{% if access_permissions_group_list %}
<h2>{{ 'Permissions granted'|trans }}</h2>
<h2 class="mt-5">{{ 'Permissions granted'|trans }}</h2>
{% if entity.groupcenters|length > 0 %}
<table>
<table class="table table-bordered border-dark align-middle mb-5">
<thead>
<tr>
<th>{{ 'Permission group'|trans }}</th>
@ -19,18 +19,18 @@
{% for groupcenter in entity.groupcenters %}
<tr>
<td>
<span class="user_group permissionsgroup">
{{ groupcenter.permissionsgroup.name }}
</span>
<span class="user_group permissionsgroup">
{{ groupcenter.permissionsgroup.name }}
</span>
</td>
<td>
<span class="user_group center">
{{ groupcenter.center.name }}
</span>
<span class="user_group center">
{{ groupcenter.center.name }}
</span>
</td>
<td>
<td class="w-25 text-end">
{{ form_start(delete_groupcenter_form[groupcenter.id]) }}
{{ form_row(delete_groupcenter_form[groupcenter.id].submit, { 'attr': { 'class': 'btn btn-chill-red' } } ) }}
{{ form_widget(delete_groupcenter_form[groupcenter.id].submit, { 'attr': { 'class': 'btn btn-remove' } } ) }}
{{ form_rest(delete_groupcenter_form[groupcenter.id]) }}
{{ form_end(delete_groupcenter_form[groupcenter.id]) }}
</td>
@ -47,7 +47,7 @@
{{ form_start(add_groupcenter_form) }}
{{ form_row(add_groupcenter_form.composed_groupcenter.center) }}
{{ form_row(add_groupcenter_form.composed_groupcenter.permissionsgroup) }}
{{ form_row(add_groupcenter_form.submit, { 'attr' : { 'class': 'btn btn-chill-green' } } ) }}
{{ form_row(add_groupcenter_form.submit, { 'attr' : { 'class': 'btn btn-create' } } ) }}
{{ form_end(add_groupcenter_form) }}
{% endif %}

View File

@ -69,19 +69,20 @@
</td>
<td>
<ul class="record_actions">
{% if is_granted('ROLE_ALLOWED_TO_SWITCH') %}
<li>
<a class="btn btn-chill-blue" href="{{ path('chill_main_homepage', {'_switch_user': entity.username }) }}" title="{{ "Impersonate"|trans|e('html_attr') }}"><i class="fa fa-user-secret"></i></a>
</li>
{% endif %}
<li>
<a class="btn btn-edit" title="{{ 'Edit'|trans }}" href="{{ path('chill_crud_admin_user_edit', { 'id': entity.id }) }}"></a>
</li>
{% if allow_change_password is same as(true) %}
<li>
<a class="btn btn-chill-red" href="{{ path('admin_user_edit_password', { 'id' : entity.id }) }}" title="{{ 'Edit password'|trans|e('html_attr') }}"><i class="fa fa-ellipsis-h"></i></a>
</li>
{% endif %}
{% if is_granted('ROLE_ALLOWED_TO_SWITCH') %}
<li>
<a class="btn btn-chill-blue" href="{{ path('chill_main_homepage', {'_switch_user': entity.username }) }}" title="{{ "Impersonate"|trans|e('html_attr') }}"><i class="fa fa-user-secret"></i></a>
<a class="btn btn-reset" href="{{ path('admin_user_edit_password', { 'id' : entity.id }) }}" title="{{ 'Edit password'|trans|e('html_attr') }}"><i class="fa fa-key-modern"></i></a>
</li>
{% endif %}
</ul>

View File

@ -2,14 +2,14 @@
{% block admin_content %}
{% embed '@ChillMain/CRUD/_index.html.twig' %}
{% block table_entities_thead_tr %}
<th>id</th>
<th>{{ 'Label'|trans }}</th>
<th>{{ 'Active'|trans }}</th>
<th>{{ 'Actions'|trans }}</th>
{% endblock %}
{% block table_entities_tbody %}
{% for entity in entities %}
<tr>
@ -25,19 +25,19 @@
<td>
<ul class="record_actions">
<li>
<a href="{{ chill_path_add_return_path('chill_crud_admin_user_job_edit', { 'id': entity.id}) }}" class="btn btn-sm btn-edit btn-mini"></a>
<a href="{{ chill_path_add_return_path('chill_crud_admin_user_job_edit', { 'id': entity.id}) }}" class="btn btn-edit"></a>
</li>
</ul>
</td>
</tr>
{% endfor %}
{% endblock %}
{% block actions_before %}
<li class='cancel'>
<a href="{{ path('chill_main_admin_central') }}" class="btn btn-cancel">{{'Back to the admin'|trans}}</a>
</li>
{% endblock %}
{% endembed %}
{% endblock %}

View File

@ -167,12 +167,16 @@ Permissionsgroup: Groupe de permissions
New permission group: Nouveau groupe de permissions
PermissionsGroup "%name%" edit: Modification du groupe de permission '%name%'
Role: Rôle
Choose amongst roles: Choisir parmi les rôles
Choose amongst roles: Choisir un rôle
Choose amongst scopes: Choisir un cercle
Add permission: Ajouter les permissions
This group does not provide any permission: Ce groupe n'attribue aucune permission
The role '%role%' has been removed: Le rôle "%role%" a été enlevé de ce groupe de permission
The role '%role%' on circle '%scope%' has been removed: Le rôle "%role%" sur le cercle "%scope%" a été enlevé de ce groupe de permission
Unclassified: Non classifié
Help to pick role and scope: Certains rôles ne nécessitent pas de cercle.
The role need scope: Ce rôle nécessite un cercle.
The role does not need scope: Ce rôle ne nécessite pas de cercle !
#admin section for users
User configuration: Gestion des utilisateurs
@ -423,6 +427,7 @@ No entities: Aucun élément
CHILL_FOO_SEE: Voir un élément
CHILL_FOO_EDIT: Modifier un élément
chill_export: Exports (statistiques)
#Show templates
Date: Date