diff --git a/src/components/home/ProjectsNavigation.vue b/src/components/home/ProjectsNavigation.vue
index 5f5bf9979..225ef8792 100644
--- a/src/components/home/ProjectsNavigation.vue
+++ b/src/components/home/ProjectsNavigation.vue
@@ -26,7 +26,7 @@
>
@@ -93,7 +93,7 @@ import {useBaseStore} from '@/stores/base'
import {useProjectStore} from '@/stores/projects'
const props = defineProps<{
- modelValue: IProject[],
+ modelValue?: IProject[],
canEditOrder: boolean,
}>()
const emit = defineEmits(['update:modelValue'])
@@ -114,11 +114,16 @@ const currentProject = computed(() => baseStore.currentProject)
// TODO: child projects
const collapsedProjects = ref<{ [id: IProject['id']]: boolean }>({})
const availableProjects = ref([])
+const childProjects = ref<{ [id: IProject['id']]: boolean }>({})
watch(
() => props.modelValue,
projects => {
- availableProjects.value = projects
- projects.forEach(p => collapsedProjects.value[p.id] = false)
+ availableProjects.value = projects || []
+ projects?.forEach(p => {
+ collapsedProjects.value[p.id] = false
+ childProjects.value[p.id] = projectStore.getChildProjects(p.id)
+ .sort((a, b) => a.position - b.position)
+ })
},
{immediate: true},
)
@@ -149,8 +154,8 @@ async function saveProjectPosition(e: SortableEvent) {
if (project.parentProjectId !== parentProjectId && project.parentProjectId > 0) {
const parentProject = projectStore.getProjectById(project.parentProjectId)
- const childProjectIndex = parentProject.childProjects.findIndex(p => p.id === project.id)
- parentProject.childProjects.splice(childProjectIndex, 1)
+ const childProjectIndex = parentProject.childProjectIds.findIndex(pId => pId === project.id)
+ parentProject.childProjectIds.splice(childProjectIndex, 1)
}
try {
diff --git a/src/components/home/ProjectsNavigationWrapper.vue b/src/components/home/ProjectsNavigationWrapper.vue
index d876ae115..de74de2e6 100644
--- a/src/components/home/ProjectsNavigationWrapper.vue
+++ b/src/components/home/ProjectsNavigationWrapper.vue
@@ -17,14 +17,18 @@ const projectStore = useProjectStore()
await projectStore.loadProjects()
-const projects = computed(() => projectStore.projectsArray
- .filter(p => p.parentProjectId === 0 && !p.isArchived)
- .sort((a, b) => a.position - b.position))
+const projects = computed({
+ get() {
+ return projectStore.projectsArray
+ .filter(p => p.parentProjectId === 0 && !p.isArchived)
+ .sort((a, b) => a.position - b.position)
+ },
+ set() { }, // Vue will complain about the component not being writable - but we never need to write here. The setter is only here to silence the warning.
+})
const favoriteProjects = computed(() => projectStore.projectsArray
.filter(p => !p.isArchived && p.isFavorite)
.map(p => ({
...p,
- childProjects: [],
}))
.sort((a, b) => a.position - b.position))
diff --git a/src/modelTypes/IProject.ts b/src/modelTypes/IProject.ts
index 8655f0f8d..ca335f3c6 100644
--- a/src/modelTypes/IProject.ts
+++ b/src/modelTypes/IProject.ts
@@ -18,7 +18,7 @@ export interface IProject extends IAbstract {
subscription: ISubscription
position: number
backgroundBlurHash: string
- childProjects: IProject[] | null
+ childProjectIds: number[]
parentProjectId: number
created: Date
diff --git a/src/models/project.ts b/src/models/project.ts
index c672f2468..4ec1dcb53 100644
--- a/src/models/project.ts
+++ b/src/models/project.ts
@@ -22,7 +22,7 @@ export default class ProjectModel extends AbstractModel implements IPr
subscription: ISubscription = null
position = 0
backgroundBlurHash = ''
- childProjects = []
+ childProjectIds = []
parentProjectId = 0
created: Date = null
@@ -47,7 +47,7 @@ export default class ProjectModel extends AbstractModel implements IPr
this.subscription = new SubscriptionModel(this.subscription)
}
- this.childProjects = this.childProjects.map(p => new ProjectModel(p))
+ this.childProjectIds = this.childProjects?.map(p => p.id) || []
this.created = new Date(this.created)
this.updated = new Date(this.updated)
diff --git a/src/stores/projects.ts b/src/stores/projects.ts
index b54ab8d1a..d40eefe01 100644
--- a/src/stores/projects.ts
+++ b/src/stores/projects.ts
@@ -34,6 +34,9 @@ export const useProjectStore = defineStore('project', () => {
const getProjectById = computed(() => {
return (id: IProject['id']) => typeof projects.value[id] !== 'undefined' ? projects.value[id] : null
})
+ const getChildProjects = computed(() => {
+ return (id: IProject['id']) => projectsArray.value.filter(p => p.parentProjectId === id) || []
+ })
const findProjectByExactname = computed(() => {
return (name: string) => {
@@ -67,24 +70,27 @@ export const useProjectStore = defineStore('project', () => {
}
if (updateChildren) {
- project.childProjects?.forEach(p => setProject(p))
+ // When projects are loaded from the api, they will include child projects
+ // in the `childProjects` property. We flatten them out into the project store here.
+ project.childProjects?.forEach(p => setProject(new ProjectModel(p)))
+ delete project.childProjects
}
// if the project is a child project, we need to also set it in the parent
if (project.parentProjectId) {
const parent = projects.value[project.parentProjectId]
let foundProject = false
- parent.childProjects = parent.childProjects?.map(p => {
+ parent.childProjectIds = parent.childProjectIds?.forEach(p => {
if (p.id === project.id) {
foundProject = true
- return project
}
-
- return p
})
// If we hit this, the project now has a new parent project which it did not have before
if (!foundProject) {
- parent.childProjects.push(project)
+ if (!parent.childProjectIds) {
+ parent.childProjectIds = []
+ }
+ parent.childProjectIds.push(project.id)
}
setProject(parent, false)
}
@@ -197,6 +203,7 @@ export const useProjectStore = defineStore('project', () => {
hasProjects: readonly(hasProjects),
getProjectById,
+ getChildProjects,
findProjectByExactname,
searchProject,