|
@@ -1,6 +1,6 @@
|
|
|
-import React, { useCallback, useState } from 'react';
|
|
|
|
|
|
|
+import React, { useCallback, useState, useEffect } from 'react';
|
|
|
|
|
|
|
|
-import type { IGrantedGroup } from '@growi/core';
|
|
|
|
|
|
|
+import { type IGrantedGroup, isPopulated } from '@growi/core';
|
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
import { Modal, TabContent, TabPane } from 'reactstrap';
|
|
import { Modal, TabContent, TabPane } from 'reactstrap';
|
|
|
|
|
|
|
@@ -11,7 +11,7 @@ import type { PopulatedGrantedGroup } from '~/interfaces/page-grant';
|
|
|
import loggerFactory from '~/utils/logger';
|
|
import loggerFactory from '~/utils/logger';
|
|
|
|
|
|
|
|
import type { SelectedPage } from '../../../../interfaces/selected-page';
|
|
import type { SelectedPage } from '../../../../interfaces/selected-page';
|
|
|
-import { createAiAssistant } from '../../../services/ai-assistant';
|
|
|
|
|
|
|
+import { createAiAssistant, updateAiAssistant } from '../../../services/ai-assistant';
|
|
|
import { useAiAssistantManagementModal, AiAssistantManagementModalPageMode, useSWRxAiAssistants } from '../../../stores/ai-assistant';
|
|
import { useAiAssistantManagementModal, AiAssistantManagementModalPageMode, useSWRxAiAssistants } from '../../../stores/ai-assistant';
|
|
|
|
|
|
|
|
import { AiAssistantManagementEditInstruction } from './AiAssistantManagementEditInstruction';
|
|
import { AiAssistantManagementEditInstruction } from './AiAssistantManagementEditInstruction';
|
|
@@ -33,12 +33,32 @@ const convertToGrantedGroups = (selectedGroups: PopulatedGrantedGroup[]): IGrant
|
|
|
}));
|
|
}));
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+// IGrantedGroup[] -> PopulatedGrantedGroup[]
|
|
|
|
|
+const convertToPopulatedGrantedGroups = (selectedGroups: IGrantedGroup[]): PopulatedGrantedGroup[] => {
|
|
|
|
|
+ const populatedGrantedGroups = selectedGroups.filter(group => isPopulated(group.item)) as PopulatedGrantedGroup[];
|
|
|
|
|
+ return populatedGrantedGroups;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// string[] -> SelectedPage[]
|
|
|
|
|
+const convertToSelectedPages = (pagePathPatterns: string[]): SelectedPage[] => {
|
|
|
|
|
+ return pagePathPatterns.map((pagePathPattern) => {
|
|
|
|
|
+ const isIncludeSubPage = pagePathPattern.endsWith('/*');
|
|
|
|
|
+ const path = isIncludeSubPage ? pagePathPattern.slice(0, -2) : pagePathPattern;
|
|
|
|
|
+ return {
|
|
|
|
|
+ page: { path },
|
|
|
|
|
+ isIncludeSubPage,
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
const AiAssistantManagementModalSubstance = (): JSX.Element => {
|
|
const AiAssistantManagementModalSubstance = (): JSX.Element => {
|
|
|
// Hooks
|
|
// Hooks
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
const { mutate: mutateAiAssistants } = useSWRxAiAssistants();
|
|
const { mutate: mutateAiAssistants } = useSWRxAiAssistants();
|
|
|
const { data: aiAssistantManagementModalData, close: closeAiAssistantManagementModal } = useAiAssistantManagementModal();
|
|
const { data: aiAssistantManagementModalData, close: closeAiAssistantManagementModal } = useAiAssistantManagementModal();
|
|
|
|
|
|
|
|
|
|
+ const aiAssistant = aiAssistantManagementModalData?.aiAssistantData;
|
|
|
|
|
+ const shouldEdit = aiAssistant != null;
|
|
|
const pageMode = aiAssistantManagementModalData?.pageMode ?? AiAssistantManagementModalPageMode.HOME;
|
|
const pageMode = aiAssistantManagementModalData?.pageMode ?? AiAssistantManagementModalPageMode.HOME;
|
|
|
|
|
|
|
|
// States
|
|
// States
|
|
@@ -51,6 +71,20 @@ const AiAssistantManagementModalSubstance = (): JSX.Element => {
|
|
|
const [selectedPages, setSelectedPages] = useState<SelectedPage[]>([]);
|
|
const [selectedPages, setSelectedPages] = useState<SelectedPage[]>([]);
|
|
|
const [instruction, setInstruction] = useState<string>(t('modal_ai_assistant.default_instruction'));
|
|
const [instruction, setInstruction] = useState<string>(t('modal_ai_assistant.default_instruction'));
|
|
|
|
|
|
|
|
|
|
+ // Effects
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ if (shouldEdit) {
|
|
|
|
|
+ setName(aiAssistant.name);
|
|
|
|
|
+ setDescription(aiAssistant.description);
|
|
|
|
|
+ setInstruction(aiAssistant.additionalInstruction);
|
|
|
|
|
+ setSelectedPages(convertToSelectedPages(aiAssistant.pagePathPatterns));
|
|
|
|
|
+ setSelectedShareScope(aiAssistant.shareScope);
|
|
|
|
|
+ setSelectedAccessScope(aiAssistant.accessScope);
|
|
|
|
|
+ setSelectedUserGroupsForShareScope(convertToPopulatedGrantedGroups(aiAssistant.grantedGroupsForShareScope ?? []));
|
|
|
|
|
+ setSelectedUserGroupsForAccessScope(convertToPopulatedGrantedGroups(aiAssistant.grantedGroupsForAccessScope ?? []));
|
|
|
|
|
+ }
|
|
|
|
|
+ // eslint-disable-next-line max-len
|
|
|
|
|
+ }, [aiAssistant?.accessScope, aiAssistant?.additionalInstruction, aiAssistant?.description, aiAssistant?.grantedGroupsForAccessScope, aiAssistant?.grantedGroupsForShareScope, aiAssistant?.name, aiAssistant?.pagePathPatterns, aiAssistant?.shareScope, shouldEdit]);
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
* For AiAssistantManagementHome methods
|
|
* For AiAssistantManagementHome methods
|
|
@@ -69,40 +103,42 @@ const AiAssistantManagementModalSubstance = (): JSX.Element => {
|
|
|
.map(selectedPage => (selectedPage.isIncludeSubPage ? `${selectedPage.page.path}/*` : selectedPage.page.path))
|
|
.map(selectedPage => (selectedPage.isIncludeSubPage ? `${selectedPage.page.path}/*` : selectedPage.page.path))
|
|
|
.filter((path): path is string => path !== undefined && path !== null);
|
|
.filter((path): path is string => path !== undefined && path !== null);
|
|
|
|
|
|
|
|
- const grantedGroupsForShareScope = convertToGrantedGroups(selectedUserGroupsForShareScope);
|
|
|
|
|
- const grantedGroupsForAccessScope = convertToGrantedGroups(selectedUserGroupsForAccessScope);
|
|
|
|
|
|
|
+ const grantedGroupsForShareScope = selectedShareScope === AiAssistantShareScope.GROUPS
|
|
|
|
|
+ ? convertToGrantedGroups(selectedUserGroupsForShareScope)
|
|
|
|
|
+ : undefined;
|
|
|
|
|
+
|
|
|
|
|
+ const grantedGroupsForAccessScope = selectedAccessScope === AiAssistantAccessScope.GROUPS
|
|
|
|
|
+ ? convertToGrantedGroups(selectedUserGroupsForAccessScope)
|
|
|
|
|
+ : undefined;
|
|
|
|
|
|
|
|
- await createAiAssistant({
|
|
|
|
|
|
|
+ const reqBody = {
|
|
|
name,
|
|
name,
|
|
|
description,
|
|
description,
|
|
|
additionalInstruction: instruction,
|
|
additionalInstruction: instruction,
|
|
|
pagePathPatterns,
|
|
pagePathPatterns,
|
|
|
shareScope: selectedShareScope,
|
|
shareScope: selectedShareScope,
|
|
|
accessScope: selectedAccessScope,
|
|
accessScope: selectedAccessScope,
|
|
|
- grantedGroupsForShareScope: selectedShareScope === AiAssistantShareScope.GROUPS ? grantedGroupsForShareScope : undefined,
|
|
|
|
|
- grantedGroupsForAccessScope: selectedAccessScope === AiAssistantAccessScope.GROUPS ? grantedGroupsForAccessScope : undefined,
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- toastSuccess('アシスタントを作成しました');
|
|
|
|
|
|
|
+ grantedGroupsForShareScope,
|
|
|
|
|
+ grantedGroupsForAccessScope,
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ if (shouldEdit) {
|
|
|
|
|
+ await updateAiAssistant(aiAssistant._id, reqBody);
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ await createAiAssistant(reqBody);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ toastSuccess(shouldEdit ? 'アシスタントが更新されました' : 'アシスタントが作成されました');
|
|
|
mutateAiAssistants();
|
|
mutateAiAssistants();
|
|
|
closeAiAssistantManagementModal();
|
|
closeAiAssistantManagementModal();
|
|
|
}
|
|
}
|
|
|
catch (err) {
|
|
catch (err) {
|
|
|
- toastError('アシスタントの作成に失敗しました');
|
|
|
|
|
|
|
+ toastError(shouldEdit ? 'アシスタントの更新に失敗しました' : 'アシスタントの作成に失敗しました');
|
|
|
logger.error(err);
|
|
logger.error(err);
|
|
|
}
|
|
}
|
|
|
- }, [
|
|
|
|
|
- mutateAiAssistants,
|
|
|
|
|
- closeAiAssistantManagementModal,
|
|
|
|
|
- description,
|
|
|
|
|
- instruction,
|
|
|
|
|
- name,
|
|
|
|
|
- selectedAccessScope,
|
|
|
|
|
- selectedPages,
|
|
|
|
|
- selectedShareScope,
|
|
|
|
|
- selectedUserGroupsForAccessScope,
|
|
|
|
|
- selectedUserGroupsForShareScope,
|
|
|
|
|
- ]);
|
|
|
|
|
|
|
+ // eslint-disable-next-line max-len
|
|
|
|
|
+ }, [selectedPages, selectedShareScope, selectedUserGroupsForShareScope, selectedAccessScope, selectedUserGroupsForAccessScope, name, description, instruction, shouldEdit, mutateAiAssistants, closeAiAssistantManagementModal, aiAssistant?._id]);
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -172,6 +208,7 @@ const AiAssistantManagementModalSubstance = (): JSX.Element => {
|
|
|
<TabContent activeTab={pageMode}>
|
|
<TabContent activeTab={pageMode}>
|
|
|
<TabPane tabId={AiAssistantManagementModalPageMode.HOME}>
|
|
<TabPane tabId={AiAssistantManagementModalPageMode.HOME}>
|
|
|
<AiAssistantManagementHome
|
|
<AiAssistantManagementHome
|
|
|
|
|
+ shouldEdit={shouldEdit}
|
|
|
name={name}
|
|
name={name}
|
|
|
description={description}
|
|
description={description}
|
|
|
shareScope={selectedShareScope}
|
|
shareScope={selectedShareScope}
|