Skip to content

Commit

Permalink
Add additional selector for family members
Browse files Browse the repository at this point in the history
  • Loading branch information
ddrury committed Nov 28, 2024
1 parent b272b59 commit 57bc4b4
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 23 deletions.
71 changes: 67 additions & 4 deletions app/Module/CensusAssistantModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Registry;
use Fisharebest\Webtrees\Validator;
use Fisharebest\Webtrees\Services\RelationshipService;
use Fisharebest\Webtrees\Services\TreeService;
use Illuminate\Support\Collection;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

Expand All @@ -33,13 +36,21 @@
use function response;
use function str_repeat;
use function str_replace;
use function strip_tags;
use function view;

/**
* Class CensusAssistantModule
*/
class CensusAssistantModule extends AbstractModule
{
private TreeService $tree_service;

public function __construct(TreeService $tree_service)
{
$this->tree_service = $tree_service;
}

/**
* How should this module be identified in the control panel, etc.?
*
Expand All @@ -62,13 +73,24 @@ public function description(): string
*
* @return ResponseInterface
*/
public function postCensusHeaderAction(ServerRequestInterface $request): ResponseInterface
public function postCensusInitializeAction(ServerRequestInterface $request): ResponseInterface
{
$census_class = Validator::parsedBody($request)->string('census');
$params = (array) $request->getParsedBody();

$html = $this->censusTableHeader(new $census_class());
$census_class = $params['census'];
$xref = $params['xref'];
$tree_id = (int) $params['tree_id'];

Check failure on line 82 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Cannot cast mixed to int.

Check failure on line 82 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Cannot cast mixed to int.
$census = new $census_class();
$individual = Registry::individualFactory()->make($xref, $this->tree_service->find($tree_id));

Check failure on line 84 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Ignored error pattern #^Parameter \#1 \$xref of method Fisharebest\\Webtrees\\Contracts\\IndividualFactoryInterface\:\:make\(\) expects string, mixed given\.$# (argument.type) in path /home/runner/work/webtrees/webtrees/app/Module/CensusAssistantModule.php is expected to occur 1 time, but occurred 2 times.

Check failure on line 84 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Ignored error pattern #^Parameter \#1 \$xref of method Fisharebest\\Webtrees\\Contracts\\IndividualFactoryInterface\:\:make\(\) expects string, mixed given\.$# (argument.type) in path /home/runner/work/webtrees/webtrees/app/Module/CensusAssistantModule.php is expected to occur 1 time, but occurred 2 times.

return response($html);
assert($individual instanceof Individual);

$data = json_encode([
'header' => $this->censusTableHeader($census),
'family' => $this->familyMembers($individual, $census),

Check failure on line 90 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Parameter #2 $census of method Fisharebest\Webtrees\Module\CensusAssistantModule::familyMembers() expects Fisharebest\Webtrees\Census\CensusInterface, object given.

Check failure on line 90 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Parameter #2 $census of method Fisharebest\Webtrees\Module\CensusAssistantModule::familyMembers() expects Fisharebest\Webtrees\Census\CensusInterface, object given.
]);

return response($data);

Check failure on line 93 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Parameter #1 $content of function response expects array<mixed>|object|string, string|false given.

Check failure on line 93 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Parameter #1 $content of function response expects array<mixed>|object|string, string|false given.
}

/**
Expand Down Expand Up @@ -261,4 +283,45 @@ public function censusTableRow(CensusInterface $census, Individual $individual,

return '<tr class="wt-census-assistant-row">' . $html . '</tr>';
}

/**
* Produce a list of close family members
* for quick selection
*
* @param Individual $individual
* @param CensusInterface $census
*
* @return array<int, array<string, mixed>>
*/
private function familyMembers(Individual $individual, CensusInterface $census): array
{
$relationship_service = Registry::container()->get(RelationshipService::class);
$max_age = (int) $individual->tree()->getPreference('MAX_ALIVE_AGE');
$censusYear = (int) substr($census->censusDate(), -4);
$options = [];
$individuals = new Collection();
$families = $individual->childFamilies()
->merge($individual->childStepFamilies())
->merge($individual->spouseFamilies())
->merge($individual->spouseStepFamilies());

$families->each(function ($family) use (&$individuals) {
$individuals = $individuals
->merge($family->spouses())
->merge($family->children());
});

$individuals->unique()->each(function (Individual $indi) use (&$options, $individual, $censusYear, $max_age, $relationship_service) {
$birth_year = (int) $indi->getBirthDate()->minimumDate()->format('%Y') ?: 0;

Check failure on line 315 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Cannot call method format() on mixed.

Check failure on line 315 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Cannot call method minimumDate() on mixed.

Check failure on line 315 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Cannot cast mixed to int.

Check failure on line 315 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Cannot call method format() on mixed.

Check failure on line 315 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Cannot call method minimumDate() on mixed.

Check failure on line 315 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Cannot cast mixed to int.
$death_year = (int) $indi->getDeathDate()->maximumDate()->format('%Y') ?: ($birth_year > 0 ? $birth_year + $max_age : PHP_INT_MAX);

Check failure on line 316 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Cannot call method format() on mixed.

Check failure on line 316 in app/Module/CensusAssistantModule.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Cannot call method format() on mixed.
$text = sprintf("%s (%s, %s)", strip_tags($indi->fullName()), $relationship_service->getCloseRelationshipName($individual, $indi), strip_tags($indi->lifespan()));
$options[] = [
'value' => $indi->xref(),
'text' => $text,
'disabled' => ($censusYear < $birth_year) || ($censusYear > $death_year),
];
});

return $options;
}
}
82 changes: 63 additions & 19 deletions resources/views/modules/census-assistant.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ use Fisharebest\Webtrees\View;
</div>
</div>

