mirror of
https://github.com/Gimanh/taskview-community.git
synced 2026-09-11 13:29:17 +00:00
fix: #106
This commit is contained in:
@@ -1,16 +1,9 @@
|
||||
import { ALL_TASKS_LIST_ID, type DefaultView } from 'taskview-api'
|
||||
import type { RouteLocationRaw, Router } from 'vue-router'
|
||||
import { $tvApi } from '@/plugins/axios'
|
||||
import { useUserStore } from '@/stores/user.store'
|
||||
import { useOrganizationStore } from '@/stores/organization.store'
|
||||
import { useUiPreferencesStore } from '@/stores/uiPreferences.store'
|
||||
|
||||
const VIEW_ROUTES: Record<DefaultView, string> = {
|
||||
tasks: 'user',
|
||||
kanban: 'kanban',
|
||||
graph: 'graph',
|
||||
sprints: 'sprints',
|
||||
}
|
||||
import { useProjectRoute } from '@/composables/useProjectRoute'
|
||||
|
||||
export const redirectToUser = async (router: Router) => {
|
||||
const userStore = useUserStore()
|
||||
@@ -36,15 +29,12 @@ export const resolveDefaultRoute = async (): Promise<RouteLocationRaw | null> =>
|
||||
// The default project may live in any of the user's organizations; try the current one first
|
||||
const orgStore = useOrganizationStore()
|
||||
const orgs = [...orgStore.organizations].sort((a) => (a.slug === orgStore.currentOrgSlug ? -1 : 1))
|
||||
const { projectRoute } = useProjectRoute()
|
||||
|
||||
for (const org of orgs) {
|
||||
const goals = await $tvApi.goals.fetchGoals(org.id)
|
||||
if (!goals?.some((goal) => goal.id === projectId)) continue
|
||||
|
||||
const view = uiPrefs.settings.defaultView ?? 'tasks'
|
||||
const params: Record<string, string | number> = { orgSlug: org.slug, projectId }
|
||||
if (view === 'tasks') params.listId = ALL_TASKS_LIST_ID
|
||||
return { name: VIEW_ROUTES[view], params }
|
||||
const goal = goals?.find((g) => g.id === projectId)
|
||||
if (goal) return projectRoute(goal, org.slug)
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
@@ -25,9 +25,10 @@ import { useOrganizationStore } from '@/stores/organization.store'
|
||||
import ProjectsList from '@/components/features/projects/ProjectsList.vue'
|
||||
import ArchiveList from '@/components/features/projects/ArchiveList.vue'
|
||||
import type { Project, ProjectSaveData } from '@/components/features/projects/types'
|
||||
import { ALL_TASKS_LIST_ID } from 'taskview-api'
|
||||
import { useProjectRoute } from '@/composables/useProjectRoute'
|
||||
|
||||
const router = useRouter()
|
||||
const { projectRoute } = useProjectRoute()
|
||||
|
||||
const goalsStore = useGoalsStore()
|
||||
const orgStore = useOrganizationStore()
|
||||
@@ -75,7 +76,7 @@ async function handleAdd(name: string) {
|
||||
...(orgStore.currentOrg && { organizationId: orgStore.currentOrg.id }),
|
||||
})
|
||||
if (newProject) {
|
||||
router.push({ name: 'user', params: { projectId: newProject.id, listId: ALL_TASKS_LIST_ID } })
|
||||
router.push(projectRoute(newProject))
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
v-for="project in projects"
|
||||
:key="project.id"
|
||||
variant="taskview"
|
||||
:to="{ name: 'user', params: { projectId: project.id, listId: '-1401' } }"
|
||||
:to="projectRoute(project)"
|
||||
:active="currentProjectId === project.id"
|
||||
>
|
||||
<div
|
||||
@@ -209,6 +209,7 @@ import ProjectDeleteDialog from '@/components/features/projects/parts/ProjectDel
|
||||
import ProjectAddInput from '@/components/features/projects/parts/ProjectAddInput.vue'
|
||||
import type { Project, ProjectSaveData } from '@/components/features/projects/types'
|
||||
import { useGoalPermissionsFor } from '@/composables/useGoalPermissions'
|
||||
import { useProjectRoute } from '@/composables/useProjectRoute'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -234,6 +235,7 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const { projectRoute } = useProjectRoute()
|
||||
|
||||
const isOpen = defineModel<boolean>('open', { required: false, default: true })
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
v-model="defaultView"
|
||||
:items="viewItems"
|
||||
value-key="value"
|
||||
:disabled="defaultProject === NONE"
|
||||
data-testid="default-view-select"
|
||||
variant="soft"
|
||||
class="w-full lg:w-72"
|
||||
size="xl"
|
||||
@@ -70,7 +70,6 @@ const defaultProject = computed<number>({
|
||||
get: () => store.settings.defaultProjectId ?? NONE,
|
||||
set: (value) => {
|
||||
store.setSetting('defaultProjectId', value === NONE ? undefined : value)
|
||||
if (value === NONE) store.setSetting('defaultView', undefined)
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ALL_TASKS_LIST_ID } from 'taskview-api'
|
||||
import { useDashboard } from '@/composables/useDashboard'
|
||||
import { useProjectRoute } from '@/composables/useProjectRoute'
|
||||
import { useGoalsStore } from '@/stores/goals.store'
|
||||
import { useOrganizationStore } from '@/stores/organization.store'
|
||||
import SearchActivator from '@/components/features/main/screen-main/parts/SearchActivator.vue'
|
||||
@@ -69,6 +69,7 @@ import SidebarOrgSelect from './dashboard-second/SidebarOrgSelect.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
const { projectRoute } = useProjectRoute()
|
||||
const { isSidebarOpen, isSidebarCollapsed } = useDashboard()
|
||||
const goalsStore = useGoalsStore()
|
||||
const orgStore = useOrganizationStore()
|
||||
@@ -79,7 +80,7 @@ async function handleAddProject(name: string) {
|
||||
...(orgStore.currentOrg && { organizationId: orgStore.currentOrg.id }),
|
||||
})
|
||||
if (newProject) {
|
||||
router.push({ name: 'user', params: { projectId: newProject.id, listId: ALL_TASKS_LIST_ID } })
|
||||
router.push(projectRoute(newProject))
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -150,9 +150,9 @@ import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ALL_TASKS_LIST_ID } from 'taskview-api'
|
||||
import { useGoalsStore } from '@/stores/goals.store'
|
||||
import { useGoalPermissionsFor } from '@/composables/useGoalPermissions'
|
||||
import { useProjectRoute } from '@/composables/useProjectRoute'
|
||||
import type { Project, ProjectSaveData } from '@/components/features/projects/types'
|
||||
import ProjectEditModal from '@/components/features/projects/parts/ProjectEditModal.vue'
|
||||
import ProjectDeleteDialog from '@/components/features/projects/parts/ProjectDeleteDialog.vue'
|
||||
@@ -160,6 +160,7 @@ import ProjectDeleteDialog from '@/components/features/projects/parts/ProjectDel
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const { projectRoute } = useProjectRoute()
|
||||
const goalsStore = useGoalsStore()
|
||||
const { goals } = storeToRefs(goalsStore)
|
||||
|
||||
@@ -186,7 +187,7 @@ const { canEditGoal, canDeleteGoal } = useGoalPermissionsFor(currentProject)
|
||||
|
||||
function selectProject(project: Project) {
|
||||
open.value = false
|
||||
router.push({ name: 'user', params: { projectId: project.id, listId: ALL_TASKS_LIST_ID } })
|
||||
router.push(projectRoute(project))
|
||||
}
|
||||
|
||||
async function archive() {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { RouteLocationRaw } from 'vue-router'
|
||||
import { ALL_TASKS_LIST_ID, type DefaultView, type GoalItem, type GoalPermissions } from 'taskview-api'
|
||||
import { useUiPreferencesStore } from '@/stores/uiPreferences.store'
|
||||
import { AllGoalPermissions } from '@/types/goals.types'
|
||||
|
||||
export const VIEW_ROUTES: Record<DefaultView, string> = {
|
||||
tasks: 'user',
|
||||
kanban: 'kanban',
|
||||
graph: 'graph',
|
||||
sprints: 'sprints',
|
||||
}
|
||||
|
||||
const VIEW_PERMISSIONS: Record<Exclude<DefaultView, 'tasks'>, (keyof GoalPermissions)[]> = {
|
||||
kanban: [AllGoalPermissions.KANBAN_CAN_VIEW, AllGoalPermissions.KANBAN_CAN_MANAGE],
|
||||
graph: [AllGoalPermissions.GRAPH_CAN_VIEW, AllGoalPermissions.GRAPH_CAN_MANAGE],
|
||||
sprints: [AllGoalPermissions.SPRINT_CAN_VIEW],
|
||||
}
|
||||
|
||||
function canOpenView(goal: GoalItem, view: DefaultView): boolean {
|
||||
if (view === 'tasks') return true
|
||||
return VIEW_PERMISSIONS[view].some((perm) => !!goal.permissions[perm])
|
||||
}
|
||||
|
||||
export function useProjectRoute() {
|
||||
const uiPrefs = useUiPreferencesStore()
|
||||
|
||||
function projectRoute(goal: GoalItem, orgSlug?: string): RouteLocationRaw {
|
||||
const preferred = uiPrefs.settings.defaultView ?? 'tasks'
|
||||
const view: DefaultView = canOpenView(goal, preferred) ? preferred : 'tasks'
|
||||
const params: Record<string, string | number> = { projectId: goal.id }
|
||||
if (orgSlug) params.orgSlug = orgSlug
|
||||
if (view === 'tasks') params.listId = ALL_TASKS_LIST_ID
|
||||
return { name: VIEW_ROUTES[view], params }
|
||||
}
|
||||
|
||||
return { projectRoute }
|
||||
}
|
||||
@@ -810,7 +810,7 @@ export default {
|
||||
defaultProjectHint: 'Dieses Projekt direkt nach der Anmeldung öffnen.',
|
||||
defaultProjectNone: 'Startbildschirm (Standard)',
|
||||
defaultView: 'Standardansicht',
|
||||
defaultViewHint: 'Welche Ansicht des Projekts geöffnet wird.',
|
||||
defaultViewHint: 'Welche Ansicht beim Öffnen eines Projekts angezeigt wird.',
|
||||
viewTasks: 'Aufgaben',
|
||||
viewKanban: 'Kanban',
|
||||
viewGraph: 'Graph',
|
||||
|
||||
@@ -824,7 +824,7 @@ export default {
|
||||
defaultProjectHint: 'Open this project right after signing in.',
|
||||
defaultProjectNone: 'Home screen (default)',
|
||||
defaultView: 'Default view',
|
||||
defaultViewHint: 'Which view of the default project to open.',
|
||||
defaultViewHint: 'Which view to open when you enter a project.',
|
||||
viewTasks: 'Tasks',
|
||||
viewKanban: 'Kanban',
|
||||
viewGraph: 'Graph',
|
||||
|
||||
@@ -810,7 +810,7 @@ export default {
|
||||
defaultProjectHint: 'Abrir este proyecto justo después de iniciar sesión.',
|
||||
defaultProjectNone: 'Pantalla de inicio (predeterminado)',
|
||||
defaultView: 'Vista predeterminada',
|
||||
defaultViewHint: 'Qué vista del proyecto abrir.',
|
||||
defaultViewHint: 'Qué vista abrir al entrar en un proyecto.',
|
||||
viewTasks: 'Tareas',
|
||||
viewKanban: 'Kanban',
|
||||
viewGraph: 'Grafo',
|
||||
|
||||
@@ -797,7 +797,7 @@ export default {
|
||||
defaultProjectHint: 'Открывать этот проект сразу после входа.',
|
||||
defaultProjectNone: 'Главный экран (по умолчанию)',
|
||||
defaultView: 'Вид по умолчанию',
|
||||
defaultViewHint: 'Какой вид проекта открывать.',
|
||||
defaultViewHint: 'Какой вид открывать при переходе в проект.',
|
||||
viewTasks: 'Задачи',
|
||||
viewKanban: 'Канбан',
|
||||
viewGraph: 'Граф',
|
||||
|
||||
Reference in New Issue
Block a user