rio-assist-widget 0.1.10 → 0.1.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rio-assist-widget",
3
- "version": "0.1.10",
3
+ "version": "0.1.14",
4
4
  "description": "Web Component do painel lateral Rio Insight, pronto para ser embutido em qualquer projeto.",
5
5
  "type": "module",
6
6
  "scripts": {
Binary file
@@ -61,6 +61,27 @@ export const conversationsPanelStyles = css`
61
61
  overflow: hidden;
62
62
  }
63
63
 
64
+ .recent-conversations-button {
65
+ display: inline-flex;
66
+ align-items: center;
67
+ gap: 12px;
68
+ padding: 6px 12px 6px 16px;
69
+ border: none;
70
+ background: transparent;
71
+ color: #1f2f36;
72
+ font-family: 'Source Sans Pro', 'Inter', sans-serif;
73
+ font-size: 18px;
74
+ font-weight: 700;
75
+ text-align: left;
76
+ width: calc(100% - 24px);
77
+ cursor: pointer;
78
+ }
79
+
80
+ .recent-conversations-button img {
81
+ width: 24px;
82
+ height: 24px;
83
+ }
84
+
64
85
  .conversation-search {
65
86
  display: flex;
66
87
  align-items: center;
@@ -173,12 +194,14 @@ export const conversationsPanelStyles = css`
173
194
  display: flex;
174
195
  align-items: center;
175
196
  justify-content: space-between;
176
- padding: 0 20px 0 6px;
197
+ padding: 0 40px 0 6px;
177
198
  border-radius: 8px;
178
199
  color: #1f2f36;
179
200
  font-size: 15px;
180
201
  position: relative;
181
202
  height: 40px;
203
+ cursor: pointer;
204
+ transition: color 0.2s ease, background-color 0.2s ease;
182
205
  }
183
206
 
184
207
  .conversations-panel--sidebar .conversation-item {
@@ -199,6 +222,17 @@ export const conversationsPanelStyles = css`
199
222
  .conversation-item__text {
200
223
  flex: 1;
201
224
  padding-right: 16px;
225
+ transition: color 0.2s ease;
226
+ }
227
+
228
+ .conversation-item:hover .conversation-item__text,
229
+ .conversation-item:focus-visible .conversation-item__text {
230
+ color: var(--accent-color, #008b9a);
231
+ }
232
+
233
+ .conversation-item:hover,
234
+ .conversation-item:focus-visible {
235
+ background: rgba(0, 139, 154, 0.08);
202
236
  }
203
237
 
204
238
  .conversation-menu-button {
@@ -210,6 +244,8 @@ export const conversationsPanelStyles = css`
210
244
  display: flex;
211
245
  align-items: center;
212
246
  justify-content: center;
247
+ margin-left: 4px;
248
+ flex-shrink: 0;
213
249
  }
214
250
 
