diff --git a/app/resources/locales/en_US/field.po b/app/resources/locales/en_US/field.po index 58cb5352..4c8afd54 100644 --- a/app/resources/locales/en_US/field.po +++ b/app/resources/locales/en_US/field.po @@ -29,8 +29,8 @@ # When adding entries to this file, group non-model specific translations at the top, # then model specific translations alphabetically by model. -msgid "action" -msgstr "Action" +msgid "actions" +msgstr "{0,plural,=1{Action} other{Actions}}" msgid "actor" msgstr "Actor" @@ -159,6 +159,9 @@ msgstr "Plugin" msgid "postal_code" msgstr "Postal Code" +msgid "primary" +msgstr "Primary" + msgid "primary_name" msgstr "Primary Name" @@ -243,6 +246,9 @@ msgstr "Value" msgid "verified" msgstr "Verified" +msgid "unverified" +msgstr "Unverified" + msgid "ApiUsers.privileged.desc" msgstr "A privileged API user has full access to the CO. Unprivileged API users may be granted specific permissions where supported." diff --git a/app/resources/locales/en_US/information.po b/app/resources/locales/en_US/information.po index 7e6551f1..4cd7ed3a 100644 --- a/app/resources/locales/en_US/information.po +++ b/app/resources/locales/en_US/information.po @@ -56,3 +56,9 @@ msgstr "There are no records to display." msgid "global.title.none" msgstr "No title" + +msgid "global.value.none" +msgstr "No value" + +msgid "global.visit.link" +msgstr "Visit link" diff --git a/app/resources/locales/en_US/operation.po b/app/resources/locales/en_US/operation.po index e337e64f..fc01b4b6 100644 --- a/app/resources/locales/en_US/operation.po +++ b/app/resources/locales/en_US/operation.po @@ -27,6 +27,9 @@ msgid "activate" msgstr "Activate" +msgid "add" +msgstr "Add" + msgid "add.a" msgstr "Add a New {0}" diff --git a/app/src/Controller/PeopleController.php b/app/src/Controller/PeopleController.php index 4577075c..c1d2e5e1 100644 --- a/app/src/Controller/PeopleController.php +++ b/app/src/Controller/PeopleController.php @@ -76,4 +76,66 @@ public function beforeRender(\Cake\Event\EventInterface $event) { return parent::beforeRender($event); } + + /** + * Person overview / canvas + * + * @since COmanage Registry v5.0.0 + */ + + public function canvas(string $id) { + /* XXX Simply including parent::edit() is nearly all that's required - but we need + to delve a little deeper to get data from underlying relationships. We might send a contains() + override to parent::edit() which would allow this to be more DRY + // Keep the following as an example for now. + parent::edit($id, false); + + // We've just set the vv_supertitle in the parent controller. + // Pass it to the title for use in the breadcrumbs. + $this->set('vv_title', $this->viewBuilder()->getVar('vv_supertitle')); + */ + + /* The following is nearly identical to parent::edit/view */ + $modelsName = $this->name; + $table = $this->$modelsName; + $tableName = $table->getTable(); + $query = $table->findById($id); + + // This contain() directive is the primary deviation from standard edit()/view(). + // We need to drill down to deeper related models for display. + $query = $query->contain([ + 'PrimaryName', + 'Names' => ['Types'], + 'Addresses' => ['Types'], + 'AdHocAttributes', + 'EmailAddresses' => ['Types'], + 'GroupMembers', + 'GroupOwners', + 'Identifiers' => ['Types'], + 'PersonRoles' => ['Cous','Types'], + 'Pronouns', + 'TelephoneNumbers' => ['Types'], + 'Urls' => ['Types'] + ]); + + try { + // Pull the current record + $obj = $query->firstOrFail(); + } catch(\Exception $e) { + // findById throws Cake\Datasource\Exception\RecordNotFoundException + $this->Flash->error($e->getMessage()); + // XXX This redirects to an Exception page because $id is not found. + // XXX A 404 with error would be better. + return $this->generateRedirect((int)$id); + } + + $this->set('vv_obj', $obj); + $this->getPrimaryLink(); + $this->populateAutoViewVars($obj); + + $this->set('vv_title', $table->generateDisplayField($obj)); + $this->set('vv_supertitle', $table->generateDisplayField($obj)); + // Pass the display field also into subtitle for dealing with External IDs + $this->set('vv_subtitle', $table->generateDisplayField($obj)); + } } \ No newline at end of file diff --git a/app/src/Controller/StandardController.php b/app/src/Controller/StandardController.php index a62131ff..e3490a4a 100644 --- a/app/src/Controller/StandardController.php +++ b/app/src/Controller/StandardController.php @@ -331,8 +331,9 @@ public function edit(string $id) { } catch(\Exception $e) { // findById throws Cake\Datasource\Exception\RecordNotFoundException - $this->Flash->error($e->getMessage()); + // XXX This redirects to an Exception page because $id is not found. + // XXX A 404 with error would be better. return $this->generateRedirect((int)$id); } @@ -724,8 +725,9 @@ public function view($id = null) { } catch(\Exception $e) { // findById throws Cake\Datasource\Exception\RecordNotFoundException - $this->Flash->error($e->getMessage()); + // XXX This redirects to an Exception page because $id is not found. + // XXX A 404 with error would be better. return $this->generateRedirect((int)$id); } @@ -742,6 +744,9 @@ public function view($id = null) { // We don't use a trait for this since each table will implement different logic $this->set('vv_title', __d('operation', 'view.ai', $table->generateDisplayField($obj))); + $this->set('vv_supertitle', $table->generateDisplayField($obj)); + // Pass the display field also into subtitle for dealing with External IDs + $this->set('vv_subtitle', $table->generateDisplayField($obj)); } else { // Default view title is the object display field $field = $table->getDisplayField(); diff --git a/app/src/Lib/Traits/PrimaryLinkTrait.php b/app/src/Lib/Traits/PrimaryLinkTrait.php index ec52aa6c..bd02b2b6 100644 --- a/app/src/Lib/Traits/PrimaryLinkTrait.php +++ b/app/src/Lib/Traits/PrimaryLinkTrait.php @@ -46,7 +46,7 @@ trait PrimaryLinkTrait { private $unkeyedActions = ['add', 'index']; // Actions where the primary link can be obtained by looking up the record ID - private $lookupActions = ['delete', 'edit', 'view']; + private $lookupActions = ['delete', 'edit', 'canvas', 'view']; // Where to redirect on add or edit, can be 'self', 'index', or 'primaryLink' private $redirectGoal = 'index'; diff --git a/app/src/Lib/Util/StringUtilities.php b/app/src/Lib/Util/StringUtilities.php index 51a8e9c9..c7056b82 100644 --- a/app/src/Lib/Util/StringUtilities.php +++ b/app/src/Lib/Util/StringUtilities.php @@ -46,7 +46,7 @@ class StringUtilities { public static function columnKey($modelsName, $c, $tz=null, $useCustomClMdlLabel=false): string { if(strpos($c, "_id", strlen($c)-3)) { // Key is of the form field_id, use .ct label instead - $k = $this->foreignKeyToClassName($c); + $k = self::foreignKeyToClassName($c); return __d('controller', $k, [1]); } diff --git a/app/src/Model/Table/PeopleTable.php b/app/src/Model/Table/PeopleTable.php index f495b9ce..4e46ac8c 100644 --- a/app/src/Model/Table/PeopleTable.php +++ b/app/src/Model/Table/PeopleTable.php @@ -150,6 +150,7 @@ public function initialize(array $config): void { 'entity' => [ 'delete' => ['platformAdmin', 'coAdmin'], 'edit' => ['platformAdmin', 'coAdmin'], + 'canvas' => ['platformAdmin', 'coAdmin'], 'view' => ['platformAdmin', 'coAdmin'] ], // Actions that operate over a table (ie: do not require an $id) diff --git a/app/templates/AdHocAttributes/columns.inc b/app/templates/AdHocAttributes/columns.inc index dd2f93b6..4d5aecbe 100644 --- a/app/templates/AdHocAttributes/columns.inc +++ b/app/templates/AdHocAttributes/columns.inc @@ -41,6 +41,6 @@ $bulkActions = [ $subnav = [ 'name' => 'person', - 'active' => 'attributes', + 'active' => 'person', 'subActive' => 'ad_hoc_attributes' ]; \ No newline at end of file diff --git a/app/templates/AdHocAttributes/fields-nav.inc b/app/templates/AdHocAttributes/fields-nav.inc index 8cddfe10..9b42482f 100644 --- a/app/templates/AdHocAttributes/fields-nav.inc +++ b/app/templates/AdHocAttributes/fields-nav.inc @@ -30,6 +30,6 @@ $topLinks = []; $subnav = [ 'name' => 'person', - 'active' => 'attributes', + 'active' => 'person', 'subActive' => 'ad_hoc_attributes' ]; \ No newline at end of file diff --git a/app/templates/Addresses/columns.inc b/app/templates/Addresses/columns.inc index 257f4b09..e5c58c12 100644 --- a/app/templates/Addresses/columns.inc +++ b/app/templates/Addresses/columns.inc @@ -45,6 +45,6 @@ $bulkActions = [ $subnav = [ 'name' => 'person', - 'active' => 'attributes', + 'active' => 'person', 'subActive' => 'addresses' ]; diff --git a/app/templates/Addresses/fields-nav.inc b/app/templates/Addresses/fields-nav.inc index 08574e5a..86686fdf 100644 --- a/app/templates/Addresses/fields-nav.inc +++ b/app/templates/Addresses/fields-nav.inc @@ -30,6 +30,6 @@ $topLinks = []; $subnav = [ 'name' => 'person', - 'active' => 'attributes', + 'active' => 'person', 'subActive' => 'addresses' ]; \ No newline at end of file diff --git a/app/templates/EmailAddresses/columns.inc b/app/templates/EmailAddresses/columns.inc index da915ca1..4c40977c 100644 --- a/app/templates/EmailAddresses/columns.inc +++ b/app/templates/EmailAddresses/columns.inc @@ -41,6 +41,6 @@ $bulkActions = [ $subnav = [ 'name' => 'person', - 'active' => 'attributes', + 'active' => 'person', 'subActive' => 'email_addresses' ]; \ No newline at end of file diff --git a/app/templates/EmailAddresses/fields-nav.inc b/app/templates/EmailAddresses/fields-nav.inc index 14b67797..797d856b 100644 --- a/app/templates/EmailAddresses/fields-nav.inc +++ b/app/templates/EmailAddresses/fields-nav.inc @@ -30,6 +30,6 @@ $topLinks = []; $subnav = [ 'name' => 'person', - 'active' => 'attributes', // default for person. 'external identities' are special cased + 'active' => 'person', // default for person. 'external identities' are special cased 'subActive' => 'email_addresses' ]; \ No newline at end of file diff --git a/app/templates/Identifiers/columns.inc b/app/templates/Identifiers/columns.inc index 48c82927..8a27be5d 100644 --- a/app/templates/Identifiers/columns.inc +++ b/app/templates/Identifiers/columns.inc @@ -56,6 +56,6 @@ $bulkActions = [ $subnav = [ 'name' => 'person', - 'active' => 'attributes', + 'active' => 'person', 'subActive' => 'identifiers' ]; \ No newline at end of file diff --git a/app/templates/Identifiers/fields-nav.inc b/app/templates/Identifiers/fields-nav.inc index bcacd714..17db0dc9 100644 --- a/app/templates/Identifiers/fields-nav.inc +++ b/app/templates/Identifiers/fields-nav.inc @@ -30,6 +30,6 @@ $topLinks = []; $subnav = [ 'name' => 'person', - 'active' => 'attributes', + 'active' => 'person', 'subActive' => 'identifiers' ]; \ No newline at end of file diff --git a/app/templates/Names/columns.inc b/app/templates/Names/columns.inc index feeda0cd..e142b78a 100644 --- a/app/templates/Names/columns.inc +++ b/app/templates/Names/columns.inc @@ -58,6 +58,6 @@ $bulkActions = [ $subnav = [ 'name' => 'person', - 'active' => 'attributes', + 'active' => 'person', 'subActive' => 'names' ]; \ No newline at end of file diff --git a/app/templates/Names/fields-nav.inc b/app/templates/Names/fields-nav.inc index d333f883..955afd92 100644 --- a/app/templates/Names/fields-nav.inc +++ b/app/templates/Names/fields-nav.inc @@ -30,6 +30,6 @@ $topLinks = []; $subnav = [ 'name' => 'person', - 'active' => 'attributes', + 'active' => 'person', 'subActive' => 'names' ]; \ No newline at end of file diff --git a/app/templates/People/canvas.php b/app/templates/People/canvas.php new file mode 100644 index 00000000..2d7397b0 --- /dev/null +++ b/app/templates/People/canvas.php @@ -0,0 +1,172 @@ + 'person', + 'active' => 'canvas' + ]; + + $linkFilter = []; + if(!empty($vv_primary_link) && !empty($this->request->getQuery($vv_primary_link))) { + $linkFilter = [$vv_primary_link => $this->request->getQuery($vv_primary_link)]; + } + + $objId = null; + if(!empty($vv_obj)) { + $objId = $vv_obj->id; + } + + // Person Attributes to display. + $attributes = [ + 'names', + 'email_addresses', + 'identifiers', + 'ad_hoc_attributes', + 'addresses', + 'telephone_numbers', + 'urls', + 'pronouns' + ]; + + // Count the number of widgets that will be displayed + $widgetCount = 0; + foreach($attributes as $attr) { + if(!empty($vv_obj[$attr])) { + $widgetCount++; + } + } + +?> + +
+ +