Просмотр исходного кода

Merge pull request #6740 from weseek/feat/admin-typescriptzation-ExternalAccountTable

feat: Admin typescriptzation ExternalAccountTable
ryoji-s 3 лет назад
Родитель
Сommit
34c9bfd770

+ 3 - 0
packages/app/public/static/locales/en_US/admin.json

@@ -1028,5 +1028,8 @@
     "ADMIN_SEARCH_CONNECTION": "Attempting to reconnect to Elasticsearch",
     "ADMIN_SEARCH_CONNECTION": "Attempting to reconnect to Elasticsearch",
     "ADMIN_SEARCH_INDICES_NORMALIZE": "Normalize of Elasticsearch indexes",
     "ADMIN_SEARCH_INDICES_NORMALIZE": "Normalize of Elasticsearch indexes",
     "ADMIN_SEARCH_INDICES_REBUILD": "Rebuild Elasticsearch indexes"
     "ADMIN_SEARCH_INDICES_REBUILD": "Rebuild Elasticsearch indexes"
+  },
+  "toaster": {
+    "remove_external_user_success": "Succeeded to remove {{accountId}}"
   }
   }
 }
 }

+ 0 - 1
packages/app/public/static/locales/en_US/translation.json

@@ -535,7 +535,6 @@
     "activate_user_success": "Succeeded to activating {{username}}",
     "activate_user_success": "Succeeded to activating {{username}}",
     "deactivate_user_success": "Succeeded to deactivate {{username}}",
     "deactivate_user_success": "Succeeded to deactivate {{username}}",
     "remove_user_success": "Succeeded to removing {{username}}",
     "remove_user_success": "Succeeded to removing {{username}}",
-    "remove_external_user_success": "Succeeded to remove {{accountId}}",
     "remove_share_link_success": "Succeeded to remove {{shareLinkId}}",
     "remove_share_link_success": "Succeeded to remove {{shareLinkId}}",
     "issue_share_link": "Succeeded to issue new share link",
     "issue_share_link": "Succeeded to issue new share link",
     "remove_share_link": "Succeeded to remove {{count}} share links",
     "remove_share_link": "Succeeded to remove {{count}} share links",

+ 3 - 0
packages/app/public/static/locales/ja_JP/admin.json

@@ -1040,5 +1040,8 @@
     "ADMIN_SEARCH_CONNECTION": "Elasticsearch の再接続の試行",
     "ADMIN_SEARCH_CONNECTION": "Elasticsearch の再接続の試行",
     "ADMIN_SEARCH_INDICES_NORMALIZE": "Elasticsearch のインデックスの正規化",
     "ADMIN_SEARCH_INDICES_NORMALIZE": "Elasticsearch のインデックスの正規化",
     "ADMIN_SEARCH_INDICES_REBUILD": "Elasticsearch のインデックスのリビルド"
     "ADMIN_SEARCH_INDICES_REBUILD": "Elasticsearch のインデックスのリビルド"
+  },
+  "toaster": {
+    "remove_external_user_success": "{{accountId}}を削除しました"
   }
   }
 }
 }

+ 0 - 1
packages/app/public/static/locales/ja_JP/translation.json

@@ -526,7 +526,6 @@
     "activate_user_success": "{{username}}を有効化しました",
     "activate_user_success": "{{username}}を有効化しました",
     "deactivate_user_success": "{{username}}を無効化しました",
     "deactivate_user_success": "{{username}}を無効化しました",
     "remove_user_success": "{{username}}を削除しました",
     "remove_user_success": "{{username}}を削除しました",
-    "remove_external_user_success": "{{accountId}}を削除しました",
     "remove_share_link_success": "{{shareLinkId}}を削除しました",
     "remove_share_link_success": "{{shareLinkId}}を削除しました",
     "issue_share_link": "共有リンクを作成しました",
     "issue_share_link": "共有リンクを作成しました",
     "remove_share_link": "共有リンクを{{count}}件削除しました",
     "remove_share_link": "共有リンクを{{count}}件削除しました",

+ 3 - 0
packages/app/public/static/locales/zh_CN/admin.json

