From 93e8491ca0fbfffaa399b15df5f6ff9fdba73eb0 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Tue, 17 Sep 2024 11:44:04 +0530 Subject: [PATCH 01/12] added side menu for ai-assistants --- .../images/icons/SideDrawer/AIToolkit.tsx | 12 +++++++++ .../images/icons/SideDrawer/Assistant.tsx | 12 +++++++++ .../images/icons/SideDrawer/Storage.tsx | 9 +++++++ .../Navigation/SideMenus/SideMenus.module.css | 8 ++++++ .../Layout/Navigation/SideMenus/SideMenus.tsx | 1 + src/components/UI/ListIcon/ListIcon.tsx | 6 +++++ src/config/menu.ts | 25 +++++++++++++++++++ src/containers/AIToolkit/AIToolkit.tsx | 5 ++++ .../AuthenticatedRoute/AuthenticatedRoute.tsx | 3 +++ 9 files changed, 81 insertions(+) create mode 100644 src/assets/images/icons/SideDrawer/AIToolkit.tsx create mode 100644 src/assets/images/icons/SideDrawer/Assistant.tsx create mode 100644 src/assets/images/icons/SideDrawer/Storage.tsx create mode 100644 src/containers/AIToolkit/AIToolkit.tsx diff --git a/src/assets/images/icons/SideDrawer/AIToolkit.tsx b/src/assets/images/icons/SideDrawer/AIToolkit.tsx new file mode 100644 index 000000000..3a81aba73 --- /dev/null +++ b/src/assets/images/icons/SideDrawer/AIToolkit.tsx @@ -0,0 +1,12 @@ +const SvgComponent = ({ color }: { color: string }) => ( + + + + + + +); +export default SvgComponent; diff --git a/src/assets/images/icons/SideDrawer/Assistant.tsx b/src/assets/images/icons/SideDrawer/Assistant.tsx new file mode 100644 index 000000000..dc088f50b --- /dev/null +++ b/src/assets/images/icons/SideDrawer/Assistant.tsx @@ -0,0 +1,12 @@ +const SvgComponent = ({ color }: { color: string }) => ( + + + + + + +); +export default SvgComponent; diff --git a/src/assets/images/icons/SideDrawer/Storage.tsx b/src/assets/images/icons/SideDrawer/Storage.tsx new file mode 100644 index 000000000..3d5aaf715 --- /dev/null +++ b/src/assets/images/icons/SideDrawer/Storage.tsx @@ -0,0 +1,9 @@ +const SvgComponent = ({ color }: { color: string }) => ( + + + +); +export default SvgComponent; diff --git a/src/components/UI/Layout/Navigation/SideMenus/SideMenus.module.css b/src/components/UI/Layout/Navigation/SideMenus/SideMenus.module.css index c8533e090..0f8324e02 100644 --- a/src/components/UI/Layout/Navigation/SideMenus/SideMenus.module.css +++ b/src/components/UI/Layout/Navigation/SideMenus/SideMenus.module.css @@ -104,3 +104,11 @@ margin-left: -10px; padding-left: 25px; } + +.New { + background-color: #119656; + font-size: 10px; + border-radius: 4px; + padding: 2px 6px; + color: #fff; +} diff --git a/src/components/UI/Layout/Navigation/SideMenus/SideMenus.tsx b/src/components/UI/Layout/Navigation/SideMenus/SideMenus.tsx index ed4ceb039..50a998737 100644 --- a/src/components/UI/Layout/Navigation/SideMenus/SideMenus.tsx +++ b/src/components/UI/Layout/Navigation/SideMenus/SideMenus.tsx @@ -212,6 +212,7 @@ const SideMenus = ({ opened }: SideMenusProps) => { primary={t(menu.title as any)} /> )} + {menu.new && {'New'}} ); diff --git a/src/components/UI/ListIcon/ListIcon.tsx b/src/components/UI/ListIcon/ListIcon.tsx index 7cfc3af0d..c9eb83596 100644 --- a/src/components/UI/ListIcon/ListIcon.tsx +++ b/src/components/UI/ListIcon/ListIcon.tsx @@ -28,6 +28,9 @@ import WaChatIcon from 'assets/images/icons/SideDrawer/WaGroupChat'; import WaCollectionIcon from 'assets/images/icons/SideDrawer/WaGroupCollection'; import WaGroupIcon from 'assets/images/icons/SideDrawer/WhatsAppGroupIcon'; import KnowledgeBaseIcon from 'assets/images/icons/SideDrawer/KnowledgeBaseIcon'; +import AIToolkit from 'assets/images/icons/SideDrawer/AIToolkit'; +import Assistant from 'assets/images/icons/SideDrawer/Assistant'; +import Storage from 'assets/images/icons/SideDrawer/Storage'; import styles from './ListIcon.module.css'; import FiberNewIcon from '@mui/icons-material/FiberNew'; import { Badge } from '@mui/material'; @@ -73,6 +76,9 @@ export const ListIcon = ({ icon = '', selected = false, count }: ListIconProps) waGroupChat: WaChatIcon, waGroup: WaGroupIcon, knowledgeBase: KnowledgeBaseIcon, + aiToolkit: AIToolkit, + assistant: Assistant, + storage: Storage, }; const iconImage = stringsToIcons[icon] && ( diff --git a/src/config/menu.ts b/src/config/menu.ts index 8b1cc92e1..37d2742aa 100644 --- a/src/config/menu.ts +++ b/src/config/menu.ts @@ -17,6 +17,7 @@ export interface Menu { url?: string; show?: boolean; children?: Menu[]; + new?: boolean; } // define all the menus in the system @@ -97,6 +98,30 @@ const menus = (): Menu[] => [ ], roles: managerLevel, }, + { + title: 'AI Toolkit', + path: '/ai/assistants', + icon: 'aiToolkit', + type: 'sideDrawer', + roles: allRoles, + new: true, + children: [ + { + title: 'Assistants', + path: '/ai/assistants', + icon: 'assistant', + type: 'sideDrawer', + roles: allRoles, + }, + { + title: 'Vector Storage', + path: '/ai/storage', + icon: 'storage', + type: 'sideDrawer', + roles: allRoles, + }, + ], + }, { title: 'Support tickets', path: '/ticket', diff --git a/src/containers/AIToolkit/AIToolkit.tsx b/src/containers/AIToolkit/AIToolkit.tsx new file mode 100644 index 000000000..a6f7b7534 --- /dev/null +++ b/src/containers/AIToolkit/AIToolkit.tsx @@ -0,0 +1,5 @@ +export const AIToolkit = () => { + return
AI
; +}; + +export default AIToolkit; diff --git a/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx b/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx index cb51d5b93..52c181775 100644 --- a/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx +++ b/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx @@ -73,6 +73,7 @@ const InteractiveMessage = lazy(() => import('containers/InteractiveMessage/Inte const RoleList = lazy(() => import('containers/Role/RoleList/RoleList')); const Role = lazy(() => import('containers/Role/Role')); const KnowledgeBase = lazy(() => import('containers/KnowledgeBase/KnowledgeBase')); +const AIToolkit = lazy(() => import('containers/AIToolkit/AIToolkit')); const routeStaff = ( @@ -156,6 +157,8 @@ const routeAdmin = ( } /> + } /> + } /> ); From 8c9cd91bf16336220eb4d712513a593c1ad5286c Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Fri, 20 Sep 2024 15:54:31 +0530 Subject: [PATCH 02/12] added assistants page --- src/common/HelpData.tsx | 6 ++ src/components/UI/Heading/Heading.module.css | 6 ++ src/components/UI/Heading/Heading.tsx | 35 +++++++++- src/containers/AIToolkit/AIToolkit.tsx | 5 -- .../Assistants/Assistants.module.css | 60 ++++++++++++++++ .../AIToolkit/Assistants/Assistants.tsx | 56 +++++++++++++++ .../CreateAssistant.tsx/CreateAssistant.tsx | 69 +++++++++++++++++++ .../AuthenticatedRoute/AuthenticatedRoute.tsx | 4 +- yarn.lock | 21 +++++- 9 files changed, 250 insertions(+), 12 deletions(-) delete mode 100644 src/containers/AIToolkit/AIToolkit.tsx create mode 100644 src/containers/AIToolkit/Assistants/Assistants.module.css create mode 100644 src/containers/AIToolkit/Assistants/Assistants.tsx create mode 100644 src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx diff --git a/src/common/HelpData.tsx b/src/common/HelpData.tsx index 96b25a2dd..cbf425fe6 100644 --- a/src/common/HelpData.tsx +++ b/src/common/HelpData.tsx @@ -101,3 +101,9 @@ export const blockedContactsInfo: HelpDataProps = { 'Glific allows you to block contacts who are sending unwanted or inappropriate messages, ensuring a positive experience for both your beneficiaries and staff.', link: 'https://glific.github.io/docs/docs/Product%20Features/Others/All%20product%20features/#block-contacts', // Replace with the actual Glific documentation link }; + +export const assistantsInfo: HelpDataProps = { + heading: + 'Assistants can call OpenAI’s models with specific instructions to tune their personality and capabilities. Assistants can access multiple tools in parallel. Assistants can access files in several formats as part of their creation. When using tools, Assistants can also create files (e.g., images, spreadsheets, etc) and cite files they reference in the Messages they create.', + link: 'https://glific.github.io/docs/docs/Product%20Features/Flows/Flow%20Variables/Flow%20variables%20vs%20Contact%20variables', // Replace with the actual Glific documentation link +}; diff --git a/src/components/UI/Heading/Heading.module.css b/src/components/UI/Heading/Heading.module.css index 6af767b1d..c738fa20f 100644 --- a/src/components/UI/Heading/Heading.module.css +++ b/src/components/UI/Heading/Heading.module.css @@ -40,3 +40,9 @@ cursor: pointer; margin-top: 10px; } + +.Button { + width: 100%; + display: flex; + column-gap: 5px; +} diff --git a/src/components/UI/Heading/Heading.tsx b/src/components/UI/Heading/Heading.tsx index fbd349871..90efed32b 100644 --- a/src/components/UI/Heading/Heading.tsx +++ b/src/components/UI/Heading/Heading.tsx @@ -2,16 +2,34 @@ import { useNavigate } from 'react-router-dom'; import HelpIcon from '../HelpIcon/HelpIcon'; import styles from './Heading.module.css'; import BackIcon from 'assets/images/icons/BackIconFlow.svg?react'; +import { Button } from '../Form/Button/Button'; +import AddIcon from 'assets/images/add.svg?react'; export interface HeadingProps { formTitle: string; helpData?: any; showHeaderHelp?: boolean; backLink?: string; + headerHelp?: string; + button?: { + show: boolean; + label: string; + action: any; + icon?: any; + }; } -export const Heading = ({ formTitle, helpData, showHeaderHelp = true, backLink }: HeadingProps) => { +export const Heading = ({ + formTitle, + helpData, + showHeaderHelp = true, + backLink, + headerHelp, + button, +}: HeadingProps) => { const navigate = useNavigate(); + const addIcon = ; + return (
@@ -24,10 +42,23 @@ export const Heading = ({ formTitle, helpData, showHeaderHelp = true, backLink } {helpData ? : ''}
- {showHeaderHelp ? `Please enter below details.` : ''} + {showHeaderHelp ? headerHelp || `Please enter below details.` : ''}
+ {button && button.show && ( +
+ +
+ )} ); }; diff --git a/src/containers/AIToolkit/AIToolkit.tsx b/src/containers/AIToolkit/AIToolkit.tsx deleted file mode 100644 index a6f7b7534..000000000 --- a/src/containers/AIToolkit/AIToolkit.tsx +++ /dev/null @@ -1,5 +0,0 @@ -export const AIToolkit = () => { - return
AI
; -}; - -export default AIToolkit; diff --git a/src/containers/AIToolkit/Assistants/Assistants.module.css b/src/containers/AIToolkit/Assistants/Assistants.module.css new file mode 100644 index 000000000..3fbac510c --- /dev/null +++ b/src/containers/AIToolkit/Assistants/Assistants.module.css @@ -0,0 +1,60 @@ +.AssistantContainer { + width: 100%; + height: 100vh !important; +} + +.MainContainer { + width: 100%; + height: 80%; + display: flex; +} + +.LeftContainer { + height: 100%; + width: 50% !important; + border-right: 1px solid #00000029; + padding: 2rem 4rem; + background-color: #f8faf5; +} + +.RightContainer { + height: 100%; + width: 50% !important; +} + +.AssistantList { + height: 100%; + display: flex; + flex-direction: column; + row-gap: 0.5rem; + margin: 1rem 0; + overflow-y: scroll; +} + +.Assistant { + background-color: #fff; + padding: 0.8rem 1rem; + border-radius: 8px; +} + +.AssistantHeader { + width: 100%; + display: flex; + justify-content: space-between; + align-items: flex-end; +} + +.AssistantTitle { + font-size: 16px; + font-weight: 600; +} + +.AssistantDate { + font-size: 10px; + color: #0000007a; +} + +.AssistantId { + font-size: 12px; + color: #555; +} diff --git a/src/containers/AIToolkit/Assistants/Assistants.tsx b/src/containers/AIToolkit/Assistants/Assistants.tsx new file mode 100644 index 000000000..50fa1c1a3 --- /dev/null +++ b/src/containers/AIToolkit/Assistants/Assistants.tsx @@ -0,0 +1,56 @@ +import { assistantsInfo } from 'common/HelpData'; +import { Heading } from 'components/UI/Heading/Heading'; +import styles from './Assistants.module.css'; +import SearchBar from 'components/UI/SearchBar/SearchBar'; +import { CreateAssistant } from '../CreateAssistant.tsx/CreateAssistant'; + +export const Assistants = () => { + const assistants = [ + { title: 'Untitled assistant', id: 'asst_KsGPe1fAchlx6lAggIWfPEXN', inserted_at: '6:30 PM' }, + { title: 'Vyse module', id: 'asst_KsGPe1fAchlx6lAggIWfPEXN', inserted_at: '6:30 PM' }, + { + title: 'Sova integration module', + id: 'asst_KsGPe1fAchlx6lAggIWfPEXN', + inserted_at: '6:30 PM', + }, + ]; + return ( +
+ {} }} + /> +
+
+
+ {}} + onReset={() => ''} + searchMode + iconFront + /> +
+
+ {[...assistants, ...assistants, ...assistants].map((assistant) => ( +
+
+ {assistant.title} + {assistant.inserted_at} +
+ {assistant.id} +
+ ))} +
+
+
+ +
+
+
+ ); +}; + +export default Assistants; diff --git a/src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx b/src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx new file mode 100644 index 000000000..a79d7d556 --- /dev/null +++ b/src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx @@ -0,0 +1,69 @@ +import { AutoComplete } from 'components/UI/Form/AutoComplete/AutoComplete'; +import { Input } from 'components/UI/Form/Input/Input'; +import { FormLayout } from 'containers/Form/FormLayout'; +import { + CREATE_COLLECTION, + DELETE_COLLECTION, + UPDATE_COLLECTION, +} from 'graphql/mutations/Collection'; +import { GET_COLLECTION } from 'graphql/queries/Collection'; + +export const CreateAssistant = () => { + const queries = { + getItemQuery: GET_COLLECTION, + createItemQuery: CREATE_COLLECTION, + updateItemQuery: UPDATE_COLLECTION, + deleteItemQuery: DELETE_COLLECTION, + }; + const formFields = [ + { + component: AutoComplete, + name: 'model', + options: [], + optionLabel: 'name', + label: 'Model', + skipPayload: true, + helperText: 'Choose the best model for your needs', + }, + { + component: Input, + name: 'name', + type: 'text', + label: 'Name', + helpeText: 'Give a recognizable name for your assistant', + }, + { + component: Input, + name: 'description', + type: 'text', + label: 'Description', + rows: 3, + textArea: true, + }, + ]; + const states = {}; + const setStates = () => {}; + const setPayload = () => {}; + + const FormSchema = {}; + + return ( + + ); +}; diff --git a/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx b/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx index 52c181775..57850f478 100644 --- a/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx +++ b/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx @@ -73,7 +73,7 @@ const InteractiveMessage = lazy(() => import('containers/InteractiveMessage/Inte const RoleList = lazy(() => import('containers/Role/RoleList/RoleList')); const Role = lazy(() => import('containers/Role/Role')); const KnowledgeBase = lazy(() => import('containers/KnowledgeBase/KnowledgeBase')); -const AIToolkit = lazy(() => import('containers/AIToolkit/AIToolkit')); +const Assistants = lazy(() => import('containers/AIToolkit/Assistants/Assistants')); const routeStaff = ( @@ -157,7 +157,7 @@ const routeAdmin = ( } /> - } /> + } /> } /> diff --git a/yarn.lock b/yarn.lock index 529a42dfc..d8abb93d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5973,8 +5973,16 @@ streamx@^2.12.0, streamx@^2.12.5, streamx@^2.13.2, streamx@^2.14.0: optionalDependencies: bare-events "^2.2.0" -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: - name string-width-cjs +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6068,7 +6076,14 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== From 8cc81501dfc4fbd081b4f6de47e42bf134dfdfc9 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Tue, 24 Sep 2024 17:29:26 +0530 Subject: [PATCH 03/12] refactored assistants page --- src/common/HelpData.tsx | 2 +- src/components/UI/HelpIcon/HelpIcon.tsx | 18 ++-- .../AssistantOptions.module.css | 40 +++++++++ .../AssistantOptions/AssistantOptions.tsx | 86 +++++++++++++++++++ .../Assistants/Assistants.module.css | 13 ++- .../AIToolkit/Assistants/Assistants.tsx | 3 +- .../CreateAssistant.tsx/CreateAssistant.tsx | 84 +++++++++++------- .../FormLayout/FormLayout.module.css | 34 ++++++++ .../AIToolkit/FormLayout/FormLayout.tsx | 52 +++++++++++ src/containers/Form/FormLayout.module.css | 2 +- 10 files changed, 290 insertions(+), 44 deletions(-) create mode 100644 src/containers/AIToolkit/AssistantOptions/AssistantOptions.module.css create mode 100644 src/containers/AIToolkit/AssistantOptions/AssistantOptions.tsx create mode 100644 src/containers/AIToolkit/FormLayout/FormLayout.module.css create mode 100644 src/containers/AIToolkit/FormLayout/FormLayout.tsx diff --git a/src/common/HelpData.tsx b/src/common/HelpData.tsx index cbf425fe6..feed84a86 100644 --- a/src/common/HelpData.tsx +++ b/src/common/HelpData.tsx @@ -1,6 +1,6 @@ export interface HelpDataProps { heading: string; - link: string; + link?: string; } export const speedSendInfo: HelpDataProps = { diff --git a/src/components/UI/HelpIcon/HelpIcon.tsx b/src/components/UI/HelpIcon/HelpIcon.tsx index fb0901e6c..5648f5a1c 100644 --- a/src/components/UI/HelpIcon/HelpIcon.tsx +++ b/src/components/UI/HelpIcon/HelpIcon.tsx @@ -26,14 +26,16 @@ export const HelpIcon = ({
{helpData.heading} -
{ - window.open(helpData.link); - }} - > - Learn more -
+ {helpData.link && ( +
{ + window.open(helpData.link); + }} + > + Learn more +
+ )}
)} diff --git a/src/containers/AIToolkit/AssistantOptions/AssistantOptions.module.css b/src/containers/AIToolkit/AssistantOptions/AssistantOptions.module.css new file mode 100644 index 000000000..10bcd68bb --- /dev/null +++ b/src/containers/AIToolkit/AssistantOptions/AssistantOptions.module.css @@ -0,0 +1,40 @@ +.AssistantOptions { + margin: 1rem 0; + display: flex; + flex-direction: column; + row-gap: 1rem; +} + +.Label { + font-size: 1rem; + font-weight: 600; + color: #555; + display: flex; + align-items: center; + column-gap: 0.5rem; +} + +.Temperature { + display: flex; + column-gap: 1rem; + align-items: center; +} + +.Slider { + width: 80%; + display: flex; + align-items: center; + column-gap: 1rem; +} + +.SliderDisplay { + font-size: 15px; + padding: 4px 8px; + border: 0.5px solid #a4a4a4; + border-radius: 4px; + width: 15%; +} + +.SliderDisplay:focus { + outline: none; +} diff --git a/src/containers/AIToolkit/AssistantOptions/AssistantOptions.tsx b/src/containers/AIToolkit/AssistantOptions/AssistantOptions.tsx new file mode 100644 index 000000000..c850397e6 --- /dev/null +++ b/src/containers/AIToolkit/AssistantOptions/AssistantOptions.tsx @@ -0,0 +1,86 @@ +import { FormControlLabel, Slider, Switch, Typography } from '@mui/material'; +import { useState } from 'react'; +import styles from './AssistantOptions.module.css'; +import InfoIcon from 'assets/images/icons/Info.svg?react'; +import Tooltip from 'components/UI/Tooltip/Tooltip'; +import HelpIcon from 'components/UI/HelpIcon/HelpIcon'; + +interface AssistantOptionsProps { + form: any; + field: any; + fileSearch: boolean; +} + +const temperatureInfo = + 'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.'; + +const fileSearchInfo = + 'File search enables the assistant with knowledge from files that you or your users upload. Once a file is uploaded, the assistant automatically decides when to retrieve content based on user requests.'; + +export const AssistantOptions = ({ form, field, fileSearch }: AssistantOptionsProps) => { + const [checked, setChecked] = useState(false); + console.log(field.value); + + return ( +
+
+ + Tools + + { + form.setFieldValue('options', { + ...field.value, + fileSearch: event.target.checked, + }); + console.log(event.target.checked); + }} + /> + } + label="File Search" + /> + + +
+ +
+ + Temperature + + + +
+ { + form.setFieldValue('options', { + ...field.value, + temperature: value, + }); + }} + value={field.value.temperature} + step={0.01} + max={2} + /> + { + form.setFieldValue('options', { + ...field.value, + temperature: event.target.value, + }); + }} + className={styles.SliderDisplay} + /> +
+
+
+ ); +}; diff --git a/src/containers/AIToolkit/Assistants/Assistants.module.css b/src/containers/AIToolkit/Assistants/Assistants.module.css index 3fbac510c..2981f138a 100644 --- a/src/containers/AIToolkit/Assistants/Assistants.module.css +++ b/src/containers/AIToolkit/Assistants/Assistants.module.css @@ -5,7 +5,7 @@ .MainContainer { width: 100%; - height: 80%; + height: calc(100vh - 110px); display: flex; } @@ -15,19 +15,28 @@ border-right: 1px solid #00000029; padding: 2rem 4rem; background-color: #f8faf5; + position: relative; } .RightContainer { height: 100%; width: 50% !important; + overflow-y: scroll; +} + +.Search { + width: 50%; + position: absolute; + top: 0; + margin: 1rem 0; } .AssistantList { + margin-top: 2rem; height: 100%; display: flex; flex-direction: column; row-gap: 0.5rem; - margin: 1rem 0; overflow-y: scroll; } diff --git a/src/containers/AIToolkit/Assistants/Assistants.tsx b/src/containers/AIToolkit/Assistants/Assistants.tsx index 50fa1c1a3..1debb9785 100644 --- a/src/containers/AIToolkit/Assistants/Assistants.tsx +++ b/src/containers/AIToolkit/Assistants/Assistants.tsx @@ -14,6 +14,7 @@ export const Assistants = () => { inserted_at: '6:30 PM', }, ]; + return (
{ />
-
+
{}} diff --git a/src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx b/src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx index a79d7d556..6eb16790c 100644 --- a/src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx +++ b/src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx @@ -1,69 +1,91 @@ import { AutoComplete } from 'components/UI/Form/AutoComplete/AutoComplete'; import { Input } from 'components/UI/Form/Input/Input'; -import { FormLayout } from 'containers/Form/FormLayout'; import { CREATE_COLLECTION, DELETE_COLLECTION, UPDATE_COLLECTION, } from 'graphql/mutations/Collection'; import { GET_COLLECTION } from 'graphql/queries/Collection'; +import { AssistantOptions } from '../AssistantOptions/AssistantOptions'; +import { useState } from 'react'; +import { FormLayout } from '../FormLayout/FormLayout'; + +const queries = { + getItemQuery: GET_COLLECTION, + createItemQuery: CREATE_COLLECTION, + updateItemQuery: UPDATE_COLLECTION, + deleteItemQuery: DELETE_COLLECTION, +}; export const CreateAssistant = () => { - const queries = { - getItemQuery: GET_COLLECTION, - createItemQuery: CREATE_COLLECTION, - updateItemQuery: UPDATE_COLLECTION, - deleteItemQuery: DELETE_COLLECTION, - }; + const [name, setName] = useState(''); + const [model, setModel] = useState(); + const [prompt, setPrompt] = useState(''); + const [fileSearch, setFileSearch] = useState(true); + const [options, setOptions] = useState({ fileSearch: true, temperature: 1 }); + + const models = [ + { id: '1', name: 'gpt-4o ' }, + { id: '2', name: 'GPT-4' }, + { id: '3', name: 'GPT-5' }, + ]; + const formFields = [ { component: AutoComplete, name: 'model', - options: [], + options: models, optionLabel: 'name', label: 'Model', skipPayload: true, helperText: 'Choose the best model for your needs', + multiple: false, }, { component: Input, name: 'name', type: 'text', label: 'Name', - helpeText: 'Give a recognizable name for your assistant', + helperText: 'Give a recognizable name for your assistant', }, { component: Input, - name: 'description', + name: 'prompt', type: 'text', - label: 'Description', + label: 'Instructions', rows: 3, textArea: true, + helperText: 'Set the instructions according to your requirements.', + }, + { + component: AssistantOptions, + name: 'options', + fileSearch, + options, }, ]; - const states = {}; - const setStates = () => {}; - const setPayload = () => {}; + + const states = { + name, + model, + prompt, + fileSearch, + options, + }; + + const setStates = ({ name: nameValue, prompt: promptValue, model: modelValue }: any) => { + setName(nameValue); + setModel(modelValue); + setPrompt(promptValue); + }; + + const setPayload = (payload: any) => { + console.log(payload); + }; const FormSchema = {}; return ( - + ); }; diff --git a/src/containers/AIToolkit/FormLayout/FormLayout.module.css b/src/containers/AIToolkit/FormLayout/FormLayout.module.css new file mode 100644 index 000000000..fd5063108 --- /dev/null +++ b/src/containers/AIToolkit/FormLayout/FormLayout.module.css @@ -0,0 +1,34 @@ +.FormContainer { + padding: 3rem; + height: 100%; + position: relative; +} + +.Form { + height: 100%; + overflow-y: scroll; +} + +.Form::-webkit-scrollbar { + display: none; +} + +.Label { + color: #555; + font-size: 1rem; + font-weight: 500; + margin-bottom: 0.5rem; +} + +.FormFields { + display: flex; + flex-direction: column; + row-gap: 1rem; +} + +.Buttons { + background-color: #fff; + padding: 1rem 0; + position: absolute; + bottom: 0; +} diff --git a/src/containers/AIToolkit/FormLayout/FormLayout.tsx b/src/containers/AIToolkit/FormLayout/FormLayout.tsx new file mode 100644 index 000000000..b84dcff0b --- /dev/null +++ b/src/containers/AIToolkit/FormLayout/FormLayout.tsx @@ -0,0 +1,52 @@ +import { Field, Form, Formik, FormikProvider, useFormik } from 'formik'; +import styles from './FormLayout.module.css'; +import { Typography } from '@mui/material'; +import { Button } from 'components/UI/Form/Button/Button'; + +interface FormLayoutProps { + initialValues: any; + validationSchema: any; + formFieldItems: any; + skipSave?: boolean; +} + +export const FormLayout = ({ + initialValues, + validationSchema, + formFieldItems, + skipSave = false, +}: FormLayoutProps) => { + const formik = useFormik({ + initialValues, + validationSchema, + enableReinitialize: true, + onSubmit: (values, { setErrors }) => {}, + }); + + return ( + +
+
+
+ {formFieldItems.map((field: any) => ( +
+ + {field.label} + + + +
+ ))} +
+
+ {!skipSave && } + + +
+
+
+
+ ); +}; diff --git a/src/containers/Form/FormLayout.module.css b/src/containers/Form/FormLayout.module.css index 3703a146d..1d6a7b45a 100644 --- a/src/containers/Form/FormLayout.module.css +++ b/src/containers/Form/FormLayout.module.css @@ -26,7 +26,7 @@ } .ItemAdd { - height: 100vh; + height: 100%; background-color: #ffffff; } From cdd32f0d39606693ad507c53e9d038b7a5697f56 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Wed, 25 Sep 2024 11:52:22 +0530 Subject: [PATCH 04/12] added storage page --- src/common/HelpData.tsx | 6 +++++ .../AIToolkit/Storage/Storage.module.css | 0 src/containers/AIToolkit/Storage/Storage.tsx | 24 +++++++++++++++++++ .../AuthenticatedRoute/AuthenticatedRoute.tsx | 2 ++ 4 files changed, 32 insertions(+) create mode 100644 src/containers/AIToolkit/Storage/Storage.module.css create mode 100644 src/containers/AIToolkit/Storage/Storage.tsx diff --git a/src/common/HelpData.tsx b/src/common/HelpData.tsx index feed84a86..7b16020eb 100644 --- a/src/common/HelpData.tsx +++ b/src/common/HelpData.tsx @@ -107,3 +107,9 @@ export const assistantsInfo: HelpDataProps = { 'Assistants can call OpenAI’s models with specific instructions to tune their personality and capabilities. Assistants can access multiple tools in parallel. Assistants can access files in several formats as part of their creation. When using tools, Assistants can also create files (e.g., images, spreadsheets, etc) and cite files they reference in the Messages they create.', link: 'https://glific.github.io/docs/docs/Product%20Features/Flows/Flow%20Variables/Flow%20variables%20vs%20Contact%20variables', // Replace with the actual Glific documentation link }; + +export const storageInfo: HelpDataProps = { + heading: + 'Assistants can call OpenAI’s models with specific instructions to tune their personality and capabilities. Assistants can access multiple tools in parallel. Assistants can access files in several formats as part of their creation. When using tools, Assistants can also create files (e.g., images, spreadsheets, etc) and cite files they reference in the Messages they create.', + link: 'https://glific.github.io/docs/docs/Product%20Features/Flows/Flow%20Variables/Flow%20variables%20vs%20Contact%20variables', // Replace with the actual Glific documentation link +}; diff --git a/src/containers/AIToolkit/Storage/Storage.module.css b/src/containers/AIToolkit/Storage/Storage.module.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/containers/AIToolkit/Storage/Storage.tsx b/src/containers/AIToolkit/Storage/Storage.tsx new file mode 100644 index 000000000..a1cd1ea2b --- /dev/null +++ b/src/containers/AIToolkit/Storage/Storage.tsx @@ -0,0 +1,24 @@ +import { storageInfo } from 'common/HelpData'; + +export const VectorStorage = () => { + const storage = [ + { title: 'Untitled store', id: 'vs_KyUlkD25kP34DIANLwxYWQK0', inserted_at: '6:30 PM' }, + { + title: 'Smart store for vyse module', + id: 'vs_KyUlkD25kP34DIANLwxYWQK0', + inserted_at: '6:30 PM', + }, + { + title: 'Sova Integration module', + id: 'vs_KyUlkD25kP34DIANLwxYWQK0', + inserted_at: '6:30 PM', + }, + ]; + const states = {}; + const formFields = [{}]; + const FormSchema = {}; + + return <>; +}; + +export default VectorStorage; diff --git a/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx b/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx index 57850f478..70c5841ff 100644 --- a/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx +++ b/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx @@ -74,6 +74,7 @@ const RoleList = lazy(() => import('containers/Role/RoleList/RoleList')); const Role = lazy(() => import('containers/Role/Role')); const KnowledgeBase = lazy(() => import('containers/KnowledgeBase/KnowledgeBase')); const Assistants = lazy(() => import('containers/AIToolkit/Assistants/Assistants')); +const VectorStorage = lazy(() => import('containers/AIToolkit/Storage/Storage')); const routeStaff = ( @@ -158,6 +159,7 @@ const routeAdmin = ( } /> } /> + } /> } /> From 5a477ec000842d3b959119bbd574e2fb6bf9fc2c Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Thu, 26 Sep 2024 20:53:17 +0530 Subject: [PATCH 05/12] added storage page --- src/assets/images/Assistant.svg | 9 +++ src/assets/images/file.svg | 3 + src/assets/images/time.svg | 3 + .../AssistantOptions.module.css | 0 .../AssistantOptions/AssistantOptions.tsx | 0 .../Assistants/Assistants.module.css | 32 +++++++++ .../{ => Assistant}/Assistants/Assistants.tsx | 15 +--- .../CreateAssistant.module.css} | 0 .../CreateAssistant}/CreateAssistant.tsx | 46 ++++++++++--- .../Assistants/Assistants.module.css | 69 ------------------- .../AIToolkit/FormLayout/FormLayout.tsx | 52 -------------- .../AIToolkit/ListItems/List.module.css | 44 ++++++++++++ src/containers/AIToolkit/ListItems/List.tsx | 25 +++++++ .../Storage/Assistants/AssistantsAttached.tsx | 7 ++ .../Storage/CreateStorage/CreateStorage.tsx | 45 ++++++++++++ .../AIToolkit/Storage/Files/Files.tsx | 7 ++ .../AIToolkit/Storage/Storage.module.css | 0 src/containers/AIToolkit/Storage/Storage.tsx | 24 ------- .../Storage/Storage/Storage.module.css | 26 +++++++ .../AIToolkit/Storage/Storage/Storage.tsx | 55 +++++++++++++++ .../StorageDetails/StorageDetails.module.css | 31 +++++++++ .../Storage/StorageDetails/StorageDetails.tsx | 34 +++++++++ .../AuthenticatedRoute/AuthenticatedRoute.tsx | 4 +- 23 files changed, 362 insertions(+), 169 deletions(-) create mode 100644 src/assets/images/Assistant.svg create mode 100644 src/assets/images/file.svg create mode 100644 src/assets/images/time.svg rename src/containers/AIToolkit/{ => Assistant}/AssistantOptions/AssistantOptions.module.css (100%) rename src/containers/AIToolkit/{ => Assistant}/AssistantOptions/AssistantOptions.tsx (100%) create mode 100644 src/containers/AIToolkit/Assistant/Assistants/Assistants.module.css rename src/containers/AIToolkit/{ => Assistant}/Assistants/Assistants.tsx (69%) rename src/containers/AIToolkit/{FormLayout/FormLayout.module.css => Assistant/CreateAssistant/CreateAssistant.module.css} (100%) rename src/containers/AIToolkit/{CreateAssistant.tsx => Assistant/CreateAssistant}/CreateAssistant.tsx (61%) delete mode 100644 src/containers/AIToolkit/Assistants/Assistants.module.css delete mode 100644 src/containers/AIToolkit/FormLayout/FormLayout.tsx create mode 100644 src/containers/AIToolkit/ListItems/List.module.css create mode 100644 src/containers/AIToolkit/ListItems/List.tsx create mode 100644 src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx create mode 100644 src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx create mode 100644 src/containers/AIToolkit/Storage/Files/Files.tsx delete mode 100644 src/containers/AIToolkit/Storage/Storage.module.css delete mode 100644 src/containers/AIToolkit/Storage/Storage.tsx create mode 100644 src/containers/AIToolkit/Storage/Storage/Storage.module.css create mode 100644 src/containers/AIToolkit/Storage/Storage/Storage.tsx create mode 100644 src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.module.css create mode 100644 src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx diff --git a/src/assets/images/Assistant.svg b/src/assets/images/Assistant.svg new file mode 100644 index 000000000..5377e7758 --- /dev/null +++ b/src/assets/images/Assistant.svg @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/src/assets/images/file.svg b/src/assets/images/file.svg new file mode 100644 index 000000000..3002fdbdd --- /dev/null +++ b/src/assets/images/file.svg @@ -0,0 +1,3 @@ + diff --git a/src/assets/images/time.svg b/src/assets/images/time.svg new file mode 100644 index 000000000..1f7afdd4b --- /dev/null +++ b/src/assets/images/time.svg @@ -0,0 +1,3 @@ + diff --git a/src/containers/AIToolkit/AssistantOptions/AssistantOptions.module.css b/src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.module.css similarity index 100% rename from src/containers/AIToolkit/AssistantOptions/AssistantOptions.module.css rename to src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.module.css diff --git a/src/containers/AIToolkit/AssistantOptions/AssistantOptions.tsx b/src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.tsx similarity index 100% rename from src/containers/AIToolkit/AssistantOptions/AssistantOptions.tsx rename to src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.tsx diff --git a/src/containers/AIToolkit/Assistant/Assistants/Assistants.module.css b/src/containers/AIToolkit/Assistant/Assistants/Assistants.module.css new file mode 100644 index 000000000..960521639 --- /dev/null +++ b/src/containers/AIToolkit/Assistant/Assistants/Assistants.module.css @@ -0,0 +1,32 @@ +.AssistantContainer { + width: 100%; + height: 100vh !important; +} + +.MainContainer { + width: 100%; + height: calc(100vh - 110px); + display: flex; +} + +.LeftContainer { + height: 100%; + width: 50% !important; + border-right: 1px solid #00000029; + padding: 2rem 4rem; + background-color: #f8faf5; + position: relative; +} + +.RightContainer { + height: 100%; + width: 50% !important; + overflow-y: scroll; +} + +.Search { + width: 50%; + position: absolute; + top: 0; + margin: 1rem 0; +} diff --git a/src/containers/AIToolkit/Assistants/Assistants.tsx b/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx similarity index 69% rename from src/containers/AIToolkit/Assistants/Assistants.tsx rename to src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx index 1debb9785..0caa7d772 100644 --- a/src/containers/AIToolkit/Assistants/Assistants.tsx +++ b/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx @@ -2,7 +2,8 @@ import { assistantsInfo } from 'common/HelpData'; import { Heading } from 'components/UI/Heading/Heading'; import styles from './Assistants.module.css'; import SearchBar from 'components/UI/SearchBar/SearchBar'; -import { CreateAssistant } from '../CreateAssistant.tsx/CreateAssistant'; +import { CreateAssistant } from '../CreateAssistant/CreateAssistant'; +import { List } from '../../ListItems/List'; export const Assistants = () => { const assistants = [ @@ -34,17 +35,7 @@ export const Assistants = () => { iconFront />
-
- {[...assistants, ...assistants, ...assistants].map((assistant) => ( -
-
- {assistant.title} - {assistant.inserted_at} -
- {assistant.id} -
- ))} -
+
diff --git a/src/containers/AIToolkit/FormLayout/FormLayout.module.css b/src/containers/AIToolkit/Assistant/CreateAssistant/CreateAssistant.module.css similarity index 100% rename from src/containers/AIToolkit/FormLayout/FormLayout.module.css rename to src/containers/AIToolkit/Assistant/CreateAssistant/CreateAssistant.module.css diff --git a/src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx b/src/containers/AIToolkit/Assistant/CreateAssistant/CreateAssistant.tsx similarity index 61% rename from src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx rename to src/containers/AIToolkit/Assistant/CreateAssistant/CreateAssistant.tsx index 6eb16790c..c93b691e8 100644 --- a/src/containers/AIToolkit/CreateAssistant.tsx/CreateAssistant.tsx +++ b/src/containers/AIToolkit/Assistant/CreateAssistant/CreateAssistant.tsx @@ -8,14 +8,11 @@ import { import { GET_COLLECTION } from 'graphql/queries/Collection'; import { AssistantOptions } from '../AssistantOptions/AssistantOptions'; import { useState } from 'react'; -import { FormLayout } from '../FormLayout/FormLayout'; +import { Field, FormikProvider, useFormik } from 'formik'; +import { Typography } from '@mui/material'; -const queries = { - getItemQuery: GET_COLLECTION, - createItemQuery: CREATE_COLLECTION, - updateItemQuery: UPDATE_COLLECTION, - deleteItemQuery: DELETE_COLLECTION, -}; +import styles from './CreateAssistant.module.css'; +import { Button } from 'components/UI/Form/Button/Button'; export const CreateAssistant = () => { const [name, setName] = useState(''); @@ -72,6 +69,14 @@ export const CreateAssistant = () => { fileSearch, options, }; + const FormSchema = {}; + + const formik = useFormik({ + initialValues: states, + validationSchema: FormSchema, + enableReinitialize: true, + onSubmit: (values, { setErrors }) => {}, + }); const setStates = ({ name: nameValue, prompt: promptValue, model: modelValue }: any) => { setName(nameValue); @@ -83,9 +88,30 @@ export const CreateAssistant = () => { console.log(payload); }; - const FormSchema = {}; - return ( - + +
+
+
+ {formFields.map((field: any) => ( +
+ + {field.label} + + + +
+ ))} +
+
+ + + +
+
+
+
); }; diff --git a/src/containers/AIToolkit/Assistants/Assistants.module.css b/src/containers/AIToolkit/Assistants/Assistants.module.css deleted file mode 100644 index 2981f138a..000000000 --- a/src/containers/AIToolkit/Assistants/Assistants.module.css +++ /dev/null @@ -1,69 +0,0 @@ -.AssistantContainer { - width: 100%; - height: 100vh !important; -} - -.MainContainer { - width: 100%; - height: calc(100vh - 110px); - display: flex; -} - -.LeftContainer { - height: 100%; - width: 50% !important; - border-right: 1px solid #00000029; - padding: 2rem 4rem; - background-color: #f8faf5; - position: relative; -} - -.RightContainer { - height: 100%; - width: 50% !important; - overflow-y: scroll; -} - -.Search { - width: 50%; - position: absolute; - top: 0; - margin: 1rem 0; -} - -.AssistantList { - margin-top: 2rem; - height: 100%; - display: flex; - flex-direction: column; - row-gap: 0.5rem; - overflow-y: scroll; -} - -.Assistant { - background-color: #fff; - padding: 0.8rem 1rem; - border-radius: 8px; -} - -.AssistantHeader { - width: 100%; - display: flex; - justify-content: space-between; - align-items: flex-end; -} - -.AssistantTitle { - font-size: 16px; - font-weight: 600; -} - -.AssistantDate { - font-size: 10px; - color: #0000007a; -} - -.AssistantId { - font-size: 12px; - color: #555; -} diff --git a/src/containers/AIToolkit/FormLayout/FormLayout.tsx b/src/containers/AIToolkit/FormLayout/FormLayout.tsx deleted file mode 100644 index b84dcff0b..000000000 --- a/src/containers/AIToolkit/FormLayout/FormLayout.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { Field, Form, Formik, FormikProvider, useFormik } from 'formik'; -import styles from './FormLayout.module.css'; -import { Typography } from '@mui/material'; -import { Button } from 'components/UI/Form/Button/Button'; - -interface FormLayoutProps { - initialValues: any; - validationSchema: any; - formFieldItems: any; - skipSave?: boolean; -} - -export const FormLayout = ({ - initialValues, - validationSchema, - formFieldItems, - skipSave = false, -}: FormLayoutProps) => { - const formik = useFormik({ - initialValues, - validationSchema, - enableReinitialize: true, - onSubmit: (values, { setErrors }) => {}, - }); - - return ( - -
-
-
- {formFieldItems.map((field: any) => ( -
- - {field.label} - - - -
- ))} -
-
- {!skipSave && } - - -
-
-
-
- ); -}; diff --git a/src/containers/AIToolkit/ListItems/List.module.css b/src/containers/AIToolkit/ListItems/List.module.css new file mode 100644 index 000000000..4b0fe4557 --- /dev/null +++ b/src/containers/AIToolkit/ListItems/List.module.css @@ -0,0 +1,44 @@ +.ListContainer { + margin-top: 2rem; + height: 100%; + display: flex; + flex-direction: column; + row-gap: 0.5rem; + overflow-y: scroll; +} + +.Item { + background-color: #fff; + padding: 0.8rem 1rem; + border-radius: 8px; + display: flex; + width: 100%; +} + +.Itemm { + display: flex; + flex-direction: column; + width: 100%; +} + +.Header { + width: 100%; + display: flex; + justify-content: space-between; + align-items: flex-end; +} + +.Title { + font-size: 16px; + font-weight: 600; +} + +.Date { + font-size: 10px; + color: #0000007a; +} + +.Id { + font-size: 12px; + color: #555; +} diff --git a/src/containers/AIToolkit/ListItems/List.tsx b/src/containers/AIToolkit/ListItems/List.tsx new file mode 100644 index 000000000..5fc7d2e68 --- /dev/null +++ b/src/containers/AIToolkit/ListItems/List.tsx @@ -0,0 +1,25 @@ +import styles from './List.module.css'; + +interface ListProps { + listItems: any[]; + icon?: any; +} + +export const List = ({ listItems, icon }: ListProps) => { + return ( +
+ {listItems.map((assistant) => ( +
+ {icon &&
{icon}
} +
+
+ {assistant.title} + {assistant.inserted_at} +
+ {assistant.id} +
+
+ ))} +
+ ); +}; diff --git a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx new file mode 100644 index 000000000..65e31a6d4 --- /dev/null +++ b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx @@ -0,0 +1,7 @@ +interface AssistantProps { + assistants: { id: string; inserted_at: string; name: string }[]; +} + +export const AssistantsAttached = ({ assistants }: AssistantProps) => { + return
; +}; diff --git a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx new file mode 100644 index 000000000..755aaa14d --- /dev/null +++ b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx @@ -0,0 +1,45 @@ +import { Input } from 'components/UI/Form/Input/Input'; +import { StorageDetails } from '../StorageDetails/StorageDetails'; +import { FilesAttached } from '../Files/Files'; +import { OutlinedInput } from '@mui/material'; +import { AssistantsAttached } from '../Assistants/AssistantsAttached'; + +const storageOb = { + id: 'vs_KyUlkD25kP34DIANLwxYWQK0', + size: 100, + last_active: '2021-10-01', + inserted_at: '2021-10-01', +}; + +const files = [{ id: '1', file_name: 'file1', inserted_at: '2021-10-01' }]; + +const assistants = [ + { id: 'asst_KyUlkD25kP34DIANLwxYWQK0', name: 'Vyse module', inserted_at: '2021-10-01' }, +]; + +export const CreateStorage = () => { + const fields = [ + { + component: Input, + name: 'name', + label: 'Name', + type: 'text', + }, + { + component: StorageDetails, + storage: storageOb, + }, + { + component: FilesAttached, + files: [], + }, + ]; + return ( +
+ + + + +
+ ); +}; diff --git a/src/containers/AIToolkit/Storage/Files/Files.tsx b/src/containers/AIToolkit/Storage/Files/Files.tsx new file mode 100644 index 000000000..078395608 --- /dev/null +++ b/src/containers/AIToolkit/Storage/Files/Files.tsx @@ -0,0 +1,7 @@ +interface FilesProps { + files: { id: string; file_name: string; inserted_at: string }[]; +} + +export const FilesAttached = ({ files }: FilesProps) => { + return
; +}; diff --git a/src/containers/AIToolkit/Storage/Storage.module.css b/src/containers/AIToolkit/Storage/Storage.module.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/containers/AIToolkit/Storage/Storage.tsx b/src/containers/AIToolkit/Storage/Storage.tsx deleted file mode 100644 index a1cd1ea2b..000000000 --- a/src/containers/AIToolkit/Storage/Storage.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { storageInfo } from 'common/HelpData'; - -export const VectorStorage = () => { - const storage = [ - { title: 'Untitled store', id: 'vs_KyUlkD25kP34DIANLwxYWQK0', inserted_at: '6:30 PM' }, - { - title: 'Smart store for vyse module', - id: 'vs_KyUlkD25kP34DIANLwxYWQK0', - inserted_at: '6:30 PM', - }, - { - title: 'Sova Integration module', - id: 'vs_KyUlkD25kP34DIANLwxYWQK0', - inserted_at: '6:30 PM', - }, - ]; - const states = {}; - const formFields = [{}]; - const FormSchema = {}; - - return <>; -}; - -export default VectorStorage; diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.module.css b/src/containers/AIToolkit/Storage/Storage/Storage.module.css new file mode 100644 index 000000000..30691834a --- /dev/null +++ b/src/containers/AIToolkit/Storage/Storage/Storage.module.css @@ -0,0 +1,26 @@ +.AssistantContainer { + width: 100%; + height: 100vh !important; +} + +.MainContainer { + width: 100%; + height: calc(100vh - 110px); + display: flex; +} + +.LeftContainer { + height: 100%; + width: 50% !important; + border-right: 1px solid #00000029; + padding: 2rem 4rem; + background-color: #f8faf5; + position: relative; +} + +.RightContainer { + height: 100%; + width: 50% !important; + overflow-y: scroll; + padding: 2rem 4rem; +} diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.tsx b/src/containers/AIToolkit/Storage/Storage/Storage.tsx new file mode 100644 index 000000000..2b456b685 --- /dev/null +++ b/src/containers/AIToolkit/Storage/Storage/Storage.tsx @@ -0,0 +1,55 @@ +import { storageInfo } from 'common/HelpData'; +import styles from './Storage.module.css'; +import { Heading } from 'components/UI/Heading/Heading'; +import SearchBar from 'components/UI/SearchBar/SearchBar'; +import { List } from '../../ListItems/List'; +import { CreateStorage } from '../CreateStorage/CreateStorage'; + +export const VectorStorage = () => { + const storage = [ + { title: 'Untitled store', id: 'vs_KyUlkD25kP34DIANLwxYWQK0', inserted_at: '6:30 PM' }, + { + title: 'Smart store for vyse module', + id: 'vs_KyUlkD25kP34DIANLwxYWQK0', + inserted_at: '6:30 PM', + }, + { + title: 'Sova Integration module', + id: 'vs_KyUlkD25kP34DIANLwxYWQK0', + inserted_at: '6:30 PM', + }, + ]; + const states = {}; + const formFields = [{}]; + const FormSchema = {}; + + return ( +
+ {} }} + /> +
+
+
+ {}} + onReset={() => ''} + searchMode + iconFront + /> +
+ +
+
+ +
+
+
+ ); +}; + +export default VectorStorage; diff --git a/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.module.css b/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.module.css new file mode 100644 index 000000000..3bac9530b --- /dev/null +++ b/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.module.css @@ -0,0 +1,31 @@ +.Storage { + background-color: #f8faf5; + padding: 1rem 2rem; + border-radius: 8px; + display: flex; + flex-direction: column; +} + +.Heading { + font-size: 1rem; + color: #555; +} + +.Details { + display: flex; + width: 100%; + margin-bottom: 0.5rem; +} + +.Details span { + width: 50%; +} + +.Title { + font-size: 1rem; + font-weight: 500; +} + +.Value { + font-size: 0.8rem; +} diff --git a/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx b/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx new file mode 100644 index 000000000..137dedfbc --- /dev/null +++ b/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx @@ -0,0 +1,34 @@ +import styles from './StorageDetails.module.css'; + +interface StorageProps { + storage: { id: string; size: number; last_active: string; inserted_at: string }; +} + +export const StorageDetails = ({ storage }: StorageProps) => { + return ( + <> +
Details
+
+
+ ID + {storage.id} +
+ +
+ Size + {storage.size} +
+ +
+ Last Active At + {storage.last_active} +
+ +
+ Created At + {storage.inserted_at} +
+
+ + ); +}; diff --git a/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx b/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx index 70c5841ff..f676c3c82 100644 --- a/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx +++ b/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx @@ -73,8 +73,8 @@ const InteractiveMessage = lazy(() => import('containers/InteractiveMessage/Inte const RoleList = lazy(() => import('containers/Role/RoleList/RoleList')); const Role = lazy(() => import('containers/Role/Role')); const KnowledgeBase = lazy(() => import('containers/KnowledgeBase/KnowledgeBase')); -const Assistants = lazy(() => import('containers/AIToolkit/Assistants/Assistants')); -const VectorStorage = lazy(() => import('containers/AIToolkit/Storage/Storage')); +const Assistants = lazy(() => import('containers/AIToolkit/Assistant/Assistants/Assistants')); +const VectorStorage = lazy(() => import('containers/AIToolkit/Storage/Storage/Storage')); const routeStaff = ( From 690418d2506f41d1f8e67878d8b04a5f5bcb6f80 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Tue, 1 Oct 2024 08:24:09 +0530 Subject: [PATCH 06/12] added apis --- .../Assistant/Assistants/Assistants.tsx | 11 +- .../AIToolkit/ListItems/List.module.css | 40 ++++++ src/containers/AIToolkit/ListItems/List.tsx | 119 +++++++++++++++--- .../CreateStorage/CreateStorage.module.css | 3 + .../Storage/CreateStorage/CreateStorage.tsx | 53 +++++++- .../Storage/Storage/Storage.module.css | 2 +- .../AIToolkit/Storage/Storage/Storage.tsx | 56 +++++---- .../Storage/StorageDetails/StorageDetails.tsx | 4 +- src/graphql/mutations/Storage.ts | 26 ++++ src/graphql/queries/Storage.ts | 43 +++++++ 10 files changed, 309 insertions(+), 48 deletions(-) create mode 100644 src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css create mode 100644 src/graphql/mutations/Storage.ts create mode 100644 src/graphql/queries/Storage.ts diff --git a/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx b/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx index 0caa7d772..bdbc6b6df 100644 --- a/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx +++ b/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx @@ -4,8 +4,12 @@ import styles from './Assistants.module.css'; import SearchBar from 'components/UI/SearchBar/SearchBar'; import { CreateAssistant } from '../CreateAssistant/CreateAssistant'; import { List } from '../../ListItems/List'; +import { VECTOR_STORES } from 'graphql/queries/Storage'; +import { useState } from 'react'; export const Assistants = () => { + const [updateList, setUpdateList] = useState(false); + const [currentItem, setCurrentItem] = useState(null); const assistants = [ { title: 'Untitled assistant', id: 'asst_KsGPe1fAchlx6lAggIWfPEXN', inserted_at: '6:30 PM' }, { title: 'Vyse module', id: 'asst_KsGPe1fAchlx6lAggIWfPEXN', inserted_at: '6:30 PM' }, @@ -35,7 +39,12 @@ export const Assistants = () => { iconFront />
- +
diff --git a/src/containers/AIToolkit/ListItems/List.module.css b/src/containers/AIToolkit/ListItems/List.module.css index 4b0fe4557..b35da51b0 100644 --- a/src/containers/AIToolkit/ListItems/List.module.css +++ b/src/containers/AIToolkit/ListItems/List.module.css @@ -1,4 +1,12 @@ +.Container { + height: 100%; + width: 100%; + display: flex; + flex-direction: column; +} + .ListContainer { + position: relative; margin-top: 2rem; height: 100%; display: flex; @@ -41,4 +49,36 @@ .Id { font-size: 12px; color: #555; + display: flex; + align-items: center; + column-gap: 1rem; +} + +.Id button { + padding: 0; +} + +.Id svg { + height: 1rem !important; +} + +.NoItems { + color: #555; + font-size: 1rem; + width: 100%; + text-align: center; +} + +.LoadMore { + width: fit-content; + background-color: #073f24; + padding: 4px 8px; + margin: 0 auto; + margin-top: 1rem; + border-radius: 12px 12px 0 0; + color: #edf6f2; + cursor: pointer; + font-weight: 500; + font-size: 0.875rem; + z-index: 101; } diff --git a/src/containers/AIToolkit/ListItems/List.tsx b/src/containers/AIToolkit/ListItems/List.tsx index 5fc7d2e68..af0247e2c 100644 --- a/src/containers/AIToolkit/ListItems/List.tsx +++ b/src/containers/AIToolkit/ListItems/List.tsx @@ -1,25 +1,114 @@ +import { DocumentNode, useQuery } from '@apollo/client'; import styles from './List.module.css'; +import SearchBar from 'components/UI/SearchBar/SearchBar'; +import { Loading } from 'components/UI/Layout/Loading/Loading'; +import dayjs from 'dayjs'; +import CopyIcon from 'assets/images/icons/Settings/Copy.svg?react'; +import { IconButton } from '@mui/material'; +import { copyToClipboard } from 'common/utils'; +import { useEffect, useState } from 'react'; +import { DEFAULT_ENTITY_LIMIT } from 'common/constants'; +// const DEFAULT_ENTITY_LIMIT = 2; interface ListProps { - listItems: any[]; icon?: any; + getItemsQuery: DocumentNode; + listItemName: string; + listItems?: any[]; + refreshList?: boolean; + setCurrentItem: any; } -export const List = ({ listItems, icon }: ListProps) => { +export const List = ({ + icon, + getItemsQuery, + listItemName, + refreshList, + setCurrentItem, +}: ListProps) => { + const [searchTerm, setSearchTerm] = useState(''); + + const { data, loading, fetchMore, refetch } = useQuery(getItemsQuery, { + variables: { + filter: { + name: searchTerm, + }, + opts: { + limit: DEFAULT_ENTITY_LIMIT, + order: 'DESC', + }, + }, + onCompleted: (data) => { + setCurrentItem(data[listItemName][0]?.id); + }, + }); + + const loadMoreItems = () => { + const variables = { + filter: { + name: searchTerm, + }, + opts: { + limit: 4, + order: 'DESC', + }, + }; + fetchMore({ variables }); + }; + + useEffect(() => { + refetch(); + }, [refreshList]); + return ( -
- {listItems.map((assistant) => ( -
- {icon &&
{icon}
} -
-
- {assistant.title} - {assistant.inserted_at} -
- {assistant.id} -
-
- ))} +
+
+ { + setSearchTerm(e.target.value); + }} + onReset={() => setSearchTerm('')} + searchMode + iconFront + /> +
+
+ {data && + data[listItemName] && + (data[listItemName].length === 0 ? ( +
No {listItemName} found!
+ ) : ( + data[listItemName].map((item: any) => ( +
+ {icon &&
{icon}
} +
+
+ {item.name} + + {dayjs(item.insertedAt).format('DD/MM/YY, HH:MM')} + +
+ + copyToClipboard(item.itemId)} + edge="end" + > + + + {item.itemId} + +
+
+ )) + ))} + {data && data[listItemName] && data[listItemName].length > DEFAULT_ENTITY_LIMIT - 1 ? ( + + {' '} + Load More + + ) : null} +
); }; diff --git a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css new file mode 100644 index 000000000..23ba37423 --- /dev/null +++ b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css @@ -0,0 +1,3 @@ +.EditIcon { + cursor: pointer; +} diff --git a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx index 755aaa14d..036257d19 100644 --- a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx +++ b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx @@ -1,8 +1,16 @@ import { Input } from 'components/UI/Form/Input/Input'; import { StorageDetails } from '../StorageDetails/StorageDetails'; import { FilesAttached } from '../Files/Files'; -import { OutlinedInput } from '@mui/material'; +import { InputAdornment, OutlinedInput, TextField } from '@mui/material'; import { AssistantsAttached } from '../Assistants/AssistantsAttached'; +import { useQuery } from '@apollo/client'; +import { VECTOR_STORE } from 'graphql/queries/Storage'; +import EditIcon from 'assets/images/icons/GreenEdit.svg?react'; +import styles from './CreateStorage.module.css'; +import { useState } from 'react'; +interface CreateStorageProps { + currentItem: any; +} const storageOb = { id: 'vs_KyUlkD25kP34DIANLwxYWQK0', @@ -17,7 +25,24 @@ const assistants = [ { id: 'asst_KyUlkD25kP34DIANLwxYWQK0', name: 'Vyse module', inserted_at: '2021-10-01' }, ]; -export const CreateStorage = () => { +export const CreateStorage = ({ currentItem }: CreateStorageProps) => { + const [vectorStore, setVectorStore] = useState(null); + const [name, setName] = useState(''); + const [editName, setEditName] = useState(false); + + const { data } = useQuery(VECTOR_STORE, { + variables: { + vectorStoreId: currentItem, + skip: !currentItem, + }, + onCompleted: ({ vectorStore }) => { + console.log(vectorStore?.vectorStore); + + setVectorStore(vectorStore?.vectorStore); + setName(vectorStore?.vectorStore?.name); + }, + }); + const fields = [ { component: Input, @@ -34,10 +59,30 @@ export const CreateStorage = () => { files: [], }, ]; + + if (!currentItem || data) return
Please select a vector storage
; + return (
- - + setEditName(!editName)} + > + + + } + onChange={(e) => setName(e.target.value)} + onBlur={(e) => { + console.log(e.target.value); + }} + /> +
diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.module.css b/src/containers/AIToolkit/Storage/Storage/Storage.module.css index 30691834a..b1f846e02 100644 --- a/src/containers/AIToolkit/Storage/Storage/Storage.module.css +++ b/src/containers/AIToolkit/Storage/Storage/Storage.module.css @@ -13,7 +13,7 @@ height: 100%; width: 50% !important; border-right: 1px solid #00000029; - padding: 2rem 4rem; + padding: 2rem 4rem 0 4rem; background-color: #f8faf5; position: relative; } diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.tsx b/src/containers/AIToolkit/Storage/Storage/Storage.tsx index 2b456b685..c0befd199 100644 --- a/src/containers/AIToolkit/Storage/Storage/Storage.tsx +++ b/src/containers/AIToolkit/Storage/Storage/Storage.tsx @@ -1,51 +1,55 @@ import { storageInfo } from 'common/HelpData'; import styles from './Storage.module.css'; import { Heading } from 'components/UI/Heading/Heading'; -import SearchBar from 'components/UI/SearchBar/SearchBar'; import { List } from '../../ListItems/List'; import { CreateStorage } from '../CreateStorage/CreateStorage'; +import { VECTOR_STORES } from 'graphql/queries/Storage'; +import { useMutation } from '@apollo/client'; +import { CREATE_STORAGE } from 'graphql/mutations/Storage'; +import { useState } from 'react'; export const VectorStorage = () => { - const storage = [ - { title: 'Untitled store', id: 'vs_KyUlkD25kP34DIANLwxYWQK0', inserted_at: '6:30 PM' }, - { - title: 'Smart store for vyse module', - id: 'vs_KyUlkD25kP34DIANLwxYWQK0', - inserted_at: '6:30 PM', - }, - { - title: 'Sova Integration module', - id: 'vs_KyUlkD25kP34DIANLwxYWQK0', - inserted_at: '6:30 PM', - }, - ]; + const [updateList, setUpdateList] = useState(false); + const [currentItem, setCurrentItem] = useState(null); + const states = {}; const formFields = [{}]; const FormSchema = {}; + const [createStorage] = useMutation(CREATE_STORAGE, { + variables: { + input: { + name: null, + }, + }, + onCompleted: () => { + setUpdateList(!updateList); + }, + }); + + const handleCreateStorage = () => { + createStorage(); + }; + return (
{} }} + button={{ show: true, label: 'Create Storage', action: handleCreateStorage }} />
-
- {}} - onReset={() => ''} - searchMode - iconFront - /> -
- +
- +
diff --git a/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx b/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx index 137dedfbc..c9db57256 100644 --- a/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx +++ b/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx @@ -1,10 +1,12 @@ import styles from './StorageDetails.module.css'; interface StorageProps { - storage: { id: string; size: number; last_active: string; inserted_at: string }; + storage: any; } export const StorageDetails = ({ storage }: StorageProps) => { + console.log(storage); + return ( <>
Details
diff --git a/src/graphql/mutations/Storage.ts b/src/graphql/mutations/Storage.ts new file mode 100644 index 000000000..c9c1847d0 --- /dev/null +++ b/src/graphql/mutations/Storage.ts @@ -0,0 +1,26 @@ +import { gql } from '@apollo/client'; + +export const CREATE_STORAGE = gql` + mutation CreateVectorStore($input: VectorStoreInput) { + createVectorStore(input: $input) { + vectorStore { + name + id + insertedAt + size + files { + id + name + size + } + vectorStoreId + assistants { + id + instructions + model + name + } + } + } + } +`; diff --git a/src/graphql/queries/Storage.ts b/src/graphql/queries/Storage.ts new file mode 100644 index 000000000..bb81ec7a6 --- /dev/null +++ b/src/graphql/queries/Storage.ts @@ -0,0 +1,43 @@ +import { gql } from '@apollo/client'; + +export const VECTOR_STORES = gql` + query VectorStores($filter: VectorStoreFilter, $opts: Opts) { + vectorStores(filter: $filter, opts: $opts) { + id + insertedAt + name + size + updatedAt + itemId: vectorStoreId + } + } +`; + +export const VECTOR_STORE = gql` + query VectorStore($vectorStoreId: ID!) { + vectorStore(id: $vectorStoreId) { + vectorStore { + assistants { + id + instructions + model + name + } + files { + id + name + size + } + id + insertedAt + name + size + updatedAt + vectorStoreId + } + errors { + message + } + } + } +`; From 5fc42960cda539ae82c28ab440ee370d0196f214 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Tue, 1 Oct 2024 13:32:47 +0530 Subject: [PATCH 07/12] added functionality for updating name --- src/assets/images/FileGreen.svg | 8 + .../AssistantOptions/AssistantOptions.tsx | 2 - .../Assistant/Assistants/Assistants.tsx | 5 +- .../AIToolkit/ListItems/List.module.css | 4 + src/containers/AIToolkit/ListItems/List.tsx | 15 +- .../Assistants/AssistantsAttached.module.css | 22 +++ .../Storage/Assistants/AssistantsAttached.tsx | 50 +++++- .../CreateStorage/CreateStorage.module.css | 6 + .../Storage/CreateStorage/CreateStorage.tsx | 64 ++++---- .../AIToolkit/Storage/Files/Files.module.css | 93 +++++++++++ .../AIToolkit/Storage/Files/Files.tsx | 154 +++++++++++++++++- .../Storage/Storage/Storage.module.css | 7 + .../AIToolkit/Storage/Storage/Storage.tsx | 7 +- .../Storage/StorageDetails/StorageDetails.tsx | 21 +-- src/graphql/mutations/Storage.ts | 42 +++++ src/graphql/queries/Storage.ts | 37 +++++ 16 files changed, 475 insertions(+), 62 deletions(-) create mode 100644 src/assets/images/FileGreen.svg create mode 100644 src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.module.css create mode 100644 src/containers/AIToolkit/Storage/Files/Files.module.css diff --git a/src/assets/images/FileGreen.svg b/src/assets/images/FileGreen.svg new file mode 100644 index 000000000..ea28a4e2f --- /dev/null +++ b/src/assets/images/FileGreen.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.tsx b/src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.tsx index c850397e6..3052ada83 100644 --- a/src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.tsx +++ b/src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.tsx @@ -19,7 +19,6 @@ const fileSearchInfo = export const AssistantOptions = ({ form, field, fileSearch }: AssistantOptionsProps) => { const [checked, setChecked] = useState(false); - console.log(field.value); return (
@@ -37,7 +36,6 @@ export const AssistantOptions = ({ form, field, fileSearch }: AssistantOptionsPr ...field.value, fileSearch: event.target.checked, }); - console.log(event.target.checked); }} /> } diff --git a/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx b/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx index bdbc6b6df..a936798ca 100644 --- a/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx +++ b/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx @@ -9,7 +9,8 @@ import { useState } from 'react'; export const Assistants = () => { const [updateList, setUpdateList] = useState(false); - const [currentItem, setCurrentItem] = useState(null); + const [currentId, setCurrentId] = useState(null); + const assistants = [ { title: 'Untitled assistant', id: 'asst_KsGPe1fAchlx6lAggIWfPEXN', inserted_at: '6:30 PM' }, { title: 'Vyse module', id: 'asst_KsGPe1fAchlx6lAggIWfPEXN', inserted_at: '6:30 PM' }, @@ -43,7 +44,7 @@ export const Assistants = () => { getItemsQuery={VECTOR_STORES} listItemName="assistants" refreshList={updateList} - setCurrentItem={setCurrentItem} + setCurrentId={setCurrentId} />
diff --git a/src/containers/AIToolkit/ListItems/List.module.css b/src/containers/AIToolkit/ListItems/List.module.css index b35da51b0..730c76132 100644 --- a/src/containers/AIToolkit/ListItems/List.module.css +++ b/src/containers/AIToolkit/ListItems/List.module.css @@ -29,6 +29,10 @@ width: 100%; } +.SelectedItem { + background-color: #ebf8ee; +} + .Header { width: 100%; display: flex; diff --git a/src/containers/AIToolkit/ListItems/List.tsx b/src/containers/AIToolkit/ListItems/List.tsx index af0247e2c..e8f1d5f33 100644 --- a/src/containers/AIToolkit/ListItems/List.tsx +++ b/src/containers/AIToolkit/ListItems/List.tsx @@ -14,9 +14,9 @@ interface ListProps { icon?: any; getItemsQuery: DocumentNode; listItemName: string; - listItems?: any[]; + currentId?: any; refreshList?: boolean; - setCurrentItem: any; + setCurrentId: any; } export const List = ({ @@ -24,7 +24,8 @@ export const List = ({ getItemsQuery, listItemName, refreshList, - setCurrentItem, + setCurrentId, + currentId, }: ListProps) => { const [searchTerm, setSearchTerm] = useState(''); @@ -39,7 +40,7 @@ export const List = ({ }, }, onCompleted: (data) => { - setCurrentItem(data[listItemName][0]?.id); + setCurrentId(data[listItemName][0]?.id); }, }); @@ -79,7 +80,11 @@ export const List = ({
No {listItemName} found!
) : ( data[listItemName].map((item: any) => ( -
+
setCurrentId(item.id)} + > {icon &&
{icon}
}
diff --git a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.module.css b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.module.css new file mode 100644 index 000000000..13c6e5519 --- /dev/null +++ b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.module.css @@ -0,0 +1,22 @@ +.Header { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; +} + +.Header button { + border-radius: 10px; + font-size: 1rem; + padding: 2px 8px; + display: flex; + align-items: center; + column-gap: 0.5rem; +} + +.EmptyText { + font-size: 0.8rem; + color: #2f2f2f; + width: 100%; + text-align: center; +} diff --git a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx index 65e31a6d4..cd94e3d02 100644 --- a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx +++ b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx @@ -1,7 +1,51 @@ +import { useQuery } from '@apollo/client'; +import { VECTOR_STORE_ASSISTANTS } from 'graphql/queries/Storage'; +import AddIcon from 'assets/images/AddGreenIcon.svg?react'; + +import styles from './AssistantsAttached.module.css'; +import Button from '@mui/material/Button'; +import { CircularProgress } from '@mui/material'; + interface AssistantProps { - assistants: { id: string; inserted_at: string; name: string }[]; + currentId: any; } -export const AssistantsAttached = ({ assistants }: AssistantProps) => { - return
; +export const AssistantsAttached = ({ currentId }: AssistantProps) => { + const { data, refetch, loading } = useQuery(VECTOR_STORE_ASSISTANTS, { + variables: { + vectorStoreId: currentId, + skip: !!currentId, + }, + }); + + return ( +
+
+
Used by
+ + +
+
+ {loading ? ( + + ) : ( + data?.vectorStore?.vectorStore?.assistants && + (data?.vectorStore?.vectorStore?.assistants.length === 0 ? ( +
Not used by any resources.
+ ) : ( + data?.vectorStore?.vectorStore?.assistants?.map((assistant: any) => ( +
+
+ {assistant.id} +
+
+ )) + )) + )} +
+
+ ); }; diff --git a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css index 23ba37423..fb5074dae 100644 --- a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css +++ b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css @@ -1,3 +1,9 @@ .EditIcon { cursor: pointer; } + +.Main { + display: flex; + flex-direction: column; + row-gap: 1rem; +} diff --git a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx index 036257d19..83f38f4d4 100644 --- a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx +++ b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx @@ -1,15 +1,17 @@ import { Input } from 'components/UI/Form/Input/Input'; import { StorageDetails } from '../StorageDetails/StorageDetails'; import { FilesAttached } from '../Files/Files'; -import { InputAdornment, OutlinedInput, TextField } from '@mui/material'; +import { CircularProgress, InputAdornment, OutlinedInput, TextField } from '@mui/material'; import { AssistantsAttached } from '../Assistants/AssistantsAttached'; -import { useQuery } from '@apollo/client'; +import { useMutation, useQuery } from '@apollo/client'; import { VECTOR_STORE } from 'graphql/queries/Storage'; import EditIcon from 'assets/images/icons/GreenEdit.svg?react'; import styles from './CreateStorage.module.css'; import { useState } from 'react'; +import { UPDATE_VECTORE_STORE } from 'graphql/mutations/Storage'; +import { Loading } from 'components/UI/Layout/Loading/Loading'; interface CreateStorageProps { - currentItem: any; + currentId: any; } const storageOb = { @@ -25,66 +27,64 @@ const assistants = [ { id: 'asst_KyUlkD25kP34DIANLwxYWQK0', name: 'Vyse module', inserted_at: '2021-10-01' }, ]; -export const CreateStorage = ({ currentItem }: CreateStorageProps) => { +export const CreateStorage = ({ currentId }: CreateStorageProps) => { const [vectorStore, setVectorStore] = useState(null); const [name, setName] = useState(''); const [editName, setEditName] = useState(false); - const { data } = useQuery(VECTOR_STORE, { + const { data, refetch } = useQuery(VECTOR_STORE, { variables: { - vectorStoreId: currentItem, - skip: !currentItem, + vectorStoreId: currentId, + skip: !currentId, }, onCompleted: ({ vectorStore }) => { - console.log(vectorStore?.vectorStore); - setVectorStore(vectorStore?.vectorStore); setName(vectorStore?.vectorStore?.name); }, }); - const fields = [ - { - component: Input, - name: 'name', - label: 'Name', - type: 'text', - }, - { - component: StorageDetails, - storage: storageOb, - }, - { - component: FilesAttached, - files: [], - }, - ]; + const [updateVectorStore, { loading }] = useMutation(UPDATE_VECTORE_STORE); + + const handleUpdateName = (name: string) => { + updateVectorStore({ + variables: { + updateVectorStoreId: currentId, + input: { + name, + }, + }, + onCompleted: () => { + setEditName(false); + refetch(); + }, + }); + }; - if (!currentItem || data) return
Please select a vector storage
; + if (!currentId || !data) return
Please select a vector storage
; return ( -
+
setEditName(!editName)} > - + {loading ? : } } onChange={(e) => setName(e.target.value)} onBlur={(e) => { - console.log(e.target.value); + handleUpdateName(e.target.value); }} /> - - + +
); }; diff --git a/src/containers/AIToolkit/Storage/Files/Files.module.css b/src/containers/AIToolkit/Storage/Files/Files.module.css new file mode 100644 index 000000000..d4c0ed470 --- /dev/null +++ b/src/containers/AIToolkit/Storage/Files/Files.module.css @@ -0,0 +1,93 @@ +.Container { + height: 100%; +} + +.Header { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; +} + +.Header button { + border-radius: 10px; + font-size: 1rem; + padding: 2px 8px; + display: flex; + align-items: center; + column-gap: 0.5rem; +} + +.DialogContent { + text-align: center; + max-height: 40vh; + display: flex; + flex-direction: column; +} + +.DialogContent span { + font-size: 0.8rem; + line-height: 0; + color: #555; + margin: 1rem 0; +} + +.DialogContent span a { + color: #119656; + font-weight: 600; +} + +.UploadContainer { + padding: 1rem 0; + display: flex; + align-items: flex-start; + justify-content: center; + border: 1px solid #119656; + border-style: dashed; + width: 100%; +} + +.UploadContainer input { + display: none; +} + +.HelperText { + margin: 0px; + color: #93a29b; + line-height: 1.5; + font-size: 12px; + margin-top: 7px; + padding: 0 8px; +} + +.FileList { + display: flex; + flex-direction: column; + row-gap: 0.5rem; + margin: 1rem 0; + height: 100%; + overflow-y: scroll; +} + +.File { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 0.8rem; + background-color: #ebf8ee; + padding: 0.5rem 1rem; + padding-right: 0; +} + +.File div { + display: flex; + align-items: center; + column-gap: 0.8rem; +} + +.EmptyText { + font-size: 0.8rem; + color: #2f2f2f; + width: 100%; + text-align: center; +} diff --git a/src/containers/AIToolkit/Storage/Files/Files.tsx b/src/containers/AIToolkit/Storage/Files/Files.tsx index 078395608..4f41f57e1 100644 --- a/src/containers/AIToolkit/Storage/Files/Files.tsx +++ b/src/containers/AIToolkit/Storage/Files/Files.tsx @@ -1,7 +1,155 @@ +import { useMutation, useQuery } from '@apollo/client'; +import Button from '@mui/material/Button'; +import { VECTOR_STORE_FILES } from 'graphql/queries/Storage'; +import styles from './Files.module.css'; +import { DialogBox } from 'components/UI/DialogBox/DialogBox'; +import { useState } from 'react'; +import AddIcon from 'assets/images/AddGreenIcon.svg?react'; +import UploadIcon from 'assets/images/icons/UploadIcon.svg?react'; +import DeleteIcon from 'assets/images/icons/Delete/Red.svg?react'; +import { CircularProgress, IconButton } from '@mui/material'; +import { REMOVE_FILES_FROM_STORAGE, UPLOAD_FILES_TO_STORAGE } from 'graphql/mutations/Storage'; +import FileIcon from 'assets/images/FileGreen.svg?react'; interface FilesProps { - files: { id: string; file_name: string; inserted_at: string }[]; + currentId: string; } -export const FilesAttached = ({ files }: FilesProps) => { - return
; +export const FilesAttached = ({ currentId }: FilesProps) => { + const [showUploadDialog, setShowUploadDialog] = useState(false); + const [files, setFiles] = useState([]); + + const { + data, + refetch, + loading: filesLoading, + } = useQuery(VECTOR_STORE_FILES, { + variables: { + vectorStoreId: currentId, + skip: !!currentId, + }, + }); + + const [uploadFiles, { loading }] = useMutation(UPLOAD_FILES_TO_STORAGE); + const [removeFile] = useMutation(REMOVE_FILES_FROM_STORAGE); + + const handleFileUpload = () => { + uploadFiles({ + variables: { media: files.map((file) => file.file), addVectorStoreFilesId: currentId }, + onCompleted: () => { + setFiles([]); + setShowUploadDialog(false); + refetch(); + }, + }); + }; + + const handleDeleteFile = (fileId: any) => { + removeFile({ + variables: { + fileId, + removeVectorStoreFileId: currentId, + }, + onCompleted: () => { + refetch(); + }, + }); + }; + + const handleFileChange = (event: any) => { + if (event.target.files.length === 0) return; + setFiles([ + ...files, + { + file: event.target.files[0], + id: `${event.target.files[0].name}${Date.now()}`, + }, + ]); + }; + + const handleRemoveFile = (id: any) => { + setFiles(files.filter((file) => file.id !== id)); + }; + + let dialog; + if (showUploadDialog) { + dialog = ( + setShowUploadDialog(false)} + buttonOk="Upload" + fullWidth + handleOk={handleFileUpload} + disableOk={loading} + buttonOkLoading={loading} + > +
+ + {files.length > 0 && ( +
+ {files.map((file, index) => ( +
+ {file.file.name} + handleRemoveFile(file.id)}> + + +
+ ))} +
+ )} + + Information in attached files will be available to Vector store for vyse module.{' '} + Learn More + +
+
+ ); + } + + return ( +
+
+
Files Attached
+ +
+
+ {filesLoading ? ( + + ) : ( + data?.vectorStore?.vectorStore?.files && + (data?.vectorStore?.vectorStore?.files.length === 0 ? ( +
This vector store is empty.
+ ) : ( + data?.vectorStore?.vectorStore?.files?.map((file: any) => ( +
+
+ + {file.name} +
+ handleDeleteFile(file.id)}> + + +
+ )) + )) + )} +
+ {dialog} +
+ ); }; diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.module.css b/src/containers/AIToolkit/Storage/Storage/Storage.module.css index b1f846e02..a6c882b1d 100644 --- a/src/containers/AIToolkit/Storage/Storage/Storage.module.css +++ b/src/containers/AIToolkit/Storage/Storage/Storage.module.css @@ -24,3 +24,10 @@ overflow-y: scroll; padding: 2rem 4rem; } + +.RightContainer h5 { + color: #555; + font-size: 1rem; + font-weight: 500; + margin: 0; +} diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.tsx b/src/containers/AIToolkit/Storage/Storage/Storage.tsx index c0befd199..8cb787cf5 100644 --- a/src/containers/AIToolkit/Storage/Storage/Storage.tsx +++ b/src/containers/AIToolkit/Storage/Storage/Storage.tsx @@ -10,7 +10,7 @@ import { useState } from 'react'; export const VectorStorage = () => { const [updateList, setUpdateList] = useState(false); - const [currentItem, setCurrentItem] = useState(null); + const [currentId, setCurrentId] = useState(null); const states = {}; const formFields = [{}]; @@ -45,11 +45,12 @@ export const VectorStorage = () => { getItemsQuery={VECTOR_STORES} listItemName="vectorStores" refreshList={updateList} - setCurrentItem={setCurrentItem} + setCurrentId={setCurrentId} + currentId={currentId} />
- +
diff --git a/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx b/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx index c9db57256..5c4ca68c8 100644 --- a/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx +++ b/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx @@ -1,36 +1,33 @@ +import dayjs from 'dayjs'; import styles from './StorageDetails.module.css'; +import { SHORT_DATE_TIME_FORMAT } from 'common/constants'; interface StorageProps { storage: any; } export const StorageDetails = ({ storage }: StorageProps) => { - console.log(storage); - return ( - <> +
Details
ID - {storage.id} + {storage?.vectorStoreId}
Size - {storage.size} -
- -
- Last Active At - {storage.last_active} + {storage?.size}
Created At - {storage.inserted_at} + + {dayjs(storage?.insertedAt).format(SHORT_DATE_TIME_FORMAT)} +
- +
); }; diff --git a/src/graphql/mutations/Storage.ts b/src/graphql/mutations/Storage.ts index c9c1847d0..51316bd94 100644 --- a/src/graphql/mutations/Storage.ts +++ b/src/graphql/mutations/Storage.ts @@ -24,3 +24,45 @@ export const CREATE_STORAGE = gql` } } `; + +export const UPDATE_VECTORE_STORE = gql` + mutation UpdateVectorStore($updateVectorStoreId: ID!, $input: VectorStoreInput!) { + updateVectorStore(id: $updateVectorStoreId, input: $input) { + vectorStore { + id + name + } + } + } +`; + +export const UPLOAD_FILES_TO_STORAGE = gql` + mutation AddVectorStoreFiles($addVectorStoreFilesId: ID!, $media: [Upload!]!) { + addVectorStoreFiles(id: $addVectorStoreFilesId, media: $media) { + vectorStore { + id + files { + id + name + size + } + } + errors { + message + } + } + } +`; + +export const REMOVE_FILES_FROM_STORAGE = gql` + mutation RemoveVectorStoreFile($fileId: String!, $removeVectorStoreFileId: ID!) { + removeVectorStoreFile(fileId: $fileId, id: $removeVectorStoreFileId) { + errors { + message + } + vectorStore { + id + } + } + } +`; diff --git a/src/graphql/queries/Storage.ts b/src/graphql/queries/Storage.ts index bb81ec7a6..512eb99c4 100644 --- a/src/graphql/queries/Storage.ts +++ b/src/graphql/queries/Storage.ts @@ -41,3 +41,40 @@ export const VECTOR_STORE = gql` } } `; + +export const VECTOR_STORE_FILES = gql` + query getVectorStoreFiles($vectorStoreId: ID!) { + vectorStore(id: $vectorStoreId) { + vectorStore { + id + name + files { + id + name + size + } + } + errors { + message + } + } + } +`; + +export const VECTOR_STORE_ASSISTANTS = gql` + query getVectorStoreAssistants($vectorStoreId: ID!) { + vectorStore(id: $vectorStoreId) { + vectorStore { + assistants { + id + instructions + model + name + } + } + errors { + message + } + } + } +`; From b86b4910dbdec3d8b3201328fe59e86b685102e1 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Thu, 3 Oct 2024 13:28:33 +0530 Subject: [PATCH 08/12] refactoring and added test cases --- .../AIToolkit/ListItems/List.module.css | 5 + src/containers/AIToolkit/ListItems/List.tsx | 46 +++- .../Storage/Assistants/AssistantsAttached.tsx | 16 +- .../Storage/CreateStorage/CreateStorage.tsx | 65 +++-- .../AIToolkit/Storage/Files/Files.module.css | 2 +- .../AIToolkit/Storage/Files/Files.tsx | 46 ++-- .../Storage/Storage/Storage.module.css | 1 + .../Storage/Storage/Storage.test.tsx | 144 +++++++++++ .../AIToolkit/Storage/Storage/Storage.tsx | 27 +- .../Storage/StorageDetails/StorageDetails.tsx | 4 +- src/mocks/Storage.ts | 241 ++++++++++++++++++ 11 files changed, 519 insertions(+), 78 deletions(-) create mode 100644 src/containers/AIToolkit/Storage/Storage/Storage.test.tsx create mode 100644 src/mocks/Storage.ts diff --git a/src/containers/AIToolkit/ListItems/List.module.css b/src/containers/AIToolkit/ListItems/List.module.css index 730c76132..09bc476fa 100644 --- a/src/containers/AIToolkit/ListItems/List.module.css +++ b/src/containers/AIToolkit/ListItems/List.module.css @@ -21,6 +21,11 @@ border-radius: 8px; display: flex; width: 100%; + cursor: pointer; +} + +.Item:hover { + background-color: #ebf8ee; } .Itemm { diff --git a/src/containers/AIToolkit/ListItems/List.tsx b/src/containers/AIToolkit/ListItems/List.tsx index e8f1d5f33..72c966fbe 100644 --- a/src/containers/AIToolkit/ListItems/List.tsx +++ b/src/containers/AIToolkit/ListItems/List.tsx @@ -1,15 +1,15 @@ import { DocumentNode, useQuery } from '@apollo/client'; -import styles from './List.module.css'; -import SearchBar from 'components/UI/SearchBar/SearchBar'; -import { Loading } from 'components/UI/Layout/Loading/Loading'; +import { IconButton } from '@mui/material'; import dayjs from 'dayjs'; +import { useEffect, useState } from 'react'; + import CopyIcon from 'assets/images/icons/Settings/Copy.svg?react'; -import { IconButton } from '@mui/material'; +import { DEFAULT_ENTITY_LIMIT, DEFAULT_MESSAGE_LOADMORE_LIMIT } from 'common/constants'; import { copyToClipboard } from 'common/utils'; -import { useEffect, useState } from 'react'; -import { DEFAULT_ENTITY_LIMIT } from 'common/constants'; +import SearchBar from 'components/UI/SearchBar/SearchBar'; + +import styles from './List.module.css'; -// const DEFAULT_ENTITY_LIMIT = 2; interface ListProps { icon?: any; getItemsQuery: DocumentNode; @@ -28,8 +28,9 @@ export const List = ({ currentId, }: ListProps) => { const [searchTerm, setSearchTerm] = useState(''); + const [showLoadMore, setLoadMore] = useState(false); - const { data, loading, fetchMore, refetch } = useQuery(getItemsQuery, { + const { data, loading, refetch, fetchMore } = useQuery(getItemsQuery, { variables: { filter: { name: searchTerm, @@ -41,6 +42,9 @@ export const List = ({ }, onCompleted: (data) => { setCurrentId(data[listItemName][0]?.id); + if (data[listItemName].length > DEFAULT_ENTITY_LIMIT - 1) { + setLoadMore(true); + } }, }); @@ -50,11 +54,29 @@ export const List = ({ name: searchTerm, }, opts: { - limit: 4, + limit: DEFAULT_MESSAGE_LOADMORE_LIMIT, + offset: data[listItemName].length, order: 'DESC', }, }; - fetchMore({ variables }); + + fetchMore({ + variables, + updateQuery: (prev, { fetchMoreResult }) => { + if (fetchMoreResult[listItemName].length === 0) setLoadMore(false); + + if (!fetchMoreResult) return prev; // If there's no new data, return the previous data + + // Merge the new items with the existing items + const updatedItems = [...prev[listItemName], ...fetchMoreResult[listItemName]]; + + // Return the updated data in the same shape as the original data + return { + ...prev, + [listItemName]: updatedItems, + }; + }, + }); }; useEffect(() => { @@ -84,6 +106,7 @@ export const List = ({ key={item.id} className={`${styles.Item} ${currentId === item.id ? styles.SelectedItem : ''}`} onClick={() => setCurrentId(item.id)} + data-testid="listItem" > {icon &&
{icon}
}
@@ -107,9 +130,8 @@ export const List = ({
)) ))} - {data && data[listItemName] && data[listItemName].length > DEFAULT_ENTITY_LIMIT - 1 ? ( + {showLoadMore ? ( - {' '} Load More ) : null} diff --git a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx index cd94e3d02..b64d63030 100644 --- a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx +++ b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx @@ -1,20 +1,20 @@ import { useQuery } from '@apollo/client'; -import { VECTOR_STORE_ASSISTANTS } from 'graphql/queries/Storage'; +import Button from '@mui/material/Button'; +import { CircularProgress } from '@mui/material'; + import AddIcon from 'assets/images/AddGreenIcon.svg?react'; +import { VECTOR_STORE_ASSISTANTS } from 'graphql/queries/Storage'; import styles from './AssistantsAttached.module.css'; -import Button from '@mui/material/Button'; -import { CircularProgress } from '@mui/material'; interface AssistantProps { - currentId: any; + vectorStoreId: any; } -export const AssistantsAttached = ({ currentId }: AssistantProps) => { - const { data, refetch, loading } = useQuery(VECTOR_STORE_ASSISTANTS, { +export const AssistantsAttached = ({ vectorStoreId }: AssistantProps) => { + const { data, loading } = useQuery(VECTOR_STORE_ASSISTANTS, { variables: { - vectorStoreId: currentId, - skip: !!currentId, + vectorStoreId: vectorStoreId, }, }); diff --git a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx index 83f38f4d4..116977ce9 100644 --- a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx +++ b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx @@ -1,17 +1,20 @@ -import { Input } from 'components/UI/Form/Input/Input'; -import { StorageDetails } from '../StorageDetails/StorageDetails'; -import { FilesAttached } from '../Files/Files'; -import { CircularProgress, InputAdornment, OutlinedInput, TextField } from '@mui/material'; -import { AssistantsAttached } from '../Assistants/AssistantsAttached'; -import { useMutation, useQuery } from '@apollo/client'; -import { VECTOR_STORE } from 'graphql/queries/Storage'; +import { useLazyQuery, useMutation } from '@apollo/client'; +import { CircularProgress, InputAdornment, OutlinedInput } from '@mui/material'; +import { useEffect, useState } from 'react'; + import EditIcon from 'assets/images/icons/GreenEdit.svg?react'; -import styles from './CreateStorage.module.css'; -import { useState } from 'react'; import { UPDATE_VECTORE_STORE } from 'graphql/mutations/Storage'; import { Loading } from 'components/UI/Layout/Loading/Loading'; +import { VECTOR_STORE } from 'graphql/queries/Storage'; + +import { AssistantsAttached } from '../Assistants/AssistantsAttached'; +import { FilesAttached } from '../Files/Files'; +import { StorageDetails } from '../StorageDetails/StorageDetails'; + +import styles from './CreateStorage.module.css'; + interface CreateStorageProps { - currentId: any; + vectorStoreId: any; } const storageOb = { @@ -27,28 +30,30 @@ const assistants = [ { id: 'asst_KyUlkD25kP34DIANLwxYWQK0', name: 'Vyse module', inserted_at: '2021-10-01' }, ]; -export const CreateStorage = ({ currentId }: CreateStorageProps) => { +export const CreateStorage = ({ vectorStoreId }: CreateStorageProps) => { const [vectorStore, setVectorStore] = useState(null); const [name, setName] = useState(''); const [editName, setEditName] = useState(false); - const { data, refetch } = useQuery(VECTOR_STORE, { - variables: { - vectorStoreId: currentId, - skip: !currentId, - }, - onCompleted: ({ vectorStore }) => { - setVectorStore(vectorStore?.vectorStore); - setName(vectorStore?.vectorStore?.name); - }, - }); + const [getVectorStore, { data, refetch, loading: vectorStoresLoading }] = useLazyQuery( + VECTOR_STORE, + { + variables: { + vectorStoreId: vectorStoreId, + }, + onCompleted: ({ vectorStore }) => { + setVectorStore(vectorStore?.vectorStore); + setName(vectorStore?.vectorStore?.name); + }, + } + ); const [updateVectorStore, { loading }] = useMutation(UPDATE_VECTORE_STORE); const handleUpdateName = (name: string) => { updateVectorStore({ variables: { - updateVectorStoreId: currentId, + updateVectorStoreId: vectorStoreId, input: { name, }, @@ -60,11 +65,20 @@ export const CreateStorage = ({ currentId }: CreateStorageProps) => { }); }; - if (!currentId || !data) return
Please select a vector storage
; + useEffect(() => { + if (vectorStoreId) { + getVectorStore(); + } + }, [vectorStoreId]); + + if (vectorStoresLoading) return ; + + if (!vectorStoreId || !data) return
Please select a vector storage
; return (
{ className={styles.EditIcon} position="end" onClick={() => setEditName(!editName)} + data-testid="editIcon" > {loading ? : } @@ -83,8 +98,8 @@ export const CreateStorage = ({ currentId }: CreateStorageProps) => { }} /> - - + +
); }; diff --git a/src/containers/AIToolkit/Storage/Files/Files.module.css b/src/containers/AIToolkit/Storage/Files/Files.module.css index d4c0ed470..32c1b6ebc 100644 --- a/src/containers/AIToolkit/Storage/Files/Files.module.css +++ b/src/containers/AIToolkit/Storage/Files/Files.module.css @@ -1,5 +1,5 @@ .Container { - height: 100%; + height: 60%; } .Header { diff --git a/src/containers/AIToolkit/Storage/Files/Files.tsx b/src/containers/AIToolkit/Storage/Files/Files.tsx index 4f41f57e1..1812bcce2 100644 --- a/src/containers/AIToolkit/Storage/Files/Files.tsx +++ b/src/containers/AIToolkit/Storage/Files/Files.tsx @@ -1,20 +1,23 @@ import { useMutation, useQuery } from '@apollo/client'; +import { CircularProgress, IconButton } from '@mui/material'; import Button from '@mui/material/Button'; -import { VECTOR_STORE_FILES } from 'graphql/queries/Storage'; -import styles from './Files.module.css'; -import { DialogBox } from 'components/UI/DialogBox/DialogBox'; import { useState } from 'react'; + import AddIcon from 'assets/images/AddGreenIcon.svg?react'; -import UploadIcon from 'assets/images/icons/UploadIcon.svg?react'; import DeleteIcon from 'assets/images/icons/Delete/Red.svg?react'; -import { CircularProgress, IconButton } from '@mui/material'; -import { REMOVE_FILES_FROM_STORAGE, UPLOAD_FILES_TO_STORAGE } from 'graphql/mutations/Storage'; import FileIcon from 'assets/images/FileGreen.svg?react'; +import UploadIcon from 'assets/images/icons/UploadIcon.svg?react'; +import { DialogBox } from 'components/UI/DialogBox/DialogBox'; +import { REMOVE_FILES_FROM_STORAGE, UPLOAD_FILES_TO_STORAGE } from 'graphql/mutations/Storage'; +import { VECTOR_STORE_FILES } from 'graphql/queries/Storage'; + +import styles from './Files.module.css'; + interface FilesProps { - currentId: string; + vectorStoreId: string; } -export const FilesAttached = ({ currentId }: FilesProps) => { +export const FilesAttached = ({ vectorStoreId }: FilesProps) => { const [showUploadDialog, setShowUploadDialog] = useState(false); const [files, setFiles] = useState([]); @@ -24,8 +27,7 @@ export const FilesAttached = ({ currentId }: FilesProps) => { loading: filesLoading, } = useQuery(VECTOR_STORE_FILES, { variables: { - vectorStoreId: currentId, - skip: !!currentId, + vectorStoreId: vectorStoreId, }, }); @@ -34,7 +36,7 @@ export const FilesAttached = ({ currentId }: FilesProps) => { const handleFileUpload = () => { uploadFiles({ - variables: { media: files.map((file) => file.file), addVectorStoreFilesId: currentId }, + variables: { media: files.map((file) => file.file), addVectorStoreFilesId: vectorStoreId }, onCompleted: () => { setFiles([]); setShowUploadDialog(false); @@ -47,7 +49,7 @@ export const FilesAttached = ({ currentId }: FilesProps) => { removeFile({ variables: { fileId, - removeVectorStoreFileId: currentId, + removeVectorStoreFileId: vectorStoreId, }, onCompleted: () => { refetch(); @@ -94,15 +96,20 @@ export const FilesAttached = ({ currentId }: FilesProps) => {
Upload File - +
{files.length > 0 && (
{files.map((file, index) => ( -
+
{file.file.name} - handleRemoveFile(file.id)}> + handleRemoveFile(file.id)}>
@@ -122,7 +129,7 @@ export const FilesAttached = ({ currentId }: FilesProps) => {
Files Attached
- @@ -136,12 +143,15 @@ export const FilesAttached = ({ currentId }: FilesProps) => {
This vector store is empty.
) : ( data?.vectorStore?.vectorStore?.files?.map((file: any) => ( -
+
{file.name}
- handleDeleteFile(file.id)}> + handleDeleteFile(file.id)} + >
diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.module.css b/src/containers/AIToolkit/Storage/Storage/Storage.module.css index a6c882b1d..7025df6f4 100644 --- a/src/containers/AIToolkit/Storage/Storage/Storage.module.css +++ b/src/containers/AIToolkit/Storage/Storage/Storage.module.css @@ -30,4 +30,5 @@ font-size: 1rem; font-weight: 500; margin: 0; + margin-bottom: 0.5rem; } diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx b/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx new file mode 100644 index 000000000..6b2ee7409 --- /dev/null +++ b/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx @@ -0,0 +1,144 @@ +import { MockedProvider } from '@apollo/client/testing'; +import { MemoryRouter } from 'react-router'; +import VectorStorage from './Storage'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { VECTOR_STORE_MOCKS } from 'mocks/Storage'; +import * as Notification from 'common/notification'; + +const wrapper = ( + + + + + +); + +const notificationSpy = vi.spyOn(Notification, 'setNotification'); + +test('it should render Vector storage component', async () => { + render(wrapper); + + await waitFor(() => { + expect(screen.getByText('Vector Storage')).toBeInTheDocument(); + }); + + await waitFor(() => { + expect(screen.getAllByRole('textbox')[1]).toHaveValue('Vector store 1'); + }); +}); + +test('it should create a Vector storage', async () => { + render(wrapper); + + await waitFor(() => { + expect(screen.getByText('Vector Storage')).toBeInTheDocument(); + }); + + await waitFor(() => { + expect(screen.getAllByRole('textbox')[1]).toHaveValue('Vector store 1'); + }); + + fireEvent.click(screen.getByText('Create Storage')); + + await waitFor(() => { + expect(notificationSpy).toHaveBeenCalledWith('Vector store created successfully!'); + }); +}); + +test('it should switch between vector stores', async () => { + render(wrapper); + + await waitFor(() => { + expect(screen.getByText('Vector Storage')).toBeInTheDocument(); + }); + + await waitFor(() => { + expect(screen.getByText('Vector store 1')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getAllByTestId('listItem')[1]); + + await waitFor(() => { + expect(screen.getAllByRole('textbox')[1]).toHaveValue('vector_store_4'); + }); +}); + +test('it should search for vector stores', async () => { + render(wrapper); + + await waitFor(() => { + expect(screen.getByText('Vector Storage')).toBeInTheDocument(); + }); + + fireEvent.change(screen.getByRole('textbox'), { target: { value: 'vector_store_4' } }); + + await waitFor(() => { + expect(screen.getAllByTestId('listItem')).toHaveLength(1); + expect(screen.getByText('vector_store_4')).toBeInTheDocument(); + }); +}); + +test('should update name', async () => { + render(wrapper); + + await waitFor(() => { + expect(screen.getByText('Vector Storage')).toBeInTheDocument(); + }); + + await waitFor(() => { + expect(screen.getAllByRole('textbox')[1]).toHaveValue('Vector store 1'); + }); + + fireEvent.click(screen.getByTestId('editIcon')); + + fireEvent.change(screen.getAllByRole('textbox')[1], { target: { value: 'updated name' } }); + + fireEvent.blur(screen.getAllByRole('textbox')[1]); + + await waitFor(() => { + expect(screen.getAllByRole('textbox')[1]).toHaveValue('updated name'); + }); +}); + +test('should add and remove files', async () => { + render(wrapper); + + await waitFor(() => { + expect(screen.getByText('Vector Storage')).toBeInTheDocument(); + }); + + await waitFor(() => { + expect(screen.getAllByRole('textbox')[1]).toHaveValue('Vector store 1'); + }); + + fireEvent.click(screen.getByTestId('addFiles')); + + //testing if it closes the dialog box + fireEvent.click(screen.getByTestId('cancel-button')); + fireEvent.click(screen.getByTestId('addFiles')); + + await waitFor(() => { + expect(screen.getByTestId('dialogBox')).toBeInTheDocument(); + }); + + const mockFile = new File(['file content'], 'testFile.txt', { type: 'text/plain' }); + + const fileInput = screen.getByTestId('uploadFile'); + fireEvent.change(fileInput, { target: { files: [mockFile] } }); + fireEvent.change(fileInput, { target: { files: [mockFile] } }); + fireEvent.change(fileInput, { target: { files: [mockFile] } }); + + await waitFor(() => { + expect(screen.getAllByTestId('fileItem')).toHaveLength(3); + }); + + fireEvent.click(screen.getAllByTestId('deleteFile')[1]); + + fireEvent.click(screen.getByTestId('ok-button')); + + await waitFor(() => { + expect(screen.getAllByTestId('vectorFile')).toHaveLength(2); + }); + + fireEvent.click(screen.getAllByTestId('removeVectorFile')[1]); +}); diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.tsx b/src/containers/AIToolkit/Storage/Storage/Storage.tsx index 8cb787cf5..6eb5aee2e 100644 --- a/src/containers/AIToolkit/Storage/Storage/Storage.tsx +++ b/src/containers/AIToolkit/Storage/Storage/Storage.tsx @@ -1,20 +1,20 @@ +import { useMutation } from '@apollo/client'; +import { useState } from 'react'; + import { storageInfo } from 'common/HelpData'; -import styles from './Storage.module.css'; +import { setNotification } from 'common/notification'; import { Heading } from 'components/UI/Heading/Heading'; -import { List } from '../../ListItems/List'; -import { CreateStorage } from '../CreateStorage/CreateStorage'; import { VECTOR_STORES } from 'graphql/queries/Storage'; -import { useMutation } from '@apollo/client'; import { CREATE_STORAGE } from 'graphql/mutations/Storage'; -import { useState } from 'react'; + +import { List } from '../../ListItems/List'; +import { CreateStorage } from '../CreateStorage/CreateStorage'; + +import styles from './Storage.module.css'; export const VectorStorage = () => { const [updateList, setUpdateList] = useState(false); - const [currentId, setCurrentId] = useState(null); - - const states = {}; - const formFields = [{}]; - const FormSchema = {}; + const [vectorStoreId, setVectorStoreId] = useState(null); const [createStorage] = useMutation(CREATE_STORAGE, { variables: { @@ -23,6 +23,7 @@ export const VectorStorage = () => { }, }, onCompleted: () => { + setNotification('Vector store created successfully!'); setUpdateList(!updateList); }, }); @@ -45,12 +46,12 @@ export const VectorStorage = () => { getItemsQuery={VECTOR_STORES} listItemName="vectorStores" refreshList={updateList} - setCurrentId={setCurrentId} - currentId={currentId} + setCurrentId={setVectorStoreId} + currentId={vectorStoreId} />
- +
diff --git a/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx b/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx index 5c4ca68c8..24a510dcf 100644 --- a/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx +++ b/src/containers/AIToolkit/Storage/StorageDetails/StorageDetails.tsx @@ -1,7 +1,9 @@ import dayjs from 'dayjs'; -import styles from './StorageDetails.module.css'; + import { SHORT_DATE_TIME_FORMAT } from 'common/constants'; +import styles from './StorageDetails.module.css'; + interface StorageProps { storage: any; } diff --git a/src/mocks/Storage.ts b/src/mocks/Storage.ts new file mode 100644 index 000000000..328fa70dc --- /dev/null +++ b/src/mocks/Storage.ts @@ -0,0 +1,241 @@ +import { + CREATE_STORAGE, + REMOVE_FILES_FROM_STORAGE, + UPDATE_VECTORE_STORE, + UPLOAD_FILES_TO_STORAGE, +} from 'graphql/mutations/Storage'; +import { + VECTOR_STORE, + VECTOR_STORES, + VECTOR_STORE_ASSISTANTS, + VECTOR_STORE_FILES, +} from 'graphql/queries/Storage'; + +const vectorStores = [ + { + id: '5', + insertedAt: '2024-09-30T09:18:44Z', + itemId: 'vs_HFGiyvbrl4c4Xx32ijAXhzd7', + name: 'Vector store 1', + size: '0 B', + updatedAt: '2024-09-30T09:18:44Z', + }, + { + id: '4', + insertedAt: '2024-09-30T09:18:41Z', + itemId: 'vs_hj6RA1dugBnhS8aT8MQtKnh2', + name: 'vector_store_4', + size: '0 B', + updatedAt: '2024-09-30T09:18:41Z', + }, + { + id: '3', + insertedAt: '2024-09-30T09:18:36Z', + itemId: 'vs_zcpHvcavkechKSUb3Iph70La', + name: 'vector_store_3', + size: '6.79 MB', + updatedAt: '2024-10-01T07:11:39Z', + }, + { + id: '2', + insertedAt: '2024-09-30T09:18:31Z', + itemId: 'vs_W7Rqngj87FuXoUP6Sjd5MSjs', + name: 'vector_store_2', + size: '8.67 MB', + updatedAt: '2024-10-01T07:15:52Z', + }, + { + id: '1', + insertedAt: '2024-09-30T08:35:49Z', + itemId: 'vs_gWTjKCBJfGfWxHtsfi2uGdCA', + name: 'vector_store_1', + size: '0 B', + updatedAt: '2024-09-30T08:35:49Z', + }, +]; + +export const vectorStorageMocks = (data: any[] = vectorStores, searchTerm: string = '') => ({ + request: { + query: VECTOR_STORES, + variables: { + filter: { name: searchTerm }, + opts: { + limit: 25, + order: 'DESC', + }, + }, + }, + result: { + data: { + vectorStores: data, + }, + }, +}); + +const getVectorStoreQuery = (vectorStoreId: string, name: string) => ({ + request: { + query: VECTOR_STORE, + variables: { vectorStoreId }, + }, + result: { + data: { + vectorStore: { + errors: null, + vectorStore: { + id: vectorStoreId, + name, + assistants: [], + files: [], + insertedAt: '2024-10-01T07:00:12Z', + size: '0 B', + updatedAt: '2024-10-01T07:56:19Z', + vectorStoreId: 'vs_6RJD1TRI6Ny9P8YA7FhR9b4w', + }, + }, + }, + }, +}); + +const createVectorStore = { + request: { + query: CREATE_STORAGE, + variables: { + input: { + name: null, + }, + }, + }, + result: { + data: { + createVectorStore: { + vectorStore: { + assistants: [], + files: [], + id: '11', + insertedAt: '2024-10-03T07:44:25Z', + name: 'vectorStore1-035b5b90', + size: '0 B', + vectorStoreId: 'vs_LUz7uG6KuWVXxoB9IzN5VdI5', + }, + }, + }, + }, +}; + +const updateNameQuery = { + request: { + query: UPDATE_VECTORE_STORE, + variables: { + updateVectorStoreId: '5', + input: { + name: 'updated name', + }, + }, + }, + result: { + data: { + updateVectorStore: { + vectorStore: { + id: '5', + name: 'updated name', + }, + }, + }, + }, +}; + +const getVectorStorFiles = { + request: { + query: VECTOR_STORE_FILES, + variables: { vectorStoreId: '5' }, + }, + result: { + data: { + vectorStore: { + errors: null, + vectorStore: { + __typename: 'VectorStore', + files: [ + { id: '1', name: 'file1', size: '0 B' }, + { id: '2', name: 'file2', size: '0 B' }, + ], + id: '10', + name: 'Vector store for testing sss', + }, + }, + }, + }, +}; + +const getVectorStoreAssistants = { + request: { + query: VECTOR_STORE_ASSISTANTS, + variables: { vectorStoreId: '5' }, + }, + result: { + data: { + vectorStore: { + errors: null, + vectorStore: { + __typename: 'VectorStore', + assistants: [], + id: '10', + name: 'Vector store for testing sss', + }, + }, + }, + }, +}; + +const addFilesToVectorStore = { + request: { + query: UPLOAD_FILES_TO_STORAGE, + }, + result: { + data: { + addVectorStoreFiles: { + errors: null, + vectorStore: { + __typename: 'VectorStore', + files: [{ id: '1', name: 'file1', size: '0 B' }], + id: '10', + }, + }, + }, + }, + variableMatcher: (variables: any) => true, +}; + +const removeFilesFromVectorStore = { + request: { + query: REMOVE_FILES_FROM_STORAGE, + variables: { fileId: '2', removeVectorStoreFileId: '5' }, + }, + result: { + data: { + removeVectorStoreFile: { + errors: null, + vectorStore: { + id: '5', + }, + }, + }, + }, +}; + +export const VECTOR_STORE_MOCKS = [ + vectorStorageMocks(), + vectorStorageMocks(), + getVectorStoreQuery('5', 'Vector store 1'), + getVectorStoreQuery('5', 'Vector store 1'), + getVectorStoreQuery('5', 'Vector store 1'), + getVectorStoreQuery('4', 'vector_store_4'), + updateNameQuery, + vectorStorageMocks(vectorStores.slice(1, 2), 'vector_store_4'), + addFilesToVectorStore, + getVectorStorFiles, + getVectorStoreAssistants, + removeFilesFromVectorStore, + getVectorStorFiles, + createVectorStore, +]; From b22f9dc1d55ce6ec879b8872f462d36baf6038c6 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Thu, 3 Oct 2024 14:57:28 +0530 Subject: [PATCH 09/12] functionality to create assistant --- .../AssistantOptions/AssistantOptions.tsx | 13 ++++- .../Assistant/Assistants/Assistants.tsx | 23 +------- .../CreateAssistant/CreateAssistant.tsx | 16 ------ src/containers/AIToolkit/ListItems/List.tsx | 6 +- .../Assistants/AssistantsAttached.module.css | 57 +++++++++++++++++++ .../Storage/Assistants/AssistantsAttached.tsx | 53 +++++++++++++---- .../CreateStorage/CreateStorage.module.css | 1 + .../Storage/CreateStorage/CreateStorage.tsx | 13 ----- .../AIToolkit/Storage/Files/Files.module.css | 4 +- .../AIToolkit/Storage/Files/Files.tsx | 7 ++- src/graphql/mutations/Assistants.ts | 12 ++++ src/graphql/queries/Storage.ts | 5 +- 12 files changed, 136 insertions(+), 74 deletions(-) create mode 100644 src/graphql/mutations/Assistants.ts diff --git a/src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.tsx b/src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.tsx index 3052ada83..99c3a4678 100644 --- a/src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.tsx +++ b/src/containers/AIToolkit/Assistant/AssistantOptions/AssistantOptions.tsx @@ -1,8 +1,6 @@ import { FormControlLabel, Slider, Switch, Typography } from '@mui/material'; import { useState } from 'react'; import styles from './AssistantOptions.module.css'; -import InfoIcon from 'assets/images/icons/Info.svg?react'; -import Tooltip from 'components/UI/Tooltip/Tooltip'; import HelpIcon from 'components/UI/HelpIcon/HelpIcon'; interface AssistantOptionsProps { @@ -39,7 +37,16 @@ export const AssistantOptions = ({ form, field, fileSearch }: AssistantOptionsPr }} /> } - label="File Search" + label={ + <> + File Search{' '} + + + } /> diff --git a/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx b/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx index a936798ca..38f6209da 100644 --- a/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx +++ b/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx @@ -9,17 +9,7 @@ import { useState } from 'react'; export const Assistants = () => { const [updateList, setUpdateList] = useState(false); - const [currentId, setCurrentId] = useState(null); - - const assistants = [ - { title: 'Untitled assistant', id: 'asst_KsGPe1fAchlx6lAggIWfPEXN', inserted_at: '6:30 PM' }, - { title: 'Vyse module', id: 'asst_KsGPe1fAchlx6lAggIWfPEXN', inserted_at: '6:30 PM' }, - { - title: 'Sova integration module', - id: 'asst_KsGPe1fAchlx6lAggIWfPEXN', - inserted_at: '6:30 PM', - }, - ]; + const [assistantId, setAssistantId] = useState(null); return (
@@ -31,20 +21,11 @@ export const Assistants = () => { />
-
- {}} - onReset={() => ''} - searchMode - iconFront - /> -
diff --git a/src/containers/AIToolkit/Assistant/CreateAssistant/CreateAssistant.tsx b/src/containers/AIToolkit/Assistant/CreateAssistant/CreateAssistant.tsx index c93b691e8..4172850e0 100644 --- a/src/containers/AIToolkit/Assistant/CreateAssistant/CreateAssistant.tsx +++ b/src/containers/AIToolkit/Assistant/CreateAssistant/CreateAssistant.tsx @@ -1,11 +1,5 @@ import { AutoComplete } from 'components/UI/Form/AutoComplete/AutoComplete'; import { Input } from 'components/UI/Form/Input/Input'; -import { - CREATE_COLLECTION, - DELETE_COLLECTION, - UPDATE_COLLECTION, -} from 'graphql/mutations/Collection'; -import { GET_COLLECTION } from 'graphql/queries/Collection'; import { AssistantOptions } from '../AssistantOptions/AssistantOptions'; import { useState } from 'react'; import { Field, FormikProvider, useFormik } from 'formik'; @@ -78,16 +72,6 @@ export const CreateAssistant = () => { onSubmit: (values, { setErrors }) => {}, }); - const setStates = ({ name: nameValue, prompt: promptValue, model: modelValue }: any) => { - setName(nameValue); - setModel(modelValue); - setPrompt(promptValue); - }; - - const setPayload = (payload: any) => { - console.log(payload); - }; - return (
diff --git a/src/containers/AIToolkit/ListItems/List.tsx b/src/containers/AIToolkit/ListItems/List.tsx index 72c966fbe..1fb7b9dea 100644 --- a/src/containers/AIToolkit/ListItems/List.tsx +++ b/src/containers/AIToolkit/ListItems/List.tsx @@ -30,7 +30,7 @@ export const List = ({ const [searchTerm, setSearchTerm] = useState(''); const [showLoadMore, setLoadMore] = useState(false); - const { data, loading, refetch, fetchMore } = useQuery(getItemsQuery, { + const { data, refetch, fetchMore } = useQuery(getItemsQuery, { variables: { filter: { name: searchTerm, @@ -63,10 +63,10 @@ export const List = ({ fetchMore({ variables, updateQuery: (prev, { fetchMoreResult }) => { - if (fetchMoreResult[listItemName].length === 0) setLoadMore(false); - if (!fetchMoreResult) return prev; // If there's no new data, return the previous data + if (fetchMoreResult[listItemName].length === 0) setLoadMore(false); + // Merge the new items with the existing items const updatedItems = [...prev[listItemName], ...fetchMoreResult[listItemName]]; diff --git a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.module.css b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.module.css index 13c6e5519..c3b034d34 100644 --- a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.module.css +++ b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.module.css @@ -1,8 +1,15 @@ +.Container { + max-height: 30%; + display: flex; + flex-direction: column; +} + .Header { width: 100%; display: flex; justify-content: space-between; align-items: center; + margin-bottom: 1rem; } .Header button { @@ -20,3 +27,53 @@ width: 100%; text-align: center; } + +.AssistantsList { + display: flex; + flex-direction: column; + row-gap: 0.5rem; + height: 100%; + overflow-y: scroll; +} + +.AssistantHeading { + font-size: 1rem; + color: #555; + font-weight: 500; + width: 100%; + display: flex; + align-items: center; +} + +.Assistant { + font-size: 0.8rem; + width: 100%; + display: flex; + column-gap: 0.5rem; +} + +.Assistant span { + white-space: nowrap; + width: 50%; + overflow-x: scroll; + position: relative; +} + +.Assistant span span { + margin-left: 1.2rem; +} + +.AssistantHeading span { + width: 50%; +} +.Assistant span::-webkit-scrollbar { + display: none; +} + +.Assistant svg { + height: 0.8rem; + position: absolute; + left: 0; + bottom: 0; + cursor: pointer; +} diff --git a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx index b64d63030..c646c702e 100644 --- a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx +++ b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx @@ -1,34 +1,57 @@ -import { useQuery } from '@apollo/client'; +import { useMutation, useQuery } from '@apollo/client'; import Button from '@mui/material/Button'; import { CircularProgress } from '@mui/material'; import AddIcon from 'assets/images/AddGreenIcon.svg?react'; +import CopyIcon from 'assets/images/icons/Settings/Copy.svg?react'; import { VECTOR_STORE_ASSISTANTS } from 'graphql/queries/Storage'; import styles from './AssistantsAttached.module.css'; +import { CREATE_ASSISTANT } from 'graphql/mutations/Assistants'; +import { copyToClipboard } from 'common/utils'; interface AssistantProps { vectorStoreId: any; } export const AssistantsAttached = ({ vectorStoreId }: AssistantProps) => { - const { data, loading } = useQuery(VECTOR_STORE_ASSISTANTS, { + const { data, loading, refetch } = useQuery(VECTOR_STORE_ASSISTANTS, { variables: { vectorStoreId: vectorStoreId, }, }); + const [createAssistant, { loading: creatingAssistant }] = useMutation(CREATE_ASSISTANT); + + const handleCreateAssistant = () => { + createAssistant({ + variables: { + input: { + vectorStoreId, + }, + }, + onCompleted: () => refetch(), + }); + }; + return (
Used by
- - + {creatingAssistant ? ( + + ) : ( + + )}
+
+ Resource + Assistant ID +
{loading ? ( ) : ( @@ -36,11 +59,17 @@ export const AssistantsAttached = ({ vectorStoreId }: AssistantProps) => { (data?.vectorStore?.vectorStore?.assistants.length === 0 ? (
Not used by any resources.
) : ( - data?.vectorStore?.vectorStore?.assistants?.map((assistant: any) => ( -
-
- {assistant.id} -
+ [ + ...data?.vectorStore?.vectorStore?.assistants, + ...data?.vectorStore?.vectorStore?.assistants, + ...data?.vectorStore?.vectorStore?.assistants, + ]?.map((assistant: any) => ( +
+ {assistant.name} + + copyToClipboard(assistant.assistantId)} /> + {assistant.assistantId} +
)) )) diff --git a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css index fb5074dae..d07a2c170 100644 --- a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css +++ b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.module.css @@ -3,6 +3,7 @@ } .Main { + height: 100%; display: flex; flex-direction: column; row-gap: 1rem; diff --git a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx index 116977ce9..12c936c14 100644 --- a/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx +++ b/src/containers/AIToolkit/Storage/CreateStorage/CreateStorage.tsx @@ -17,19 +17,6 @@ interface CreateStorageProps { vectorStoreId: any; } -const storageOb = { - id: 'vs_KyUlkD25kP34DIANLwxYWQK0', - size: 100, - last_active: '2021-10-01', - inserted_at: '2021-10-01', -}; - -const files = [{ id: '1', file_name: 'file1', inserted_at: '2021-10-01' }]; - -const assistants = [ - { id: 'asst_KyUlkD25kP34DIANLwxYWQK0', name: 'Vyse module', inserted_at: '2021-10-01' }, -]; - export const CreateStorage = ({ vectorStoreId }: CreateStorageProps) => { const [vectorStore, setVectorStore] = useState(null); const [name, setName] = useState(''); diff --git a/src/containers/AIToolkit/Storage/Files/Files.module.css b/src/containers/AIToolkit/Storage/Files/Files.module.css index 32c1b6ebc..2c0398841 100644 --- a/src/containers/AIToolkit/Storage/Files/Files.module.css +++ b/src/containers/AIToolkit/Storage/Files/Files.module.css @@ -1,5 +1,7 @@ .Container { - height: 60%; + max-height: 40%; + display: flex; + flex-direction: column; } .Header { diff --git a/src/containers/AIToolkit/Storage/Files/Files.tsx b/src/containers/AIToolkit/Storage/Files/Files.tsx index 1812bcce2..d8c67ccaf 100644 --- a/src/containers/AIToolkit/Storage/Files/Files.tsx +++ b/src/containers/AIToolkit/Storage/Files/Files.tsx @@ -142,8 +142,11 @@ export const FilesAttached = ({ vectorStoreId }: FilesProps) => { (data?.vectorStore?.vectorStore?.files.length === 0 ? (
This vector store is empty.
) : ( - data?.vectorStore?.vectorStore?.files?.map((file: any) => ( -
+ [ + ...data?.vectorStore?.vectorStore?.files, + ...data?.vectorStore?.vectorStore?.files, + ]?.map((file: any) => ( +
{file.name} diff --git a/src/graphql/mutations/Assistants.ts b/src/graphql/mutations/Assistants.ts new file mode 100644 index 000000000..8571fa311 --- /dev/null +++ b/src/graphql/mutations/Assistants.ts @@ -0,0 +1,12 @@ +import { gql } from '@apollo/client'; + +export const CREATE_ASSISTANT = gql` + mutation CreateAssistant($input: AssistantInput) { + createAssistant(input: $input) { + assistant { + id + name + } + } + } +`; diff --git a/src/graphql/queries/Storage.ts b/src/graphql/queries/Storage.ts index 512eb99c4..bfb30ee75 100644 --- a/src/graphql/queries/Storage.ts +++ b/src/graphql/queries/Storage.ts @@ -66,10 +66,9 @@ export const VECTOR_STORE_ASSISTANTS = gql` vectorStore(id: $vectorStoreId) { vectorStore { assistants { - id - instructions - model + assistantId name + id } } errors { From 1a688374242d09780cb43c279253dbc7bab1513e Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Thu, 3 Oct 2024 15:11:51 +0530 Subject: [PATCH 10/12] added test cases for assistants --- .../Storage/Assistants/AssistantsAttached.tsx | 8 ++++-- .../Storage/Storage/Storage.test.tsx | 27 +++++++++++++++++-- src/mocks/Storage.ts | 23 ++++++++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx index c646c702e..f33f43c26 100644 --- a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx +++ b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx @@ -9,6 +9,7 @@ import { VECTOR_STORE_ASSISTANTS } from 'graphql/queries/Storage'; import styles from './AssistantsAttached.module.css'; import { CREATE_ASSISTANT } from 'graphql/mutations/Assistants'; import { copyToClipboard } from 'common/utils'; +import { setNotification } from 'common/notification'; interface AssistantProps { vectorStoreId: any; @@ -30,7 +31,10 @@ export const AssistantsAttached = ({ vectorStoreId }: AssistantProps) => { vectorStoreId, }, }, - onCompleted: () => refetch(), + onCompleted: () => { + setNotification('Assistant created successfully!'); + refetch(); + }, }); }; @@ -41,7 +45,7 @@ export const AssistantsAttached = ({ vectorStoreId }: AssistantProps) => { {creatingAssistant ? ( ) : ( - diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx b/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx index 6b2ee7409..dc69207b9 100644 --- a/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx +++ b/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx @@ -76,6 +76,12 @@ test('it should search for vector stores', async () => { expect(screen.getAllByTestId('listItem')).toHaveLength(1); expect(screen.getByText('vector_store_4')).toBeInTheDocument(); }); + + fireEvent.click(screen.getByTestId('CloseIcon')); + + await waitFor(() => { + expect(screen.getAllByRole('textbox')[0]).toHaveValue(''); + }); }); test('should update name', async () => { @@ -133,12 +139,29 @@ test('should add and remove files', async () => { }); fireEvent.click(screen.getAllByTestId('deleteFile')[1]); - fireEvent.click(screen.getByTestId('ok-button')); await waitFor(() => { - expect(screen.getAllByTestId('vectorFile')).toHaveLength(2); + expect(screen.getAllByTestId('vectorFile')).toHaveLength(4); }); fireEvent.click(screen.getAllByTestId('removeVectorFile')[1]); }); + +test('it should create an assistant', async () => { + render(wrapper); + + await waitFor(() => { + expect(screen.getByText('Vector Storage')).toBeInTheDocument(); + }); + + await waitFor(() => { + expect(screen.getAllByRole('textbox')[1]).toHaveValue('Vector store 1'); + }); + + fireEvent.click(screen.getByTestId('addAssistant')); + + await waitFor(() => { + expect(notificationSpy).toHaveBeenCalled(); + }); +}); diff --git a/src/mocks/Storage.ts b/src/mocks/Storage.ts index 328fa70dc..c3b508ddd 100644 --- a/src/mocks/Storage.ts +++ b/src/mocks/Storage.ts @@ -1,3 +1,4 @@ +import { CREATE_ASSISTANT } from 'graphql/mutations/Assistants'; import { CREATE_STORAGE, REMOVE_FILES_FROM_STORAGE, @@ -223,6 +224,27 @@ const removeFilesFromVectorStore = { }, }; +const addAssistant = { + request: { + query: CREATE_ASSISTANT, + variables: { + input: { + vectorStoreId: '5', + }, + }, + }, + result: { + data: { + createAssistant: { + assistant: { + id: '1', + name: 'assistant', + }, + }, + }, + }, +}; + export const VECTOR_STORE_MOCKS = [ vectorStorageMocks(), vectorStorageMocks(), @@ -238,4 +260,5 @@ export const VECTOR_STORE_MOCKS = [ removeFilesFromVectorStore, getVectorStorFiles, createVectorStore, + addAssistant, ]; From d46a77aa1cc7e4701576b4f077cef935515833ad Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Thu, 3 Oct 2024 15:22:32 +0530 Subject: [PATCH 11/12] deepscan fixes --- .../AIToolkit/Assistant/Assistants/Assistants.tsx | 1 - .../AIToolkit/Storage/Assistants/AssistantsAttached.tsx | 6 +----- src/containers/AIToolkit/Storage/Files/Files.tsx | 5 +---- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx b/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx index 38f6209da..2114a4bc7 100644 --- a/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx +++ b/src/containers/AIToolkit/Assistant/Assistants/Assistants.tsx @@ -1,7 +1,6 @@ import { assistantsInfo } from 'common/HelpData'; import { Heading } from 'components/UI/Heading/Heading'; import styles from './Assistants.module.css'; -import SearchBar from 'components/UI/SearchBar/SearchBar'; import { CreateAssistant } from '../CreateAssistant/CreateAssistant'; import { List } from '../../ListItems/List'; import { VECTOR_STORES } from 'graphql/queries/Storage'; diff --git a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx index f33f43c26..c66b398d3 100644 --- a/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx +++ b/src/containers/AIToolkit/Storage/Assistants/AssistantsAttached.tsx @@ -63,11 +63,7 @@ export const AssistantsAttached = ({ vectorStoreId }: AssistantProps) => { (data?.vectorStore?.vectorStore?.assistants.length === 0 ? (
Not used by any resources.
) : ( - [ - ...data?.vectorStore?.vectorStore?.assistants, - ...data?.vectorStore?.vectorStore?.assistants, - ...data?.vectorStore?.vectorStore?.assistants, - ]?.map((assistant: any) => ( + data?.vectorStore?.vectorStore?.assistants?.map((assistant: any) => (
{assistant.name} diff --git a/src/containers/AIToolkit/Storage/Files/Files.tsx b/src/containers/AIToolkit/Storage/Files/Files.tsx index d8c67ccaf..91f37fed7 100644 --- a/src/containers/AIToolkit/Storage/Files/Files.tsx +++ b/src/containers/AIToolkit/Storage/Files/Files.tsx @@ -142,10 +142,7 @@ export const FilesAttached = ({ vectorStoreId }: FilesProps) => { (data?.vectorStore?.vectorStore?.files.length === 0 ? (
This vector store is empty.
) : ( - [ - ...data?.vectorStore?.vectorStore?.files, - ...data?.vectorStore?.vectorStore?.files, - ]?.map((file: any) => ( + data?.vectorStore?.vectorStore?.files?.map((file: any) => (
From c86c3c27bfa0bd9effd6f1fccf2e0c6830eedece Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Thu, 3 Oct 2024 15:41:34 +0530 Subject: [PATCH 12/12] added more tests --- src/containers/AIToolkit/ListItems/List.tsx | 2 +- .../Storage/Storage/Storage.test.tsx | 41 ++++++++++++++----- src/mocks/Storage.ts | 30 +++++++++++--- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/containers/AIToolkit/ListItems/List.tsx b/src/containers/AIToolkit/ListItems/List.tsx index 1fb7b9dea..f0b671d95 100644 --- a/src/containers/AIToolkit/ListItems/List.tsx +++ b/src/containers/AIToolkit/ListItems/List.tsx @@ -131,7 +131,7 @@ export const List = ({ )) ))} {showLoadMore ? ( - + Load More ) : null} diff --git a/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx b/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx index dc69207b9..755271ddb 100644 --- a/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx +++ b/src/containers/AIToolkit/Storage/Storage/Storage.test.tsx @@ -2,11 +2,11 @@ import { MockedProvider } from '@apollo/client/testing'; import { MemoryRouter } from 'react-router'; import VectorStorage from './Storage'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; -import { VECTOR_STORE_MOCKS } from 'mocks/Storage'; +import { VECTOR_STORE_MOCKS, loadMoreMocks } from 'mocks/Storage'; import * as Notification from 'common/notification'; -const wrapper = ( - +const wrapper = (mocks: any = VECTOR_STORE_MOCKS) => ( + @@ -16,7 +16,7 @@ const wrapper = ( const notificationSpy = vi.spyOn(Notification, 'setNotification'); test('it should render Vector storage component', async () => { - render(wrapper); + render(wrapper()); await waitFor(() => { expect(screen.getByText('Vector Storage')).toBeInTheDocument(); @@ -28,7 +28,7 @@ test('it should render Vector storage component', async () => { }); test('it should create a Vector storage', async () => { - render(wrapper); + render(wrapper()); await waitFor(() => { expect(screen.getByText('Vector Storage')).toBeInTheDocument(); @@ -46,7 +46,7 @@ test('it should create a Vector storage', async () => { }); test('it should switch between vector stores', async () => { - render(wrapper); + render(wrapper()); await waitFor(() => { expect(screen.getByText('Vector Storage')).toBeInTheDocument(); @@ -64,7 +64,7 @@ test('it should switch between vector stores', async () => { }); test('it should search for vector stores', async () => { - render(wrapper); + render(wrapper()); await waitFor(() => { expect(screen.getByText('Vector Storage')).toBeInTheDocument(); @@ -85,7 +85,7 @@ test('it should search for vector stores', async () => { }); test('should update name', async () => { - render(wrapper); + render(wrapper()); await waitFor(() => { expect(screen.getByText('Vector Storage')).toBeInTheDocument(); @@ -107,7 +107,7 @@ test('should update name', async () => { }); test('should add and remove files', async () => { - render(wrapper); + render(wrapper()); await waitFor(() => { expect(screen.getByText('Vector Storage')).toBeInTheDocument(); @@ -142,14 +142,14 @@ test('should add and remove files', async () => { fireEvent.click(screen.getByTestId('ok-button')); await waitFor(() => { - expect(screen.getAllByTestId('vectorFile')).toHaveLength(4); + expect(screen.getAllByTestId('vectorFile')).toHaveLength(2); }); fireEvent.click(screen.getAllByTestId('removeVectorFile')[1]); }); test('it should create an assistant', async () => { - render(wrapper); + render(wrapper()); await waitFor(() => { expect(screen.getByText('Vector Storage')).toBeInTheDocument(); @@ -165,3 +165,22 @@ test('it should create an assistant', async () => { expect(notificationSpy).toHaveBeenCalled(); }); }); + +test('should test loadmore', async () => { + render(wrapper(loadMoreMocks)); + + await waitFor(() => { + expect(screen.getByText('Vector Storage')).toBeInTheDocument(); + }); + + await waitFor(() => { + expect(screen.getAllByTestId('listItem')).toHaveLength(25); + expect(screen.getAllByRole('textbox')[1]).toHaveValue('vector_store_1'); + }); + + fireEvent.click(screen.getByText('Load More')); + + await waitFor(() => { + expect(screen.getAllByTestId('listItem')).toHaveLength(75); + }); +}); diff --git a/src/mocks/Storage.ts b/src/mocks/Storage.ts index c3b508ddd..d3dbf781e 100644 --- a/src/mocks/Storage.ts +++ b/src/mocks/Storage.ts @@ -55,15 +55,19 @@ const vectorStores = [ }, ]; -export const vectorStorageMocks = (data: any[] = vectorStores, searchTerm: string = '') => ({ +export const vectorStorageMocks = ( + data: any[] = vectorStores, + searchTerm: string = '', + opts: any = { + limit: 25, + order: 'DESC', + } +) => ({ request: { query: VECTOR_STORES, variables: { filter: { name: searchTerm }, - opts: { - limit: 25, - order: 'DESC', - }, + opts, }, }, result: { @@ -262,3 +266,19 @@ export const VECTOR_STORE_MOCKS = [ createVectorStore, addAssistant, ]; + +const vectors = (limit: number = 25) => + new Array(limit).fill(null).map((val, ind) => ({ + id: `${ind + 1}`, + insertedAt: '2024-09-30T09:18:44Z', + itemId: 'vs_HFGiyvbrl4c4Xx32ijAXhzd7', + name: `vector_store_${ind + 1}`, + size: '0 B', + updatedAt: '2024-09-30T09:18:44Z', + })); + +export const loadMoreMocks = [ + vectorStorageMocks(vectors(), ''), + getVectorStoreQuery('1', 'vector_store_1'), + vectorStorageMocks(vectors(50), '', { limit: 50, offset: 25, order: 'DESC' }), +];