Răsfoiți Sursa

Class Component to FC

Taichi Masuyama 4 ani în urmă
părinte
comite
1b8fe86479

+ 2 - 2
packages/app/src/components/Admin/UserGroup/UserGroupCreateForm.jsx

@@ -43,11 +43,11 @@ class UserGroupCreateForm extends React.Component {
       const userGroup = res.data.userGroup;
       const userGroupId = userGroup._id;
 
-      const res2 = await this.props.appContainer.apiv3.get(`/user-groups/${userGroupId}/users`);
+      const res2 = await this.props.appContainer.apiv3.get(`/user-groups/${userGroupId}/users`); // TODO 85062: fetch userGroupRelationsById instead
 
       const { users } = res2.data;
 
-      this.props.onCreate(userGroup, users);
+      this.props.onCreate(userGroup, users); // TODO 85062: pass userGroupRelations instead of users
 
       this.setState({ name: '' });
 

+ 84 - 122
packages/app/src/components/Admin/UserGroup/UserGroupPage.tsx

@@ -1,4 +1,6 @@
-import React, { Fragment } from 'react';
+import React, {
+  FC, Fragment, useState, useCallback, useEffect,
+} from 'react';
 
 import UserGroupTable from './UserGroupTable';
 import UserGroupCreateForm from './UserGroupCreateForm';
@@ -10,152 +12,112 @@ import { toastSuccess, toastError } from '~/client/util/apiNotification';
 import { IUserGroupHasObjectId, IUserGroupRelation } from '~/interfaces/user';
 import Xss from '~/services/xss';
 import { CustomWindow } from '~/interfaces/global';
+import { apiv3Get, apiv3Delete } from '~/client/util/apiv3-client';
 
 type Props = {
   appContainer: AppContainer,
 };
-type State = {
-  userGroups: IUserGroupHasObjectId[],
-  userGroupRelations: IUserGroupRelation[],
-  selectedUserGroup: IUserGroupHasObjectId | undefined,
-  isDeleteModalShown: boolean,
-};
-
-class UserGroupPage extends React.Component<Props, State> {
-
-  xss: Xss;
-
-  state: State;
-
-  constructor(props) {
-    super(props);
-
-    this.state = {
-      userGroups: [],
-      userGroupRelations: [],
-      selectedUserGroup: undefined, // not null but undefined (to use defaultProps in UserGroupDeleteModal)
-      isDeleteModalShown: false,
-    };
-
-    this.xss = (window as CustomWindow).xss;
 
-    this.showDeleteModal = this.showDeleteModal.bind(this);
-    this.hideDeleteModal = this.hideDeleteModal.bind(this);
-    this.addUserGroup = this.addUserGroup.bind(this);
-    this.deleteUserGroupById = this.deleteUserGroupById.bind(this);
-  }
+const UserGroupPage: FC<Props> = (props: Props) => {
+  const xss: Xss = (window as CustomWindow).xss;
+  const { isAclEnabled } = props.appContainer.config;
+
+  /*
+   * State
+   */
+  const [userGroups, setUserGroups] = useState<IUserGroupHasObjectId[]>([]);
+  const [userGroupRelations, setUserGroupRelations] = useState<IUserGroupRelation[]>([]);
+  const [selectedUserGroup, setSelectedUserGroup] = useState<IUserGroupHasObjectId | undefined>(undefined); // not null but undefined (to use defaultProps in UserGroupDeleteModal)
+  const [isDeleteModalShown, setDeleteModalShown] = useState<boolean>(false);
+
+  /*
+   * Functions
+   */
+  const syncUserGroupAndRelations = useCallback(async() => {
+    try {
+      const userGroupsRes = await apiv3Get('/user-groups', { pagination: false });
+      const userGroupRelationsRes = await apiv3Get('/user-group-relations');
 
-  async componentDidMount() {
-    await this.syncUserGroupAndRelations();
-  }
+      setUserGroups(userGroupsRes.data.userGroups);
+      setUserGroupRelations(userGroupRelationsRes.data.userGroupRelations);
+    }
+    catch (err) {
+      toastError(err);
+    }
+  }, []);
 
-  async showDeleteModal(group: IUserGroupHasObjectId) {
+  const showDeleteModal = useCallback(async(group: IUserGroupHasObjectId) => {
     try {
-      await this.syncUserGroupAndRelations();
+      await syncUserGroupAndRelations();
 
-      this.setState({
-        selectedUserGroup: group,
-        isDeleteModalShown: true,
-      });
+      setSelectedUserGroup(group);
+      setDeleteModalShown(true);
     }
     catch (err) {
       toastError(err);
     }
-  }
-
-  hideDeleteModal() {
-    this.setState({
-      selectedUserGroup: undefined,
-      isDeleteModalShown: false,
-    });
-  }
-
-  addUserGroup(userGroup, users) {
-    this.setState((prevState) => {
-      const userGroupRelations = Object.assign(prevState.userGroupRelations, {
-        [userGroup._id]: users,
-      });
+  }, []);
 
-      return {
-        userGroups: [...prevState.userGroups, userGroup],
-        userGroupRelations,
-      };
-    });
-  }
+  const hideDeleteModal = useCallback(() => {
+    setSelectedUserGroup(undefined);
+    setDeleteModalShown(false);
+  }, []);
 
-  async deleteUserGroupById(deleteGroupId: string, actionName: string, transferToUserGroupId: string) {
+  const addUserGroup = useCallback((userGroup: IUserGroupHasObjectId, userGroupRelations: IUserGroupRelation[]) => {
+    setUserGroups(prev => [...prev, userGroup]);
+    setUserGroupRelations(prev => ([...prev, ...userGroupRelations]));
+  }, []);
+
+  const deleteUserGroupById = useCallback(async(deleteGroupId: string, actionName: string, transferToUserGroupId: string) => {
     try {
-      const res = await this.props.appContainer.apiv3.delete(`/user-groups/${deleteGroupId}`, {
+      const res = await apiv3Delete(`/user-groups/${deleteGroupId}`, {
         actionName,
         transferToUserGroupId,
       });
 
-      this.setState((prevState) => {
-        const userGroups = prevState.userGroups.filter((userGroup) => {
-          return userGroup._id !== deleteGroupId;
-        });
-
-        delete prevState.userGroupRelations[deleteGroupId];
-
-        return {
-          userGroups,
-          userGroupRelations: prevState.userGroupRelations,
-          selectedUserGroup: undefined,
-          isDeleteModalShown: false,
-        };
-      });
+      setUserGroups(prev => prev.filter(userGroup => userGroup._id !== deleteGroupId));
+      setUserGroupRelations(prev => prev.filter(relation => relation.relatedGroup !== deleteGroupId));
+      setSelectedUserGroup(undefined);
+      setDeleteModalShown(false);
 
-      toastSuccess(`Deleted a group "${this.xss.process(res.data.userGroup.name)}"`);
+      toastSuccess(`Deleted a group "${xss.process(res.data.userGroup.name)}"`);
     }
     catch (err) {
       toastError(new Error('Unable to delete the group'));
     }
-  }
-
-  async syncUserGroupAndRelations() {
-    try {
-      const userGroupsRes = await this.props.appContainer.apiv3.get('/user-groups', { pagination: false });
-      const userGroupRelationsRes = await this.props.appContainer.apiv3.get('/user-group-relations');
-
-      this.setState({
-        userGroups: userGroupsRes.data.userGroups,
-        userGroupRelations: userGroupRelationsRes.data.userGroupRelations,
-      });
-    }
-    catch (err) {
-      toastError(err);
-    }
-  }
-
-  render() {
-    const { isAclEnabled } = this.props.appContainer.config;
-
-    return (
-      <Fragment>
-        <UserGroupCreateForm
-          isAclEnabled={isAclEnabled}
-          onCreate={this.addUserGroup}
-        />
-        <UserGroupTable
-          userGroups={this.state.userGroups}
-          isAclEnabled={isAclEnabled}
-          onDelete={this.showDeleteModal}
-          userGroupRelations={this.state.userGroupRelations}
-        />
-        <UserGroupDeleteModal
-          appContainer={this.props.appContainer}
-          userGroups={this.state.userGroups}
-          deleteUserGroup={this.state.selectedUserGroup}
-          onDelete={this.deleteUserGroupById}
-          isShow={this.state.isDeleteModalShown}
-          onShow={this.showDeleteModal}
-          onHide={this.hideDeleteModal}
-        />
-      </Fragment>
-    );
-  }
-
-}
+  }, []);
+
+  /*
+   * componentDidMount
+   */
+  useEffect(() => {
+    syncUserGroupAndRelations();
+  });
+
+  return (
+    <Fragment>
+      <UserGroupCreateForm
+        isAclEnabled={isAclEnabled}
+        onCreate={addUserGroup}
+      />
+      <UserGroupTable
+        userGroups={userGroups}
+        isAclEnabled={isAclEnabled}
+        onDelete={showDeleteModal}
+        userGroupRelations={userGroupRelations}
+      />
+      <UserGroupDeleteModal
+        appContainer={props.appContainer}
+        userGroups={userGroups}
+        deleteUserGroup={selectedUserGroup}
+        onDelete={deleteUserGroupById}
+        isShow={isDeleteModalShown}
+        onShow={showDeleteModal}
+        onHide={hideDeleteModal}
+      />
+    </Fragment>
+  );
+};
 
 /**
  * Wrapper component for using unstated

+ 2 - 2
packages/app/src/interfaces/user.ts

@@ -9,8 +9,8 @@ export type IUser = {
 }
 
 export type IUserGroupRelation = {
-  relatedGroup: IUserGroup,
-  relatedUser: IUser,
+  relatedGroup: Ref<IUserGroup>,
+  relatedUser: Ref<IUser>,
   createdAt: Date,
 }