@@ -1006,5 +1006,8 @@
     "ADMIN_SEARCH_CONNECTION": "重试Elasticsearch连接",
     "ADMIN_SEARCH_CONNECTION": "重试Elasticsearch连接",
     "ADMIN_SEARCH_INDICES_NORMALIZE": "试图重新连接Elasticsearch",
     "ADMIN_SEARCH_INDICES_NORMALIZE": "试图重新连接Elasticsearch",
     "ADMIN_SEARCH_INDICES_REBUILD": "重建 Elasticsearch 索引"
     "ADMIN_SEARCH_INDICES_REBUILD": "重建 Elasticsearch 索引"
+  },
+  "toaster": {
+    "remove_external_user_success": "Succeeded to remove {{accountId}}"
   }
   }
 }
 }

+ 0 - 1
packages/app/public/static/locales/zh_CN/translation.json

@@ -508,7 +508,6 @@
 		"activate_user_success": "Succeeded to activating {{username}}",
 		"activate_user_success": "Succeeded to activating {{username}}",
 		"deactivate_user_success": "Succeeded to deactivate {{username}}",
 		"deactivate_user_success": "Succeeded to deactivate {{username}}",
 		"remove_user_success": "Succeeded to removing {{username}} ",
 		"remove_user_success": "Succeeded to removing {{username}} ",
-    "remove_external_user_success": "Succeeded to remove {{accountId}} ",
     "switch_disable_link_sharing_success": "成功更新分享链接设置",
     "switch_disable_link_sharing_success": "成功更新分享链接设置",
     "failed_to_reset_password":"Failed to reset password"
     "failed_to_reset_password":"Failed to reset password"
   },
   },

+ 0 - 132
packages/app/src/components/Admin/Users/ExternalAccountTable.jsx

@@ -1,132 +0,0 @@
-import React, { Fragment } from 'react';
-
-import dateFnsFormat from 'date-fns/format';
-import { useTranslation } from 'next-i18next';
-import PropTypes from 'prop-types';
-
-import AdminExternalAccountsContainer from '~/client/services/AdminExternalAccountsContainer';
-import { toastSuccess, toastError } from '~/client/util/apiNotification';
-
-import { withUnstatedContainers } from '../../UnstatedUtils';
-
-class ExternalAccountTable extends React.Component {
-
-  constructor(props) {
-    super(props);
-
-    this.state = {
-
-    };
-    this.removeExtenalAccount = this.removeExtenalAccount.bind(this);
-  }
-
-  // remove external-account
-  async removeExtenalAccount(externalAccountId) {
-    const { t } = this.props;
-
-    try {
-      const accountId = await this.props.adminExternalAccountsContainer.removeExternalAccountById(externalAccountId);
-      toastSuccess(t('toaster.remove_external_user_success', { accountId }));
-    }
-    catch (err) {
-      toastError(err);
-    }
-  }
-
-
-  render() {
-    const { t, adminExternalAccountsContainer } = this.props;
-    return (
-      <Fragment>
-        <table className="table table-bordered table-user-list">
-          <thead>
-            <tr>
-              <th width="120px">{t('admin:user_management.authentication_provider')}</th>
-              <th><code>accountId</code></th>
-              <th>{t('admin:user_management.related_username')}<code>username</code></th>
-              <th>
-                {t('admin:user_management.password_setting')}
-                <div
-                  className="text-muted"
-                  data-toggle="popover"
-                  data-placement="top"
-                  data-trigger="hover focus"
-                  tabIndex="0"
-                  role="button"
-                  data-animation="false"
-                  data-html="true"
-                  data-content={t('admin:user_management.password_setting_help')}
-                >
-                  <small>
-                    <i className="icon-question" aria-hidden="true"></i>
-                  </small>
-                </div>
-              </th>
-              <th width="100px">{t('Created')}</th>
-              <th width="70px"></th>
-            </tr>
-          </thead>
-          <tbody>
-            {adminExternalAccountsContainer.state.externalAccounts.map((ea) => {
-              return (
-                <tr key={ea._id}>
-                  <td>{ea.providerType}</td>
-                  <td>
-                    <strong>{ea.accountId}</strong>
-                  </td>
-                  <td>
-                    <strong>{ea.user.username}</strong>
-                  </td>
-                  <td>
-                    {ea.user.password
-                      ? (
-                        <span className="badge badge-info">
-                          {t('admin:user_management.set')}
-                        </span>
-                      )
-                      : (
-                        <span className="badge badge-warning">
-                          {t('admin:user_management.unset')}
-                        </span>
-                      )
-                    }
-                  </td>
-                  <td>{dateFnsFormat(new Date(ea.createdAt), 'yyyy-MM-dd')}</td>
-                  <td>
-                    <div className="btn-group admin-user-menu">
-                      <button type="button" className="btn btn-outline-secondary btn-sm dropdown-toggle" data-toggle="dropdown">
-                        <i className="icon-settings"></i> <span className="caret"></span>
-                      </button>
-                      <ul className="dropdown-menu" role="menu">
-                        <li className="dropdown-header">{t('admin:user_management.user_table.edit_menu')}</li>
-                        <button className="dropdown-item" type="button" role="button" onClick={() => { return this.removeExtenalAccount(ea._id) }}>
-                          <i className="icon-fw icon-fire text-danger"></i> {t('Delete')}
-                        </button>
-                      </ul>
-                    </div>
-                  </td>
-                </tr>
-              );
-            })}
-          </tbody>
-        </table>
-      </Fragment>
-    );
-  }
-
-}
-
-ExternalAccountTable.propTypes = {
-  t: PropTypes.func.isRequired, // i18next
-  adminExternalAccountsContainer: PropTypes.instanceOf(AdminExternalAccountsContainer).isRequired,
-};
-
-const ExternalAccountTableWrapperFC = (props) => {
-  const { t } = useTranslation();
-  return <ExternalAccountTable t={t} {...props} />;
-};
-
-const ExternalAccountTableWrapper = withUnstatedContainers(ExternalAccountTableWrapperFC, [AdminExternalAccountsContainer]);
-
-
-export default ExternalAccountTableWrapper;

