@meistrari/chat-nuxt 1.9.0 → 1.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.
- package/README.md +1 -0
- package/dist/module.json +1 -1
- package/dist/runtime/components/MeistrariChatEmbed.vue +3 -0
- package/dist/runtime/components/chat/conversation-creator-filter.d.vue.ts +3 -0
- package/dist/runtime/components/chat/conversation-creator-filter.vue +95 -0
- package/dist/runtime/components/chat/conversation-creator-filter.vue.d.ts +3 -0
- package/dist/runtime/components/chat/conversation-item.d.vue.ts +1 -0
- package/dist/runtime/components/chat/conversation-item.vue +44 -5
- package/dist/runtime/components/chat/conversation-item.vue.d.ts +1 -0
- package/dist/runtime/components/chat/conversation-list.d.vue.ts +2 -0
- package/dist/runtime/components/chat/conversation-list.vue +19 -6
- package/dist/runtime/components/chat/conversation-list.vue.d.ts +2 -0
- package/dist/runtime/components/chat/conversation-search.vue +21 -2
- package/dist/runtime/components/chat/mobile/shell/drawer.vue +1 -0
- package/dist/runtime/components/chat/mobile/shell/shell.d.vue.ts +2 -2
- package/dist/runtime/components/chat/mobile/shell/shell.vue.d.ts +2 -2
- package/dist/runtime/composables/useConversations.d.ts +2 -0
- package/dist/runtime/composables/useConversations.js +250 -110
- package/dist/runtime/composables/useEmbedConfig.d.ts +3 -0
- package/dist/runtime/composables/useEmbedConfig.js +4 -0
- package/dist/runtime/embed/components/ChatEmbed.vue +2 -0
- package/dist/runtime/embed/components/ChatEmbedInner.vue +10 -39
- package/dist/runtime/server/api/chat/conversations/metadata.get.d.ts +1 -0
- package/dist/runtime/server/api/chat/conversations/metadata.get.js +1 -0
- package/dist/runtime/server/api/conversations/index.get.js +5 -4
- package/dist/runtime/server/api/conversations/metadata.get.d.ts +2 -0
- package/dist/runtime/server/api/conversations/metadata.get.js +20 -0
- package/dist/runtime/server/utils/conversation-list.d.ts +4 -0
- package/dist/runtime/server/utils/conversation-list.js +28 -0
- package/dist/runtime/types/chat.d.ts +12 -0
- package/dist/runtime/types/chat.js +4 -0
- package/dist/runtime/types/embed.d.ts +3 -0
- package/dist/runtime/utils/conversation-creator-filter.d.ts +5 -0
- package/dist/runtime/utils/conversation-creator-filter.js +24 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -220,6 +220,7 @@ Key props for embedding:
|
|
|
220
220
|
| `conversationId` | `string \| null` | `null` | Controlled conversation (supports v-model) |
|
|
221
221
|
| `initialConversationId` | `string \| null` | `null` | Open this conversation on mount |
|
|
222
222
|
| `conversationScope` | `string \| null` | `null` | Isolate conversation history by technical scope within the current workspace and runtime |
|
|
223
|
+
| `defaultConversationCreatorFilter` | `'all' \| 'mine'` | `'all'` | Initial sidebar creator filter |
|
|
223
224
|
| `telaAgentId` | `string` | — | Use Tela agent mode for this embed |
|
|
224
225
|
| `telaAgentInputs` | `TelaAgentExecutionInput[] \| null` | `undefined` | Inputs sent with each Tela agent run; hides the variables panel when non-null |
|
|
225
226
|
| `workspaceSettings` | `WorkspaceSettings \| null` | `null` | Override settings from host app |
|
package/dist/module.json
CHANGED
|
@@ -3,6 +3,7 @@ const props = defineProps({
|
|
|
3
3
|
conversationId: { type: [String, null], required: false },
|
|
4
4
|
initialConversationId: { type: [String, null], required: false },
|
|
5
5
|
conversationScope: { type: [String, null], required: false },
|
|
6
|
+
defaultConversationCreatorFilter: { type: String, required: false },
|
|
6
7
|
hideSidebar: { type: Boolean, required: false },
|
|
7
8
|
hideSettings: { type: Boolean, required: false },
|
|
8
9
|
loadingMessages: { type: [Array, null], required: false },
|
|
@@ -27,6 +28,7 @@ const hideSettings = computed(() => props.hideSettings ?? false);
|
|
|
27
28
|
:conversation-id="conversationId"
|
|
28
29
|
:initial-conversation-id="initialConversationId"
|
|
29
30
|
:conversation-scope="conversationScope"
|
|
31
|
+
:default-conversation-creator-filter="defaultConversationCreatorFilter"
|
|
30
32
|
:hide-sidebar="hideSidebar"
|
|
31
33
|
:hide-settings="hideSettings"
|
|
32
34
|
:features="features"
|
|
@@ -44,6 +46,7 @@ const hideSettings = computed(() => props.hideSettings ?? false);
|
|
|
44
46
|
:conversation-id="conversationId"
|
|
45
47
|
:initial-conversation-id="initialConversationId"
|
|
46
48
|
:conversation-scope="conversationScope"
|
|
49
|
+
:default-conversation-creator-filter="defaultConversationCreatorFilter"
|
|
47
50
|
:hide-sidebar="hideSidebar"
|
|
48
51
|
:hide-settings="hideSettings"
|
|
49
52
|
:features="features"
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { nextTick } from "vue";
|
|
3
|
+
import { CONVERSATION_CREATOR_FILTER_OPTIONS } from "../../types/chat";
|
|
4
|
+
import {
|
|
5
|
+
hasConversationCreatorFilterResults,
|
|
6
|
+
resolveConversationCreatorFilterKeyboardTarget
|
|
7
|
+
} from "../../utils/conversation-creator-filter";
|
|
8
|
+
const { conversationCreatorFilter, conversationCreatorFilterCounts, fetchConversations } = useConversations();
|
|
9
|
+
const isUpdating = ref(false);
|
|
10
|
+
const filterButtonElements = ref([]);
|
|
11
|
+
const filterOptions = computed(() => CONVERSATION_CREATOR_FILTER_OPTIONS.map((option) => ({
|
|
12
|
+
...option,
|
|
13
|
+
count: conversationCreatorFilterCounts.value[option.value]
|
|
14
|
+
})));
|
|
15
|
+
const showConversationCreatorFilter = computed(
|
|
16
|
+
() => hasConversationCreatorFilterResults(conversationCreatorFilterCounts.value)
|
|
17
|
+
);
|
|
18
|
+
function isConversationCreatorFilter(value) {
|
|
19
|
+
return value === "all" || value === "mine";
|
|
20
|
+
}
|
|
21
|
+
function setFilterButtonElement(element, index) {
|
|
22
|
+
if (element && "focus" in element) {
|
|
23
|
+
filterButtonElements.value[index] = element;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function focusFilterButton(value) {
|
|
27
|
+
const index = filterOptions.value.findIndex((option) => option.value === value);
|
|
28
|
+
filterButtonElements.value[index]?.focus();
|
|
29
|
+
}
|
|
30
|
+
async function handleFilterUpdate(value, options = {}) {
|
|
31
|
+
if (isUpdating.value || !isConversationCreatorFilter(value) || value === conversationCreatorFilter.value)
|
|
32
|
+
return;
|
|
33
|
+
conversationCreatorFilter.value = value;
|
|
34
|
+
if (options.focus) {
|
|
35
|
+
await nextTick();
|
|
36
|
+
focusFilterButton(value);
|
|
37
|
+
}
|
|
38
|
+
isUpdating.value = true;
|
|
39
|
+
try {
|
|
40
|
+
await fetchConversations({ force: true });
|
|
41
|
+
} finally {
|
|
42
|
+
isUpdating.value = false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function handleFilterKeydown(event, value) {
|
|
46
|
+
const nextFilter = resolveConversationCreatorFilterKeyboardTarget(value, event.key);
|
|
47
|
+
if (!nextFilter || isUpdating.value)
|
|
48
|
+
return;
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
void handleFilterUpdate(nextFilter, { focus: true });
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<template>
|
|
55
|
+
<div
|
|
56
|
+
v-if="showConversationCreatorFilter"
|
|
57
|
+
role="tablist"
|
|
58
|
+
aria-label="Filtrar conversas por criador"
|
|
59
|
+
flex items-center w-full h-34px p-3px rounded-12px bg="#F1F1EF"
|
|
60
|
+
:class="{ 'opacity-70': isUpdating }"
|
|
61
|
+
>
|
|
62
|
+
<button
|
|
63
|
+
v-for="(option, index) in filterOptions"
|
|
64
|
+
:key="option.value"
|
|
65
|
+
:ref="(element) => setFilterButtonElement(element, index)"
|
|
66
|
+
type="button"
|
|
67
|
+
role="tab"
|
|
68
|
+
class="creator-filter-option"
|
|
69
|
+
flex-1 min-w-0 h-28px rounded-9px px-8px
|
|
70
|
+
flex items-center justify-center gap-4px
|
|
71
|
+
:class="conversationCreatorFilter === option.value ? 'creator-filter-option-active bg-white cursor-default' : 'bg-transparent hover:bg-white/45 cursor-pointer'"
|
|
72
|
+
:aria-disabled="isUpdating"
|
|
73
|
+
:aria-selected="conversationCreatorFilter === option.value"
|
|
74
|
+
:tabindex="conversationCreatorFilter === option.value ? 0 : -1"
|
|
75
|
+
@click="handleFilterUpdate(option.value)"
|
|
76
|
+
@keydown="handleFilterKeydown($event, option.value)"
|
|
77
|
+
>
|
|
78
|
+
<span
|
|
79
|
+
body-12-semibold leading-16px truncate
|
|
80
|
+
:class="conversationCreatorFilter === option.value ? 'text-neutral-950' : 'text-neutral-500'"
|
|
81
|
+
>
|
|
82
|
+
{{ option.label }}
|
|
83
|
+
</span>
|
|
84
|
+
<span
|
|
85
|
+
body-12-semibold leading-16px shrink-0 text-neutral-400
|
|
86
|
+
>
|
|
87
|
+
{{ option.count }}
|
|
88
|
+
</span>
|
|
89
|
+
</button>
|
|
90
|
+
</div>
|
|
91
|
+
</template>
|
|
92
|
+
|
|
93
|
+
<style scoped>
|
|
94
|
+
.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}
|
|
95
|
+
</style>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -4,6 +4,7 @@ type __VLS_Props = {
|
|
|
4
4
|
conversation: DeepReadonly<Conversation>;
|
|
5
5
|
active: boolean;
|
|
6
6
|
userImage?: string;
|
|
7
|
+
selectConversation?: (id: string) => void | Promise<void>;
|
|
7
8
|
};
|
|
8
9
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
10
|
delete: (id: string) => any;
|
|
@@ -5,12 +5,14 @@ import { capitalizeFirst } from "../../utils/string";
|
|
|
5
5
|
const props = defineProps({
|
|
6
6
|
conversation: { type: null, required: true },
|
|
7
7
|
active: { type: Boolean, required: true },
|
|
8
|
-
userImage: { type: String, required: false }
|
|
8
|
+
userImage: { type: String, required: false },
|
|
9
|
+
selectConversation: { type: Function, required: false }
|
|
9
10
|
});
|
|
10
11
|
const emit = defineEmits(["delete", "rename", "duplicate", "export"]);
|
|
11
12
|
const isRenamingInline = ref(false);
|
|
12
13
|
const renameTitle = ref("");
|
|
13
14
|
const renameInputRef = ref(null);
|
|
15
|
+
const isIgnoringInitialRenameBlur = ref(false);
|
|
14
16
|
const showDeleteModal = ref(false);
|
|
15
17
|
const { escape } = useMagicKeys();
|
|
16
18
|
watch(() => escape?.value, (pressed) => {
|
|
@@ -37,12 +39,26 @@ useMutationObserver(menuButtonRef, (mutations) => {
|
|
|
37
39
|
const conversationPath = computed(() => `/${props.conversation.id}`);
|
|
38
40
|
const conversationNavigationDelayMs = 250;
|
|
39
41
|
let conversationNavigationTimer = null;
|
|
42
|
+
let renameBlurTimer = null;
|
|
40
43
|
function clearPendingConversationNavigation() {
|
|
41
44
|
if (conversationNavigationTimer === null)
|
|
42
45
|
return;
|
|
43
46
|
clearTimeout(conversationNavigationTimer);
|
|
44
47
|
conversationNavigationTimer = null;
|
|
45
48
|
}
|
|
49
|
+
function clearRenameBlurTimer() {
|
|
50
|
+
if (renameBlurTimer === null)
|
|
51
|
+
return;
|
|
52
|
+
clearTimeout(renameBlurTimer);
|
|
53
|
+
renameBlurTimer = null;
|
|
54
|
+
}
|
|
55
|
+
function allowRenameBlurSoon() {
|
|
56
|
+
clearRenameBlurTimer();
|
|
57
|
+
renameBlurTimer = setTimeout(() => {
|
|
58
|
+
isIgnoringInitialRenameBlur.value = false;
|
|
59
|
+
renameBlurTimer = null;
|
|
60
|
+
}, 100);
|
|
61
|
+
}
|
|
46
62
|
function handleConversationClick(event) {
|
|
47
63
|
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
|
|
48
64
|
return;
|
|
@@ -51,7 +67,11 @@ function handleConversationClick(event) {
|
|
|
51
67
|
if (event.detail > 1)
|
|
52
68
|
return;
|
|
53
69
|
conversationNavigationTimer = setTimeout(() => {
|
|
54
|
-
|
|
70
|
+
if (props.selectConversation) {
|
|
71
|
+
void props.selectConversation(props.conversation.id);
|
|
72
|
+
} else {
|
|
73
|
+
navigateTo(conversationPath.value);
|
|
74
|
+
}
|
|
55
75
|
conversationNavigationTimer = null;
|
|
56
76
|
}, conversationNavigationDelayMs);
|
|
57
77
|
}
|
|
@@ -59,11 +79,14 @@ async function focusRenameInput() {
|
|
|
59
79
|
await nextTick();
|
|
60
80
|
renameInputRef.value?.focus();
|
|
61
81
|
renameInputRef.value?.select();
|
|
82
|
+
allowRenameBlurSoon();
|
|
62
83
|
}
|
|
63
84
|
function startRename() {
|
|
64
85
|
isMenuOpen.value = false;
|
|
65
86
|
clearPendingConversationNavigation();
|
|
87
|
+
clearRenameBlurTimer();
|
|
66
88
|
renameTitle.value = props.conversation.title;
|
|
89
|
+
isIgnoringInitialRenameBlur.value = true;
|
|
67
90
|
isRenamingInline.value = true;
|
|
68
91
|
void focusRenameInput();
|
|
69
92
|
}
|
|
@@ -73,7 +96,9 @@ function handleConversationDoubleClick() {
|
|
|
73
96
|
}
|
|
74
97
|
function cancelRename() {
|
|
75
98
|
isRenamingInline.value = false;
|
|
99
|
+
isIgnoringInitialRenameBlur.value = false;
|
|
76
100
|
renameTitle.value = "";
|
|
101
|
+
clearRenameBlurTimer();
|
|
77
102
|
}
|
|
78
103
|
function submitRename() {
|
|
79
104
|
if (!isRenamingInline.value)
|
|
@@ -86,6 +111,11 @@ function submitRename() {
|
|
|
86
111
|
emit("rename", props.conversation.id, title);
|
|
87
112
|
cancelRename();
|
|
88
113
|
}
|
|
114
|
+
function handleRenameBlur() {
|
|
115
|
+
if (isIgnoringInitialRenameBlur.value)
|
|
116
|
+
return;
|
|
117
|
+
submitRename();
|
|
118
|
+
}
|
|
89
119
|
const menuItems = [
|
|
90
120
|
{
|
|
91
121
|
label: "Renomear",
|
|
@@ -109,7 +139,10 @@ const menuItems = [
|
|
|
109
139
|
click: () => showDeleteModal.value = true
|
|
110
140
|
}
|
|
111
141
|
];
|
|
112
|
-
onBeforeUnmount(
|
|
142
|
+
onBeforeUnmount(() => {
|
|
143
|
+
clearPendingConversationNavigation();
|
|
144
|
+
clearRenameBlurTimer();
|
|
145
|
+
});
|
|
113
146
|
</script>
|
|
114
147
|
|
|
115
148
|
<template>
|
|
@@ -145,7 +178,7 @@ onBeforeUnmount(clearPendingConversationNavigation);
|
|
|
145
178
|
bg-transparent border-none outline-none
|
|
146
179
|
text-14px font-medium text-neutral-700 leading-18px tracking="-.15px"
|
|
147
180
|
p-0
|
|
148
|
-
@blur="
|
|
181
|
+
@blur="handleRenameBlur"
|
|
149
182
|
@keydown.enter.prevent="submitRename"
|
|
150
183
|
@keydown.escape.prevent.stop="cancelRename"
|
|
151
184
|
>
|
|
@@ -191,7 +224,13 @@ onBeforeUnmount(clearPendingConversationNavigation);
|
|
|
191
224
|
</span>
|
|
192
225
|
</div>
|
|
193
226
|
|
|
194
|
-
<div
|
|
227
|
+
<div
|
|
228
|
+
mt-2px
|
|
229
|
+
flex
|
|
230
|
+
items-center
|
|
231
|
+
class="opacity-0 group-hover:opacity-100 transition-opacity"
|
|
232
|
+
:class="isMenuOpen && 'opacity-100'"
|
|
233
|
+
>
|
|
195
234
|
<TelaDropdownMenu :items="menuItems">
|
|
196
235
|
<button
|
|
197
236
|
ref="menuButtonRef"
|
|
@@ -4,6 +4,7 @@ type __VLS_Props = {
|
|
|
4
4
|
conversation: DeepReadonly<Conversation>;
|
|
5
5
|
active: boolean;
|
|
6
6
|
userImage?: string;
|
|
7
|
+
selectConversation?: (id: string) => void | Promise<void>;
|
|
7
8
|
};
|
|
8
9
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
10
|
delete: (id: string) => any;
|
|
@@ -4,6 +4,8 @@ type __VLS_Props = {
|
|
|
4
4
|
conversations: DeepReadonly<Conversation[]>;
|
|
5
5
|
currentId?: string;
|
|
6
6
|
getMemberImage?: (userId: string) => string | undefined;
|
|
7
|
+
selectConversation?: (id: string) => void | Promise<void>;
|
|
8
|
+
resetConversation?: () => void | Promise<void>;
|
|
7
9
|
loading?: boolean;
|
|
8
10
|
};
|
|
9
11
|
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,6 +7,8 @@ const props = defineProps({
|
|
|
7
7
|
conversations: { type: null, required: true },
|
|
8
8
|
currentId: { type: String, required: false },
|
|
9
9
|
getMemberImage: { type: Function, required: false },
|
|
10
|
+
selectConversation: { type: Function, required: false },
|
|
11
|
+
resetConversation: { type: Function, required: false },
|
|
10
12
|
loading: { type: Boolean, required: false }
|
|
11
13
|
});
|
|
12
14
|
const chatApi = useChatApi();
|
|
@@ -24,12 +26,17 @@ const groupedConversations = computed(() => {
|
|
|
24
26
|
return groupConversationsByDate(filteredConversations.value);
|
|
25
27
|
});
|
|
26
28
|
const hasConversationSearchQuery = computed(() => conversationSearch.value.trim().length > 0);
|
|
27
|
-
function handleDelete(id) {
|
|
29
|
+
async function handleDelete(id) {
|
|
28
30
|
const route = useRoute();
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
const shouldResetConversation = props.currentId === id || route.params.id === id;
|
|
32
|
+
const deleted = await deleteConversation(id);
|
|
33
|
+
if (deleted && shouldResetConversation) {
|
|
34
|
+
if (props.resetConversation) {
|
|
35
|
+
void props.resetConversation();
|
|
36
|
+
} else {
|
|
37
|
+
router.push("/");
|
|
38
|
+
}
|
|
31
39
|
}
|
|
32
|
-
deleteConversation(id);
|
|
33
40
|
}
|
|
34
41
|
async function handleRename(id, title) {
|
|
35
42
|
await renameConversation(id, title);
|
|
@@ -38,7 +45,11 @@ async function handleDuplicate(id) {
|
|
|
38
45
|
const duplicated = await duplicateConversation(id);
|
|
39
46
|
if (duplicated) {
|
|
40
47
|
setConversation(duplicated);
|
|
41
|
-
|
|
48
|
+
if (props.selectConversation) {
|
|
49
|
+
void props.selectConversation(duplicated.id);
|
|
50
|
+
} else {
|
|
51
|
+
router.push(`/${duplicated.id}`);
|
|
52
|
+
}
|
|
42
53
|
}
|
|
43
54
|
}
|
|
44
55
|
async function handleExport(id) {
|
|
@@ -56,8 +67,9 @@ async function handleExport(id) {
|
|
|
56
67
|
|
|
57
68
|
<template>
|
|
58
69
|
<div flex="~ col" gap-12px>
|
|
59
|
-
<div px-8px>
|
|
70
|
+
<div px-8px flex="~ col" gap-8px>
|
|
60
71
|
<ChatConversationSearch v-model="conversationSearch" />
|
|
72
|
+
<ChatConversationCreatorFilter />
|
|
61
73
|
</div>
|
|
62
74
|
|
|
63
75
|
<div v-if="loading && conversations.length === 0" flex="~ col" gap-4px>
|
|
@@ -99,6 +111,7 @@ async function handleExport(id) {
|
|
|
99
111
|
:conversation="conversation"
|
|
100
112
|
:active="conversation.id === currentId"
|
|
101
113
|
:user-image="getMemberImage?.(conversation.userId)"
|
|
114
|
+
:select-conversation="selectConversation"
|
|
102
115
|
@delete="handleDelete"
|
|
103
116
|
@rename="handleRename"
|
|
104
117
|
@duplicate="handleDuplicate"
|
|
@@ -4,6 +4,8 @@ type __VLS_Props = {
|
|
|
4
4
|
conversations: DeepReadonly<Conversation[]>;
|
|
5
5
|
currentId?: string;
|
|
6
6
|
getMemberImage?: (userId: string) => string | undefined;
|
|
7
|
+
selectConversation?: (id: string) => void | Promise<void>;
|
|
8
|
+
resetConversation?: () => void | Promise<void>;
|
|
7
9
|
loading?: boolean;
|
|
8
10
|
};
|
|
9
11
|
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>;
|
|
@@ -3,6 +3,9 @@ defineProps({
|
|
|
3
3
|
placeholder: { type: String, required: false, default: "Buscar conversas" }
|
|
4
4
|
});
|
|
5
5
|
const searchQuery = defineModel({ type: String, ...{ required: true } });
|
|
6
|
+
function clearSearch() {
|
|
7
|
+
searchQuery.value = "";
|
|
8
|
+
}
|
|
6
9
|
</script>
|
|
7
10
|
|
|
8
11
|
<template>
|
|
@@ -10,7 +13,23 @@ const searchQuery = defineModel({ type: String, ...{ required: true } });
|
|
|
10
13
|
v-model="searchQuery"
|
|
11
14
|
icon="i-ph-magnifying-glass-bold"
|
|
12
15
|
:placeholder="placeholder"
|
|
13
|
-
show-clear-button
|
|
14
16
|
autocomplete="off"
|
|
15
|
-
|
|
17
|
+
>
|
|
18
|
+
<template v-if="searchQuery" #trailing>
|
|
19
|
+
<TelaTooltip content="Limpar busca">
|
|
20
|
+
<button
|
|
21
|
+
type="button"
|
|
22
|
+
aria-label="Limpar busca"
|
|
23
|
+
hover:bg="#EBEFF199"
|
|
24
|
+
transition-colors
|
|
25
|
+
p-4px rounded-full
|
|
26
|
+
class="group"
|
|
27
|
+
tabindex="-1"
|
|
28
|
+
@click.stop="clearSearch"
|
|
29
|
+
>
|
|
30
|
+
<TelaIcon name="i-ph-x-circle-light" text="#031E22" op-40 group-hover:op-100 transition-opacity />
|
|
31
|
+
</button>
|
|
32
|
+
</TelaTooltip>
|
|
33
|
+
</template>
|
|
34
|
+
</TelaInput>
|
|
16
35
|
</template>
|
|
@@ -50,6 +50,7 @@ type __VLS_Slots = {} & {
|
|
|
50
50
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
51
51
|
delete: () => any;
|
|
52
52
|
cancel: () => any;
|
|
53
|
+
selectConversation: (id: string) => any;
|
|
53
54
|
rename: () => any;
|
|
54
55
|
duplicate: () => any;
|
|
55
56
|
export: () => any;
|
|
@@ -76,12 +77,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
76
77
|
switchWorkspace: () => any;
|
|
77
78
|
signout: () => any;
|
|
78
79
|
dismissOutdatedBanner: () => any;
|
|
79
|
-
selectConversation: (id: string) => any;
|
|
80
80
|
"update:drawerOpen": (value: boolean) => any;
|
|
81
81
|
"update:workspaceSheetOpen": (value: boolean) => any;
|
|
82
82
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
83
83
|
onDelete?: (() => any) | undefined;
|
|
84
84
|
onCancel?: (() => any) | undefined;
|
|
85
|
+
onSelectConversation?: ((id: string) => any) | undefined;
|
|
85
86
|
onRename?: (() => any) | undefined;
|
|
86
87
|
onDuplicate?: (() => any) | undefined;
|
|
87
88
|
onExport?: (() => any) | undefined;
|
|
@@ -108,7 +109,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
108
109
|
onSwitchWorkspace?: (() => any) | undefined;
|
|
109
110
|
onSignout?: (() => any) | undefined;
|
|
110
111
|
onDismissOutdatedBanner?: (() => any) | undefined;
|
|
111
|
-
onSelectConversation?: ((id: string) => any) | undefined;
|
|
112
112
|
"onUpdate:drawerOpen"?: ((value: boolean) => any) | undefined;
|
|
113
113
|
"onUpdate:workspaceSheetOpen"?: ((value: boolean) => any) | undefined;
|
|
114
114
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -50,6 +50,7 @@ type __VLS_Slots = {} & {
|
|
|
50
50
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
51
51
|
delete: () => any;
|
|
52
52
|
cancel: () => any;
|
|
53
|
+
selectConversation: (id: string) => any;
|
|
53
54
|
rename: () => any;
|
|
54
55
|
duplicate: () => any;
|
|
55
56
|
export: () => any;
|
|
@@ -76,12 +77,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
76
77
|
switchWorkspace: () => any;
|
|
77
78
|
signout: () => any;
|
|
78
79
|
dismissOutdatedBanner: () => any;
|
|
79
|
-
selectConversation: (id: string) => any;
|
|
80
80
|
"update:drawerOpen": (value: boolean) => any;
|
|
81
81
|
"update:workspaceSheetOpen": (value: boolean) => any;
|
|
82
82
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
83
83
|
onDelete?: (() => any) | undefined;
|
|
84
84
|
onCancel?: (() => any) | undefined;
|
|
85
|
+
onSelectConversation?: ((id: string) => any) | undefined;
|
|
85
86
|
onRename?: (() => any) | undefined;
|
|
86
87
|
onDuplicate?: (() => any) | undefined;
|
|
87
88
|
onExport?: (() => any) | undefined;
|
|
@@ -108,7 +109,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
108
109
|
onSwitchWorkspace?: (() => any) | undefined;
|
|
109
110
|
onSignout?: (() => any) | undefined;
|
|
110
111
|
onDismissOutdatedBanner?: (() => any) | undefined;
|
|
111
|
-
onSelectConversation?: ((id: string) => any) | undefined;
|
|
112
112
|
"onUpdate:drawerOpen"?: ((value: boolean) => any) | undefined;
|
|
113
113
|
"onUpdate:workspaceSheetOpen"?: ((value: boolean) => any) | undefined;
|
|
114
114
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -14,5 +14,7 @@ export declare function useConversations(): {
|
|
|
14
14
|
deleteConversation: (id: string) => Promise<boolean>;
|
|
15
15
|
renameConversation: (id: string, title: string) => Promise<boolean>;
|
|
16
16
|
duplicateConversation: (id: string) => Promise<ConversationWithMessages | null>;
|
|
17
|
+
conversationCreatorFilter: any;
|
|
18
|
+
conversationCreatorFilterCounts: any;
|
|
17
19
|
updateConversationInList: (updated: Conversation | DeepReadonly<Conversation>) => void;
|
|
18
20
|
};
|