Skip to content

CFM-291_filter_groups_by_member #196

Merged
merged 7 commits into from
May 6, 2024
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: 5 additions & 1 deletion app/src/Lib/Traits/IndexQueryTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,11 @@ public function getIndexQuery(bool $pickerMode = false, array $requestParams = [
$this->viewBuilder()
->getVar('vv_tz'));

// Pass any additional field filter confiration in the view
// Extra View Variables
foreach ($table->getViewVars() as $key => $variable) {
$this->set($key, $variable);
}
// Pass any additional field filter configuration in the view
$this->set('vv_searchable_attributes_extras', $table->getSearchFiltersExtras());
if(!empty($searchableAttributes)) {
$this->set('vv_searchable_attributes', $searchableAttributes);
Expand Down
32 changes: 30 additions & 2 deletions app/src/Lib/Traits/SearchFilterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ trait SearchFilterTrait {
*/
private array $searchFiltersExtras = [];

/**
* List of view Vars
* @var array
*/
private array $viewVars = [];

/**
* Optional filter configuration that dictates display state and allows for related models
*
Expand Down Expand Up @@ -135,7 +141,7 @@ public function addJoins(Query $query, string $attribute, ServerRequest $request
* @since COmanage Registry v5.0.0
*/
public function constructDateComparisonClause(QueryExpression $exp, string $attributeWithModelPrefix, array $dates): QueryExpression {
// Both are empty, just return
// Both are empty, return
if (empty($dates[0]) && empty($dates[1])) {
return $exp;
}
Expand Down Expand Up @@ -243,9 +249,22 @@ public function getSearchableAttributes(string $controller, string $vv_tz=null):
}

$filterType = $f['type'] ?? 'string';
// Custom boolean use cases
if(\in_array($f['type'], ['isNull', 'isNotNull'])) {
$filterType = 'boolean';
}
// Picker configuration
if(isset($f['picker'])) {
$autocompleteArgs = [
'type' => 'default',
'fieldName' => $field,
'personType' => $f['picker']['type'],
'htmlId' => $field, // This is the input ID
'viewConfigParameters' => $f['picker']['configuration']
];
$this->viewVars['vv_autocomplete_arguments'] = $autocompleteArgs;
}

$this->searchFilters[$field] = [
'type' => $filterType,
'label' => $f['label'] ?? StringUtilities::columnKey($fieldName, $field, $vv_tz, true),
Expand All @@ -256,7 +275,7 @@ public function getSearchableAttributes(string $controller, string $vv_tz=null):
}

foreach ($this->filterMetadataFields() as $column => $type) {
// If the column is an array then we are accessing the Metadata fields. Skip
// If the column is an array, then we are accessing the Metadata fields. Skip
if(is_array($type)) {
continue;
}
Expand Down Expand Up @@ -323,4 +342,13 @@ public function getSearchFiltersExtras(): array
return $this->searchFiltersExtras;
}

/**
* Get View Vars
*
* @since COmanage Registry v5.0.0
*/
public function getViewVars(): array
{
return $this->viewVars;
}
}
26 changes: 26 additions & 0 deletions app/src/Model/Table/GroupsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ public function initialize(array $config): void {
'groupTypes' => [
'type' => 'enum',
'class' => 'GroupTypeEnum'
],
// Required for peoplePicker
'cosettings' => [
'type' => 'auxiliary',
'model' => 'CoSettings'
],
// Required for peoplePicker
'types' => [
'type' => 'auxiliary',
'model' => 'Types'
]
]);

Expand All @@ -154,6 +164,22 @@ public function initialize(array $config): void {
'model' => 'Identifiers',
'active' => true,
'order' => 4
],
'person_id' => [
'type' => 'integer',
'model' => 'GroupMembers',
'active' => true,
'order' => 5,
'picker' => [
'type' => 'person',
'configuration' => [
// For the Groups Filtering block we want to
// pick/GET from the entire CO pool of people
'action' => 'GET',
// The co configuration will fall throught the default configuration
'for' => 'co'
]
]
]
]);

Expand Down
34 changes: 34 additions & 0 deletions app/src/View/Helper/FieldHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,40 @@ public function calculateLabelAndDescription(string $fieldName): array
return [$label, $desc];
}

/**
* Calculate the list of classes for the li element
*
* @return string
*/
public function calculateLiClasses(): string
{
$fieldName = $this->getView()->get('fieldName');
$vv_field_arguments = $this->getView()->get('vv_field_arguments');

// Class calculation by field Type
$classes = match ($this->getFieldType($fieldName)) {
'date',
'datetime',
'timestamp' => 'fields-datepicker ',
default => ''
};

// Class calculation by field name
$classes .= match ($fieldName) {
'source_record' => 'source-record ',
'retry_interval',
'login' => 'subfield ',
default => ''
};

// Class calculation by type of Info Div
if(isset($vv_field_arguments['autocomplete'])) {
$classes .= 'fields-people-autocomplete ';
}

return $classes;
}

/**
* Emit a date/time form control.
* This is a wrapper function for $this->control()
Expand Down
18 changes: 18 additions & 0 deletions app/src/View/Helper/FilterHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
namespace App\View\Helper;

use Cake\Collection\Collection;
use Cake\ORM\TableRegistry;
use Cake\Utility\{Inflector, Hash};
use Cake\View\Helper;

Expand Down Expand Up @@ -157,4 +158,21 @@ public function getHiddenFields(): array
->filter(fn($value, $key) => !\in_array($key, $searchable_parameters, true) && $key != 'page')
->toArray();
}

/**
* Construct Full Name from Person ID
*
* @param int $personId
*
* @return string
*/
public function getFullName(int $personId): string
{
if(empty($personId)) {
return '';
}
$ModelTable = TableRegistry::getTableLocator()->get('Names');
$person = $ModelTable->primaryName($personId);
return "{$person->given} {$person->family}";
}
}
26 changes: 25 additions & 1 deletion app/templates/element/filter/filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,23 @@

