Răsfoiți Sursa

typescriptize UserGroupUserModal

kaori 3 ani în urmă
părinte
comite
7910e99b74

+ 0 - 71
packages/app/src/client/services/AdminUserGroupDetailContainer.js

@@ -5,13 +5,8 @@
 import { isServer } from '@growi/core';
 import { Container } from 'unstated';
 
-import {
-  apiv3Get, apiv3Delete, apiv3Put, apiv3Post,
-} from '~/client/util/apiv3-client';
 import loggerFactory from '~/utils/logger';
 
-import { toastError } from '../util/apiNotification';
-
 
 // eslint-disable-next-line no-unused-vars
 const logger = loggerFactory('growi:services:AdminUserGroupDetailContainer');
@@ -31,12 +26,6 @@ export default class AdminUserGroupDetailContainer extends Container {
 
     this.appContainer = appContainer;
 
-    // const rootElem = document.getElementById('admin-user-group-detail');
-
-    // if (rootElem == null) {
-    //   return;
-    // }
-
     this.state = {
       // TODO: [SPA] get userGroup from props
       userGroupRelations: [], // For user list
@@ -48,7 +37,6 @@ export default class AdminUserGroupDetailContainer extends Container {
       childUserGroupRelations: [], // TODO 85062: fetch data on init (findRelationsByGroupIds) For child group list users
       // relatedPages: [], // For page list
       isUserGroupUserModalOpen: false,
-      searchType: 'partial',
       isAlsoMailSearched: false,
       isAlsoNameSearched: false,
     };
@@ -59,9 +47,6 @@ export default class AdminUserGroupDetailContainer extends Container {
     this.switchIsAlsoNameSearched = this.switchIsAlsoNameSearched.bind(this);
     this.openUserGroupUserModal = this.openUserGroupUserModal.bind(this);
     this.closeUserGroupUserModal = this.closeUserGroupUserModal.bind(this);
-    // this.addUserByUsername = this.addUserByUsername.bind(this);
-    // this.removeUserByUsername = this.removeUserByUsername.bind(this);
-    // this.fetchApplicableUsers = this.fetchApplicableUsers.bind(this);
   }
 
   /**
@@ -86,13 +71,6 @@ export default class AdminUserGroupDetailContainer extends Container {
     this.setState({ isAlsoNameSearched: !this.state.isAlsoNameSearched });
   }
 
-  /**
-   * switch searchType
-   */
-  switchSearchType(searchType) {
-    this.setState({ searchType });
-  }
-
   /**
    * open a modal
    *
@@ -111,53 +89,4 @@ export default class AdminUserGroupDetailContainer extends Container {
     await this.setState({ isUserGroupUserModalOpen: false });
   }
 
-  // /**
-  //  * search user for invitation
-  //  * @param {string} username username of the user to be searched
-  //  */
-  // async fetchApplicableUsers(searchWord) {
-  //   const res = await apiv3Get(`/user-groups/${this.state.userGroup._id}/unrelated-users`, {
-  //     searchWord,
-  //     searchType: this.state.searchType,
-  //     isAlsoMailSearched: this.state.isAlsoMailSearched,
-  //     isAlsoNameSearched: this.state.isAlsoNameSearched,
-  //   });
-
-  //   const { users } = res.data;
-
-  //   return users;
-  // }
-
-
-  // /**
-  //  * update user group
-  //  *
-  //  * @memberOf AdminUserGroupDetailContainer
-  //  * @param {string} username username of the user to be added to the group
-  //  */
-  // async addUserByUsername(username) {
-  //   const res = await apiv3Post(`/user-groups/${this.state.userGroup._id}/users/${username}`);
-
-  //   // do not add users for ducaplicate
-  //   if (res.data.userGroupRelation == null) { return }
-
-  //   this.init();
-  // }
-
-  /**
-   * update user group
-   *
-   * @memberOf AdminUserGroupDetailContainer
-   * @param {string} username username of the user to be removed from the group
-   */
-  // async removeUserByUsername(username) {
-  //   const res = await apiv3Delete(`/user-groups/${this.state.userGroup._id}/users/${username}`);
-
-  //   this.setState((prevState) => {
-  //     return {
-  //       userGroupRelations: prevState.userGroupRelations.filter((u) => { return u._id !== res.data.userGroupRelation._id }),
-  //     };
-  //   });
-  // }
-
 }

+ 11 - 4
packages/app/src/components/Admin/UserGroupDetail/UserGroupDetailPage.tsx

@@ -1,5 +1,5 @@
 import React, {
-  FC, useState, useCallback, useEffect, useMemo,
+  useState, useCallback, useEffect, useMemo,
 } from 'react';
 
 
@@ -13,6 +13,7 @@ import {
   apiv3Get, apiv3Put, apiv3Delete, apiv3Post,
 } from '~/client/util/apiv3-client';
 import { IUserGroup, IUserGroupHasId } from '~/interfaces/user';
+import { SearchTypes, SearchType } from '~/interfaces/user-group';
 import Xss from '~/services/xss';
 import { useIsAclEnabled } from '~/stores/context';
 import { useUpdateUserGroupConfirmModal } from '~/stores/modal';
@@ -39,7 +40,7 @@ type Props = {
   userGroupId?: string,
 }
 
-const UserGroupDetailPage = (props: Props) => {
+const UserGroupDetailPage = (props: Props): JSX.Element => {
   const { t } = useTranslation();
   const router = useRouter();
   const xss = useMemo(() => new Xss(), []);
@@ -49,7 +50,7 @@ const UserGroupDetailPage = (props: Props) => {
    * State (from AdminUserGroupDetailContainer)
    */
   const { data: currentUserGroup } = useSWRxUserGroup(currentUserGroupId);
-  const [searchType, setSearchType] = useState<string>('partial');
+  const [searchType, setSearchType] = useState<SearchType>(SearchTypes.PARTIAL);
   const [isAlsoMailSearched, setAlsoMailSearched] = useState<boolean>(false);
   const [isAlsoNameSearched, setAlsoNameSearched] = useState<boolean>(false);
   const [selectedUserGroup, setSelectedUserGroup] = useState<IUserGroupHasId | undefined>(undefined); // not null but undefined (to use defaultProps in UserGroupDeleteModal)
@@ -351,7 +352,13 @@ const UserGroupDetailPage = (props: Props) => {
       </div>
       <h2 className="admin-setting-header mt-4">{t('admin:user_group_management.user_list')}</h2>
       <UserGroupUserTable userGroup={currentUserGroup} userGroupRelations={childUserGroupRelations} onClickRemoveUserBtn={removeUserByUsername} />
-      <UserGroupUserModal userGroup={currentUserGroup} onClickAddUserBtn={addUserByUsername} onSearchApplicableUsers={fetchApplicableUsers} />
+      <UserGroupUserModal
+        userGroup={currentUserGroup}
+        searchType={searchType}
+        onClickAddUserBtn={addUserByUsername}
+        onSearchApplicableUsers={fetchApplicableUsers}
+        onSwitchSearchType={switchSearchType}
+      />
 
       <h2 className="admin-setting-header mt-4">{t('admin:user_group_management.child_group_list')}</h2>
       <UserGroupDropdown

+ 0 - 106
packages/app/src/components/Admin/UserGroupDetail/UserGroupUserModal.jsx

@@ -1,106 +0,0 @@
-import React from 'react';
-
-import { useTranslation } from 'next-i18next';
-import PropTypes from 'prop-types';
-import {
-  Modal, ModalHeader, ModalBody,
-} from 'reactstrap';
-
-import AdminUserGroupDetailContainer from '~/client/services/AdminUserGroupDetailContainer';
-
-import { withUnstatedContainers } from '../../UnstatedUtils';
-
-import CheckBoxForSerchUserOption from './CheckBoxForSerchUserOption';
-import RadioButtonForSerchUserOption from './RadioButtonForSerchUserOption';
-import UserGroupUserFormByInput from './UserGroupUserFormByInput';
-
-class UserGroupUserModal extends React.Component {
-
-  render() {
-    const {
-      t, userGroup, adminUserGroupDetailContainer, onClickAddUserBtn, onSearchApplicableUsers,
-    } = this.props;
-
-    return (
-      <Modal isOpen={adminUserGroupDetailContainer.state.isUserGroupUserModalOpen} toggle={adminUserGroupDetailContainer.closeUserGroupUserModal}>
-        <ModalHeader tag="h4" toggle={adminUserGroupDetailContainer.closeUserGroupUserModal} className="bg-info text-light">
-          {t('admin:user_group_management.add_modal.add_user') }
-        </ModalHeader>
-        <ModalBody>
-          <p className="card well">{t('admin:user_group_management.add_modal.description')}</p>
-          <div className="p-3">
-            <UserGroupUserFormByInput userGroup={userGroup} onClickAddUserBtn={onClickAddUserBtn} onSearchApplicableUsers={onSearchApplicableUsers} />
-          </div>
-          <h2 className="border-bottom">{t('admin:user_group_management.add_modal.search_option')}</h2>
-          <div className="row mt-4">
-            <div className="col-6">
-              <div className="mb-5">
-                <CheckBoxForSerchUserOption
-                  option="mail"
-                  checked={adminUserGroupDetailContainer.state.isAlsoMailSearched}
-                  onChange={adminUserGroupDetailContainer.switchIsAlsoMailSearched}
-                />
-              </div>
-              <div className="mb-5">
-                <CheckBoxForSerchUserOption
-                  option="name"
-                  checked={adminUserGroupDetailContainer.state.isAlsoNameSearched}
-                  onChange={adminUserGroupDetailContainer.switchIsAlsoNameSearched}
-                />
-              </div>
-            </div>
-            <div className="col-6">
-              <div className="mb-5">
-                <RadioButtonForSerchUserOption
-                  searchType="forward"
-                  checked={adminUserGroupDetailContainer.state.searchType === 'forward'}
-                  onChange={() => { adminUserGroupDetailContainer.switchSearchType('forward') }}
-                />
-              </div>
-              <div className="mb-5">
-                <RadioButtonForSerchUserOption
-                  searchType="partial"
-                  checked={adminUserGroupDetailContainer.state.searchType === 'partial'}
-                  onChange={() => { adminUserGroupDetailContainer.switchSearchType('partial') }}
-                />
-              </div>
-              <div className="mb-5">
-                <RadioButtonForSerchUserOption
-                  searchType="backward"
-                  checked={adminUserGroupDetailContainer.state.searchType === 'backword'}
-                  onChange={() => { adminUserGroupDetailContainer.switchSearchType('backword') }}
-                />
-              </div>
-            </div>
-          </div>
-        </ModalBody>
-      </Modal>
-    );
-  }
-
-}
-
-UserGroupUserModal.propTypes = {
-  t: PropTypes.func.isRequired, // i18next
-  adminUserGroupDetailContainer: PropTypes.instanceOf(AdminUserGroupDetailContainer).isRequired,
-  onClickAddUserBtn: PropTypes.func,
-  onSearchApplicableUsers: PropTypes.func,
-  userGroup: PropTypes.object.isRequired,
-};
-
-const UserGroupUserModalWrapperFC = (props) => {
-  const { t } = useTranslation();
-  return <UserGroupUserModal
-    t={t}
-    userGroup={props.userGroup}
-    onClickAddUserBtn={props.onClickAddUserBtn}
-    onSearchApplicableUsers={props.onSearchApplicableUsers}
-    {...props}
-  />;
-};
-/**
- * Wrapper component for using unstated
- */
-const UserGroupUserModalWrapper = withUnstatedContainers(UserGroupUserModalWrapperFC, [AdminUserGroupDetailContainer]);
-
-export default UserGroupUserModalWrapper;

+ 96 - 0
packages/app/src/components/Admin/UserGroupDetail/UserGroupUserModal.tsx

@@ -0,0 +1,96 @@
+import React from 'react';
+
+import { useTranslation } from 'next-i18next';
+import {
+  Modal, ModalHeader, ModalBody,
+} from 'reactstrap';
+
+import AdminUserGroupDetailContainer from '~/client/services/AdminUserGroupDetailContainer';
+import { IUserGroupHasId } from '~/interfaces/user';
+import { SearchTypes, SearchType } from '~/interfaces/user-group';
+
+
+import { withUnstatedContainers } from '../../UnstatedUtils';
+
+import CheckBoxForSerchUserOption from './CheckBoxForSerchUserOption';
+import RadioButtonForSerchUserOption from './RadioButtonForSerchUserOption';
+import UserGroupUserFormByInput from './UserGroupUserFormByInput';
+
+type Props = {
+  adminUserGroupDetailContainer: AdminUserGroupDetailContainer,
+  userGroup: IUserGroupHasId,
+  searchType: SearchType,
+  onClickAddUserBtn: () => void,
+  onSearchApplicableUsers: () => void,
+  onSwitchSearchType: (searchType: SearchType) => void
+}
+
+const UserGroupUserModal = (props: Props) => {
+  const { t } = useTranslation();
+  const {
+    adminUserGroupDetailContainer, userGroup, searchType, onClickAddUserBtn, onSearchApplicableUsers, onSwitchSearchType,
+  } = props;
+
+  return (
+    <Modal isOpen={adminUserGroupDetailContainer.state.isUserGroupUserModalOpen} toggle={adminUserGroupDetailContainer.closeUserGroupUserModal}>
+      <ModalHeader tag="h4" toggle={adminUserGroupDetailContainer.closeUserGroupUserModal} className="bg-info text-light">
+        {t('admin:user_group_management.add_modal.add_user') }
+      </ModalHeader>
+      <ModalBody>
+        <p className="card well">{t('admin:user_group_management.add_modal.description')}</p>
+        <div className="p-3">
+          <UserGroupUserFormByInput userGroup={userGroup} onClickAddUserBtn={onClickAddUserBtn} onSearchApplicableUsers={onSearchApplicableUsers} />
+        </div>
+        <h2 className="border-bottom">{t('admin:user_group_management.add_modal.search_option')}</h2>
+        <div className="row mt-4">
+          <div className="col-6">
+            <div className="mb-5">
+              <CheckBoxForSerchUserOption
+                option="mail"
+                checked={adminUserGroupDetailContainer.state.isAlsoMailSearched}
+                onChange={adminUserGroupDetailContainer.switchIsAlsoMailSearched}
+              />
+            </div>
+            <div className="mb-5">
+              <CheckBoxForSerchUserOption
+                option="name"
+                checked={adminUserGroupDetailContainer.state.isAlsoNameSearched}
+                onChange={adminUserGroupDetailContainer.switchIsAlsoNameSearched}
+              />
+            </div>
+          </div>
+          <div className="col-6">
+            <div className="mb-5">
+              <RadioButtonForSerchUserOption
+                searchType="forward"
+                checked={searchType === SearchTypes.FORWARD}
+                onChange={() => onSwitchSearchType(SearchTypes.FORWARD)}
+              />
+            </div>
+            <div className="mb-5">
+              <RadioButtonForSerchUserOption
+                searchType="partial"
+                checked={searchType === SearchTypes.PARTIAL}
+                onChange={() => onSwitchSearchType(SearchTypes.PARTIAL)}
+              />
+            </div>
+            <div className="mb-5">
+              <RadioButtonForSerchUserOption
+                searchType="backward"
+                checked={searchType === SearchTypes.BACKWORD}
+                onChange={() => onSwitchSearchType(SearchTypes.BACKWORD)}
+              />
+            </div>
+          </div>
+        </div>
+      </ModalBody>
+    </Modal>
+  );
+};
+
+/**
+ * Wrapper component for using unstated
+ */
+const UserGroupUserModalWrapper = withUnstatedContainers(UserGroupUserModal, [AdminUserGroupDetailContainer]);
+
+export default UserGroupUserModalWrapper;