diff --git a/apps/app/public/static/locales/en_US/translation.json b/apps/app/public/static/locales/en_US/translation.json index 31e4a328d9a..8f044565d50 100644 --- a/apps/app/public/static/locales/en_US/translation.json +++ b/apps/app/public/static/locales/en_US/translation.json @@ -508,6 +508,28 @@ "share": "Assistant Sharing", "pages": "Reference Pages", "instruction": "Assistant Instructions" + }, + "access_scope": { + "owner": "All pages accessible by {{username}}", + "groups": "Specify groups", + "publicOnly": "Public pages only" + }, + "share_scope": { + "owner": { + "label": "{{username}} only" + }, + "publicOnly": { + "label": "Public", + "desc": "Shared with all users" + }, + "groups": { + "label": "Specify groups", + "desc": "Shared only with members of selected groups" + }, + "sameAsAccessScope": { + "label": "Same as page access scope", + "desc": "Shared with the same scope as page access" + } } }, "link_edit": { diff --git a/apps/app/public/static/locales/fr_FR/translation.json b/apps/app/public/static/locales/fr_FR/translation.json index 95cf0b40b3b..ad13714b4c6 100644 --- a/apps/app/public/static/locales/fr_FR/translation.json +++ b/apps/app/public/static/locales/fr_FR/translation.json @@ -503,6 +503,28 @@ "share": "Partage de l'assistant", "pages": "Pages de référence", "instruction": "Instructions de l'assistant" + }, + "access_scope": { + "owner": "Toutes les pages accessibles par {{username}}", + "groups": "Spécifier les groupes", + "publicOnly": "Pages publiques uniquement" + }, + "share_scope": { + "owner": { + "label": "Seulement {{username}}" + }, + "publicOnly": { + "label": "Public", + "desc": "Partagé avec tous les utilisateurs" + }, + "groups": { + "label": "Spécifier les groupes", + "desc": "Partagé uniquement avec les membres des groupes sélectionnés" + }, + "sameAsAccessScope": { + "label": "Même portée que l'accès à la page", + "desc": "Partagé avec la même portée que l'accès à la page" + } } }, "link_edit": { diff --git a/apps/app/public/static/locales/ja_JP/translation.json b/apps/app/public/static/locales/ja_JP/translation.json index 36f837b5724..a8004e46250 100644 --- a/apps/app/public/static/locales/ja_JP/translation.json +++ b/apps/app/public/static/locales/ja_JP/translation.json @@ -541,6 +541,28 @@ "share": "アシスタントの共有", "pages": "参照ページ", "instruction": "アシスタントへの指示" + }, + "access_scope": { + "owner": "{{username}} がアクセス可能な全てのページ", + "groups": "グループを指定", + "publicOnly": "公開ページのみ" + }, + "share_scope": { + "owner": { + "label": "{{username}} のみ" + }, + "publicOnly": { + "label": "全体公開", + "desc": "すべてのユーザーに共有されます" + }, + "groups": { + "label": "グループを指定", + "desc": "選択したグループのメンバーにのみ共有されます" + }, + "sameAsAccessScope": { + "label": "ページのアクセス権限と同じ範囲", + "desc": "ページのアクセス権限と同じ範囲で共有されます" + } } }, "link_edit": { diff --git a/apps/app/public/static/locales/zh_CN/translation.json b/apps/app/public/static/locales/zh_CN/translation.json index 678d018ebfd..79ce1019563 100644 --- a/apps/app/public/static/locales/zh_CN/translation.json +++ b/apps/app/public/static/locales/zh_CN/translation.json @@ -497,6 +497,28 @@ "share": "助理共享", "pages": "参考页面", "instruction": "助理指示" + }, + "access_scope": { + "owner": "{{username}} 可访问的所有页面", + "groups": "指定群组", + "publicOnly": "仅公开页面" + }, + "share_scope": { + "owner": { + "label": "仅 {{ username }}" + }, + "publicOnly": { + "label": "公开", + "desc": "与所有用户共享" + }, + "groups": { + "label": "指定群组", + "desc": "仅与选定组的成员共享" + }, + "sameAsAccessScope": { + "label": "与页面访问范围相同", + "desc": "与页面访问范围相同的范围共享" + } } }, "link_edit": { diff --git a/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AccessScopeDropdown.tsx b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AccessScopeDropdown.tsx new file mode 100644 index 00000000000..e894494ecb1 --- /dev/null +++ b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AccessScopeDropdown.tsx @@ -0,0 +1,66 @@ +import React, { useCallback } from 'react'; + +import { useTranslation } from 'react-i18next'; +import { + UncontrolledDropdown, DropdownToggle, DropdownMenu, DropdownItem, Label, +} from 'reactstrap'; + +import { useCurrentUser } from '~/stores-universal/context'; + +import { AiAssistantAccessScope } from '../../../../interfaces/ai-assistant'; + +type Props = { + isDisabled: boolean, + isDisabledGroups: boolean, + selectedAccessScope: AiAssistantAccessScope, + onSelect: (accessScope: AiAssistantAccessScope) => void, +} + +export const AccessScopeDropdown: React.FC = (props: Props) => { + const { + isDisabled, + isDisabledGroups, + selectedAccessScope, + onSelect, + } = props; + + const { t } = useTranslation(); + const { data: currentUser } = useCurrentUser(); + + const getAccessScopeLabel = useCallback((accessScope: AiAssistantAccessScope) => { + const baseLabel = `modal_ai_assistant.access_scope.${accessScope}`; + return accessScope === AiAssistantAccessScope.OWNER + ? t(baseLabel, { username: currentUser?.username }) + : t(baseLabel); + }, [currentUser?.username, t]); + + const selectAccessScopeHandler = useCallback((accessScope: AiAssistantAccessScope) => { + onSelect(accessScope); + }, [onSelect]); + + return ( +
+ + + + {getAccessScopeLabel(selectedAccessScope)} + + + { [AiAssistantAccessScope.OWNER, AiAssistantAccessScope.GROUPS, AiAssistantAccessScope.PUBLIC_ONLY].map(accessScope => ( + selectAccessScopeHandler(accessScope)} + key={accessScope} + > + {getAccessScopeLabel(accessScope)} + + ))} + + +
+ ); +}; diff --git a/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementEditShare.tsx b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementEditShare.tsx new file mode 100644 index 00000000000..f092c496ad6 --- /dev/null +++ b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementEditShare.tsx @@ -0,0 +1,136 @@ +import React, { useCallback, useState } from 'react'; + +import { + ModalBody, Input, Label, +} from 'reactstrap'; + +import { AiAssistantShareScope, AiAssistantAccessScope } from '~/features/openai/interfaces/ai-assistant'; +import type { PopulatedGrantedGroup } from '~/interfaces/page-grant'; +import { useSWRxUserRelatedGroups } from '~/stores/user'; + +import { AccessScopeDropdown } from './AccessScopeDropdown'; +import { AiAssistantManagementHeader } from './AiAssistantManagementHeader'; +import { SelectUserGroupModal } from './SelectUserGroupModal'; +import { ShareScopeSwitch } from './ShareScopeSwitch'; + +const ScopeType = { + ACCESS: 'Access', + SHARE: 'Share', +} as const; + +type ScopeType = typeof ScopeType[keyof typeof ScopeType]; + +type Props = { + selectedShareScope: AiAssistantShareScope, + selectedAccessScope: AiAssistantAccessScope, + selectedUserGroupsForShareScope: PopulatedGrantedGroup[], + selectedUserGroupsForAccessScope: PopulatedGrantedGroup[], + onSelectShareScope: (scope: AiAssistantShareScope) => void, + onSelectAccessScope: (scope: AiAssistantAccessScope) => void, + onSelectShareScopeUserGroups: (userGroup: PopulatedGrantedGroup) => void, + onSelectAccessScopeUserGroups: (userGroup: PopulatedGrantedGroup) => void, +} + +export const AiAssistantManagementEditShare = (props: Props): JSX.Element => { + const { + selectedShareScope, + selectedAccessScope, + selectedUserGroupsForShareScope, + selectedUserGroupsForAccessScope, + onSelectShareScope, + onSelectAccessScope, + onSelectShareScopeUserGroups, + onSelectAccessScopeUserGroups, + } = props; + + const { data: userRelatedGroups } = useSWRxUserRelatedGroups(); + const hasNoRelatedGroups = userRelatedGroups == null || userRelatedGroups.relatedGroups.length === 0; + + const [isShared, setIsShared] = useState(false); + const [isSelectUserGroupModalOpen, setIsSelectUserGroupModalOpen] = useState(false); + const [selectedUserGroupType, setSelectedUserGroupType] = useState(ScopeType.ACCESS); + + const changeShareToggleHandler = useCallback(() => { + setIsShared((prev) => { + if (prev) { // if isShared === true + onSelectShareScope(AiAssistantShareScope.SAME_AS_ACCESS_SCOPE); + onSelectAccessScope(AiAssistantAccessScope.OWNER); + } + else { + onSelectShareScope(AiAssistantShareScope.PUBLIC_ONLY); + } + return !prev; + }); + }, [onSelectAccessScope, onSelectShareScope]); + + const selectGroupScopeHandler = useCallback((scopeType: ScopeType) => { + setSelectedUserGroupType(scopeType); + setIsSelectUserGroupModalOpen(true); + }, []); + + const selectShareScopeHandler = useCallback((shareScope: AiAssistantShareScope) => { + onSelectShareScope(shareScope); + if (shareScope === AiAssistantShareScope.GROUPS && !hasNoRelatedGroups) { + selectGroupScopeHandler(ScopeType.SHARE); + } + }, [hasNoRelatedGroups, onSelectShareScope, selectGroupScopeHandler]); + + const selectAccessScopeHandler = useCallback((accessScope: AiAssistantAccessScope) => { + onSelectAccessScope(accessScope); + if (accessScope === AiAssistantAccessScope.GROUPS && !hasNoRelatedGroups) { + selectGroupScopeHandler(ScopeType.ACCESS); + } + }, [hasNoRelatedGroups, onSelectAccessScope, selectGroupScopeHandler]); + + + return ( + <> + + + +
+ + +
+ + + + + + setIsSelectUserGroupModalOpen(false)} + selectedUserGroups={selectedUserGroupType === ScopeType.ACCESS ? selectedUserGroupsForAccessScope : selectedUserGroupsForShareScope} + onSelect={(userGroup) => { + if (selectedUserGroupType === ScopeType.ACCESS) { + onSelectAccessScopeUserGroups(userGroup); + } + else { + onSelectShareScopeUserGroups(userGroup); + } + }} + /> +
+ + ); +}; diff --git a/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementHome.tsx b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementHome.tsx index c5feb6fb948..a3a5677b7ba 100644 --- a/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementHome.tsx +++ b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementHome.tsx @@ -1,23 +1,47 @@ -import React from 'react'; +import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { ModalHeader, ModalBody, ModalFooter, Input, } from 'reactstrap'; +import { AiAssistantShareScope } from '~/features/openai/interfaces/ai-assistant'; +import { useCurrentUser } from '~/stores-universal/context'; + import { useAiAssistantManagementModal, AiAssistantManagementModalPageMode } from '../../../stores/ai-assistant'; type Props = { + name: string; + description: string; instruction: string; + shareScope: AiAssistantShareScope + onNameChange: (value: string) => void; + onDescriptionChange: (value: string) => void; + onCreateAiAssistant: () => Promise } export const AiAssistantManagementHome = (props: Props): JSX.Element => { - const { instruction } = props; + const { + name, + description, + instruction, + shareScope, + onNameChange, + onDescriptionChange, + onCreateAiAssistant, + } = props; const { t } = useTranslation(); - + const { data: currentUser } = useCurrentUser(); const { close: closeAiAssistantManagementModal, changePageMode } = useAiAssistantManagementModal(); + const getShareScopeLabel = useCallback((shareScope: AiAssistantShareScope) => { + const baseLabel = `modal_ai_assistant.share_scope.${shareScope}.label`; + return shareScope === AiAssistantShareScope.OWNER + ? t(baseLabel, { username: currentUser?.username }) + : t(baseLabel); + }, [currentUser?.username, t]); + return ( <> @@ -33,6 +57,8 @@ export const AiAssistantManagementHome = (props: Props): JSX.Element => { placeholder="アシスタント名を入力" bsSize="lg" className="border-0 border-bottom border-2 px-0 rounded-0" + value={name} + onChange={e => onNameChange(e.target.value)} /> @@ -45,6 +71,8 @@ export const AiAssistantManagementHome = (props: Props): JSX.Element => { type="textarea" placeholder="内容や用途のメモを表示させることができます" rows="4" + value={description} + onChange={e => onDescriptionChange(e.target.value)} /> メモの内容はアシスタントの処理に影響しません。 @@ -54,11 +82,12 @@ export const AiAssistantManagementHome = (props: Props): JSX.Element => {
@@ -93,7 +122,7 @@ export const AiAssistantManagementHome = (props: Props): JSX.Element => { - +
diff --git a/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementModal.tsx b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementModal.tsx index 9410d2f4e8f..cfbd8106d6e 100644 --- a/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementModal.tsx +++ b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementModal.tsx @@ -1,10 +1,13 @@ import React, { useCallback, useState } from 'react'; +import type { IGrantedGroup } from '@growi/core'; import { useTranslation } from 'react-i18next'; import { Modal, TabContent, TabPane } from 'reactstrap'; import { toastError, toastSuccess } from '~/client/util/toastr'; +import { AiAssistantAccessScope, AiAssistantShareScope } from '~/features/openai/interfaces/ai-assistant'; import type { IPageForItem } from '~/interfaces/page'; +import type { PopulatedGrantedGroup } from '~/interfaces/page-grant'; import loggerFactory from '~/utils/logger'; import type { SelectedPage } from '../../../../interfaces/selected-page'; @@ -13,6 +16,7 @@ import { useAiAssistantManagementModal, AiAssistantManagementModalPageMode } fro import { AiAssistantManagementEditInstruction } from './AiAssistantManagementEditInstruction'; import { AiAssistantManagementEditPages } from './AiAssistantManagementEditPages'; +import { AiAssistantManagementEditShare } from './AiAssistantManagementEditShare'; import { AiAssistantManagementHome } from './AiAssistantManagementHome'; import styles from './AiAssistantManagementModal.module.scss'; @@ -21,39 +25,117 @@ const moduleClass = styles['grw-ai-assistant-management'] ?? ''; const logger = loggerFactory('growi:openai:client:components:AiAssistantManagementModal'); +// PopulatedGrantedGroup[] -> IGrantedGroup[] +const convertToGrantedGroups = (selectedGroups: PopulatedGrantedGroup[]): IGrantedGroup[] => { + return selectedGroups.map(group => ({ + type: group.type, + item: group.item._id, + })); +}; + const AiAssistantManagementModalSubstance = (): JSX.Element => { // Hooks const { t } = useTranslation(); - const { data: aiAssistantManagementModalData } = useAiAssistantManagementModal(); + const { data: aiAssistantManagementModalData, close: closeAiAssistantManagementModal } = useAiAssistantManagementModal(); const pageMode = aiAssistantManagementModalData?.pageMode ?? AiAssistantManagementModalPageMode.HOME; // States + const [name, setName] = useState(''); + const [description, setDescription] = useState(''); + const [selectedShareScope, setSelectedShareScope] = useState(AiAssistantShareScope.SAME_AS_ACCESS_SCOPE); + const [selectedAccessScope, setSelectedAccessScope] = useState(AiAssistantAccessScope.OWNER); + const [selectedUserGroupsForAccessScope, setSelectedUserGroupsForAccessScope] = useState([]); + const [selectedUserGroupsForShareScope, setSelectedUserGroupsForShareScope] = useState([]); const [selectedPages, setSelectedPages] = useState([]); const [instruction, setInstruction] = useState(t('modal_ai_assistant.default_instruction')); - // Functions - const clickCreateAiAssistantHandler = useCallback(async() => { + + /* + * For AiAssistantManagementHome methods + */ + const changeNameHandler = useCallback((value: string) => { + setName(value); + }, []); + + const changeDescriptionHandler = useCallback((value: string) => { + setDescription(value); + }, []); + + const createAiAssistantHandler = useCallback(async() => { try { const pagePathPatterns = selectedPages .map(selectedPage => (selectedPage.isIncludeSubPage ? `${selectedPage.page.path}/*` : selectedPage.page.path)) .filter((path): path is string => path !== undefined && path !== null); + const grantedGroupsForShareScope = convertToGrantedGroups(selectedUserGroupsForShareScope); + const grantedGroupsForAccessScope = convertToGrantedGroups(selectedUserGroupsForAccessScope); + await createAiAssistant({ - name: 'test', - description: 'test', + name, + description, additionalInstruction: instruction, pagePathPatterns, - shareScope: 'publicOnly', - accessScope: 'publicOnly', + shareScope: selectedShareScope, + accessScope: selectedAccessScope, + grantedGroupsForShareScope: selectedShareScope === AiAssistantShareScope.GROUPS ? grantedGroupsForShareScope : undefined, + grantedGroupsForAccessScope: selectedAccessScope === AiAssistantAccessScope.GROUPS ? grantedGroupsForAccessScope : undefined, }); + toastSuccess('アシスタントを作成しました'); + closeAiAssistantManagementModal(); } catch (err) { toastError('アシスタントの作成に失敗しました'); logger.error(err); } - }, [instruction, selectedPages]); + }, [ + closeAiAssistantManagementModal, + description, + instruction, + name, + selectedAccessScope, + selectedPages, + selectedShareScope, + selectedUserGroupsForAccessScope, + selectedUserGroupsForShareScope, + ]); + + + /* + * For AiAssistantManagementEditShare methods + */ + const selectShareScopeHandler = useCallback((shareScope: AiAssistantShareScope) => { + setSelectedShareScope(shareScope); + }, []); + + const selectAccessScopeHandler = useCallback((accessScope: AiAssistantAccessScope) => { + setSelectedAccessScope(accessScope); + }, []); + + const selectShareScopeUserGroups = useCallback((targetUserGroup: PopulatedGrantedGroup) => { + const selectedUserGroupIds = selectedUserGroupsForShareScope.map(userGroup => userGroup.item._id); + if (selectedUserGroupIds.includes(targetUserGroup.item._id)) { + // if selected, remove it + setSelectedUserGroupsForShareScope(selectedUserGroupsForShareScope.filter(userGroup => userGroup.item._id !== targetUserGroup.item._id)); + } + else { + // if not selected, add it + setSelectedUserGroupsForShareScope([...selectedUserGroupsForShareScope, targetUserGroup]); + } + }, [selectedUserGroupsForShareScope]); + + const selectAccessScopeUserGroups = useCallback((targetUserGroup: PopulatedGrantedGroup) => { + const selectedUserGroupIds = selectedUserGroupsForAccessScope.map(userGroup => userGroup.item._id); + if (selectedUserGroupIds.includes(targetUserGroup.item._id)) { + // if selected, remove it + setSelectedUserGroupsForAccessScope(selectedUserGroupsForAccessScope.filter(userGroup => userGroup.item._id !== targetUserGroup.item._id)); + } + else { + // if not selected, add it + setSelectedUserGroupsForAccessScope([...selectedUserGroupsForAccessScope, targetUserGroup]); + } + }, [selectedUserGroupsForAccessScope]); /* @@ -87,7 +169,26 @@ const AiAssistantManagementModalSubstance = (): JSX.Element => { + + + + @@ -108,107 +209,6 @@ const AiAssistantManagementModalSubstance = (): JSX.Element => { - //
- // - //
- // - // - // - // - - // - //
- // - // help - //
- //
- // - // - // - // - // - // - // - // - // - // - // - // - //
- //
- - // - //
- // - // help - //
- // - // - // - //
- - // - //
- // - // help - //
- // - // - //
- - // - //
- // - // - //
- // - //
- - // - //
- // - // - //
- // - //

メモ内容はアシスタントには影響しません。

- //
- //
- //
- - // - // - // - // - //
); }; diff --git a/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/SelectUserGroupModal.tsx b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/SelectUserGroupModal.tsx new file mode 100644 index 00000000000..de3d96d0fa7 --- /dev/null +++ b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/SelectUserGroupModal.tsx @@ -0,0 +1,74 @@ +import React, { useCallback } from 'react'; + +import { GroupType } from '@growi/core'; +import { useTranslation } from 'react-i18next'; +import { + Modal, ModalHeader, ModalBody, +} from 'reactstrap'; + +import type { PopulatedGrantedGroup } from '~/interfaces/page-grant'; + +type Props = { + isOpen: boolean, + userRelatedGroups?: PopulatedGrantedGroup[], + selectedUserGroups: PopulatedGrantedGroup[], + closeModal: () => void, + onSelect: (userGroup: PopulatedGrantedGroup) => void, +} + +const SelectUserGroupModalSubstance: React.FC = (props: Props) => { + const { + userRelatedGroups, + selectedUserGroups, + onSelect, + closeModal, + } = props; + + const { t } = useTranslation(); + + const checked = useCallback((targetUserGroup: PopulatedGrantedGroup) => { + const selectedUserGroupIds = selectedUserGroups.map(userGroup => userGroup.item._id); + return selectedUserGroupIds.includes(targetUserGroup.item._id); + }, [selectedUserGroups]); + + return ( + + {userRelatedGroups != null && userRelatedGroups.map(userGroup => ( + + ))} + + + + ); +}; + +export const SelectUserGroupModal: React.FC = (props) => { + const { t } = useTranslation(); + + const { isOpen, closeModal } = props; + + return ( + + + {t('user_group.select_group')} + + + + ); +}; diff --git a/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/ShareScopeSwitch.tsx b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/ShareScopeSwitch.tsx new file mode 100644 index 00000000000..9ee9188cd4d --- /dev/null +++ b/apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/ShareScopeSwitch.tsx @@ -0,0 +1,52 @@ +import React from 'react'; + +import { useTranslation } from 'react-i18next'; +import { + Input, Label, FormGroup, +} from 'reactstrap'; + +import { AiAssistantShareScope } from '../../../../interfaces/ai-assistant'; + +type Props = { + isDisabled: boolean, + isDisabledGroups: boolean, + selectedShareScope: AiAssistantShareScope, + onSelect: (shareScope: AiAssistantShareScope) => void, +} + +export const ShareScopeSwitch: React.FC = (props: Props) => { + const { + isDisabled, + isDisabledGroups, + selectedShareScope, + onSelect, + } = props; + + const { t } = useTranslation(); + + return ( +
+ +
+ + {[AiAssistantShareScope.PUBLIC_ONLY, AiAssistantShareScope.GROUPS, AiAssistantShareScope.SAME_AS_ACCESS_SCOPE].map(shareScope => ( + + onSelect(shareScope)} + checked={selectedShareScope === shareScope} + /> + + + ))} +
+
+ ); +}; diff --git a/apps/app/src/features/openai/interfaces/ai-assistant.ts b/apps/app/src/features/openai/interfaces/ai-assistant.ts index 5653e91c649..b995e9681fc 100644 --- a/apps/app/src/features/openai/interfaces/ai-assistant.ts +++ b/apps/app/src/features/openai/interfaces/ai-assistant.ts @@ -6,7 +6,8 @@ import type { VectorStore } from '../server/models/vector-store'; * Objects */ export const AiAssistantShareScope = { - PUBLIC_ONLY: 'publicOnly', + SAME_AS_ACCESS_SCOPE: 'sameAsAccessScope', + PUBLIC_ONLY: 'publicOnly', // TODO: Rename to "PUBLIC" OWNER: 'owner', GROUPS: 'groups', } as const;