393 lines
24 KiB
Twig
393 lines
24 KiB
Twig
{# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #}
|
|
{% trans_default_domain ea.i18n.translationDomain %}
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="{{ ea.i18n.htmlLocale }}" dir="{{ ea.i18n.textDirection }}" data-turbo="false">
|
|
<head>
|
|
{% block head_metas %}
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="robots" content="noindex, nofollow, noarchive, nosnippet, noodp, noimageindex, notranslate, nocache" />
|
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
|
<meta name="generator" content="EasyAdmin" />
|
|
{% endblock head_metas %}
|
|
|
|
{% set page_title_block_output %}{% block page_title %}{{ block('content_title') }}{% endblock %}{% endset %}
|
|
<title>{{ page_title_block_output|striptags|raw }}</title>
|
|
|
|
{% block head_stylesheets %}
|
|
<link rel="stylesheet" href="{{ asset('app.css', ea.assets.defaultAssetPackageName) }}">
|
|
{% endblock %}
|
|
|
|
{% block configured_stylesheets %}
|
|
{{ include('@EasyAdmin/includes/_css_assets.html.twig', { assets: ea.assets.cssAssets ?? [] }, with_context = false) }}
|
|
{{ include('@EasyAdmin/includes/_encore_link_tags.html.twig', { assets: ea.assets.webpackEncoreAssets ?? [] }, with_context = false) }}
|
|
{% endblock %}
|
|
|
|
{% block head_favicon %}
|
|
<link rel="shortcut icon" href="{{ asset(ea.dashboardFaviconPath) }}">
|
|
{% endblock %}
|
|
|
|
{% block head_javascript %}
|
|
<script src="{{ asset('app.js', ea.assets.defaultAssetPackageName) }}"></script>
|
|
|
|
{% block importmap %}
|
|
{{ include('@EasyAdmin/includes/_importmap.html.twig', { assets: ea.assets.assetMapperAssets ?? [] }, with_context = false) }}
|
|
{% endblock %}
|
|
{% endblock head_javascript %}
|
|
|
|
{% block configured_javascripts %}
|
|
{{ include('@EasyAdmin/includes/_js_assets.html.twig', { assets: ea.assets.jsAssets ?? [] }, with_context = false) }}
|
|
{{ include('@EasyAdmin/includes/_encore_script_tags.html.twig', { assets: ea.assets.webpackEncoreAssets ?? [] }, with_context = false) }}
|
|
{% endblock %}
|
|
|
|
{% block configured_head_contents %}
|
|
{% for htmlContent in ea.assets.headContents ?? [] %}
|
|
{{ htmlContent|raw }}
|
|
{% endfor %}
|
|
{% endblock %}
|
|
</head>
|
|
|
|
{% block body %}
|
|
<body {% block body_attr %}{% endblock %}
|
|
id="{% block body_id %}{% endblock %}"
|
|
class="ea {% block body_class %}{% endblock %}"
|
|
data-ea-content-width="{{ ea.crud.contentWidth ?? ea.dashboardContentWidth ?? 'normal' }}"
|
|
data-ea-sidebar-width="{{ ea.crud.sidebarWidth ?? ea.dashboardSidebarWidth ?? 'normal' }}"
|
|
data-ea-dark-scheme-is-enabled="{{ ea.dashboardHasDarkModeEnabled ? 'true' : 'false' }}"
|
|
data-ea-default-color-scheme="{{ ea.dashboardDefaultColorScheme }}"
|
|
data-ea-icon-set="{{ ea.assets.iconSet }}"
|
|
data-ea-icon-prefix="{{ ea.assets.defaultIconPrefix }}"
|
|
>
|
|
{% block javascript_page_layout %}
|
|
<script src="{{ asset('page-layout.js', ea.assets.defaultAssetPackageName) }}"></script>
|
|
{% endblock javascript_page_layout %}
|
|
{% block javascript_page_color_scheme %}
|
|
<script src="{{ asset('page-color-scheme.js', ea.assets.defaultAssetPackageName) }}"></script>
|
|
{% endblock javascript_page_color_scheme %}
|
|
|
|
{% block wrapper_wrapper %}
|
|
{% block flash_messages %}
|
|
{{ include(ea.templatePath('flash_messages')) }}
|
|
{% endblock flash_messages %}
|
|
|
|
{% set user_menu_avatar %}
|
|
{% if null == ea.userMenu.avatarUrl %}
|
|
<span class="user-avatar">
|
|
<twig:ea:Icon name="internal:user" />
|
|
</span>
|
|
{% else %}
|
|
<img class="user-avatar" src="{{ ea.userMenu.avatarUrl }}" />
|
|
{% endif %}
|
|
{% endset %}
|
|
|
|
{% set impersonator_permission = constant('Symfony\\Component\\Security\\Core\\Authorization\\Voter\\AuthenticatedVoter::IS_IMPERSONATOR') is defined ? 'IS_IMPERSONATOR' : 'ROLE_PREVIOUS_ADMIN' %}
|
|
|
|
{% set user_menu_dropdown %}
|
|
<ul class="dropdown-menu dropdown-menu-end">
|
|
<li class="dropdown-user-details">
|
|
<div>{{ user_menu_avatar }}</div>
|
|
<div>
|
|
<span class="user-label">{{ 'user.logged_in_as'|trans(domain = 'EasyAdminBundle') }}</span>
|
|
<span class="user-name">{{ ea.user is null ? 'user.anonymous'|trans(domain = 'EasyAdminBundle') : ea.userMenu.name }}</span>
|
|
</div>
|
|
</li>
|
|
|
|
{% block user_menu %}
|
|
{% if ea.userMenu.items|length > 0 %}
|
|
<li><hr class="dropdown-divider"></li>
|
|
{% for item in ea.userMenu.items %}
|
|
<li>
|
|
{% if item.isMenuSection and not loop.first %}
|
|
<hr class="dropdown-divider">
|
|
{% elseif not item.isMenuSection %}
|
|
<a href="{{ item.linkUrl }}" class="dropdown-item user-action {{ item.cssClass }}"
|
|
target="{{ item.linkTarget }}" rel="{{ item.linkRel }}"
|
|
referrerpolicy="origin-when-cross-origin">
|
|
{% if item.icon is not empty %}<twig:ea:Icon name="{{ item.icon }}" />{% endif %}
|
|
{{ item.label|trans }}
|
|
</a>
|
|
{% endif %}
|
|
</li>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endblock user_menu %}
|
|
</ul>
|
|
{% endset %}
|
|
|
|
{% set settings_dropdown %}
|
|
{% if ea.dashboardLocales or ea.dashboardHasDarkModeEnabled %}
|
|
<div class="dropdown dropdown-settings">
|
|
<a class="dropdown-settings-button" type="button" data-bs-toggle="dropdown" data-bs-offset="0,5" aria-expanded="false">
|
|
<twig:ea:Icon name="internal:gear" />
|
|
</a>
|
|
|
|
<ul class="dropdown-menu dropdown-menu-end">
|
|
{% if ea.dashboardLocales %}
|
|
<li class="dropdown-header dropdown-locales-label">
|
|
{{ 'settings.locale'|trans(domain = 'EasyAdminBundle') }}
|
|
</li>
|
|
|
|
{% for localeDto in ea.dashboardLocales %}
|
|
<li>
|
|
<a href="{{ ea_url().set('_locale', localeDto.locale) }}" class="dropdown-item{% if app.request.locale == localeDto.locale %} active{% endif %}">
|
|
{% if localeDto.icon %}
|
|
<twig:ea:Icon name="{{ localeDto.icon }}" />
|
|
{% endif %}
|
|
{{ localeDto.name }}
|
|
</a>
|
|
</li>
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
{% if ea.dashboardHasDarkModeEnabled %}
|
|
{% if ea.dashboardLocales %}
|
|
<div class="dropdown-divider"></div>
|
|
{% endif %}
|
|
|
|
<li class="dropdown-header dropdown-appearance-label">
|
|
{{ 'settings.appearance.label'|trans(domain = 'EasyAdminBundle') }}
|
|
</li>
|
|
<li>
|
|
<a href="#" class="dropdown-item dropdown-appearance-item" data-ea-color-scheme="light">
|
|
<twig:ea:Icon name="internal:sun" />
|
|
{{ 'settings.appearance.light'|trans(domain = 'EasyAdminBundle') }}
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#" class="dropdown-item dropdown-appearance-item" data-ea-color-scheme="dark">
|
|
<twig:ea:Icon name="internal:moon" />
|
|
{{ 'settings.appearance.dark'|trans(domain = 'EasyAdminBundle') }}
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#" class="dropdown-item dropdown-appearance-item active" data-ea-color-scheme="auto">
|
|
<twig:ea:Icon name="internal:desktop" />
|
|
{{ 'settings.appearance.auto'|trans(domain = 'EasyAdminBundle') }}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</div>
|
|
{% endif %}
|
|
{% endset %}
|
|
|
|
<div class="wrapper">
|
|
{% block wrapper %}
|
|
<div class="responsive-header">
|
|
{% block responsive_header %}
|
|
<button id="navigation-toggler" type="button" aria-label="Toggle navigation">
|
|
<twig:ea:Icon name="internal:menu-bars" />
|
|
</button>
|
|
|
|
<div id="responsive-header-logo" class="text-truncate ms-auto">
|
|
{% block responsive_header_logo %}
|
|
<a class="responsive-logo" title="{{ ea.dashboardTitle|striptags }}" href="{{ path(ea.dashboardRouteName) }}">
|
|
{{ ea.dashboardTitle|raw }}
|
|
</a>
|
|
{% endblock responsive_header_logo %}
|
|
</div>
|
|
|
|
<div class="dropdown user-menu-wrapper {{ is_granted(impersonator_permission) ? 'user-is-impersonated' }} ms-auto">
|
|
<a class="user-details" type="button" data-bs-toggle="dropdown" data-bs-offset="0,5" aria-expanded="false">
|
|
{# to make the site design consistent, always display the user avatar in responsive header
|
|
and hide the user name (because there's no space left) regardless of the user config #}
|
|
{% if ea.userMenu.avatarDisplayed %}
|
|
{{ user_menu_avatar }}
|
|
{% else %}
|
|
<twig:ea:Icon class="user-avatar" name="{{ ea.user is not null ? 'internal:user' : 'internal:user-xmark' }}" />
|
|
{% endif %}
|
|
</a>
|
|
|
|
{{ user_menu_dropdown }}
|
|
</div>
|
|
|
|
{{ settings_dropdown }}
|
|
{% endblock responsive_header %}
|
|
</div>
|
|
|
|
<div class="sidebar-wrapper">
|
|
<aside class="sidebar">
|
|
{% block sidebar %}
|
|
<header class="main-header">
|
|
{% block header %}
|
|
<nav class="navbar" role="navigation">
|
|
{% block header_navbar %}
|
|
<div id="header-logo">
|
|
{% block header_logo %}
|
|
<a class="logo" title="{{ ea.dashboardTitle|striptags }}" href="{{ path(ea.dashboardRouteName) }}">
|
|
<span class="logo-custom">{{ ea.dashboardTitle|raw }}</span>
|
|
<span class="logo-compact"><twig:ea:Icon name="internal:home" /></span>
|
|
</a>
|
|
{% endblock header_logo %}
|
|
</div>
|
|
{% endblock header_navbar %}
|
|
</nav>
|
|
{% endblock header %}
|
|
</header>
|
|
|
|
{% block main_menu_wrapper %}
|
|
{{ include(ea.templatePath('main_menu')) }}
|
|
{% endblock main_menu_wrapper %}
|
|
{% endblock sidebar %}
|
|
|
|
<div id="sidebar-resizer-handler" class="resizer-handler resizer-handler-left"></div>
|
|
</aside>
|
|
</div>
|
|
|
|
<section class="main-content">
|
|
{% set has_search = ea.crud is not null and ea.crud.isSearchEnabled %}
|
|
<aside class="content-top {{ has_search ? 'ea-search-enabled' : 'ea-search-disabled' }}">
|
|
{% block content_top_header %}
|
|
{% block search_wrapper %}
|
|
<div class="content-search">
|
|
{% if has_search %}
|
|
{% block search %}
|
|
{% set formActionUrl = null %}
|
|
{% if ea.usePrettyUrls %}
|
|
{% set formActionUrl = ea_url().setController(ea.request.attributes.get('crudControllerFqcn')).setAction('index').set('page', 1) %}
|
|
{% endif %}
|
|
<form class="form-action-search" method="get" {% if formActionUrl %}action="{{ formActionUrl }}"{% endif %}>
|
|
{% block search_form %}
|
|
{% block search_form_filters %}
|
|
{% for field, fieldValue in ea.search.appliedFilters %}
|
|
{% if fieldValue is iterable %}
|
|
{% for key, value in fieldValue %}
|
|
{# This code re-applies your filters on searches, an iterable check is needed in cases we have more than one object for a filter #}
|
|
{% if value is iterable %}
|
|
{% for index, iterValue in value %}
|
|
{# This sub-level iterable check is needed in cases we have more complex filters like the DateTimeFilter cf. issue #5038 #}
|
|
{% if iterValue is iterable %}
|
|
{% for subIndex, subIterValue in iterValue %}
|
|
<input type="hidden" name="filters[{{ field }}][{{ key }}][{{ index }}][{{ subIndex }}]" value="{{ subIterValue }}">
|
|
{% endfor %}
|
|
{% else %}
|
|
<input type="hidden" name="filters[{{ field }}][{{ key }}][{{ index }}]" value="{{ iterValue }}">
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% else %}
|
|
<input type="hidden" name="filters[{{ field }}][{{ key }}]" value="{{ value }}">
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% else %}
|
|
<input type="hidden" name="filters[{{ field }}]" value="{{ fieldValue }}">
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endblock %}
|
|
|
|
{% if not ea.usePrettyUrls %}
|
|
<input type="hidden" name="crudAction" value="index">
|
|
<input type="hidden" name="crudControllerFqcn" value="{{ ea.request.query.get('crudControllerFqcn') }}">
|
|
<input type="hidden" name="page" value="1">
|
|
{% endif %}
|
|
|
|
<div class="form-group">
|
|
<div class="form-widget">
|
|
<twig:ea:Icon name="internal:search" class="content-search-icon" />
|
|
|
|
<label class="content-search-label" data-value="{{ app.request.get('query') }}">
|
|
<input class="form-control {{ app.request.get('query') is null ? 'is-blank' }}" type="search" name="query" value="{{ app.request.get('query') ?? '' }}" placeholder="{{ t('action.search', ea.i18n.translationParameters, 'EasyAdminBundle')|trans }}" spellcheck="false" autocorrect="off" onInput="this.parentNode.dataset.value=this.value"{% if ea.crud.currentAction == 'index' and ea.crud.autofocusSearch == true %} autofocus="autofocus"{% endif %}>
|
|
</label>
|
|
|
|
{% if app.request.get('query') %}
|
|
{% set search_reset_url = ea_url().unset('query') %}
|
|
{% if ea.usePrettyUrls %}
|
|
{% set search_reset_url = ea_url().unset('query').setController(ea.request.attributes.get('crudControllerFqcn')).setAction('index').set('page', 1) %}
|
|
{% endif %}
|
|
<a href="{{ search_reset_url }}" class="content-search-reset">
|
|
<twig:ea:Icon name="internal:xmark" />
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
</form>
|
|
{% endblock search %}
|
|
{% endif %}
|
|
</div>
|
|
{% endblock search_wrapper %}
|
|
|
|
{% block header_custom_menu_wrapper %}
|
|
<div class="navbar-custom-menu">
|
|
{% block header_custom_menu %}
|
|
<div class="dropdown user-menu-wrapper {{ is_granted(impersonator_permission) ? 'user-is-impersonated' }}">
|
|
<a class="user-details" type="button" data-bs-toggle="dropdown" data-bs-offset="0,5" aria-expanded="false">
|
|
{{ user_menu_avatar }}
|
|
{% if ea.userMenu.isNameDisplayed %}
|
|
<span class="user-name">{{ ea.userMenu.name }}</span>
|
|
{% endif %}
|
|
</a>
|
|
|
|
{{ user_menu_dropdown }}
|
|
</div>
|
|
{% endblock header_custom_menu %}
|
|
</div>
|
|
{% endblock header_custom_menu_wrapper %}
|
|
|
|
{% block settings_dropdown_wrapper %}
|
|
{{ settings_dropdown }}
|
|
{% endblock settings_dropdown_wrapper %}
|
|
{% endblock content_top_header %}
|
|
</aside>
|
|
|
|
<div class="content-wrapper">
|
|
{% block content %}
|
|
<article class="content">
|
|
{% block content_header_wrapper %}
|
|
{% set has_help_message = (ea.crud.helpMessage ?? '') is not empty %}
|
|
<section class="content-header">
|
|
{% block content_header %}
|
|
<div class="content-header-title">
|
|
<h1 class="title">
|
|
{% block content_title %}{% endblock %}
|
|
|
|
{% block content_help %}
|
|
{% if has_help_message %}
|
|
<a tabindex="0" class="content-header-help" data-bs-toggle="popover" data-bs-custom-class="ea-content-help-popover" data-bs-animation="true" data-bs-html="true" data-bs-placement="bottom" data-bs-trigger="focus" data-bs-content="{{ ea.crud.helpMessage|trans|e('html_attr') }}">
|
|
<twig:ea:Icon name="internal:circle-info" />
|
|
</a>
|
|
{% endif %}
|
|
{% endblock %}
|
|
</h1>
|
|
</div>
|
|
|
|
{% block page_actions_wrapper %}
|
|
<div class="page-actions">{% block page_actions %}{% endblock %}</div>
|
|
{% endblock %}
|
|
{% endblock content_header %}
|
|
</section>
|
|
{% endblock content_header_wrapper %}
|
|
|
|
<section id="main" class="content-body">
|
|
{% block main %}{% endblock %}
|
|
</section>
|
|
|
|
{% block content_footer_wrapper %}
|
|
{% set content_footer = block('content_footer') is defined ? block('content_footer') : '' %}
|
|
{% if content_footer is not empty %}
|
|
<section class="content-footer">
|
|
{{ content_footer }}
|
|
</section>
|
|
{% endif %}
|
|
{% endblock %}
|
|
</article>
|
|
{% endblock content %}
|
|
|
|
<div id="content-resizer-handler" class="resizer-handler resizer-handler-right"></div>
|
|
</div>
|
|
</section>
|
|
{% endblock wrapper %}
|
|
</div>
|
|
{% endblock wrapper_wrapper %}
|
|
|
|
{% block body_javascript %}{% endblock body_javascript %}
|
|
|
|
{% block configured_body_contents %}
|
|
{% for htmlContent in ea.assets.bodyContents ?? [] %}
|
|
{{ htmlContent|raw }}
|
|
{% endfor %}
|
|
{% endblock %}
|
|
</body>
|
|
{% endblock body %}
|
|
</html>
|