Skip to content

Commit

Permalink
Impersonate from user menu dropdown #6524
Browse files Browse the repository at this point in the history
  • Loading branch information
elias-playfinder authored and eliasfernandez committed Dec 29, 2024
1 parent c4d72d4 commit c01b778
Show file tree
Hide file tree
Showing 33 changed files with 141 additions and 46 deletions.
9 changes: 9 additions & 0 deletions assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class App {
this.#createModalWindowsForDeleteActions();
this.#createPopovers();
this.#createTooltips();
this.#createImpersonateModal();

document.addEventListener('ea.collection.item-added', () => this.#createAutoCompleteFields());
}
Expand Down Expand Up @@ -449,4 +450,12 @@ class App {
});
});
}

#createImpersonateModal(){
const impersonateButton = document.querySelector('#modal-impersonate-link');
const impersonateModal = document.querySelector(impersonateButton.getAttribute('data-bs-target'));
document.querySelector('#impersonate-modal-apply-button').addEventListener('click', () => {
impersonateModal.querySelector('form').submit();
});
}
}
2 changes: 0 additions & 2 deletions public/app.1ecd6d7a.js

This file was deleted.

2 changes: 2 additions & 0 deletions public/app.3682f817.js

Large diffs are not rendered by default.

File renamed without changes.
22 changes: 0 additions & 22 deletions public/app.9f3e666b.css

This file was deleted.

