]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-21086 Refactor class components
authorguillaume-peoch-sonarsource <guillaume.peoch@sonarsource.com>
Tue, 21 Nov 2023 10:13:03 +0000 (11:13 +0100)
committersonartech <sonartech@sonarsource.com>
Thu, 23 Nov 2023 20:02:58 +0000 (20:02 +0000)
server/sonar-web/src/main/js/apps/groups/components/EditMembersModal.tsx
server/sonar-web/src/main/js/apps/groups/components/Members.tsx

index 5c27d2f3775b8a554b2a6a454b94840da353230e..875bade13e33651cca88b9025426dd291c3bc82a 100644 (file)
@@ -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>
+  );
 }
index d1d733f55426a51e279acd9bdf3e3733aef044cc..64814df42f7b9a3c7339bac6c0678641732bddaa 100644 (file)
@@ -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} />
+        ))}
+    </>
+  );
 }