fix: keep list menus on screen and clip long activity subtitles

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-17 13:26:11 +03:30
co-authored by Cursor
parent 2c7c943802
commit 177e5cc31b
5 changed files with 158 additions and 101 deletions
+53 -37
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
import { RouterLink, useRoute, useRouter } from 'vue-router';
import axios from 'axios';
import { api } from '@/lib/api';
@@ -661,7 +661,11 @@ async function confirmDeleteActivities() {
function onBoardMenu(activityId: string) {
boardMenuId.value = boardMenuId.value === activityId ? null : activityId;
boardMenuStyle.value = boardMenuId.value ? cardMenuStyle(activityId) : null;
boardMenuStyle.value = null;
if (!boardMenuId.value) return;
void nextTick(() => {
boardMenuStyle.value = cardMenuStyle(activityId);
});
}
const unbindBoardMenuDismiss = bindMenuDismiss(
@@ -1332,38 +1336,40 @@ onUnmounted(() => {
/>
</template>
<div
v-if="boardMenuId"
class="menu-pop"
role="menu"
:style="boardMenuStyle ?? undefined"
@click.stop
>
<button type="button" role="menuitem" @click="startSelect(boardMenuId)">انتخاب</button>
<RouterLink
role="menuitem"
:to="{ name: 'activity-detail', params: { id: boardMenuId } }"
@click="boardMenuId = null"
<Teleport to="body">
<div
v-if="boardMenuId"
class="menu-pop"
role="menu"
:style="boardMenuStyle ?? undefined"
@click.stop
>
مشاهده
</RouterLink>
<RouterLink
role="menuitem"
:to="{ name: 'activity-edit', params: { id: boardMenuId } }"
@click="boardMenuId = null"
>
ویرایش
</RouterLink>
<button
type="button"
role="menuitem"
class="danger"
@click="askDeleteActivity(boardMenuId)"
>
حذف
</button>
<button type="button" role="menuitem" @click="boardMenuId = null">بستن</button>
</div>
<button type="button" role="menuitem" @click="startSelect(boardMenuId)">انتخاب</button>
<RouterLink
role="menuitem"
:to="{ name: 'activity-detail', params: { id: boardMenuId } }"
@click="boardMenuId = null"
>
مشاهده
</RouterLink>
<RouterLink
role="menuitem"
:to="{ name: 'activity-edit', params: { id: boardMenuId } }"
@click="boardMenuId = null"
>
ویرایش
</RouterLink>
<button
type="button"
role="menuitem"
class="danger"
@click="askDeleteActivity(boardMenuId)"
>
حذف
</button>
<button type="button" role="menuitem" @click="boardMenuId = null">بستن</button>
</div>
</Teleport>
<UiModal
:open="Boolean(activityModal)"
@@ -1887,17 +1893,29 @@ h1 {
display: flex;
gap: 0.55rem;
min-width: 0;
max-width: 100%;
overflow: hidden;
}
.title-cell > div {
min-width: 0;
flex: 1;
overflow: hidden;
}
.star {
color: #cbd5e1;
margin-top: 0.2rem;
flex: 0 0 auto;
}
.title {
display: block;
color: inherit;
font-weight: 600;
overflow-wrap: anywhere;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sub {
@@ -2148,9 +2166,7 @@ time.note {
.menu-pop {
position: fixed;
inset-inline-start: 1rem;
bottom: calc(var(--mobile-tabbar-h, 0px) + 1.75rem);
z-index: 40;
z-index: 80;
background: #fff;
border: 1px solid var(--line, #e2e8f0);
border-radius: var(--radius);
+28 -24
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';
import { api } from '@/lib/api';
@@ -559,7 +559,11 @@ const menuStyle = ref<Record<string, string> | null>(null);
function onMenuDeal(dealId: string) {
menuOpenId.value = menuOpenId.value === dealId ? null : dealId;
menuStyle.value = menuOpenId.value ? cardMenuStyle(dealId) : null;
menuStyle.value = null;
if (!menuOpenId.value) return;
void nextTick(() => {
menuStyle.value = cardMenuStyle(dealId);
});
}
const unbindMenuDismiss = bindMenuDismiss(
@@ -702,25 +706,27 @@ defineExpose({ updateDealStage: applyUpdateDealStage });
/>
</Teleport>
<div v-if="menuOpenId" class="menu-pop" role="menu" :style="menuStyle ?? undefined">
<button type="button" role="menuitem" @click="startSelect(menuOpenId)">
انتخاب
</button>
<button type="button" role="menuitem" @click="onOpenDeal(menuOpenId)">
مشاهده معامله
</button>
<button
type="button"
role="menuitem"
@click="dealModal = { dealId: menuOpenId ?? undefined }; menuOpenId = null"
>
ویرایش
</button>
<button type="button" role="menuitem" class="danger" @click="askDeleteDeal(menuOpenId)">
حذف
</button>
<button type="button" role="menuitem" @click="menuOpenId = null">بستن</button>
</div>
<Teleport to="body">
<div v-if="menuOpenId" class="menu-pop" role="menu" :style="menuStyle ?? undefined">
<button type="button" role="menuitem" @click="startSelect(menuOpenId)">
انتخاب
</button>
<button type="button" role="menuitem" @click="onOpenDeal(menuOpenId)">
مشاهده معامله
</button>
<button
type="button"
role="menuitem"
@click="dealModal = { dealId: menuOpenId ?? undefined }; menuOpenId = null"
>
ویرایش
</button>
<button type="button" role="menuitem" class="danger" @click="askDeleteDeal(menuOpenId)">
حذف
</button>
<button type="button" role="menuitem" @click="menuOpenId = null">بستن</button>
</div>
</Teleport>
<UiModal
:open="showCreate && canCreatePipeline"
@@ -891,9 +897,7 @@ defineExpose({ updateDealStage: applyUpdateDealStage });
.menu-pop {
position: fixed;
inset-inline-start: 1rem;
bottom: calc(var(--mobile-tabbar-h) + 1.75rem);
z-index: 40;
z-index: 80;
background: #fff;
border: 1px solid var(--line);
border-radius: var(--radius);
+22 -18
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';
import { api } from '@/lib/api';
@@ -445,7 +445,11 @@ const menuStyle = ref<Record<string, string> | null>(null);
function onMenuCard(cardId: string) {
menuOpenId.value = menuOpenId.value === cardId ? null : cardId;
menuStyle.value = menuOpenId.value ? cardMenuStyle(cardId) : null;
menuStyle.value = null;
if (!menuOpenId.value) return;
void nextTick(() => {
menuStyle.value = cardMenuStyle(cardId);
});
}
const unbindMenuDismiss = bindMenuDismiss(
@@ -558,19 +562,21 @@ onBeforeUnmount(() => {
/>
</Teleport>
<div v-if="menuOpenId" class="menu-pop" role="menu" :style="menuStyle ?? undefined">
<button type="button" role="menuitem" @click="onOpenCard(menuOpenId)">
مشاهده کارت
</button>
<button
type="button"
role="menuitem"
@click="cardModal = { cardId: menuOpenId ?? undefined }; menuOpenId = null"
>
ویرایش
</button>
<button type="button" role="menuitem" @click="menuOpenId = null">بستن</button>
</div>
<Teleport to="body">
<div v-if="menuOpenId" class="menu-pop" role="menu" :style="menuStyle ?? undefined">
<button type="button" role="menuitem" @click="onOpenCard(menuOpenId)">
مشاهده کارت
</button>
<button
type="button"
role="menuitem"
@click="cardModal = { cardId: menuOpenId ?? undefined }; menuOpenId = null"
>
ویرایش
</button>
<button type="button" role="menuitem" @click="menuOpenId = null">بستن</button>
</div>
</Teleport>
<UiModal
:open="showCreate && canCreateBoard"
@@ -720,9 +726,7 @@ onBeforeUnmount(() => {
.menu-pop {
position: fixed;
inset-inline-start: 1rem;
bottom: calc(var(--mobile-tabbar-h) + 1.75rem);
z-index: 40;
z-index: 80;
background: #fff;
border: 1px solid var(--line);
border-radius: var(--radius);