fix(activities): keep board filters and make card drops reliable
Return to the filtered desk after marking an activity done, widen the detail title, and stop a stuck column-drag id from blocking card moves. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import axios from 'axios';
|
||||
import type {
|
||||
@@ -227,7 +227,8 @@ function onMenuActivity(id: string) {
|
||||
}
|
||||
|
||||
function onDragStart(deal: PipelineDeal, event: DragEvent) {
|
||||
if (quickId.value) closeQuick();
|
||||
// اگر شناسهٔ درگ ستون گیر کرده باشد، دراپ کارت را ستونجابهجا میبیند
|
||||
draggingColumnId.value = null;
|
||||
draggingId.value = deal.id;
|
||||
overlayDeal.value = deal;
|
||||
const sid = findStageOf(deal.id);
|
||||
@@ -241,12 +242,19 @@ function onDragStart(deal: PipelineDeal, event: DragEvent) {
|
||||
img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
||||
event.dataTransfer.setDragImage(img, 0, 0);
|
||||
}
|
||||
// بستن پیشنمایش وسط dragstart گاهی خودِ درگ را لغو میکند
|
||||
if (quickId.value) void nextTick(() => closeQuick());
|
||||
}
|
||||
|
||||
function onDragEnd() {
|
||||
draggingId.value = null;
|
||||
dropStageId.value = null;
|
||||
overlayDeal.value = null;
|
||||
const endedId = draggingId.value;
|
||||
// drop معمولاً قبل از dragend است؛ کمی تأخیر تا fallback شناسه از بین نرود
|
||||
window.setTimeout(() => {
|
||||
if (draggingId.value !== endedId) return;
|
||||
draggingId.value = null;
|
||||
dropStageId.value = null;
|
||||
overlayDeal.value = null;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function onDragOver(stageId: string, event: DragEvent) {
|
||||
@@ -331,18 +339,24 @@ async function moveCard(activityId: string, toStageId: string, index?: number) {
|
||||
|
||||
async function onDrop(stageId: string, event: DragEvent, index?: number) {
|
||||
event.preventDefault();
|
||||
const raw = event.dataTransfer?.getData('text/plain') || draggingColumnId.value || draggingId.value || '';
|
||||
const transfer = event.dataTransfer?.getData('text/plain') || '';
|
||||
const cardId = draggingId.value;
|
||||
const columnId = draggingColumnId.value;
|
||||
dropStageId.value = null;
|
||||
draggingId.value = null;
|
||||
overlayDeal.value = null;
|
||||
if (raw.startsWith('stage:') || draggingColumnId.value) {
|
||||
const fromId = raw.replace(/^stage:/, '') || draggingColumnId.value;
|
||||
draggingColumnId.value = null;
|
||||
draggingColumnId.value = null;
|
||||
|
||||
const isStageDrag = transfer.startsWith('stage:');
|
||||
if (isStageDrag || (!transfer && !cardId && columnId)) {
|
||||
const fromId = isStageDrag ? transfer.slice('stage:'.length) : columnId;
|
||||
if (fromId) await reorderColumn(fromId, stageId);
|
||||
return;
|
||||
}
|
||||
if (!raw || moving.value) return;
|
||||
await moveCard(raw, stageId, index);
|
||||
|
||||
const activityId = (!isStageDrag && transfer) || cardId || '';
|
||||
if (!activityId || moving.value) return;
|
||||
await moveCard(activityId, stageId, index);
|
||||
}
|
||||
|
||||
async function persistOrder(ids: string[]) {
|
||||
@@ -500,7 +514,7 @@ function openFullActivity(id: string) {
|
||||
@rename-stage="onRenameStage"
|
||||
@delete-stage="onDeleteStage"
|
||||
@move-stage="onMoveStage"
|
||||
@column-drag-start="(id: string) => (draggingColumnId = id)"
|
||||
@column-drag-start="(id: string) => { draggingId = null; overlayDeal = null; draggingColumnId = id; }"
|
||||
@column-drag-end="draggingColumnId = null; dropStageId = null"
|
||||
@add-stage="onAddStage"
|
||||
@load-more="loadMore"
|
||||
|
||||
@@ -58,8 +58,7 @@ function activitiesListLocation() {
|
||||
return { name: 'activities' as const, query };
|
||||
}
|
||||
|
||||
async function goBack() {
|
||||
if (!(await resolveDirty())) return;
|
||||
function leaveToActivitiesList() {
|
||||
const back = (window.history.state as { back?: string | null } | null)?.back ?? '';
|
||||
if (back.split('?')[0] === '/activities') {
|
||||
router.back();
|
||||
@@ -67,6 +66,11 @@ async function goBack() {
|
||||
}
|
||||
void router.push(activitiesListLocation());
|
||||
}
|
||||
|
||||
async function goBack() {
|
||||
if (!(await resolveDirty())) return;
|
||||
leaveToActivitiesList();
|
||||
}
|
||||
const auth = useAuthStore();
|
||||
const id = computed(() => (typeof route.params.id === 'string' ? route.params.id : ''));
|
||||
const canReassign = computed(() => canAssignToOthers(auth.user, 'activities'));
|
||||
@@ -755,7 +759,9 @@ async function complete(kind: 'share' | 'force' | 'undo' = 'share') {
|
||||
{ params },
|
||||
);
|
||||
if (data.status === 'done') {
|
||||
await router.push({ name: 'activities' });
|
||||
// مثل بازگشت و پیشنمایش: فیلتر/نمای قبلی حفظ شود
|
||||
discardDrafts();
|
||||
leaveToActivitiesList();
|
||||
return;
|
||||
}
|
||||
activity.value = data;
|
||||
@@ -1707,17 +1713,21 @@ onUnmounted(() => {
|
||||
padding-bottom: 0.65rem;
|
||||
}
|
||||
|
||||
.hero > div {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.hero h2 {
|
||||
margin: 0;
|
||||
font-size: 1.05rem;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.35rem;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title-input {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
border: 1px solid #e5e7eb;
|
||||
|
||||
@@ -244,6 +244,7 @@ function onPointerMove(event: PointerEvent | MouseEvent) {
|
||||
}
|
||||
|
||||
function onDragStart(deal: PipelineDeal, event: DragEvent) {
|
||||
draggingColumnId.value = null;
|
||||
draggingId.value = deal.id;
|
||||
overlayDeal.value = deal;
|
||||
overlayAccent.value = findAccent(deal.id);
|
||||
@@ -262,9 +263,13 @@ function onDragStart(deal: PipelineDeal, event: DragEvent) {
|
||||
}
|
||||
|
||||
function onDragEnd() {
|
||||
draggingId.value = null;
|
||||
dropStageId.value = null;
|
||||
overlayDeal.value = null;
|
||||
const endedId = draggingId.value;
|
||||
window.setTimeout(() => {
|
||||
if (draggingId.value !== endedId) return;
|
||||
draggingId.value = null;
|
||||
dropStageId.value = null;
|
||||
overlayDeal.value = null;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function onDragOver(stageId: string, event: DragEvent) {
|
||||
@@ -304,21 +309,22 @@ async function applyUpdateDealStage(
|
||||
|
||||
async function onDrop(stageId: string, event: DragEvent, index?: number) {
|
||||
event.preventDefault();
|
||||
const raw =
|
||||
event.dataTransfer?.getData('text/plain') ||
|
||||
draggingColumnId.value ||
|
||||
draggingId.value ||
|
||||
'';
|
||||
const transfer = event.dataTransfer?.getData('text/plain') || '';
|
||||
const draggedCardId = draggingId.value;
|
||||
const columnId = draggingColumnId.value;
|
||||
dropStageId.value = null;
|
||||
draggingId.value = null;
|
||||
overlayDeal.value = null;
|
||||
if (raw.startsWith('stage:') || draggingColumnId.value) {
|
||||
const fromId = raw.replace(/^stage:/, '') || draggingColumnId.value;
|
||||
draggingColumnId.value = null;
|
||||
draggingColumnId.value = null;
|
||||
|
||||
const isStageDrag = transfer.startsWith('stage:');
|
||||
if (isStageDrag || (!transfer && !draggedCardId && columnId)) {
|
||||
const fromId = isStageDrag ? transfer.slice('stage:'.length) : columnId;
|
||||
if (fromId) await reorderColumn(fromId, stageId);
|
||||
return;
|
||||
}
|
||||
const dealId = raw;
|
||||
|
||||
const dealId = (!isStageDrag && transfer) || draggedCardId || '';
|
||||
if (!dealId || moving.value) return;
|
||||
|
||||
const current = stages.value.find((stage) => stage.deals.some((deal) => deal.id === dealId));
|
||||
@@ -351,6 +357,8 @@ function onAddDeal(stageId: string) {
|
||||
}
|
||||
|
||||
function onColumnDragStart(stageId: string) {
|
||||
draggingId.value = null;
|
||||
overlayDeal.value = null;
|
||||
draggingColumnId.value = stageId;
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,7 @@ function onPointerMove(event: PointerEvent | MouseEvent) {
|
||||
}
|
||||
|
||||
function onDragStart(deal: PipelineDeal, event: DragEvent) {
|
||||
draggingColumnId.value = null;
|
||||
draggingId.value = deal.id;
|
||||
overlayDeal.value = deal;
|
||||
overlayAccent.value = findAccent(deal.id);
|
||||
@@ -195,9 +196,13 @@ function onDragStart(deal: PipelineDeal, event: DragEvent) {
|
||||
}
|
||||
|
||||
function onDragEnd() {
|
||||
draggingId.value = null;
|
||||
dropStageId.value = null;
|
||||
overlayDeal.value = null;
|
||||
const endedId = draggingId.value;
|
||||
window.setTimeout(() => {
|
||||
if (draggingId.value !== endedId) return;
|
||||
draggingId.value = null;
|
||||
dropStageId.value = null;
|
||||
overlayDeal.value = null;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function onDragOver(stageId: string, event: DragEvent) {
|
||||
@@ -237,21 +242,22 @@ async function applyUpdateCardStage(
|
||||
|
||||
async function onDrop(stageId: string, event: DragEvent, index?: number) {
|
||||
event.preventDefault();
|
||||
const raw =
|
||||
event.dataTransfer?.getData('text/plain') ||
|
||||
draggingColumnId.value ||
|
||||
draggingId.value ||
|
||||
'';
|
||||
const transfer = event.dataTransfer?.getData('text/plain') || '';
|
||||
const draggedCardId = draggingId.value;
|
||||
const columnId = draggingColumnId.value;
|
||||
dropStageId.value = null;
|
||||
draggingId.value = null;
|
||||
overlayDeal.value = null;
|
||||
if (raw.startsWith('stage:') || draggingColumnId.value) {
|
||||
const fromId = raw.replace(/^stage:/, '') || draggingColumnId.value;
|
||||
draggingColumnId.value = null;
|
||||
draggingColumnId.value = null;
|
||||
|
||||
const isStageDrag = transfer.startsWith('stage:');
|
||||
if (isStageDrag || (!transfer && !draggedCardId && columnId)) {
|
||||
const fromId = isStageDrag ? transfer.slice('stage:'.length) : columnId;
|
||||
if (fromId) await reorderColumn(fromId, stageId);
|
||||
return;
|
||||
}
|
||||
const cardId = raw;
|
||||
|
||||
const cardId = (!isStageDrag && transfer) || draggedCardId || '';
|
||||
if (!cardId || moving.value) return;
|
||||
|
||||
const current = stages.value.find((s) => s.deals.some((d) => d.id === cardId));
|
||||
@@ -268,6 +274,8 @@ function onAddCard(stageId: string) {
|
||||
}
|
||||
|
||||
function onColumnDragStart(stageId: string) {
|
||||
draggingId.value = null;
|
||||
overlayDeal.value = null;
|
||||
draggingColumnId.value = stageId;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user