@meistrari/chat-nuxt 1.7.0 → 1.8.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 (90) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +2 -0
  3. package/dist/runtime/components/MeistrariChatEmbed.vue +5 -1
  4. package/dist/runtime/components/chat/bash-widget.vue +3 -3
  5. package/dist/runtime/components/chat/doc-sdk-widget.vue +3 -3
  6. package/dist/runtime/components/chat/files-view.vue +3 -64
  7. package/dist/runtime/components/chat/generic-tool-widget.vue +3 -3
  8. package/dist/runtime/components/chat/grep-widget.vue +3 -3
  9. package/dist/runtime/components/chat/message-bubble.vue +1 -1
  10. package/dist/runtime/components/chat/message-input.d.vue.ts +2 -0
  11. package/dist/runtime/components/chat/message-input.vue +21 -5
  12. package/dist/runtime/components/chat/message-input.vue.d.ts +2 -0
  13. package/dist/runtime/components/chat/message-list.vue +1 -1
  14. package/dist/runtime/components/chat/mobile/files/file-preview.d.vue.ts +11 -0
  15. package/dist/runtime/components/chat/mobile/files/file-preview.vue +112 -0
  16. package/dist/runtime/components/chat/mobile/files/file-preview.vue.d.ts +11 -0
  17. package/dist/runtime/components/chat/mobile/files/files-view.d.vue.ts +10 -0
  18. package/dist/runtime/components/chat/mobile/files/files-view.vue +384 -0
  19. package/dist/runtime/components/chat/mobile/files/files-view.vue.d.ts +10 -0
  20. package/dist/runtime/components/chat/mobile/home/header.d.vue.ts +19 -0
  21. package/dist/runtime/components/chat/mobile/home/header.vue +55 -0
  22. package/dist/runtime/components/chat/mobile/home/header.vue.d.ts +19 -0
  23. package/dist/runtime/components/chat/mobile/home/recents.d.vue.ts +14 -0
  24. package/dist/runtime/components/chat/mobile/home/recents.vue +48 -0
  25. package/dist/runtime/components/chat/mobile/home/recents.vue.d.ts +14 -0
  26. package/dist/runtime/components/chat/mobile/home/suggestions.d.vue.ts +7 -0
  27. package/dist/runtime/components/chat/mobile/home/suggestions.vue +31 -0
  28. package/dist/runtime/components/chat/mobile/home/suggestions.vue.d.ts +7 -0
  29. package/dist/runtime/components/chat/mobile/primitives/bottom-sheet.d.vue.ts +21 -0
  30. package/dist/runtime/components/chat/mobile/primitives/bottom-sheet.vue +48 -0
  31. package/dist/runtime/components/chat/mobile/primitives/bottom-sheet.vue.d.ts +21 -0
  32. package/dist/runtime/components/chat/mobile/primitives/info-bubble.d.vue.ts +6 -0
  33. package/dist/runtime/components/chat/mobile/primitives/info-bubble.vue +50 -0
  34. package/dist/runtime/components/chat/mobile/primitives/info-bubble.vue.d.ts +6 -0
  35. package/dist/runtime/components/chat/mobile/shell/drawer.d.vue.ts +22 -0
  36. package/dist/runtime/components/chat/mobile/shell/drawer.vue +143 -0
  37. package/dist/runtime/components/chat/mobile/shell/drawer.vue.d.ts +22 -0
  38. package/dist/runtime/components/chat/mobile/shell/header.d.vue.ts +40 -0
  39. package/dist/runtime/components/chat/mobile/shell/header.vue +139 -0
  40. package/dist/runtime/components/chat/mobile/shell/header.vue.d.ts +40 -0
  41. package/dist/runtime/components/chat/mobile/shell/outdated-settings-sheet.d.vue.ts +14 -0
  42. package/dist/runtime/components/chat/mobile/shell/outdated-settings-sheet.vue +47 -0
  43. package/dist/runtime/components/chat/mobile/shell/outdated-settings-sheet.vue.d.ts +14 -0
  44. package/dist/runtime/components/chat/mobile/shell/shell.d.vue.ts +122 -0
  45. package/dist/runtime/components/chat/mobile/shell/shell.vue +283 -0
  46. package/dist/runtime/components/chat/mobile/shell/shell.vue.d.ts +122 -0
  47. package/dist/runtime/components/chat/mobile/shell/workspace-sheet.d.vue.ts +19 -0
  48. package/dist/runtime/components/chat/mobile/shell/workspace-sheet.vue +51 -0
  49. package/dist/runtime/components/chat/mobile/shell/workspace-sheet.vue.d.ts +19 -0
  50. package/dist/runtime/components/chat/mobile/usage/usage-view.d.vue.ts +8 -0
  51. package/dist/runtime/components/chat/mobile/usage/usage-view.vue +243 -0
  52. package/dist/runtime/components/chat/mobile/usage/usage-view.vue.d.ts +8 -0
  53. package/dist/runtime/components/chat/model-selector.vue +6 -0
  54. package/dist/runtime/components/chat/read-widget.vue +3 -3
  55. package/dist/runtime/components/chat/reasoning-step-item.vue +1 -1
  56. package/dist/runtime/components/chat/reasoning-steps.vue +1 -1
  57. package/dist/runtime/components/chat/reasoning-thought.vue +2 -3
  58. package/dist/runtime/components/chat/tela-skill-widget.vue +3 -3
  59. package/dist/runtime/components/chat/thinking-widget.vue +3 -3
  60. package/dist/runtime/components/chat/usage-view.vue +20 -101
  61. package/dist/runtime/components/chat/web-search-widget.vue +3 -3
  62. package/dist/runtime/components/chat/workstation-query-widget.vue +6 -6
  63. package/dist/runtime/components/chat/write-widget.vue +3 -3
  64. package/dist/runtime/composables/useConversationFileDownloads.d.ts +6 -0
  65. package/dist/runtime/composables/useConversationFileDownloads.js +50 -0
  66. package/dist/runtime/composables/useConversationUsage.d.ts +13 -0
  67. package/dist/runtime/composables/useConversationUsage.js +121 -0
  68. package/dist/runtime/composables/useEmbedConfig.d.ts +2 -0
  69. package/dist/runtime/composables/useEmbedConfig.js +4 -0
  70. package/dist/runtime/composables/useMentionAutocomplete.d.ts +6 -0
  71. package/dist/runtime/composables/useMentionAutocomplete.js +71 -23
  72. package/dist/runtime/composables/useWorkspaceSwitchModal.d.ts +5 -0
  73. package/dist/runtime/composables/useWorkspaceSwitchModal.js +14 -0
  74. package/dist/runtime/embed/components/ChatConfigurationModal.vue +119 -13
  75. package/dist/runtime/embed/components/ChatEmbed.vue +4 -0
  76. package/dist/runtime/embed/components/ChatEmbedInner.d.vue.ts +2 -0
  77. package/dist/runtime/embed/components/ChatEmbedInner.vue +201 -11
  78. package/dist/runtime/embed/components/ChatEmbedInner.vue.d.ts +2 -0
  79. package/dist/runtime/embed/components/configuration/ChatConfigurationMobileShell.d.vue.ts +34 -0
  80. package/dist/runtime/embed/components/configuration/ChatConfigurationMobileShell.vue +95 -0
  81. package/dist/runtime/embed/components/configuration/ChatConfigurationMobileShell.vue.d.ts +34 -0
  82. package/dist/runtime/server/api/conversations/[id]/messages/[messageId]/retry.post.js +3 -1
  83. package/dist/runtime/server/api/conversations/[id]/messages/index.get.js +29 -5
  84. package/dist/runtime/server/utils/conversation-message-sync.d.ts +8 -2
  85. package/dist/runtime/server/utils/conversation-message-sync.js +52 -6
  86. package/dist/runtime/types/chat-auth.d.ts +1 -0
  87. package/dist/runtime/types/embed.d.ts +2 -0
  88. package/dist/runtime/utils/breakpoints.d.ts +1 -0
  89. package/dist/runtime/utils/breakpoints.js +1 -0
  90. package/package.json +1 -1
