Keep desktop modals open on outside click and allow larger group member lists.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,12 +2,23 @@
|
||||
import { onUnmounted, watch } from 'vue';
|
||||
import UiIcon from '@/components/UiIcon.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
open: boolean;
|
||||
title: string;
|
||||
/** برای مودال روی مودال (مثل انتخاب مخاطب داخل فرم) */
|
||||
nest?: boolean;
|
||||
}>();
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
open: boolean;
|
||||
title: string;
|
||||
/** برای مودال روی مودال (مثل انتخاب مخاطب داخل فرم) */
|
||||
nest?: boolean;
|
||||
/**
|
||||
* بستن با کلیک روی پسزمینه.
|
||||
* پیشفرض: فقط موبایل (تمامصفحه). در دسکتاپ عمداً بسته نمیشود.
|
||||
*/
|
||||
closeOnBackdrop?: boolean | 'mobile';
|
||||
}>(),
|
||||
{
|
||||
nest: false,
|
||||
closeOnBackdrop: 'mobile',
|
||||
},
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
close: [];
|
||||
@@ -24,8 +35,17 @@ onUnmounted(() => {
|
||||
document.body.style.overflow = '';
|
||||
});
|
||||
|
||||
function isMobileViewport() {
|
||||
return typeof window !== 'undefined' && window.matchMedia('(max-width: 900px)').matches;
|
||||
}
|
||||
|
||||
function onBackdrop(event: MouseEvent) {
|
||||
if (event.target === event.currentTarget) emit('close');
|
||||
if (event.target !== event.currentTarget) return;
|
||||
const mode = props.closeOnBackdrop;
|
||||
if (mode === false) return;
|
||||
if (mode === true || (mode === 'mobile' && isMobileViewport())) {
|
||||
emit('close');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1575,8 +1575,17 @@ async function startGroup() {
|
||||
groupMemberIds.value = [];
|
||||
await openRoom(data);
|
||||
} catch (e) {
|
||||
if (axios.isAxiosError(e) && e.response?.status === 403) {
|
||||
error.value = 'اجازه ساخت گروه را ندارید.';
|
||||
if (axios.isAxiosError(e)) {
|
||||
const msg = (e.response?.data as { message?: string | string[] })?.message;
|
||||
if (e.response?.status === 403) {
|
||||
error.value = 'اجازه ساخت گروه را ندارید.';
|
||||
} else if (Array.isArray(msg)) {
|
||||
error.value = msg.join('، ');
|
||||
} else if (typeof msg === 'string' && msg.trim()) {
|
||||
error.value = msg;
|
||||
} else {
|
||||
error.value = 'ساخت گروه ناموفق بود.';
|
||||
}
|
||||
} else {
|
||||
error.value = 'ساخت گروه ناموفق بود.';
|
||||
}
|
||||
@@ -1620,6 +1629,13 @@ function toggleChannelMember(id: string) {
|
||||
}
|
||||
}
|
||||
|
||||
/** در دسکتاپ با کلیک بیرون مودال بسته نشود (انتخاب اعضا قطع نشود) */
|
||||
function closeModalOnBackdrop(close: () => void) {
|
||||
if (typeof window !== 'undefined' && window.matchMedia('(max-width: 900px)').matches) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
function openNewDm() {
|
||||
peerPickerQuery.value = '';
|
||||
dmPeerId.value = '';
|
||||
@@ -2478,7 +2494,12 @@ onUnmounted(() => {
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<dialog v-if="showNewDm" class="modal" open @click.self="showNewDm = false">
|
||||
<dialog
|
||||
v-if="showNewDm"
|
||||
class="modal"
|
||||
open
|
||||
@click.self="closeModalOnBackdrop(() => (showNewDm = false))"
|
||||
>
|
||||
<div class="modal-card wide">
|
||||
<h3>گفتگوی جدید</h3>
|
||||
<p class="hint">همکار موردنظر را انتخاب کنید</p>
|
||||
@@ -2518,8 +2539,13 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog v-if="showNewGroup" class="modal" open @click.self="showNewGroup = false">
|
||||
<div class="modal-card wide">
|
||||
<dialog
|
||||
v-if="showNewGroup"
|
||||
class="modal"
|
||||
open
|
||||
@click.self="closeModalOnBackdrop(() => (showNewGroup = false))"
|
||||
>
|
||||
<div class="modal-card wide member-picker-modal">
|
||||
<h3>گروه جدید</h3>
|
||||
<input v-model="groupName" type="text" placeholder="نام گروه" />
|
||||
<div class="picker-head">
|
||||
@@ -2585,8 +2611,13 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog v-if="showNewChannel" class="modal" open @click.self="showNewChannel = false">
|
||||
<div class="modal-card wide">
|
||||
<dialog
|
||||
v-if="showNewChannel"
|
||||
class="modal"
|
||||
open
|
||||
@click.self="closeModalOnBackdrop(() => (showNewChannel = false))"
|
||||
>
|
||||
<div class="modal-card wide member-picker-modal">
|
||||
<h3>کانال جدید</h3>
|
||||
<p class="hint channel-hint">
|
||||
کانال یکطرفه است؛ فقط شما و مدیران سازمان میتوانند پیام بفرستند.
|
||||
@@ -2659,7 +2690,7 @@ onUnmounted(() => {
|
||||
v-if="showActivityFromMsg"
|
||||
class="modal"
|
||||
open
|
||||
@click.self="closeActivityFromMsg"
|
||||
@click.self="closeModalOnBackdrop(closeActivityFromMsg)"
|
||||
>
|
||||
<div class="modal-card activity-sheet">
|
||||
<template v-if="!activityCreatedId">
|
||||
@@ -2706,7 +2737,12 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog v-if="showCrmLink" class="modal" open @click.self="showCrmLink = false">
|
||||
<dialog
|
||||
v-if="showCrmLink"
|
||||
class="modal"
|
||||
open
|
||||
@click.self="closeModalOnBackdrop(() => (showCrmLink = false))"
|
||||
>
|
||||
<div class="modal-card wide">
|
||||
<h3>لینک CRM</h3>
|
||||
<p class="hint">شخص، معامله یا تیکت را انتخاب کنید تا در پیام درج شود.</p>
|
||||
@@ -2765,7 +2801,12 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog v-if="showAiAssist" class="modal" open @click.self="showAiAssist = false">
|
||||
<dialog
|
||||
v-if="showAiAssist"
|
||||
class="modal"
|
||||
open
|
||||
@click.self="closeModalOnBackdrop(() => (showAiAssist = false))"
|
||||
>
|
||||
<div class="modal-card wide ai-assist-sheet">
|
||||
<h3>{{ brand.askLabelFa }}</h3>
|
||||
<p class="hint">با توجه به CRM و چند پیام اخیر این گفتگو پاسخ میدهد؛ میتوانید پاسخ را در پیشنویس درج کنید.</p>
|
||||
@@ -2781,8 +2822,13 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog v-if="showMembers" class="modal" open @click.self="showMembers = false">
|
||||
<div class="modal-card wide members-sheet">
|
||||
<dialog
|
||||
v-if="showMembers"
|
||||
class="modal"
|
||||
open
|
||||
@click.self="closeModalOnBackdrop(() => (showMembers = false))"
|
||||
>
|
||||
<div class="modal-card wide members-sheet member-picker-modal">
|
||||
<h3>اعضای {{ activeRoom ? roomTitle(activeRoom) : 'گفتگو' }}</h3>
|
||||
<p v-if="activeRoom?.kind === 'channel'" class="hint channel-hint">
|
||||
ادمینها میتوانند در کانال پیام بفرستند؛ بقیه فقط مشاهده میکنند.
|
||||
@@ -2839,7 +2885,12 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog v-if="showForward" class="modal" open @click.self="showForward = false">
|
||||
<dialog
|
||||
v-if="showForward"
|
||||
class="modal"
|
||||
open
|
||||
@click.self="closeModalOnBackdrop(() => (showForward = false))"
|
||||
>
|
||||
<div class="modal-card">
|
||||
<h3>ارسال برای دیگری</h3>
|
||||
<p class="hint">{{ toFaDigits(selectedCount) }} پیام انتخاب شده</p>
|
||||
@@ -4212,9 +4263,22 @@ onUnmounted(() => {
|
||||
}
|
||||
.modal-card.wide {
|
||||
width: min(440px, 100%);
|
||||
max-height: min(88vh, 640px);
|
||||
max-height: min(88vh, 720px);
|
||||
overflow: auto;
|
||||
}
|
||||
.modal-card.member-picker-modal {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
overflow: hidden;
|
||||
min-height: min(70vh, 560px);
|
||||
}
|
||||
.modal-card.member-picker-modal > .peer-list,
|
||||
.modal-card.member-picker-modal > .members-list {
|
||||
flex: 1 1 auto;
|
||||
min-height: 220px;
|
||||
max-height: none;
|
||||
}
|
||||
.modal-card select,
|
||||
.modal-card input[type='text'],
|
||||
.modal-card input[type='search'],
|
||||
@@ -4302,10 +4366,12 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.3rem;
|
||||
max-height: 240px;
|
||||
max-height: min(48vh, 360px);
|
||||
overflow: auto;
|
||||
overscroll-behavior: contain;
|
||||
padding: 0.15rem;
|
||||
margin: 0 -0.15rem;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
.peer-row {
|
||||
display: grid;
|
||||
|
||||
Reference in New Issue
Block a user