index.blade.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. @extends('layouts.app')
  2. @section('content')
  3. <div class="row mb-2 page-header-row">
  4. <div class="col-12 col-md-6 page-header-title">
  5. <h3>Каталог общий</h3>
  6. </div>
  7. <div class="col-12 col-md-6 text-md-end page-header-actions">
  8. @if($canExportTechnicalDescriptions)
  9. <button type="button" id="technical-description-export-button"
  10. class="btn btn-sm mb-1 btn-outline-primary page-action-btn" disabled
  11. data-bs-toggle="modal" data-bs-target="#technicalDescriptionExportModal">
  12. <i class="bi bi-file-earmark-word page-action-btn__icon"></i>
  13. <span class="page-action-btn__label">Техописания</span>
  14. </button>
  15. @endif
  16. @if(hasPermission('common-catalog.import'))
  17. <button type="button" class="btn btn-sm mb-1 btn-primary page-action-btn"
  18. data-bs-toggle="modal" data-bs-target="#commonCatalogImportModal">
  19. <i class="bi bi-upload page-action-btn__icon"></i>
  20. <span class="page-action-btn__label">Импорт</span>
  21. </button>
  22. @endif
  23. @if(hasPermission('common-catalog.export'))
  24. <form action="{{ route('common-catalog.export') }}" method="POST" class="d-inline">
  25. @csrf
  26. <button type="submit" class="btn btn-sm mb-1 btn-primary page-action-btn">
  27. <i class="bi bi-download page-action-btn__icon"></i>
  28. <span class="page-action-btn__label">Экспорт</span>
  29. </button>
  30. </form>
  31. @endif
  32. @if(hasPermission('common-catalog.create'))
  33. <a href="{{ route('common-catalog.create', ['nav' => $nav ?? null]) }}"
  34. class="btn btn-sm mb-1 btn-primary page-action-btn">
  35. <i class="bi bi-plus-lg page-action-btn__icon"></i>
  36. <span class="page-action-btn__label">Добавить</span>
  37. </a>
  38. @endif
  39. </div>
  40. </div>
  41. @include('partials.table', [
  42. 'id' => $id,
  43. 'header' => $header,
  44. 'strings' => $items,
  45. 'routeName' => 'common-catalog.show',
  46. 'routeParam' => 'commonCatalogItem',
  47. 'nav' => $nav,
  48. 'selectable' => $canExportTechnicalDescriptions,
  49. ])
  50. @include('partials.pagination', ['items' => $items])
  51. @if(hasPermission('common-catalog.import'))
  52. <div class="modal fade" id="commonCatalogImportModal" tabindex="-1"
  53. aria-labelledby="commonCatalogImportModalLabel" aria-hidden="true">
  54. <div class="modal-dialog modal-fullscreen-sm-down">
  55. <div class="modal-content">
  56. <div class="modal-header">
  57. <h1 class="modal-title fs-5" id="commonCatalogImportModalLabel">Импорт общего каталога</h1>
  58. <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
  59. </div>
  60. <div class="modal-body">
  61. <p class="small text-muted">
  62. Используйте утверждённый XLSX-шаблон. Существующие позиции обновляются по артикулу.
  63. </p>
  64. <form action="{{ route('common-catalog.import') }}" method="POST" enctype="multipart/form-data">
  65. @csrf
  66. @include('partials.input', [
  67. 'title' => 'XLSX файл',
  68. 'name' => 'import_file',
  69. 'type' => 'file',
  70. 'required' => true,
  71. ])
  72. @include('partials.submit', ['name' => 'Импорт'])
  73. </form>
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. @endif
  79. @if($canExportTechnicalDescriptions)
  80. <div class="modal fade" id="technicalDescriptionExportModal" tabindex="-1"
  81. aria-labelledby="technicalDescriptionExportModalLabel" aria-hidden="true">
  82. <div class="modal-dialog">
  83. <div class="modal-content">
  84. <div class="modal-header">
  85. <h1 class="modal-title fs-5" id="technicalDescriptionExportModalLabel">Экспорт технических описаний</h1>
  86. <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
  87. </div>
  88. <form id="technical-description-export-form"
  89. action="{{ route('common-catalog.technical-description.export') }}" method="POST">
  90. @csrf
  91. <div class="modal-body">
  92. <p>Выбрано позиций: <strong id="technical-description-selected-count">0</strong></p>
  93. <div id="technical-description-selected-inputs"></div>
  94. @include('partials.select', [
  95. 'name' => 'description_mode',
  96. 'title' => 'Содержимое описания',
  97. 'options' => $technicalDescriptionModes,
  98. 'value' => \App\Services\TechnicalDescriptionService::MODE_CHARACTERISTICS_SHORT,
  99. ])
  100. <div class="row mb-2">
  101. <div class="offset-md-4 col-md-8">
  102. <label class="form-check-label">
  103. <input type="checkbox" class="form-check-input" name="separate_documents" value="1">
  104. Отдельный DOCX для каждой позиции в ZIP
  105. </label>
  106. </div>
  107. </div>
  108. </div>
  109. <div class="modal-footer">
  110. <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Отмена</button>
  111. <button type="submit" class="btn btn-primary">Сформировать</button>
  112. </div>
  113. </form>
  114. </div>
  115. </div>
  116. </div>
  117. @push('scripts')
  118. <script>
  119. document.addEventListener('DOMContentLoaded', () => {
  120. const rows = Array.from(document.querySelectorAll('.js-table-row-select'));
  121. const selectAll = document.querySelector('.js-table-select-all');
  122. const button = document.getElementById('technical-description-export-button');
  123. const count = document.getElementById('technical-description-selected-count');
  124. const inputs = document.getElementById('technical-description-selected-inputs');
  125. const selected = () => rows.filter((checkbox) => checkbox.checked);
  126. const refresh = () => {
  127. const selectedRows = selected();
  128. button.disabled = selectedRows.length === 0;
  129. count.textContent = String(selectedRows.length);
  130. if (selectAll) {
  131. selectAll.checked = rows.length > 0 && selectedRows.length === rows.length;
  132. selectAll.indeterminate = selectedRows.length > 0 && selectedRows.length < rows.length;
  133. }
  134. };
  135. selectAll?.addEventListener('change', () => {
  136. rows.forEach((checkbox) => checkbox.checked = selectAll.checked);
  137. refresh();
  138. });
  139. rows.forEach((checkbox) => checkbox.addEventListener('change', refresh));
  140. document.getElementById('technical-description-export-form')?.addEventListener('submit', () => {
  141. inputs.replaceChildren(...selected().map((checkbox) => {
  142. const input = document.createElement('input');
  143. input.type = 'hidden';
  144. input.name = 'item_ids[]';
  145. input.value = checkbox.value;
  146. return input;
  147. }));
  148. });
  149. refresh();
  150. });
  151. </script>
  152. @endpush
  153. @endif
  154. @endsection