feature/projects-all-the-way-down #3323
|
@ -14,7 +14,7 @@
|
|||
<BaseButton
|
||||
:to="{ name: 'project.index', params: { projectId: project.id} }"
|
||||
class="list-menu-link"
|
||||
:class="{'router-link-exact-active': currentProject.id === project.id}"
|
||||
:class="{'router-link-exact-active': currentProject?.id === project.id}"
|
||||
>
|
||||
<span
|
||||
v-if="!canCollapse || childProjects?.length === 0"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<MenuButton class="menu-button" />
|
||||
|
||||
<div v-if="currentProject.id" class="project-title-wrapper">
|
||||
<div v-if="currentProject?.id" class="project-title-wrapper">
|
||||
<h1 class="project-title">{{ currentProject.title === '' ? $t('misc.loading') : getProjectTitle(currentProject) }}
|
||||
</h1>
|
||||
|
||||
|
@ -89,7 +89,7 @@ import { useAuthStore } from '@/stores/auth'
|
|||
const baseStore = useBaseStore()
|
||||
const currentProject = computed(() => baseStore.currentProject)
|
||||
const background = computed(() => baseStore.background)
|
||||
const canWriteCurrentProject = computed(() => baseStore.currentProject.maxRight > Rights.READ)
|
||||
const canWriteCurrentProject = computed(() => baseStore.currentProject?.maxRight > Rights.READ)
|
||||
const menuActive = computed(() => baseStore.menuActive)
|
||||
|
||||
const authStore = useAuthStore()
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
<Logo class="logo" v-if="logoVisible"/>
|
||||
<h1
|
||||
:class="{'m-0': !logoVisible}"
|
||||
:style="{ 'opacity': currentProject.title === '' ? '0': '1' }"
|
||||
:style="{ 'opacity': currentProject?.title === '' ? '0': '1' }"
|
||||
class="title">
|
||||
{{ currentProject.title === '' ? $t('misc.loading') : currentProject.title }}
|
||||
{{ currentProject?.title === '' ? $t('misc.loading') : currentProject?.title }}
|
||||
</h1>
|
||||
<div class="box has-text-left view">
|
||||
<router-view/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div
|
||||
:class="{ 'is-loading': projectService.loading, 'is-archived': currentProject.isArchived}"
|
||||
:class="{ 'is-loading': projectService.loading, 'is-archived': currentProject?.isArchived}"
|
||||
class="loader-container"
|
||||
>
|
||||
<div class="switch-view-container">
|
||||
|
@ -45,7 +45,7 @@
|
|||
<slot name="header" />
|
||||
</div>
|
||||
<CustomTransition name="fade">
|
||||
<Message variant="warning" v-if="currentProject.isArchived" class="mb-4">
|
||||
<Message variant="warning" v-if="currentProject?.isArchived" class="mb-4">
|
||||
{{ $t('project.archivedMessage') }}
|
||||
dpschen marked this conversation as resolved
Outdated
|
||||
</Message>
|
||||
</CustomTransition>
|
||||
|
@ -98,7 +98,7 @@ const currentProject = computed(() => {
|
|||
maxRight: null,
|
||||
} : baseStore.currentProject
|
||||
})
|
||||
useTitle(() => currentProject.value.id ? getProjectTitle(currentProject.value) : '')
|
||||
useTitle(() => currentProject.value?.id ? getProjectTitle(currentProject.value) : '')
|
||||
|
||||
// watchEffect would be called every time the prop would get a value assigned, even if that value was the same as before.
|
||||
// This resulted in loading and setting the project multiple times, even when navigating away from it.
|
||||
|
@ -118,7 +118,7 @@ watch(
|
|||
(
|
||||
projectIdToLoad === loadedProjectId.value ||
|
||||
typeof projectIdToLoad === 'undefined' ||
|
||||
projectIdToLoad === currentProject.value.id
|
||||
projectIdToLoad === currentProject.value?.id
|
||||
)
|
||||
&& typeof currentProject.value !== 'undefined' && currentProject.value.maxRight !== null
|
||||
) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
/>
|
||||
|
||||
<ColorBubble
|
||||
v-if="showProjectColor && projectColor !== '' && currentProject.id !== task.projectId"
|
||||
v-if="showProjectColor && projectColor !== '' && currentProject?.id !== task.projectId"
|
||||
:color="projectColor"
|
||||
class="mr-1"
|
||||
/>
|
||||
|
@ -104,7 +104,7 @@
|
|||
</progress>
|
||||
|
||||
<router-link
|
||||
v-if="!showProject && currentProject.id !== task.projectId && project"
|
||||
v-if="!showProject && currentProject?.id !== task.projectId && project"
|
||||
:to="{ name: 'project.list', params: { projectId: task.projectId } }"
|
||||
class="task-project"
|
||||
v-tooltip="$t('task.detail.belongsToProject', {project: project.title})"
|
||||
|
|
|
@ -40,7 +40,7 @@ export function getSavedFilterIdFromProjectId(projectId: IProject['id']) {
|
|||
}
|
||||
|
||||
export function isSavedFilter(project: IProject) {
|
||||
return getSavedFilterIdFromProjectId(project.id) > 0
|
||||
return getSavedFilterIdFromProjectId(project?.id) > 0
|
||||
}
|
||||
|
||||
export default class SavedFilterService extends AbstractService<ISavedFilter> {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {watch, reactive, shallowReactive, unref, toRefs, readonly, ref, computed} from 'vue'
|
||||
import {watch, reactive, shallowReactive, unref, toRefs, readonly, ref, computed, watchEffect} from 'vue'
|
||||
import {acceptHMRUpdate, defineStore} from 'pinia'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useRouter} from 'vue-router'
|
||||
|
@ -44,6 +44,8 @@ export const useProjectStore = defineStore('project', () => {
|
|||
return (id: IProject['id']) => projectsArray.value.filter(p => p.parentProjectId === id)
|
||||
})
|
||||
|
||||
watchEffect(() => baseStore.setCurrentProject(projects.value[baseStore.currentProject?.id] || null))
|
||||
|
||||
const findProjectByExactname = computed(() => {
|
||||
return (name: string) => {
|
||||
const project = Object.values(projects.value).find(l => {
|
||||
|
@ -70,10 +72,6 @@ export const useProjectStore = defineStore('project', () => {
|
|||
function setProject(project: IProject) {
|
||||
projects.value[project.id] = project
|
||||
dpschen
commented
See comment about having the data as sub projects from earlier. See comment about having the data as sub projects from earlier.
|
||||
update(project)
|
||||
|
||||
if (baseStore.currentProject?.id === project.id) {
|
||||
baseStore.setCurrentProject(project)
|
||||
}
|
||||
}
|
||||
|
||||
dpschen
commented
The three lines above should be called via a deep watcher on the current project. Not as a side effect. The three lines above should be called via a deep watcher on the current project. Not as a side effect.
konrad
commented
You mean setting the current project in the base store? You mean setting the current project in the base store?
dpschen
commented
I mean:
It might be even better to make the currentProject a computed based on the store instead and only setting it via id (unsure here how to handle projects that are not saved yet) I mean:
1) remove this sideeffect of the `setProject` function:
```
if (baseStore.currentProject?.id === project.id) {
baseStore.setCurrentProject(project)
}
```
2) Instead add a watcher on the project that has the id of the current project.
```ts
watchEffect(() => baseStore.setCurrentProject(projects.value[baseStore.currentProject.id])
)
```
It might be even better to make the currentProject a computed based on the store instead and only setting it via id (unsure here how to handle projects that are not saved yet)
konrad
commented
I've now changed it to use a watcher.
That sounds like a good idea, but let's push that to another PR. I've now changed it to use a watcher.
> It might be even better to make the currentProject a computed based on the store instead and only setting it via id (unsure here how to handle projects that are not saved yet)
That sounds like a good idea, but let's push that to another PR.
konrad
commented
I've now changed it to use a watcher.
That sounds like a good idea, but let's push that to another PR. I've now changed it to use a watcher.
> It might be even better to make the currentProject a computed based on the store instead and only setting it via id (unsure here how to handle projects that are not saved yet)
That sounds like a good idea, but let's push that to another PR.
|
||||
function setProjects(newProjects: IProject[]) {
|
||||
|
|
|
@ -75,7 +75,7 @@ const GanttChart = createAsyncComponent(() => import('@/components/tasks/GanttCh
|
|||
const props = defineProps<{route: RouteLocationNormalized}>()
|
||||
|
||||
const baseStore = useBaseStore()
|
||||
const canWrite = computed(() => baseStore.currentProject.maxRight > RIGHTS.READ)
|
||||
const canWrite = computed(() => baseStore.currentProject?.maxRight > RIGHTS.READ)
|
||||
|
||||
const {route} = toRefs(props)
|
||||
const {
|
||||
|
|
|
@ -330,7 +330,7 @@ const bucketDraggableComponentData = computed(() => ({
|
|||
],
|
||||
}))
|
||||
|
||||
const canWrite = computed(() => baseStore.currentProject.maxRight > Rights.READ)
|
||||
const canWrite = computed(() => baseStore.currentProject?.maxRight > Rights.READ)
|
||||
const project = computed(() => baseStore.currentProject)
|
||||
|
||||
const buckets = computed(() => kanbanStore.buckets)
|
||||
|
|
How about
archivedMessage
orarchivedWarning
I like
archivedMessage
, renamed it.