@meistrari/chat-nuxt 3.9.2 → 3.11.0

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.
Files changed (106) hide show
  1. package/README.md +50 -440
  2. package/dist/module.d.mts +1 -1
  3. package/dist/module.json +1 -1
  4. package/dist/runtime/assets/css/markstream.css +1 -1
  5. package/dist/runtime/conversations/components/chat-conversation-creator-filter.vue +11 -67
  6. package/dist/runtime/conversations/components/chat-conversation-item.d.vue.ts +2 -1
  7. package/dist/runtime/conversations/components/chat-conversation-item.vue +29 -33
  8. package/dist/runtime/conversations/components/chat-conversation-item.vue.d.ts +2 -1
  9. package/dist/runtime/conversations/components/chat-conversation-list.d.vue.ts +0 -1
  10. package/dist/runtime/conversations/components/chat-conversation-list.vue +117 -158
  11. package/dist/runtime/conversations/components/chat-conversation-list.vue.d.ts +0 -1
  12. package/dist/runtime/conversations/components/chat-conversation-new-group-button.vue +34 -73
  13. package/dist/runtime/conversations/components/chat-conversation-search.vue +1 -21
  14. package/dist/runtime/conversations/components/chat-widget-history-list.d.vue.ts +12 -0
  15. package/dist/runtime/conversations/components/chat-widget-history-list.vue +27 -0
  16. package/dist/runtime/conversations/components/chat-widget-history-list.vue.d.ts +12 -0
  17. package/dist/runtime/conversations/composables/conversation-groups.d.ts +1 -0
  18. package/dist/runtime/conversations/composables/conversation-groups.js +2 -0
  19. package/dist/runtime/conversations/composables/conversation-item.js +4 -4
  20. package/dist/runtime/conversations/composables/conversation-list.js +14 -5
  21. package/dist/runtime/embed/components/chat-configuration-modal.d.vue.ts +3 -3
  22. package/dist/runtime/embed/components/chat-configuration-modal.vue.d.ts +3 -3
  23. package/dist/runtime/embed/components/chat-embed-inner.d.vue.ts +6 -3
  24. package/dist/runtime/embed/components/chat-embed-inner.vue +442 -174
  25. package/dist/runtime/embed/components/chat-embed-inner.vue.d.ts +6 -3
  26. package/dist/runtime/embed/components/chat-embed.d.vue.ts +31 -4
  27. package/dist/runtime/embed/components/chat-embed.vue +10 -4
  28. package/dist/runtime/embed/components/chat-embed.vue.d.ts +31 -4
  29. package/dist/runtime/embed/components/chat-topbar.vue +83 -85
  30. package/dist/runtime/embed/components/meistrari-chat-embed.d.vue.ts +5 -3
  31. package/dist/runtime/embed/components/meistrari-chat-embed.vue +118 -57
  32. package/dist/runtime/embed/components/meistrari-chat-embed.vue.d.ts +5 -3
  33. package/dist/runtime/embed/components/mobile/chat-mobile-drawer.d.vue.ts +0 -1
  34. package/dist/runtime/embed/components/mobile/chat-mobile-drawer.vue +2 -45
  35. package/dist/runtime/embed/components/mobile/chat-mobile-drawer.vue.d.ts +0 -1
  36. package/dist/runtime/embed/components/mobile/chat-mobile-home-suggestions.d.vue.ts +9 -5
  37. package/dist/runtime/embed/components/mobile/chat-mobile-home-suggestions.vue +14 -25
  38. package/dist/runtime/embed/components/mobile/chat-mobile-home-suggestions.vue.d.ts +9 -5
  39. package/dist/runtime/embed/components/mobile/chat-mobile-shell.d.vue.ts +4 -4
  40. package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue +2 -4
  41. package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue.d.ts +4 -4
  42. package/dist/runtime/embed/composables/use-agent-wake.d.ts +23 -0
  43. package/dist/runtime/embed/composables/use-agent-wake.js +182 -0
  44. package/dist/runtime/embed/feature-config.d.ts +7 -0
  45. package/dist/runtime/embed/feature-config.js +2 -1
  46. package/dist/runtime/embed/loading-messages.d.ts +16 -0
  47. package/dist/runtime/embed/loading-messages.js +10 -0
  48. package/dist/runtime/embed/types.d.ts +47 -8
  49. package/dist/runtime/files/icons.d.ts +1 -1
  50. package/dist/runtime/files/icons.js +1 -1
  51. package/dist/runtime/messages/components/chat-mention-dropdown.d.vue.ts +6 -1
  52. package/dist/runtime/messages/components/chat-mention-dropdown.vue +46 -22
  53. package/dist/runtime/messages/components/chat-mention-dropdown.vue.d.ts +6 -1
  54. package/dist/runtime/messages/components/chat-message-bubble.d.vue.ts +10 -1
  55. package/dist/runtime/messages/components/chat-message-bubble.vue +69 -76
  56. package/dist/runtime/messages/components/chat-message-bubble.vue.d.ts +10 -1
  57. package/dist/runtime/messages/components/chat-message-feedback.vue +25 -229
  58. package/dist/runtime/messages/components/chat-message-input.vue +176 -134
  59. package/dist/runtime/messages/components/chat-message-list.d.vue.ts +12 -1
  60. package/dist/runtime/messages/components/chat-message-list.vue +37 -24
  61. package/dist/runtime/messages/components/chat-message-list.vue.d.ts +12 -1
  62. package/dist/runtime/messages/components/chat-model-selector.vue +10 -22
  63. package/dist/runtime/messages/components/reasoning/chat-reasoning-message.vue +2 -3
  64. package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.d.vue.ts +2 -1
  65. package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.vue +69 -77
  66. package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.vue.d.ts +2 -1
  67. package/dist/runtime/messages/components/reasoning/chat-thinking-indicator.vue +3 -9
  68. package/dist/runtime/messages/components/widgets/chat-bash-widget.vue +3 -12
  69. package/dist/runtime/messages/components/widgets/chat-doc-sdk-widget.vue +3 -12
  70. package/dist/runtime/messages/components/widgets/chat-generic-tool-widget.vue +3 -12
  71. package/dist/runtime/messages/components/widgets/chat-grep-widget.vue +7 -17
  72. package/dist/runtime/messages/components/widgets/chat-read-widget.vue +7 -17
  73. package/dist/runtime/messages/components/widgets/chat-tela-skill-widget.vue +4 -13
  74. package/dist/runtime/messages/components/widgets/chat-thinking-widget.vue +11 -22
  75. package/dist/runtime/messages/components/widgets/chat-web-search-widget.vue +13 -40
  76. package/dist/runtime/messages/components/widgets/chat-workstation-query-widget.vue +52 -65
  77. package/dist/runtime/messages/components/widgets/chat-write-widget.vue +8 -18
  78. package/dist/runtime/messages/composables/chat.d.ts +8 -2
  79. package/dist/runtime/messages/composables/chat.js +180 -25
  80. package/dist/runtime/messages/composables/mention-autocomplete.js +4 -0
  81. package/dist/runtime/messages/composables/use-direct-stream.d.ts +41 -0
  82. package/dist/runtime/messages/composables/use-direct-stream.js +263 -0
  83. package/dist/runtime/messages/message-state.js +1 -0
  84. package/dist/runtime/messages/reasoning.d.ts +7 -0
  85. package/dist/runtime/messages/reasoning.js +5 -0
  86. package/dist/runtime/public/files/generic.svg +2 -5
  87. package/dist/runtime/public/files/image.svg +2 -1
  88. package/dist/runtime/types/embed.d.ts +1 -1
  89. package/dist/runtime/types/schemas/chat/conversations.d.ts +4 -0
  90. package/dist/runtime/types/schemas/chat/conversations.js +3 -0
  91. package/dist/runtime/types/schemas/chat/messages.d.ts +43 -0
  92. package/dist/runtime/types/schemas/chat/messages.js +31 -0
  93. package/dist/runtime/types/schemas/chat/models.d.ts +3 -2
  94. package/dist/runtime/types/schemas/chat/models.js +2 -1
  95. package/dist/runtime/types/schemas/chat/ui.d.ts +10 -0
  96. package/dist/runtime/types/schemas/chat/ui.js +1 -0
  97. package/dist/runtime/types/schemas/integrations/tela-agent-api.d.ts +35 -0
  98. package/dist/runtime/types/schemas/integrations/tela-agent-api.js +17 -0
  99. package/dist/types.d.mts +1 -1
  100. package/package.json +5 -4
  101. package/dist/runtime/conversations/components/chat-conversation-new-group-popover-content.d.vue.ts +0 -23
  102. package/dist/runtime/conversations/components/chat-conversation-new-group-popover-content.vue +0 -75
  103. package/dist/runtime/conversations/components/chat-conversation-new-group-popover-content.vue.d.ts +0 -23
  104. package/dist/runtime/messages/components/reasoning/chat-reasoning-step-item.d.vue.ts +0 -37
  105. package/dist/runtime/messages/components/reasoning/chat-reasoning-step-item.vue +0 -125
  106. package/dist/runtime/messages/components/reasoning/chat-reasoning-step-item.vue.d.ts +0 -37
