Skip to content

Provide read-only output for External Identity "view" action (CFM-319) #122

Merged
merged 2 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/resources/locales/en_US/information.po
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ msgstr "Please select the collaboration (CO) you wish to manage."
msgid "entity.id"
msgstr "ID: {0}"

msgid "noattrs"
msgstr "No attributes"

msgid "notset"
msgstr "not set"

msgid "pagination.format"
msgstr "Page {{page}} of {{pages}}, Viewing {{start}}-{{end}} of {{count}}"

Expand Down
11 changes: 11 additions & 0 deletions app/src/Model/Table/ExternalIdentitiesTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,17 @@ public function initialize(array $config): void {
'Urls'
]);
$this->setIndexContains(['PrimaryName']);
$this->setViewContains([
'PrimaryName',
'Addresses',
'AdHocAttributes',
'EmailAddresses',
'Identifiers',
'Names',
'Pronouns',
'TelephoneNumbers',
'Urls'
]);

$this->setAutoViewVars([
'statuses' => [
Expand Down
147 changes: 83 additions & 64 deletions app/src/View/Helper/FieldHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,76 +191,95 @@ public function control(string $fieldName,
*/

public function dateControl(string $fieldName, string $dateType=DateTypeEnum::Standard): string {
// A datetime field will be rendered as a plain text input with adjacent date and time pickers
// that will interact with the field value. Allowing direct access to the input field is for
// accessibility purposes.

$pickerType = $dateType;
// Special-case the very common "valid_from" and "valid_through" fields so we won't need
// to specify their types in fields.inc.
if($fieldName == 'valid_from') {
$pickerType = DateTypeEnum::FromTime;
}
if($fieldName == 'valid_through') {
$pickerType = DateTypeEnum::ThroughTime;
}

// Append the timezone to the label -- TODO: see that the timezone gets output to the display
$label = __d('field', $fieldName.".tz", [$this->_View->get('vv_tz')]);

// Create the options array for the (text input) form control
$coptions = [];
$coptions['class'] = 'form-control datepicker';

if($pickerType == DateTypeEnum::DateOnly) {
$coptions['placeholder'] = 'YYYY-MM-DD';
$coptions['pattern'] = '\d{4}-\d{2}-\d{2}';
$coptions['title'] = __d('field', 'datepicker.enterDate');
if($this->action == 'view') {
// return the date as plaintext
$coptions = [];
$entity = $this->getView()->get('vv_obj');
if (!empty($entity->$fieldName)) {
// Adjust the time back to the user's timezone
if ($dateType == DateTypeEnum::DateOnly) {
$controlCode = '<time>' . $entity->$fieldName->i18nFormat("yyyy-MM-dd", $this->getView()->get('vv_tz')) . '</time>';
} else {
$controlCode = '<time>' . $entity->$fieldName->i18nFormat("yyyy-MM-dd HH:mm:ss", $this->getView()->get('vv_tz')) . '</time>';
}
} else {
$controlCode = __d('information', 'notset');
}
// Return this to the generic control() function
return $this->control($fieldName, $coptions, ctrlCode: $controlCode, labelIsTextOnly: true);

} else {
$coptions['placeholder'] = 'YYYY-MM-DD HH:MM:SS';
$coptions['pattern'] = '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}';
$coptions['title'] = __d('field', 'datepicker.enterDateTime');
}
$coptions['id'] = str_replace("_", "-", $fieldName);
// A datetime field will be rendered as a plain text input with adjacent date and time pickers
// that will interact with the field value. Allowing direct access to the input field is for
// accessibility purposes.

$pickerType = $dateType;
// Special-case the very common "valid_from" and "valid_through" fields so we won't need
// to specify their types in fields.inc.
if ($fieldName == 'valid_from') {
$pickerType = DateTypeEnum::FromTime;
}
if ($fieldName == 'valid_through') {
$pickerType = DateTypeEnum::ThroughTime;
}

$entity = $this->getView()->get('vv_obj');
// Append the timezone to the label -- TODO: see that the timezone gets output to the display
$label = __d('field', $fieldName . ".tz", [$this->_View->get('vv_tz')]);

// Default the picker date to today
$now = FrozenTime::now();
$pickerDate = $now->i18nFormat('yyyy-MM-dd');

// Get the existing values, if present
if(!empty($entity->$fieldName)) {
// Adjust the time back to the user's timezone
if($pickerType == DateTypeEnum::DateOnly) {
$coptions['value'] = $entity->$fieldName->i18nFormat("yyyy-MM-dd", $this->getView()->get('vv_tz'));
// Create the options array for the (text input) form control
$coptions = [];
$coptions['class'] = 'form-control datepicker';

if ($pickerType == DateTypeEnum::DateOnly) {
$coptions['placeholder'] = 'YYYY-MM-DD';
$coptions['pattern'] = '\d{4}-\d{2}-\d{2}';
$coptions['title'] = __d('field', 'datepicker.enterDate');
} else {
$coptions['value'] = $entity->$fieldName->i18nFormat("yyyy-MM-dd HH:mm:ss", $this->getView()->get('vv_tz'));
$coptions['placeholder'] = 'YYYY-MM-DD HH:MM:SS';
$coptions['pattern'] = '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}';
$coptions['title'] = __d('field', 'datepicker.enterDateTime');
}
$pickerDate = $entity->$fieldName->i18nFormat("yyyy-MM-dd", $this->getView()->get('vv_tz'));
}

// Set the date picker floor year value (-100 years)
$pickerDateFT = new FrozenTime($pickerDate);
$pickerDateFT = $pickerDateFT->subYears(100);
$pickerFloor = $pickerDateFT->i18nFormat("yyyy-MM-dd");

$date_picker_args = [
'fieldName' => $fieldName,
'pickerDate' => $pickerDate,
'pickerType' => $pickerType,
'pickerFloor' => $pickerFloor
];

// Create a text field to hold our value and call the datePicker
$controlCode = $this->Form->text($fieldName, $coptions)
. $this->getView()->element('datePicker', $date_picker_args);
$coptions['id'] = str_replace("_", "-", $fieldName);

// Specify a class on the <li> form control wrapper
$liClass = "fields-datepicker";

// Pass everything to the generic control() function
return $this->control($fieldName, $coptions, ctrlCode: $controlCode, cssClass: $liClass);
$entity = $this->getView()->get('vv_obj');

// Default the picker date to today
$now = FrozenTime::now();
$pickerDate = $now->i18nFormat('yyyy-MM-dd');

// Get the existing values, if present
if(!empty($entity->$fieldName)) {
// Adjust the time back to the user's timezone
if($pickerType == DateTypeEnum::DateOnly) {
$coptions['value'] = $entity->$fieldName->i18nFormat("yyyy-MM-dd", $this->getView()->get('vv_tz'));
} else {
$coptions['value'] = $entity->$fieldName->i18nFormat("yyyy-MM-dd HH:mm:ss", $this->getView()->get('vv_tz'));
}
$pickerDate = $entity->$fieldName->i18nFormat("yyyy-MM-dd", $this->getView()->get('vv_tz'));
}

// Set the date picker floor year value (-100 years)
$pickerDateFT = new FrozenTime($pickerDate);
$pickerDateFT = $pickerDateFT->subYears(100);
$pickerFloor = $pickerDateFT->i18nFormat("yyyy-MM-dd");

$date_picker_args = [
'fieldName' => $fieldName,
'pickerDate' => $pickerDate,
'pickerType' => $pickerType,
'pickerFloor' => $pickerFloor
];

// Create a text field to hold our value and call the datePicker
$controlCode = $this->Form->text($fieldName, $coptions)
. $this->getView()->element('datePicker', $date_picker_args);

// Specify a class on the <li> form control wrapper
$liClass = "fields-datepicker";

// Pass everything to the generic control() function
return $this->control($fieldName, $coptions, ctrlCode: $controlCode, cssClass: $liClass);
}
}

/**
Expand Down
3 changes: 1 addition & 2 deletions app/templates/AdHocAttributes/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

// This view does not currently support read-only
if($vv_action == 'add' || $vv_action == 'edit') {
if($vv_action == 'add' || $vv_action == 'edit' || $vv_action == 'view') {
print $this->Field->control('tag');

print $this->Field->control('value');
Expand Down
3 changes: 1 addition & 2 deletions app/templates/Addresses/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

// This view does not currently support read-only
if($vv_action == 'add' || $vv_action == 'edit') {
if($vv_action == 'add' || $vv_action == 'edit' || $vv_action == 'view') {
// Dynamic required fields is automatically handled by FormHelper via the
// validation rules

Expand Down
3 changes: 1 addition & 2 deletions app/templates/EmailAddresses/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

// This view does currently not support read-only
if($vv_action == 'add' || $vv_action == 'edit') {
if($vv_action == 'add' || $vv_action == 'edit' || $vv_action == 'view') {
print $this->Field->control('mail');

print $this->Field->control('type_id', ['default' => $vv_default_type]);
Expand Down
1 change: 1 addition & 0 deletions app/templates/ExternalIdentities/columns.inc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
$indexColumns = [
'name' => [
'type' => 'link',
'action' => 'view',
'model' => 'primary_name',
'field' => 'full_name',
// XXX see comments in the controller about sorting on given vs family
Expand Down
3 changes: 1 addition & 2 deletions app/templates/ExternalIdentities/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

// This view does not currently support read-only
if($vv_action == 'add' || $vv_action == 'edit') {
if($vv_action == 'add' || $vv_action == 'edit' || $vv_action == 'view') {
// XXX sync status?
print $this->Field->control('status', ['empty' => false]);

Expand Down
1 change: 1 addition & 0 deletions app/templates/ExternalIdentityRoles/columns.inc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
$indexColumns = [
'title' => [
'type' => 'link',
'action' => 'view',
'sortable' => true
],
'affiliation_type_id' => [
Expand Down
3 changes: 1 addition & 2 deletions app/templates/ExternalIdentityRoles/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

// This view does not currently support read-only
if($vv_action == 'add' || $vv_action == 'edit') {
if($vv_action == 'add' || $vv_action == 'edit' || $vv_action == 'view') {
print $this->Field->control('affiliation_type_id', labelText: __d('field', 'affiliation'));

print $this->Field->control('status', ['empty' => false]);
Expand Down
3 changes: 1 addition & 2 deletions app/templates/Identifiers/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

// This view does not currently support read-only
if($vv_action == 'add' || $vv_action == 'edit') {
if($vv_action == 'add' || $vv_action == 'edit' || $vv_action == 'view') {
print $this->Field->control('identifier');

print $this->Field->control('type_id', ['default' => $vv_default_type]);
Expand Down
3 changes: 1 addition & 2 deletions app/templates/Names/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

// This view does not currently support read-only
if($vv_action == 'add' || $vv_action == 'edit') {
if($vv_action == 'add' || $vv_action == 'edit' || $vv_action == 'view') {
// Dynamic required fields is automatically handled by FormHelper via the
// validation rules, but we need to manually check permitted fields.

Expand Down
3 changes: 1 addition & 2 deletions app/templates/Pronouns/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

// This view does currently not support read-only
if($vv_action == 'add' || $vv_action == 'edit') {
if($vv_action == 'add' || $vv_action == 'edit' || $vv_action == 'view') {
print $this->Field->control('pronouns');

print $this->Field->control('type_id', ['default' => $vv_default_type]);
Expand Down
3 changes: 1 addition & 2 deletions app/templates/TelephoneNumbers/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

// This view does not currently support read-only
if($vv_action == 'add' || $vv_action == 'edit') {
if($vv_action == 'add' || $vv_action == 'edit' || $vv_action == 'view') {
// Dynamic required fields is automatically handled by FormHelper via the
// validation rules, but we need to manually check permitted fields.

Expand Down
3 changes: 1 addition & 2 deletions app/templates/Urls/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

// This view does currently not support read-only
if($vv_action == 'add' || $vv_action == 'edit') {
if($vv_action == 'add' || $vv_action == 'edit' || $vv_action == 'view') {
print $this->Field->control('url');

print $this->Field->control('type_id', ['default' => $vv_default_type]);
Expand Down
37 changes: 20 additions & 17 deletions app/templates/element/mveaCanvas.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
?>
<div id="mvea-canvas-title-container">
<h2><?= __d('information','global.attributes') ?></h2>
<?php if(!empty($vv_add_menu_links)): ?>
<?php if(!empty($vv_add_menu_links) && $vv_action == 'edit'): ?>
<div id="mvea-add-menu-container" class="field-actions">
<?= $this->element('menuAction', $action_args) ?>
</div>
Expand All @@ -92,22 +92,25 @@
?>
<div id="mvea-canvas" class="co-cards">
<div id="mvea-canvas-attributes-js" class="row row-cols-1 g-4<?= ($widgetCount > 1) ? ' row-cols-md-2' : ''?>">
<?php
foreach($attributes as $attr) {
if(!empty(($vv_obj[$attr]))) {
print $this->element(
'mveaJs',
[
'htmlId' => 'mvea-canvas-' . $attr . '-js',
'parentId' => $objId,
'mveaType' => $attr,
'entityType' => $vv_entity_type
]
);
<?php if($widgetCount == 0): ?>
<div class="no-attributes"><?= __d('information','noattrs') ?></div>
<?php else: ?>
<?php
foreach ($attributes as $attr) {
if (!empty(($vv_obj[$attr]))) {
print $this->element(
'mveaJs',
[
'htmlId' => 'mvea-canvas-' . $attr . '-js',
'parentId' => $objId,
'mveaType' => $attr,
'entityType' => $vv_entity_type
]
);
}
}
}
// TODO: Add the DOB as its own special card (CFM-261)
print $this->element('mveaModal');
?>
?>
<?php endif; ?>
<?= $this->element('mveaModal') ?>
</div>
</div>
5 changes: 3 additions & 2 deletions app/templates/element/mveaJs.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
$htmlId = $htmlId;
$parentId = $parentId;
$mveaType = $mveaType; // the type of MVEA we will fetch
$entityType = $entityType; // the type of entity continaing the MVEA (person, person_role, external_identity)
$entityType = $entityType; // the type of entity continaing the MVEA (person, person_role, external_identity, external_identity_role)

// Get the camel-case controller name and generate the title
$mveaController = Cake\Utility\Inflector::camelize($mveaType);
Expand Down Expand Up @@ -63,7 +63,8 @@
mveaType: '<?= $mveaType ?>',
mveaController: '<?= Cake\Utility\Inflector::dasherize($mveaController) ?>',
mveaTitle: '<?= $title ?>',
webroot: '<?= $this->request->getAttribute('webroot') ?>'
webroot: '<?= $this->request->getAttribute('webroot') ?>',
action: '<?= $vv_action ?>'
},
txt: JSON.parse('<?= json_encode($vueHelper->locales()) ?>'),
isLoading: true
Expand Down
Loading