+ 8 - 0
packages/app/src/components/Admin/Users/ExternalAccountTable.module.scss

@@ -0,0 +1,8 @@
+.ea-table :global {
+  thead th {
+    vertical-align: top;
+  }
+  td {
+    vertical-align: middle;
+  }
+}

+ 103 - 0
packages/app/src/components/Admin/Users/ExternalAccountTable.tsx

@@ -0,0 +1,103 @@
+import React, { useCallback } from 'react';
+
+import { IAdminExternalAccount } from '@growi/core';
+import dateFnsFormat from 'date-fns/format';
+import { useTranslation } from 'next-i18next';
+
+import AdminExternalAccountsContainer from '~/client/services/AdminExternalAccountsContainer';
+import { toastSuccess, toastError } from '~/client/util/apiNotification';
+
+import { withUnstatedContainers } from '../../UnstatedUtils';
+
+import styles from './ExternalAccountTable.module.scss';
+
+
+type ExternalAccountTableProps = {
+  adminExternalAccountsContainer: AdminExternalAccountsContainer,
+}
+
+const ExternalAccountTable = (props: ExternalAccountTableProps): JSX.Element => {
+
+  const { t } = useTranslation();
+
+  const { adminExternalAccountsContainer } = props;
+
+  const removeExtenalAccount = useCallback(async(externalAccountId) => {
+    try {
+      const accountId = await adminExternalAccountsContainer.removeExternalAccountById(externalAccountId);
+      toastSuccess(t('admin:toaster.remove_external_user_success', { accountId }));
+    }
+    catch (err) {
+      toastError(err);
+    }
+  }, [adminExternalAccountsContainer, t]);
+
+  return (
+    <table className={`${styles['ea-table']} table table-bordered table-user-list`}>
+      <thead>
+        <tr>
+          <th style={{ width: '140px' }}>{t('admin:user_management.authentication_provider')}</th>
+          <th style={{ width: '390px' }}><code>accountId</code></th>
+          <th style={{ width: '390px' }}>{t('admin:user_management.related_username')}<code>username</code></th>
+          <th style={{ width: '160px' }}>
+            {t('admin:user_management.password_setting')}
+            {/* TODO: Enable popper */}
+            <span
+              role="button"
+              className="text-muted px-2"
+              data-toggle="popper"
+              data-placement="top"
+              data-trigger="hover"
+              data-html="true"
+              title={t('admin:user_management.password_setting_help')}
+            >
+              <small><i className="icon-question" aria-hidden="true"></i></small>
+            </span>
+          </th>
+          <th style={{ width: '140px' }}>{t('admin:Created')}</th>
+          <th style={{ width: '70px' }}></th>
+        </tr>
+      </thead>
+      <tbody>
+        { adminExternalAccountsContainer.state.externalAccounts.map((ea: IAdminExternalAccount) => {
+          return (
+            <tr key={ea._id}>
+              <td><span>{ea.providerType}</span></td>
+              <td><strong>{ea.accountId}</strong></td>
+              <td><strong>{ea.user.username}</strong></td>
+              <td>
+                {ea.user.password
+                  ? (<span className="badge badge-info">{t('admin:user_management.set')}</span>)
+                  : (<span className="badge badge-warning">{t('admin:user_management.unset')}</span>)
+                }
+              </td>
+              <td><span>{dateFnsFormat(new Date(ea.createdAt), 'yyyy-MM-dd')}</span></td>
+              <td>
+                <div className="btn-group admin-user-menu">
+                  <button type="button" className="btn btn-outline-secondary btn-sm dropdown-toggle" data-toggle="dropdown">
+                    <i className="icon-settings"></i> <span className="caret"></span>
+                  </button>
+                  <ul className="dropdown-menu" role="menu">
+                    <li className="dropdown-header">{t('admin:user_management.user_table.edit_menu')}</li>
+                    <button
+                      className="dropdown-item"
+                      type="button"
+                      role="button"
+                      onClick={() => removeExtenalAccount(ea._id)}
+                    >
+                      <i className="icon-fw icon-fire text-danger"></i> {t('admin:Delete')}
+                    </button>
+                  </ul>
+                </div>
+              </td>
+            </tr>
+          );
+        }) }
+      </tbody>
+    </table>
+  );
+};
+
+const ExternalAccountTableWrapper = withUnstatedContainers(ExternalAccountTable, [AdminExternalAccountsContainer]);
+
+export default ExternalAccountTableWrapper;

