diff --git a/changelog/unreleased/bugfix-re-fetch-quota b/changelog/unreleased/bugfix-re-fetch-quota
new file mode 100644
index 00000000000..442b03d8c48
--- /dev/null
+++ b/changelog/unreleased/bugfix-re-fetch-quota
@@ -0,0 +1,8 @@
+Bugfix: Re-fetch quota
+
+We've fixed a bug where uploading, deleting or restoring resources doesn't always re-fetch the quota and therefore
+was falsy displayed.
+
+https://github.com/owncloud/web/pull/7415
+https://github.com/owncloud/web/issues/6930
+https://github.com/owncloud/web/issues/7389
diff --git a/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue b/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue
index 98c2040c9a3..0f0f615fcfd 100644
--- a/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue
+++ b/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue
@@ -122,9 +122,12 @@ import MixinFileActions, { EDITOR_MODE_CREATE } from '../../mixins/fileActions'
import { buildResource, buildWebDavFilesPath, buildWebDavSpacesPath } from '../../helpers/resources'
import { isLocationPublicActive, isLocationSpacesActive } from '../../router'
import { useActiveLocation } from '../../composables'
+import { useGraphClient } from 'web-client/src/composables'
+
import {
useRequest,
useCapabilityShareJailEnabled,
+ useCapabilitySpacesEnabled,
useStore,
usePublicLinkPassword,
useUserContext
@@ -151,7 +154,6 @@ export default defineComponent({
onMounted(() => {
const filesSelectedSub = uppyService.subscribe('filesSelected', instance.onFilesSelected)
- const uploadSuccessSub = uppyService.subscribe('uploadSuccess', instance.onFileSuccess)
const uploadCompletedSub = uppyService.subscribe('uploadCompleted', instance.onUploadComplete)
uppyService.useDropTarget({
@@ -161,7 +163,6 @@ export default defineComponent({
instance.$on('beforeDestroy', () => {
uppyService.unsubscribe('filesSelected', filesSelectedSub)
- uppyService.unsubscribe('uploadSuccess', uploadSuccessSub)
uppyService.unsubscribe('uploadCompleted', uploadCompletedSub)
uppyService.removeDropTarget()
})
@@ -173,12 +174,14 @@ export default defineComponent({
}),
...useUploadHelpers(),
...useRequest(),
+ ...useGraphClient(),
isPersonalLocation: useActiveLocation(isLocationSpacesActive, 'files-spaces-personal'),
isPublicLocation: useActiveLocation(isLocationPublicActive, 'files-public-files'),
isSpacesProjectsLocation: useActiveLocation(isLocationSpacesActive, 'files-spaces-projects'),
isSpacesProjectLocation: useActiveLocation(isLocationSpacesActive, 'files-spaces-project'),
isSpacesShareLocation: useActiveLocation(isLocationSpacesActive, 'files-spaces-share'),
hasShareJail: useCapabilityShareJailEnabled(),
+ hasSpaces: useCapabilitySpacesEnabled(),
publicLinkPassword: usePublicLinkPassword({ store }),
isUserContext: useUserContext({ store })
}
@@ -278,16 +281,10 @@ export default defineComponent({
'setModalInputErrorMessage',
'hideModal'
]),
- ...mapMutations('Files', ['UPSERT_RESOURCE']),
+ ...mapMutations('Files', ['UPSERT_RESOURCE', 'UPDATE_SPACE_FIELD']),
...mapMutations(['SET_QUOTA']),
- onFileSuccess() {
- if (this.user?.quota) {
- this.SET_QUOTA(this.user.quota)
- }
- },
-
- onUploadComplete(result) {
+ async onUploadComplete(result) {
if (result.successful) {
const file = result.successful[0]
@@ -295,6 +292,20 @@ export default defineComponent({
return
}
+ if (this.isSpacesProjectLocation || this.isPersonalLocation) {
+ if (this.hasSpaces) {
+ const driveResponse = await this.graphClient.drives.getDrive(file.meta.routeStorageId)
+ this.UPDATE_SPACE_FIELD({
+ id: driveResponse.data.id,
+ field: 'spaceQuota',
+ value: driveResponse.data.quota
+ })
+ } else {
+ const user = await this.$client.users.getUser(this.user.id)
+ this.SET_QUOTA(user.quota)
+ }
+ }
+
let pathFileWasUploadedTo = file.meta.currentFolder
if (file.meta.relativeFolder) {
pathFileWasUploadedTo += file.meta.relativeFolder
diff --git a/packages/web-app-files/src/components/SpaceQuota.vue b/packages/web-app-files/src/components/SpaceQuota.vue
index 63d98068789..51094ee35af 100644
--- a/packages/web-app-files/src/components/SpaceQuota.vue
+++ b/packages/web-app-files/src/components/SpaceQuota.vue
@@ -2,7 +2,7 @@
s.driveType === 'personal').id
+ const driveResponse = await graphClient.drives.getDrive(driveId)
+ this.UPDATE_SPACE_FIELD({
+ id: driveResponse.data.id,
+ field: 'spaceQuota',
+ value: driveResponse.data.quota
+ })
+ } else {
+ const user = await this.$client.users.getUser(this.user.id)
+ this.SET_QUOTA(user.quota)
+ }
}
}
}
diff --git a/packages/web-app-files/src/mixins/deleteResources.js b/packages/web-app-files/src/mixins/deleteResources.js
index 8a9b8b5fea6..40762c4a174 100644
--- a/packages/web-app-files/src/mixins/deleteResources.js
+++ b/packages/web-app-files/src/mixins/deleteResources.js
@@ -3,7 +3,8 @@ import { cloneStateObject } from '../helpers/store'
import { isSameResource } from '../helpers/resource'
import { buildWebDavFilesTrashPath, buildWebDavSpacesTrashPath } from '../helpers/resources'
import PQueue from 'p-queue'
-import { isLocationTrashActive } from '../router'
+import { isLocationTrashActive, isLocationSpacesActive } from '../router'
+import { clientService } from 'web-pkg/src/services'
export default {
data: () => ({
@@ -14,8 +15,9 @@ export default {
computed: {
...mapGetters('Files', ['selectedFiles']),
- ...mapGetters(['user']),
+ ...mapGetters(['user', 'configuration', 'capabilities']),
...mapGetters('runtime/auth', { isPublicLinkContext: 'isPublicLinkContextReady' }),
+ ...mapGetters('runtime/auth', ['accessToken']),
$_deleteResources_isInTrashbin() {
return (
@@ -97,6 +99,7 @@ export default {
methods: {
...mapActions('Files', ['pushResourcesToDeleteList', 'removeFilesFromTrashbin', 'deleteFiles']),
...mapActions(['showMessage', 'toggleModalConfirmButton', 'hideModal', 'createModal']),
+ ...mapMutations('Files', ['UPDATE_SPACE_FIELD']),
...mapMutations(['SET_QUOTA']),
$_deleteResources_trashbin_deleteOp(resource) {
@@ -160,9 +163,27 @@ export default {
this.toggleModalConfirmButton()
// Load quota
- if (this.user?.id) {
- const user = await this.$client.users.getUser(this.user.id)
- this.SET_QUOTA(user.quota)
+ if (
+ isLocationSpacesActive(this.$router, 'files-spaces-project') ||
+ isLocationSpacesActive(this.$router, 'files-spaces-personal')
+ ) {
+ if (this.capabilities?.spaces?.enabled) {
+ const graphClient = clientService.graphAuthenticated(
+ this.configuration.server,
+ this.accessToken
+ )
+ const driveResponse = await graphClient.drives.getDrive(
+ this.$_deleteResources_resources[0].storageId
+ )
+ this.UPDATE_SPACE_FIELD({
+ id: driveResponse.data.id,
+ field: 'spaceQuota',
+ value: driveResponse.data.quota
+ })
+ } else {
+ const user = await this.$client.users.getUser(this.user.id)
+ this.SET_QUOTA(user.quota)
+ }
}
let parentFolderPath
diff --git a/packages/web-app-files/src/services/folder/legacy/loaderPersonal.ts b/packages/web-app-files/src/services/folder/legacy/loaderPersonal.ts
index e6159aa6a5b..1e13c0f5215 100644
--- a/packages/web-app-files/src/services/folder/legacy/loaderPersonal.ts
+++ b/packages/web-app-files/src/services/folder/legacy/loaderPersonal.ts
@@ -55,12 +55,6 @@ export class FolderLoaderLegacyPersonal implements FolderLoader {
currentFolder,
files: resources
})
-
- // fetch user quota
- ;(async () => {
- const user = await client.users.getUser(router.currentRoute.params.storageId)
- store.commit('SET_QUOTA', user.quota)
- })()
} catch (error) {
store.commit('Files/SET_CURRENT_FOLDER', null)
console.error(error)
diff --git a/packages/web-app-files/src/services/folder/spaces/loaderPersonal.ts b/packages/web-app-files/src/services/folder/spaces/loaderPersonal.ts
index 3bd64974445..1062f4b9a24 100644
--- a/packages/web-app-files/src/services/folder/spaces/loaderPersonal.ts
+++ b/packages/web-app-files/src/services/folder/spaces/loaderPersonal.ts
@@ -51,12 +51,6 @@ export class FolderLoaderSpacesPersonal implements FolderLoader {
currentFolder,
files: resources
})
-
- // fetch user quota
- ;(async () => {
- const user = await clientService.owncloudSdk.users.getUser(ref.user.id)
- store.commit('SET_QUOTA', user.quota)
- })()
} catch (error) {
store.commit('Files/SET_CURRENT_FOLDER', null)
console.error(error)
diff --git a/packages/web-app-files/tests/unit/components/__snapshots__/SpaceQuota.spec.js.snap b/packages/web-app-files/tests/unit/components/__snapshots__/SpaceQuota.spec.js.snap
index f6d007d7977..3351829570d 100644
--- a/packages/web-app-files/tests/unit/components/__snapshots__/SpaceQuota.spec.js.snap
+++ b/packages/web-app-files/tests/unit/components/__snapshots__/SpaceQuota.spec.js.snap
@@ -2,7 +2,7 @@
exports[`SpaceQuota component renders the space storage quota label 1`] = `
-
1 B of 10 B used (10.0% used)
+
1 B of 10 B used (10% used)
`;
diff --git a/packages/web-app-files/tests/unit/mixins/actions/restore.spec.js b/packages/web-app-files/tests/unit/mixins/actions/restore.spec.js
index 521a512cb1d..53a137942e9 100644
--- a/packages/web-app-files/tests/unit/mixins/actions/restore.spec.js
+++ b/packages/web-app-files/tests/unit/mixins/actions/restore.spec.js
@@ -101,7 +101,8 @@ function getWrapper({ invalidLocation = false, resolveClearTrashBin: resolveRest
getters: {
configuration: () => ({
server: 'https://example.com'
- })
+ }),
+ capabilities: () => {}
},
modules: {
user: {
@@ -119,6 +120,9 @@ function getWrapper({ invalidLocation = false, resolveClearTrashBin: resolveRest
removeFilesFromTrashbin: jest.fn()
}
}
+ },
+ mutations: {
+ SET_QUOTA: () => jest.fn()
}
})
})
diff --git a/packages/web-app-files/tests/unit/mixins/deleteResources.spec.js b/packages/web-app-files/tests/unit/mixins/deleteResources.spec.js
index 6c9acb38c3e..549ec37e524 100644
--- a/packages/web-app-files/tests/unit/mixins/deleteResources.spec.js
+++ b/packages/web-app-files/tests/unit/mixins/deleteResources.spec.js
@@ -2,6 +2,7 @@ import Vuex from 'vuex'
import { createStore } from 'vuex-extensions'
import { mount, createLocalVue } from '@vue/test-utils'
import deleteResources from '@files/src/mixins/deleteResources.js'
+import { createLocationSpaces } from '../../../src/router'
const localVue = createLocalVue()
localVue.use(Vuex)
@@ -27,9 +28,10 @@ describe('deleteResources', () => {
const resourcesToDelete = [{ id: 2, path: '/' }]
const wrapper = getWrapper(resourcesToDelete)
const spyHideModalStub = jest.spyOn(wrapper.vm, 'hideModal')
+ const spyRouterPushStub = jest.spyOn(wrapper.vm.$router, 'push')
await wrapper.vm.$_deleteResources_filesList_delete()
await wrapper.vm.$nextTick()
- expect(wrapper.vm.$router.length).toBeGreaterThanOrEqual(0)
+ expect(spyRouterPushStub).toHaveBeenCalledTimes(0)
expect(spyHideModalStub).toHaveBeenCalledTimes(1)
})
@@ -37,9 +39,10 @@ describe('deleteResources', () => {
const resourcesToDelete = [currentFolder]
const wrapper = getWrapper(resourcesToDelete)
const spyHideModalStub = jest.spyOn(wrapper.vm, 'hideModal')
+ const spyRouterPushStub = jest.spyOn(wrapper.vm.$router, 'push')
await wrapper.vm.$_deleteResources_filesList_delete()
await wrapper.vm.$nextTick()
- expect(wrapper.vm.$router.length).toBeGreaterThanOrEqual(1)
+ expect(spyRouterPushStub).toHaveBeenCalledTimes(1)
expect(spyHideModalStub).toHaveBeenCalledTimes(1)
})
})
@@ -52,7 +55,15 @@ function getWrapper(resourcesToDelete) {
$route: {
name: 'files-personal'
},
- $router: [],
+ $router: {
+ currentRoute: createLocationSpaces('files-spaces-personal'),
+ resolve: (r) => {
+ return {
+ href: r.name
+ }
+ },
+ push: jest.fn()
+ },
$client: {
users: {
getUser: jest.fn(() => user)
@@ -67,7 +78,11 @@ function getWrapper(resourcesToDelete) {
getters: {
user: () => {
return { id: 'marie' }
- }
+ },
+ configuration: () => ({
+ server: 'https://example.com'
+ }),
+ capabilities: () => {}
},
modules: {
Files: {
diff --git a/packages/web-runtime/src/components/Topbar/UserMenu.vue b/packages/web-runtime/src/components/Topbar/UserMenu.vue
index ac5057d0d3d..458b8df59c5 100644
--- a/packages/web-runtime/src/components/Topbar/UserMenu.vue
+++ b/packages/web-runtime/src/components/Topbar/UserMenu.vue
@@ -64,7 +64,7 @@