rio-assist-widget 0.1.11 → 0.1.18

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.
@@ -19,13 +19,26 @@ export type ChatMessage = {
19
19
  timestamp: number;
20
20
  };
21
21
 
22
- type ConversationItem = {
23
- id: string;
24
- title: string;
25
- updatedAt: string;
26
- };
27
-
28
- export class RioAssistWidget extends LitElement {
22
+ type ConversationItem = {
23
+ id: string;
24
+ title: string;
25
+ updatedAt: string;
26
+ };
27
+
28
+ type ConversationDeleteTarget = {
29
+ id: string;
30
+ title: string;
31
+ index: number;
32
+ };
33
+
34
+ export type HeaderActionConfig = {
35
+ id?: string;
36
+ iconUrl: string;
37
+ ariaLabel?: string;
38
+ onClick?: () => void;
39
+ };
40
+
41
+ export class RioAssistWidget extends LitElement {
29
42
  static styles = widgetStyles;
30
43
 
31
44
  static properties = {
@@ -51,6 +64,10 @@ export class RioAssistWidget extends LitElement {
51
64
  conversations: { state: true },
52
65
  conversationHistoryLoading: { type: Boolean, state: true },
53
66
  activeConversationTitle: { state: true },
67
+ conversationHistoryError: { type: String, state: true },
68
+ deleteConversationTarget: { attribute: false },
69
+ headerActions: { attribute: false },
70
+ homeUrl: { type: String, attribute: 'data-home-url' },
54
71
  };
55
72
 
56
73
  open = false;
@@ -97,10 +114,18 @@ export class RioAssistWidget extends LitElement {
97
114
 
98
115
  conversationHistoryLoading = false;
99
116
 
117
+ conversationHistoryError = '';
118
+
119
+ deleteConversationTarget: ConversationDeleteTarget | null = null;
120
+
100
121
  private refreshConversationsAfterResponse = false;
101
122
 
102
123
  activeConversationTitle: string | null = null;
103
124
 
125
+ headerActions: HeaderActionConfig[] = [];
126
+
127
+ homeUrl = '';
128
+
104
129
  private generateConversationId() {
105
130
  if (!this.conversationUserId) {
106
131
  this.conversationUserId = this.inferUserIdFromToken();
@@ -342,25 +367,168 @@ export class RioAssistWidget extends LitElement {
342
367
  this.conversationMenuId = null;
343
368
  }
344
369
  }
345
-
346
- handleConversationAction(action: 'rename' | 'delete', id: string) {
347
- this.conversationMenuId = null;
348
- const conversation = this.conversations.find((item) => item.id === id);
349
- if (!conversation) {
350
- return;
351
- }
352
-
353
- const message = `${
354
- action === 'rename' ? 'Renomear' : 'Excluir'
355
- } "${conversation.title}"`;
356
- console.info(`[Mock] ${message}`);
357
- }
358
-
359
- handleCloseAction() {
360
- if (this.isFullscreen) {
361
- this.exitFullscreen(true);
362
- return;
363
- }
370
+
371
+ handleConversationAction(action: 'rename' | 'delete', id: string) {
372
+ this.conversationMenuId = null;
373
+ const conversationIndex = this.conversations.findIndex((item) => item.id === id);
374
+ if (conversationIndex === -1) {
375
+ return;
376
+ }
377
+
378
+ const conversation = this.conversations[conversationIndex];
379
+ if (action === 'delete') {
380
+ this.deleteConversationTarget = {
381
+ id: conversation.id,
382
+ title: conversation.title,
383
+ index: conversationIndex,
384
+ };
385
+ return;
386
+ }
387
+
388
+ this.dispatchConversationAction('rename', conversation, conversationIndex);
389
+ }
390
+
391
+ handleHomeNavigation() {
392
+ const detail = { url: this.homeUrl || null };
393
+ const allowed = this.dispatchEvent(
394
+ new CustomEvent('rioassist:home', {
395
+ detail,
396
+ bubbles: true,
397
+ composed: true,
398
+ cancelable: true,
399
+ }),
400
+ );
401
+
402
+ if (!allowed) {
403
+ return;
404
+ }
405
+
406
+ if (this.homeUrl) {
407
+ window.location.assign(this.homeUrl);
408
+ }
409
+ }
410
+
411
+ applyConversationRename(id: string, newTitle: string) {
412
+ if (!id || !newTitle) {
413
+ return;
414
+ }
415
+
416
+ let changed = false;
417
+ this.conversations = this.conversations.map((conversation) => {
418
+ if (conversation.id === id) {
419
+ changed = true;
420
+ return { ...conversation, title: newTitle };
421
+ }
422
+ return conversation;
423
+ });
424
+
425
+ if (!changed) {
426
+ return;
427
+ }
428
+
429
+ if (this.currentConversationId === id) {
430
+ this.activeConversationTitle = newTitle;
431
+ }
432
+ }
433
+
434
+ applyConversationDeletion(id: string) {
435
+ if (!id) {
436
+ return;
437
+ }
438
+
439
+ const wasActive = this.currentConversationId === id;
440
+ const next = this.conversations.filter((conversation) => conversation.id !== id);
441
+
442
+ if (next.length === this.conversations.length) {
443
+ return;
444
+ }
445
+
446
+ this.conversations = next;
447
+
448
+ if (wasActive) {
449
+ this.currentConversationId = null;
450
+ this.activeConversationTitle = null;
451
+ this.messages = [];
452
+ }
453
+ }
454
+
455
+ confirmDeleteConversation() {
456
+ const target = this.deleteConversationTarget;
457
+ if (!target) {
458
+ return;
459
+ }
460
+
461
+ this.dispatchConversationAction('delete', { id: target.id, title: target.title }, target.index);
462
+ this.deleteConversationTarget = null;
463
+ }
464
+
465
+ cancelDeleteConversation() {
466
+ this.deleteConversationTarget = null;
467
+ }
468
+
469
+ private dispatchConversationAction(
470
+ action: 'rename' | 'delete',
471
+ conversation: Pick<ConversationItem, 'id' | 'title'>,
472
+ index: number,
473
+ ) {
474
+ const eventName =
475
+ action === 'rename' ? 'rioassist:conversation-rename' : 'rioassist:conversation-delete';
476
+ const detail = {
477
+ id: conversation.id,
478
+ title: conversation.title,
479
+ index,
480
+ action,
481
+ };
482
+
483
+ const allowed = this.dispatchEvent(
484
+ new CustomEvent(eventName, {
485
+ detail,
486
+ bubbles: true,
487
+ composed: true,
488
+ cancelable: true,
489
+ }),
490
+ );
491
+
492
+ if (!allowed) {
493
+ return;
494
+ }
495
+
496
+ if (action === 'delete') {
497
+ this.applyConversationDeletion(conversation.id);
498
+ }
499
+ }
500
+
501
+ handleHeaderActionClick(action: HeaderActionConfig, index: number) {
502
+ const detail = {
503
+ index,
504
+ id: action.id ?? null,
505
+ ariaLabel: action.ariaLabel ?? null,
506
+ iconUrl: action.iconUrl,
507
+ };
508
+
509
+ const allowed = this.dispatchEvent(
510
+ new CustomEvent('rioassist:header-action', {
511
+ detail,
512
+ bubbles: true,
513
+ composed: true,
514
+ cancelable: true,
515
+ }),
516
+ );
517
+
518
+ if (!allowed) {
519
+ return;
520
+ }
521
+
522
+ if (typeof action.onClick === 'function') {
523
+ action.onClick();
524
+ }
525
+ }
526
+
527
+ handleCloseAction() {
528
+ if (this.isFullscreen) {
529
+ this.exitFullscreen(true);
530
+ return;
531
+ }
364
532
 
365
533
  if (this.showConversations) {
366
534
  this.closeConversationsPanel();
@@ -369,15 +537,16 @@ export class RioAssistWidget extends LitElement {
369
537
  }
370
538
  }
371
539
 
372
- enterFullscreen() {
373
- if (this.isFullscreen) {
374
- return;
375
- }
376
-
377
- this.isFullscreen = true;
378
- this.open = false;
379
- this.showConversations = false;
380
- }
540
+ enterFullscreen() {
541
+ if (this.isFullscreen) {
542
+ return;
543
+ }
544
+
545
+ this.isFullscreen = true;
546
+ this.open = false;
547
+ this.showConversations = false;
548
+ this.requestConversationHistory();
549
+ }
381
550
 
382
551
  exitFullscreen(restorePanel: boolean) {
383
552
  if (!this.isFullscreen) {
@@ -687,10 +856,15 @@ export class RioAssistWidget extends LitElement {
687
856
  limit,
688
857
  });
689
858
 
859
+ this.conversationHistoryError = '';
690
860
  this.conversationHistoryLoading = true;
691
861
  await client.requestHistory({ conversationId, limit });
692
862
  } catch (error) {
693
863
  console.error('[RioAssist][history] erro ao solicitar historico', error);
864
+ this.conversationHistoryError =
865
+ error instanceof Error && error.message
866
+ ? error.message
867
+ : 'Nao foi possivel carregar as conversas.';
694
868
  this.conversationHistoryLoading = false;
695
869
  }
696
870
  }
@@ -754,6 +928,7 @@ export class RioAssistWidget extends LitElement {
754
928
  console.info('[RioAssist][history] payload sem itens para montar lista de conversas');
755
929
  this.conversations = [];
756
930
  this.conversationHistoryLoading = false;
931
+ this.conversationHistoryError = '';
757
932
  return;
758
933
  }
759
934
 
@@ -794,6 +969,7 @@ export class RioAssistWidget extends LitElement {
794
969
 
795
970
  this.conversations = conversations;
796
971
  this.conversationHistoryLoading = false;
972
+ this.conversationHistoryError = '';
797
973
  this.syncActiveConversationTitle();
798
974
  console.info('[RioAssist][history] conversas normalizadas', conversations);
799
975
  }