@stack-spot/ai-chat-widget 1.17.1 → 1.18.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/StackspotAIWidget.js +1 -1
- package/dist/app-metadata.json +2 -2
- package/dist/components/ComponentNavigator.d.ts +21 -0
- package/dist/components/ComponentNavigator.d.ts.map +1 -0
- package/dist/components/ComponentNavigator.js +33 -0
- package/dist/components/ComponentNavigator.js.map +1 -0
- package/dist/components/ListGroup.d.ts +46 -0
- package/dist/components/ListGroup.d.ts.map +1 -0
- package/dist/components/ListGroup.js +16 -0
- package/dist/components/ListGroup.js.map +1 -0
- package/dist/components/RightPanelForm.d.ts.map +1 -1
- package/dist/components/RightPanelForm.js +29 -1
- package/dist/components/RightPanelForm.js.map +1 -1
- package/dist/components/Selector/index.js +5 -5
- package/dist/components/Selector/index.js.map +1 -1
- package/dist/components/Selector/styled.d.ts +3 -1
- package/dist/components/Selector/styled.d.ts.map +1 -1
- package/dist/components/Selector/styled.js +2 -1
- package/dist/components/Selector/styled.js.map +1 -1
- package/dist/components/WorkspaceTabNavigator.d.ts +15 -0
- package/dist/components/WorkspaceTabNavigator.d.ts.map +1 -0
- package/dist/components/WorkspaceTabNavigator.js +95 -0
- package/dist/components/WorkspaceTabNavigator.js.map +1 -0
- package/dist/components/form/DescribedCheckboxGroup.d.ts.map +1 -1
- package/dist/components/form/DescribedCheckboxGroup.js +23 -2
- package/dist/components/form/DescribedCheckboxGroup.js.map +1 -1
- package/dist/views/Agents/AgentsPanel.d.ts.map +1 -1
- package/dist/views/Agents/AgentsPanel.js +19 -11
- package/dist/views/Agents/AgentsPanel.js.map +1 -1
- package/dist/views/Agents/AgentsTab.d.ts +9 -3
- package/dist/views/Agents/AgentsTab.d.ts.map +1 -1
- package/dist/views/Agents/AgentsTab.js +25 -7
- package/dist/views/Agents/AgentsTab.js.map +1 -1
- package/dist/views/Agents/dictionary.d.ts +1 -1
- package/dist/views/Agents/dictionary.d.ts.map +1 -1
- package/dist/views/Agents/dictionary.js +2 -0
- package/dist/views/Agents/dictionary.js.map +1 -1
- package/dist/views/ChatHistory/utils.d.ts.map +1 -1
- package/dist/views/ChatHistory/utils.js +8 -3
- package/dist/views/ChatHistory/utils.js.map +1 -1
- package/dist/views/KnowledgeSources.d.ts +12 -0
- package/dist/views/KnowledgeSources.d.ts.map +1 -1
- package/dist/views/KnowledgeSources.js +20 -6
- package/dist/views/KnowledgeSources.js.map +1 -1
- package/dist/views/MessageInput/AgentSelector.d.ts.map +1 -1
- package/dist/views/MessageInput/AgentSelector.js +4 -3
- package/dist/views/MessageInput/AgentSelector.js.map +1 -1
- package/dist/views/MessageInput/ButtonGroup.js +2 -2
- package/dist/views/MessageInput/ButtonGroup.js.map +1 -1
- package/dist/views/MessageInput/QuickCommandSelector.d.ts.map +1 -1
- package/dist/views/MessageInput/QuickCommandSelector.js +9 -3
- package/dist/views/MessageInput/QuickCommandSelector.js.map +1 -1
- package/dist/views/MessageInput/dictionary.d.ts +1 -1
- package/dist/views/MessageInput/dictionary.d.ts.map +1 -1
- package/dist/views/MessageInput/dictionary.js +2 -0
- package/dist/views/MessageInput/dictionary.js.map +1 -1
- package/dist/views/Stacks.d.ts +9 -0
- package/dist/views/Stacks.d.ts.map +1 -1
- package/dist/views/Stacks.js +37 -14
- package/dist/views/Stacks.js.map +1 -1
- package/dist/views/Workspaces/WorkspacesTab.d.ts +20 -0
- package/dist/views/Workspaces/WorkspacesTab.d.ts.map +1 -0
- package/dist/views/Workspaces/WorkspacesTab.js +64 -0
- package/dist/views/Workspaces/WorkspacesTab.js.map +1 -0
- package/dist/views/{Workspaces.d.ts → Workspaces/index.d.ts} +1 -1
- package/dist/views/Workspaces/index.d.ts.map +1 -0
- package/dist/views/Workspaces/index.js +76 -0
- package/dist/views/Workspaces/index.js.map +1 -0
- package/package.json +2 -2
- package/src/app-metadata.json +2 -2
- package/src/components/ComponentNavigator.tsx +78 -0
- package/src/components/ListGroup.tsx +76 -0
- package/src/components/RightPanelForm.tsx +29 -1
- package/src/components/Selector/index.tsx +5 -5
- package/src/components/Selector/styled.ts +3 -2
- package/src/components/WorkspaceTabNavigator.tsx +172 -0
- package/src/components/form/DescribedCheckboxGroup.tsx +45 -14
- package/src/views/Agents/AgentsPanel.tsx +21 -11
- package/src/views/Agents/AgentsTab.tsx +42 -9
- package/src/views/Agents/dictionary.ts +3 -0
- package/src/views/ChatHistory/utils.ts +9 -3
- package/src/views/KnowledgeSources.tsx +37 -14
- package/src/views/MessageInput/AgentSelector.tsx +4 -3
- package/src/views/MessageInput/ButtonGroup.tsx +3 -3
- package/src/views/MessageInput/QuickCommandSelector.tsx +10 -3
- package/src/views/MessageInput/dictionary.ts +2 -0
- package/src/views/Stacks.tsx +57 -17
- package/src/views/Workspaces/WorkspacesTab.tsx +118 -0
- package/src/views/Workspaces/index.tsx +85 -0
- package/dist/views/Workspaces.d.ts.map +0 -1
- package/dist/views/Workspaces.js +0 -103
- package/dist/views/Workspaces.js.map +0 -1
- package/src/views/Workspaces.tsx +0 -137
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { QuickCommand } from '@citric/icons'
|
|
2
|
-
import { aiClient } from '@stack-spot/portal-network'
|
|
2
|
+
import { aiClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
3
3
|
import { QuickCommandListResponse } from '@stack-spot/portal-network/api/ai'
|
|
4
4
|
import { useCallback } from 'react'
|
|
5
5
|
import { Selector } from '../../components/Selector'
|
|
@@ -74,8 +74,15 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
74
74
|
inputRef.current.focus()
|
|
75
75
|
}, [chat, inputRef])
|
|
76
76
|
|
|
77
|
+
const getQuickCommands = () => {
|
|
78
|
+
const quickCommands = aiClient.quickCommands.useQuery({ order: 'a-to-z' })
|
|
79
|
+
const quickCommandsFiltered = quickCommands.filter((qc) => qc.visibility_level.toLowerCase() !== 'workspace')
|
|
80
|
+
const workspaceQuickCommands = workspaceAiClient.workspacesContentsByType.useQuery({ contentType: 'quick_command' })
|
|
81
|
+
return [...quickCommandsFiltered, ...workspaceQuickCommands.qcs]
|
|
82
|
+
}
|
|
83
|
+
|
|
77
84
|
const QuickCommandItem = ({ slug, description }: QuickCommandListResponse) => <>
|
|
78
|
-
<p className="selector-title">/{slug
|
|
85
|
+
<p className="selector-title">/{slug?.toUpperCase()}</p>
|
|
79
86
|
<p className="selector-description">{description}</p>
|
|
80
87
|
</>
|
|
81
88
|
|
|
@@ -95,7 +102,7 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
95
102
|
isEnabled: isQuickCommandEnabled,
|
|
96
103
|
onSelect: onSelectItem,
|
|
97
104
|
renderComponentItem: QuickCommandItem,
|
|
98
|
-
useData:
|
|
105
|
+
useData: getQuickCommands,
|
|
99
106
|
}}
|
|
100
107
|
/>
|
|
101
108
|
}
|
|
@@ -5,6 +5,7 @@ const dictionary = {
|
|
|
5
5
|
stack: 'Select stack',
|
|
6
6
|
code: 'Open code editor',
|
|
7
7
|
workspace: 'Select workspace',
|
|
8
|
+
space: 'Select space',
|
|
8
9
|
knowledgeSource: 'Select knowledge sources',
|
|
9
10
|
agent: 'Select agent',
|
|
10
11
|
collapse: 'Hide buttons',
|
|
@@ -24,6 +25,7 @@ const dictionary = {
|
|
|
24
25
|
stack: 'Selecionar stack',
|
|
25
26
|
code: 'Abrir editor de código',
|
|
26
27
|
workspace: 'Selecionar workspace',
|
|
28
|
+
space: 'Select Space',
|
|
27
29
|
knowledgeSource: 'Selecionar knowledge sources',
|
|
28
30
|
agent: 'Selecionar agente',
|
|
29
31
|
collapse: 'Esconder botões',
|
package/src/views/Stacks.tsx
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { Button } from '@citric/core'
|
|
2
2
|
import { Search } from '@citric/icons'
|
|
3
3
|
import { Placeholder } from '@stack-spot/portal-components/Placeholder'
|
|
4
|
-
import { aiClient } from '@stack-spot/portal-network'
|
|
4
|
+
import { aiClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
5
5
|
import { GetAiStackResponse, VisibilityLevelEnum } from '@stack-spot/portal-network/api/ai'
|
|
6
|
+
import { WorkspaceResponse } from '@stack-spot/portal-network/api/workspace-ai'
|
|
6
7
|
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
7
|
-
import { useEffect, useMemo, useState } from 'react'
|
|
8
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
8
9
|
import { ButtonFavorite } from '../components/ButtonFavorite'
|
|
10
|
+
import { NavigationItem } from '../components/ComponentNavigator'
|
|
9
11
|
import { DescribedRadioGroup } from '../components/form/DescribedRadioGroup'
|
|
10
12
|
import { IconInput } from '../components/IconInput'
|
|
11
13
|
import { RightPanelTabs } from '../components/RightPanelTabs'
|
|
14
|
+
import { WorkspaceTabNavigator } from '../components/WorkspaceTabNavigator'
|
|
12
15
|
import { useCurrentChat, useWidget, useWidgetState } from '../context/hooks'
|
|
13
16
|
import { useRightPanel } from '../right-panel/hooks'
|
|
17
|
+
import { ChatProperties } from '../state/ChatState'
|
|
14
18
|
import { checkIsTrial } from '../utils/check-is-trial'
|
|
15
19
|
|
|
16
20
|
/**
|
|
@@ -35,23 +39,35 @@ export const Stacks = () => {
|
|
|
35
39
|
const StacksPanel = () => {
|
|
36
40
|
const t = useTranslate(dictionary)
|
|
37
41
|
const chat = useCurrentChat()
|
|
38
|
-
|
|
39
42
|
const isTrial = checkIsTrial()
|
|
43
|
+
const stack = useRef(chat.get('stack'))
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
stack.current = chat.get('stack')
|
|
47
|
+
}, [chat])
|
|
40
48
|
|
|
41
49
|
const tabs = useMemo(() => isTrial ? [
|
|
42
|
-
{ title: t.favorites, content: <StacksTab key="favorites" visibility="favorite" /> },
|
|
43
|
-
{ title: t.personal, content: <StacksTab key="personal" visibility="personal" /> },
|
|
50
|
+
{ title: t.favorites, content: <StacksTab key="favorites" visibility="favorite" stack={stack} /> },
|
|
51
|
+
{ title: t.personal, content: <StacksTab key="personal" visibility="personal" stack={stack} /> },
|
|
44
52
|
]: [
|
|
45
|
-
{ title: t.favorites, content: <StacksTab key="favorites" visibility="favorite" /> },
|
|
46
|
-
{ title: t.personal, content: <StacksTab key="personal" visibility="personal" /> },
|
|
47
|
-
{ title: t.shared, content: <StacksTab key="shared" visibility="shared" /> },
|
|
48
|
-
{ title: t.
|
|
53
|
+
{ title: t.favorites, content: <StacksTab key="favorites" visibility="favorite" stack={stack} /> },
|
|
54
|
+
{ title: t.personal, content: <StacksTab key="personal" visibility="personal" stack={stack} /> },
|
|
55
|
+
{ title: t.shared, content: <StacksTab key="shared" visibility="shared" stack={stack} /> },
|
|
56
|
+
{ title: t.spaces, content: <StacksTabWorkspace key="workspace" visibility="workspace" stack={stack} /> },
|
|
57
|
+
{ title: t.account, content: <StacksTab key="account" visibility="account" stack={stack} /> },
|
|
49
58
|
], [t, isTrial])
|
|
50
59
|
|
|
51
60
|
return <RightPanelTabs key={chat.id} tabs={tabs} />
|
|
52
61
|
}
|
|
53
62
|
|
|
54
|
-
|
|
63
|
+
export interface StacksTabProps {
|
|
64
|
+
visibility: VisibilityLevelEnum,
|
|
65
|
+
workspaceId?: string,
|
|
66
|
+
stack: React.MutableRefObject<ChatProperties['stack']>,
|
|
67
|
+
showSubmitButton?: boolean,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const StacksTab = ({ visibility, workspaceId, stack, showSubmitButton = true }: StacksTabProps) => {
|
|
55
71
|
const t = useTranslate(dictionary)
|
|
56
72
|
const { close } = useRightPanel()
|
|
57
73
|
const chat = useCurrentChat()
|
|
@@ -111,13 +127,19 @@ const StacksTab = ({ visibility }: { visibility: VisibilityLevelEnum }) => {
|
|
|
111
127
|
}
|
|
112
128
|
})
|
|
113
129
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
const stacks = workspaceId
|
|
133
|
+
? workspaceAiClient.getStackFromWorkspaceAi.useQuery({ workspaceId })
|
|
134
|
+
//@ts-ignore
|
|
135
|
+
: aiClient.aiStacks.useQuery({ visibility, order: 'a-to-z' })
|
|
136
|
+
|
|
137
|
+
const currentStackId = stack.current ? stack.current.id : chat.get('stack')?.id
|
|
138
|
+
const [value, setValue] = useState<GetAiStackResponse | undefined>(stacks.find(s => s.id === currentStackId))
|
|
117
139
|
const filtered = useMemo(() => filter ?
|
|
118
140
|
// Recreate the list so that the favorites list is taken into account
|
|
119
|
-
stacks.filter(s => s === value || s.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase())) : [...stacks],
|
|
120
|
-
[stacks, listFavorites, filter, value],
|
|
141
|
+
stacks.filter(s => s === value || s.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase())) : [...stacks],
|
|
142
|
+
[stacks, listFavorites, filter, value],
|
|
121
143
|
)
|
|
122
144
|
|
|
123
145
|
function submit() {
|
|
@@ -125,6 +147,11 @@ const StacksTab = ({ visibility }: { visibility: VisibilityLevelEnum }) => {
|
|
|
125
147
|
close()
|
|
126
148
|
}
|
|
127
149
|
|
|
150
|
+
const onChange = useCallback((newValue: GetAiStackResponse) => {
|
|
151
|
+
setValue(newValue)
|
|
152
|
+
stack.current = { ...newValue, label: newValue.name }
|
|
153
|
+
}, [])
|
|
154
|
+
|
|
128
155
|
return (
|
|
129
156
|
<>
|
|
130
157
|
<div className="content">
|
|
@@ -136,7 +163,7 @@ const StacksTab = ({ visibility }: { visibility: VisibilityLevelEnum }) => {
|
|
|
136
163
|
}
|
|
137
164
|
keygen={s => s.id}
|
|
138
165
|
value={value}
|
|
139
|
-
onChange={
|
|
166
|
+
onChange={onChange}
|
|
140
167
|
renderLabel={s => s.name}
|
|
141
168
|
renderDescription={s => s.use_case}
|
|
142
169
|
optionClassName={s => (s === value && filter && !s.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase()))
|
|
@@ -149,11 +176,22 @@ const StacksTab = ({ visibility }: { visibility: VisibilityLevelEnum }) => {
|
|
|
149
176
|
<Placeholder title={t.noSearchResults} description={t.noSearchResultsDescription} className="no-data-placeholder"/>}
|
|
150
177
|
{!stacks.length && <Placeholder title={t.noData} description={t.noDataDescription} />}
|
|
151
178
|
</div>
|
|
152
|
-
{!!filtered.length && <Button onClick={submit} disabled={!value}>{t.apply}</Button>}
|
|
179
|
+
{!!filtered.length && showSubmitButton && <Button onClick={submit} disabled={!value}>{t.apply}</Button>}
|
|
153
180
|
</>
|
|
154
181
|
)
|
|
155
182
|
}
|
|
156
183
|
|
|
184
|
+
function StacksTabWorkspace({ stack, visibility, showSubmitButton }: StacksTabProps) {
|
|
185
|
+
const workspaceTabComponents = useMemo(() => ({ stack: StacksTab }), [stack])
|
|
186
|
+
|
|
187
|
+
const buildNavigateParams = (workspace: WorkspaceResponse): NavigationItem<typeof workspaceTabComponents> => ({
|
|
188
|
+
component: 'stack',
|
|
189
|
+
props: { visibility, workspaceId: workspace.id, stack, showSubmitButton },
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
return <WorkspaceTabNavigator components={workspaceTabComponents} getNavigateParam={buildNavigateParams} />
|
|
193
|
+
}
|
|
194
|
+
|
|
157
195
|
const dictionary = {
|
|
158
196
|
en: {
|
|
159
197
|
title: 'Stacks AI',
|
|
@@ -167,6 +205,7 @@ const dictionary = {
|
|
|
167
205
|
noData: 'There are no stacks in this category yet.',
|
|
168
206
|
noDataDescription: 'Use the tabs above to try other categories or use the AI portal to create new stacks.',
|
|
169
207
|
favorites: 'Favorites',
|
|
208
|
+
spaces: 'Spaces',
|
|
170
209
|
},
|
|
171
210
|
pt: {
|
|
172
211
|
title: 'Stacks AI',
|
|
@@ -180,5 +219,6 @@ const dictionary = {
|
|
|
180
219
|
noData: 'Ainda não há stacks nesta categoria.',
|
|
181
220
|
noDataDescription: 'Use as abas acima para tentar outras categorias ou use o Portal AI para criar novas stacks.',
|
|
182
221
|
favorites: 'Favoritos',
|
|
222
|
+
spaces: 'Spaces',
|
|
183
223
|
},
|
|
184
224
|
} satisfies Dictionary
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Button, Flex, IconBox, Image, Text } from '@citric/core'
|
|
2
|
+
import { Agent, Circle, KnowledgeSource, Stack } from '@citric/icons'
|
|
3
|
+
import { Avatar } from '@citric/ui'
|
|
4
|
+
import { workspaceAiClient } from '@stack-spot/portal-network'
|
|
5
|
+
import { WorkspaceResponse, WorkspaceVisibilityLevelEnum } from '@stack-spot/portal-network/api/workspace-ai'
|
|
6
|
+
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
7
|
+
import { useTransition } from 'react'
|
|
8
|
+
import { useComponentNavigation } from '../../components/ComponentNavigator'
|
|
9
|
+
import { ListGroup } from '../../components/ListGroup'
|
|
10
|
+
import { CardSpace, WorkspaceTabNavigator } from '../../components/WorkspaceTabNavigator'
|
|
11
|
+
import { ChatProperties } from '../../state/ChatState'
|
|
12
|
+
import { AgentsTab } from '../Agents/AgentsTab'
|
|
13
|
+
import { KnowledgeSourcesTab } from '../KnowledgeSources'
|
|
14
|
+
import { StacksTab } from '../Stacks'
|
|
15
|
+
|
|
16
|
+
const SpaceCard = ({ workspaceId }: { workspaceId: string }) => {
|
|
17
|
+
const workspace = workspaceAiClient.workspaceAi.useQuery({ id: workspaceId })
|
|
18
|
+
return <Flex flexDirection="column" sx={{ gap: '8px' }}>
|
|
19
|
+
<Flex flexDirection="column" sx={{ gap: '4px' }}>
|
|
20
|
+
<Flex alignContent="center" alignItems="center" sx={{ gap: '8px', m: 1 }} >
|
|
21
|
+
<Avatar size="xxs" appearance="square" sx={{ bg: 'light.600', r: 'xxs' }}>
|
|
22
|
+
{workspace.logo ? <Image src={workspace.logo} /> : <IconBox> <Circle /> </IconBox>}
|
|
23
|
+
</Avatar>
|
|
24
|
+
<Text appearance="body2" weight="medium">{workspace.name} </Text>
|
|
25
|
+
</Flex>
|
|
26
|
+
<Text colorScheme="light.700">{workspace.description}</Text>
|
|
27
|
+
</Flex>
|
|
28
|
+
</Flex>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface TabProps {
|
|
32
|
+
visibility: WorkspaceVisibilityLevelEnum,
|
|
33
|
+
allKS: React.MutableRefObject<ChatProperties['knowledgeSources']>,
|
|
34
|
+
agent: React.MutableRefObject<ChatProperties['agent']>,
|
|
35
|
+
stack: React.MutableRefObject<ChatProperties['stack']>,
|
|
36
|
+
workspaceId?: string,
|
|
37
|
+
onSubmit: () => void,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface WorkspaceResource {
|
|
41
|
+
id: string,
|
|
42
|
+
resourceType: 'agent' | 'ks' | 'stack',
|
|
43
|
+
displayName: string,
|
|
44
|
+
icon: React.ReactElement,
|
|
45
|
+
workspaceId?: string,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const showSubmitButton = false
|
|
49
|
+
|
|
50
|
+
export const WorkspaceResources = ({ workspaceId, allKS, agent, stack }: Omit<TabProps, 'onSubmit'>) => {
|
|
51
|
+
const { navigate } = useComponentNavigation<typeof workspaceTabComponents>()
|
|
52
|
+
const [isPending, startTransition] = useTransition()
|
|
53
|
+
const resourceTypes: WorkspaceResource[] = [
|
|
54
|
+
{ id: 'agents', resourceType: 'agent', displayName: 'Agents', workspaceId, icon: <Agent /> },
|
|
55
|
+
{ id: 'ks', resourceType: 'ks', displayName: 'Knowledge Sources', workspaceId, icon: <KnowledgeSource /> },
|
|
56
|
+
{ id: 'stack', resourceType: 'stack', displayName: 'Stacks', workspaceId, icon: <Stack /> },
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
const handleNavigate = (resource: WorkspaceResource) => {
|
|
60
|
+
startTransition(() => {
|
|
61
|
+
if (resource.resourceType === 'agent')
|
|
62
|
+
navigate({ component: 'agent', props: { visibility: 'WORKSPACE', agent, workspaceId, showSubmitButton }, fullScreen: true })
|
|
63
|
+
|
|
64
|
+
if (resource.resourceType === 'ks')
|
|
65
|
+
navigate({ component: 'ks', props: { visibility: 'workspace', allKS, workspaceId, showSubmitButton }, fullScreen: true })
|
|
66
|
+
|
|
67
|
+
if (resource.resourceType === 'stack')
|
|
68
|
+
navigate({ component: 'stack', props: { visibility: 'workspace', stack, workspaceId, showSubmitButton }, fullScreen: true })
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return (<>
|
|
73
|
+
{workspaceId && <SpaceCard workspaceId={workspaceId} />}
|
|
74
|
+
<ListGroup
|
|
75
|
+
list={resourceTypes}
|
|
76
|
+
keygen={w => w.id}
|
|
77
|
+
onClick={(resource) => { handleNavigate(resource) }}
|
|
78
|
+
renderLabel={r => <CardSpace name={r.displayName} icon={r.icon} onClick={() => handleNavigate(r)} />}
|
|
79
|
+
style={{ gap: '6px', display: 'flex', flexDirection: 'column', opacity: isPending ? '0.5' : '1' }}
|
|
80
|
+
/>
|
|
81
|
+
</>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const workspaceTabComponents = {
|
|
86
|
+
workspaceResource: WorkspaceResources,
|
|
87
|
+
agent: AgentsTab,
|
|
88
|
+
ks: KnowledgeSourcesTab,
|
|
89
|
+
stack: StacksTab,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function WorkspacesTab({ visibility, allKS, agent, stack, onSubmit }: TabProps) {
|
|
93
|
+
const t = useTranslate(dictionary)
|
|
94
|
+
const buildNavigateParams = (workspace: WorkspaceResponse) => ({
|
|
95
|
+
component: 'workspaceResource',
|
|
96
|
+
props: { allKS, agent, stack, visibility, workspaceId: workspace.id } satisfies Omit<TabProps, 'onSubmit'>,
|
|
97
|
+
fullScreen: true,
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
return (<>
|
|
101
|
+
<WorkspaceTabNavigator
|
|
102
|
+
components={workspaceTabComponents}
|
|
103
|
+
getNavigateParam={buildNavigateParams}
|
|
104
|
+
visibility={visibility}
|
|
105
|
+
/>
|
|
106
|
+
<Button className="workspace-submit" onClick={onSubmit} >{t.apply}</Button>
|
|
107
|
+
</>
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const dictionary = {
|
|
112
|
+
en: {
|
|
113
|
+
apply: 'Apply',
|
|
114
|
+
},
|
|
115
|
+
pt: {
|
|
116
|
+
apply: 'Aplicar',
|
|
117
|
+
},
|
|
118
|
+
} satisfies Dictionary
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
2
|
+
import { useCallback, useEffect, useRef } from 'react'
|
|
3
|
+
import { RightPanelTabs } from '../../components/RightPanelTabs'
|
|
4
|
+
import { useCurrentChat, useWidget, useWidgetState } from '../../context/hooks'
|
|
5
|
+
import { useRightPanel } from '../../right-panel/hooks'
|
|
6
|
+
import { WorkspacesTab } from './WorkspacesTab'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Renders the Workspace selection form in the Right Panel if this is the panel that is currently opened.
|
|
10
|
+
*/
|
|
11
|
+
export const Workspaces = () => {
|
|
12
|
+
const t = useTranslate(dictionary)
|
|
13
|
+
const panel = useWidgetState('panel')
|
|
14
|
+
const { open } = useRightPanel()
|
|
15
|
+
const widget = useWidget()
|
|
16
|
+
const chat = useCurrentChat()
|
|
17
|
+
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (panel === 'workspace') open(
|
|
20
|
+
<WorkspacesPanel key={chat.id} />,
|
|
21
|
+
{ title: t.title, description: t.description, onClose: () => widget.set('panel', undefined) },
|
|
22
|
+
)
|
|
23
|
+
}, [panel, t, chat.id])
|
|
24
|
+
return null
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const WorkspacesPanel = () => {
|
|
28
|
+
const t = useTranslate(dictionary)
|
|
29
|
+
const chat = useCurrentChat()
|
|
30
|
+
const allKS = useRef(chat.get('knowledgeSources') ?? [])
|
|
31
|
+
const agent = useRef(chat.get('agent'))
|
|
32
|
+
const stack = useRef(chat.get('stack'))
|
|
33
|
+
const { close } = useRightPanel()
|
|
34
|
+
|
|
35
|
+
const onSubmit = useCallback(() => {
|
|
36
|
+
chat.set('knowledgeSources', allKS.current)
|
|
37
|
+
chat.set('stack', stack.current)
|
|
38
|
+
chat.set('agent', agent.current)
|
|
39
|
+
close()
|
|
40
|
+
}, [chat])
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
allKS.current = chat.get('knowledgeSources') ?? []
|
|
44
|
+
agent.current = chat.get('agent')
|
|
45
|
+
stack.current = chat.get('stack')
|
|
46
|
+
}, [chat])
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
return <RightPanelTabs key={chat.id} tabs={[
|
|
50
|
+
{
|
|
51
|
+
title: t.favorites,
|
|
52
|
+
content: <WorkspacesTab key="favorite" visibility="favorite" allKS={allKS} agent={agent} stack={stack} onSubmit={onSubmit} />,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
title: t.all,
|
|
56
|
+
content: <WorkspacesTab key="all" visibility="all" allKS={allKS} agent={agent} stack={stack} onSubmit={onSubmit} />,
|
|
57
|
+
},
|
|
58
|
+
]}
|
|
59
|
+
/>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const dictionary = {
|
|
63
|
+
en: {
|
|
64
|
+
title: 'Spaces',
|
|
65
|
+
description: 'By selecting a space, its Knowledge Sources (KSs), Agents, Quick Commands and Stacks Ai will be consulted to generate the answers.',
|
|
66
|
+
apply: 'Apply',
|
|
67
|
+
noSearchResults: "Your search didn't yield results.",
|
|
68
|
+
noSearchResultsDescription: 'Please, try another search term.',
|
|
69
|
+
noData: 'There are no spaces yet.',
|
|
70
|
+
noDataDescription: 'Use the AI portal to create new spaces.',
|
|
71
|
+
all: 'All',
|
|
72
|
+
favorites: 'Favorites',
|
|
73
|
+
},
|
|
74
|
+
pt: {
|
|
75
|
+
title: 'Spaces',
|
|
76
|
+
description: 'Ao selecionar um space, seus Knowledge Sources (KSs), Agentes, Quick Commands e Stacks Ai serão consultados para gerar as respostas.',
|
|
77
|
+
apply: 'Aplicar',
|
|
78
|
+
noSearchResults: 'Sua busca não produziu resultados',
|
|
79
|
+
noSearchResultsDescription: 'Por favor, tente outra busca.',
|
|
80
|
+
noData: 'Ainda não há spaces.',
|
|
81
|
+
noDataDescription: 'Use o Portal AI para criar novos spaces.',
|
|
82
|
+
all: 'Todos',
|
|
83
|
+
favorites: 'Favoritos',
|
|
84
|
+
},
|
|
85
|
+
} satisfies Dictionary
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Workspaces.d.ts","sourceRoot":"","sources":["../../src/views/Workspaces.tsx"],"names":[],"mappings":"AAaA;;GAEG;AACH,eAAO,MAAM,UAAU,YActB,CAAA"}
|
package/dist/views/Workspaces.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Button } from '@citric/core';
|
|
3
|
-
import { Search } from '@citric/icons';
|
|
4
|
-
import { Placeholder } from '@stack-spot/portal-components/Placeholder';
|
|
5
|
-
import { workspaceClient } from '@stack-spot/portal-network';
|
|
6
|
-
import { useTranslate } from '@stack-spot/portal-translate';
|
|
7
|
-
import { useEffect, useMemo, useState } from 'react';
|
|
8
|
-
import { DescribedRadioGroup } from '../components/form/DescribedRadioGroup.js';
|
|
9
|
-
import { IconInput } from '../components/IconInput.js';
|
|
10
|
-
import { RightPanelTabs } from '../components/RightPanelTabs.js';
|
|
11
|
-
import { useCurrentChat, useWidget, useWidgetState } from '../context/hooks.js';
|
|
12
|
-
import { useRightPanel } from '../right-panel/hooks.js';
|
|
13
|
-
/**
|
|
14
|
-
* Renders the Workspace selection form in the Right Panel if this is the panel that is currently opened.
|
|
15
|
-
*/
|
|
16
|
-
export const Workspaces = () => {
|
|
17
|
-
const t = useTranslate(dictionary);
|
|
18
|
-
const panel = useWidgetState('panel');
|
|
19
|
-
const { open } = useRightPanel();
|
|
20
|
-
const widget = useWidget();
|
|
21
|
-
const chat = useCurrentChat();
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
if (panel === 'workspace')
|
|
24
|
-
open(_jsx(WorkspacesPanel, {}, chat.id), { title: t.title, description: t.description, onClose: () => widget.set('panel', undefined) });
|
|
25
|
-
}, [panel, t, chat.id]);
|
|
26
|
-
return null;
|
|
27
|
-
};
|
|
28
|
-
const WorkspacesPanel = () => {
|
|
29
|
-
const t = useTranslate(dictionary);
|
|
30
|
-
const chat = useCurrentChat();
|
|
31
|
-
return _jsx(RightPanelTabs, { tabs: [
|
|
32
|
-
// { title: t.favorites, content: <WorkspaceSourcesTab key="favorite" visibility="favorite" /> },
|
|
33
|
-
{ title: t.all, content: _jsx(WorkspaceSourcesTab, {}, "all") },
|
|
34
|
-
] }, chat.id);
|
|
35
|
-
};
|
|
36
|
-
const WorkspaceSourcesTab = () => {
|
|
37
|
-
const t = useTranslate(dictionary);
|
|
38
|
-
const { close } = useRightPanel();
|
|
39
|
-
const chat = useCurrentChat();
|
|
40
|
-
const [filter, setFilter] = useState('');
|
|
41
|
-
// const workspaces = workspaceAiClient.workspacesAi.useQuery({ visibility })
|
|
42
|
-
// const [value, setValue] = useState<WorkspaceResponse | undefined>(workspaces.find(w => w.id === chat.get('workspace')?.id))
|
|
43
|
-
const workspaces = workspaceClient.workspaces.useQuery({ aclOnly: false });
|
|
44
|
-
const [value, setValue] = useState(workspaces.find(w => w.id === chat.get('workspace')?.id));
|
|
45
|
-
// const listFavorites = workspaceAiClient.workspacesAi.useQuery({ visibility: 'favorite' })
|
|
46
|
-
// const [addFavorite, pendingAddFav] = workspaceAiClient.addFavoriteWorkspaceAi.useMutation()
|
|
47
|
-
// const [removeFavorite, pendingRemoveFav] = workspaceAiClient.removeFavoriteWorkspaceAi.useMutation()
|
|
48
|
-
// const onAddFavorite = async(idOrSlug: string) => {
|
|
49
|
-
// try {
|
|
50
|
-
// await addFavorite({ workspaceId: idOrSlug })
|
|
51
|
-
// await workspaceAiClient.workspacesAi.invalidate()
|
|
52
|
-
// } catch (error) {
|
|
53
|
-
// // eslint-disable-next-line no-console
|
|
54
|
-
// console.error(error)
|
|
55
|
-
// }
|
|
56
|
-
// }
|
|
57
|
-
// const onRemoveFavorite = async(idOrSlug: string) => {
|
|
58
|
-
// try {
|
|
59
|
-
// await removeFavorite({ workspaceId: idOrSlug })
|
|
60
|
-
// await workspaceAiClient.workspacesAi.invalidate()
|
|
61
|
-
// } catch (error) {
|
|
62
|
-
// // eslint-disable-next-line no-console
|
|
63
|
-
// console.error(error)
|
|
64
|
-
// }
|
|
65
|
-
// }
|
|
66
|
-
const filtered = useMemo(
|
|
67
|
-
// Recreate the list so that the favorites list is taken into account
|
|
68
|
-
() => filter ? workspaces.filter(w => w === value || w.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase())) : workspaces, [workspaces, filter, value]);
|
|
69
|
-
function submit() {
|
|
70
|
-
if (value)
|
|
71
|
-
chat.set('workspace', { id: value.id, label: value.name });
|
|
72
|
-
close();
|
|
73
|
-
}
|
|
74
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "content", children: [_jsx(IconInput, { icon: _jsx(Search, {}), value: filter, onChange: setFilter, className: "search" }), !!filtered.length && _jsx(DescribedRadioGroup, { options: filtered, keygen: w => w.id, value: value, onChange: setValue, renderLabel: w => w.name, renderDescription: w => w.description, optionClassName: w => (w === value && filter && !w.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase()))
|
|
75
|
-
? 'filtered-out'
|
|
76
|
-
: '', className: "option-list" }), !!workspaces.length && !filtered.length &&
|
|
77
|
-
_jsx(Placeholder, { title: t.noSearchResults, description: t.noSearchResultsDescription, className: "no-data-placeholder" }), !workspaces.length && _jsx(Placeholder, { title: t.noData, description: t.noDataDescription })] }), !!filtered.length && _jsx(Button, { onClick: submit, disabled: !value, children: t.apply })] }));
|
|
78
|
-
};
|
|
79
|
-
const dictionary = {
|
|
80
|
-
en: {
|
|
81
|
-
title: 'Workspaces',
|
|
82
|
-
description: 'By selecting a workspace, its Knowledge Sources (KSs) will be consulted to generate the answers.',
|
|
83
|
-
apply: 'Apply',
|
|
84
|
-
noSearchResults: "Your search didn't yield results.",
|
|
85
|
-
noSearchResultsDescription: 'Please, try another search term.',
|
|
86
|
-
noData: 'There are no workspaces yet.',
|
|
87
|
-
noDataDescription: 'Use the AI portal to create new workspaces.',
|
|
88
|
-
all: 'All',
|
|
89
|
-
favorites: 'Favorites',
|
|
90
|
-
},
|
|
91
|
-
pt: {
|
|
92
|
-
title: 'Workspaces',
|
|
93
|
-
description: 'Ao selecionar um workspace, seus Knowledge Sources (KSs) serão consultados para gerar as respostas.',
|
|
94
|
-
apply: 'Aplicar',
|
|
95
|
-
noSearchResults: 'Sua busca não produziu resultados',
|
|
96
|
-
noSearchResultsDescription: 'Por favor, tente outra busca.',
|
|
97
|
-
noData: 'Ainda não há workspace.',
|
|
98
|
-
noDataDescription: 'Use o Portal AI para criar novos workspaces.',
|
|
99
|
-
all: 'Todos',
|
|
100
|
-
favorites: 'Favoritos',
|
|
101
|
-
},
|
|
102
|
-
};
|
|
103
|
-
//# sourceMappingURL=Workspaces.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Workspaces.js","sourceRoot":"","sources":["../../src/views/Workspaces.tsx"],"names":[],"mappings":"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"}
|
package/src/views/Workspaces.tsx
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { Button } from '@citric/core'
|
|
2
|
-
import { Search } from '@citric/icons'
|
|
3
|
-
import { Placeholder } from '@stack-spot/portal-components/Placeholder'
|
|
4
|
-
import { workspaceClient } from '@stack-spot/portal-network'
|
|
5
|
-
import { WorkspaceReadResponse } from '@stack-spot/portal-network/api/workspace'
|
|
6
|
-
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
7
|
-
import { useEffect, useMemo, useState } from 'react'
|
|
8
|
-
import { DescribedRadioGroup } from '../components/form/DescribedRadioGroup'
|
|
9
|
-
import { IconInput } from '../components/IconInput'
|
|
10
|
-
import { RightPanelTabs } from '../components/RightPanelTabs'
|
|
11
|
-
import { useCurrentChat, useWidget, useWidgetState } from '../context/hooks'
|
|
12
|
-
import { useRightPanel } from '../right-panel/hooks'
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Renders the Workspace selection form in the Right Panel if this is the panel that is currently opened.
|
|
16
|
-
*/
|
|
17
|
-
export const Workspaces = () => {
|
|
18
|
-
const t = useTranslate(dictionary)
|
|
19
|
-
const panel = useWidgetState('panel')
|
|
20
|
-
const { open } = useRightPanel()
|
|
21
|
-
const widget = useWidget()
|
|
22
|
-
const chat = useCurrentChat()
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
if (panel === 'workspace') open(
|
|
26
|
-
<WorkspacesPanel key={chat.id} />,
|
|
27
|
-
{ title: t.title, description: t.description, onClose: () => widget.set('panel', undefined) },
|
|
28
|
-
)
|
|
29
|
-
}, [panel, t, chat.id])
|
|
30
|
-
return null
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const WorkspacesPanel = () => {
|
|
34
|
-
const t = useTranslate(dictionary)
|
|
35
|
-
const chat = useCurrentChat()
|
|
36
|
-
|
|
37
|
-
return <RightPanelTabs key={chat.id} tabs={[
|
|
38
|
-
// { title: t.favorites, content: <WorkspaceSourcesTab key="favorite" visibility="favorite" /> },
|
|
39
|
-
{ title: t.all, content: <WorkspaceSourcesTab key="all" /> },
|
|
40
|
-
]}
|
|
41
|
-
/>
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const WorkspaceSourcesTab = () => {
|
|
45
|
-
const t = useTranslate(dictionary)
|
|
46
|
-
const { close } = useRightPanel()
|
|
47
|
-
const chat = useCurrentChat()
|
|
48
|
-
const [filter, setFilter] = useState('')
|
|
49
|
-
// const workspaces = workspaceAiClient.workspacesAi.useQuery({ visibility })
|
|
50
|
-
// const [value, setValue] = useState<WorkspaceResponse | undefined>(workspaces.find(w => w.id === chat.get('workspace')?.id))
|
|
51
|
-
const workspaces = workspaceClient.workspaces.useQuery({ aclOnly: false })
|
|
52
|
-
|
|
53
|
-
const [value, setValue] = useState<WorkspaceReadResponse | undefined>(workspaces.find(w => w.id === chat.get('workspace')?.id))
|
|
54
|
-
// const listFavorites = workspaceAiClient.workspacesAi.useQuery({ visibility: 'favorite' })
|
|
55
|
-
|
|
56
|
-
// const [addFavorite, pendingAddFav] = workspaceAiClient.addFavoriteWorkspaceAi.useMutation()
|
|
57
|
-
// const [removeFavorite, pendingRemoveFav] = workspaceAiClient.removeFavoriteWorkspaceAi.useMutation()
|
|
58
|
-
|
|
59
|
-
// const onAddFavorite = async(idOrSlug: string) => {
|
|
60
|
-
// try {
|
|
61
|
-
// await addFavorite({ workspaceId: idOrSlug })
|
|
62
|
-
// await workspaceAiClient.workspacesAi.invalidate()
|
|
63
|
-
// } catch (error) {
|
|
64
|
-
// // eslint-disable-next-line no-console
|
|
65
|
-
// console.error(error)
|
|
66
|
-
// }
|
|
67
|
-
// }
|
|
68
|
-
// const onRemoveFavorite = async(idOrSlug: string) => {
|
|
69
|
-
// try {
|
|
70
|
-
// await removeFavorite({ workspaceId: idOrSlug })
|
|
71
|
-
// await workspaceAiClient.workspacesAi.invalidate()
|
|
72
|
-
// } catch (error) {
|
|
73
|
-
// // eslint-disable-next-line no-console
|
|
74
|
-
// console.error(error)
|
|
75
|
-
// }
|
|
76
|
-
// }
|
|
77
|
-
|
|
78
|
-
const filtered = useMemo(
|
|
79
|
-
// Recreate the list so that the favorites list is taken into account
|
|
80
|
-
() => filter ? workspaces.filter(w => w === value || w.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase())) : workspaces,
|
|
81
|
-
[workspaces, filter, value],
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
function submit() {
|
|
85
|
-
if (value) chat.set('workspace', { id: value.id, label: value.name })
|
|
86
|
-
close()
|
|
87
|
-
}
|
|
88
|
-
return (
|
|
89
|
-
<>
|
|
90
|
-
<div className="content">
|
|
91
|
-
<IconInput icon={<Search />} value={filter} onChange={setFilter} className="search" />
|
|
92
|
-
{!!filtered.length && <DescribedRadioGroup
|
|
93
|
-
options={filtered}
|
|
94
|
-
keygen={w => w.id}
|
|
95
|
-
value={value}
|
|
96
|
-
onChange={setValue}
|
|
97
|
-
renderLabel={w => w.name}
|
|
98
|
-
renderDescription={w => w.description}
|
|
99
|
-
optionClassName={w => (w === value && filter && !w.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase()))
|
|
100
|
-
? 'filtered-out'
|
|
101
|
-
: ''
|
|
102
|
-
}
|
|
103
|
-
className="option-list"
|
|
104
|
-
/>}
|
|
105
|
-
{!!workspaces.length && !filtered.length &&
|
|
106
|
-
<Placeholder title={t.noSearchResults} description={t.noSearchResultsDescription} className="no-data-placeholder" />}
|
|
107
|
-
{!workspaces.length && <Placeholder title={t.noData} description={t.noDataDescription} />}
|
|
108
|
-
</div>
|
|
109
|
-
{!!filtered.length && <Button onClick={submit} disabled={!value}>{t.apply}</Button>}
|
|
110
|
-
</>
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const dictionary = {
|
|
115
|
-
en: {
|
|
116
|
-
title: 'Workspaces',
|
|
117
|
-
description: 'By selecting a workspace, its Knowledge Sources (KSs) will be consulted to generate the answers.',
|
|
118
|
-
apply: 'Apply',
|
|
119
|
-
noSearchResults: "Your search didn't yield results.",
|
|
120
|
-
noSearchResultsDescription: 'Please, try another search term.',
|
|
121
|
-
noData: 'There are no workspaces yet.',
|
|
122
|
-
noDataDescription: 'Use the AI portal to create new workspaces.',
|
|
123
|
-
all: 'All',
|
|
124
|
-
favorites: 'Favorites',
|
|
125
|
-
},
|
|
126
|
-
pt: {
|
|
127
|
-
title: 'Workspaces',
|
|
128
|
-
description: 'Ao selecionar um workspace, seus Knowledge Sources (KSs) serão consultados para gerar as respostas.',
|
|
129
|
-
apply: 'Aplicar',
|
|
130
|
-
noSearchResults: 'Sua busca não produziu resultados',
|
|
131
|
-
noSearchResultsDescription: 'Por favor, tente outra busca.',
|
|
132
|
-
noData: 'Ainda não há workspace.',
|
|
133
|
-
noDataDescription: 'Use o Portal AI para criar novos workspaces.',
|
|
134
|
-
all: 'Todos',
|
|
135
|
-
favorites: 'Favoritos',
|
|
136
|
-
},
|
|
137
|
-
} satisfies Dictionary
|