@@ -1,17 +1,12 @@
1
1
  <script setup>
2
- import { nextTick } from "vue";
3
2
  import { useConversations } from "../composables/conversations";
4
3
  import { conversationCreatorFilterOptions } from "../../types/schemas/chat/ui.js";
5
- import {
6
- hasConversationCreatorFilterResults,
7
- resolveConversationCreatorFilterKeyboardTarget
8
- } from "../creator-filter";
4
+ import { hasConversationCreatorFilterResults } from "../creator-filter";
9
5
  const { conversationCreatorFilter, conversationCreatorFilterCounts, fetchConversations } = useConversations();
10
6
  const isUpdating = ref(false);
11
- const filterButtonElements = ref([]);
12
7
  const filterOptions = computed(() => conversationCreatorFilterOptions.map((option) => ({
13
- ...option,
14
- count: conversationCreatorFilterCounts.value[option.value]
8
+ value: option.value,
9
+ label: `${option.label} ${conversationCreatorFilterCounts.value[option.value]}`
15
10
  })));
16
11
  const showConversationCreatorFilter = computed(
17
12
  () => hasConversationCreatorFilterResults(conversationCreatorFilterCounts.value)
@@ -19,23 +14,10 @@ const showConversationCreatorFilter = computed(
19
14
  function isConversationCreatorFilter(value) {
20
15
  return value === "all" || value === "mine";
21
16
  }
22
- function setFilterButtonElement(element, index) {
23
- if (element && typeof element === "object" && "focus" in element) {
24
- filterButtonElements.value[index] = element;
25
- }
26
- }
27
- function focusFilterButton(value) {
28
- const index = filterOptions.value.findIndex((option) => option.value === value);
29
- filterButtonElements.value[index]?.focus();
30
- }
31
- async function handleFilterUpdate(value, options = {}) {
17
+ async function handleFilterUpdate(value) {
32
18
  if (isUpdating.value || !isConversationCreatorFilter(value) || value === conversationCreatorFilter.value)
33
19
  return;
34
20
  conversationCreatorFilter.value = value;
35
- if (options.focus) {
36
- await nextTick();
37
- focusFilterButton(value);
38
- }
39
21
  isUpdating.value = true;
40
22
  try {
41
23
  await fetchConversations({ force: true });
@@ -43,54 +25,16 @@ async function handleFilterUpdate(value, options = {}) {
43
25
  isUpdating.value = false;
44
26
  }
45
27
  }
46
- function handleFilterKeydown(event, value) {
47
- const nextFilter = resolveConversationCreatorFilterKeyboardTarget(value, event.key);
48
- if (!nextFilter || isUpdating.value)
49
- return;
50
- event.preventDefault();
51
- void handleFilterUpdate(nextFilter, { focus: true });
52
- }
53
28
  </script>
54
29
 
55
30
  <template>
56
- <div
31
+ <TelaSegmentToggle
57
32
  v-if="showConversationCreatorFilter"
58
- role="tablist"
33
+ :model-value="conversationCreatorFilter"
34
+ :options="filterOptions"
35
+ class="w-full"
36
+ buttons-class="flex-1 min-w-0 px-8px"
59
37
  aria-label="Filtrar conversas por criador"
60
- flex items-center w-full h-34px p-3px rounded-12px bg="#F1F1EF"
61
- :class="{ 'opacity-70': isUpdating }"
62
- >
63
- <button
64
- v-for="(option, index) in filterOptions"
65
- :key="option.value"
66
- :ref="(element) => setFilterButtonElement(element, index)"
67
- type="button"
68
- role="tab"
69
- class="creator-filter-option"
70
- flex-1 min-w-0 h-28px rounded-9px px-8px
71
- flex items-center justify-center gap-4px
72
- :class="conversationCreatorFilter === option.value ? 'creator-filter-option-active bg-white cursor-default' : 'bg-transparent hover:bg-white/45 cursor-pointer'"
73
- :aria-disabled="isUpdating"
74
- :aria-selected="conversationCreatorFilter === option.value"
75
- :tabindex="conversationCreatorFilter === option.value ? 0 : -1"
76
- @click="handleFilterUpdate(option.value)"
77
- @keydown="handleFilterKeydown($event, option.value)"
78
- >
79
- <span
80
- body-12-semibold leading-16px truncate
81
- :class="conversationCreatorFilter === option.value ? 'text-neutral-950' : 'text-neutral-500'"
82
- >
83
- {{ option.label }}
84
- </span>
85
- <span
86
- body-12-semibold leading-16px shrink-0 text-neutral-400
87
- >
88
- {{ option.count }}
89
- </span>
90
- </button>
91
- </div>
38
+ @update:model-value="handleFilterUpdate"
39
+ />
92
40
  </template>
93
-
94
- <style scoped>
95
- .creator-filter-option{transition:background-color .16s ease,color .16s ease,box-shadow .16s ease,opacity .16s ease}.creator-filter-option-active{box-shadow:0 1px 2px rgba(16,24,40,.08),0 2px 8px rgba(16,24,40,.1)}.creator-filter-option[aria-disabled=true]{cursor:wait}
96
- </style>
@@ -1,9 +1,10 @@
1
- import type { DeepReadonly } from 'vue';
1
+ import type { DeepReadonly, HTMLAttributes } from 'vue';
2
2
  import type { Conversation } from '../../types/schemas/chat/conversations.js';
3
3
  type __VLS_Props = {
4
4
  conversation: DeepReadonly<Conversation>;
5
5
  active: boolean;
6
6
  draggable?: boolean;
7
+ itemClass?: HTMLAttributes['class'];
7
8
  userImage?: string;
8
9
  selectConversation?: (id: string) => void | Promise<void>;
9
10
  };
@@ -4,6 +4,7 @@ const props = defineProps({
4
4
  conversation: { type: null, required: true },
5
5
  active: { type: Boolean, required: true },
6
6
  draggable: { type: Boolean, required: false },
7
+ itemClass: { type: null, required: false },
7
8
  userImage: { type: String, required: false },
8
9
  selectConversation: { type: Function, required: false }
9
10
  });
@@ -39,26 +40,21 @@ function setMenuButtonRef(element) {
39
40
  <template>
40
41
  <div
41
42
  v-if="isRenamingInline"
42
- px-12px
43
+ pl-10px pr-4px
43
44
  h-32px
44
- rounded-8px
45
- :class="active ? 'bg-neutral-200' : ''"
45
+ rounded-10px
46
+ :class="active ? 'bg-muted' : ''"
46
47
  >
47
- <div flex items-center justify-between gap-12px h-full>
48
- <div v-if="userImage" w-16px h-16px rounded-full overflow-hidden flex-shrink-0>
48
+ <div flex items-center justify-between gap-8px h-full :class="props.itemClass">
49
+ <div v-if="userImage" w-16px h-16px flex items-center justify-center rounded-full overflow-hidden flex-shrink-0>
49
50
  <TelaAvatar
50
51
  :image="userImage"
51
52
  alt="Usuário"
52
- size="xs"
53
+ size="2xs"
53
54
  />
54
55
  </div>
55
56
 
56
- <div
57
- flex-1 min-w-0 flex items-center
58
- text-neutral-700
59
- pb-1px
60
- b-b=".5px solid #A3A3A3"
61
- >
57
+ <div relative flex-1 min-w-0 flex items-center>
62
58
  <input
63
59
  :ref="setRenameInputRef"
64
60
  v-model="renameTitle"
@@ -67,12 +63,13 @@ function setMenuButtonRef(element) {
67
63
  aria-label="Nome da conversa"
68
64
  w-full min-w-0
69
65
  bg-transparent border-none outline-none
70
- text-14px font-medium text-neutral-700 leading-18px tracking="-.15px"
66
+ body-14-medium text-neutral-700
71
67
  p-0
72
68
  @blur="handleRenameBlur"
73
69
  @keydown.enter.prevent="submitRename"
74
70
  @keydown.escape.prevent.stop="cancelRename"
75
71
  >
72
+ <div aria-hidden="true" absolute inset-x-0 bottom--0.5px h-0.5px bg-border pointer-events-none />
76
73
  </div>
77
74
  </div>
78
75
  </div>
@@ -82,37 +79,33 @@ function setMenuButtonRef(element) {
82
79
  :href="conversationPath"
83
80
  :draggable="draggable"
84
81
  block
85
- px-12px
82
+ pl-10px pr-4px
86
83
  h-32px
87
- rounded-8px
84
+ rounded-10px
88
85
  cursor-pointer
89
- transition
90
- class="group"
91
- :class="[
92
- active ? 'bg-neutral-200' : 'hover:bg-neutral-200/50'
93
- ]"
86
+ class="group data-[active=true]:bg-muted data-[active=false]:hover:bg-subtle"
87
+ :data-active="active"
94
88
  @click="handleConversationClick"
95
89
  @dblclick.prevent.stop="handleConversationDoubleClick"
96
90
  @dragstart="handleConversationDragStart"
97
91
  @dragend="handleConversationDragEnd"
98
92
  >
99
- <div flex items-center justify-between gap-12px h-full>
93
+ <div flex items-center justify-between gap-8px h-full :class="props.itemClass">
100
94
  <!-- User Avatar -->
101
- <div v-if="userImage" w-16px h-16px rounded-full overflow-hidden flex-shrink-0>
95
+ <div v-if="userImage" w-16px h-16px flex items-center justify-center rounded-full overflow-hidden flex-shrink-0>
102
96
  <TelaAvatar
103
97
  :image="userImage"
104
98
  alt="Usuário"
105
- size="xs"
99
+ size="2xs"
106
100
  />
107
101
  </div>
108
102
 
109
103
  <div flex-1 min-w-0 flex items-center>
110
104
  <span
111
- text-14px
112
- font-medium
113
- text-neutral-700
105
+ body-14-medium
106
+ text-secondary
107
+ class="group-hover:text-primary group-data-[active=true]:text-primary"
114
108
  truncate
115
- tracking="-.15px"
116
109
  >
117
110
  {{ displayTitle }}
118
111
  </span>
@@ -122,21 +115,24 @@ function setMenuButtonRef(element) {
122
115
  mt-2px
123
116
  flex
124
117
  items-center
125
- class="opacity-0 group-hover:opacity-100 transition-opacity"
118
+ class="opacity-0 group-hover:opacity-100"
126
119
  :class="isMenuOpen && 'opacity-100'"
127
120
  >
128
121
  <TelaDropdownMenu :items="menuItems" content-class="chat-sidebar-floating">
129
122
  <button
130
123
  :ref="setMenuButtonRef"
131
124
  p-4px
132
- rounded-6px
133
- hover:bg-neutral-300
134
- transition-colors
125
+ rounded-8px
126
+ hover:bg-lowered
135
127
  cursor-pointer
136
- :class="isMenuOpen && '!bg-neutral-300'"
128
+ :class="isMenuOpen && '!bg-lowered'"
137
129
  @click.prevent.stop
138
130
  >
139
- <div i-ph-dots-three-vertical text-16px text-neutral-400 />
131
+ <TelaIcon
132
+ name="i-ph-dots-three"
133
+ size="18px"
134
+ :color="isMenuOpen ? 'icon-tertiary' : 'icon-subtle group-hover:icon-tertiary'"
135
+ />
140
136
  </button>
141
137
  </TelaDropdownMenu>
142
138
  </div>
@@ -1,9 +1,10 @@
1
- import type { DeepReadonly } from 'vue';
1
+ import type { DeepReadonly, HTMLAttributes } from 'vue';
2
2
  import type { Conversation } from '../../types/schemas/chat/conversations.js';
3
3
  type __VLS_Props = {
4
4
  conversation: DeepReadonly<Conversation>;
5
5
  active: boolean;
6
6
  draggable?: boolean;
7
+ itemClass?: HTMLAttributes['class'];
7
8
  userImage?: string;
8
9
  selectConversation?: (id: string) => void | Promise<void>;
9
10
  };
@@ -8,7 +8,6 @@ type __VLS_Props = {
8
8
  resetConversation?: () => void | Promise<void>;
9
9
  startConversation?: (groupId?: string | null) => void | Promise<void>;
10
10
  loading?: boolean;
11
- hideFolderHint?: boolean;
12
11
  };
13
12
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
13
  declare const _default: typeof __VLS_export;
@@ -7,8 +7,7 @@ const props = defineProps({
7
7
  selectConversation: { type: Function, required: false },
8
8
  resetConversation: { type: Function, required: false },
9
9
  startConversation: { type: Function, required: false },
10
- loading: { type: Boolean, required: false },
11
- hideFolderHint: { type: Boolean, required: false }
10
+ loading: { type: Boolean, required: false }
12
11
  });
13
12
  const {
14
13
  conversationSearch,
@@ -20,8 +19,6 @@ const {
20
19
  ungroupedConversations,
21
20
  ungroupedDropTarget,
22
21
  ungroupedConversationLabel,
23
- shouldShowUngroupedHeader,
24
- showGroupCreationPrompt,
25
22
  showDeleteGroupModal,
26
23
  showDeleteGroupConversationsModal,
27
24
  groupActionLoading,
@@ -82,44 +79,12 @@ const {
82
79
  </p>
83
80
  </div>
84
81
 
85
- <template v-else>
86
- <div
87
- v-if="showGroupCreationPrompt && !hideFolderHint"
88
- mx-8px
89
- flex="~ col" gap-10px
90
- >
91
- <div h-20px flex items-center px-4px>
92
- <span text-12px font-semibold text-neutral-400 uppercase style="letter-spacing: 0">
93
- PASTAS
94
- </span>
95
- </div>
96
- <div flex="~ col" gap-6px>
97
- <div
98
- h-36px px-10px
99
- flex items-center gap-10px
100
- rounded-8px
101
- b=".5px dashed neutral-200"
102
- >
103
- <span i-ph-folder text-16px text-neutral-400 shrink-0 />
104
- <span h-10px w-120px rounded-full bg-neutral-100 />
105
- </div>
106
- <div
107
- h-36px px-10px
108
- flex items-center gap-10px
109
- rounded-8px
110
- b=".5px dashed neutral-200"
111
- >
112
- <span i-ph-folder text-16px text-neutral-400 shrink-0 />
113
- <span h-10px w-84px rounded-full bg-neutral-100 />
114
- </div>
115
- </div>
116
- <p px-4px text-14px text-neutral-500 leading-20px>
117
- Suas pastas aparecem aqui. Crie uma para começar a agrupar conversas.
118
- </p>
119
- <ChatConversationNewGroupButton label="Criar pasta" variant="empty-state" />
120
- </div>
121
-
82
+ <div v-else flex="~ col" gap-4px mt-4px>
122
83
  <div v-if="groupItems.length > 0" flex="~ col" gap-2px>
84
+ <span body-12-medium text-secondary pl-10px>
85
+ Pastas · {{ groupItems.length }}
86
+ </span>
87
+
123
88
  <div
124
89
  v-for="groupBucket in groupItems"
125
90
  :key="groupBucket.group.id"
@@ -133,100 +98,99 @@ const {
133
98
  @drop.prevent="handleConversationDrop($event, groupBucket.group.id)"
134
99
  >
135
100
  <div
136
- v-if="groupBucket.isRenaming"
137
- h-32px w-full px-8px
138
- flex items-center gap-8px
139
- rounded-8px
140
- :class="groupBucket.dropTarget ? 'bg-neutral-200' : ''"
101
+ rounded-10px
102
+ class="group"
103
+ :class="groupBucket.dropTarget ? '' : groupBucket.open ? 'bg-muted' : 'hover:bg-subtle'"
141
104
  >
142
- <span
143
- i-ph-caret-right
144
- text-12px text-neutral-400
145
- transition-transform
146
- :class="groupBucket.open && 'rotate-90'"
147
- />
148
- <span
149
- :class="groupBucket.folderIcon"
150
- text-16px text-neutral-500 shrink-0
151
- />
152
- <div
153
- flex-1 min-w-0 flex items-center
154
- pb-1px
155
- b-b=".5px solid #A3A3A3"
156
- :class="renameGroupError && 'border-red-500'"
157
- >
158
- <input
159
- :ref="(element) => setRenameGroupInputRef(element, groupBucket.group.id)"
160
- v-model="renameGroupName"
161
- type="text"
162
- autocomplete="off"
163
- maxlength="80"
164
- aria-label="Nome da pasta"
165
- w-full min-w-0
166
- bg-transparent border-none outline-none
167
- text-14px font-semibold text-neutral-700 leading-18px
168
- p-0
169
- :disabled="groupActionLoading"
170
- @blur="handleRenameGroupBlur"
171
- @keydown.enter.prevent="submitRenameGroup"
172
- @keydown.escape.prevent.stop="cancelRenameGroup"
173
- @click.stop
174
- @dblclick.stop
175
- >
176
- </div>
177
- </div>
178
-
179
- <div v-else rounded-8px class="group" :class="groupBucket.dropTarget ? '' : 'hover:bg-neutral-100'">
180
- <div h-32px w-full px-8px flex items-center gap-4px text-left>
181
- <button
182
- type="button"
183
- h-full flex-1 min-w-0
184
- flex items-center gap-8px
185
- text-left
186
- cursor-pointer
187
- @click="toggleGroup(groupBucket.group.id)"
188
- >
189
- <span
190
- i-ph-caret-right
191
- text-12px text-neutral-400
192
- transition-transform
193
- :class="groupBucket.open && 'rotate-90'"
194
- />
195
- <span
196
- :class="groupBucket.folderIcon"
197
- text-16px text-neutral-500 shrink-0
105
+ <div h-32px w-full pl-10px pr-4px flex items-center gap-8px text-left>
106
+ <template v-if="groupBucket.isRenaming">
107
+ <TelaIcon
108
+ :name="groupBucket.folderIcon"
109
+ size="16px"
110
+ color="icon-secondary"
111
+ shrink-0
198
112
  />
199
- <span flex-1 min-w-0 truncate text-14px font-semibold text-neutral-900 leading-18px>
200
- {{ groupBucket.group.name }}
201
- </span>
202
- <span v-if="groupBucket.conversationCountLabel" text-13px font-medium text-neutral-400 tabular-nums>
203
- {{ groupBucket.conversationCountLabel }}
204
- </span>
205
- </button>
113
+ <div
114
+ relative
115
+ flex-1 min-w-0 flex items-center
116
+ mr-4px
117
+ >
118
+ <input
119
+ :ref="(element) => setRenameGroupInputRef(element, groupBucket.group.id)"
120
+ v-model="renameGroupName"
121
+ type="text"
122
+ autocomplete="off"
123
+ maxlength="80"
124
+ aria-label="Nome da pasta"
125
+ w-full min-w-0
126
+ bg-transparent border-none outline-none
127
+ body-14-medium text-primary
128
+ p-0
129
+ :disabled="groupActionLoading"
130
+ @blur="handleRenameGroupBlur"
131
+ @keydown.enter.prevent="submitRenameGroup"
132
+ @keydown.escape.prevent.stop="cancelRenameGroup"
133
+ @click.stop
134
+ @dblclick.stop
135
+ >
136
+ <div
137
+ aria-hidden="true"
138
+ absolute inset-x-0 bottom--2px h-0.5px pointer-events-none
139
+ :class="renameGroupError ? 'bg-red-500' : 'bg-border'"
140
+ />
141
+ </div>
142
+ </template>
206
143
 
207
- <div
208
- flex items-center justify-center shrink-0
209
- class="opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity"
210
- >
211
- <TelaDropdownMenu
212
- :items="groupBucket.menuItems"
213
- align="end"
214
- content-class="chat-sidebar-floating"
144
+ <template v-else>
145
+ <button
146
+ type="button"
147
+ h-full flex-1 min-w-0
148
+ flex items-center gap-8px
149
+ text-left
150
+ cursor-pointer
151
+ @click="toggleGroup(groupBucket.group.id)"
215
152
  >
216
- <button
217
- type="button"
218
- aria-label="Ações da pasta"
219
- p-4px
220
- rounded-6px
221
- hover:bg-neutral-200
222
- transition-colors
223
- cursor-pointer
224
- @click.prevent.stop
153
+ <TelaIcon
154
+ :name="groupBucket.folderIcon"
155
+ size="16px"
156
+ color="icon-secondary"
157
+ shrink-0
158
+ />
159
+ <div flex items-center gap-6px>
160
+ <span min-w-0 truncate body-14-medium :class="groupBucket.open ? 'text-primary' : 'text-secondary group-hover:text-primary'">
161
+ {{ groupBucket.group.name }}
162
+ </span>
163
+ <TelaAnimatedNumber v-if="groupBucket.conversationCountLabel" :value="groupBucket.conversationCountLabel" body-12-medium text-tertiary />
164
+ </div>
165
+ </button>
166
+
167
+ <div
168
+ flex items-center justify-center shrink-0
169
+ class="opacity-0 group-hover:opacity-100 focus-within:opacity-100 [&:has([data-state=open])]:opacity-100"
170
+ >
171
+ <TelaDropdownMenu
172
+ :items="groupBucket.menuItems"
173
+ content-class="chat-sidebar-floating"
225
174
  >
226
- <div i-ph-dots-three-vertical text-16px text-neutral-400 />
227
- </button>
228
- </TelaDropdownMenu>
229
- </div>
175
+ <button
176
+ type="button"
177
+ aria-label="Ações da pasta"
178
+ p-4px mt-2px
179
+ rounded-8px
180
+ hover:bg-lowered
181
+ cursor-pointer
182
+ class="group data-[state=open]:!bg-lowered"
183
+ @click.prevent.stop
184
+ >
185
+ <TelaIcon
186
+ name="i-ph-dots-three"
187
+ size="18px"
188
+ color="icon-subtle group-hover:icon-tertiary group-data-[state=open]:icon-tertiary"
189
+ />
190
+ </button>
191
+ </TelaDropdownMenu>
192
+ </div>
193
+ </template>
230
194
  </div>
231
195
  </div>
232
196
 
@@ -239,14 +203,15 @@ const {
239
203
  </span>
240
204
  </div>
241
205
 
242
- <Transition name="group-slide">
243
- <div v-if="groupBucket.open" class="group-slide-panel">
244
- <div class="group-slide__inner">
245
- <div flex="~ col" gap-1px ml-20px mt-1px mb-4px>
206
+ <TelaCollapsible :open="groupBucket.open" @update:open="toggleGroup(groupBucket.group.id)">
207
+ <TelaCollapsibleContent>
208
+ <div flex="~ col" relative>
209
+ <div flex="~ col" gap-1px mt-1px>
246
210
  <ChatConversationItem
247
211
  v-for="conversation in groupBucket.items"
248
212
  :key="conversation.id"
249
213
  v-bind="getConversationItemProps(conversation)"
214
+ item-class="ml-24px"
250
215
  @delete="handleDelete"
251
216
  @rename="handleRename"
252
217
  @duplicate="handleDuplicate"
@@ -257,50 +222,48 @@ const {
257
222
  <button
258
223
  v-if="groupBucket.showNewConversationAction"
259
224
  type="button"
260
- h-32px px-8px
261
- flex items-center gap-8px
262
- rounded-8px
225
+ h-32px px-12px
226
+ flex items-center gap-9px
227
+ rounded-10px
263
228
  text-left
264
- hover:bg-neutral-100
265
- transition-colors
229
+ hover:bg-subtle
266
230
  cursor-pointer
267
231
  @click="startConversationInGroup(groupBucket.group.id)"
268
232
  >
269
- <span i-ph-plus text-14px text-neutral-500 shrink-0 />
270
- <span text-14px font-medium text-neutral-500 leading-18px>
233
+ <span body-14-medium text-secondary leading-18px ml-24px>
271
234
  Nova conversa
272
235
  </span>
236
+ <TelaIcon name="i-ph-plus" size="14px" color="icon-secondary" shrink-0 />
273
237
  </button>
274
238
  <div
275
239
  v-else-if="groupBucket.showSearchEmpty"
276
- h-32px px-8px flex items-center
240
+ h-32px flex items-center ml-36px
277
241
  >
278
- <span text-13px text-neutral-400 leading-17px>
242
+ <span body-14-medium text-tertiary>
279
243
  Sem resultados
280
244
  </span>
281
245
  </div>
282
246
  </div>
247
+
248
+ <div aria-hidden="true" absolute left-17px h-full w-0.5px bg-border pointer-events-none />
283
249
  </div>
284
- </div>
285
- </Transition>
250
+ </TelaCollapsibleContent>
251
+ </TelaCollapsible>
286
252
  </div>
287
253
  </div>
288
254
 
289
255
  <div
290
256
  flex="~ col" gap-4px
291
- rounded-8px
292
- transition-colors
293
- :class="ungroupedDropTarget ? 'bg-neutral-100' : ''"
257
+ rounded-10px
258
+ :class="ungroupedDropTarget ? 'bg-lowered' : ''"
294
259
  @dragenter.prevent="handleDragEnter(null)"
295
260
  @dragover.prevent="handleDragOver($event, null)"
296
261
  @dragleave="handleDragLeave($event, null)"
297
262
  @drop.prevent="handleConversationDrop($event, null)"
298
263
  >
299
- <div v-if="shouldShowUngroupedHeader" h-20px flex items-center pl-12px pr-4px mb-4px>
300
- <span text-12px font-semibold text-neutral-400 uppercase style="letter-spacing: 0">
301
- {{ ungroupedConversationLabel }}
302
- </span>
303
- </div>
264
+ <span body-12-medium text-secondary pl-10px pt-4px>
265
+ {{ ungroupedConversationLabel }}
266
+ </span>
304
267
 
305
268
  <div v-if="ungroupedConversations.length > 0" flex="~ col" gap-1px>
306
269
  <ChatConversationItem
@@ -316,7 +279,7 @@ const {
316
279
  />
317
280
  </div>
318
281
  </div>
319
- </template>
282
+ </div>
320
283
  </div>
321
284
 
322
285
  <TelaConfirmationModal
@@ -347,7 +310,3 @@ const {
347
310
  {{ deleteGroupConversationsConfirmationMessage }}
348
311
  </TelaConfirmationModal>
349
312
  </template>
350
-
351
- <style scoped>
352
- .group-slide-panel{display:grid;grid-template-rows:1fr}.group-slide-enter-active,.group-slide-leave-active{overflow:hidden;transition:grid-template-rows .18s cubic-bezier(.2,.8,.2,1),opacity .14s ease,transform .18s cubic-bezier(.2,.8,.2,1)}.group-slide-enter-from,.group-slide-leave-to{grid-template-rows:0fr;opacity:0;transform:translateY(-4px)}.group-slide-enter-to,.group-slide-leave-from{grid-template-rows:1fr;opacity:1;transform:translateY(0)}.group-slide__inner{min-height:0;overflow:hidden}
353
- </style>
@@ -8,7 +8,6 @@ type __VLS_Props = {
8
8
  resetConversation?: () => void | Promise<void>;
9
9
  startConversation?: (groupId?: string | null) => void | Promise<void>;
10
10
  loading?: boolean;
11
- hideFolderHint?: boolean;
12
11
  };
13
12
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
13
  declare const _default: typeof __VLS_export;