Skip to content

Commit fe33e19

Browse files
Merge pull request #164 from Sanketika-Obsrv/user_ui_update
#OBS-I494: User UI update
2 parents ff723c5 + 1300a34 commit fe33e19

File tree

2 files changed

+105
-49
lines changed

2 files changed

+105
-49
lines changed

web-console-v2/src/pages/UserManagement/AddUser.tsx

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import { Dialog, DialogActions, DialogContent, DialogTitle, TextField, MenuItem,
33
import { UserRequest } from './UserManagement';
44
import { useUserList } from 'services/user';
55
import { User } from './UserManagement';
6+
import { useAlert } from 'contexts/AlertContextProvider';
7+
import Alert from '@mui/material/Alert';
68

79
interface AddUserProps {
810
open: boolean;
911
onClose: () => void;
10-
onSubmit: (newUser: UserRequest) => void;
12+
onSubmit: (newUser: UserRequest) => Promise<void>;
1113
currentUser: User;
1214
}
1315

@@ -25,17 +27,16 @@ const emailRegex = /^[\w.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
2527
const AddUser: React.FC<AddUserProps> = ({ open, onClose, onSubmit, currentUser }) => {
2628
const [newUser, setNewUser] = useState<UserRequest>({
2729
user_name: '',
28-
first_name: '',
29-
last_name: '',
3030
email_address: '',
3131
password: '',
3232
roles: ['viewer'],
33-
status: 'active',
3433
});
3534

3635
const [isUsernameTaken, setIsUsernameTaken] = useState<boolean | null>(null);
3736
const [isEmailTaken, setIsEmailTaken] = useState<boolean | null>(null);
3837
const { data: users } = useUserList();
38+
const { showAlert } = useAlert();
39+
const [error, setError] = useState<boolean | null>(null);
3940

4041
useEffect(() => {
4142
const userName = newUser?.user_name.replace(/\s+/g, '_');
@@ -71,36 +72,61 @@ const AddUser: React.FC<AddUserProps> = ({ open, onClose, onSubmit, currentUser
7172
};
7273

7374
const handleSubmit = () => {
74-
setTimeout(() => {
75-
onSubmit(newUser);
76-
onClose();
77-
setNewUser({
78-
user_name: '',
79-
first_name: '',
80-
last_name: '',
81-
email_address: '',
82-
roles: ['viewer'],
83-
status: 'active',
84-
password: ''
75+
onSubmit(newUser)
76+
.then(() => {
77+
onClose();
78+
resetForm();
79+
})
80+
.catch(() => {
81+
showAlert('Failed to create user', 'error');
82+
setError(true);
8583
});
86-
}, 1000);
84+
};
85+
86+
87+
const resetForm = () => {
88+
setNewUser({
89+
user_name: '',
90+
email_address: '',
91+
roles: ['viewer'],
92+
password: '',
93+
});
8794
};
8895

89-
const isEmailValid = newUser.email_address ? emailRegex.test(newUser.email_address) : true;
96+
const isEmailValid = newUser?.email_address ? emailRegex.test(newUser?.email_address) : true;
97+
const isFirstNameValid = !newUser.first_name || newUser.first_name.length >= 3;
98+
const isLastNameValid = !newUser.last_name || newUser.last_name.length >= 3;
9099
const isFormValid =
91-
newUser.user_name &&
92-
newUser.email_address &&
93-
newUser.password &&
94-
newUser.roles.length > 0 &&
100+
newUser?.user_name &&
101+
newUser?.email_address &&
102+
newUser?.password &&
103+
newUser?.roles.length > 0 &&
95104
isUsernameTaken === false &&
96-
isEmailTaken === false &&
97-
isEmailValid;
105+
isEmailValid &&
106+
isFirstNameValid &&
107+
isLastNameValid;
98108

99109
const availableRoles = currentUser?.is_owner ? rolesOptions : rolesOptions.filter(role => role.value !== 'admin');
100110

111+
const handleCancel = () => {
112+
setError(null);
113+
resetForm();
114+
onClose();
115+
};
116+
117+
const handleDialogClose = (event: React.SyntheticEvent, reason: string) => {
118+
if (reason && (reason !== 'backdropClick')) {
119+
onClose();
120+
}
121+
};
122+
101123
return (
102-
<Dialog open={open} onClose={onClose}>
124+
<Dialog
125+
open={open}
126+
onClose={handleDialogClose}
127+
>
103128
<DialogTitle>Create New User</DialogTitle>
129+
{error && <Alert severity="error">Failed to create User</Alert>}
104130
<DialogContent>
105131
<TextField
106132
label="User Name"
@@ -122,6 +148,8 @@ const AddUser: React.FC<AddUserProps> = ({ open, onClose, onSubmit, currentUser
122148
value={newUser.first_name}
123149
onChange={handleChange}
124150
margin="normal"
151+
error={ !isFirstNameValid}
152+
helperText={!isFirstNameValid ? 'If provided, first name must be at least 3 characters' : ''}
125153
/>
126154
<TextField
127155
label="Last Name"
@@ -131,6 +159,8 @@ const AddUser: React.FC<AddUserProps> = ({ open, onClose, onSubmit, currentUser
131159
value={newUser.last_name}
132160
onChange={handleChange}
133161
margin="normal"
162+
error={!isLastNameValid}
163+
helperText={!isLastNameValid ? 'If provided, last name must be at least 3 characters' : ''}
134164
/>
135165
<TextField
136166
label="Email"
@@ -175,7 +205,7 @@ const AddUser: React.FC<AddUserProps> = ({ open, onClose, onSubmit, currentUser
175205
</FormControl>
176206
</DialogContent>
177207
<DialogActions>
178-
<Button onClick={onClose} color="primary" variant='outlined' size='small'>
208+
<Button onClick={handleCancel} color="primary" variant='outlined' size='small'>
179209
Cancel
180210
</Button>
181211
<Button onClick={handleSubmit} color="primary" variant='contained' size='small' disabled={!isFormValid}>

web-console-v2/src/pages/UserManagement/UserManagement.tsx

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import Filters from './Filters';
99
import AddUser from './AddUser';
1010
import ChangeRoleDialog from './ChangeRoleDialog';
1111
import AlertDialog from 'components/AlertDialog/AlertDialog';
12+
import { useAlert } from 'contexts/AlertContextProvider';
13+
import _ from 'lodash';
1214

1315
export interface User {
1416
id: string;
@@ -28,12 +30,12 @@ export interface User {
2830

2931
export type UserRequest = {
3032
user_name: string;
31-
first_name: string;
32-
last_name: string;
33+
first_name?: string;
34+
last_name?: string;
3335
email_address: string;
3436
password: string;
3537
roles: string[];
36-
status: string;
38+
status?: string;
3739
};
3840

3941
const UserManagement = () => {
@@ -45,8 +47,9 @@ const UserManagement = () => {
4547
const { mutate: updateUserStatus } = useUserStatusManage();
4648
const [selectedUser, setSelectedUser] = useState<User | null>(null);
4749
const [openRoleChangeDialog, setOpenRoleChangeDialog] = useState<boolean>(false);
50+
const { showAlert } = useAlert();
4851

49-
const { data, isLoading, refetch } = useUserList();
52+
const { data, isLoading, refetch, isError } = useUserList();
5053
const { data: currentUser } = useUserRead();
5154
const [showModal, setShowModal] = useState<boolean>(false);
5255
const [pendingAction, setPendingAction] = useState<{ userName: string; } | null>(null);
@@ -92,21 +95,28 @@ const UserManagement = () => {
9295
setOpenDialog(false);
9396
};
9497

95-
const handleAddUser = (newUser: UserRequest) => {
96-
setLoading(true);
97-
createUser(
98-
{ payload: newUser },
99-
{
100-
onSuccess: () => {
101-
refetch();
102-
setOpenDialog(false);
103-
setLoading(false);
104-
},
105-
onError: (error) => {
106-
console.error('Error creating user:', error);
107-
},
108-
}
109-
);
98+
const handleAddUser = (newUser: UserRequest): Promise<void> => {
99+
return new Promise<void>((resolve, reject) => {
100+
setLoading(true);
101+
const filteredPayload = _.pickBy(newUser, _.identity);
102+
createUser(
103+
{ payload: filteredPayload },
104+
{
105+
onSuccess: () => {
106+
refetch();
107+
setOpenDialog(false);
108+
setLoading(false);
109+
showAlert('User created successfully', 'success');
110+
resolve();
111+
},
112+
onError: (error) => {
113+
setLoading(false);
114+
showAlert('Failed to create user', 'error');
115+
reject(error);
116+
},
117+
}
118+
);
119+
});
110120
};
111121

112122
const handleDeactivateUser = (userName: string) => {
@@ -120,10 +130,12 @@ const UserManagement = () => {
120130
{
121131
onSuccess: () => {
122132
refetch();
133+
showAlert('User deactivated successfully', 'success');
123134
setLoading(false);
124135
},
125136
onError: (error) => {
126-
console.error('Error deactivating user:', error);
137+
showAlert('Failed to deactivate user', 'error');
138+
setLoading(false);
127139
},
128140
}
129141
);
@@ -140,19 +152,33 @@ const UserManagement = () => {
140152
{
141153
onSuccess: () => {
142154
refetch();
155+
showAlert('User activated successfully', 'success');
143156
setLoading(false);
144157
},
145158
onError: (error) => {
146-
console.error('Error activating user:', error);
159+
showAlert('Failed to activate user', 'error');
160+
setLoading(false);
147161
},
148162
}
149163
);
150164
};
151165

152-
const handleRoleChanged = () => {
166+
const handleRoleChanged = async () => {
153167
setLoading(true);
154-
refetch();
155-
setLoading(false)
168+
169+
try {
170+
await refetch();
171+
172+
if (isError) {
173+
showAlert('Failed to change role', 'error');
174+
} else if (data) {
175+
showAlert('Role changed successfully', 'success');
176+
}
177+
} catch (error) {
178+
showAlert('Failed to change role', 'error');
179+
} finally {
180+
setLoading(false);
181+
}
156182
};
157183

158184
const handleMenu = async (

0 commit comments

Comments
 (0)