+ 4 - 4
packages/app/src/components/PageComment.tsx

@@ -123,7 +123,7 @@ export const PageComment: FC<PageCommentProps> = memo((props:PageCommentProps):
   const revisionId = getIdForRef(revision);
   const revisionId = getIdForRef(revision);
   const revisionCreatedAt = (isPopulated(revision)) ? revision.createdAt : undefined;
   const revisionCreatedAt = (isPopulated(revision)) ? revision.createdAt : undefined;
 
 
-  const generateCommentElement = (comment: ICommentHasId) => (
+  const commentElement = (comment: ICommentHasId) => (
     <Comment
     <Comment
       rendererOptions={rendererOptions}
       rendererOptions={rendererOptions}
       comment={comment}
       comment={comment}
@@ -137,7 +137,7 @@ export const PageComment: FC<PageCommentProps> = memo((props:PageCommentProps):
     />
     />
   );
   );
 
 
-  const generateReplyCommentsElement = (replyComments: ICommentHasIdList) => (
+  const replyCommentsElement = (replyComments: ICommentHasIdList) => (
     <ReplyComments
     <ReplyComments
       rendererOptions={rendererOptions}
       rendererOptions={rendererOptions}
       isReadOnly={isReadOnly}
       isReadOnly={isReadOnly}
@@ -167,8 +167,8 @@ export const PageComment: FC<PageCommentProps> = memo((props:PageCommentProps):
 
 
                 return (
                 return (
                   <div key={comment._id} className={commentThreadClasses}>
                   <div key={comment._id} className={commentThreadClasses}>
-                    {generateCommentElement(comment)}
-                    {hasReply && generateReplyCommentsElement(allReplies[comment._id])}
+                    {commentElement(comment)}
+                    {hasReply && replyCommentsElement(allReplies[comment._id])}
                     {(!isReadOnly && !showEditorIds.has(comment._id)) && (
                     {(!isReadOnly && !showEditorIds.has(comment._id)) && (
                       <div className="text-right">
                       <div className="text-right">
                         <Button
                         <Button

+ 8 - 0
packages/core/src/interfaces/user.ts

@@ -39,3 +39,11 @@ export type IUserGroup = {
 export type IUserHasId = IUser & HasObjectId;
 export type IUserHasId = IUser & HasObjectId;
 export type IUserGroupHasId = IUserGroup & HasObjectId;
 export type IUserGroupHasId = IUserGroup & HasObjectId;
 export type IUserGroupRelationHasId = IUserGroupRelation & HasObjectId;
 export type IUserGroupRelationHasId = IUserGroupRelation & HasObjectId;
+
+export type IAdminExternalAccount = {
+  _id: string,
+  providerType: string,
+  accountId: string,
+  user: IUser,
+  createdAt: Date,
+}