Shun Miyazawa 1 год назад
Родитель
Сommit
1adcc3e908

+ 8 - 1
apps/app/public/static/locales/en_US/admin.json

@@ -1135,6 +1135,13 @@
   },
   },
   "ai_integration": {
   "ai_integration": {
     "ai_integration": "AI Integration",
     "ai_integration": "AI Integration",
-    "disable_mode_explanation": "Currently, AI integration is disabled. To enable it, please set the environment variable <code>AI_ENABLED</code> to true."
+    "disable_mode_explanation": "Currently, AI integration is disabled. To enable it, please set the environment variable <code>AI_ENABLED</code> to true.",
+    "ai_search_management": "AI search management",
+    "rebuild_vector_store": "Rebuild Vector Store",
+    "rebuild_vector_store_label": "Rebuild",
+    "rebuild_vector_store_explanation1": "Delete the existing Vector Store and recreate the Vector Store on the public page.",
+    "rebuild_vector_store_explanation2": "This process may take several minutes.",
+    "rebuild_vector_store_succeeded": "Vector Store rebuild succeeded",
+    "rebuild_vector_store_failed": "Vector Store rebuild failed"
   }
   }
 }
 }

+ 8 - 1
apps/app/public/static/locales/fr_FR/admin.json

@@ -1134,6 +1134,13 @@
   },
   },
   "ai_integration": {
   "ai_integration": {
     "ai_integration": "Intégration de l'IA",
     "ai_integration": "Intégration de l'IA",
-    "disable_mode_explanation": "Actuellement, l'intégration de l'IA est désactivée. Pour l'activer, veuillez définir la variable d'environnement <code>AI_ENABLED</code> sur true"
+    "disable_mode_explanation": "Actuellement, l'intégration de l'IA est désactivée. Pour l'activer, veuillez définir la variable d'environnement <code>AI_ENABLED</code> sur true",
+    "ai_search_management": "Gestion de la recherche par l'IA",
+    "rebuild_vector_store": "Reconstruire le magasin Vector",
+    "rebuild_vector_store_label": "Reconstruire",
+    "rebuild_vector_store_explanation1": "Supprimez le Vector Store existant et recréez le Vector Store sur la page publique.",
+    "rebuild_vector_store_explanation2": "Ce processus peut prendre plusieurs minutes.",
+    "rebuild_vector_store_succeeded": "La reconstruction du magasin vectoriel a réussi",
+    "rebuild_vector_store_failed": "Échec de la reconstruction du magasin de vecteurs"
   }
   }
 }
 }

+ 8 - 1
apps/app/public/static/locales/ja_JP/admin.json

@@ -1145,6 +1145,13 @@
   },
   },
   "ai_integration": {
   "ai_integration": {
     "ai_integration": "AI 連携",
     "ai_integration": "AI 連携",
-    "disable_mode_explanation": "現在、AI 連携は無効になっています。有効にする場合は環境変数 <code>AI_ENABLED</code> を true に設定してください。"
+    "disable_mode_explanation": "現在、AI 連携は無効になっています。有効にする場合は環境変数 <code>AI_ENABLED</code> を true に設定してください。",
+    "ai_search_management": "AI 検索管理",
+    "rebuild_vector_store": "Vector Store のリビルド",
+    "rebuild_vector_store_label": "リビルド",
+    "rebuild_vector_store_explanation1": "既存の Vector Store を削除し、公開ページの Vector Store を再作成します。",
+    "rebuild_vector_store_explanation2": "この作業には数分かかる可能性があります。",
+    "rebuild_vector_store_succeeded": "Vector Store のリビルドに成功しました",
+    "rebuild_vector_store_failed": "Vector Store のリビルドに失敗しました"
   }
   }
 }
 }

+ 8 - 1
apps/app/public/static/locales/zh_CN/admin.json

@@ -1144,6 +1144,13 @@
   },
   },
   "ai_integration": {
   "ai_integration": {
     "ai_integration": "AI 集成",
     "ai_integration": "AI 集成",
-    "disable_mode_explanation": "目前,AI 集成已禁用。要启用它,请将环境变量 <code>AI_ENABLED</code> 设置为 true”"
+    "disable_mode_explanation": "目前,AI 集成已禁用。要启用它,请将环境变量 <code>AI_ENABLED</code> 设置为 true",
+    "ai_search_management": "AI 搜索管理",
+    "rebuild_vector_store": "重建矢量商店",
+    "rebuild_vector_store_label": "重建",
+    "rebuild_vector_store_explanation1": "删除现有的矢量存储,在公共页面上重新创建矢量存储。",
+    "rebuild_vector_store_explanation2": "这个过程可能需要几分钟。",
+    "rebuild_vector_store_succeeded": "矢量存储器重建成功",
+    "rebuild_vector_store_failed": "向量存储区重建失败"
   }
   }
 }
 }

