From dfce25709a588033c304cb14c2cc09dd7693cb3c Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Thu, 5 May 2022 13:11:20 +0200 Subject: [PATCH] change(ui) - user limit check and other fixes --- frontend/app/components/Client/Sites/Sites.js | 9 ++-- .../app/components/Client/Users/UsersView.tsx | 18 +++++--- .../Users/components/UserForm/UserForm.tsx | 10 ++--- .../Users/components/UserList/UserList.tsx | 12 +++-- .../components/UserListItem/UserListItem.tsx | 44 +++++++++++++++---- .../app/components/shared/Select/Select.tsx | 2 +- frontend/app/mstore/types/user.ts | 5 +++ frontend/app/mstore/userStore.ts | 41 +++++++++++++++++ frontend/app/services/UserService.ts | 6 +++ 9 files changed, 121 insertions(+), 26 deletions(-) diff --git a/frontend/app/components/Client/Sites/Sites.js b/frontend/app/components/Client/Sites/Sites.js index 19f2b8563..cb9c4df3b 100644 --- a/frontend/app/components/Client/Sites/Sites.js +++ b/frontend/app/components/Client/Sites/Sites.js @@ -168,8 +168,11 @@ class Sites extends React.PureComponent {
-
-
Name
+
+
Name
+
Key
+
+
{ sites.map(_site => ( @@ -191,7 +194,7 @@ class Sites extends React.PureComponent {
- {_site.projectKey} + {_site.projectKey}
{/*
{ _site.host }
diff --git a/frontend/app/components/Client/Users/UsersView.tsx b/frontend/app/components/Client/Users/UsersView.tsx index 7d4029b5f..9825db446 100644 --- a/frontend/app/components/Client/Users/UsersView.tsx +++ b/frontend/app/components/Client/Users/UsersView.tsx @@ -8,23 +8,26 @@ import { useModal } from 'App/components/Modal'; import UserForm from './components/UserForm'; import { connect } from 'react-redux'; +const PERMISSION_WARNING = 'You don’t have the permissions to perform this action.'; +const LIMIT_WARNING = 'You have reached users limit.'; interface Props { account: any; isEnterprise: boolean; + limits: any; } function UsersView(props: Props) { - const { account, isEnterprise } = props; + const { account, limits, isEnterprise } = props; const { userStore, roleStore } = useStore(); const userCount = useObserver(() => userStore.list.length); const roles = useObserver(() => roleStore.list); const { showModal } = useModal(); + const reachedLimit = (limits.remaining + userStore.modifiedCount) <= 0; const isAdmin = account.admin || account.superAdmin; - // const canAddUsers = isAdmin && userCount !== 0; // TODO fetch limits and disable button if limit reached const editHandler = (user = null) => { userStore.initUser(user).then(() => { - showModal(, { right: true }); + showModal(, {}); }); } @@ -34,6 +37,8 @@ function UsersView(props: Props) { } }, []); + console.log('remaining', limits, reachedLimit) + return (
@@ -45,7 +50,7 @@ function UsersView(props: Props) {
} - // disabled={ canAddUsers } - // content={ `${ !canAddUsers ? (!isAdmin ? PERMISSION_WARNING : LIMIT_WARNING) : 'Add team member' }` } + content={ `${ !isAdmin ? PERMISSION_WARNING : (reachedLimit ? LIMIT_WARNING : 'Add team member') }` } size="tiny" inverted position="top left" @@ -74,4 +78,6 @@ function UsersView(props: Props) { export default connect(state => ({ account: state.getIn([ 'user', 'account' ]), isEnterprise: state.getIn([ 'user', 'client', 'edition' ]) === 'ee', + limits: state.getIn([ 'user', 'account', 'limits', 'teamMember' ]), + // remaining: this.props.account.limits.teamMember.remaining }))(UsersView); \ No newline at end of file diff --git a/frontend/app/components/Client/Users/components/UserForm/UserForm.tsx b/frontend/app/components/Client/Users/components/UserForm/UserForm.tsx index c34828ec6..25f35097c 100644 --- a/frontend/app/components/Client/Users/components/UserForm/UserForm.tsx +++ b/frontend/app/components/Client/Users/components/UserForm/UserForm.tsx @@ -12,9 +12,9 @@ interface Props { } function UserForm(props: Props) { const { isSmtp = false, isEnterprise = false } = props; - const isSaving = false; const { hideModal } = useModal(); const { userStore, roleStore } = useStore(); + const isSaving = useObserver(() => userStore.saving); const user: any = useObserver(() => userStore.instance); const roles = useObserver(() => roleStore.list.filter(r => r.isProtected ? user.isSuperAdmin : true).map(r => ({ label: r.name, value: r.roleId }))); @@ -98,7 +98,7 @@ function UserForm(props: Props) {
{ const newUser = new User().fromJson(response); if (wasCreating) { + this.modifiedCount -= 1; this.list.push(new User().fromJson(newUser)); toast.success('User created successfully'); } else { @@ -108,6 +111,7 @@ export default class UserStore { return new Promise((resolve, reject) => { userService.delete(userId) .then(response => { + this.modifiedCount += 1; this.list = this.list.filter(user => user.userId !== userId); resolve(response); }).catch(error => { @@ -118,4 +122,41 @@ export default class UserStore { }); }); } + + copyInviteCode(userId: string): void { + const content = this.list.find(u => u.userId === userId)?.invitationLink; + if (content) { + copy(content); + toast.success('Invite code copied successfully'); + } else { + toast.error('Invite code not found'); + } + } + + generateInviteCode(userId: string): Promise { + this.saving = true; + const promise = new Promise((resolve, reject) => { + userService.generateInviteCode(userId) + .then(response => { + const index = this.list.findIndex(u => u.userId === userId); + if (index > -1) { + this.list[index].updateKey('isExpiredInvite', false); + this.list[index].updateKey('invitationLink', response.invitationLink); + } + resolve(response); + }).catch(error => { + this.saving = false; + reject(error); + }).finally(() => { + this.saving = false; + }); + }); + + toast.promise(promise, { + pending: 'Generating an invite code...', + success: 'Invite code generated successfully', + }) + + return promise; + } } \ No newline at end of file diff --git a/frontend/app/services/UserService.ts b/frontend/app/services/UserService.ts index db86fdd7a..615368db6 100644 --- a/frontend/app/services/UserService.ts +++ b/frontend/app/services/UserService.ts @@ -37,6 +37,12 @@ export default class UserService { } } + generateInviteCode(userId: any): Promise { + return this.client.get(`/client/members/${userId}/reset`) + .then(response => response.json()) + .then(response => response.data || {}); + } + delete(userId: string) { return this.client.delete('/client/members/' + userId) .then(response => response.json())