Skip to content

Commit

Permalink
Apply loading service to the new action composables
Browse files Browse the repository at this point in the history
  • Loading branch information
JammingBen committed Mar 17, 2023
1 parent 5abe349 commit 3b8a325
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@ import { archiverService } from '../../../services'
import { isPublicSpaceResource, Resource } from 'web-client/src/helpers'
import { Store } from 'vuex'
import { computed, unref } from 'vue'
import { usePublicLinkPassword, useRouter, useStore } from 'web-pkg/src/composables'
import {
useLoadingService,
usePublicLinkPassword,
useRouter,
useStore
} from 'web-pkg/src/composables'
import { Action, ActionOptions } from 'web-pkg/src/composables/actions'
import { useGettext } from 'vue3-gettext'

export const useFileActionsDownloadArchive = ({ store }: { store?: Store<any> } = {}) => {
store = store || useStore()
const router = useRouter()
const loadingService = useLoadingService()
const { $ngettext, $gettext } = useGettext()
const publicLinkPassword = usePublicLinkPassword({ store })
const isFilesAppActive = useIsFilesAppActive()
Expand All @@ -31,25 +37,27 @@ export const useFileActionsDownloadArchive = ({ store }: { store?: Store<any> }
dir: path.dirname(first<Resource>(resources).path) || '/',
files: resources.map((resource) => resource.name)
}
await archiverService
.triggerDownload({
...fileOptions,
...(isPublicSpaceResource(space) && {
publicToken: space.id as string,
publicLinkPassword: unref(publicLinkPassword)
return loadingService.addTask(() => {
return archiverService
.triggerDownload({
...fileOptions,
...(isPublicSpaceResource(space) && {
publicToken: space.id as string,
publicLinkPassword: unref(publicLinkPassword)
})
})
})
.catch((e) => {
console.error(e)
store.dispatch('showMessage', {
title: $ngettext(
'Failed to download the selected folder.', // on single selection only available for folders
'Failed to download the selected files.', // on multi selection available for files+folders
resources.length
),
status: 'danger'
.catch((e) => {
console.error(e)
store.dispatch('showMessage', {
title: $ngettext(
'Failed to download the selected folder.', // on single selection only available for folders
'Failed to download the selected files.', // on multi selection available for files+folders
resources.length
),
status: 'danger'
})
})
})
})
}

const actions = computed((): Action[] => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
useCapabilityFilesPermanentDeletion,
useCapabilityShareJailEnabled,
useClientService,
useLoadingService,
useRouter,
useStore
} from 'web-pkg/src/composables'
Expand All @@ -19,6 +20,7 @@ export const useFileActionsEmptyTrashBin = ({ store }: { store?: Store<any> } =
const router = useRouter()
const { $gettext, $pgettext } = useGettext()
const { owncloudSdk } = useClientService()
const loadingService = useLoadingService()
const hasShareJail = useCapabilityShareJailEnabled()
const hasPermanentDeletion = useCapabilityFilesPermanentDeletion()

Expand All @@ -27,27 +29,29 @@ export const useFileActionsEmptyTrashBin = ({ store }: { store?: Store<any> } =
? buildWebDavSpacesTrashPath(space.id)
: buildWebDavFilesTrashPath(store.getters.user.id)

return owncloudSdk.fileTrash
.clearTrashBin(path)
.then(() => {
store.dispatch('showMessage', {
title: $gettext('All deleted files were removed')
return loadingService.addTask(() => {
return owncloudSdk.fileTrash
.clearTrashBin(path)
.then(() => {
store.dispatch('showMessage', {
title: $gettext('All deleted files were removed')
})
store.dispatch('Files/clearTrashBin')
})
store.dispatch('Files/clearTrashBin')
})
.catch((error) => {
console.error(error)
store.dispatch('showMessage', {
title: $pgettext(
'Error message in case clearing the trash bin fails',
'Failed to delete all files permanently'
),
status: 'danger'
.catch((error) => {
console.error(error)
store.dispatch('showMessage', {
title: $pgettext(
'Error message in case clearing the trash bin fails',
'Failed to delete all files permanently'
),
status: 'danger'
})
})
})
.finally(() => {
store.dispatch('hideModal')
})
.finally(() => {
store.dispatch('hideModal')
})
})
}

const handler = ({ space }: ActionOptions) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import {
import { Store } from 'vuex'
import { computed, unref } from 'vue'
import { useGettext } from 'vue3-gettext'
import { useClientService, useRouter, useStore } from 'web-pkg/src/composables'
import { useClientService, useLoadingService, useRouter, useStore } from 'web-pkg/src/composables'
import { Action } from 'web-pkg/src/composables/actions'

export const useFileActionsPaste = ({ store }: { store?: Store<any> } = {}) => {
store = store || useStore()
const router = useRouter()
const clientService = useClientService()
const loadingService = useLoadingService()
const { $gettext, $pgettext, interpolate: $gettextInterpolate, $ngettext } = useGettext()

const isMacOs = computed(() => {
Expand All @@ -30,6 +31,7 @@ export const useFileActionsPaste = ({ store }: { store?: Store<any> } = {}) => {
store.dispatch('Files/pasteSelectedFiles', {
targetSpace: space,
clientService,
loadingService,
createModal: (...args) => store.dispatch('createModal', ...args),
hideModal: (...args) => store.dispatch('hideModal', ...args),
showMessage: (...args) => store.dispatch('showMessage', ...args),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@ import {
useAccessToken,
useCapabilitySpacesEnabled,
useClientService,
useLoadingService,
useRouter,
useStore
} from 'web-pkg/src/composables'
import { computed, unref } from 'vue'
import { useGettext } from 'vue3-gettext'
import { Action, ActionOptions } from 'web-pkg/src/composables/actions'
import { LoadingTaskCallbackArguments } from 'web-pkg'

export const useFileActionsRestore = ({ store }: { store?: Store<any> } = {}) => {
store = store || useStore()
const router = useRouter()
const { $gettext, $ngettext, interpolate: $gettextInterpolate } = useGettext()
const clientService = useClientService()
const accessToken = useAccessToken({ store })
const loadingService = useLoadingService()

const hasSpacesEnabled = useCapabilitySpacesEnabled()

Expand Down Expand Up @@ -151,13 +154,14 @@ export const useFileActionsRestore = ({ store }: { store?: Store<any> } = {}) =>
const restoreResources = async (
space: SpaceResource,
resources: Resource[],
missingFolderPaths: string[]
missingFolderPaths: string[],
{ setProgress }: LoadingTaskCallbackArguments
) => {
const restoredResources = []
const failedResources = []

let createdFolderPaths = []
for (const resource of resources) {
for (const [i, resource] of resources.entries()) {
const parentPath = dirname(resource.path)
if (missingFolderPaths.includes(parentPath)) {
const { existingPaths } = await createFolderStructure(space, parentPath, createdFolderPaths)
Expand All @@ -172,6 +176,8 @@ export const useFileActionsRestore = ({ store }: { store?: Store<any> } = {}) =>
} catch (e) {
console.error(e)
failedResources.push(resource)
} finally {
setProgress({ total: resources.length, current: i + 1 })
}
}

Expand Down Expand Up @@ -261,7 +267,12 @@ export const useFileActionsRestore = ({ store }: { store?: Store<any> } = {}) =>
resource.path = urlJoin(parentPath, resolvedName)
resolvedResources.push(resource)
}
return restoreResources(space, resolvedResources, missingFolderPaths)
return loadingService.addTask(
({ setProgress }) => {
return restoreResources(space, resolvedResources, missingFolderPaths, { setProgress })
},
{ indeterminate: false }
)
}

const actions = computed((): Action[] => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
useCapabilityShareJailEnabled,
useClientService,
useRouter,
useStore
useStore,
useLoadingService
} from 'web-pkg/src/composables'
import { useGettext } from 'vue3-gettext'
import { ref } from 'vue'
Expand All @@ -27,6 +28,7 @@ export const useFileActionsDeleteResources = ({ store }: { store?: Store<any> })
const hasShareJail = useCapabilityShareJailEnabled()
const hasSpacesEnabled = useCapabilitySpacesEnabled()
const clientService = useClientService()
const loadingService = useLoadingService()
const { owncloudSdk } = clientService
const accessToken = useAccessToken({ store })

Expand Down Expand Up @@ -143,6 +145,7 @@ export const useFileActionsDeleteResources = ({ store }: { store?: Store<any> })
const trashbin_delete = (space: SpaceResource) => {
// TODO: use clear all if all files are selected
store.dispatch('toggleModalConfirmButton')
// FIXME: Implement proper batch delete and add loading indicator
for (const file of unref(resources)) {
const p = queue.add(() => {
return trashbin_deleteOp(space, file)
Expand All @@ -157,51 +160,59 @@ export const useFileActionsDeleteResources = ({ store }: { store?: Store<any> })
}

const filesList_delete = (space: SpaceResource) => {
store
.dispatch('Files/deleteFiles', {
...language,
space,
files: unref(resources),
clientService
})
.then(async () => {
store.dispatch('hideModal')
store.dispatch('toggleModalConfirmButton')

// Load quota
if (
isLocationSpacesActive(router, 'files-spaces-generic') &&
!['public', 'share'].includes(space?.driveType)
) {
if (unref(hasSpacesEnabled)) {
const graphClient = clientService.graphAuthenticated(
store.getters.configuration.server,
unref(accessToken)
)
const driveResponse = await graphClient.drives.getDrive(unref(resources)[0].storageId)
store.commit('runtime/spaces/UPDATE_SPACE_FIELD', {
id: driveResponse.data.id,
field: 'spaceQuota',
value: driveResponse.data.quota
})
} else {
const user = await owncloudSdk.users.getUser(store.getters.user.id)
store.commit('SET_QUOTA', user.quota)
}
}

if (
unref(resourcesToDelete).length &&
isSameResource(unref(resourcesToDelete)[0], store.getters['Files/currentFolder'])
) {
return router.push(
createFileRouteOptions(space, {
path: dirname(unref(resourcesToDelete)[0].path),
fileId: unref(resourcesToDelete)[0].parentFolderId
})
)
}
})
return loadingService.addTask(
(loadingCallbackArgs) => {
return store
.dispatch('Files/deleteFiles', {
...language,
space,
files: unref(resources),
clientService,
loadingCallbackArgs
})
.then(async () => {
store.dispatch('hideModal')
store.dispatch('toggleModalConfirmButton')

// Load quota
if (
isLocationSpacesActive(router, 'files-spaces-generic') &&
!['public', 'share'].includes(space?.driveType)
) {
if (unref(hasSpacesEnabled)) {
const graphClient = clientService.graphAuthenticated(
store.getters.configuration.server,
unref(accessToken)
)
const driveResponse = await graphClient.drives.getDrive(
unref(resources)[0].storageId
)
store.commit('runtime/spaces/UPDATE_SPACE_FIELD', {
id: driveResponse.data.id,
field: 'spaceQuota',
value: driveResponse.data.quota
})
} else {
const user = await owncloudSdk.users.getUser(store.getters.user.id)
store.commit('SET_QUOTA', user.quota)
}
}

if (
unref(resourcesToDelete).length &&
isSameResource(unref(resourcesToDelete)[0], store.getters['Files/currentFolder'])
) {
return router.push(
createFileRouteOptions(space, {
path: dirname(unref(resourcesToDelete)[0].path),
fileId: unref(resourcesToDelete)[0].parentFolderId
})
)
}
})
},
{ indeterminate: false }
)
}

const deleteHelper = (space: SpaceResource) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/web-app-files/src/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export default {
const { setProgress } = loadingCallbackArgs
const promises = []
const removedFiles = []
for (const file of files) {
for (const [i, file] of files.entries()) {
const promise = clientService.webdav
.deleteFile(space, file)
.then(() => {
Expand Down Expand Up @@ -208,7 +208,7 @@ export default {
)
})
.finally(() => {
setProgress({ total: files.length, current: removedFiles.length })
setProgress({ total: files.length, current: i + 1 })
})
promises.push(promise)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useStore } from 'web-pkg/src/composables'
import { unref } from 'vue'
import { Resource } from 'web-client'
import { FileResource, ProjectSpaceResource, SpaceResource } from 'web-client/src/helpers'
import { LoadingTaskCallbackArguments } from 'web-pkg'

describe('restore', () => {
afterEach(() => jest.clearAllMocks())
Expand Down Expand Up @@ -80,7 +81,12 @@ describe('restore', () => {
it('should show message on success', () => {
const { wrapper } = getWrapper({
setup: async ({ restoreResources }, { space, storeOptions }) => {
await restoreResources(space, [{ id: '1', path: '/1' }], [])
await restoreResources(
space,
[{ id: '1', path: '/1' }],
[],
mock<LoadingTaskCallbackArguments>()
)

expect(storeOptions.actions.showMessage).toHaveBeenCalledTimes(1)
expect(storeOptions.modules.Files.actions.removeFilesFromTrashbin).toHaveBeenCalledTimes(
Expand Down

0 comments on commit 3b8a325

Please sign in to comment.