1010 </b-button >
1111 </b-col >
1212 </page-banner >
13- <b-row class =" pb-2 px-4 pt-4 bg-white" align-v =" center " >
14- <b-col cols =" 12" md =" 6" lg =" 3 " xl =" 2" >
13+ <b-row class =" users-filter-row pb-2 px-4 pt-4 bg-white" align-v =" end " >
14+ <b-col cols =" 12" md =" 6" lg =" 2 " xl =" 2" class = " users-filter-col " >
1515 <p class =" select-header" > {{ $t('users.list.select_status') }}</p >
1616 <v-select
1717 v-model =" activatedFilter"
2323 ]"
2424 label =" name"
2525 :reduce =" option => option.value"
26+ :disabled =" fetchingUsers"
2627 placeholder =" Select Status" >
2728 </v-select >
2829 </b-col >
29- <b-col cols =" 12" md =" 6" lg =" 3 " xl =" 2" v-if =" !apiUsers" >
30+ <b-col cols =" 12" md =" 6" lg =" 2 " xl =" 2" class = " users-filter-col " v-if =" !apiUsers" >
3031 <p class =" select-header" > {{ $t('users.list.select_role') }}</p >
3132 <v-select
3233 v-model =" roleFilter"
3334 class =" v-select-custom"
3435 :options =" roleOptions"
3536 label =" name"
3637 :reduce =" option => option.id"
38+ :disabled =" fetchingUsers"
3739 placeholder =" Select Role" >
3840 </v-select >
3941 </b-col >
40- <b-col cols =" 12" md =" 6" lg =" 3 " xl =" 2" v-if =" apiUsers" >
42+ <b-col cols =" 12" md =" 6" lg =" 2 " xl =" 2" class = " users-filter-col " v-if =" apiUsers" >
4143 <p class =" select-header" > {{ $t('users.list.select_country') }}</p >
4244 <v-select
4345 v-model =" countryFilter"
4446 class =" v-select-custom"
4547 :options =" countryList"
4648 label =" name"
4749 :reduce =" option => option.id"
50+ :disabled =" fetchingUsers"
4851 placeholder =" Select Country" >
4952 </v-select >
5053 </b-col >
51- <b-col cols =" 12" md =" 6" lg =" 4" xl =" 3" v-if =" apiUsers" >
54+ <b-col cols =" 12" md =" 6" lg =" 4" xl =" 3" class = " users-filter-col " v-if =" apiUsers" >
5255 <p class =" select-header" > {{ $t('users.list.select_terms') }}</p >
5356 <v-select
5457 v-model =" termsFilter"
5558 class =" v-select-custom text-nowrap"
5659 :options =" termsList"
5760 label =" version"
5861 :reduce =" option => option.version"
62+ :disabled =" fetchingUsers"
5963 placeholder =" Select Terms" >
6064 </v-select >
6165 </b-col >
62- <b-col cols =" 12" md =" 6" lg =" 3 " xl =" 2" >
63- <p class =" select-header" v-if = " !apiUsers " > {{ $t('users.list.select_society') }}</p >
66+ <b-col cols =" 12" md =" 6" lg =" 2 " xl =" 2" class = " users-filter-col " v-if = " !apiUsers " >
67+ <p class =" select-header" > {{ $t('users.list.select_society') }}</p >
6468 <selectSociety
65- class =" float-right "
69+ class =" users-society-filter "
6670 :selected.sync =" selectedSoc"
67- :staynull = " true "
68- v-if = " !apiUsers " />
71+ :disabled = " fetchingUsers "
72+ :staynull = " true " />
6973 </b-col >
70- <b-col cols =" 12" md =" 6" lg =" 4 " xl =" 3" class =" ml-lg-auto" >
74+ <b-col cols =" 12" md =" 6" lg =" 3 " xl =" 3" class =" users-filter-col users-search-filter-col " :class = " { ' ml-lg-auto': !apiUsers } " >
7175 <p class =" select-header" > {{ $t('users.list.search') }}</p >
7276 <b-form-input
73- v-model.trim =" searchFilter "
77+ v-model.trim =" localSearchFilter "
7478 class =" search-filter-input"
7579 type =" text"
7680 :disabled =" fetchingUsers"
7781 :placeholder =" $t('users.list.search_placeholder')" >
7882 </b-form-input >
7983 </b-col >
80- <b-col class =" text-right" >
81- <b-button @click =" clearFilters" :disabled =" noFilters" class =" btn-outline-primary clear-filter-btn" >
84+ <b-col cols = " 12 " md = " 6 " lg = " auto " xl = " auto " class =" users-filter-col users-clear-filter-col text-lg -right" >
85+ <b-button @click =" clearFilters" :disabled =" fetchingUsers || noFilters" class =" btn-outline-primary clear-filter-btn" >
8286 {{ $t('users.list.clear_filters') }}
8387 </b-button >
8488 </b-col >
@@ -237,6 +241,8 @@ export default {
237241 roles: null ,
238242 locationOptions: null ,
239243 searchDebounce: null ,
244+ localSearchFilter: ' ' ,
245+ pendingSearchFetch: false ,
240246 countries: require (' country-list' )()
241247 }
242248 },
@@ -250,7 +256,7 @@ export default {
250256 deep: true
251257 },
252258 activatedFilter: fetchHandler,
253- searchFilter : {
259+ localSearchFilter : {
254260 handler (val , oldVal ) {
255261 if (val !== oldVal) {
256262 clearTimeout (this .searchDebounce )
@@ -259,12 +265,19 @@ export default {
259265 return
260266 }
261267 this .searchDebounce = setTimeout (() => {
262- this .currentPage = 1
263- this .fetchUsers ()
268+ this .queueSearchFetch ()
264269 }, 350 )
265270 }
266271 }
267272 },
273+ searchFilter: {
274+ handler (val ) {
275+ const search = val || ' '
276+ if (search !== this .localSearchFilter ) {
277+ this .localSearchFilter = search
278+ }
279+ }
280+ },
268281 roleFilter: fetchHandler,
269282 countryFilter: fetchHandler,
270283 termsFilter: fetchHandler,
@@ -282,6 +295,7 @@ export default {
282295 },
283296 mounted () {
284297 this .fetchOrganisations ()
298+ this .localSearchFilter = this .searchFilter
285299 this .fetchUsers ()
286300 this .fetchTerms ()
287301 },
@@ -297,6 +311,7 @@ export default {
297311 this .roleFilter = null
298312 this .countryFilter = null
299313 this .selectedSoc = null
314+ this .localSearchFilter = ' '
300315 this .searchFilter = ' '
301316 this .termsFilter = termsDefault
302317 },
@@ -338,7 +353,27 @@ export default {
338353 async fetchOrganisations () {
339354 await this .$store .dispatch (' content/fetchOrganisations' )
340355 },
356+ queueSearchFetch () {
357+ const search = this .localSearchFilter ? this .localSearchFilter .trim () : ' '
358+ if (search .length > 0 && search .length < 3 ) {
359+ return
360+ }
361+ this .searchFilter = search
362+ if (this .fetchingUsers ) {
363+ this .pendingSearchFetch = true
364+ return
365+ }
366+ if (this .currentPage !== 1 ) {
367+ this .currentPage = 1
368+ } else {
369+ this .fetchUsers ()
370+ }
371+ },
341372 async fetchUsers () {
373+ const search = this .searchFilter ? this .searchFilter .trim () : ' '
374+ if (search .length > 0 && search .length < 3 ) {
375+ return
376+ }
342377 this .fetchingUsers = true
343378 if (this .rolesEmpty ) {
344379 await this .fetchRoles ()
@@ -349,6 +384,7 @@ export default {
349384 if (filterRoleId === null ) {
350385 filterRoleId = this .apiUsers && apiUserRole ? apiUserRole .id : null
351386 }
387+ const excludeRoleId = ! this .apiUsers && filterRoleId === null && apiUserRole ? apiUserRole .id : null
352388
353389 if (! apiUserRole && this .apiUsers ) {
354390 console .warn (' Could not find API User in the role list' )
@@ -363,9 +399,10 @@ export default {
363399 society: this .selectedSoc ? this .selectedSoc .countryCode : null ,
364400 country_code: this .countryFilter ,
365401 search: this .searchFilter ,
366- terms_version: this .termsFilter === termsDefault ? null : this .termsFilter
402+ terms_version: this .termsFilter === termsDefault ? null : this .termsFilter ,
403+ exclude_role: excludeRoleId
367404 },
368- admin: ! this .apiUsers && filterRoleId === null ,
405+ admin: ! this .apiUsers && filterRoleId === null && ! apiUserRole ,
369406 orderBy: this .orderBy ,
370407 sort: this .sortDesc ? ' desc' : ' asc'
371408 })
@@ -374,6 +411,10 @@ export default {
374411 }
375412
376413 this .fetchingUsers = false
414+ if (this .pendingSearchFetch ) {
415+ this .pendingSearchFetch = false
416+ this .queueSearchFetch ()
417+ }
377418 },
378419 async fetchRoles () {
379420 this .roles = this .roleOptions
@@ -492,7 +533,7 @@ export default {
492533 this .roleFilter === null &&
493534 this .countryFilter === null &&
494535 this .selectedSoc === null &&
495- ! this .searchFilter &&
536+ ! this .localSearchFilter &&
496537 this .termsFilter === termsDefault
497538 },
498539 ... mapGetters ({
@@ -519,8 +560,28 @@ export default {
519560 color : #FFFFFF !important ;
520561 }
521562
563+ .users-filter-row {
564+ row-gap : 1rem ;
565+ }
566+ .users-filter-col {
567+ margin-bottom : 0.75rem ;
568+ }
569+ .users-society-filter {
570+ width : 100% ;
571+ }
572+ .users-search-filter-col {
573+ padding-right : 0.5rem ;
574+ }
575+ .users-clear-filter-col {
576+ display : flex ;
577+ justify-content : flex-end ;
578+ padding-left : 0.25rem ;
579+ }
522580 .clear-filter-btn {
523- margin-top : 2.5rem ;
581+ align-self : flex-end ;
582+ margin-top : 0 ;
583+ min-height : 2rem ;
584+ white-space : nowrap ;
524585 }
525586 btn-outline-primary .disabled , .btn-outline-primary :disabled {
526587 color : white ;
@@ -536,4 +597,10 @@ export default {
536597 height : 2.45rem ;
537598 }
538599
600+ @media (max-width : 991.98px ) {
601+ .users-clear-filter-col {
602+ justify-content : flex-start ;
603+ }
604+ }
605+
539606 </style >
0 commit comments