diff options
Diffstat (limited to 'server/sonar-web/src/main/js/apps/groups/components')
-rw-r--r-- | server/sonar-web/src/main/js/apps/groups/components/EditMembersModal.tsx | 168 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/groups/components/Members.tsx | 78 |
2 files changed, 90 insertions, 156 deletions
diff --git a/server/sonar-web/src/main/js/apps/groups/components/EditMembersModal.tsx b/server/sonar-web/src/main/js/apps/groups/components/EditMembersModal.tsx index 5c27d2f3775..875bade13e3 100644 --- a/server/sonar-web/src/main/js/apps/groups/components/EditMembersModal.tsx +++ b/server/sonar-web/src/main/js/apps/groups/components/EditMembersModal.tsx @@ -34,95 +34,56 @@ interface Props { onClose: () => void; } -interface State { - lastSearchParams?: SelectListSearchParams; - needToReload: boolean; - users: UserSelected[]; - usersTotalCount?: number; - selectedUsers: string[]; -} - -export default class EditMembersModal extends React.PureComponent<Props, State> { - mounted = false; - - constructor(props: Props) { - super(props); - - this.state = { - needToReload: false, - users: [], - selectedUsers: [], - }; - } - - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - } - - fetchUsers = (searchParams: SelectListSearchParams) => +export default function EditMembersModal(props: Readonly<Props>) { + const [needToReload, setNeedToReload] = React.useState(false); + const [users, setUsers] = React.useState<UserSelected[]>([]); + const [selectedUsers, setSelectedUsers] = React.useState<string[]>([]); + const [usersTotalCount, setUsersTotalCount] = React.useState<number | undefined>(undefined); + const [lastSearchParams, setLastSearchParams] = React.useState< + SelectListSearchParams | undefined + >(undefined); + + const { group } = props; + const modalHeader = translate('users.update'); + + const fetchUsers = (searchParams: SelectListSearchParams) => getUsersInGroup({ - name: this.props.group.name, + name: props.group.name, p: searchParams.page, ps: searchParams.pageSize, q: searchParams.query !== '' ? searchParams.query : undefined, selected: searchParams.filter, }).then((data) => { - if (this.mounted) { - this.setState((prevState) => { - const more = searchParams.page != null && searchParams.page > 1; - - const users = more ? [...prevState.users, ...data.users] : data.users; - const newSelectedUsers = data.users - .filter((user) => user.selected) - .map((user) => user.login); - const selectedUsers = more - ? [...prevState.selectedUsers, ...newSelectedUsers] - : newSelectedUsers; - - return { - needToReload: false, - lastSearchParams: searchParams, - loading: false, - users, - usersTotalCount: data.paging.total, - selectedUsers, - }; - }); - } + const more = searchParams.page != null && searchParams.page > 1; + + setUsers(more ? [...users, ...data.users] : data.users); + const newSelectedUsers = data.users.filter((user) => user.selected).map((user) => user.login); + setSelectedUsers(more ? [...selectedUsers, ...newSelectedUsers] : newSelectedUsers); + setNeedToReload(false); + setLastSearchParams(searchParams); + setUsersTotalCount(data.paging.total); }); - handleSelect = (login: string) => + const handleSelect = (login: string) => addUserToGroup({ - name: this.props.group.name, + name: group.name, login, }).then(() => { - if (this.mounted) { - this.setState((state: State) => ({ - needToReload: true, - selectedUsers: [...state.selectedUsers, login], - })); - } + setNeedToReload(true); + setSelectedUsers([...selectedUsers, login]); }); - handleUnselect = (login: string) => + const handleUnselect = (login: string) => removeUserFromGroup({ - name: this.props.group.name, + name: group.name, login, }).then(() => { - if (this.mounted) { - this.setState((state: State) => ({ - needToReload: true, - selectedUsers: without(state.selectedUsers, login), - })); - } + setNeedToReload(true); + setSelectedUsers(without(selectedUsers, login)); }); - renderElement = (login: string): React.ReactNode => { - const user = find(this.state.users, { login }); + const renderElement = (login: string): React.ReactNode => { + const user = find(users, { login }); return ( <div className="select-list-list-item"> {user === undefined ? ( @@ -138,40 +99,35 @@ export default class EditMembersModal extends React.PureComponent<Props, State> ); }; - render() { - const modalHeader = translate('users.update'); - return ( - <Modal - className="group-menbers-modal" - contentLabel={modalHeader} - onRequestClose={this.props.onClose} - > - <header className="modal-head"> - <h2>{modalHeader}</h2> - </header> - - <div className="modal-body modal-container"> - <SelectList - elements={this.state.users.map((user) => user.login)} - elementsTotalCount={this.state.usersTotalCount} - needToReload={ - this.state.needToReload && - this.state.lastSearchParams && - this.state.lastSearchParams.filter !== SelectListFilter.All - } - onSearch={this.fetchUsers} - onSelect={this.handleSelect} - onUnselect={this.handleUnselect} - renderElement={this.renderElement} - selectedElements={this.state.selectedUsers} - withPaging - /> - </div> + return ( + <Modal + className="group-menbers-modal" + contentLabel={modalHeader} + onRequestClose={props.onClose} + > + <header className="modal-head"> + <h2>{modalHeader}</h2> + </header> + + <div className="modal-body modal-container"> + <SelectList + elements={users.map((user) => user.login)} + elementsTotalCount={usersTotalCount} + needToReload={ + needToReload && lastSearchParams && lastSearchParams.filter !== SelectListFilter.All + } + onSearch={fetchUsers} + onSelect={handleSelect} + onUnselect={handleUnselect} + renderElement={renderElement} + selectedElements={selectedUsers} + withPaging + /> + </div> - <footer className="modal-foot"> - <ResetButtonLink onClick={this.props.onClose}>{translate('done')}</ResetButtonLink> - </footer> - </Modal> - ); - } + <footer className="modal-foot"> + <ResetButtonLink onClick={props.onClose}>{translate('done')}</ResetButtonLink> + </footer> + </Modal> + ); } diff --git a/server/sonar-web/src/main/js/apps/groups/components/Members.tsx b/server/sonar-web/src/main/js/apps/groups/components/Members.tsx index d1d733f5542..64814df42f7 100644 --- a/server/sonar-web/src/main/js/apps/groups/components/Members.tsx +++ b/server/sonar-web/src/main/js/apps/groups/components/Members.tsx @@ -31,58 +31,36 @@ interface Props { onEdit: () => void; } -interface State { - modal: boolean; -} - -export default class Members extends React.PureComponent<Props, State> { - mounted = false; - state: State = { modal: false }; - - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - } - - handleMembersClick = () => { - this.setState({ modal: true }); - }; +export default function Members(props: Readonly<Props>) { + const [openModal, setOpenModal] = React.useState(false); + const { isManaged, group } = props; - handleModalClose = () => { - const { isManaged, group } = this.props; - if (this.mounted) { - this.setState({ modal: false }); - if (!isManaged && !group.default) { - this.props.onEdit(); - } + const handleModalClose = () => { + setOpenModal(false); + if (!isManaged && !group.default) { + props.onEdit(); } }; - render() { - const { isManaged, group } = this.props; - return ( - <> - <ButtonIcon - aria-label={translateWithParameters( - isManaged || group.default ? 'groups.users.view' : 'groups.users.edit', - group.name, - )} - className="button-small little-spacer-left little-padded" - onClick={this.handleMembersClick} - title={translateWithParameters('groups.users.edit', group.name)} - > - <BulletListIcon /> - </ButtonIcon> - {this.state.modal && - (isManaged || group.default ? ( - <ViewMembersModal isManaged={isManaged} group={group} onClose={this.handleModalClose} /> - ) : ( - <EditMembersModal group={group} onClose={this.handleModalClose} /> - ))} - </> - ); - } + return ( + <> + <ButtonIcon + aria-label={translateWithParameters( + isManaged || group.default ? 'groups.users.view' : 'groups.users.edit', + group.name, + )} + className="button-small little-spacer-left little-padded" + onClick={() => setOpenModal(true)} + title={translateWithParameters('groups.users.edit', group.name)} + > + <BulletListIcon /> + </ButtonIcon> + {openModal && + (isManaged || group.default ? ( + <ViewMembersModal isManaged={isManaged} group={group} onClose={handleModalClose} /> + ) : ( + <EditMembersModal group={group} onClose={handleModalClose} /> + ))} + </> + ); } |