1ce42304aSGreg Roach<?php 2ce42304aSGreg Roach 3ce42304aSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\ControlPanel; 4ce42304aSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\DataFixData; 5ce42304aSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\DataFixPage; 6ce42304aSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\DataFixUpdateAll; 73de8af15SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\HelpText; 86fd01894SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\ManageTrees; 9ce42304aSGreg Roachuse Fisharebest\Webtrees\I18N; 10ce42304aSGreg Roachuse Fisharebest\Webtrees\Module\ModuleDataFixInterface; 11ce42304aSGreg Roachuse Fisharebest\Webtrees\Tree; 12ce42304aSGreg Roachuse Fisharebest\Webtrees\View; 13ce42304aSGreg Roach 14ce42304aSGreg Roach/** 15ce42304aSGreg Roach * @var ModuleDataFixInterface $data_fix 16ce42304aSGreg Roach * @var string $latest_version 17ce42304aSGreg Roach * @var string $title 18ce42304aSGreg Roach * @var Tree $tree 19ce42304aSGreg Roach * @var string $pending_url 20ce42304aSGreg Roach */ 21ce42304aSGreg Roach 22ce42304aSGreg Roach?> 23ce42304aSGreg Roach 246fd01894SGreg Roach<?= view('components/breadcrumbs', ['links' => [route(ControlPanel::class) => I18N::translate('Control panel'), route(ManageTrees::class, ['tree' => $tree->name()]) => I18N::translate('Manage family trees'), route(DataFixPage::class, ['tree' => $tree->name()]) => view('icons/data-fix') . I18N::translate('Data fixes'), $title]]) ?> 25ce42304aSGreg Roach 26ce42304aSGreg Roach<h1><?= $title ?></h1> 27ce42304aSGreg Roach 28ce42304aSGreg Roach<form action="#" id="data-fix-options"> 29ce42304aSGreg Roach <p> 30ce42304aSGreg Roach <?= $data_fix->description() ?> 31ce42304aSGreg Roach </p> 32ce42304aSGreg Roach 33ce42304aSGreg Roach <?= $data_fix->fixOptions($tree) ?> 34ce42304aSGreg Roach 35ce42304aSGreg Roach <div class="row form-group"> 36ce42304aSGreg Roach <div class="col-sm-3"> 37ce42304aSGreg Roach </div> 38ce42304aSGreg Roach 39ce42304aSGreg Roach <div class="col-sm-9"> 40ce42304aSGreg Roach <button class="btn btn-primary" type="button" id="btn-search"> 41ce42304aSGreg Roach <?= view('icons/search') ?> 42ce42304aSGreg Roach <?= I18N::translate('Search') ?> 43ce42304aSGreg Roach </button> 44ce42304aSGreg Roach 45ce42304aSGreg Roach <button class="btn btn-primary" type="button" id="btn-update-all"> 46ce42304aSGreg Roach <?= view('icons/data-fix') ?> 47ce42304aSGreg Roach <?= I18N::translate('Update all') ?> 48ce42304aSGreg Roach </button> 49ce42304aSGreg Roach </div> 50ce42304aSGreg Roach </div> 51ce42304aSGreg Roach</form> 52ce42304aSGreg Roach 53ce42304aSGreg Roach<div id="data-fix-table-container" class="d-none"> 54ce42304aSGreg Roach <table 55ce42304aSGreg Roach id="data-fix-table" 56ce42304aSGreg Roach class="table table-bordered table-sm table-hover wt-data-fix-table" 57ce42304aSGreg Roach <?= view('lists/datatables-attributes') ?> 58ce42304aSGreg Roach data-server-side="true" 59ce42304aSGreg Roach data-filter="false" 60ad321e85SGreg Roach data-processing="true" 61ce42304aSGreg Roach data-sort="false" 62ce42304aSGreg Roach > 63ce42304aSGreg Roach <thead> 64ce42304aSGreg Roach <tr> 65ce42304aSGreg Roach <th class="w-75"> 66ce42304aSGreg Roach <?= I18N::translate('Record') ?> 67ce42304aSGreg Roach </th> 68ce42304aSGreg Roach <th class="w-25"> 69ce42304aSGreg Roach <?= view('icons/data-fix') ?> 70ce42304aSGreg Roach <?= I18N::translate('Data fix') ?> 71ce42304aSGreg Roach </th> 72ce42304aSGreg Roach </tr> 73ce42304aSGreg Roach </thead> 74ce42304aSGreg Roach <tbody> 75ce42304aSGreg Roach </tbody> 76ce42304aSGreg Roach </table> 773de8af15SGreg Roach 783de8af15SGreg Roach <hr> 793de8af15SGreg Roach 80d4786c66SGreg Roach <a href="#" data-bs-toggle="modal" data-bs-backdrop="static" data-bs-target="#wt-ajax-modal" data-wt-href="<?= e(route(HelpText::class, ['topic' => 'data-fixes'])) ?>"> 813de8af15SGreg Roach <?= view('icons/help') ?> 823de8af15SGreg Roach <?= I18N::translate('Why does this list include records that do not need to be updated?') ?> 833de8af15SGreg Roach </a> 84ce42304aSGreg Roach</div> 85ce42304aSGreg Roach 86ce42304aSGreg Roach<div id="data-fix-progress" class="d-none"> 87ce42304aSGreg Roach <div class="progress"> 88ce42304aSGreg Roach <div class="progress-bar" role="progressbar"></div> 89ce42304aSGreg Roach </div> 90ce42304aSGreg Roach</div> 91ce42304aSGreg Roach 92ce42304aSGreg Roach<?= view('modals/ajax') ?> 93ce42304aSGreg Roach 94ce42304aSGreg Roach<?php View::push('javascript') ?> 95ce42304aSGreg Roach<script> 96ce42304aSGreg Roach (function () { 97ce42304aSGreg Roach let form = document.getElementById("data-fix-options"); 98ce42304aSGreg Roach let container = document.getElementById("data-fix-table-container"); 99ce42304aSGreg Roach let table = document.getElementById("data-fix-table"); 100ce42304aSGreg Roach let progress = document.getElementById("data-fix-progress"); 101ce42304aSGreg Roach let progressbar = progress.querySelector('.progress-bar'); 102ce42304aSGreg Roach let queue = []; 103ce42304aSGreg Roach 104ce42304aSGreg Roach function getParams() { 105ce42304aSGreg Roach let formData = new FormData(form); 106ce42304aSGreg Roach let params = {}; 107ce42304aSGreg Roach formData.forEach(function (value, key) { 108ce42304aSGreg Roach params[key] = value; 109ce42304aSGreg Roach }); 110ce42304aSGreg Roach 111ce42304aSGreg Roach return params; 112ce42304aSGreg Roach } 113ce42304aSGreg Roach 114ce42304aSGreg Roach function addParamsToUrl(u) { 115ce42304aSGreg Roach let url = new URL(u); 116ce42304aSGreg Roach let formData = new FormData(form); 117ce42304aSGreg Roach formData.forEach(function (value, key) { 118ce42304aSGreg Roach url.searchParams.append(key, value); 119ce42304aSGreg Roach }); 120ce42304aSGreg Roach 121ce42304aSGreg Roach return url.toString(); 122ce42304aSGreg Roach 123ce42304aSGreg Roach } 124ce42304aSGreg Roach 125ce42304aSGreg Roach form.addEventListener('submit', function (event) { 126ce42304aSGreg Roach event.preventDefault(); 127ce42304aSGreg Roach }); 128ce42304aSGreg Roach 129ce42304aSGreg Roach container.addEventListener('click', function (event) { 130ce42304aSGreg Roach if ('updateUrl' in event.target.dataset) { 131ce42304aSGreg Roach event.preventDefault(); 132ce42304aSGreg Roach 133ce42304aSGreg Roach fetch(event.target.dataset.updateUrl, { 134ce42304aSGreg Roach body: getParams(), 135ce42304aSGreg Roach headers: new Headers({ 136ce42304aSGreg Roach 'X-CSRF-TOKEN': $('meta[name=csrf]').attr('content'), 137ce42304aSGreg Roach 'X-Requested-with': 'XMLHttpRequest', 138ce42304aSGreg Roach }), 139ce42304aSGreg Roach method: 'POST', 140ce42304aSGreg Roach }).then(function (response) { 141ce42304aSGreg Roach $(table).DataTable().ajax.reload(null, false); 142ce42304aSGreg Roach }).catch(function (error) { 143ce42304aSGreg Roach alert(error); 144ce42304aSGreg Roach }); 145ce42304aSGreg Roach } 146ce42304aSGreg Roach }); 147ce42304aSGreg Roach 148ce42304aSGreg Roach document.getElementById('btn-search').addEventListener('click', function (event) { 149ce42304aSGreg Roach event.preventDefault(); 150ce42304aSGreg Roach 151ce42304aSGreg Roach // If we were in the middle of doing "update all", stop processing. 152ce42304aSGreg Roach queue = []; 153ce42304aSGreg Roach 154ce42304aSGreg Roach progress.classList.add('d-none'); 155ce42304aSGreg Roach 156ce42304aSGreg Roach if ($.fn.dataTable.isDataTable(table)) { 157ce42304aSGreg Roach $(table).DataTable().ajax.reload(); 158ce42304aSGreg Roach } else { 159ce42304aSGreg Roach $(table).DataTable({ 160ce42304aSGreg Roach 'ajax': { 161*728c8c27SGreg Roach 'url': <?= json_encode(route(DataFixData::class, ['tree' => $tree->name(), 'data_fix' => $data_fix->name()]), JSON_THROW_ON_ERROR) ?>, 162ce42304aSGreg Roach 'data': function (data) { 163ce42304aSGreg Roach $.extend(data, getParams()); 164ce42304aSGreg Roach } 165ce42304aSGreg Roach } 166ce42304aSGreg Roach }); 167ce42304aSGreg Roach } 168ce42304aSGreg Roach 169ce42304aSGreg Roach container.classList.remove('d-none'); 170ce42304aSGreg Roach }); 171ce42304aSGreg Roach 172ce42304aSGreg Roach document.getElementById('btn-update-all').addEventListener('click', function (event) { 173ce42304aSGreg Roach event.preventDefault(); 174ce42304aSGreg Roach 175ce42304aSGreg Roach progressbar.innerHTML = ''; 176ce42304aSGreg Roach progressbar.style.width = '0%'; 177ce42304aSGreg Roach 178ce42304aSGreg Roach container.classList.add('d-none'); 179ce42304aSGreg Roach progress.classList.remove('d-none'); 180ce42304aSGreg Roach 181*728c8c27SGreg Roach let url = addParamsToUrl(<?= json_encode(route(DataFixUpdateAll::class, ['tree' => $tree->name(), 'data_fix' => $data_fix->name()]), JSON_THROW_ON_ERROR) ?>); 182ce42304aSGreg Roach 183ce42304aSGreg Roach fetch(url, { 184ce42304aSGreg Roach headers: new Headers({ 185ce42304aSGreg Roach 'X-CSRF-TOKEN': $('meta[name=csrf]').attr('content'), 186ce42304aSGreg Roach 'X-Requested-with': 'XMLHttpRequest', 187ce42304aSGreg Roach }), 188ce42304aSGreg Roach method: 'POST', 189ce42304aSGreg Roach }).then(function (response) { 190ce42304aSGreg Roach return response.json(); 191ce42304aSGreg Roach }).then(async function (data) { 192ce42304aSGreg Roach queue = data; 193ce42304aSGreg Roach while (queue.length > 0) { 194ce42304aSGreg Roach let datum = queue.shift(); 195ce42304aSGreg Roach await fetch(datum.url, { 196ce42304aSGreg Roach headers: new Headers({ 197ce42304aSGreg Roach 'X-CSRF-TOKEN': $('meta[name=csrf]').attr('content'), 198ce42304aSGreg Roach 'X-Requested-with': 'XMLHttpRequest', 199ce42304aSGreg Roach }), 200ce42304aSGreg Roach method: 'POST', 201ce42304aSGreg Roach }).then(function () { 202ce42304aSGreg Roach let progressbar = progress.querySelector('.progress-bar'); 203ce42304aSGreg Roach progressbar.innerHTML = datum.progress; 204ce42304aSGreg Roach progressbar.style.width = datum.percent; 205ce42304aSGreg Roach }); 206ce42304aSGreg Roach } 207ce42304aSGreg Roach }).catch(function (error) { 208ce42304aSGreg Roach progress.innerHTML = error; 209ce42304aSGreg Roach }); 210ce42304aSGreg Roach }); 211ce42304aSGreg Roach })(); 212ce42304aSGreg Roach</script> 213ce42304aSGreg Roach<?php View::endpush() ?> 214