diff --git a/app/src/Lib/Traits/IndexQueryTrait.php b/app/src/Lib/Traits/IndexQueryTrait.php index b62d65c11..8a6eb8f64 100644 --- a/app/src/Lib/Traits/IndexQueryTrait.php +++ b/app/src/Lib/Traits/IndexQueryTrait.php @@ -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); diff --git a/app/src/Lib/Traits/SearchFilterTrait.php b/app/src/Lib/Traits/SearchFilterTrait.php index 7827e6593..6b266a0b8 100644 --- a/app/src/Lib/Traits/SearchFilterTrait.php +++ b/app/src/Lib/Traits/SearchFilterTrait.php @@ -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 * @@ -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; } @@ -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), @@ -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; } @@ -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; + } } diff --git a/app/src/Model/Table/GroupsTable.php b/app/src/Model/Table/GroupsTable.php index a91ea9e38..4326cea6f 100644 --- a/app/src/Model/Table/GroupsTable.php +++ b/app/src/Model/Table/GroupsTable.php @@ -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' ] ]); @@ -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' + ] + ] ] ]); diff --git a/app/src/View/Helper/FieldHelper.php b/app/src/View/Helper/FieldHelper.php index 958d17005..544fbb7cd 100644 --- a/app/src/View/Helper/FieldHelper.php +++ b/app/src/View/Helper/FieldHelper.php @@ -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() diff --git a/app/src/View/Helper/FilterHelper.php b/app/src/View/Helper/FilterHelper.php index 1cd59b602..5c7b169ae 100644 --- a/app/src/View/Helper/FilterHelper.php +++ b/app/src/View/Helper/FilterHelper.php @@ -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; @@ -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}"; + } } \ No newline at end of file diff --git a/app/templates/element/filter/filter.php b/app/templates/element/filter/filter.php index aba4149e8..cff0d99d7 100644 --- a/app/templates/element/filter/filter.php +++ b/app/templates/element/filter/filter.php @@ -27,8 +27,23 @@ declare(strict_types = 1); -use Cake\Utility\Inflector; +?> + + +name = Models $modelsName = $this->name; @@ -68,8 +83,17 @@ $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), }; } diff --git a/app/templates/element/filter/peoplePicker.php b/app/templates/element/filter/peoplePicker.php new file mode 100644 index 000000000..5d6fc6f2f --- /dev/null +++ b/app/templates/element/filter/peoplePicker.php @@ -0,0 +1,65 @@ +Filter->calculateFieldParams($key, $label); +if(!empty($formParams['value']) && $key == 'person_id') { + $formParams['fullName'] = $this->Filter->getFullName((int)$formParams['value']); +} +$vv_autocomplete_arguments['formParams'] = $formParams; + +?> + +