Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[full-ci] Add global loading indicator for long running tasks #8611

Merged
merged 9 commits into from
Mar 20, 2023
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 })
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to destructure and build a new object, but not so important

{ 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