Skip to content

Commit

Permalink
Provide read-only output for External Identity "view" action (CFM-319)
Browse files Browse the repository at this point in the history
  • Loading branch information
arlen committed Sep 21, 2023
1 parent 1af88ab commit 5299254
Show file tree
Hide file tree
Showing 19 changed files with 143 additions and 120 deletions.
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

0 comments on commit 5299254

Please sign in to comment.