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

Merge branch 'feat/ldap-group-sync' into imprv/133399-133400-provider-dependent-group-sync

Futa Arai 2 лет назад
Родитель
Сommit
444cd03a62

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

@@ -1069,6 +1069,9 @@
     "sync_succeeded": "External group sync succeeded",
     "sync_failed": "External group sync failed",
     "provider": "Provider",
+    "confirmation_before_sync": "Confirmation before sync",
+    "execution_time_warning": "If the number of groups or users is large, it might take a while until sync finishes",
+    "parallel_sync_forbidden": "While sync is executing, you cannot execute a different external group sync",
     "ldap": {
       "group_sync_settings": "LDAP Group Sync Settings",
       "group_search_base_DN": "Group Search Base DN",

+ 4 - 0
apps/app/public/static/locales/ja_JP/admin.json

@@ -10,6 +10,7 @@
   "Created": "作成日",
   "Edit": "編集",
   "Description": "説明",
+  "Execute": "実行",
   "last_login": "最終ログイン",
   "wiki_management_homepage": "Wiki管理トップ",
   "public": "公開",
@@ -1078,6 +1079,9 @@
     "sync_succeeded": "外部グループ同期に成功しました",
     "sync_failed": "外部グループ同期に失敗しました",
     "provider": "プロバイダ",
+    "confirmation_before_sync": "同期実行前の確認",
+    "execution_time_warning": "同期するグループやユーザが多い場合、同期が完了するまでに時間を要します",
+    "parallel_sync_forbidden": "同期実行中は、他の外部グループ同期は実行できません",
     "ldap": {
       "group_sync_settings": "LDAP グループ同期設定",
       "group_search_base_DN": "グループ検索ベース DN",

+ 4 - 0
apps/app/public/static/locales/zh_CN/admin.json

@@ -10,6 +10,7 @@
   "Page": "页面",
   "Edit": "编辑",
   "Description": "描述",
+  "Execute": "执行",
   "last_login": "上次登录",
   "wiki_management_homepage": "Wiki管理首页",
   "public": "公共",
@@ -1077,6 +1078,9 @@
     "sync_succeeded": "External group sync succeeded",
     "sync_failed": "External group sync failed",
     "provider": "Provider",
+    "confirmation_before_sync": "Confirmation before sync",
+    "execution_time_warning": "If the number of groups or users is large, it might take a while until sync finishes",
+    "parallel_sync_forbidden": "While sync is executing, you cannot execute a different external group sync",
     "ldap": {
       "group_sync_settings": "LDAP Group Sync Settings",
       "group_search_base_DN": "Group Search Base DN",

+ 1 - 1
apps/app/src/features/external-user-group/client/components/ExternalUserGroup/LdapGroupManagement.tsx

@@ -31,7 +31,7 @@ export const LdapGroupManagement: FC = () => {
 
   const requestSyncAPI = useCallback(async(e) => {
     if (isUserBind) {
-      const password = e.target.password.value;
+      const password = e.target.password?.value;
       await apiv3Put('/external-user-groups/ldap/sync', { password });
     }
     else {

+ 34 - 4
apps/app/src/features/external-user-group/client/components/ExternalUserGroup/SyncExecution.tsx

@@ -3,6 +3,7 @@ import {
 } from 'react';
 
 import { useTranslation } from 'react-i18next';
+import { Modal, ModalHeader, ModalBody } from 'reactstrap';
 
 import { toastError, toastSuccess } from '~/client/util/toastr';
 import LabeledProgressBar from '~/components/Admin/Common/LabeledProgressBar';
@@ -14,7 +15,7 @@ import { useSWRxExternalUserGroupList } from '../../stores/external-user-group';
 
 type SyncExecutionProps = {
   provider: ExternalGroupProviderType
-  requestSyncAPI: (e) => Promise<void>
+  requestSyncAPI: (e?: React.FormEvent<HTMLFormElement>) => Promise<void>
   AdditionalForm?: FC
 }
 
@@ -38,6 +39,9 @@ export const SyncExecution = ({
     total: 0,
     current: 0,
   });
+  const [isAlertModalOpen, setIsAlertModalOpen] = useState(false);
+  // value to propagate the submit event of form to submit confirm modal
+  const [currentSubmitEvent, setCurrentSubmitEvent] = useState<React.FormEvent<HTMLFormElement>>();
 
   useEffect(() => {
     if (socket == null) return;
@@ -71,19 +75,25 @@ export const SyncExecution = ({
     };
   }, [socket, mutateExternalUserGroups, t, provider]);
 
-  const onSyncBtnClick = useCallback(async(e) => {
+  const onSyncBtnClick = (e: React.FormEvent<HTMLFormElement>) => {
     e.preventDefault();
+    setCurrentSubmitEvent(e);
+    setIsAlertModalOpen(true);
+  };
+
+  const onSyncExecConfirmBtnClick = useCallback(async() => {
+    setIsAlertModalOpen(false);
     try {
       // set sync status before requesting to API, so that setting to syncFailed does not get overwritten
       setSyncStatus(SyncStatus.syncExecuting);
       setProgress({ total: 0, current: 0 });
-      await requestSyncAPI(e);
+      await requestSyncAPI(currentSubmitEvent);
     }
     catch (errs) {
       setSyncStatus(SyncStatus.syncFailed);
       toastError(t(errs[0]?.code));
     }
-  }, [t, requestSyncAPI]);
+  }, [t, requestSyncAPI, currentSubmitEvent]);
 
   const renderProgressBar = () => {
     if (syncStatus === SyncStatus.beforeSync) return null;
@@ -124,6 +134,26 @@ export const SyncExecution = ({
           <div className="col-md-6"><button className="btn btn-primary" type="submit">{t('external_user_group.sync')}</button></div>
         </div>
       </form>
+
+      <Modal
+        className="select-grant-group"
+        isOpen={isAlertModalOpen}
+        toggle={() => setIsAlertModalOpen(false)}
+      >
+        <ModalHeader tag="h4" toggle={() => setIsAlertModalOpen(false)} className="bg-purple text-light">
+          <i className="icon-fw icon-exclamation align-middle"></i>
+          <span className="align-middle">{t('external_user_group.confirmation_before_sync')}</span>
+        </ModalHeader>
+        <ModalBody>
+          <ul>
+            <li>{t('external_user_group.execution_time_warning')}</li>
+            <li>{t('external_user_group.parallel_sync_forbidden')}</li>
+          </ul>
+          <div className="text-center">
+            <button className="btn btn-primary" type="button" onClick={onSyncExecConfirmBtnClick}>{t('Execute')}</button>
+          </div>
+        </ModalBody>
+      </Modal>
     </>
   );
 };