@@ -16,40 +16,55 @@ export default class UsersIndexController extends Controller {
1616 @service fetch ;
1717 @service abilities ;
1818 @service filters ;
19+ @service tableContext ;
1920
20- /**
21- * Queryable parameters for this controller's model
22- *
23- * @var {Array}
24- */
25- queryParams = [ 'page' , 'limit' , 'sort' , 'query' , 'type' , 'created_by' , 'updated_by' , 'status' , 'role' , 'name' ] ;
21+ /** action buttons */
22+ get actionButtons ( ) {
23+ return [
24+ {
25+ icon : 'refresh' ,
26+ onClick : ( ) => this . hostRouter . refresh ( ) ,
27+ helpText : this . intl . t ( 'common.refresh' ) ,
28+ } ,
29+ {
30+ text : this . intl . t ( 'common.new' ) ,
31+ type : 'primary' ,
32+ icon : 'plus' ,
33+ permission : 'iam create user' ,
34+ onClick : this . createUser ,
35+ } ,
36+ {
37+ text : this . intl . t ( 'common.export' ) ,
38+ icon : 'long-arrow-up' ,
39+ iconClass : 'rotate-icon-45' ,
40+ wrapperClass : 'hidden md:flex' ,
41+ permission : 'iam export user' ,
42+ onClick : this . exportUsers ,
43+ } ,
44+ ] ;
45+ }
2646
27- /**
28- * The current page of data being viewed
29- *
30- * @var {Integer}
31- */
32- @tracked page = 1 ;
47+ /** bulk actions */
48+ get bulkActions ( ) {
49+ const selected = this . tableContext . getSelectedRows ( ) ;
3350
34- /**
35- * The maximum number of items to show per page
36- *
37- * @var {Integer}
38- */
39- @tracked limit ;
51+ return [
52+ {
53+ label : this . intl . t ( 'common.delete-selected-count' , { count : selected . length } ) ,
54+ class : 'text-red-500' ,
55+ fn : this . bulkDeleteUsers ,
56+ } ,
57+ ] ;
58+ }
4059
41- /**
42- * The search query param
43- *
44- * @var {Integer}
45- */
60+ queryParams = [ 'page' , 'limit' , 'sort' , 'query' , 'type' , 'created_by' , 'updated_by' , 'status' , 'role' , 'name' , 'phone' , 'email' ] ;
61+ @tracked page = 1 ;
62+ @tracked limit ;
4663 @tracked query ;
47-
48- /**
49- * The param to sort the data on, the param with prepended `-` is descending
50- *
51- * @var {String}
52- */
64+ @tracked name ;
65+ @tracked phone ;
66+ @tracked email ;
67+ @tracked role ;
5368 @tracked sort = '-created_at' ;
5469
5570 /**
@@ -59,9 +74,9 @@ export default class UsersIndexController extends Controller {
5974 */
6075 @tracked columns = [
6176 {
77+ sticky : true ,
6278 label : this . intl . t ( 'iam.common.name' ) ,
6379 valuePath : 'name' ,
64- width : '160px' ,
6580 cellComponent : 'table/cell/user-name' ,
6681 permission : 'iam view user' ,
6782 mediaPath : 'avatar_url' ,
@@ -72,24 +87,28 @@ export default class UsersIndexController extends Controller {
7287 filterComponent : 'filter/string' ,
7388 } ,
7489 {
90+ sticky : true ,
7591 label : this . intl . t ( 'iam.common.email' ) ,
7692 valuePath : 'email' ,
7793 cellComponent : 'click-to-copy' ,
78- sortable : false ,
79- width : '12%' ,
94+ resizable : true ,
95+ sortable : true ,
96+ filterable : true ,
97+ filterComponent : 'filter/string' ,
8098 } ,
8199 {
82100 label : this . intl . t ( 'iam.common.phone' ) ,
83101 valuePath : 'phone' ,
84102 cellComponent : 'click-to-copy' ,
85- sortable : false ,
86- width : '12%' ,
103+ resizable : true ,
104+ sortable : true ,
105+ filterable : true ,
106+ filterComponent : 'filter/string' ,
87107 } ,
88108 {
89109 label : this . intl . t ( 'iam.common.role' ) ,
90110 valuePath : 'role.name' ,
91111 sortable : false ,
92- width : '10%' ,
93112 filterable : true ,
94113 filterComponent : 'filter/model' ,
95114 filterComponentPlaceholder : 'Select role' ,
@@ -100,17 +119,15 @@ export default class UsersIndexController extends Controller {
100119 label : this . intl . t ( 'iam.common.status' ) ,
101120 valuePath : 'session_status' ,
102121 sortable : false ,
103- width : '12%' ,
104122 cellComponent : 'table/cell/status' ,
105123 filterable : true ,
106124 filterComponent : 'filter/select' ,
107125 filterParam : 'status' ,
108- filterOptions : [ 'pending' , 'active' ] ,
126+ filterOptions : [ 'pending' , 'active' , 'inactive' ] ,
109127 } ,
110128 {
111129 label : this . intl . t ( 'iam.users.index.last-login' ) ,
112130 valuePath : 'lastLogin' ,
113- width : '130px' ,
114131 resizable : true ,
115132 sortable : false ,
116133 filterable : false ,
@@ -120,7 +137,6 @@ export default class UsersIndexController extends Controller {
120137 label : this . intl . t ( 'iam.users.index.created-at' ) ,
121138 valuePath : 'createdAt' ,
122139 sortParam : 'created_at' ,
123- width : '140px' ,
124140 resizable : true ,
125141 sortable : false ,
126142 filterable : false ,
@@ -130,7 +146,6 @@ export default class UsersIndexController extends Controller {
130146 label : this . intl . t ( 'iam.users.index.updated-at' ) ,
131147 valuePath : 'updatedAt' ,
132148 sortParam : 'updated_at' ,
133- width : '130px' ,
134149 resizable : true ,
135150 hidden : true ,
136151 sortable : false ,
@@ -146,7 +161,8 @@ export default class UsersIndexController extends Controller {
146161 ddMenuLabel : this . intl . t ( 'iam.users.index.user-actions' ) ,
147162 cellClassNames : 'overflow-visible' ,
148163 wrapperClass : 'flex items-center justify-end mx-2' ,
149- width : '10%' ,
164+ sticky : 'right' ,
165+ width : 60 ,
150166 actions : [
151167 {
152168 label : this . intl . t ( 'iam.users.index.edit-user' ) ,
@@ -324,6 +340,7 @@ export default class UsersIndexController extends Controller {
324340 acceptButtonIcon : 'save' ,
325341 acceptButtonDisabled : this . abilities . cannot ( formPermission ) ,
326342 acceptButtonHelpText : this . abilities . cannot ( formPermission ) ? this . intl . t ( 'common.unauthorized' ) : null ,
343+ keepOpen : true ,
327344 formPermission,
328345 user,
329346 uploadNewPhoto : ( file ) => {
@@ -354,9 +371,16 @@ export default class UsersIndexController extends Controller {
354371 try {
355372 await user . save ( ) ;
356373 this . notifications . success ( this . intl . t ( 'iam.users.index.user-changes-saved-success' ) ) ;
357- return this . hostRouter . refresh ( ) ;
374+ this . hostRouter . refresh ( ) ;
375+ modal . done ( ) ;
358376 } catch ( error ) {
359377 this . notifications . serverError ( error ) ;
378+
379+ // If error is because email address was made empty rollback changes
380+ if ( error && typeof error . message === 'string' && error . message . includes ( 'Email address cannot be empty' ) ) {
381+ user . rollbackAttributes ( ) ;
382+ }
383+
360384 modal . stopLoading ( ) ;
361385 }
362386 } ,
@@ -379,6 +403,7 @@ export default class UsersIndexController extends Controller {
379403 body : this . intl . t ( 'iam.users.index.data-assosciated-user-delete' ) ,
380404 confirm : async ( modal ) => {
381405 modal . startLoading ( ) ;
406+
382407 try {
383408 await user . removeFromCurrentCompany ( ) ;
384409 this . notifications . success ( this . intl . t ( 'iam.users.index.delete-user-success-message' , { userName : user . get ( 'name' ) } ) ) ;
@@ -402,6 +427,7 @@ export default class UsersIndexController extends Controller {
402427 body : this . intl . t ( 'iam.users.index.access-account-or-resources-unless-re-activated' ) ,
403428 confirm : async ( modal ) => {
404429 modal . startLoading ( ) ;
430+
405431 try {
406432 await user . deactivate ( ) ;
407433 this . notifications . success ( this . intl . t ( 'iam.users.index.deactivate-user-success-message' , { userName : user . get ( 'name' ) } ) ) ;
@@ -425,6 +451,7 @@ export default class UsersIndexController extends Controller {
425451 body : this . intl . t ( 'iam.users.index.this-user-will-regain-access-to-your-organization' ) ,
426452 confirm : async ( modal ) => {
427453 modal . startLoading ( ) ;
454+
428455 try {
429456 await user . activate ( ) ;
430457 this . notifications . success ( this . intl . t ( 'iam.users.index.re-activate-user-success-message' , { userName : user . get ( 'name' ) } ) ) ;
@@ -448,6 +475,7 @@ export default class UsersIndexController extends Controller {
448475 body : this . intl . t ( 'iam.users.index.verify-user-manually-prompt' ) ,
449476 confirm : async ( modal ) => {
450477 modal . startLoading ( ) ;
478+
451479 try {
452480 await user . verify ( ) ;
453481 this . notifications . success ( this . intl . t ( 'iam.users.index.user-verified-success-message' , { userName : user . get ( 'name' ) } ) ) ;
@@ -483,6 +511,7 @@ export default class UsersIndexController extends Controller {
483511 body : this . intl . t ( 'iam.users.index.confirming-fleetbase-will-re-send-invitation-for-user-to-join-your-organization' ) ,
484512 confirm : async ( modal ) => {
485513 modal . startLoading ( ) ;
514+
486515 try {
487516 await user . resendInvite ( ) ;
488517 this . notifications . success ( this . intl . t ( 'iam.users.index.invitation-resent' ) ) ;
0 commit comments