1<?php 2 3declare(strict_types=1); 4 5use Fisharebest\Webtrees\I18N; 6use Fisharebest\Webtrees\Module\ModuleBlockInterface; 7use Fisharebest\Webtrees\View; 8use Illuminate\Support\Collection; 9 10/** 11 * @var Collection<string,ModuleBlockInterface> $all_blocks 12 * @var bool $can_reset 13 * @var Collection<int,ModuleBlockInterface> $main_blocks 14 * @var Collection<int,ModuleBlockInterface> $side_blocks 15 * @var string $title 16 * @var string $url_cancel 17 * @var string $url_save 18 */ 19 20?> 21 22<h2><?= $title ?></h2> 23 24<p class="mt-4 mb-1"> 25 <?= I18N::translate('Drag the blocks to change their position.') ?> 26</p> 27 28<form method="post" action="<?= e($url_save) ?>" id="edit-blocks"> 29 <div class="row row-cols-1 row-cols-sm-2 g-3" id="current-blocks"> 30 <div class="col"> 31 <div class="card h-100"> 32 <div class="card-body" id="main-blocks"> 33 <?php foreach ($main_blocks as $block_id => $block) : ?> 34 <?= view('edit-blocks-block', ['block_id' => $block_id, 'block' => $block]) ?> 35 <?php endforeach ?> 36 </div> 37 </div> 38 </div> 39 <div class="col"> 40 <div class="card h-100"> 41 <div class="card-body" id="side-blocks"> 42 <?php foreach ($side_blocks as $block_id => $block) : ?> 43 <?= view('edit-blocks-block', ['block_id' => $block_id, 'block' => $block]) ?> 44 <?php endforeach ?> 45 </div> 46 </div> 47 </div> 48 </div> 49 50 <p class="mt-4 mb-1"> 51 <?= I18N::translate('Add more blocks from the following list.') ?> 52 </p> 53 54 <div class="d-flex flex-wrap" id="available-blocks"> 55 <?php foreach ($all_blocks as $block_id => $block) : ?> 56 <?= view('edit-blocks-block', ['block_id' => $block_id, 'block' => $block]) ?> 57 <?php endforeach ?> 58 </div> 59 60 <hr> 61 62 <div> 63 <button class="btn btn-primary" type="submit"> 64 <?= view('icons/save') ?> 65 <?= I18N::translate('save') ?> 66 </button> 67 68 <a class="btn btn-secondary" href="<?= e($url_cancel) ?>"> 69 <?= view('icons/cancel') ?> 70 <?= I18N::translate('cancel') ?> 71 </a> 72 73 <?php if ($can_reset) : ?> 74 <button class="btn btn-link" id="defaults" type="submit" name="defaults" value="on" data-wt-confirm="<?= I18N::translate('Restore the default block layout') ?>" onclick="return confirm(this.dataset.confirm)"> 75 <?= I18N::translate('Restore the default block layout') ?> 76 </button> 77 <?php endif ?> 78 </div> 79 80 <?= csrf_field() ?> 81</form> 82 83<?php View::push('styles') ?> 84<style> 85 #available-blocks .wt-icon-delete { 86 display: none; 87 } 88 89 #current-blocks .wt-icon-help { 90 display: none; 91 } 92</style> 93<?php View::endpush() ?> 94 95<?php View::push('javascript') ?> 96<script> 97 new Sortable(document.getElementById("main-blocks"), { 98 group: "blocks", 99 handle: ".wt-icon-drag-handle", 100 animation: 150, 101 pull: "clone", 102 }); 103 104 new Sortable(document.getElementById("side-blocks"), { 105 group: "blocks", 106 handle: ".wt-icon-drag-handle", 107 animation: 150, 108 pull: "clone", 109 }); 110 111 new Sortable(document.getElementById("available-blocks"), { 112 group: { 113 name: "blocks", 114 pull: "clone", 115 put: false, 116 }, 117 handle: ".wt-icon-drag-handle", 118 animation: 150, 119 sort: false, 120 }); 121 122 document.getElementById('current-blocks').addEventListener('click', function (event) { 123 if (event.target.closest('.wt-icon-delete')) { 124 const wtBlock = event.target.closest('.wt-block'); 125 wtBlock.parentNode.removeChild(wtBlock); 126 } 127 }); 128 129 document.getElementById('edit-blocks').addEventListener('submit', function (event) { 130 document.querySelectorAll('#main-blocks input').forEach((element) => { element.setAttribute('name', 'main[]'); }) 131 document.querySelectorAll('#side-blocks input').forEach((element) => { element.setAttribute('name', 'side[]'); }) 132 }); 133</script> 134<?php View::endpush() ?> 135