/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ import * as React from 'react'; import Auth from '@aws-amplify/auth'; import API from '@aws-amplify/api'; import { Logger } from '@aws-amplify/core'; import { Grid, Row, Col, Table, Button, ProgressBar, Modal, Form, FormGroup, ControlLabel, FormControl, Alert, PageHeader, Breadcrumb, BreadcrumbItem, InputGroup, Glyphicon, HelpBlock } from 'react-bootstrap'; import { LOGGING_LEVEL} from '../components/CustomUtil'; // Properties interface IProps{ history?: any; getApiToken: Function; } // States interface IState { token: string; users: HideableUser[]; sortIcon: string; isLoading: boolean; error: string; isModalInProgress: boolean; showModal: boolean; modalAction: string; modalError: string; username: string; name: string; email: string; group: string; loggedInUser: string; isEmailValid: boolean; emailValidation: any; } // User interface export interface User { username: string; name: string; email: string; group: string; status: string; } interface HideableUser extends User{ visible?: boolean; } // External variables const LOGGER = new Logger('Users', LOGGING_LEVEL); const apiName = 'operations-conductor-api'; class Users extends React.Component { constructor(props: Readonly) { super(props); this.state = { token: '', users: [], sortIcon: 'sort-by-attributes', isLoading: false, error: '', isModalInProgress: false, showModal: false, modalAction: '', modalError: '', username: '', name: '', email: '', group: '', loggedInUser: '', isEmailValid: true, emailValidation: null }; } componentDidMount() { // If the user is not admin user, redirect to the main page. this.isAdminGroup().then((isAdmin) => { if (!isAdmin) { this.props.history.push('/tasks'); } else { this.setApiToken().then(() => { this.setLoggedInUser(); this.getUsers(); }).catch((error) => { this.handleError('Error occurred while setting API token', error); }); } }).catch((error) => { this.handleError('Error occurred while checking user group.', error); }); } // Sets API token setApiToken = async () => { let token = await this.props.getApiToken(); this.setState({ token }); }; // Checks user belonging to Admin group isAdminGroup = async () => { let session = await Auth.currentSession(); let groups = session.getAccessToken().payload['cognito:groups']; return groups.indexOf('Admin') > -1; }; // Sets logged in user setLoggedInUser = async () => { let user = await Auth.currentAuthenticatedUser(); this.setState({ loggedInUser: user.attributes.email }); } // Gets users getUsers = async () => { this.setState({ isLoading: true, users: [] }); let path = '/users'; let params = { headers: { 'Authorization': this.state.token } }; try { let users: HideableUser[] = await API.get(apiName, path, params); // Filters the result let keyword = (document.getElementById("searchKeyword") as HTMLInputElement).value; for (let user of users) { if (keyword === '' || user.name.indexOf(keyword) > -1) { user.visible = true; } else { user.visible = false; } } // Sorts the result let sortIcon = this.state.sortIcon; if (sortIcon === 'sort-by-attributes') { users.sort((a: HideableUser, b: HideableUser) => a.name.localeCompare(b.name)); } else if (sortIcon === 'sort-by-attributes-alt') { users.sort((a: HideableUser, b: HideableUser) => b.name.localeCompare(a.name)); } this.setState({ users }); } catch (error) { this.handleError('Error occurred while getting list of users.', error); } finally { this.setState({ isLoading: false }); } }; // Invites a user inviteUser = async (name: string, email: string, group: string) => { this.setState({ isModalInProgress: true, modalError: '' }); let path = '/users'; let params = { headers: { 'Authorization': this.state.token }, body: { name, email, group } }; try { let user: HideableUser = await API.post(apiName, path, params); LOGGER.info(`User invited: ${JSON.stringify(user)}`); this.setState({ showModal: false, name: '', email: '', group: '' }); await this.getUsers(); } catch (error) { this.handleError('Error occurred while inviting a user.', error, 'modal'); } finally { this.setState({ isModalInProgress: false }); } }; // Edits a user editUser = async (username: string, group: string) => { this.setState({ isModalInProgress: true, modalError: '' }); let path = `/users/${username}`; let params = { headers: { 'Authorization': this.state.token }, body: { group } }; try { let user: HideableUser = await API.put(apiName, path, params); LOGGER.info(`User edited: ${JSON.stringify(user)}`); this.setState({ showModal: false }); await this.getUsers(); } catch (error) { this.handleError('Error occurred while editing a user.', error, 'modal'); } finally { this.setState({ isModalInProgress: false }); } }; // Deletes a user deleteUser = async (username: string) => { this.setState({ isModalInProgress: true, modalError: '' }); let path = `/users/${encodeURIComponent(username)}`; let params = { headers: { 'Authorization': this.state.token }, response: true }; try { await API.del(apiName, path, params); LOGGER.info(`User deleted: ${username}`); this.setState({ modalAction: 'deleteUserConfirm', isModalInProgress: false }); await this.getUsers(); } catch (error) { this.handleError('Error occurred while deleting a user.', error, 'modal'); this.setState({ isModalInProgress: false }); } }; // Handles modal close handleModalClose = () => { this.setState({ showModal: false, modalError: '' }); }; // Handles value changes handleUsernameChange = (event: any) => { this.setState({ name: event.target.value }); }; handleEmailChange = (event: any) => { let pattern = /^[_a-z0-9-]+(\.[_a-z0-9-]+)*(\+[a-z0-9-]+)?@\w+([\.-]?\w+)*(\.\w{2,3})+$/; let email = event.target.value; if (!pattern.test(email)) { this.setState({ emailValidation: 'error', isEmailValid: false }); } else { this.setState({ email: event.target.value, emailValidation: null, isEmailValid: true }); } }; handleGroupChange = (event: any) => { this.setState({ group: event.target.value }); }; handleSearch = (event: any) => { let keyword = event.target.value; let users = this.state.users; for (let user of users) { if (keyword === '' || user.name.indexOf(keyword) > -1) { user.visible = true; } else { user.visible = false; } } this.setState({ users }); }; handleSort = () => { let sortIcon = this.state.sortIcon; let users = this.state.users; if (sortIcon === 'sort-by-attributes') { users.sort((a: HideableUser, b: HideableUser) => b.name.localeCompare(a.name)); sortIcon = 'sort-by-attributes-alt'; } else if (sortIcon === 'sort-by-attributes-alt') { users.sort((a: HideableUser, b: HideableUser) => a.name.localeCompare(b.name)); sortIcon = 'sort-by-attributes'; } this.setState({ users, sortIcon }); }; // Handles error handleError = (message: string, error: any, type?: string) => { if (error.response !== undefined) { LOGGER.error(message, error.response.data.message); if (type === 'modal') { this.setState({ modalError: error.response.data.message }); } else { this.setState({ error: error.response.data.message }); } } else { LOGGER.error(message, error.message); if (type === 'modal') { this.setState({ modalError: error.message }); } else { this.setState({ error: error.message }); } } }; render() { return (
Users Users   { this.state.isLoading && } { this.state.users.length === 0 && !this.state.isLoading && } { this.state.users .filter((user: HideableUser) => user.visible) .map((user: HideableUser) => { return ( ); }) }
User Name   E-Mail Status Group Actions
Loading...
No user found.
{user.name} {user.email} {user.status} {user.group} {/* Users cannot edit themselves. */} {/* Users cannot delete themselves. */}
{ this.state.error && Error:
{this.state.error}
} { this.state.isLoading && }
{ this.state.modalAction === 'inviteUser' && [ Invite User ,
User Name E-Mail { !this.state.isEmailValid && Enter the valid E-Mail address. } Group
, ] } { this.state.modalAction === 'editUser' && [ Edit User ,
User Name Group
, ] } { this.state.modalAction === 'deleteUser' && [ Delete User , Are you sure to delete the following user?
Attributes Value
User Name { this.state.name }
E-Mail { this.state.email }
Group { this.state.group }
, ] } { this.state.modalAction === 'deleteUserConfirm' && [ User Deleted , User { this.state.name } ({ this.state.email }) has been deleted. , ] } { this.state.isModalInProgress && } { this.state.modalError && Error:
{this.state.modalError}
}
); } } export default Users;