Addition of an AI chat assistant and a 100MB file upload limit.
This commit is contained in:
@@ -35,13 +35,15 @@ import {
|
||||
parseChatMessageText,
|
||||
} from '@/lib/chatMessageFormat';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import AskMentoPanel from '@/components/AskMentoPanel.vue';
|
||||
import UiIcon from '@/components/UiIcon.vue';
|
||||
import UserAvatar from '@/components/UserAvatar.vue';
|
||||
import type {
|
||||
PaginatedResponse,
|
||||
PersonDto,
|
||||
PipelineBoardDto,
|
||||
TicketDto,
|
||||
import {
|
||||
brand,
|
||||
type PaginatedResponse,
|
||||
type PersonDto,
|
||||
type PipelineBoardDto,
|
||||
type TicketDto,
|
||||
} from '@mento/shared';
|
||||
|
||||
type PendingAttach = {
|
||||
@@ -139,6 +141,8 @@ const crmLinkKind = ref<'person' | 'deal' | 'ticket'>('person');
|
||||
const crmLinkQuery = ref('');
|
||||
const crmLinkResults = ref<Array<{ id: string; title: string }>>([]);
|
||||
const crmLinkBusy = ref(false);
|
||||
const showAiAssist = ref(false);
|
||||
const aiChatContext = ref('');
|
||||
const chatSearchOpen = ref(false);
|
||||
const chatSearchQuery = ref('');
|
||||
const chatSearchIndex = ref(0);
|
||||
@@ -774,6 +778,55 @@ function openCrmLinkPicker() {
|
||||
void searchCrmLinks();
|
||||
}
|
||||
|
||||
function messageSenderLabel(msg: ChatMessage) {
|
||||
if (isMineMessage(msg)) return 'شما';
|
||||
return (
|
||||
peers.value.find((p) => p.chatUserId === msg.senderId)?.fullName ||
|
||||
peers.value.find((p) => p.id === msg.senderId)?.fullName ||
|
||||
'همکار'
|
||||
);
|
||||
}
|
||||
|
||||
function buildChatContext(): string {
|
||||
const room = activeRoom.value;
|
||||
const title = room ? roomTitle(room) : 'گفتگو';
|
||||
const recent = messages.value.slice(-20);
|
||||
const lines = recent.map((m) => {
|
||||
const who = messageSenderLabel(m);
|
||||
if (m.deleted) return `${who}: [حذفشده]`;
|
||||
if (m.type === 'text') {
|
||||
return `${who}: ${(m.content || '').replace(/\s+/g, ' ').trim().slice(0, 280)}`;
|
||||
}
|
||||
return `${who}: ${previewLabelForMessage(m)}`;
|
||||
});
|
||||
return `گفتگو: ${title}\n${lines.join('\n')}`.slice(0, 3500);
|
||||
}
|
||||
|
||||
function openAiAssist() {
|
||||
aiChatContext.value = buildChatContext();
|
||||
showAiAssist.value = true;
|
||||
emojiOpen.value = false;
|
||||
}
|
||||
|
||||
function insertAiAnswer(text: string) {
|
||||
const chunk = text.trim();
|
||||
if (!chunk) return;
|
||||
const el = draftInputEl.value;
|
||||
const value = draft.value;
|
||||
const start = el?.selectionStart ?? value.length;
|
||||
const end = el?.selectionEnd ?? value.length;
|
||||
const pad =
|
||||
start > 0 && value.slice(0, start).length && !/\s$/.test(value.slice(0, start))
|
||||
? '\n'
|
||||
: '';
|
||||
draft.value = value.slice(0, start) + pad + chunk + value.slice(end);
|
||||
showAiAssist.value = false;
|
||||
nextTick(() => {
|
||||
draftInputEl.value?.focus();
|
||||
onDraftInput();
|
||||
});
|
||||
}
|
||||
|
||||
function insertCrmEntity(item: { id: string; title: string }) {
|
||||
const chunk = insertCrmLink(crmLinkKind.value, item.id, item.title);
|
||||
const el = draftInputEl.value;
|
||||
@@ -2264,6 +2317,14 @@ onUnmounted(() => {
|
||||
<button type="button" class="fmt-btn" title="لینک CRM" @click="openCrmLinkPicker">
|
||||
<UiIcon name="briefcase" :size="14" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="fmt-btn fmt-ai"
|
||||
:title="brand.askLabelFa"
|
||||
@click="openAiAssist"
|
||||
>
|
||||
<UiIcon name="sparkle" :size="14" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="composer-row">
|
||||
<input
|
||||
@@ -2704,6 +2765,22 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog v-if="showAiAssist" class="modal" open @click.self="showAiAssist = false">
|
||||
<div class="modal-card wide ai-assist-sheet">
|
||||
<h3>{{ brand.askLabelFa }}</h3>
|
||||
<p class="hint">با توجه به CRM و چند پیام اخیر این گفتگو پاسخ میدهد؛ میتوانید پاسخ را در پیشنویس درج کنید.</p>
|
||||
<AskMentoPanel
|
||||
:chat-context="aiChatContext"
|
||||
allow-insert
|
||||
:placeholder="`${brand.askLabelFa} درباره این گفتگو…`"
|
||||
@insert-answer="insertAiAnswer"
|
||||
/>
|
||||
<div class="modal-actions">
|
||||
<button type="button" @click="showAiAssist = false">بستن</button>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog v-if="showMembers" class="modal" open @click.self="showMembers = false">
|
||||
<div class="modal-card wide members-sheet">
|
||||
<h3>اعضای {{ activeRoom ? roomTitle(activeRoom) : 'گفتگو' }}</h3>
|
||||
@@ -3136,6 +3213,9 @@ onUnmounted(() => {
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.fmt-btn.fmt-ai {
|
||||
color: #0f766e;
|
||||
}
|
||||
.msg-text em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user