您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

362 行
20KB

  1. {# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #}
  2. {# @var entities \EasyCorp\Bundle\EasyAdminBundle\Collection\EntityDtoCollection #}
  3. {# @var paginator \EasyCorp\Bundle\EasyAdminBundle\Orm\EntityPaginator #}
  4. {% extends ea.templatePath('layout') %}
  5. {% trans_default_domain ea.i18n.translationDomain %}
  6. {% block body_id entities|length > 0 ? 'ea-index-' ~ entities|first.name : '' %}
  7. {% block body_class 'index' ~ (entities|length > 0 ? ' index-' ~ entities|first.name : '') %}
  8. {% block content_title %}
  9. {{ 'index'|sov_trans_admin_title(translation_entity_name) }}
  10. {% endblock %}
  11. {% block content_breadcrumb %}
  12. {{ include('@LcSov/adminlte/block/breadcrumb.html.twig') }}
  13. {% endblock content_breadcrumb %}
  14. {% set has_batch_actions = batch_actions|length > 0 %}
  15. {% block page_actions %}
  16. {% endblock page_actions %}
  17. {% block main %}
  18. {% block main_prepend %}{% endblock %}
  19. {% set _block_index_id = block('index_id') %}
  20. <div {% if _block_index_id %}id="{% block index_id %}{% endblock index_id %}"{% endif %}>
  21. {# sort can be multiple; let's consider the sorting field the first one #}
  22. {% set sort_field_name = app.request.get('sort')|keys|first %}
  23. {% set sort_order = app.request.get('sort')|first %}
  24. {% set some_results_are_hidden = false %}
  25. {% set has_footer = entities|length != 0 %}
  26. {% set has_search = ea.crud.isSearchEnabled %}
  27. {% set has_filters = filters|length > 0 %}
  28. {% set has_datagrid_tools = has_search or has_filters %}
  29. {% block card_wrapper %}
  30. <div class="card card-table card-outline card-primary">
  31. {% block card_header_wrapper %}
  32. <div class="card-header">
  33. <span data-toggle="tooltip" class="badge badge-light" data-original-title="Total" title="Total">
  34. {{ paginator.numResults }} résultats
  35. </span>
  36. <div class="btn-list float-sm-right">
  37. <div class="global-actions">
  38. {% block global_actions %}
  39. {% for action in global_actions %}
  40. {{ include(action.templatePath, { action: action }, with_context = false) }}
  41. {% endfor %}
  42. {% endblock global_actions %}
  43. </div>
  44. {% block batch_actions %}
  45. {% if has_batch_actions %}
  46. <div class="batch-actions" style="display: none">
  47. {% for action in batch_actions %}
  48. {{ include(action.templatePath, { action: action }, with_context = false) }}
  49. {% endfor %}
  50. </div>
  51. {% endif %}
  52. {% endblock %}
  53. </div>
  54. </div>
  55. {% endblock %}
  56. {% block card_body_wrapper %}
  57. <div class="card-body">
  58. <div class="">
  59. <table class="table table-bordered table-hover table-striped">
  60. <thead>
  61. {% block table_head %}
  62. <tr>
  63. {% if has_batch_actions %}
  64. <th class="">
  65. <input type="hidden" id="batch_form_entityIds" value=""/>
  66. <span><input type="checkbox"
  67. class="form-check-input m-0 align-middle form-batch-checkbox-all"></span>
  68. </th>
  69. {% endif %}
  70. {% set ea_sort_asc = constant('EasyCorp\\Bundle\\EasyAdminBundle\\Config\\Option\\SortOrder::ASC') %}
  71. {% set ea_sort_desc = constant('EasyCorp\\Bundle\\EasyAdminBundle\\Config\\Option\\SortOrder::DESC') %}
  72. {% for field in fields ?? [] %}
  73. {% set field = field.getAsDto() %}
  74. {% if field.isDisplayedOn('index') %}
  75. {% set is_sorting_field = ea.search.isSortingField(field.property) %}
  76. {% set next_sort_direction = is_sorting_field ? (ea.search.sortDirection(field.property) == ea_sort_desc ? ea_sort_asc : ea_sort_desc) : ea_sort_desc %}
  77. {% set column_icon = is_sorting_field ? (next_sort_direction == ea_sort_desc ? 'fa-arrow-up' : 'fa-arrow-down') : 'fa-sort' %}
  78. <th class="{{ is_sorting_field ? 'sorted' }} {{ field.isVirtual ? 'field-virtual' }} {% if field.textAlign %}text-{{ field.textAlign }}{% endif %}"
  79. dir="{{ ea.i18n.textDirection }}">
  80. {% if field.isSortable %}
  81. <a href="{{ ea_url({ page: 1, sort: { (field.property): next_sort_direction } }).includeReferrer() }}">
  82. {% if field.label is not null %}
  83. {{ field.label|raw }}
  84. {% else %}
  85. {{ field.getProperty|sov_trans_admin_field_index(translation_entity_name) }}
  86. {% endif %}
  87. <i class="fa fa-fw {{ column_icon }}"></i>
  88. </a>
  89. {% else %}
  90. {% if field.label is not null %}
  91. <span>{{ field.label|raw }}</span>
  92. {% else %}
  93. <span>{{ field.getProperty|sov_trans_admin_field_index(translation_entity_name) }}</span>
  94. {% endif %}
  95. {% endif %}
  96. </th>
  97. {% endif %}
  98. {% endfor %}
  99. <th class="w-1" {% if ea.crud.showEntityActionsAsDropdown %}width="10px"{% endif %}
  100. dir="{{ ea.i18n.textDirection }}">
  101. <span class="sr-only">{{ 'action.entity_actions'|trans(ea.i18n.translationParameters, 'EasyAdminBundle') }}</span>
  102. </th>
  103. </tr>
  104. {% endblock table_head %}
  105. {% block table_filters %}
  106. {{ include('@LcSov/adminlte/block/table_filters.html.twig') }}
  107. {% endblock table_filters %}
  108. </thead>
  109. <tbody>
  110. {% block table_body %}
  111. {% for entity in entities %}
  112. {% if not entity.isAccessible %}
  113. {% set some_results_are_hidden = true %}
  114. {% else %}
  115. <tr data-id="{{ entity.primaryKeyValueAsString }}">
  116. {% if has_batch_actions %}
  117. <td><input type="checkbox" class="form-batch-checkbox"
  118. value="{{ entity.primaryKeyValue }}"></td>
  119. {% endif %}
  120. {% for field in entity.fields %}
  121. <td class="{{ field.property == sort_field_name ? 'sorted' }} text-{{ field.textAlign }} {{ field.cssClass }}"
  122. dir="{{ ea.i18n.textDirection }}">
  123. {# {% if (field.property == 'id' or field.property == 'title') %}#}
  124. {# #}{# {% if (field == 'title' or field== 'id') and (metadata.dataType=="string" or metadata.dataType=="integer") and _entity_config.name != 'ProductFamilyAdvancedEditing' %} #}
  125. {# <a class="link-as-text"#}
  126. {# href="{{ ea_url_short(null, 'edit', entity.instance.id) }}">#}
  127. {# {{ include(field.templatePath, { field: field, entity: entity }, with_context = false) }}#}
  128. {# </a>#}
  129. {# {% else %}#}
  130. {{ include(field.templatePath, { field: field, entity: entity }, with_context = false) }}
  131. {# {% endif %}#}
  132. </td>
  133. {% endfor %}
  134. {% block entity_actions %}
  135. <td class="actions text-right">
  136. {% if entity.actions.count > 0 %}
  137. {% set has_dropdown = false %}
  138. {% set in_dropdown_class = 'in-dropdown' %}
  139. {% for action in entity.actions %}
  140. {% if not (in_dropdown_class in action.cssClass) %}
  141. {{ include(action.templatePath, { action: action, entity: entity, isIncludedInDropdown: 0 }, with_context = false) }}
  142. {% else %}
  143. {% set has_dropdown = true %}
  144. {% endif %}
  145. {% endfor %}
  146. {% if has_dropdown %}
  147. <div class="dropdown dropdown-actions">
  148. <a class="dropdown-toggle btn btn-secondary btn-sm"
  149. href="#"
  150. role="button" data-toggle="dropdown"
  151. aria-haspopup="true"
  152. aria-expanded="false">
  153. </a>
  154. <div class="dropdown-menu dropdown-menu-right">
  155. {% for action in entity.actions %}
  156. {% if in_dropdown_class in action.cssClass %}
  157. {{ include(action.templatePath, { action: action, isIncludedInDropdown: 1 }, with_context = false) }}
  158. {% endif %}
  159. {% endfor %}
  160. </div>
  161. </div>
  162. {% endif %}
  163. {% endif %}
  164. {% if not ea.crud.showEntityActionsAsDropdown %}
  165. {% else %}
  166. {% endif %}
  167. </td>
  168. {% endblock entity_actions %}
  169. </tr>
  170. {% endif %}
  171. {% else %}
  172. <tr>
  173. <td class="no-results" colspan="100">
  174. {{ 'datagrid.no_results'|trans(ea.i18n.translationParameters, 'EasyAdminBundle') }}
  175. </td>
  176. </tr>
  177. {% endfor %}
  178. {% if some_results_are_hidden %}
  179. <tr class="datagrid-row-empty">
  180. <td class="text-center" colspan="{{ entities|first.fields|length + 1 }}">
  181. <span class="datagrid-row-empty-message"><i
  182. class="fa fa-lock mr-1"></i> {{ 'datagrid.hidden_results'|trans({}, 'EasyAdminBundle') }}</span>
  183. </td>
  184. </tr>
  185. {% endif %}
  186. {% endblock table_body %}
  187. </tbody>
  188. </table>
  189. {% block filters_form %}
  190. {% if filters_form is defined %}
  191. {{ form_start(filters_form, {'attr' :{'id' : 'filters-form'}}) }}
  192. {# <input type="hidden" name="entity" value="{{ _entity_config.name }}">
  193. <input type="hidden" name="menuIndex" value="{{ app.request.get('menuIndex') }}">
  194. <input type="hidden" name="submenuIndex" value="{{ app.request.get('submenuIndex') }}">
  195. <input type="hidden" name="sortField" value="{{ app.request.get('sortField', '') }}">
  196. <input type="hidden" name="sortDirection"
  197. value="{{ app.request.get('sortDirection', 'DESC') }}">
  198. <input type="hidden" name="action" value="{{ app.request.get('action') }}"> #}
  199. {{ form_end(filters_form) }}
  200. {% endif %}
  201. {% endblock filters_form %}
  202. </div>
  203. </div>
  204. {% endblock %}
  205. {% block card_footer_wrapper %}
  206. <div class="card-footer">
  207. <div class="row">
  208. {% block paginator %}
  209. {{ include(ea.templatePath('crud/paginator')) }}
  210. {% endblock paginator %}
  211. </div>
  212. </div>
  213. {% endblock %}
  214. {% block delete_form %}
  215. {{ include('@EasyAdmin/crud/includes/_delete_form.html.twig', with_context = false) }}
  216. {% endblock delete_form %}
  217. {% if has_filters %}
  218. {{ include('@EasyAdmin/crud/includes/_filters_modal.html.twig') }}
  219. {% endif %}
  220. {% if has_batch_actions %}
  221. {{ include('@EasyAdmin/crud/includes/_batch_action_modal.html.twig', {}, with_context = false) }}
  222. {% endif %}
  223. </div>
  224. {% endblock card_wrapper %}
  225. {% block main_append %}{% endblock %}
  226. {% endblock main %}
  227. {% block body_javascript %}
  228. {{ parent() }}
  229. <script type="text/javascript">
  230. $(function () {
  231. /* $('.action-delete').on('click', function (e) {
  232. e.preventDefault();
  233. const formAction = $(this).attr('formaction');
  234. $('#modal-delete').modal({backdrop: true, keyboard: true})
  235. .off('click', '#modal-delete-button')
  236. .on('click', '#modal-delete-button', function () {
  237. let deleteForm = $('#delete-form');
  238. deleteForm.attr('action', formAction);
  239. deleteForm.submit();
  240. });
  241. });*/
  242. /* {% if filters|length > 0 %}
  243. const filterModal = document.querySelector('#modal-filters');
  244. const removeFilter = function (field) {
  245. field.closest('form').querySelectorAll('input[name^="filters[' + field.dataset.filterProperty + ']"]').forEach(hidden => {
  246. hidden.remove();
  247. });
  248. field.remove();
  249. }
  250. document.querySelector('#modal-clear-button').addEventListener('click', function () {
  251. filterModal.querySelectorAll('.filter-field').forEach(filterField => {
  252. removeFilter(filterField);
  253. });
  254. filterModal.querySelector('form').submit();
  255. });
  256. document.querySelector('#modal-apply-button').addEventListener('click', function () {
  257. filterModal.querySelectorAll('.filter-checkbox:not(:checked)').forEach(notAppliedFilter => {
  258. removeFilter(notAppliedFilter.closest('.filter-field'));
  259. });
  260. filterModal.querySelector('form').submit();
  261. });
  262. // HTML5 specifies that a <script> tag inserted with innerHTML should not execute
  263. // https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#Security_considerations
  264. // That's why we can't use just 'innerHTML'. See https://stackoverflow.com/a/47614491/2804294
  265. let setInnerHTML = function (element, htmlContent) {
  266. element.innerHTML = htmlContent;
  267. Array.from(element.querySelectorAll('script')).forEach(oldScript => {
  268. const newScript = document.createElement('script');
  269. Array.from(oldScript.attributes)
  270. .forEach(attr => newScript.setAttribute(attr.name, attr.value));
  271. newScript.appendChild(document.createTextNode(oldScript.innerHTML));
  272. oldScript.parentNode.replaceChild(newScript, oldScript);
  273. });
  274. };
  275. let filterButton = document.querySelector('.action-filters-button');
  276. filterButton.addEventListener('click', function (event) {
  277. let filterModal = document.querySelector(filterButton.dataset.modal);
  278. let filterModalBody = filterModal.querySelector('.modal-body');
  279. $(filterModal).modal({backdrop: true, keyboard: true});
  280. filterModalBody.innerHTML = '<div class="fa-3x px-3 py-3 text-muted text-center"><i class="fas fa-circle-notch fa-spin"></i></div>';
  281. $.get(filterButton.getAttribute('href'), function (response) {
  282. setInnerHTML(filterModalBody, response);
  283. });
  284. event.preventDefault();
  285. event.stopPropagation();
  286. });
  287. filterButton.setAttribute('href', filterButton.getAttribute('data-href'));
  288. filterButton.removeAttribute('data-href');
  289. filterButton.classList.remove('disabled');
  290. {% endif %}
  291. {% if has_batch_actions %}
  292. {% endif %}*/
  293. });
  294. </script>
  295. {% if app.request.get('query') is not empty %}
  296. <script type="text/javascript">
  297. const search_query = "{{ ea.search.query|default('')|e('js') }}";
  298. // the original query is prepended to allow matching exact phrases in addition to single words
  299. $('#main').find('table tbody td:not(.actions)').highlight($.merge([search_query], search_query.split(' ')));
  300. </script>
  301. {% endif %}
  302. {% endblock %}