<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<label for="census-assistant-family" class="input-group-text">
<?= I18N::translate('Family members') ?>
</label>
</div>
<select id="census-assistant-family" class="form-select" name="census-assistant-family"></select>
</div>
</div>

<div class="table-responsive">
<table class="table table-sm table-borderless small wt-census-assistant-table" id="census-assistant-table">
<thead class="wt-census-assistant-header"></thead>
Expand All @@ -86,6 +97,10 @@ use Fisharebest\Webtrees\View;

<?php View::push('javascript') ?>
<script>
const family_tomselect = new TomSelect(document.getElementById('census-assistant-family'), {
placeholder: "<?= I18N::translate('Select a family member') ?>"
});

// When a census date/place is selected, activate the census-assistant
function censusAssistantSelect () {
const select = this;
Expand Down Expand Up @@ -113,14 +128,21 @@ use Fisharebest\Webtrees\View;

let formData = new FormData();
formData.append('census', census);
formData.append('xref', '<?= $individual->xref() ?>');
formData.append('tree_id', '<?= $individual->tree()->id() ?>');
formData.append('_csrf', document.querySelector('meta[name=csrf]').content);

const url = <?= json_encode(route('module', ['module' => 'GEDFact_assistant', 'action' => 'CensusHeader', 'tree' => $individual->tree()->name()]), JSON_THROW_ON_ERROR) ?>;
webtrees.httpPost(url, formData)
.then(response => response.text())
.then(function (text) {
document.querySelector('#census-assistant-table thead').innerHTML = text;
fetch(<?= json_encode(route('module', ['module' => 'GEDFact_assistant', 'action' => 'CensusInitialize', 'tree' => $individual->tree()->name()]), JSON_THROW_ON_ERROR) ?>, {
credentials: 'same-origin',
body: formData,
method: 'POST',
})
.then(response => response.text())
.then(function (text) {
const data = JSON.parse(text);
document.querySelector('#census-assistant-table thead').innerHTML = data.header;
document.querySelector('#census-assistant-table tbody').innerHTML = '';
family_tomselect.addOptions([data.family], false);
});
}

Expand All @@ -130,21 +152,29 @@ use Fisharebest\Webtrees\View;
this.setAttribute('hidden', '');
document.getElementById('census-assistant').removeAttribute('hidden');
// Set the current individual as the head of household.
censusAssistantAdd();
censusAssistantAdd('individual');

return false;
}

// Add the currently selected individual to the census
function censusAssistantAdd () {
var censusSelector = document.querySelector('.census-selector');
var census = censusSelector.options[censusSelector.selectedIndex].dataset.wtCensus;
var indi_selector = document.querySelector('#census-assistant-individual');
var xref = indi_selector.options[indi_selector.selectedIndex].value;
var headInput = document.querySelector('#census-assistant-table td input');
var head = headInput === null ? xref : headInput.value;
function censusAssistantAdd(caller) {
const selector = document.querySelector('#census-assistant-' + caller);
const xref = selector.options[selector.selectedIndex].value;
const rows = Array.from(document.querySelectorAll('#census-assistant-table tbody tr td:first-child input')).map(input => input.value);

let formData = new FormData();
// Is the selected individual already in the census?
if (xref !== '' && rows.includes(xref)) {
webtrees.resetTomSelect(document.querySelector('#census-assistant-individual').tomselect, '', '');

return false;
}

const censusSelector = document.querySelector('.census-selector');
const census = censusSelector.options[censusSelector.selectedIndex].dataset.wtCensus;
const headInput = document.querySelector('#census-assistant-table td input');
const head = headInput === null ? xref : headInput.value;
const formData = new FormData();
formData.append('census', census);
formData.append('_csrf', document.querySelector('meta[name=csrf]').content);
formData.append('head', head);
Expand All @@ -156,12 +186,21 @@ use Fisharebest\Webtrees\View;
.then(response => response.text())
.then(function (text) {
document.querySelector('#census-assistant-table tbody').insertAdjacentHTML('beforeend', text);
webtrees.resetTomSelect(document.querySelector('#census-assistant-individual').tomselect, '', '');
});
document.querySelector('#census-assistant-individual').tomselect.clear(true);
document.querySelector('#census-assistant-individual').tomselect.clearOptions();
if (xref !== '') {
family_tomselect.updateOption(xref, {...family_tomselect.options[xref], ...{disabled: true}});
family_tomselect.clear(true);
}
});

return false;
}

family_tomselect.on('change', () => {
censusAssistantAdd('family');
});

document.querySelectorAll('.census-selector').forEach(function (el) {
el.addEventListener('change', censusAssistantSelect);
});
Expand All @@ -171,13 +210,18 @@ use Fisharebest\Webtrees\View;
});

document.querySelectorAll('.census-assistant-add').forEach(function (el) {
el.addEventListener('click', censusAssistantAdd);
el.addEventListener('click', () => {
censusAssistantAdd('individual')});
});

document.querySelectorAll('#census-assistant-table').forEach(function (el) {
el.addEventListener('click', function (el) {
el.addEventListener('click', (el) => {
if (el.target.matches('.wt-icon-delete')) {
el.target.closest('tr').remove();
let line = el.target.closest('tr');
let xref = line.firstChild.firstChild.value;
line.remove();
family_tomselect.updateOption(xref, {...family_tomselect.options[xref], ...{disabled: false}});
family_tomselect.clear(true);
}
});
});
Expand Down

0 comments on commit 57bc4b4

Please sign in to comment.