fix(activities): return to the same group after opening a card

The back link dropped the board from the address, so the desk reopened on the default group.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-29 09:22:23 +03:30
co-authored by Cursor
parent 63a1803adc
commit 6f42440b3b
3 changed files with 52 additions and 12 deletions
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import { useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import axios from 'axios'; import axios from 'axios';
import type { import type {
ActivityDto, ActivityDto,
@@ -389,8 +389,15 @@ async function onAddStage(name: string) {
} }
} }
const route = useRoute();
function openActivity(id: string) { function openActivity(id: string) {
void router.push({ name: 'activity-detail', params: { id } }); const query: Record<string, string> = {};
for (const key of ['board', 'view', 'desk', 'filter', 'stage', 'q', 'typeDefId', 'status', 'assigneeId']) {
const value = route.query[key];
if (typeof value === 'string' && value) query[key] = value;
}
void router.push({ name: 'activity-detail', params: { id }, query });
} }
</script> </script>
+21 -8
View File
@@ -399,6 +399,19 @@ async function loadStages() {
} }
} }
function activityRoute(id: string, edit = false) {
const query: Record<string, string> = {};
for (const key of ['board', 'view', 'desk', 'filter', 'stage', 'q', 'typeDefId', 'status', 'assigneeId'] as const) {
const value = route.query[key];
if (typeof value === 'string' && value) query[key] = value;
}
return {
name: edit ? ('activity-edit' as const) : ('activity-detail' as const),
params: { id },
query,
};
}
function setBoard(next: string) { function setBoard(next: string) {
void router.replace({ void router.replace({
name: 'activities', name: 'activities',
@@ -1370,7 +1383,7 @@ onUnmounted(() => {
<div v-if="colOn('title')" class="title-cell"> <div v-if="colOn('title')" class="title-cell">
<UiIcon name="star" :size="16" class="star" /> <UiIcon name="star" :size="16" class="star" />
<div> <div>
<RouterLink class="title" :to="{ name: 'activity-detail', params: { id: item.id } }"> <RouterLink class="title" :to="activityRoute(item.id)">
{{ item.title }} {{ item.title }}
</RouterLink> </RouterLink>
<p v-if="subtitle(item)" class="sub">{{ subtitle(item) }}</p> <p v-if="subtitle(item)" class="sub">{{ subtitle(item) }}</p>
@@ -1452,10 +1465,10 @@ onUnmounted(() => {
</button> </button>
</template> </template>
<button type="button" @click="startSelect(item.id)">انتخاب</button> <button type="button" @click="startSelect(item.id)">انتخاب</button>
<RouterLink :to="{ name: 'activity-detail', params: { id: item.id } }"> <RouterLink :to="activityRoute(item.id)">
مشاهده مشاهده
</RouterLink> </RouterLink>
<RouterLink :to="{ name: 'activity-edit', params: { id: item.id } }"> <RouterLink :to="activityRoute(item.id, true)">
ویرایش ویرایش
</RouterLink> </RouterLink>
<button v-if="canPromotePrior(item)" type="button" @click="promotePriorActivity(item.id)"> <button v-if="canPromotePrior(item)" type="button" @click="promotePriorActivity(item.id)">
@@ -1497,7 +1510,7 @@ onUnmounted(() => {
<time :class="item.type">{{ clockText(item) }}</time> <time :class="item.type">{{ clockText(item) }}</time>
<RouterLink <RouterLink
class="title" class="title"
:to="{ name: 'activity-detail', params: { id: item.id } }" :to="activityRoute(item.id)"
@click="selectMode && $event.preventDefault()" @click="selectMode && $event.preventDefault()"
> >
{{ item.title }} {{ item.title }}
@@ -1542,10 +1555,10 @@ onUnmounted(() => {
</button> </button>
</template> </template>
<button type="button" @click="startSelect(item.id)">انتخاب</button> <button type="button" @click="startSelect(item.id)">انتخاب</button>
<RouterLink :to="{ name: 'activity-detail', params: { id: item.id } }"> <RouterLink :to="activityRoute(item.id)">
مشاهده مشاهده
</RouterLink> </RouterLink>
<RouterLink :to="{ name: 'activity-edit', params: { id: item.id } }"> <RouterLink :to="activityRoute(item.id, true)">
ویرایش ویرایش
</RouterLink> </RouterLink>
<button v-if="canPromotePrior(item)" type="button" @click="promotePriorActivity(item.id)"> <button v-if="canPromotePrior(item)" type="button" @click="promotePriorActivity(item.id)">
@@ -1601,14 +1614,14 @@ onUnmounted(() => {
<button type="button" role="menuitem" @click="startSelect(boardMenuId)">انتخاب</button> <button type="button" role="menuitem" @click="startSelect(boardMenuId)">انتخاب</button>
<RouterLink <RouterLink
role="menuitem" role="menuitem"
:to="{ name: 'activity-detail', params: { id: boardMenuId } }" :to="activityRoute(boardMenuId)"
@click="boardMenuId = null; boardMenuActivity = null" @click="boardMenuId = null; boardMenuActivity = null"
> >
مشاهده مشاهده
</RouterLink> </RouterLink>
<RouterLink <RouterLink
role="menuitem" role="menuitem"
:to="{ name: 'activity-edit', params: { id: boardMenuId } }" :to="activityRoute(boardMenuId, true)"
@click="boardMenuId = null; boardMenuActivity = null" @click="boardMenuId = null; boardMenuActivity = null"
> >
ویرایش ویرایش
+22 -2
View File
@@ -27,6 +27,26 @@ import { brand } from '@mento/shared';
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const ACTIVITY_LIST_QUERY = ['board', 'view', 'desk', 'filter', 'stage', 'q', 'typeDefId', 'status', 'assigneeId'] as const;
function activitiesListLocation() {
const query: Record<string, string> = {};
for (const key of ACTIVITY_LIST_QUERY) {
const value = route.query[key];
if (typeof value === 'string' && value) query[key] = value;
}
return { name: 'activities' as const, query };
}
function goBack() {
const back = (window.history.state as { back?: string | null } | null)?.back ?? '';
if (back.split('?')[0] === '/activities') {
router.back();
return;
}
void router.push(activitiesListLocation());
}
const auth = useAuthStore(); const auth = useAuthStore();
const id = computed(() => (typeof route.params.id === 'string' ? route.params.id : '')); const id = computed(() => (typeof route.params.id === 'string' ? route.params.id : ''));
const canReassign = computed(() => canReassignRecords(auth.user?.role)); const canReassign = computed(() => canReassignRecords(auth.user?.role));
@@ -314,9 +334,9 @@ onMounted(() => {
<template> <template>
<section class="page" @click="moreOpen = false"> <section class="page" @click="moreOpen = false">
<header class="nav"> <header class="nav">
<RouterLink class="icon-btn back" :to="{ name: 'activities' }" aria-label="بازگشت"> <a class="icon-btn back" href="/activities" aria-label="بازگشت" @click.prevent="goBack">
<UiIcon name="chevron" :size="18" /> <UiIcon name="chevron" :size="18" />
</RouterLink> </a>
<span class="brand">{{ brand.name }}</span> <span class="brand">{{ brand.name }}</span>
<div class="more" @click.stop> <div class="more" @click.stop>
<button class="icon-btn" type="button" aria-label="منوی بیشتر" @click="moreOpen = !moreOpen"> <button class="icon-btn" type="button" aria-label="منوی بیشتر" @click="moreOpen = !moreOpen">