22 changes: 22 additions & 0 deletions public/app.ab66d3f1.css

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions public/entrypoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"entrypoints": {
"app": {
"css": [
"/app.9f3e666b.css"
"/app.ab66d3f1.css"
],
"js": [
"/app.1ecd6d7a.js"
"/app.3682f817.js"
]
},
"form": {
Expand All @@ -30,10 +30,10 @@
},
"field-code-editor": {
"css": [
"/field-code-editor.cdcf15eb.css"
"/field-code-editor.b7d8b94d.css"
],
"js": [
"/field-code-editor.877c61fa.js"
"/field-code-editor.c092384b.js"
]
},
"field-collection": {
Expand Down Expand Up @@ -66,7 +66,7 @@
"/field-text-editor.750725ec.css"
],
"js": [
"/field-text-editor.cb6de4f5.js"
"/field-text-editor.ae3901ca.js"
]
},
"login": {
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions public/field-text-editor.ae3901ca.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion public/field-text-editor.cb6de4f5.js

This file was deleted.

Binary file not shown.
Binary file added public/fonts/fa-brands-400.bb8d5a14.woff2
Binary file not shown.
Binary file removed public/fonts/fa-brands-400.fdbb5585.woff2
Binary file not shown.
Binary file not shown.
Binary file removed public/fonts/fa-regular-400.4f6a2dab.woff2
Binary file not shown.
Binary file added public/fonts/fa-regular-400.bc372268.woff2
Binary file not shown.
Binary file not shown.
Binary file removed public/fonts/fa-solid-900.83a538a0.woff2
Binary file not shown.
Binary file added public/fonts/fa-solid-900.93f719f4.woff2
Binary file not shown.
Binary file not shown.
Binary file added public/fonts/fa-v4compatibility.6cfec841.woff2
Binary file not shown.
Binary file removed public/fonts/fa-v4compatibility.c3ea317a.woff2
Binary file not shown.
26 changes: 13 additions & 13 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
{
"app.css": "app.9f3e666b.css",
"app.js": "app.1ecd6d7a.js",
"app.css": "app.ab66d3f1.css",
"app.js": "app.3682f817.js",
"form.js": "form.bcec6c2a.js",
"page-layout.js": "page-layout.3347892e.js",
"page-color-scheme.js": "page-color-scheme.30cb23c2.js",
"field-boolean.js": "field-boolean.ae2abe46.js",
"field-code-editor.css": "field-code-editor.cdcf15eb.css",
"field-code-editor.js": "field-code-editor.877c61fa.js",
"field-code-editor.css": "field-code-editor.b7d8b94d.css",
"field-code-editor.js": "field-code-editor.c092384b.js",
"field-collection.js": "field-collection.f685c209.js",
"field-file-upload.js": "field-file-upload.7f9cb952.js",
"field-image.js": "field-image.c338d2ad.js",
"field-slug.js": "field-slug.df11f109.js",
"field-textarea.js": "field-textarea.74319bb1.js",
"field-text-editor.css": "field-text-editor.750725ec.css",
"field-text-editor.js": "field-text-editor.cb6de4f5.js",
"field-text-editor.js": "field-text-editor.ae3901ca.js",
"login.js": "login.7259f5de.js",
"fonts/fa-solid-900.ttf": "fonts/fa-solid-900.ad1782c7.ttf",
"fonts/fa-brands-400.ttf": "fonts/fa-brands-400.26b80c88.ttf",
"fonts/fa-solid-900.woff2": "fonts/fa-solid-900.83a538a0.woff2",
"fonts/fa-brands-400.woff2": "fonts/fa-brands-400.fdbb5585.woff2",
"fonts/fa-regular-400.ttf": "fonts/fa-regular-400.05fdd87b.ttf",
"fonts/fa-regular-400.woff2": "fonts/fa-regular-400.4f6a2dab.woff2",
"fonts/fa-v4compatibility.ttf": "fonts/fa-v4compatibility.fa86b3c8.ttf",
"fonts/fa-v4compatibility.woff2": "fonts/fa-v4compatibility.c3ea317a.woff2"
"fonts/fa-solid-900.ttf": "fonts/fa-solid-900.07ed6d5f.ttf",
"fonts/fa-brands-400.ttf": "fonts/fa-brands-400.0ff70dcb.ttf",
"fonts/fa-solid-900.woff2": "fonts/fa-solid-900.93f719f4.woff2",
"fonts/fa-brands-400.woff2": "fonts/fa-brands-400.bb8d5a14.woff2",
"fonts/fa-regular-400.ttf": "fonts/fa-regular-400.17a6e1ae.ttf",
"fonts/fa-regular-400.woff2": "fonts/fa-regular-400.bc372268.woff2",
"fonts/fa-v4compatibility.ttf": "fonts/fa-v4compatibility.0f6cb412.ttf",
"fonts/fa-v4compatibility.woff2": "fonts/fa-v4compatibility.6cfec841.woff2"
}
27 changes: 27 additions & 0 deletions src/Config/Menu/AccessImpersonationMenuItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace EasyCorp\Bundle\EasyAdminBundle\Config\Menu;

use EasyCorp\Bundle\EasyAdminBundle\Contracts\Menu\MenuItemInterface;
use EasyCorp\Bundle\EasyAdminBundle\Dto\MenuItemDto;
use Symfony\Contracts\Translation\TranslatableInterface;

/**
* @see EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem::linkToAccessImpersonation()
*
* @author Elías Fernández <[email protected]>
*/
final class AccessImpersonationMenuItem implements MenuItemInterface
{
use MenuItemTrait;

public function __construct(TranslatableInterface|string $label, ?string $icon)
{
$this->dto = new MenuItemDto();

$this->dto->setType(MenuItemDto::TYPE_ACCESS_IMPERSONATION);
$this->dto->setLabel($label);
$this->dto->setIcon($icon);
$this->dto->setLinkUrl('test');
}
}
9 changes: 9 additions & 0 deletions src/Config/MenuItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace EasyCorp\Bundle\EasyAdminBundle\Config;

use EasyCorp\Bundle\EasyAdminBundle\Config\Menu\AccessImpersonationMenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Config\Menu\CrudMenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Config\Menu\DashboardMenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Config\Menu\ExitImpersonationMenuItem;
Expand Down Expand Up @@ -45,6 +46,14 @@ public static function linkToExitImpersonation(TranslatableInterface|string $lab
return new ExitImpersonationMenuItem($label, $icon);
}

/**
* @param string|null $icon The full CSS classes of the FontAwesome icon to render (see https://fontawesome.com/v6/search?m=free)
*/
public static function linkToAccessImpersonation(TranslatableInterface|string $label, ?string $icon = null): AccessImpersonationMenuItem
{
return new AccessImpersonationMenuItem($label, $icon);
}

/**
* @param string|null $icon The full CSS classes of the FontAwesome icon to render (see https://fontawesome.com/v6/search?m=free)
*/
Expand Down
3 changes: 3 additions & 0 deletions src/Controller/AbstractDashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ public function configureUserMenu(UserInterface $user): UserMenu
if ($this->isGranted(Permission::EA_EXIT_IMPERSONATION)) {
$userMenuItems[] = MenuItem::linkToExitImpersonation(t('user.exit_impersonation', domain: 'EasyAdminBundle'), 'internal:user-lock');
}
if (!$this->isGranted(Permission::EA_EXIT_IMPERSONATION) && $this->isGranted(Permission::EA_CAN_SWITCH_USER)) {
$userMenuItems[] = MenuItem::linkToAccessImpersonation(t('user.impersonate_user', domain: 'EasyAdminBundle'), 'fa-user-lock');
}

$userName = method_exists($user, '__toString') ? (string) $user : $user->getUserIdentifier();

Expand Down
1 change: 1 addition & 0 deletions src/Dto/MenuItemDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ final class MenuItemDto
public const TYPE_URL = 'url';
public const TYPE_SECTION = 'section';
public const TYPE_EXIT_IMPERSONATION = 'exit_impersonation';
public const TYPE_ACCESS_IMPERSONATION = 'access_impersonation';
public const TYPE_DASHBOARD = 'dashboard';
public const TYPE_LOGOUT = 'logout';
public const TYPE_SUBMENU = 'submenu';
Expand Down
1 change: 1 addition & 0 deletions src/Security/Permission.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ final class Permission
public const EA_VIEW_MENU_ITEM = 'EA_VIEW_MENU_ITEM';
public const EA_VIEW_FIELD = 'EA_VIEW_FIELD';
public const EA_EXIT_IMPERSONATION = 'EA_EXIT_IMPERSONATION';
public const EA_CAN_SWITCH_USER = 'EA_CAN_SWITCH_USER';

public static function exists(?string $permissionName): bool
{
Expand Down
29 changes: 29 additions & 0 deletions templates/includes/_impersonate_modal.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<div id="modal-impersonate" class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body p-4">
<form method="get">
<div class="row">
<div class="col-12">
<div class="field-text form-group">
<label for="_switch_user" class="form-control-label required">{{ 'impersonate.username'|trans(domain = 'EasyAdminBundle') }}</label>
<div class="form-widget">
<input type="text" name="_switch_user" id="impersonate_user_name" required="required" class="form-control" value="">
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" data-bs-dismiss="modal" class="btn btn-sm btn-secondary" id="impersonate-modal-clear-button" formtarget="_self">
<i class="fa fa-close"></i> {{ 'action.close'|trans(domain = 'EasyAdminBundle') }}
</button>

<button type="button" data-bs-dismiss="modal" class="btn btn-sm btn-primary" id="impersonate-modal-apply-button" formtarget="_self">
<i class="fa fa-check"></i> {{ 'user.impersonate_user'|trans(domain = 'EasyAdminBundle') }}
</button>
</div>
</div>
</div>
</div>
6 changes: 6 additions & 0 deletions templates/layout.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@
{% elseif not item.isMenuSection %}
<a href="{{ item.linkUrl }}" class="dropdown-item user-action {{ item.cssClass }}"
target="{{ item.linkTarget }}" rel="{{ item.linkRel }}"
{% if item.type == "access_impersonation" %}
data-bs-toggle="modal" data-bs-target="#modal-impersonate" id="modal-impersonate-link"
{% endif %}
referrerpolicy="origin-when-cross-origin">
{% if item.icon is not empty %}<twig:ea:Icon name="{{ item.icon }}" />{% endif %}
{{ item.label|trans }}
Expand Down Expand Up @@ -360,6 +363,9 @@

<section id="main" class="content-body">
{% block main %}{% endblock %}
{% if impersonator_permission == 'IS_IMPERSONATOR' %}
{{ include('@EasyAdmin/includes/_impersonate_modal.html.twig') }}
{% endif %}
</section>

{% block content_footer_wrapper %}
Expand Down
5 changes: 5 additions & 0 deletions translations/EasyAdminBundle.en.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
'anonymous' => 'Anonymous User',
'sign_out' => 'Sign out',
'exit_impersonation' => 'Exit impersonation',
'impersonate_user' => 'Impersonate user',
],

'settings' => [
Expand Down Expand Up @@ -141,4 +142,8 @@
'no-more-results' => 'No more results',
'loading-more-results' => 'Loading more results…',
],

'impersonate' => [
'username' => 'Username to impersonate',
],
];
7 changes: 6 additions & 1 deletion translations/EasyAdminBundle.es.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@
'unnamed' => 'Usuario sin nombre',
'anonymous' => 'Usuario anónimo',
'sign_out' => 'Cerrar sesión',
'exit_impersonation' => 'Terminar impersonación',
'exit_impersonation' => 'Terminar suplantación',
'impersonate_user' => 'Suplantar usuario',
],

'settings' => [
Expand Down Expand Up @@ -141,4 +142,8 @@
'no-more-results' => 'No hay más resultados',
'loading-more-results' => 'Cargando más resultados…',
],

'impersonate' => [
'username' => 'Nombre de usuario a suplantar',
],
];

0 comments on commit c01b778

Please sign in to comment.