33var module = angular . module ( 'supportAdminApp' ) ;
44
55module . controller ( 'permissionmanagement.RoleMembersListController' , [
6- '$scope' , '$rootScope' , 'RoleService' , 'IdResolverService' , '$stateParams' , '$state' , '$q' , 'Alert' , '$timeout' ,
7- function ( $scope , $rootScope , RoleService , IdResolverService , $stateParams , $state , $q , $alert , $timeout ) {
6+ '$scope' , '$rootScope' , 'RoleService' , 'IdResolverService' , 'UserService' , '$animate' , ' $stateParams', '$state' , '$q' , 'Alert' , '$timeout' ,
7+ function ( $scope , $rootScope , RoleService , IdResolverService , UserService , $animate , $stateParams , $state , $q , $alert , $timeout ) {
88
99 // true if role is loading
1010 $scope . isLoading = false ;
@@ -31,6 +31,15 @@ module.controller('permissionmanagement.RoleMembersListController', [
3131 $scope . users = { } ;
3232 var loadUser = IdResolverService . getUserResolverFunction ( $scope . users ) ;
3333
34+ // keep list of all members for client side filtering
35+ var allMembers = [ ] ;
36+
37+ // criteria to filter members
38+ $scope . filterCriteria = {
39+ userId : '' ,
40+ userHandle : ''
41+ } ;
42+
3443 /**
3544 * Return members which are selected in the table by checkboxes
3645 *
@@ -58,6 +67,8 @@ module.controller('permissionmanagement.RoleMembersListController', [
5867 id : memberId
5968 }
6069 } ) ;
70+ // save all members list for filtering
71+ allMembers = _ . clone ( $scope . members ) ;
6172 // if have some members we will redraw table using footable plugin
6273 if ( $scope . members . length ) {
6374 // make sure changes to scope are applied
@@ -102,6 +113,7 @@ module.controller('permissionmanagement.RoleMembersListController', [
102113 member . isRemoving = true ;
103114 return RoleService . unassignRole ( $stateParams . roleId , member . id ) . then ( function ( ) {
104115 _ . remove ( $scope . members , { id : member . id } ) ;
116+ _ . remove ( allMembers , { id : member . id } ) ;
105117 // we remove row of deleted member from footable table
106118 // which will also triggers footable table redraw
107119 // we don't worry to call it after $scope.members is updated so we don't use $timeout here
@@ -140,6 +152,93 @@ module.controller('permissionmanagement.RoleMembersListController', [
140152 } ) ;
141153 }
142154
155+ /**
156+ * Helper function which redraws table with new member list
157+ * and properly takes care about updating footable plugin
158+ *
159+ * The essential problem this function is solving is that after we
160+ * update $scope.members, rows from the table are not being deleted immediately
161+ * because we are using animations for rows.
162+ * That's why if we try to force update footable plugin it still find old rows which are in
163+ * process of animation and still in DOM tree.
164+ * As a workaround in this function we disable animations for rows before updating them,
165+ * thus footable plugin can see changes immediately after scope is updated.
166+ *
167+ * @param {Array } members new array of members which has to displayed
168+ * @param {Function } callback optional callback after table is fully redrawn
169+ *
170+ * @return {Promise } resolved after table was completely updated
171+ */
172+ function redrawTableWithMembers ( members ) {
173+ var $footable = $ ( '.footable' ) ;
174+
175+ // disable animations for rows, so old rows will be removed immediately
176+ // from the DOM tree and footable can see changes
177+ $footable . find ( 'tr' ) . each ( function ( index , el ) {
178+ $animate . enabled ( el , false ) ;
179+ } ) ;
180+
181+ // update members list in scope
182+ $scope . members = members ;
183+
184+ // make sure that changes are applied to the scope
185+ return $timeout ( function ( ) {
186+ // force footable plugin to redraw
187+ $footable . trigger ( 'footable_redraw' ) ;
188+ // enable animation for table rows again
189+ $footable . find ( 'tr' ) . each ( function ( index , el ) {
190+ $animate . enabled ( el , true ) ;
191+ } ) ;
192+ } ) ;
193+ }
194+
195+ /**
196+ * Applies filter to the member list
197+ */
198+ $scope . applyFilter = function ( ) {
199+ var filteredMembers = _ . clone ( allMembers ) ;
200+
201+ // filter by ids first, it works immediately as we know all the data
202+ // so we don't need to show loader for this
203+ if ( $scope . filterCriteria . userId ) {
204+ filteredMembers = _ . filter ( filteredMembers , { id : $scope . filterCriteria . userId } ) ;
205+ }
206+
207+ // if handle filter is defined and we still have some rows to filter
208+ if ( $scope . filterCriteria . userHandle && filteredMembers . length > 0 ) {
209+ // we show loader as we need to make request to the server
210+ $scope . isLoading = true ;
211+
212+ // As there is no server API to filter role members and we don't have
213+ // user handles to filter, we first have to find user ids by it's handle
214+ // and after we can filter users by id
215+ UserService . find ( {
216+ fields : 'id' ,
217+ filter : 'handle=*' + $scope . filterCriteria . userHandle + '*&like=true' ,
218+ limit : 1000000 // set big limit to make sure server returns all records
219+ } ) . then ( function ( users ) {
220+ var foundIds = _ . map ( users , 'id' ) ;
221+
222+ filteredMembers = _ . filter ( filteredMembers , function ( member ) {
223+ return _ . includes ( foundIds , member . id ) ;
224+ } ) ;
225+
226+ redrawTableWithMembers ( filteredMembers ) . then ( function ( ) {
227+ $scope . isLoading = false ;
228+ } ) ;
229+ } ) . catch ( function ( error ) {
230+ // is any error occurs show it and leave table untouched
231+ $scope . isLoading = false ;
232+ $alert . error ( error . error , $rootScope ) ;
233+ } ) ;
234+
235+ // if we don't filter by handle which makes server request
236+ // redraw table immediately
237+ } else {
238+ redrawTableWithMembers ( filteredMembers ) ;
239+ }
240+ }
241+
143242 /**
144243 * Uncheck all checkboxes
145244 */
@@ -174,6 +273,7 @@ module.controller('permissionmanagement.RoleMembersListController', [
174273 }
175274 }
176275
276+ // init footable plugin
177277 angular . element ( document ) . ready ( function ( ) {
178278 $ ( '.footable' ) . on ( {
179279 // we watch footable jquery plugin footable_page_filled event
0 commit comments