Skip to content

Commit

Permalink
Merge pull request #8611 from owncloud/global-loading-indicator
Browse files Browse the repository at this point in the history
[full-ci] Add global loading indicator for long running tasks
  • Loading branch information
JammingBen authored Mar 20, 2023
2 parents 9978254 + e404ff6 commit 0f704fc
Show file tree
Hide file tree
Showing 34 changed files with 562 additions and 156 deletions.
7 changes: 7 additions & 0 deletions changelog/unreleased/enhancement-global-loading-indicator
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Global loading indicator

A global loading indicator for long running actions has been added to the top of the page.

https://github.com/owncloud/web/issues/6183
https://github.com/owncloud/web/issues/2134
https://github.com/owncloud/web/pull/8611
18 changes: 10 additions & 8 deletions packages/web-app-admin-settings/src/views/Users.vue
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ import {
useAccessToken,
useCapabilitySpacesMaxQuota,
useGraphClient,
useLoadingService,
useRouteQuery,
useStore
} from 'web-pkg/src/composables'
Expand Down Expand Up @@ -221,6 +222,7 @@ export default defineComponent({
const store = useStore()
const accessToken = useAccessToken({ store })
const { graphClient } = useGraphClient()
const loadingService = useLoadingService()
const { actions: removeFromGroupsActions } = useRemoveFromGroups()
const { actions: addToGroupsActions } = useAddToGroups()
Expand Down Expand Up @@ -434,10 +436,10 @@ export default defineComponent({
}
return acc
}, addUsersToGroupsRequests)
await Promise.all(addUsersToGroupsRequests)
const usersResponse = await Promise.all(
usersToFetch.map((userId) => unref(graphClient).users.getUser(userId))
)
const usersResponse = await loadingService.addTask(async () => {
await Promise.all(addUsersToGroupsRequests)
return Promise.all(usersToFetch.map((userId) => unref(graphClient).users.getUser(userId)))
})
for (const { data: updatedUser } of usersResponse) {
const userIndex = unref(users).findIndex((user) => user.id === updatedUser.id)
unref(users)[userIndex] = updatedUser
Expand Down Expand Up @@ -477,10 +479,10 @@ export default defineComponent({
}
return acc
}, removeUsersToGroupsRequests)
await Promise.all(removeUsersToGroupsRequests)
const usersResponse = await Promise.all(
usersToFetch.map((userId) => unref(graphClient).users.getUser(userId))
)
const usersResponse = await loadingService.addTask(async () => {
await Promise.all(removeUsersToGroupsRequests)
return Promise.all(usersToFetch.map((userId) => unref(graphClient).users.getUser(userId)))
})
for (const { data: updatedUser } of usersResponse) {
const userIndex = unref(users).findIndex((user) => user.id === updatedUser.id)
unref(users)[userIndex] = updatedUser
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import SpacesList from '../../../../src/components/Spaces/SpacesList.vue'
import { defaultPlugins, mount, shallowMount } from 'web-test-helpers'
import { displayPositionedDropdown, eventBus } from 'web-pkg'
import { eventBus } from 'web-pkg'
import { displayPositionedDropdown } from 'web-pkg/src/helpers'
import { SideBarEventTopics } from 'web-pkg/src/composables/sideBar'
import { nextTick } from 'vue'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ export default defineComponent({
this.pasteSelectedFiles({
targetSpace: this.space,
clientService: this.$clientService,
loadingService: this.$loadingService,
createModal: this.createModal,
hideModal: this.hideModal,
showMessage: this.showMessage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,10 @@
<script lang="ts">
import keycode from 'keycode'
import { eventBus } from 'web-pkg/src/services/eventBus'
import {
defineComponent,
getCurrentInstance,
onBeforeUnmount,
onMounted,
PropType,
computed,
ref,
unref
} from 'vue'
import { defineComponent, onBeforeUnmount, onMounted, PropType, computed, ref, unref } from 'vue'
import { Resource, SpaceResource } from 'web-client/src/helpers'
import { useScrollTo } from 'web-app-files/src/composables/scrollTo'
import { useClientService, useStore } from 'web-pkg'
import { useClientService, useLoadingService, useStore } from 'web-pkg'
import { useGettext } from 'vue3-gettext'
export default defineComponent({
Expand All @@ -37,11 +28,11 @@ export default defineComponent({
}
},
setup(props) {
const instance = getCurrentInstance().proxy as any
const store = useStore()
const language = useGettext()
const clientService = useClientService()
const { scrollToResource } = useScrollTo()
const loadingService = useLoadingService()
const selectionCursor = ref(0)
let fileListClickedEvent
Expand Down Expand Up @@ -106,6 +97,7 @@ export default defineComponent({
store.dispatch('Files/pasteSelectedFiles', {
targetSpace: props.space,
clientService: clientService,
loadingService: loadingService,
createModal: (modal) => {
store.dispatch('createModal', modal)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
useCapabilityFilesSharingResharing,
useCapabilityShareJailEnabled,
useClientService,
useLoadingService,
useRouter,
useStore
} from 'web-pkg/src/composables'
Expand All @@ -23,6 +24,7 @@ export const useFileActionsAcceptShare = ({ store }: { store?: Store<any> } = {}
const hasResharing = useCapabilityFilesSharingResharing()
const hasShareJail = useCapabilityShareJailEnabled()
const { owncloudSdk } = useClientService()
const loadingService = useLoadingService()

const handler = async ({ resources }: FileActionOptions) => {
const errors = []
Expand Down Expand Up @@ -81,7 +83,7 @@ export const useFileActionsAcceptShare = ({ store }: { store?: Store<any> } = {}
{
name: 'accept-share',
icon: 'check',
handler,
handler: (args) => loadingService.addTask(() => handler(args)),
label: ({ resources }) => $ngettext('Accept share', 'Accept shares', resources.length),
isEnabled: ({ space, resources }) => {
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
useCapabilityFilesSharingResharing,
useCapabilityShareJailEnabled,
useClientService,
useLoadingService,
useRouter,
useStore
} from 'web-pkg/src/composables'
Expand All @@ -26,6 +27,7 @@ export const useFileActionsDeclineShare = ({ store }: { store?: Store<any> } = {
const hasResharing = useCapabilityFilesSharingResharing()
const hasShareJail = useCapabilityShareJailEnabled()
const { owncloudSdk } = useClientService()
const loadingService = useLoadingService()

const handler = async ({ resources }: FileActionOptions) => {
const errors = []
Expand Down Expand Up @@ -85,7 +87,7 @@ export const useFileActionsDeclineShare = ({ store }: { store?: Store<any> } = {
{
name: 'decline-share',
icon: 'spam-3',
handler,
handler: (args) => loadingService.addTask(() => handler(args)),
label: ({ resources }) => $ngettext('Decline share', 'Decline shares', resources.length),
isEnabled: ({ space, resources }) => {
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Store } from 'vuex'
import { computed, unref } from 'vue'
import {
useClientService,
useLoadingService,
usePublicLinkPassword,
useRouter,
useStore
Expand All @@ -23,12 +24,13 @@ 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 clientService = useClientService()
const publicLinkPassword = usePublicLinkPassword({ store })
const isFilesAppActive = useIsFilesAppActive()

const handler = async ({ space, resources }: FileActionOptions) => {
const handler = ({ space, resources }: FileActionOptions) => {
const fileOptions = archiverService.fileIdsSupported
? {
fileIds: resources.map((resource) => resource.fileId)
Expand All @@ -37,7 +39,7 @@ export const useFileActionsDownloadArchive = ({ store }: { store?: Store<any> }
dir: path.dirname(first<Resource>(resources).path) || '/',
files: resources.map((resource) => resource.name)
}
await archiverService
return archiverService
.triggerDownload({
clientService,
...fileOptions,
Expand All @@ -64,7 +66,7 @@ export const useFileActionsDownloadArchive = ({ store }: { store?: Store<any> }
{
name: 'download-archive',
icon: 'inbox-archive',
handler,
handler: (args) => loadingService.addTask(() => handler(args)),
label: () => {
return $gettext('Download')
},
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 Down Expand Up @@ -62,7 +64,7 @@ export const useFileActionsEmptyTrashBin = ({ store }: { store?: Store<any> } =
),
hasInput: false,
onCancel: () => store.dispatch('hideModal'),
onConfirm: () => emptyTrashBin({ space })
onConfirm: () => loadingService.addTask(() => emptyTrashBin({ space }))
}

store.dispatch('createModal', modal)
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 { FileAction, FileActionOptions } 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 @@ -12,7 +12,7 @@ import {
import { createFileRouteOptions } from 'web-pkg/src/helpers/router'
import { renameResource as _renameResource } from '../../../helpers/resources'
import { computed, unref } from 'vue'
import { useClientService, useRouter, useStore } from 'web-pkg/src/composables'
import { useClientService, useLoadingService, useRouter, useStore } from 'web-pkg/src/composables'
import { useGettext } from 'vue3-gettext'
import { FileAction, FileActionOptions } from 'web-pkg/src/composables/actions'
import { useCapabilityFilesSharingCanRename } from 'web-pkg/src/composables/capability'
Expand All @@ -22,6 +22,7 @@ export const useFileActionsRename = ({ store }: { store?: Store<any> } = {}) =>
const router = useRouter()
const { $gettext, interpolate: $gettextInterpolate } = useGettext()
const clientService = useClientService()
const loadingService = useLoadingService()
const canRename = useCapabilityFilesSharingCanRename()

const checkNewName = (resource, newName, parentResources = undefined) => {
Expand Down Expand Up @@ -167,7 +168,7 @@ export const useFileActionsRename = ({ store }: { store?: Store<any> } = {}) =>
newName = `${newName}.${resources[0].extension}`
}

renameResource(space, resources[0], newName)
return renameResource(space, resources[0], newName)
}
const checkName = (newName) => {
if (!areFileExtensionsShown) {
Expand Down Expand Up @@ -200,7 +201,7 @@ export const useFileActionsRename = ({ store }: { store?: Store<any> } = {}) =>
inputSelectionRange,
inputLabel: resources[0].isFolder ? $gettext('Folder name') : $gettext('File name'),
onCancel: () => store.dispatch('hideModal'),
onConfirm: confirmAction,
onConfirm: (args) => loadingService.addTask(() => confirmAction(args)),
onInput: checkName
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@ import { urlJoin } from 'web-client/src/utils'
import {
useCapabilitySpacesEnabled,
useClientService,
useLoadingService,
useRouter,
useStore
} from 'web-pkg/src/composables'
import { computed, unref } from 'vue'
import { useGettext } from 'vue3-gettext'
import { FileAction, FileActionOptions } 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 loadingService = useLoadingService()

const hasSpacesEnabled = useCapabilitySpacesEnabled()

Expand Down Expand Up @@ -149,13 +152,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 @@ -170,6 +174,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 @@ -256,7 +262,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((): FileAction[] => [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isLocationSpacesActive } from '../../../router'
import { Store } from 'vuex'
import { thumbnailService } from '../../../services'
import { useClientService, useRouter, useStore } from 'web-pkg/src/composables'
import { useClientService, useLoadingService, useRouter, useStore } from 'web-pkg/src/composables'
import { useGettext } from 'vue3-gettext'
import { computed } from 'vue'
import { FileAction, FileActionOptions } from 'web-pkg/src/composables/actions'
Expand All @@ -11,6 +11,7 @@ export const useFileActionsSetImage = ({ store }: { store?: Store<any> } = {}) =
const router = useRouter()
const { $gettext } = useGettext()
const clientService = useClientService()
const loadingService = useLoadingService()

const handler = async ({ space, resources }: FileActionOptions) => {
const graphClient = clientService.graphAuthenticated
Expand Down Expand Up @@ -68,7 +69,7 @@ export const useFileActionsSetImage = ({ store }: { store?: Store<any> } = {}) =
{
name: 'set-space-image',
icon: 'image-edit',
handler,
handler: (args) => loadingService.addTask(() => handler(args)),
label: () => {
return $gettext('Set as space image')
},
Expand Down
Loading

0 comments on commit 0f704fc

Please sign in to comment.