@@ -0,0 +1,122 @@
1
+ import type { DeepReadonly } from 'vue';
2
+ import type { Conversation, ConversationFile, ConversationWithMessages, FileUploadInput, Message, ModelOption, TopbarTab } from '../../../../types/chat.js';
3
+ import type { TelaAgentInputVariable } from '../../../../types/tela-agent.js';
4
+ import type { WorkspaceSettings } from '../../../../types/workspace-settings-data.js';
5
+ import type { ChatActor } from '../../../../utils/tela-chat.js';
6
+ type __VLS_Props = {
7
+ currentConversation: ConversationWithMessages | null;
8
+ displayTitle: string;
9
+ conversationCreator?: ChatActor | null;
10
+ currentUser?: ChatActor | null;
11
+ activeTab: TopbarTab;
12
+ activeConversationId: string | null;
13
+ allowModelSelection?: boolean;
14
+ agentInputSchema?: readonly TelaAgentInputVariable[] | null;
15
+ agentInputSchemaLoading?: boolean;
16
+ conversations: DeepReadonly<Conversation[]>;
17
+ conversationsLoading?: boolean;
18
+ conversationFiles: ConversationFile[];
19
+ drawerOpen: boolean;
20
+ editTitle: string;
21
+ filesCount: number;
22
+ generatingTitle?: boolean;
23
+ hasMessages: boolean;
24
+ hasPendingMessage?: boolean;
25
+ hideSettings?: boolean;
26
+ hideSidebar?: boolean;
27
+ isEditing: boolean;
28
+ loading?: boolean;
29
+ messages: Message[];
30
+ model: ModelOption;
31
+ showCancelButton?: boolean;
32
+ showDebugOption?: boolean;
33
+ showModelSelector?: boolean;
34
+ showOutdatedBadge?: boolean;
35
+ showOutdatedBanner?: boolean;
36
+ showUsageTab?: boolean;
37
+ workspaceLogo?: string;
38
+ workspaceName: string;
39
+ workspaceSettings?: DeepReadonly<WorkspaceSettings> | null;
40
+ workspaceSheetOpen: boolean;
41
+ };
42
+ declare var __VLS_54: {}, __VLS_99: {}, __VLS_101: {};
43
+ type __VLS_Slots = {} & {
44
+ loading?: (props: typeof __VLS_54) => any;
45
+ } & {
46
+ empty?: (props: typeof __VLS_99) => any;
47
+ } & {
48
+ default?: (props: typeof __VLS_101) => any;
49
+ };
50
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
51
+ delete: () => any;
52
+ cancel: () => any;
53
+ rename: () => any;
54
+ duplicate: () => any;
55
+ export: () => any;
56
+ saveTitle: () => any;
57
+ send: (content: string, files: FileUploadInput[], model?: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6" | undefined, agentInputs?: ({
58
+ type: "file";
59
+ name: string;
60
+ vaultRef: string;
61
+ filename: string;
62
+ metadata?: string | undefined;
63
+ } | {
64
+ type: "text";
65
+ name: string;
66
+ content: string;
67
+ })[] | undefined) => any;
68
+ "update:model": (value: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6") => any;
69
+ settings: () => any;
70
+ "update:editTitle": (value: string) => any;
71
+ cancelEditing: () => any;
72
+ copyLink: () => any;
73
+ debug: () => any;
74
+ tabChange: (tab: TopbarTab) => any;
75
+ newConversation: () => any;
76
+ switchWorkspace: () => any;
77
+ signout: () => any;
78
+ dismissOutdatedBanner: () => any;
79
+ selectConversation: (id: string) => any;
80
+ "update:drawerOpen": (value: boolean) => any;
81
+ "update:workspaceSheetOpen": (value: boolean) => any;
82
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
83
+ onDelete?: (() => any) | undefined;
84
+ onCancel?: (() => any) | undefined;
85
+ onRename?: (() => any) | undefined;
86
+ onDuplicate?: (() => any) | undefined;
87
+ onExport?: (() => any) | undefined;
88
+ onSaveTitle?: (() => any) | undefined;
89
+ onSend?: ((content: string, files: FileUploadInput[], model?: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6" | undefined, agentInputs?: ({
90
+ type: "file";
91
+ name: string;
92
+ vaultRef: string;
93
+ filename: string;
94
+ metadata?: string | undefined;
95
+ } | {
96
+ type: "text";
97
+ name: string;
98
+ content: string;
99
+ })[] | undefined) => any) | undefined;
100
+ "onUpdate:model"?: ((value: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6") => any) | undefined;
101
+ onSettings?: (() => any) | undefined;
102
+ "onUpdate:editTitle"?: ((value: string) => any) | undefined;
103
+ onCancelEditing?: (() => any) | undefined;
104
+ onCopyLink?: (() => any) | undefined;
105
+ onDebug?: (() => any) | undefined;
106
+ onTabChange?: ((tab: TopbarTab) => any) | undefined;
107
+ onNewConversation?: (() => any) | undefined;
108
+ onSwitchWorkspace?: (() => any) | undefined;
109
+ onSignout?: (() => any) | undefined;
110
+ onDismissOutdatedBanner?: (() => any) | undefined;
111
+ onSelectConversation?: ((id: string) => any) | undefined;
112
+ "onUpdate:drawerOpen"?: ((value: boolean) => any) | undefined;
113
+ "onUpdate:workspaceSheetOpen"?: ((value: boolean) => any) | undefined;
114
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
115
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
116
+ declare const _default: typeof __VLS_export;
117
+ export default _default;
118
+ type __VLS_WithSlots<T, S> = T & {
119
+ new (): {
120
+ $slots: S;
121
+ };
122
+ };
@@ -0,0 +1,283 @@
1
+ <script setup>
2
+ import ChatMessageInput from "../../message-input.vue";
3
+ import ChatMobileFilesView from "../files/files-view.vue";
4
+ import ChatMobileHomeHeader from "../home/header.vue";
5
+ import ChatMobileHomeRecents from "../home/recents.vue";
6
+ import ChatMobileHomeSuggestions from "../home/suggestions.vue";
7
+ import ChatMobileBottomSheet from "../primitives/bottom-sheet.vue";
8
+ import ChatMobileUsageView from "../usage/usage-view.vue";
9
+ import ChatMobileDrawer from "./drawer.vue";
10
+ import ChatMobileHeader from "./header.vue";
11
+ import ChatMobileOutdatedSettingsSheet from "./outdated-settings-sheet.vue";
12
+ import ChatMobileWorkspaceSheet from "./workspace-sheet.vue";
13
+ const props = defineProps({
14
+ currentConversation: { type: [Object, null], required: true },
15
+ displayTitle: { type: String, required: true },
16
+ conversationCreator: { type: [Object, null], required: false },
17
+ currentUser: { type: [Object, null], required: false },
18
+ activeTab: { type: String, required: true },
19
+ activeConversationId: { type: [String, null], required: true },
20
+ allowModelSelection: { type: Boolean, required: false },
21
+ agentInputSchema: { type: [Array, null], required: false },
22
+ agentInputSchemaLoading: { type: Boolean, required: false },
23
+ conversations: { type: null, required: true },
24
+ conversationsLoading: { type: Boolean, required: false },
25
+ conversationFiles: { type: Array, required: true },
26
+ drawerOpen: { type: Boolean, required: true },
27
+ editTitle: { type: String, required: true },
28
+ filesCount: { type: Number, required: true },
29
+ generatingTitle: { type: Boolean, required: false },
30
+ hasMessages: { type: Boolean, required: true },
31
+ hasPendingMessage: { type: Boolean, required: false },
32
+ hideSettings: { type: Boolean, required: false },
33
+ hideSidebar: { type: Boolean, required: false },
34
+ isEditing: { type: Boolean, required: true },
35
+ loading: { type: Boolean, required: false },
36
+ messages: { type: Array, required: true },
37
+ model: { type: null, required: true },
38
+ showCancelButton: { type: Boolean, required: false },
39
+ showDebugOption: { type: Boolean, required: false },
40
+ showModelSelector: { type: Boolean, required: false },
41
+ showOutdatedBadge: { type: Boolean, required: false },
42
+ showOutdatedBanner: { type: Boolean, required: false },
43
+ showUsageTab: { type: Boolean, required: false },
44
+ workspaceLogo: { type: String, required: false },
45
+ workspaceName: { type: String, required: true },
46
+ workspaceSettings: { type: null, required: false },
47
+ workspaceSheetOpen: { type: Boolean, required: true }
48
+ });
49
+ const emit = defineEmits(["cancel", "cancelEditing", "copyLink", "debug", "delete", "dismissOutdatedBanner", "duplicate", "export", "newConversation", "rename", "saveTitle", "selectConversation", "send", "settings", "signout", "switchWorkspace", "tabChange", "update:drawerOpen", "update:editTitle", "update:model", "update:workspaceSheetOpen"]);
50
+ const renameInputRef = ref(null);
51
+ const homeInputRef = ref(null);
52
+ const outdatedSettingsSheetOpen = ref(false);
53
+ const showConversationHistory = computed(() => !props.hideSidebar);
54
+ const showWorkspaceSettings = computed(() => !props.hideSettings);
55
+ const editTitleModel = computed({
56
+ get: () => props.editTitle,
57
+ set: (value) => emit("update:editTitle", value)
58
+ });
59
+ const selectedModel = computed({
60
+ get: () => props.model,
61
+ set: (value) => emit("update:model", value)
62
+ });
63
+ watch(() => props.isEditing, async (editing) => {
64
+ if (!editing)
65
+ return;
66
+ await nextTick();
67
+ renameInputRef.value?.focus();
68
+ renameInputRef.value?.select();
69
+ });
70
+ watch(() => props.showOutdatedBanner, (show) => {
71
+ if (show) {
72
+ outdatedSettingsSheetOpen.value = true;
73
+ }
74
+ }, { immediate: true });
75
+ watch(showConversationHistory, (show) => {
76
+ if (!show && props.drawerOpen)
77
+ setDrawerOpen(false);
78
+ });
79
+ watch(showWorkspaceSettings, (show) => {
80
+ if (!show && props.workspaceSheetOpen)
81
+ setWorkspaceSheetOpen(false);
82
+ });
83
+ function setDrawerOpen(open) {
84
+ if (open && !showConversationHistory.value)
85
+ return;
86
+ emit("update:drawerOpen", open);
87
+ }
88
+ function setWorkspaceSheetOpen(open) {
89
+ if (open && !showWorkspaceSettings.value)
90
+ return;
91
+ emit("update:workspaceSheetOpen", open);
92
+ }
93
+ function applySuggestion(label) {
94
+ homeInputRef.value?.setDraft(label);
95
+ }
96
+ function handleSeeAllConversations() {
97
+ if (!showConversationHistory.value)
98
+ return;
99
+ setDrawerOpen(true);
100
+ }
101
+ function openOutdatedSettingsSheet() {
102
+ outdatedSettingsSheetOpen.value = true;
103
+ }
104
+ function dismissOutdatedSettingsSheet() {
105
+ outdatedSettingsSheetOpen.value = false;
106
+ emit("dismissOutdatedBanner");
107
+ }
108
+ function startNewConversationFromOutdatedSettings() {
109
+ outdatedSettingsSheetOpen.value = false;
110
+ emit("newConversation");
111
+ }
112
+ </script>
113
+
114
+ <template>
115
+ <ChatMobileHeader
116
+ v-if="currentConversation"
117
+ :title="displayTitle"
118
+ :creator-name="conversationCreator?.name ?? void 0"
119
+ :creator-email="currentConversation.createdBy ?? void 0"
120
+ :creator-image="conversationCreator?.image ?? void 0"
121
+ :updated-at="currentConversation.updatedAt"
122
+ :generating-title="generatingTitle"
123
+ :files-count="filesCount"
124
+ :active-tab="activeTab"
125
+ :show-outdated-badge="showOutdatedBanner || showOutdatedBadge"
126
+ :show-usage-tab="showUsageTab"
127
+ :show-debug-option="showDebugOption"
128
+ :show-drawer-button="showConversationHistory"
129
+ @open-drawer="setDrawerOpen(true)"
130
+ @open-outdated-settings="openOutdatedSettingsSheet"
131
+ @rename="emit('rename')"
132
+ @duplicate="emit('duplicate')"
133
+ @export="emit('export')"
134
+ @copy-link="emit('copyLink')"
135
+ @debug="emit('debug')"
136
+ @delete="emit('delete')"
137
+ @tab-change="emit('tabChange', $event)"
138
+ />
139
+
140
+ <ChatMobileDrawer
141
+ v-if="showConversationHistory"
142
+ :open="drawerOpen"
143
+ :conversations="conversations"
144
+ :active-id="activeConversationId"
145
+ :loading="conversationsLoading"
146
+ :user-name="currentUser?.name ?? void 0"
147
+ :user-email="currentUser?.email ?? void 0"
148
+ :user-image="currentUser?.image ?? void 0"
149
+ @close="setDrawerOpen(false)"
150
+ @select="emit('selectConversation', $event)"
151
+ @new-convo="emit('newConversation')"
152
+ />
153
+
154
+ <ChatMobileBottomSheet
155
+ :open="isEditing"
156
+ title="Renomear conversa"
157
+ @close="emit('cancelEditing')"
158
+ >
159
+ <div flex="~ col" gap-12px px-18px py-12px>
160
+ <input
161
+ ref="renameInputRef"
162
+ v-model="editTitleModel"
163
+ type="text"
164
+ class="rename-input"
165
+ placeholder="Nome da conversa"
166
+ @keydown.enter.prevent="emit('saveTitle')"
167
+ @keydown.escape.prevent="emit('cancelEditing')"
168
+ >
169
+ <div flex items-center justify-end gap-8px>
170
+ <button class="rename-btn rename-btn--ghost" @click="emit('cancelEditing')">
171
+ Cancelar
172
+ </button>
173
+ <button class="rename-btn rename-btn--primary" :disabled="!editTitleModel.trim()" @click="emit('saveTitle')">
174
+ Salvar
175
+ </button>
176
+ </div>
177
+ </div>
178
+ </ChatMobileBottomSheet>
179
+
180
+ <ChatMobileOutdatedSettingsSheet
181
+ :open="outdatedSettingsSheetOpen"
182
+ @close="dismissOutdatedSettingsSheet"
183
+ @dismiss="dismissOutdatedSettingsSheet"
184
+ @new-conversation="startNewConversationFromOutdatedSettings"
185
+ />
186
+
187
+ <template v-if="activeTab === 'files' && currentConversation">
188
+ <ChatMobileFilesView
189
+ :conversation-id="currentConversation.id"
190
+ @view-in-chat="emit('tabChange', 'chat')"
191
+ />
192
+ </template>
193
+
194
+ <template v-else-if="activeTab === 'usage' && showUsageTab && currentConversation">
195
+ <ChatMobileUsageView
196
+ :conversation-id="currentConversation.id"
197
+ :created-at="currentConversation.createdAt"
198
+ :updated-at="currentConversation.updatedAt"
199
+ />
200
+ </template>
201
+
202
+ <template v-else-if="loading">
203
+ <slot name="loading" />
204
+ </template>
205
+
206
+ <template v-else-if="!currentConversation">
207
+ <ChatMobileHomeHeader
208
+ :workspace-name="workspaceName"
209
+ :workspace-logo="workspaceLogo"
210
+ :workspace-initial="workspaceName"
211
+ :show-drawer-button="showConversationHistory"
212
+ :show-workspace-button="showWorkspaceSettings"
213
+ @open-drawer="setDrawerOpen(true)"
214
+ @open-workspace="setWorkspaceSheetOpen(true)"
215
+ />
216
+ <div flex="~ col 1" overflow-y-auto pt-54px min-h-0>
217
+ <div flex="~ col 1" justify-center>
218
+ <div px-20px pb-20px text-center>
219
+ <h1 text-24px font-580 text-neutral-900 leading-28px tracking="-.4px">
220
+ Olá, {{ currentUser?.name?.split(" ")[0] ?? "usu\xE1rio" }}
221
+ </h1>
222
+ <p text-14px text-neutral-500 leading-18px mt-6px>
223
+ Como posso te ajudar hoje?
224
+ </p>
225
+ </div>
226
+
227
+ <div px-14px pb-12px>
228
+ <ChatMessageInput
229
+ ref="homeInputRef"
230
+ v-model:model="selectedModel"
231
+ :disabled="hasPendingMessage"
232
+ :loading="hasPendingMessage"
233
+ :creator-name="currentUser?.name ?? void 0"
234
+ :creator-email="currentUser?.email ?? void 0"
235
+ :creator-image="currentUser?.image ?? void 0"
236
+ :messages="messages"
237
+ :conversation-files="conversationFiles"
238
+ :workspace-settings="workspaceSettings"
239
+ :allow-model-selection="allowModelSelection"
240
+ :agent-input-schema="agentInputSchema"
241
+ :agent-input-schema-loading="agentInputSchemaLoading"
242
+ :show-model-selector="showModelSelector"
243
+ :show-cancel-button="showCancelButton"
244
+ centered
245
+ @send="(content, files, model, agentInputs) => emit('send', content, files, model, agentInputs)"
246
+ @cancel="emit('cancel')"
247
+ />
248
+ </div>
249
+
250
+ <ChatMobileHomeSuggestions @pick="applySuggestion" />
251
+ </div>
252
+
253
+ <div v-if="showConversationHistory" mt-auto pt-12px pb-20px b-t=".5px solid #E8E8E8">
254
+ <ChatMobileHomeRecents
255
+ :conversations="conversations"
256
+ @select="emit('selectConversation', $event)"
257
+ @see-all="handleSeeAllConversations"
258
+ />
259
+ </div>
260
+ </div>
261
+
262
+ <ChatMobileWorkspaceSheet
263
+ v-if="showWorkspaceSettings"
264
+ :open="workspaceSheetOpen"
265
+ :workspace-name="workspaceName"
266
+ :workspace-logo="workspaceLogo"
267
+ @close="setWorkspaceSheetOpen(false)"
268
+ @settings="emit('settings')"
269
+ @switch-workspace="emit('switchWorkspace')"
270
+ @signout="emit('signout')"
271
+ />
272
+ </template>
273
+
274
+ <template v-else-if="!hasMessages">
275
+ <slot name="empty" />
276
+ </template>
277
+
278
+ <slot v-else />
279
+ </template>
280
+
281
+ <style scoped>
282
+ .rename-input{background:#fff;border:.5px solid #d9d9d9;border-radius:10px;color:#171717;font-size:16px;letter-spacing:-.2px;line-height:20px;outline:none;padding:12px 14px;transition:border-color .15s;width:100%}.rename-input:focus{border-color:#171717}.rename-btn{border-radius:10px;font-size:14px;font-weight:500;letter-spacing:-.15px;line-height:18px;padding:9px 14px;transition:background .12s,opacity .12s}.rename-btn--ghost{background:transparent;color:#171717}.rename-btn--ghost:active{background:#f5f5f5}.rename-btn--primary{background:#171717;color:#fff}.rename-btn--primary:disabled{opacity:.4}
283
+ </style>
@@ -0,0 +1,122 @@
1
+ import type { DeepReadonly } from 'vue';
2
+ import type { Conversation, ConversationFile, ConversationWithMessages, FileUploadInput, Message, ModelOption, TopbarTab } from '../../../../types/chat.js';
3
+ import type { TelaAgentInputVariable } from '../../../../types/tela-agent.js';
4
+ import type { WorkspaceSettings } from '../../../../types/workspace-settings-data.js';
5
+ import type { ChatActor } from '../../../../utils/tela-chat.js';
6
+ type __VLS_Props = {
7
+ currentConversation: ConversationWithMessages | null;
8
+ displayTitle: string;
9
+ conversationCreator?: ChatActor | null;
10
+ currentUser?: ChatActor | null;
11
+ activeTab: TopbarTab;
12
+ activeConversationId: string | null;
13
+ allowModelSelection?: boolean;
14
+ agentInputSchema?: readonly TelaAgentInputVariable[] | null;
15
+ agentInputSchemaLoading?: boolean;
16
+ conversations: DeepReadonly<Conversation[]>;
17
+ conversationsLoading?: boolean;
18
+ conversationFiles: ConversationFile[];
19
+ drawerOpen: boolean;
20
+ editTitle: string;
21
+ filesCount: number;
22
+ generatingTitle?: boolean;
23
+ hasMessages: boolean;
24
+ hasPendingMessage?: boolean;
25
+ hideSettings?: boolean;
26
+ hideSidebar?: boolean;
27
+ isEditing: boolean;
28
+ loading?: boolean;
29
+ messages: Message[];
30
+ model: ModelOption;
31
+ showCancelButton?: boolean;
32
+ showDebugOption?: boolean;
33
+ showModelSelector?: boolean;
34
+ showOutdatedBadge?: boolean;
35
+ showOutdatedBanner?: boolean;
36
+ showUsageTab?: boolean;
37
+ workspaceLogo?: string;
38
+ workspaceName: string;
39
+ workspaceSettings?: DeepReadonly<WorkspaceSettings> | null;
40
+ workspaceSheetOpen: boolean;
41
+ };
42
+ declare var __VLS_54: {}, __VLS_99: {}, __VLS_101: {};
43
+ type __VLS_Slots = {} & {
44
+ loading?: (props: typeof __VLS_54) => any;
45
+ } & {
46
+ empty?: (props: typeof __VLS_99) => any;
47
+ } & {
48
+ default?: (props: typeof __VLS_101) => any;
49
+ };
50
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
51
+ delete: () => any;
52
+ cancel: () => any;
53
+ rename: () => any;
54
+ duplicate: () => any;
55
+ export: () => any;
56
+ saveTitle: () => any;
57
+ send: (content: string, files: FileUploadInput[], model?: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6" | undefined, agentInputs?: ({
58
+ type: "file";
59
+ name: string;
60
+ vaultRef: string;
61
+ filename: string;
62
+ metadata?: string | undefined;
63
+ } | {
64
+ type: "text";
65
+ name: string;
66
+ content: string;
67
+ })[] | undefined) => any;
68
+ "update:model": (value: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6") => any;
69
+ settings: () => any;
70
+ "update:editTitle": (value: string) => any;
71
+ cancelEditing: () => any;
72
+ copyLink: () => any;
73
+ debug: () => any;
74
+ tabChange: (tab: TopbarTab) => any;
75
+ newConversation: () => any;
76
+ switchWorkspace: () => any;
77
+ signout: () => any;
78
+ dismissOutdatedBanner: () => any;
79
+ selectConversation: (id: string) => any;
80
+ "update:drawerOpen": (value: boolean) => any;
81
+ "update:workspaceSheetOpen": (value: boolean) => any;
82
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
83
+ onDelete?: (() => any) | undefined;
84
+ onCancel?: (() => any) | undefined;
85
+ onRename?: (() => any) | undefined;
86
+ onDuplicate?: (() => any) | undefined;
87
+ onExport?: (() => any) | undefined;
88
+ onSaveTitle?: (() => any) | undefined;
89
+ onSend?: ((content: string, files: FileUploadInput[], model?: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6" | undefined, agentInputs?: ({
90
+ type: "file";
91
+ name: string;
92
+ vaultRef: string;
93
+ filename: string;
94
+ metadata?: string | undefined;
95
+ } | {
96
+ type: "text";
97
+ name: string;
98
+ content: string;
99
+ })[] | undefined) => any) | undefined;
100
+ "onUpdate:model"?: ((value: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6") => any) | undefined;
101
+ onSettings?: (() => any) | undefined;
102
+ "onUpdate:editTitle"?: ((value: string) => any) | undefined;
103
+ onCancelEditing?: (() => any) | undefined;
104
+ onCopyLink?: (() => any) | undefined;
105
+ onDebug?: (() => any) | undefined;
106
+ onTabChange?: ((tab: TopbarTab) => any) | undefined;
107
+ onNewConversation?: (() => any) | undefined;
108
+ onSwitchWorkspace?: (() => any) | undefined;
109
+ onSignout?: (() => any) | undefined;
110
+ onDismissOutdatedBanner?: (() => any) | undefined;
111
+ onSelectConversation?: ((id: string) => any) | undefined;
112
+ "onUpdate:drawerOpen"?: ((value: boolean) => any) | undefined;
113
+ "onUpdate:workspaceSheetOpen"?: ((value: boolean) => any) | undefined;
114
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
115
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
116
+ declare const _default: typeof __VLS_export;
117
+ export default _default;
118
+ type __VLS_WithSlots<T, S> = T & {
119
+ new (): {
120
+ $slots: S;
121
+ };
122
+ };
@@ -0,0 +1,19 @@
1
+ type __VLS_Props = {
2
+ open: boolean;
3
+ workspaceName?: string;
4
+ workspaceLogo?: string;
5
+ workspaceSubtitle?: string;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
+ close: () => void;
9
+ settings: () => void;
10
+ switchWorkspace: () => void;
11
+ signout: () => void;
12
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
13
+ onClose?: (() => any) | undefined;
14
+ onSettings?: (() => any) | undefined;
15
+ onSwitchWorkspace?: (() => any) | undefined;
16
+ onSignout?: (() => any) | undefined;
17
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ declare const _default: typeof __VLS_export;
19
+ export default _default;
@@ -0,0 +1,51 @@
1
+ <script setup>
2
+ import ChatMobileBottomSheet from "../primitives/bottom-sheet.vue";
3
+ const props = defineProps({
4
+ open: { type: Boolean, required: true },
5
+ workspaceName: { type: String, required: false },
6
+ workspaceLogo: { type: String, required: false },
7
+ workspaceSubtitle: { type: String, required: false }
8
+ });
9
+ const emit = defineEmits(["close", "settings", "switchWorkspace", "signout"]);
10
+ const initial = computed(() => (props.workspaceName ?? "M").charAt(0).toUpperCase());
11
+ function pick(action) {
12
+ emit(action);
13
+ emit("close");
14
+ }
15
+ </script>
16
+
17
+ <template>
18
+ <ChatMobileBottomSheet :open="open" @close="emit('close')">
19
+ <div class="identity-row">
20
+ <div class="ws-tile">
21
+ <img v-if="workspaceLogo" :src="workspaceLogo" :alt="workspaceName ?? ''" class="ws-tile__img">
22
+ <span v-else>{{ initial }}</span>
23
+ </div>
24
+ <div flex="~ col" gap-2px min-w-0 flex-1>
25
+ <span class="ws-name">{{ workspaceName ?? "Workspace" }}</span>
26
+ <span class="ws-subtitle">{{ workspaceSubtitle ?? "Workspace pessoal" }}</span>
27
+ </div>
28
+ </div>
29
+
30
+ <div class="menu">
31
+ <button class="menu__item" @click="pick('settings')">
32
+ <span i-ph-gear-six class="menu__icon" />
33
+ <span class="menu__label">Configurações</span>
34
+ </button>
35
+ <div class="menu__divider" />
36
+ <button class="menu__item" @click="pick('switchWorkspace')">
37
+ <span i-ph-arrows-left-right class="menu__icon" />
38
+ <span class="menu__label">Trocar Workspace</span>
39
+ </button>
40
+ <div class="menu__divider" />
41
+ <button class="menu__item" @click="pick('signout')">
42
+ <span i-ph-sign-out class="menu__icon" />
43
+ <span class="menu__label">Sair</span>
44
+ </button>
45
+ </div>
46
+ </ChatMobileBottomSheet>
47
+ </template>
48
+
49
+ <style scoped>
50
+ .identity-row{align-items:center;border-bottom:.5px solid #f5f5f5;display:flex;gap:12px;padding:8px 18px 14px}.ws-tile{align-items:center;background:#171717;border-radius:8px;color:#fff;display:inline-flex;flex-shrink:0;font-size:16px;font-weight:580;height:40px;justify-content:center;overflow:hidden;width:40px}.ws-tile__img{height:100%;-o-object-fit:cover;object-fit:cover;width:100%}.ws-name{color:#171717;font-size:14px;font-weight:580;letter-spacing:-.15px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ws-subtitle{color:#a3a3a3;font-size:12px;line-height:16px}.menu{padding-bottom:18px}.menu__item{align-items:center;background:transparent;color:#171717;display:flex;gap:14px;padding:14px 18px;transition:background .12s;width:100%}.menu__item:active{background:#f5f5f5}.menu__icon{color:#404040;font-size:20px}.menu__label{color:#171717;font-size:15px;font-weight:500;line-height:20px}.menu__divider{background:#f5f5f5;height:.5px;margin:0 18px}
51
+ </style>
@@ -0,0 +1,19 @@
1
+ type __VLS_Props = {
2
+ open: boolean;
3
+ workspaceName?: string;
4
+ workspaceLogo?: string;
5
+ workspaceSubtitle?: string;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
+ close: () => void;
9
+ settings: () => void;
10
+ switchWorkspace: () => void;
11
+ signout: () => void;
12
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
13
+ onClose?: (() => any) | undefined;
14
+ onSettings?: (() => any) | undefined;
15
+ onSwitchWorkspace?: (() => any) | undefined;
16
+ onSignout?: (() => any) | undefined;
17
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ declare const _default: typeof __VLS_export;
19
+ export default _default;
@@ -0,0 +1,8 @@
1
+ type __VLS_Props = {
2
+ conversationId: string;
3
+ createdAt?: string | Date;
4
+ updatedAt?: string | Date;
5
+ };
6
+ 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>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;