From 0f2c895d304fc1c7e5ceb00a5f6d5318fa36b238 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Fri, 8 Mar 2024 21:11:05 +0200 Subject: [PATCH] autocomplete improvements.Other improvements and minor fixes. --- Controller/GrouperGroupsController.php | 4 +-- Model/GrouperGroup.php | 12 +++++-- View/GrouperGroups/base.ctp | 1 + webroot/js/autocomplete.grouperplugin.js | 21 +++++++++++ webroot/js/autocomplete.js | 46 +++++++++++++++--------- webroot/js/members.js | 2 +- webroot/js/page/GroupMember.js | 6 +--- webroot/js/page/UserManager.js | 14 ++++++-- 8 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 webroot/js/autocomplete.grouperplugin.js diff --git a/Controller/GrouperGroupsController.php b/Controller/GrouperGroupsController.php index 1657acd..b9749a0 100644 --- a/Controller/GrouperGroupsController.php +++ b/Controller/GrouperGroupsController.php @@ -67,8 +67,8 @@ public function addSubscriber(): void $this->layout = null; $this->autoRender = false; - $groupName = urldecode($this->request->query['group']); - $addUserId = urldecode($this->request->query['userId']); + $groupName = $this->request->data['group']; + $addUserId = $this->request->data['userId']; // Need to see if coming from AdHoc or from a WG (Working Group) $groupNameFormatted = strpos($groupName, ':') === false ? 'ref:incommon-collab:' . $groupName . ':users' diff --git a/Model/GrouperGroup.php b/Model/GrouperGroup.php index e32c589..e90fb0b 100644 --- a/Model/GrouperGroup.php +++ b/Model/GrouperGroup.php @@ -217,8 +217,10 @@ public function findForPicker(int $coId, string $mode, ?string $term): array $idArr = $p['Identifier']; $emailArr = $p['EmailAddress']; $email = ''; + $email_short = ''; $emailLabel = ''; $id = ''; + $id_short = ''; $idLabel = ''; // Iterate over the email array @@ -228,6 +230,7 @@ public function findForPicker(int $coId, string $mode, ?string $term): array foreach($emailArr as $e) { if($e['type'] == $pickerEmailType) { $email = $e['mail']; + $email_short = mb_strimwidth($e['mail'], 0, 30, '...'); break; } } @@ -243,7 +246,8 @@ public function findForPicker(int $coId, string $mode, ?string $term): array } foreach($idArr as $i) { if($i['type'] == $pickerIdentifierType) { - $id = mb_strimwidth($i['identifier'], 0, 30, '...'); + $id_short = mb_strimwidth($i['identifier'], 0, 30, '...'); + $id = $i['identifier']; break; } } @@ -255,9 +259,13 @@ public function findForPicker(int $coId, string $mode, ?string $term): array 'value' => $p['CoPerson']['id'], 'label' => $label, 'email' => $email, + 'emailShort' => $email_short, 'emailLabel' => $emailLabel, + 'emailType' => $pickerEmailType, 'identifier' => $id, - 'identifierLabel' => $idLabel + 'identifierShort' => $id_short, + 'identifierLabel' => $idLabel, + 'identifierType' => $pickerIdentifierType ); } } diff --git a/View/GrouperGroups/base.ctp b/View/GrouperGroups/base.ctp index 8301abc..ef2c37d 100644 --- a/View/GrouperGroups/base.ctp +++ b/View/GrouperGroups/base.ctp @@ -16,6 +16,7 @@ echo $this->Html->meta( array('inline' => false) ); +print $this->Html->script('GrouperLiteWidget.autocomplete.grouperplugin') . PHP_EOL; print $this->element('GrouperLiteWidget.base-styles'); print $this->Html->css('GrouperLiteWidget.co-grouper-plugin') . PHP_EOL; diff --git a/webroot/js/autocomplete.grouperplugin.js b/webroot/js/autocomplete.grouperplugin.js new file mode 100644 index 0000000..0b37dc9 --- /dev/null +++ b/webroot/js/autocomplete.grouperplugin.js @@ -0,0 +1,21 @@ +$.widget( "ui.autocomplete", $.ui.autocomplete, { + _renderMenu: function( ul, items ) { + var that = this; + $.each( items, function( index, item ) { + that._renderItemData( ul, item ); + }); + }, + _renderItem: function( ul, item ) { + let itemMarkup = '
'; + itemMarkup += '
' + item.label + '
'; + if(item?.emailShort != '') { + itemMarkup += ''; + } + if(item?.identifierShort != '') { + itemMarkup += '
' + item.identifierLabel + '' + item.identifierShort + '
'; + } + itemMarkup += '
'; + + return $("
  • ").append(itemMarkup).appendTo(ul); + } +}); \ No newline at end of file diff --git a/webroot/js/autocomplete.js b/webroot/js/autocomplete.js index ae8235a..52d81c7 100644 --- a/webroot/js/autocomplete.js +++ b/webroot/js/autocomplete.js @@ -21,6 +21,9 @@ export default { search: '', val: '', item: null, + limit: 15, + minLength: 3, + url: '' }; }, methods: { @@ -43,27 +46,36 @@ export default { }, mounted(el) { const input = $(this.$el).find(`#${this.toKebabCase(this.action)}-input`); + this.url = `${this.api.find}?co=${this.api.co}&mode=${this.api.mode}&page=${this.page}&limit=${this.limit}` input.autocomplete({ - source: `${this.api.find}?co=${this.api.co}&mode=${this.api.mode}`, - minLength: 3, - maxShowItems: 15, - focus: ( event, ui ) => { - $("#grouper-search-container .co-loading-mini").hide(); - return false; - }, - open: function (event, ui) { - $("#grouper-search-container .co-loading-mini").hide(); + source: ( request, response ) => { + $("#grouper-search-container .co-loading-mini").show(); + $.ajax({ + url: this.url, + type: 'GET', + dataType: "json", + data: { + // XXX Change the term key to any other query key that fits your needs. + term: request.term + }, + success: function (data) { + $("#grouper-search-container .co-loading-mini").hide(); + // If i have more data from before append at the end + response( data ); + }, + error: function(data) { + $("#grouper-search-container .co-loading-mini").hide(); + console.log('Autocomplete ajax error:', data) + generateFlash('Find action failed', 'error'); + } + }); }, + delay: 1000, + minLength: this.minLength, + maxShowItems: this.limit, create: (event, ui) => { - // debugger $(`#${this.toKebabCase(this.action)}-input`).focus(); }, - close: function (event, ui) { - $("#grouper-search-container .co-loading-mini").hide(); - }, - search: function (event, ui) { - $("#grouper-search-container .co-loading-mini").show(); - }, // XXX We need access to the parent data object. // As a result we have to use arrow function syntax (ES6) select: (event, ui) => { @@ -73,7 +85,7 @@ export default { $(`#${this.toKebabCase(this.action)}-btn`).prop('disabled', false).focus(); return false; }, - }).autocomplete( "instance" )._renderItem = formatCoPersonAutoselectItem; + }) }, template: /*html*/`
    diff --git a/webroot/js/members.js b/webroot/js/members.js index 7c900ac..9c3edac 100644 --- a/webroot/js/members.js +++ b/webroot/js/members.js @@ -116,7 +116,7 @@ export default { const formData = new FormData(); formData.append("userId", id); formData.append("group", name); - const resp = await fetch(`${this.api.add}?group=${name}&userId=${id}`, { + const resp = await fetch(`${this.api.add}`, { method: "POST", headers: { "Accept": "application/json", diff --git a/webroot/js/page/GroupMember.js b/webroot/js/page/GroupMember.js index a6f781b..09da695 100644 --- a/webroot/js/page/GroupMember.js +++ b/webroot/js/page/GroupMember.js @@ -23,6 +23,7 @@ export default { }, methods: { showSubscribers(group) { + // Create and show the modal this.$refs.members.show(group); }, }, @@ -31,11 +32,6 @@ export default { setQueryParam('view', newValue); } }, - computed: { - routePath() { - return `/groupmember/co:${this.api.co}/glid:${this.api.glid}`; - } - }, mounted() { let view = hasQueryParam('view') ? getQueryParam('view') : 'adhoc'; if (view !== 'working' && view !== 'adhoc') { diff --git a/webroot/js/page/UserManager.js b/webroot/js/page/UserManager.js index 0677a2c..7d9cd80 100644 --- a/webroot/js/page/UserManager.js +++ b/webroot/js/page/UserManager.js @@ -1,4 +1,3 @@ -import Groups from '../groups.js'; import PageCount from '../pagecount.js'; import Pagination from '../pagination.js'; import GroupsTable from '../groups-table.js'; @@ -8,7 +7,6 @@ import Loader from '../loader.js'; export default { components: { - Groups, PageCount, Pagination, GroupsTable, @@ -24,6 +22,9 @@ export default { }, inject: ['api', 'txt'], methods: { + dummy() { + console.log('hi from dummy') + }, async findManagedUsers(user) { const { identifier: id, label } = user; this.loading = true; @@ -52,5 +53,14 @@ export default { :activeBtn="loading" /> + + + ` } \ No newline at end of file