diff --git a/changelog/unreleased/enhancement-space-store-improvements b/changelog/unreleased/enhancement-space-store-improvements new file mode 100644 index 00000000000..b03427ddd4a --- /dev/null +++ b/changelog/unreleased/enhancement-space-store-improvements @@ -0,0 +1,6 @@ +Enhancement: Space store improvements + +We've improved the space's store, this allows us to keep the search reactive to space changes, +for example, as a project space gets added or renamed. + +https://github.com/owncloud/web/pull/6868 diff --git a/packages/web-app-files/src/components/AppBar/CreateSpace.vue b/packages/web-app-files/src/components/AppBar/CreateSpace.vue index dc2f3acdf90..c33c25db373 100644 --- a/packages/web-app-files/src/components/AppBar/CreateSpace.vue +++ b/packages/web-app-files/src/components/AppBar/CreateSpace.vue @@ -42,7 +42,8 @@ export default { 'CLEAR_CURRENT_FILES_LIST', 'SET_FILE_SELECTION', 'UPSERT_RESOURCE', - 'UPDATE_RESOURCE_FIELD' + 'UPDATE_RESOURCE_FIELD', + 'UPSERT_SPACE' ]), showCreateSpaceModal() { @@ -77,6 +78,7 @@ export default { this.hideModal() const resource = buildSpace(space) this.UPSERT_RESOURCE(resource) + this.UPSERT_SPACE(resource) this.$client.files.createFolder(`spaces/${space.id}/.space`).then(() => { this.$client.files diff --git a/packages/web-app-files/src/mixins/spaces/actions/delete.js b/packages/web-app-files/src/mixins/spaces/actions/delete.js index 796ace37776..97412110358 100644 --- a/packages/web-app-files/src/mixins/spaces/actions/delete.js +++ b/packages/web-app-files/src/mixins/spaces/actions/delete.js @@ -36,7 +36,7 @@ export default { 'showMessage', 'toggleModalConfirmButton' ]), - ...mapMutations('Files', ['REMOVE_FILE']), + ...mapMutations('Files', ['REMOVE_FILE', 'REMOVE_SPACE']), $_delete_trigger({ resources }) { if (resources.length !== 1) { @@ -69,6 +69,7 @@ export default { .then(() => { this.hideModal() this.REMOVE_FILE({ id }) + this.REMOVE_SPACE({ id }) this.showMessage({ title: this.$gettext('Space was deleted successfully') }) diff --git a/packages/web-app-files/src/mixins/spaces/actions/rename.js b/packages/web-app-files/src/mixins/spaces/actions/rename.js index 58c5e022204..090ca07c83e 100644 --- a/packages/web-app-files/src/mixins/spaces/actions/rename.js +++ b/packages/web-app-files/src/mixins/spaces/actions/rename.js @@ -35,7 +35,7 @@ export default { 'showMessage', 'toggleModalConfirmButton' ]), - ...mapMutations('Files', ['UPDATE_RESOURCE_FIELD']), + ...mapMutations('Files', ['UPDATE_RESOURCE_FIELD', 'UPDATE_SPACE_FIELD']), $_rename_trigger({ resources }) { if (resources.length !== 1) { @@ -76,6 +76,11 @@ export default { field: 'name', value: name }) + this.UPDATE_SPACE_FIELD({ + id, + field: 'name', + value: name + }) this.showMessage({ title: this.$gettext('Space name was changed successfully') }) diff --git a/packages/web-app-files/src/store/mutations.js b/packages/web-app-files/src/store/mutations.js index fab657456b0..87c08af2fb6 100644 --- a/packages/web-app-files/src/store/mutations.js +++ b/packages/web-app-files/src/store/mutations.js @@ -9,6 +9,38 @@ export default { LOAD_SPACES(state, spaces) { state.spaces = spaces }, + /** + * Updates a single space field. If the space with given id doesn't exist nothing will happen. + * + * @param state Current state of this store module + * @param params + * @param params.id Id of the resource to be updated + * @param params.field the resource field that the value should be applied to + * @param params.value the value that will be attached to the key + */ + UPDATE_SPACE_FIELD(state, params) { + const spaceSource = state.spaces + const index = state.spaces.findIndex((r) => r.id === params.id) + if (index < 0) { + return + } + + const resource = spaceSource[index] + const isReactive = has(resource, params.field) + const newResource = set(resource, params.field, params.value) + + if (isReactive) { + return + } + + Vue.set(spaceSource, index, newResource) + }, + UPSERT_SPACE(state, space) { + state.spaces.push(space) + }, + REMOVE_SPACE(state, space) { + state.spaces = state.spaces.filter((s) => s.id !== space.id) + }, CLEAR_SPACES(state) { state.spaces = [] }, diff --git a/packages/web-app-files/tests/unit/store/mutations.spec.js b/packages/web-app-files/tests/unit/store/mutations.spec.js index 745f3048b45..7bb2c91b436 100644 --- a/packages/web-app-files/tests/unit/store/mutations.spec.js +++ b/packages/web-app-files/tests/unit/store/mutations.spec.js @@ -16,6 +16,18 @@ const stateFixture = { id: 5, name: 'test5' } + ], + spaces: [ + { + id: 1, + name: 'personal', + driveType: 'personal' + }, + { + id: 2, + name: 'My space', + driveType: 'project' + } ] } let stateMock = {} @@ -138,4 +150,40 @@ describe('vuex store mutations', () => { expect(state.currentFileOutgoingShares[0]).toEqual(updatedShare) }) }) + + describe('space store', () => { + beforeEach(resetState) + describe('method "UPSERT_SPACE"', () => { + it('Adds the space to the store', () => { + const upsertSpace = { id: 3, name: 'New space', driveType: 'project' } + mutations.UPSERT_SPACE(stateMock, upsertSpace) + expect(stateMock.spaces.some((sM) => sM.id === upsertSpace.id)).toBeTruthy() + }) + }) + describe('method "CLEAR_SPACES"', () => { + it('Sets space store to an empty array', () => { + mutations.CLEAR_SPACES(stateMock) + expect(stateMock.spaces).toEqual([]) + }) + }) + describe('method "REMOVE_SPACE"', () => { + it('Removes the space from the store', () => { + mutations.REMOVE_SPACE( + stateMock, + stateMock.spaces.find((sM) => sM.id === 1) + ) + expect(stateMock.spaces.every((sM) => sM.id !== 1)).toBeTruthy() + }) + }) + describe('method "UPDATE_SPACE_FIELD"', () => { + it('Updates the space in the store', () => { + mutations.UPDATE_SPACE_FIELD(stateMock, { + id: 2, + field: 'name', + value: 'Renamed space' + }) + expect(stateMock.spaces.some((sM) => sM.name === 'Renamed space')).toBeTruthy() + }) + }) + }) })