Skip to content

Commit

Permalink
Merge pull request #164 from Sanketika-Obsrv/user_ui_update
Browse files Browse the repository at this point in the history
#OBS-I494: User UI update
  • Loading branch information
HarishGangula authored Jan 10, 2025
2 parents ff723c5 + 1300a34 commit fe33e19
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 49 deletions.
80 changes: 55 additions & 25 deletions web-console-v2/src/pages/UserManagement/AddUser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { Dialog, DialogActions, DialogContent, DialogTitle, TextField, MenuItem,
import { UserRequest } from './UserManagement';
import { useUserList } from 'services/user';
import { User } from './UserManagement';
import { useAlert } from 'contexts/AlertContextProvider';
import Alert from '@mui/material/Alert';

interface AddUserProps {
open: boolean;
onClose: () => void;
onSubmit: (newUser: UserRequest) => void;
onSubmit: (newUser: UserRequest) => Promise<void>;
currentUser: User;
}

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

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

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

const handleSubmit = () => {
setTimeout(() => {
onSubmit(newUser);
onClose();
setNewUser({
user_name: '',
first_name: '',
last_name: '',
email_address: '',
roles: ['viewer'],
status: 'active',
password: ''
onSubmit(newUser)
.then(() => {
onClose();
resetForm();
})
.catch(() => {
showAlert('Failed to create user', 'error');
setError(true);
});
}, 1000);
};


const resetForm = () => {
setNewUser({
user_name: '',
email_address: '',
roles: ['viewer'],
password: '',
});
};

const isEmailValid = newUser.email_address ? emailRegex.test(newUser.email_address) : true;
const isEmailValid = newUser?.email_address ? emailRegex.test(newUser?.email_address) : true;
const isFirstNameValid = !newUser.first_name || newUser.first_name.length >= 3;
const isLastNameValid = !newUser.last_name || newUser.last_name.length >= 3;
const isFormValid =
newUser.user_name &&
newUser.email_address &&
newUser.password &&
newUser.roles.length > 0 &&
newUser?.user_name &&
newUser?.email_address &&
newUser?.password &&
newUser?.roles.length > 0 &&
isUsernameTaken === false &&
isEmailTaken === false &&
isEmailValid;
isEmailValid &&
isFirstNameValid &&
isLastNameValid;

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

const handleCancel = () => {
setError(null);
resetForm();
onClose();
};

const handleDialogClose = (event: React.SyntheticEvent, reason: string) => {
if (reason && (reason !== 'backdropClick')) {
onClose();
}
};

return (
<Dialog open={open} onClose={onClose}>
<Dialog
open={open}
onClose={handleDialogClose}
>
<DialogTitle>Create New User</DialogTitle>
{error && <Alert severity="error">Failed to create User</Alert>}
<DialogContent>
<TextField
label="User Name"
Expand All @@ -122,6 +148,8 @@ const AddUser: React.FC<AddUserProps> = ({ open, onClose, onSubmit, currentUser
value={newUser.first_name}
onChange={handleChange}
margin="normal"
error={ !isFirstNameValid}
helperText={!isFirstNameValid ? 'If provided, first name must be at least 3 characters' : ''}
/>
<TextField
label="Last Name"
Expand All @@ -131,6 +159,8 @@ const AddUser: React.FC<AddUserProps> = ({ open, onClose, onSubmit, currentUser
value={newUser.last_name}
onChange={handleChange}
margin="normal"
error={!isLastNameValid}
helperText={!isLastNameValid ? 'If provided, last name must be at least 3 characters' : ''}
/>
<TextField
label="Email"
Expand Down Expand Up @@ -175,7 +205,7 @@ const AddUser: React.FC<AddUserProps> = ({ open, onClose, onSubmit, currentUser
</FormControl>
</DialogContent>
<DialogActions>
<Button onClick={onClose} color="primary" variant='outlined' size='small'>
<Button onClick={handleCancel} color="primary" variant='outlined' size='small'>
Cancel
</Button>
<Button onClick={handleSubmit} color="primary" variant='contained' size='small' disabled={!isFormValid}>
Expand Down
74 changes: 50 additions & 24 deletions web-console-v2/src/pages/UserManagement/UserManagement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import Filters from './Filters';
import AddUser from './AddUser';
import ChangeRoleDialog from './ChangeRoleDialog';
import AlertDialog from 'components/AlertDialog/AlertDialog';
import { useAlert } from 'contexts/AlertContextProvider';
import _ from 'lodash';

export interface User {
id: string;
Expand All @@ -28,12 +30,12 @@ export interface User {

export type UserRequest = {
user_name: string;
first_name: string;
last_name: string;
first_name?: string;
last_name?: string;
email_address: string;
password: string;
roles: string[];
status: string;
status?: string;
};

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

const { data, isLoading, refetch } = useUserList();
const { data, isLoading, refetch, isError } = useUserList();
const { data: currentUser } = useUserRead();
const [showModal, setShowModal] = useState<boolean>(false);
const [pendingAction, setPendingAction] = useState<{ userName: string; } | null>(null);
Expand Down Expand Up @@ -92,21 +95,28 @@ const UserManagement = () => {
setOpenDialog(false);
};

const handleAddUser = (newUser: UserRequest) => {
setLoading(true);
createUser(
{ payload: newUser },
{
onSuccess: () => {
refetch();
setOpenDialog(false);
setLoading(false);
},
onError: (error) => {
console.error('Error creating user:', error);
},
}
);
const handleAddUser = (newUser: UserRequest): Promise<void> => {
return new Promise<void>((resolve, reject) => {
setLoading(true);
const filteredPayload = _.pickBy(newUser, _.identity);
createUser(
{ payload: filteredPayload },
{
onSuccess: () => {
refetch();
setOpenDialog(false);
setLoading(false);
showAlert('User created successfully', 'success');
resolve();
},
onError: (error) => {
setLoading(false);
showAlert('Failed to create user', 'error');
reject(error);
},
}
);
});
};

const handleDeactivateUser = (userName: string) => {
Expand All @@ -120,10 +130,12 @@ const UserManagement = () => {
{
onSuccess: () => {
refetch();
showAlert('User deactivated successfully', 'success');
setLoading(false);
},
onError: (error) => {
console.error('Error deactivating user:', error);
showAlert('Failed to deactivate user', 'error');
setLoading(false);
},
}
);
Expand All @@ -140,19 +152,33 @@ const UserManagement = () => {
{
onSuccess: () => {
refetch();
showAlert('User activated successfully', 'success');
setLoading(false);
},
onError: (error) => {
console.error('Error activating user:', error);
showAlert('Failed to activate user', 'error');
setLoading(false);
},
}
);
};

const handleRoleChanged = () => {
const handleRoleChanged = async () => {
setLoading(true);
refetch();
setLoading(false)

try {
await refetch();

if (isError) {
showAlert('Failed to change role', 'error');
} else if (data) {
showAlert('Role changed successfully', 'success');
}
} catch (error) {
showAlert('Failed to change role', 'error');
} finally {
setLoading(false);
}
};

const handleMenu = async (
Expand Down

0 comments on commit fe33e19

Please sign in to comment.