@stack-spot/ai-chat-widget 1.20.2-beta.0 → 1.20.2-beta.10
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/app-metadata.json +6 -6
- package/dist/components/ProgressBar.d.ts +5 -1
- package/dist/components/ProgressBar.d.ts.map +1 -1
- package/dist/components/ProgressBar.js +8 -8
- package/dist/components/ProgressBar.js.map +1 -1
- package/dist/components/Selector/index.d.ts +1 -1
- package/dist/components/Selector/index.d.ts.map +1 -1
- package/dist/components/Selector/index.js +4 -4
- package/dist/components/Selector/index.js.map +1 -1
- package/dist/layout.css +2 -1
- package/dist/views/Agents/AgentDescription.d.ts +2 -2
- package/dist/views/Agents/AgentDescription.d.ts.map +1 -1
- package/dist/views/Agents/AgentDescription.js +1 -3
- package/dist/views/Agents/AgentDescription.js.map +1 -1
- package/dist/views/Agents/AgentsPanel.d.ts.map +1 -1
- package/dist/views/Agents/AgentsPanel.js +2 -2
- package/dist/views/Agents/AgentsPanel.js.map +1 -1
- package/dist/views/Agents/AgentsTab.d.ts.map +1 -1
- package/dist/views/Agents/AgentsTab.js +5 -16
- package/dist/views/Agents/AgentsTab.js.map +1 -1
- package/dist/views/Agents/useAgentFavorites.d.ts +1 -1
- package/dist/views/Agents/useAgentFavorites.js +3 -3
- package/dist/views/Agents/useAgentFavorites.js.map +1 -1
- package/dist/views/Chat/ChatMessage.d.ts +2 -2
- package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
- package/dist/views/Chat/ChatMessage.js +14 -10
- package/dist/views/Chat/ChatMessage.js.map +1 -1
- package/dist/views/Chat/styled.d.ts.map +1 -1
- package/dist/views/Chat/styled.js +10 -4
- package/dist/views/Chat/styled.js.map +1 -1
- package/dist/views/ChatHistory/utils.d.ts.map +1 -1
- package/dist/views/ChatHistory/utils.js +3 -13
- package/dist/views/ChatHistory/utils.js.map +1 -1
- package/dist/views/MessageInput/AgentSelector.d.ts.map +1 -1
- package/dist/views/MessageInput/AgentSelector.js +11 -19
- package/dist/views/MessageInput/AgentSelector.js.map +1 -1
- package/dist/views/MessageInput/ButtonAgent.d.ts.map +1 -1
- package/dist/views/MessageInput/ButtonAgent.js +3 -4
- package/dist/views/MessageInput/ButtonAgent.js.map +1 -1
- package/dist/views/MessageInput/ButtonBar.d.ts +17 -0
- package/dist/views/MessageInput/ButtonBar.d.ts.map +1 -0
- package/dist/views/MessageInput/ButtonBar.js +16 -0
- package/dist/views/MessageInput/ButtonBar.js.map +1 -0
- package/dist/views/MessageInput/InfoBar.d.ts.map +1 -1
- package/dist/views/MessageInput/InfoBar.js +2 -2
- package/dist/views/MessageInput/InfoBar.js.map +1 -1
- package/dist/views/MessageInput/SelectContent.d.ts +2 -0
- package/dist/views/MessageInput/SelectContent.d.ts.map +1 -0
- package/dist/views/MessageInput/SelectContent.js +48 -0
- package/dist/views/MessageInput/SelectContent.js.map +1 -0
- package/dist/views/MessageInput/dictionary.js +2 -2
- package/dist/views/MessageInput/dictionary.js.map +1 -1
- package/dist/views/MessageInput/index.d.ts.map +1 -1
- package/dist/views/MessageInput/index.js +4 -8
- package/dist/views/MessageInput/index.js.map +1 -1
- package/dist/views/MessageInput/styled.d.ts +6 -1
- package/dist/views/MessageInput/styled.d.ts.map +1 -1
- package/dist/views/MessageInput/styled.js +60 -22
- package/dist/views/MessageInput/styled.js.map +1 -1
- package/package.json +1 -1
- package/src/app-metadata.json +2 -2
- package/src/components/ProgressBar.tsx +3 -3
- package/src/layout.css +2 -1
- package/src/views/Chat/ChatMessage.tsx +45 -16
- package/src/views/Chat/styled.ts +10 -4
- package/src/views/MessageInput/ButtonBar.tsx +2 -2
- package/src/views/MessageInput/SelectContent.tsx +45 -12
- package/src/views/MessageInput/styled.ts +19 -21
- package/dist/utils/agent.d.ts +0 -2
- package/dist/utils/agent.d.ts.map +0 -1
- package/dist/utils/agent.js +0 -2
- package/dist/utils/agent.js.map +0 -1
- package/dist/views/MessageInput/ButtonGroup.d.ts +0 -29
- package/dist/views/MessageInput/ButtonGroup.d.ts.map +0 -1
- package/dist/views/MessageInput/ButtonGroup.js +0 -34
- package/dist/views/MessageInput/ButtonGroup.js.map +0 -1
|
@@ -1,17 +1,58 @@
|
|
|
1
1
|
import { IconButton } from '@citric/ui';
|
|
2
2
|
import { theme } from '@stack-spot/portal-theme';
|
|
3
3
|
import { styled } from 'styled-components';
|
|
4
|
-
const INFO_BAR_HEIGHT =
|
|
4
|
+
const INFO_BAR_HEIGHT = 38;
|
|
5
5
|
const INFO_BAR_DISPLACEMENT = 4;
|
|
6
6
|
export const MAX_INPUT_HEIGHT = 300;
|
|
7
7
|
export const MIN_INPUT_HEIGHT = 24;
|
|
8
|
+
export const SelectionBarWrapper = styled.div `
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
justify-content: space-between;
|
|
11
|
+
position: relative;
|
|
12
|
+
padding: 8px;
|
|
13
|
+
background-color: ${theme.color.light[500]};
|
|
14
|
+
border-bottom-left-radius: 4px;
|
|
15
|
+
border-bottom-right-radius: 4px;
|
|
16
|
+
border: 2px solid ${({ $inputFocused }) => theme.color.light[$inputFocused ? 600 : 500]};
|
|
17
|
+
border-top: none;
|
|
18
|
+
|
|
19
|
+
.selection-list {
|
|
20
|
+
opacity: 0;
|
|
21
|
+
transition: height 0.4s, opacity 0.3s;
|
|
22
|
+
}
|
|
23
|
+
.visible {
|
|
24
|
+
opacity: 1;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.selection-list-content {
|
|
28
|
+
background-color: ${theme.color.light[500]};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
ul {
|
|
32
|
+
list-style: none;
|
|
33
|
+
padding: 0;
|
|
34
|
+
margin: 12px;
|
|
35
|
+
min-width: 225px;
|
|
36
|
+
}
|
|
37
|
+
li {
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
svg {
|
|
40
|
+
width: 16px;
|
|
41
|
+
height: 16px;
|
|
42
|
+
}
|
|
43
|
+
&:hover {
|
|
44
|
+
background-color: ${theme.color.light[600]}
|
|
45
|
+
}
|
|
46
|
+
a:hover {
|
|
47
|
+
background-color: ${theme.color.light[600]}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
8
51
|
export const MessageInputBox = styled.div `
|
|
9
52
|
display: flex;
|
|
10
53
|
flex-direction: column;
|
|
11
54
|
|
|
12
55
|
> .info-bar {
|
|
13
|
-
margin-top: 8px;
|
|
14
|
-
margin-bottom: -3px;
|
|
15
56
|
position: relative;
|
|
16
57
|
overflow: hidden;
|
|
17
58
|
|
|
@@ -31,14 +72,14 @@ export const MessageInputBox = styled.div `
|
|
|
31
72
|
top: 0;
|
|
32
73
|
left: 0;
|
|
33
74
|
right: 0;
|
|
34
|
-
border-top-left-radius: 10px;
|
|
35
|
-
border-top-right-radius: 10px;
|
|
36
75
|
height: ${INFO_BAR_HEIGHT}px;
|
|
37
|
-
padding:
|
|
76
|
+
padding-top: 8px;
|
|
38
77
|
background-color: ${theme.color.light[500]};
|
|
39
78
|
display: flex;
|
|
40
79
|
flex-direction: row;
|
|
41
|
-
gap:
|
|
80
|
+
gap: 4px;
|
|
81
|
+
border-right: 2px solid ${({ $inputFocused }) => theme.color.light[$inputFocused ? 600 : 500]};
|
|
82
|
+
border-left: 2px solid ${({ $inputFocused }) => theme.color.light[$inputFocused ? 600 : 500]};
|
|
42
83
|
|
|
43
84
|
.list-overflow {
|
|
44
85
|
max-width: calc(100% - 30px); // close button + gap
|
|
@@ -91,16 +132,19 @@ export const MessageInputBox = styled.div `
|
|
|
91
132
|
flex-direction: row;
|
|
92
133
|
gap: 8px;
|
|
93
134
|
align-items: end;
|
|
94
|
-
border-radius: 4px;
|
|
95
|
-
border:
|
|
96
|
-
|
|
135
|
+
border-top-left-radius: 4px;
|
|
136
|
+
border-top-right-radius: 4px;
|
|
137
|
+
border: 2px solid ${theme.color.light[500]};
|
|
138
|
+
|
|
139
|
+
background-color: ${theme.color.light[500]};
|
|
97
140
|
padding: 10px 8px;
|
|
98
141
|
transition: border-color 0.3s, background-color 0.3s;
|
|
99
142
|
|
|
100
143
|
&.focused {
|
|
101
|
-
border
|
|
144
|
+
border: 2px solid ${theme.color.light[600]};
|
|
102
145
|
}
|
|
103
146
|
|
|
147
|
+
|
|
104
148
|
&.disabled {
|
|
105
149
|
background-color: ${theme.color.light[500]};
|
|
106
150
|
}
|
|
@@ -119,18 +163,12 @@ export const MessageInputBox = styled.div `
|
|
|
119
163
|
button {
|
|
120
164
|
border: none;
|
|
121
165
|
border-radius: 2px;
|
|
122
|
-
opacity: 0.6;
|
|
166
|
+
/* opacity: 0.6; */
|
|
123
167
|
transition: background-color 0.2s, opacity 0.2s;
|
|
124
|
-
background-color: transparent;
|
|
168
|
+
/* background-color: transparent; */
|
|
125
169
|
padding: 0;
|
|
126
170
|
|
|
127
|
-
|
|
128
|
-
fill: ${theme.color.light[700]};
|
|
129
|
-
width: 16px;
|
|
130
|
-
height: 16px;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
&:hover {
|
|
171
|
+
/* &:hover {
|
|
134
172
|
background-color: ${theme.color.light[500]};
|
|
135
173
|
}
|
|
136
174
|
|
|
@@ -141,7 +179,7 @@ export const MessageInputBox = styled.div `
|
|
|
141
179
|
}
|
|
142
180
|
svg {
|
|
143
181
|
fill: ${theme.color.inverse.contrastText};
|
|
144
|
-
}
|
|
182
|
+
}
|
|
145
183
|
}
|
|
146
184
|
|
|
147
185
|
&.expand {
|
|
@@ -154,7 +192,7 @@ export const MessageInputBox = styled.div `
|
|
|
154
192
|
svg {
|
|
155
193
|
transform: rotate(180deg);
|
|
156
194
|
}
|
|
157
|
-
}
|
|
195
|
+
} */
|
|
158
196
|
|
|
159
197
|
&.agent {
|
|
160
198
|
border-radius: 50%;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styled.js","sourceRoot":"","sources":["../../../src/views/MessageInput/styled.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE1C,MAAM,eAAe,GAAG,EAAE,CAAA;AAC1B,MAAM,qBAAqB,GAAG,CAAC,CAAA;AAC/B,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA;AACnC,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAElC,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"styled.js","sourceRoot":"","sources":["../../../src/views/MessageInput/styled.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE1C,MAAM,eAAe,GAAG,EAAE,CAAA;AAC1B,MAAM,qBAAqB,GAAG,CAAC,CAAA;AAC/B,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA;AACnC,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAElC,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAA2B;;;;;sBAKlD,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;sBAGtB,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;;;;;;;;;;;;wBAYjE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;0BAgBpB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;0BAGtB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;CAG/C,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAA2B;;;;;;;;;;kBAUlD,eAAe,GAAG,qBAAqB;;;;;;;;;;;;;;gBAczC,eAAe;;0BAEL,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;;gCAIhB,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;+BACpE,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4BxF,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;0BA2BM,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;0BAEtB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;;;4BAKpB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;;;4BAKtB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;4BAuBtB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;;4BAItB,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;;;;;kBAKlC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAuD5C,UAAU;;;;;;;;;;;;;;8BAcc,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;8BACtB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;;;;;;gCAQpB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;;;;;;;oBAOlC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;cAoBpC,gBAAgB;;;;;;;;CAQ7B,CAAA"}
|
package/package.json
CHANGED
package/src/app-metadata.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stack-spot/ai-chat-widget",
|
|
3
|
-
"version": "1.20.2",
|
|
4
|
-
"date": "
|
|
3
|
+
"version": "1.20.2-beta.10",
|
|
4
|
+
"date": "Mon May 19 2025 15:28:06 GMT-0300 (Horário Padrão de Brasília)",
|
|
5
5
|
"dependencies": [
|
|
6
6
|
{
|
|
7
7
|
"name": "@stack-spot/app-metadata",
|
|
@@ -129,15 +129,15 @@ const Styled = styled.div<{ $bg: string[], $fg: string[], $shimmer: string[], $a
|
|
|
129
129
|
&:before {
|
|
130
130
|
content: '';
|
|
131
131
|
display: block;
|
|
132
|
-
width:
|
|
132
|
+
width: 100%;
|
|
133
133
|
height: 100%;
|
|
134
134
|
background: ${({ $fg, $animate, $bg }) => $animate ? gradientFromColorArray($fg) : $bg};
|
|
135
|
-
animation: ${({ $animate }) => $animate ? 'slide
|
|
135
|
+
animation: ${({ $animate }) => $animate ? 'slide .5s infinite forwards' : 'none'};
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
@keyframes slide {
|
|
139
139
|
from {
|
|
140
|
-
margin-left: -
|
|
140
|
+
margin-left: -100%;
|
|
141
141
|
}
|
|
142
142
|
to {
|
|
143
143
|
margin-left: 100%;
|
package/src/layout.css
CHANGED
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
background-color: var(--light-400);
|
|
32
32
|
border-radius: 4px;
|
|
33
33
|
position: relative;
|
|
34
|
-
overflow: hidden;
|
|
35
34
|
width: 100%;
|
|
36
35
|
height: 100%;
|
|
37
36
|
|
|
@@ -104,11 +103,13 @@
|
|
|
104
103
|
}
|
|
105
104
|
|
|
106
105
|
.chat-content {
|
|
106
|
+
padding-bottom: 16px;
|
|
107
107
|
display: flex;
|
|
108
108
|
flex-direction: column;
|
|
109
109
|
flex: 1;
|
|
110
110
|
flex-basis: 0;
|
|
111
111
|
overflow: auto;
|
|
112
|
+
padding-right: 12px;
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
.chat-right-panel {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Box, Button, Checkbox, Flex, IconBox, Input, Label, Radio, Text } from '@citric/core'
|
|
2
2
|
import { Cog, Copy, Dislike, DislikeFill, Like, LikeFill, TimesCircle } from '@citric/icons'
|
|
3
|
-
import {
|
|
3
|
+
import { Badge, IconButton } from '@citric/ui'
|
|
4
4
|
import { agentClient } from '@stack-spot/portal-network'
|
|
5
5
|
import { listToClass } from '@stack-spot/portal-theme'
|
|
6
6
|
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
@@ -37,7 +37,7 @@ interface Props extends CustomMessage {
|
|
|
37
37
|
/**
|
|
38
38
|
* The name of the user currently logged in (will be used if the agent type of the message is "user").
|
|
39
39
|
*/
|
|
40
|
-
username
|
|
40
|
+
username?: string,
|
|
41
41
|
/**
|
|
42
42
|
* Whether or not this is the last message in the chat. This is important for disabling action buttons in messages that are no longer
|
|
43
43
|
* relevant.
|
|
@@ -169,14 +169,15 @@ const RenderInputsEntry = ({ isLast, entry, value, setValue, labels, setLabels }
|
|
|
169
169
|
/**
|
|
170
170
|
* Renders a message (ChatEntry) in the chat.
|
|
171
171
|
*/
|
|
172
|
-
export const ChatMessage = ({ message,
|
|
172
|
+
export const ChatMessage = ({ message, isLast, beforeMessage, afterMessage }: Props) => {
|
|
173
173
|
const t = useTranslate(dictionary)
|
|
174
174
|
const [liked, setLiked] = useState<boolean | undefined>()
|
|
175
175
|
const [value, setValue] = useState<string[]>(message.getValue()?.initialValue ?? [])
|
|
176
176
|
const [labels, setLabels] = useState<string[]>(message.getValue()?.initialValue ?? [])
|
|
177
177
|
const entry = useChatEntry(message)
|
|
178
178
|
const dateFormatter = useDateFormatter()
|
|
179
|
-
const userInfo = entry.agentType === 'user' ? <Avatar size="xs">{username}</Avatar> : <AgentInfo agent={entry.agent} />
|
|
179
|
+
// const userInfo = entry.agentType === 'user' ? <Avatar size="xs">{username}</Avatar> : <AgentInfo agent={entry.agent} />
|
|
180
|
+
const userInfo = entry.agentType === 'user' ? <></> : <AgentInfo agent={entry.agent} />
|
|
180
181
|
const date = new Date(entry.updated ?? '')
|
|
181
182
|
const shouldShowFooter = entry.updated && !isNaN(date.getTime())
|
|
182
183
|
const ref = useRef<HTMLLIElement>(null)
|
|
@@ -185,7 +186,8 @@ export const ChatMessage = ({ message, username, isLast, beforeMessage, afterMes
|
|
|
185
186
|
const chat = useCurrentChat()
|
|
186
187
|
const agentId = entry.agent?.id ?? ''
|
|
187
188
|
const [agent] = agentClient.agentById.useStatefulQuery({ agentId, builtIn: !!entry?.agent?.builtIn }, { enabled: !!agentId })
|
|
188
|
-
|
|
189
|
+
const [copied, setCopied] = useState(false)
|
|
190
|
+
|
|
189
191
|
useChatScrollToBottomEffect(ref, [entry])
|
|
190
192
|
|
|
191
193
|
const detailKS = useCallback(({ name, slug, documentScore, documentId }: Required<TextChatEntry>['knowledgeSources'][number]) => {
|
|
@@ -250,6 +252,12 @@ export const ChatMessage = ({ message, username, isLast, beforeMessage, afterMes
|
|
|
250
252
|
)}
|
|
251
253
|
</>, [entry, isLast, runAction])
|
|
252
254
|
|
|
255
|
+
const handleCopy = () => {
|
|
256
|
+
onCopyAll(entry, chat)
|
|
257
|
+
setCopied(true)
|
|
258
|
+
setTimeout(() => setCopied(false), 1000)
|
|
259
|
+
}
|
|
260
|
+
|
|
253
261
|
const renderContent = () => {
|
|
254
262
|
if (entry.type === 'md') {
|
|
255
263
|
return <>
|
|
@@ -257,13 +265,7 @@ export const ChatMessage = ({ message, username, isLast, beforeMessage, afterMes
|
|
|
257
265
|
{renderActions()}
|
|
258
266
|
</>
|
|
259
267
|
}
|
|
260
|
-
|
|
261
|
-
return <>
|
|
262
|
-
<p className="plain-text">{entry.content}</p>
|
|
263
|
-
{renderActions()}
|
|
264
|
-
</>
|
|
265
|
-
}
|
|
266
|
-
|
|
268
|
+
|
|
267
269
|
return <form>
|
|
268
270
|
<RenderInputsEntry entry={entry} isLast={isLast} value={value} setValue={setValue} setLabels={setLabels} labels={labels} />
|
|
269
271
|
<Box mt="4">
|
|
@@ -322,22 +324,47 @@ export const ChatMessage = ({ message, username, isLast, beforeMessage, afterMes
|
|
|
322
324
|
{shouldShowFooter && <div className="message-footer">
|
|
323
325
|
{entry.agentType === 'bot' && !entry.error && <div className="message-actions">
|
|
324
326
|
{entry.type === 'md' && (
|
|
325
|
-
<IconButton title={t.copy} aria-label={t.copy} onClick={
|
|
327
|
+
<IconButton appearance="square" color="light" title={t.copy} aria-label={t.copy} onClick={handleCopy}>
|
|
326
328
|
<Copy />
|
|
329
|
+
{copied && (
|
|
330
|
+
<div style={{ fontSize: 12, marginLeft: 4 }}>
|
|
331
|
+
<Text appearance="microtext1" colorScheme="light.700">{t.copied}</Text>
|
|
332
|
+
</div>
|
|
333
|
+
)}
|
|
327
334
|
</IconButton>
|
|
328
335
|
)}
|
|
329
336
|
{entry.messageId && (
|
|
330
337
|
<>
|
|
331
|
-
<IconButton title={t.like} aria-label={t.like} onClick={like}>
|
|
338
|
+
<IconButton appearance="square" color="light" title={t.like} aria-label={t.like} onClick={like}>
|
|
332
339
|
{liked === true ? <LikeFill /> : <Like />}
|
|
333
340
|
</IconButton>
|
|
334
|
-
<IconButton title={t.dislike} aria-label={t.dislike} onClick={dislike}>
|
|
341
|
+
<IconButton appearance="square" color="light" title={t.dislike} aria-label={t.dislike} onClick={dislike}>
|
|
335
342
|
{liked === false ? <DislikeFill /> : <Dislike />}
|
|
336
343
|
</IconButton>
|
|
337
344
|
</>
|
|
338
345
|
)}
|
|
339
346
|
</div>}
|
|
340
|
-
|
|
347
|
+
|
|
348
|
+
{entry.agentType === 'user' && (
|
|
349
|
+
<div className="message-actions">
|
|
350
|
+
<IconButton
|
|
351
|
+
appearance="square"
|
|
352
|
+
color="light"
|
|
353
|
+
title={t.copy}
|
|
354
|
+
aria-label={t.copy}
|
|
355
|
+
onClick={handleCopy}
|
|
356
|
+
size="sm"
|
|
357
|
+
>
|
|
358
|
+
<Copy />
|
|
359
|
+
{copied && (
|
|
360
|
+
<div style={{ fontSize: 12, marginLeft: 4 }}>
|
|
361
|
+
<Text appearance="microtext1" colorScheme="light.700">{t.copied}</Text>
|
|
362
|
+
</div>
|
|
363
|
+
)}
|
|
364
|
+
</IconButton>
|
|
365
|
+
</div>
|
|
366
|
+
)}
|
|
367
|
+
<Text as="label" appearance="microtext1" className="chat-date">
|
|
341
368
|
{dateFormatter.formatForChatMessage(date)}
|
|
342
369
|
</Text>
|
|
343
370
|
</div>}
|
|
@@ -352,6 +379,7 @@ const dictionary = {
|
|
|
352
379
|
dislike: 'Dislike',
|
|
353
380
|
tools: 'Tools',
|
|
354
381
|
openToolsPanel: 'Open the tools panel to see more details.',
|
|
382
|
+
copied: 'Copied',
|
|
355
383
|
},
|
|
356
384
|
pt: {
|
|
357
385
|
copy: 'Copiar',
|
|
@@ -359,5 +387,6 @@ const dictionary = {
|
|
|
359
387
|
dislike: 'Não gostei',
|
|
360
388
|
tools: 'Ferramentas',
|
|
361
389
|
openToolsPanel: 'Abrir o painel de ferramentas para ver mais detalhes.',
|
|
390
|
+
copied: 'Copiado',
|
|
362
391
|
},
|
|
363
392
|
} satisfies Dictionary
|
package/src/views/Chat/styled.ts
CHANGED
|
@@ -11,7 +11,8 @@ export const ChatList: IStyledComponentBase<
|
|
|
11
11
|
flex-direction: column;
|
|
12
12
|
justify-content: end;
|
|
13
13
|
gap: 20px;
|
|
14
|
-
margin: 0 5px;
|
|
14
|
+
/* margin: 0 5px; */
|
|
15
|
+
margin: 0;
|
|
15
16
|
padding: 0;
|
|
16
17
|
flex: 1;
|
|
17
18
|
|
|
@@ -61,14 +62,18 @@ export const ChatList: IStyledComponentBase<
|
|
|
61
62
|
.message-footer {
|
|
62
63
|
display: flex;
|
|
63
64
|
flex-direction: row;
|
|
65
|
+
align-items: center;
|
|
66
|
+
gap: 8px;
|
|
64
67
|
|
|
65
68
|
.message-actions {
|
|
66
69
|
display: flex;
|
|
67
70
|
flex-direction: row;
|
|
68
|
-
gap:
|
|
71
|
+
gap: 4px;
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
.chat-date {
|
|
75
|
+
display: inline-block;
|
|
76
|
+
align-content: flex-end;
|
|
72
77
|
opacity: 0.6;
|
|
73
78
|
margin-left: auto;
|
|
74
79
|
}
|
|
@@ -145,9 +150,10 @@ export const ChatList: IStyledComponentBase<
|
|
|
145
150
|
gap: 8px;
|
|
146
151
|
|
|
147
152
|
.message-content {
|
|
148
|
-
padding:
|
|
153
|
+
padding: 16px;
|
|
154
|
+
border-radius: 24px;
|
|
155
|
+
border-top-right-radius: 0;
|
|
149
156
|
background-color: ${theme.color.light[500]};
|
|
150
|
-
border-radius: 4px;
|
|
151
157
|
|
|
152
158
|
.markdown > p:first-child {
|
|
153
159
|
margin-top: 0;
|
|
@@ -28,8 +28,8 @@ export const ButtonBar = ({ onSend, isLoading, focused }: SelectionBarProps) =>
|
|
|
28
28
|
const features = useCurrentChatState('features')
|
|
29
29
|
|
|
30
30
|
return (
|
|
31
|
-
<SelectionBarWrapper $inputFocused={focused}>
|
|
32
|
-
<Flex>
|
|
31
|
+
<SelectionBarWrapper className="button-group" $inputFocused={focused}>
|
|
32
|
+
<Flex sx={{ gap: '4px' }}>
|
|
33
33
|
<SelectContent />
|
|
34
34
|
{features.editor && (
|
|
35
35
|
<IconButton color="light" appearance="square" aria-label={t.code} title={t.code} onClick={() => widget.set('panel', 'editor')}>
|
|
@@ -1,13 +1,52 @@
|
|
|
1
1
|
import { Clip, KnowledgeSource, Spaces, Stack } from '@citric/icons'
|
|
2
2
|
import { IconButton } from '@citric/ui'
|
|
3
3
|
import { SelectionList } from '@stack-spot/portal-components/SelectionList'
|
|
4
|
-
import { useState } from 'react'
|
|
5
|
-
import { useWidget } from '../../context/hooks'
|
|
4
|
+
import { useMemo, useState } from 'react'
|
|
5
|
+
import { useCurrentChatState, useWidget } from '../../context/hooks'
|
|
6
|
+
|
|
7
|
+
type chatFeatures = 'workspace' | 'knowledgeSource' | 'stack'
|
|
8
|
+
type chatPanel = 'ks' | 'workspace' | 'stack'
|
|
6
9
|
|
|
7
10
|
export const SelectContent = () => {
|
|
8
11
|
const widget = useWidget()
|
|
9
12
|
const [visibleMenu, setVisibleMenu] = useState(false)
|
|
10
|
-
|
|
13
|
+
const features = useCurrentChatState('features')
|
|
14
|
+
const hasFeatureButtons = features.workspace || features.knowledgeSource || features.stack
|
|
15
|
+
|
|
16
|
+
const itemConfigs = [
|
|
17
|
+
{
|
|
18
|
+
key: 'knowledgeSource',
|
|
19
|
+
label: 'Knowledge Sources',
|
|
20
|
+
icon: <KnowledgeSource />,
|
|
21
|
+
panel: 'ks',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
key: 'stack',
|
|
25
|
+
label: 'Stacks AI',
|
|
26
|
+
icon: <Stack />,
|
|
27
|
+
panel: 'stack',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
key: 'workspace',
|
|
31
|
+
label: 'Spots',
|
|
32
|
+
icon: <Spaces />,
|
|
33
|
+
panel: 'workspace',
|
|
34
|
+
},
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
const listItems = useMemo(() =>
|
|
38
|
+
itemConfigs.filter(chatFeatures => features[chatFeatures.key as chatFeatures])
|
|
39
|
+
.map(chatFeatures => ({
|
|
40
|
+
label: chatFeatures.label,
|
|
41
|
+
icon: chatFeatures.icon,
|
|
42
|
+
onClick: () => {
|
|
43
|
+
widget.set('panel', chatFeatures.panel as chatPanel)
|
|
44
|
+
setVisibleMenu(false)
|
|
45
|
+
},
|
|
46
|
+
})), [features, widget])
|
|
47
|
+
|
|
48
|
+
if (!hasFeatureButtons) return null
|
|
49
|
+
|
|
11
50
|
return (
|
|
12
51
|
<>
|
|
13
52
|
<IconButton
|
|
@@ -17,24 +56,18 @@ export const SelectContent = () => {
|
|
|
17
56
|
title="title"
|
|
18
57
|
data-test-hint="button-hint"
|
|
19
58
|
aria-label="aria-label"
|
|
20
|
-
onClick={() => setVisibleMenu(state => !state)}
|
|
59
|
+
onClick={() => setVisibleMenu(state => !state)}>
|
|
21
60
|
<Clip />
|
|
22
61
|
</IconButton>
|
|
23
62
|
<SelectionList
|
|
24
63
|
style={{
|
|
25
64
|
position: 'absolute',
|
|
26
|
-
top: '-
|
|
65
|
+
top: '-140px',
|
|
27
66
|
}}
|
|
28
67
|
id="teste"
|
|
29
68
|
visible={visibleMenu}
|
|
30
69
|
onHide={() => setVisibleMenu(false)}
|
|
31
|
-
items={
|
|
32
|
-
[
|
|
33
|
-
{ label: 'Knowledge Sources', icon: <KnowledgeSource />, onClick: () => widget.set('panel', 'ks') },
|
|
34
|
-
{ label: 'Stacks AI', icon: <Stack />, onClick: () => widget.set('panel', 'stack') },
|
|
35
|
-
{ label: 'Spots', icon: <Spaces />, onClick: () => widget.set('panel', 'workspace') },
|
|
36
|
-
]
|
|
37
|
-
}
|
|
70
|
+
items={listItems}
|
|
38
71
|
/>
|
|
39
72
|
</>
|
|
40
73
|
)
|
|
@@ -2,7 +2,7 @@ import { IconButton } from '@citric/ui'
|
|
|
2
2
|
import { theme } from '@stack-spot/portal-theme'
|
|
3
3
|
import { styled } from 'styled-components'
|
|
4
4
|
|
|
5
|
-
const INFO_BAR_HEIGHT =
|
|
5
|
+
const INFO_BAR_HEIGHT = 38
|
|
6
6
|
const INFO_BAR_DISPLACEMENT = 4
|
|
7
7
|
export const MAX_INPUT_HEIGHT = 300
|
|
8
8
|
export const MIN_INPUT_HEIGHT = 24
|
|
@@ -12,15 +12,24 @@ export const SelectionBarWrapper = styled.div<{$inputFocused?: boolean}>`
|
|
|
12
12
|
justify-content: space-between;
|
|
13
13
|
position: relative;
|
|
14
14
|
padding: 8px;
|
|
15
|
-
padding-top: 6px;
|
|
16
15
|
background-color: ${theme.color.light[500]};
|
|
17
16
|
border-bottom-left-radius: 4px;
|
|
18
17
|
border-bottom-right-radius: 4px;
|
|
19
18
|
border: 2px solid ${({ $inputFocused }) => theme.color.light[$inputFocused ? 600 : 500]};
|
|
20
19
|
border-top: none;
|
|
20
|
+
|
|
21
|
+
.selection-list {
|
|
22
|
+
opacity: 0;
|
|
23
|
+
transition: height 0.4s, opacity 0.3s;
|
|
24
|
+
}
|
|
25
|
+
.visible {
|
|
26
|
+
opacity: 1;
|
|
27
|
+
}
|
|
28
|
+
|
|
21
29
|
.selection-list-content {
|
|
22
|
-
background-color: ${theme.color.light[500]}
|
|
30
|
+
background-color: ${theme.color.light[500]};
|
|
23
31
|
}
|
|
32
|
+
|
|
24
33
|
ul {
|
|
25
34
|
list-style: none;
|
|
26
35
|
padding: 0;
|
|
@@ -45,11 +54,8 @@ export const SelectionBarWrapper = styled.div<{$inputFocused?: boolean}>`
|
|
|
45
54
|
export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
|
|
46
55
|
display: flex;
|
|
47
56
|
flex-direction: column;
|
|
48
|
-
margin-top: 8px;
|
|
49
57
|
|
|
50
58
|
> .info-bar {
|
|
51
|
-
padding-top: 8px;
|
|
52
|
-
/* padding-bottom: -3px; */
|
|
53
59
|
position: relative;
|
|
54
60
|
overflow: hidden;
|
|
55
61
|
|
|
@@ -69,14 +75,12 @@ export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
|
|
|
69
75
|
top: 0;
|
|
70
76
|
left: 0;
|
|
71
77
|
right: 0;
|
|
72
|
-
/* border-top-left-radius: 10px;
|
|
73
|
-
border-top-right-radius: 10px; */
|
|
74
78
|
height: ${INFO_BAR_HEIGHT}px;
|
|
75
|
-
padding:
|
|
79
|
+
padding-top: 8px;
|
|
76
80
|
background-color: ${theme.color.light[500]};
|
|
77
81
|
display: flex;
|
|
78
82
|
flex-direction: row;
|
|
79
|
-
gap:
|
|
83
|
+
gap: 4px;
|
|
80
84
|
border-right: 2px solid ${({ $inputFocused }) => theme.color.light[$inputFocused ? 600 : 500]};
|
|
81
85
|
border-left: 2px solid ${({ $inputFocused }) => theme.color.light[$inputFocused ? 600 : 500]};
|
|
82
86
|
|
|
@@ -162,18 +166,12 @@ export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
|
|
|
162
166
|
button {
|
|
163
167
|
border: none;
|
|
164
168
|
border-radius: 2px;
|
|
165
|
-
opacity: 0.6;
|
|
169
|
+
/* opacity: 0.6; */
|
|
166
170
|
transition: background-color 0.2s, opacity 0.2s;
|
|
167
|
-
background-color: transparent;
|
|
171
|
+
/* background-color: transparent; */
|
|
168
172
|
padding: 0;
|
|
169
173
|
|
|
170
|
-
|
|
171
|
-
fill: ${theme.color.light[700]};
|
|
172
|
-
width: 16px;
|
|
173
|
-
height: 16px;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
&:hover {
|
|
174
|
+
/* &:hover {
|
|
177
175
|
background-color: ${theme.color.light[500]};
|
|
178
176
|
}
|
|
179
177
|
|
|
@@ -184,7 +182,7 @@ export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
|
|
|
184
182
|
}
|
|
185
183
|
svg {
|
|
186
184
|
fill: ${theme.color.inverse.contrastText};
|
|
187
|
-
}
|
|
185
|
+
}
|
|
188
186
|
}
|
|
189
187
|
|
|
190
188
|
&.expand {
|
|
@@ -197,7 +195,7 @@ export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
|
|
|
197
195
|
svg {
|
|
198
196
|
transform: rotate(180deg);
|
|
199
197
|
}
|
|
200
|
-
}
|
|
198
|
+
} */
|
|
201
199
|
|
|
202
200
|
&.agent {
|
|
203
201
|
border-radius: 50%;
|
package/dist/utils/agent.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/utils/agent.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,eAAgB,MAAM,kCAAmC,CAAA"}
|
package/dist/utils/agent.js
DELETED
package/dist/utils/agent.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/utils/agent.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,SAAkB,EAAE,EAAE,CAAC,SAAS,KAAK,gBAAgB,CAAA"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
interface ButtonGroupProps {
|
|
2
|
-
/**
|
|
3
|
-
* Whether or not the button group is expanded.
|
|
4
|
-
*/
|
|
5
|
-
expanded: boolean;
|
|
6
|
-
/**
|
|
7
|
-
* A function to set the button group as expanded or collapsed.
|
|
8
|
-
*/
|
|
9
|
-
setExpanded: React.Dispatch<React.SetStateAction<boolean>>;
|
|
10
|
-
/**
|
|
11
|
-
* Whether or not the message is currently being sent. This is used to decide which button to show: send or cancel.
|
|
12
|
-
*/
|
|
13
|
-
isLoading: boolean;
|
|
14
|
-
/**
|
|
15
|
-
* A function to run when the send button is clicked.
|
|
16
|
-
*/
|
|
17
|
-
onSend: () => void;
|
|
18
|
-
/**
|
|
19
|
-
* A function to run when the cancel button is clicked.
|
|
20
|
-
*/
|
|
21
|
-
onCancel: () => void;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Renders the button group at right bottom side of the message input. This includes the send button as well as the buttons to open the
|
|
25
|
-
* editor, change the stack, etc.
|
|
26
|
-
*/
|
|
27
|
-
export declare const ButtonGroup: ({ onSend, onCancel, expanded, setExpanded, isLoading }: ButtonGroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
28
|
-
export {};
|
|
29
|
-
//# sourceMappingURL=ButtonGroup.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonGroup.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/ButtonGroup.tsx"],"names":[],"mappings":"AAOA,UAAU,gBAAgB;IACxB;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3D;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB;;OAEG;IACH,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,2DAA4D,gBAAgB,4CA0EnG,CAAA"}
|