mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-08-30 09:07:40 -05:00
fix(projects): reload projects when the api recalculated positions
The api renumbers all sibling positions when they drift too close together but only returns the updated project. The store kept stale positions for the siblings, so navigating to one of them pulled in its recalculated position and made it jump to a different spot in the sidebar.
This commit is contained in:
@@ -30,6 +30,22 @@ vi.mock('@/stores/base', () => ({
|
||||
}),
|
||||
}))
|
||||
|
||||
const projectServiceMock = {
|
||||
update: vi.fn(),
|
||||
getAll: vi.fn(),
|
||||
totalPages: 1,
|
||||
}
|
||||
|
||||
vi.mock('@/services/project', () => ({
|
||||
default: class {
|
||||
update = (project: IProject) => projectServiceMock.update(project)
|
||||
getAll = (...args: unknown[]) => projectServiceMock.getAll(...args)
|
||||
get totalPages() {
|
||||
return projectServiceMock.totalPages
|
||||
}
|
||||
},
|
||||
}))
|
||||
|
||||
function createMockProject(overrides: Partial<IProject>): IProject {
|
||||
return {
|
||||
id: 1,
|
||||
@@ -211,4 +227,41 @@ describe('project store', () => {
|
||||
expect(store.getEffectiveParentProjectId(orphanedProject, 5)).toBe(5)
|
||||
})
|
||||
})
|
||||
|
||||
describe('updateProject', () => {
|
||||
beforeEach(() => {
|
||||
projectServiceMock.update.mockReset()
|
||||
projectServiceMock.getAll.mockReset()
|
||||
projectServiceMock.totalPages = 1
|
||||
})
|
||||
|
||||
it('should not reload all projects when the api kept the position', async () => {
|
||||
const store = useProjectStore()
|
||||
const project = createMockProject({id: 1, position: 100})
|
||||
store.setProject(project)
|
||||
projectServiceMock.update.mockResolvedValue(createMockProject({id: 1, position: 100}))
|
||||
|
||||
await store.updateProject({...project, title: 'Renamed'})
|
||||
|
||||
expect(projectServiceMock.getAll).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should reload all projects when the api recalculated the position', async () => {
|
||||
const store = useProjectStore()
|
||||
store.setProject(createMockProject({id: 1, position: 0.0001}))
|
||||
store.setProject(createMockProject({id: 2, position: 100}))
|
||||
projectServiceMock.update.mockResolvedValue(createMockProject({id: 1, position: 2147483648}))
|
||||
projectServiceMock.getAll.mockResolvedValue([
|
||||
createMockProject({id: 1, position: 2147483648}),
|
||||
createMockProject({id: 2, position: 4294967296}),
|
||||
])
|
||||
|
||||
await store.updateProject(createMockProject({id: 1, position: 0.0001}))
|
||||
|
||||
expect(projectServiceMock.getAll).toHaveBeenCalled()
|
||||
// Project 2 was never updated - only the reload can fix its stale position.
|
||||
expect(store.projectsArray.map(p => p.id)).toEqual([1, 2])
|
||||
expect(store.projects[2].position).toBe(4294967296)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -224,6 +224,12 @@ export const useProjectStore = defineStore('project', () => {
|
||||
const updatedProject = await projectService.update(project)
|
||||
setProject(project)
|
||||
|
||||
// The api renumbers all sibling positions once they drift too close together but
|
||||
// only returns the updated project, so the rest would keep stale positions.
|
||||
if (updatedProject.position !== project.position) {
|
||||
await loadAllProjects()
|
||||
}
|
||||
|
||||
// the returned project from projectService.update is the same!
|
||||
// in order to not create a manipulation in pinia store we have to create a new copy
|
||||
return updatedProject
|
||||
|
||||
Reference in New Issue
Block a user