declare(strict_types = 1);

use Cake\Utility\Inflector;
?>

<script type="text/javascript">
$(function() {
// Remove the friendly representation of the person_id input element before submiting
const filterForm = document.getElementById("top-filters-form");
filterForm.addEventListener('formdata', (event) => {
if(event.formData.has('person_id')) {
const personId = $(filterForm).find('#person_id')[0].getAttribute('datapersonid')
event.formData.set('person_id', personId)
}
});
});
</script>

<?php
use Cake\Utility\Inflector;

// $this->name = Models
$modelsName = $this->name;
Expand Down Expand Up @@ -68,8 +83,17 @@
<?php
foreach($field_generic_columns as $key => $options) {
$elementArguments = compact('options', 'key');
// Set in SearchfilterTrait.php
if($vv_autocomplete_arguments['fieldName'] === $key) {
// Picker is a custom type.
// This is why we calculate it here, and we
// only use it to pick the correct element
$options['type'] = 'picker';
}

print match($options['type']) {
'date' => $this->element('filter/dateSingle', $elementArguments),
'picker' => $this->element('filter/peoplePicker', $elementArguments),
default => $this->element('filter/default', $elementArguments),
};
}
Expand Down
65 changes: 65 additions & 0 deletions app/templates/element/filter/peoplePicker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php
/**
* COmanage Registry People Picker
*
* Portions licensed to the University Corporation for Advanced Internet
* Development, Inc. ("UCAID") under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* UCAID licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @link https://www.internet2.edu/comanage COmanage Project
* @package registry
* @since COmanage Registry v5.0.0
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/


/*
* Parameters:
* $columns : array, required
* $key : string, required
* $options : array, required
*/

declare(strict_types = 1);

use Cake\Utility\{Inflector};

// $columns = the passed parameter $indexColumns as found in columns.inc; provides overrides for labels and sorting.
$columns = $vv_indexColumns;

$wrapperCssClass = 'filter-active';
if(empty($options['active'])) {
$wrapperCssClass = 'filter-inactive';
}

$label = Inflector::humanize(
Inflector::underscore(
$options['label'] ?? $columns[$key]['label']
)
);

// Get the Field configuration
$formParams = $this->Filter->calculateFieldParams($key, $label);
if(!empty($formParams['value']) && $key == 'person_id') {
$formParams['fullName'] = $this->Filter->getFullName((int)$formParams['value']);
}
$vv_autocomplete_arguments['formParams'] = $formParams;

?>

<div class="filter-standard <?= $wrapperCssClass ?>">
<?= $this->element('peopleAutocomplete', $vv_autocomplete_arguments) ?>
</div>
6 changes: 5 additions & 1 deletion app/templates/element/filter/topButtons.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@
$populated_vvar = lcfirst(Inflector::pluralize(Inflector::camelize($key)));
$button_label = 'Range';
if(isset($$populated_vvar) && isset($$populated_vvar[$params])) {
// Get label name from AutoViewPopulated vars
$button_label = $$populated_vvar[$params];
} elseif(!is_array($params)) {
$button_label = $params;
if(isset($vv_searchable_attributes_extras)) {
// Extras use case
if(!empty($vv_searchable_attributes_extras)) {
$flattenedSearchableAttributesExtras = Hash::flatten($vv_searchable_attributes_extras);
$filteredFlattenedSearchableAttributesExtras = array_filter(
$flattenedSearchableAttributesExtras,
Expand All @@ -54,6 +56,8 @@
if(!empty($filteredFlattenedSearchableAttributesExtras)) {
$button_label = array_pop($filteredFlattenedSearchableAttributesExtras);
}
} elseif ($key == 'person_id') {
$button_label = $this->Filter->getFullName((int)$params);
}
}

Expand Down
24 changes: 1 addition & 23 deletions app/templates/element/form/listItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,6 @@
$fieldName = $arguments['fieldName'];
$this->set('vv_field_arguments', $arguments);

// Class calculation by field Type
$classes = match ($this->Field->getFieldType($fieldName)) {
'date',
'datetime',
'timestamp' => 'fields-datepicker ',
default => ''
};

// Class calculation by field name
$classes .= match ($fieldName) {
'source_record' => 'source-record ',
'retry_interval',
'login' => 'subfield ',
default => ''
};

// Class calculation by type of Info Div
if(isset($arguments['autocomplete'])) {
$classes .= 'fields-people-autocomplete ';
}


// If an attribute is frozen, inject a special link to unfreeze it, since
// the attribute is read-only and the admin can't simply uncheck the setting
if($fieldName == 'frozen' && $this->Field->getEntity()->frozen) {
Expand Down Expand Up @@ -101,6 +79,6 @@

?>

<li class="<?= trim($classes) ?>">
<li class="<?= trim($this->Field->calculateLiClasses()) ?>">
<?= $this->element('form/fieldDiv')?>
</li>
2 changes: 1 addition & 1 deletion app/templates/element/javascript.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
$('#top-filters-submit').addClass("tss-rebalance");
} else {
$('#top-filters-submit').removeClass("tss-rebalance");
}
}
}
});

Expand Down
Loading