+ 47 - 0
apps/app/src/client/components/Admin/AiIntegration/AiIntegration.tsx

@@ -0,0 +1,47 @@
+import { useCallback } from 'react';
+
+import { useTranslation } from 'react-i18next';
+
+import { apiv3Put } from '~/client/util/apiv3-client';
+import { toastSuccess, toastError } from '~/client/util/toastr';
+
+
+export const AiIntegration = (): JSX.Element => {
+  const { t } = useTranslation('admin');
+
+  const clickRebuildVectorStoreButtonHandler = useCallback(async() => {
+    try {
+      await apiv3Put('/ai-integration/rebuild-vector-store');
+      toastSuccess(t('ai_integration.rebuild_vector_store_succeeded'));
+    }
+    catch {
+      toastError(t('ai_integration.rebuild_vector_store_failed'));
+    }
+  }, [t]);
+
+  return (
+    <div data-testid="admin-ai-integration">
+      <h2 className="mb-4"> { t('ai_integration.ai_integration') } </h2>
+
+      <h3>{ t('ai_integration.ai_search_management') }</h3>
+
+      <div className="row">
+        <label className="col-md-3 col-form-label text-start text-md-end">{ t('ai_integration.rebuild_vector_store_label') }</label>
+        <div className="col-md-8">
+          <button
+            type="submit"
+            className="btn btn-primary"
+            onClick={clickRebuildVectorStoreButtonHandler}
+          >
+            {t('ai_integration.rebuild_vector_store')}
+          </button>
+
+          <p className="form-text text-muted">
+            {t('ai_integration.rebuild_vector_store_explanation1')}<br />
+            {t('ai_integration.rebuild_vector_store_explanation2')}<br />
+          </p>
+        </div>
+      </div>
+    </div>
+  );
+};

+ 3 - 2
apps/app/src/pages/admin/ai-integration.page.tsx

@@ -13,6 +13,7 @@ import { retrieveServerSideProps } from '../../utils/admin-page-util';
 
 
 const AdminLayout = dynamic(() => import('~/components/Layout/AdminLayout'), { ssr: false });
 const AdminLayout = dynamic(() => import('~/components/Layout/AdminLayout'), { ssr: false });
 const ForbiddenPage = dynamic(() => import('~/client/components/Admin/ForbiddenPage').then(mod => mod.ForbiddenPage), { ssr: false });
 const ForbiddenPage = dynamic(() => import('~/client/components/Admin/ForbiddenPage').then(mod => mod.ForbiddenPage), { ssr: false });
+const AiIntegration = dynamic(() => import('~/client/components/Admin/AiIntegration/AiIntegration').then(mod => mod.AiIntegration), { ssr: false });
 const AiIntegrationDisableMode = dynamic(
 const AiIntegrationDisableMode = dynamic(
   () => import('~/client/components/Admin/AiIntegration/AiIntegrationDisableMode').then(mod => mod.AiIntegrationDisableMode), { ssr: false },
   () => import('~/client/components/Admin/AiIntegration/AiIntegrationDisableMode').then(mod => mod.AiIntegrationDisableMode), { ssr: false },
 );
 );
@@ -21,7 +22,7 @@ type Props = CommonProps & {
   aiEnabled: boolean,
   aiEnabled: boolean,
 };
 };
 
 
-const AdminAiIntegrationPage: NextPage<Props> = (props) => {
+const AdminAiIntegrationPage: NextPage<Props> = (props: Props) => {
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
 
 
   const title = t('ai_integration.ai_integration');
   const title = t('ai_integration.ai_integration');
@@ -37,7 +38,7 @@ const AdminAiIntegrationPage: NextPage<Props> = (props) => {
         <title>{headTitle}</title>
         <title>{headTitle}</title>
       </Head>
       </Head>
       {props.aiEnabled
       {props.aiEnabled
-        ? <></> // TODO: implement admin page
+        ? <AiIntegration />
         : <AiIntegrationDisableMode />
         : <AiIntegrationDisableMode />
       }
       }
     </AdminLayout>
     </AdminLayout>