feature/projects-all-the-way-down #3323
|
@ -18,7 +18,6 @@ export interface IProject extends IAbstract {
|
|||
subscription: ISubscription
|
||||
position: number
|
||||
backgroundBlurHash: string
|
||||
childProjectIds: number[]
|
||||
parentProjectId: number
|
||||
|
||||
|
||||
created: Date
|
||||
|
|
|
@ -22,7 +22,6 @@ export default class ProjectModel extends AbstractModel<IProject> implements IPr
|
|||
subscription: ISubscription = null
|
||||
position = 0
|
||||
backgroundBlurHash = ''
|
||||
childProjectIds = []
|
||||
parentProjectId = 0
|
||||
|
||||
dpschen
commented
Coming from the recent discussion: wouldn't it be better if this was Coming from the recent discussion: wouldn't it be better if this was `undefined` or `null`?
konrad
commented
You mean to make it clear if this was not set, since it will be overridden with 0 by the api anyway? You mean to make it clear if this was not set, since it will be overridden with 0 by the api anyway?
dpschen
commented
Okay, wasn't aware of this. So the EDIT: Okay, wasn't aware of this. So the `0` here is coming from the golang format. I think we should use the equivalent in js for the frontend, similar to how we use camelCase for variable names.
**EDIT:**
Keeping this `unresolved` because I still want to check something.
|
||||
created: Date = null
|
||||
|
@ -47,8 +46,6 @@ export default class ProjectModel extends AbstractModel<IProject> implements IPr
|
|||
this.subscription = new SubscriptionModel(this.subscription)
|
||||
}
|
||||
|
||||
this.childProjectIds = this.childProjects?.map(p => p.id) || []
|
||||
|
||||
this.created = new Date(this.created)
|
||||
this.updated = new Date(this.updated)
|
||||
dpschen
commented
If we receive child projects like this from the server: Do we have that info somewhere else? If we receive child projects like this from the server: Do we have that info somewhere else?
konrad
commented
We don't actually receive them like this anymore, so this is obsolete, and I've removed it. Each project has a parent project id. To get all child projects we need to iterate over them and return all projects with a parent project id of the project we're interested in. We don't need to that anywhere so I think it's fine to leave at that. We don't actually receive them like this anymore, so this is obsolete, and I've removed it.
Each project has a parent project id. To get all child projects we need to iterate over them and return all projects with a parent project id of the project we're interested in. We don't need to that anywhere so I think it's fine to leave at that.
|
||||
}
|
||||
|
|
|
@ -110,15 +110,6 @@ export const useProjectStore = defineStore('project', () => {
|
|||
const cancel = setModuleLoading(setIsLoading)
|
||||
const projectService = new ProjectService()
|
||||
|
||||
const oldProject = projects.value[project.id]
|
||||
if (oldProject && oldProject.parentProjectId !== project.parentProjectId && oldProject.parentProjectId > 0) {
|
||||
const parentProject = projects.value[oldProject.parentProjectId]
|
||||
if (parentProject) {
|
||||
const childProjectIndex = parentProject.childProjectIds.findIndex(pId => pId === project.id)
|
||||
parentProject.childProjectIds.splice(childProjectIndex, 1)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await projectService.update(project)
|
||||
setProject(project)
|
||||
|
|
This is really error prone. In the moment the project including child projects is coming from the backend we should replace this with an array of
childProjects
instead. All projects should be included in a flat id-Map
inside the store.Having hierarchies just adds complexity everywhere. If a component wants to use a list it can get it directly from the store.
What's that? The projects in
childProjects
are just regular projects.Coming from the api – yes I know. But using them like this in the frontend – not a good pattern. I know we did this similar in other places already. But here we this is the first time for projects. Because of that I would like to prevent the introduction of this pattern here. So when we get the regular projects child array from the api we replace them with their ids instead and add the child projects to the general projects list in the store. That general list is a list of all projects – including all child projects. If we just want the root projects we can create a filter for projects that don't have a parent.
Adding to this – of course we have to reverse this when we send stuff back to the api. By the way for all of this zod is really helpfull…
We already save all projects in the store, regardless of whether they are a child or not. The navigation then starts with a filtered list of that.
Maybe we could just ignore
childProjects
completely and only useparentProjectId
? And then build the list of child projects dynamically when needed? Not sure about the performance implications here.This is basically the idea I have only in the reverse direction. It would be better to have the id of the child though because than we don't have to iterate through all projects everytime we want to find all childs. Instead we can get via the id which should be much faster.
I wouldn't ignore the childProjects because the data inside would need to be manually synced. Instead that property should not exist in the frontend data model.
See normalizr. The utility is unmaintained but the examples are still valid. Since our store is flux inspired this applies to use as well.
The api only uses the
childProjects
property when returning a response with all projects. It won't use it to update the parent <-> child relation.Makes sense, I wonder how good that would work with the dragging and dropping of projects though.
Okay that means that we could simply return ids of the childProjects via a new property (e.g.)
childProjectIds
? That would make that step from the API obsolete.Why would that be a problem?
Note that the store still could provide a
getChildProjects
computed that would return a function where you can pass in the id of a project and would get a reactive list of child projects.I think we should be able to, yes.
Would you add that as a new property to the Project Model and then map it out in the constructor?
Not really, since we need to fetch all children anyway.
Should that include the children of children (of children... and so on) as well?
I started moving this from the current implementation to one where the store only has a flat map and does not store the children directly. It works for the basics, but I could not get any version of drag n' drop to work with that. Not sure what I did wrong.
One problem is the api returns the projects already in the child projects structure. This makes it easy to handle it as such when parsing the data from the api.
Another issue I have with that approach is how it requires a new ref in the projects navigation component, which holds all children for each project of the current tree. That's the same as a property of the
Projects
model, but feels a lot hackier.Here's what I did:
I got something working! See
2557b182dd
There are a few cases where the performance is really bad but I didn't manage to reproduce that reliably (let alone profile it).