215
251
  .conversation-menu {
@@ -250,6 +286,12 @@ export const conversationsPanelStyles = css`
250
286
  height: 16px;
251
287
  }
252
288
 
289
+ .conversation-loading {
290
+ font-size: 13px;
291
+ color: #4b5b68;
292
+ padding: 6px 12px 2px;
293
+ }
294
+
253
295
  .new-conversation-cta {
254
296
  overflow: hidden;
255
297
  max-height: 0;
@@ -9,6 +9,7 @@ const trashIconUrl = new URL('../../assets/icons/trash.png', import.meta.url).hr
9
9
  const searchIconUrl = new URL('../../assets/icons/searchIcon.png', import.meta.url).href;
10
10
  const plusFileSelectionUrl = new URL('../../assets/icons/plusFileSelection.png', import.meta.url)
11
11
  .href;
12
+ const hamburgerBlack = new URL('../../assets/icons/hamburgerBlack.png', import.meta.url).href;
12
13
 
13
14
  type ConversationsPanelVariant = 'drawer' | 'sidebar';
14
15
 
@@ -84,7 +85,19 @@ const renderConversationSurface = (
84
85
  const menuOpen = component.conversationMenuId === conversation.id;
85
86
 
86
87
  return html`
87
- <div class="conversation-item">
88
+ <div
89
+ class="conversation-item"
90
+ role="button"
91
+ tabindex="0"
92
+ title=${`Recuperar ${conversation.title}`}
93
+ @click=${() => component.handleConversationSelect(conversation.id)}
94
+ @keydown=${(event: KeyboardEvent) => {
95
+ if (event.key === 'Enter' || event.key === ' ') {
96
+ event.preventDefault();
97
+ component.handleConversationSelect(conversation.id);
98
+ }
99
+ }}
100
+ >
88
101
  <div class="conversation-item__text">
89
102
  ${conversation.title}
90
103
  </div>
@@ -135,6 +148,15 @@ const renderConversationSurface = (
135
148
  return html`
136
149
  ${newConversationCta}
137
150
 
151
+ ${isSidebar
152
+ ? html`
153
+ <button class="recent-conversations-button" type="button" aria-label="Conversas recentes">
154
+ <img src=${hamburgerBlack} alt="" aria-hidden="true" />
155
+ <span>Conversas recentes</span>
156
+ </button>
157
+ `
158
+ : null}
159
+
138
160
  <div class="conversation-search">
139
161
  <img class="search-icon" src=${searchIconUrl} alt="" aria-hidden="true" />
140
162
  <input
@@ -151,6 +173,9 @@ const renderConversationSurface = (
151
173
  'conversation-list-wrapper--sidebar': isSidebar,
152
174
  })}
153
175
  >
176
+ ${component.conversationHistoryLoading
177
+ ? html`<div class="conversation-loading">Carregando conversas...</div>`
178
+ : null}
154
179
  ${list}
155
180
  ${isSidebar
156
181
  ? html`
@@ -22,12 +22,13 @@ export const fullscreenStyles = css`
22
22
  padding: 6px 0 12px;
23
23
  }
24
24
 
25
- .fullscreen-shell__content {
26
- flex: 1;
27
- display: flex;
28
- flex-direction: column;
29
- overflow: hidden;
30
- }
25
+ .fullscreen-shell__content {
26
+ flex: 1;
27
+ display: flex;
28
+ flex-direction: column;
29
+ overflow: hidden;
30
+ position: relative;
31
+ }
31
32
 
32
33
  .rail-button {
33
34
  width: 38px;
@@ -153,16 +154,36 @@ export const fullscreenStyles = css`
153
154
  padding: 0;
154
155
  }
155
156
 
156
- .fullscreen-header__icon img {
157
- width: 24px;
158
- height: 24px;
159
- }
160
-
161
- .fullscreen-grid {
162
- flex: 1;
163
- display: grid;
164
- grid-template-columns: 300px minmax(0, 1fr);
165
- min-height: 0;
157
+ .fullscreen-header__icon img {
158
+ width: 24px;
159
+ height: 24px;
160
+ }
161
+
162
+ .fullscreen-exit-inline {
163
+ position: absolute;
164
+ top: 56px;
165
+ right: 14px;
166
+ width: 28px;
167
+ height: 28px;
168
+ border: none;
169
+ background: transparent;
170
+ padding: 0;
171
+ display: grid;
172
+ place-items: center;
173
+ cursor: pointer;
174
+ z-index: 1;
175
+ }
176
+
177
+ .fullscreen-exit-inline img {
178
+ width: 28px;
179
+ height: 28px;
180
+ }
181
+
182
+ .fullscreen-grid {
183
+ flex: 1;
184
+ display: grid;
185
+ grid-template-columns: 300px minmax(0, 1fr);
186
+ min-height: 0;
166
187
  background: linear-gradient(180deg, #eef3f6 0%, #fff 100%);
167
188
  }
168
189
 
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit';
2
2
  import { classMap } from 'lit/directives/class-map.js';
3
- import type { RioAssistWidget } from '../rio-assist/rio-assist';
3
+ import type { HeaderActionConfig, RioAssistWidget } from '../rio-assist/rio-assist';
4
4
  import { renderConversationsPanel } from '../conversations-panel/conversations-panel.template';
5
5
  import { renderChatSurface } from '../mini-panel/mini-panel.template';
6
6
 
@@ -8,14 +8,29 @@ const homeIconUrl = new URL('../../assets/icons/homeIcon.png', import.meta.url).
8
8
  const checkFrameIconUrl = new URL('../../assets/icons/checkFrame.png', import.meta.url).href;
9
9
  const infoFrameIconUrl = new URL('../../assets/icons/infoFrame.png', import.meta.url).href;
10
10
  const profileFrameIconUrl = new URL('../../assets/icons/profileFrame.png', import.meta.url).href;
11
+ const resizeScreenIconUrl = new URL('../../assets/icons/resizeScreen.png', import.meta.url).href;
12
+
13
+ const defaultHeaderActions: HeaderActionConfig[] = [
14
+ { id: 'status', iconUrl: checkFrameIconUrl, ariaLabel: 'Status' },
15
+ { id: 'info', iconUrl: infoFrameIconUrl, ariaLabel: 'Informacoes' },
16
+ { id: 'profile', iconUrl: profileFrameIconUrl, ariaLabel: 'Perfil de usuario' },
17
+ ];
11
18
 
12
19
  export const renderFullscreen = (component: RioAssistWidget) => {
13
20
  const chatSurface = renderChatSurface(component);
21
+ const headerActions = (component.headerActions?.length
22
+ ? component.headerActions
23
+ : defaultHeaderActions) as HeaderActionConfig[];
14
24
 
15
25
  return html`
16
26
  <section class="fullscreen-shell" role="dialog" aria-modal="true">
17
27
  <div class="fullscreen-shell__rail">
18
- <button type="button" class="rail-button" aria-label="Ir para home">
28
+ <button
29
+ type="button"
30
+ class="rail-button"
31
+ aria-label="Ir para home"
32
+ @click=${() => component.handleHomeNavigation()}
33
+ >
19
34
  <img src=${homeIconUrl} alt="" aria-hidden="true" />
20
35
  </button>
21
36
  <button
@@ -67,22 +82,36 @@ export const renderFullscreen = (component: RioAssistWidget) => {
67
82
  </div>
68
83
 
69
84
  <div class="fullscreen-header__tabs">
70
- <span class="fullscreen-header__tab">CONVERSA</span>
85
+ ${component.activeConversationTitle
86
+ ? html`<span class="fullscreen-header__tab">${component.activeConversationTitle}</span>`
87
+ : null}
71
88
  </div>
72
89
 
73
90
  <div class="fullscreen-header__actions">
74
- <button type="button" class="fullscreen-header__icon" aria-label="Status">
75
- <img src=${checkFrameIconUrl} alt="" aria-hidden="true" />
76
- </button>
77
- <button type="button" class="fullscreen-header__icon" aria-label="Informacoes">
78
- <img src=${infoFrameIconUrl} alt="" aria-hidden="true" />
79
- </button>
80
- <button type="button" class="fullscreen-header__icon" aria-label="Perfil de usuario">
81
- <img src=${profileFrameIconUrl} alt="" aria-hidden="true" />
82
- </button>
91
+ ${headerActions.map(
92
+ (action, index) => html`
93
+ <button
94
+ type="button"
95
+ class="fullscreen-header__icon"
96
+ aria-label=${action.ariaLabel ?? 'Acao do cabecalho'}
97
+ @click=${() => component.handleHeaderActionClick(action, index)}
98
+ >
99
+ <img src=${action.iconUrl} alt="" aria-hidden="true" />
100
+ </button>
101
+ `,
102
+ )}
83
103
  </div>
84
104
  </header>
85
105
 
106
+ <button
107
+ type="button"
108
+ class="fullscreen-exit-inline"
109
+ aria-label="Retornar para painel compacto"
110
+ @click=${() => component.exitFullscreen(true)}
111
+ >
112
+ <img src=${resizeScreenIconUrl} alt="" aria-hidden="true" />
113
+ </button>
114
+
86
115
  <div class="fullscreen-grid">
87
116
  ${renderConversationsPanel(component, { variant: 'sidebar' })}
88
117
  <div class="fullscreen-chat">
@@ -169,58 +169,58 @@ export const miniPanelStyles = css`
169
169
  gap: 12px;
170
170
  }
171
171
 
172
- .message {
173
- border-radius: 16px;
174
- border: 1px solid #e4eaee;
175
- padding: 10px 16px;
176
- max-width: 90%;
172
+ .message {
173
+ border-radius: 16px;
174
+ border: 1px solid #e4eaee;
175
+ padding: 10px 16px;
176
+ max-width: 90%;
177
177
  background: #fff;
178
178
  color: #1f2f36;
179
- font-size: 15px;
180
- }
181
-
182
- .message__content {
183
- line-height: 1.35;
184
- }
185
-
186
- .message__content p,
187
- .message__content ul,
188
- .message__content ol {
189
- margin: 4px 0;
190
- }
191
-
192
- .message__content pre {
193
- background: #0d161b;
194
- color: #f3f7fb;
195
- border-radius: 8px;
196
- padding: 10px;
197
- overflow-x: auto;
198
- margin: 6px 0;
199
- font-size: 14px;
200
- }
201
-
202
- .message__content code {
203
- background: #f1f4f7;
204
- padding: 2px 6px;
205
- border-radius: 6px;
206
- }
207
-
208
- .message__content blockquote {
209
- border-left: 3px solid #cfd6dc;
210
- margin: 6px 0;
211
- padding-left: 10px;
212
- color: #4b5a65;
213
- }
214
-
215
- .message__content ul,
216
- .message__content ol {
217
- padding-left: 20px;
218
- }
219
-
220
- .message--user {
221
- align-self: flex-end;
222
- background: #e5ebf0;
223
- border-color: #cfd6dc;
179
+ font-size: 15px;
180
+ }
181
+
182
+ .message__content {
183
+ line-height: 1.35;
184
+ }
185
+
186
+ .message__content p,
187
+ .message__content ul,
188
+ .message__content ol {
189
+ margin: 4px 0;
190
+ }
191
+
192
+ .message__content pre {
193
+ background: #0d161b;
194
+ color: #f3f7fb;
195
+ border-radius: 8px;
196
+ padding: 10px;
197
+ overflow-x: auto;
198
+ margin: 6px 0;
199
+ font-size: 14px;
200
+ }
201
+
202
+ .message__content code {
203
+ background: #f1f4f7;
204
+ padding: 2px 6px;
205
+ border-radius: 6px;
206
+ }
207
+
208
+ .message__content blockquote {
209
+ border-left: 3px solid #cfd6dc;
210
+ margin: 6px 0;
211
+ padding-left: 10px;
212
+ color: #4b5a65;
213
+ }
214
+
215
+ .message__content ul,
216
+ .message__content ol {
217
+ padding-left: 20px;
218
+ }
219
+
220
+ .message--user {
221
+ align-self: flex-end;
222
+ background: #e5ebf0;
223
+ border-color: #cfd6dc;
224
224
  color: #1f2f36;
225
225
  padding: 8px 10px;
226
226
  }
@@ -287,18 +287,19 @@ export const miniPanelStyles = css`
287
287
  white-space: nowrap;
288
288
  }
289
289
 
290
- form {
291
- display: flex;
292
- align-items: center;
293
- gap: 12px;
294
- border: 1px solid #a4afbb;
295
- border-radius: 80px;
296
- padding: 10px 20px;
297
- background: #fff;
298
- width: 100%;
299
- max-width: 520px;
300
- margin-bottom: 0;
301
- max-height: 56px;
290
+ form {
291
+ display: flex;
292
+ align-items: center;
293
+ gap: 12px;
294
+ border: 1px solid #a4afbb;
295
+ border-radius: 80px;
296
+ padding: 8px 12px 8px 16px;
297
+ background: #fff;
298
+ width: 100%;
299
+ max-width: 520px;
300
+ margin-bottom: 0;
301
+ height: 56px;
302
+ box-sizing: border-box;
302
303
  }
303
304
 
304
305
  form input {
@@ -319,19 +320,20 @@ export const miniPanelStyles = css`
319
320
  }
320
321
 
321
322
  .input-button {
322
- width: 32px;
323
- height: 32px;
323
+ width: 40px;
324
+ height: 40px;
324
325
  border-radius: 50%;
325
326
  border: none;
326
327
  background: transparent;
327
328
  display: flex;
328
329
  align-items: center;
329
330
  justify-content: center;
331
+ padding: 0;
330
332
  }
331
333
 
332
334
  .input-button img {
333
- width: 32px;
334
- height: 32px;
335
+ width: 40px;
336
+ height: 40px;
335
337
  }
336
338
 
337
339
  .input-button:disabled {
@@ -9,6 +9,7 @@ const expandIconUrl = new URL('../../assets/icons/expandScreen.png', import.meta
9
9
  const iaCentralIconUrl = new URL('../../assets/icons/iaCentralIcon.png', import.meta.url).href;
10
10
  const plusFileSelectionUrl = new URL('../../assets/icons/plusFileSelection.png', import.meta.url).href;
11
11
  const closeIconUrl = new URL('../../assets/icons/closeIcon.png', import.meta.url).href;
12
+ const arrowButtonUrl = new URL('../../assets/icons/arrowButton.png', import.meta.url).href;
12
13
 
13
14
  export const renderChatSurface = (component: RioAssistWidget) => {
14
15
  const hasMessages = component.messages.length > 0;
@@ -103,6 +104,14 @@ export const renderChatSurface = (component: RioAssistWidget) => {
103
104
  }}
104
105
  ?disabled=${component.isLoading}
105
106
  />
107
+ <button
108
+ class="input-button submit-button"
109
+ type="submit"
110
+ aria-label="Enviar mensagem"
111
+ ?disabled=${component.isLoading}
112
+ >
113
+ <img src=${arrowButtonUrl} alt="" aria-hidden="true" />
114
+ </button>
106
115
  </form>
107
116
 
108
117
  <p class="footnote">