From 7ef2380ec4689ddb03c89792aff01c51ff45e150 Mon Sep 17 00:00:00 2001 From: Jannik Stehle Date: Wed, 18 Oct 2023 17:36:05 +0200 Subject: [PATCH] put remaining parts together to make it work --- .../src/components/OcButton/OcButton.vue | 1 - .../components/Shares/SharedWithMeSection.vue | 53 ++++--- .../src/views/shares/SharedWithMe.vue | 130 +++++++----------- .../unit/views/shares/SharedWithMe.spec.ts | 65 +++------ .../web-client/src/helpers/resource/types.ts | 2 +- .../web-client/src/helpers/share/functions.ts | 2 +- .../web-pkg/src/components/AppBar/AppBar.vue | 11 +- .../components/FilesList/ContextActions.vue | 8 +- .../components/Filters/ItemFilterInline.vue | 107 ++++++++++++++ .../web-pkg/src/components/Filters/index.ts | 2 + .../web-pkg/src/components/Filters/types.ts | 4 + packages/web-pkg/src/components/index.ts | 1 + .../src/composables/actions/files/index.ts | 6 +- .../actions/files/useFileActions.ts | 14 +- ...eptShare.ts => useFileActionsSyncShare.ts} | 18 +-- ...re.ts => useFileActionsToggleHideShare.ts} | 68 ++++----- ...eShare.ts => useFileActionsUnsyncShare.ts} | 20 ++- .../src/helpers/share/triggerShareAction.ts | 6 +- .../FilesList/ContextActions.spec.ts | 4 +- .../Filters/ItemFilterInline.spec.ts | 70 ++++++++++ ...pec.ts => useFileActionsSyncShare.spec.ts} | 6 +- .../helpers/share/triggerShareAction.spec.ts | 2 +- pnpm-lock.yaml | 59 ++++---- .../FilesPageElement/fileActionsMenu.js | 4 +- .../pageObjects/sharedWithMePage.js | 2 +- .../objects/app-files/share/actions.ts | 2 +- 26 files changed, 387 insertions(+), 280 deletions(-) create mode 100644 packages/web-pkg/src/components/Filters/ItemFilterInline.vue create mode 100644 packages/web-pkg/src/components/Filters/index.ts create mode 100644 packages/web-pkg/src/components/Filters/types.ts rename packages/web-pkg/src/composables/actions/files/{useFileActionsAcceptShare.ts => useFileActionsSyncShare.ts} (87%) rename packages/web-pkg/src/composables/actions/files/{useFileActionsHideShare.ts => useFileActionsToggleHideShare.ts} (58%) rename packages/web-pkg/src/composables/actions/files/{useFileActionsDeclineShare.ts => useFileActionsUnsyncShare.ts} (86%) create mode 100644 packages/web-pkg/tests/unit/components/Filters/ItemFilterInline.spec.ts rename packages/web-pkg/tests/unit/composables/actions/files/{useFileActionsAcceptShare.spec.ts => useFileActionsSyncShare.spec.ts} (90%) diff --git a/packages/design-system/src/components/OcButton/OcButton.vue b/packages/design-system/src/components/OcButton/OcButton.vue index 99fd847e290..d51668ae0da 100644 --- a/packages/design-system/src/components/OcButton/OcButton.vue +++ b/packages/design-system/src/components/OcButton/OcButton.vue @@ -221,7 +221,6 @@ export default defineComponent({ &-raw-inverse { background-color: transparent; border-style: none; - font-size: var(--oc-font-size-medium); font-weight: normal; min-height: 0; padding: 0; diff --git a/packages/web-app-files/src/components/Shares/SharedWithMeSection.vue b/packages/web-app-files/src/components/Shares/SharedWithMeSection.vue index 4cdeca44be5..ccebeca1b1a 100644 --- a/packages/web-app-files/src/components/Shares/SharedWithMeSection.vue +++ b/packages/web-app-files/src/components/Shares/SharedWithMeSection.vue @@ -39,7 +39,11 @@ :key="resource.getDomSelector() + resource.status" class="oc-text-nowrap oc-flex oc-flex-middle oc-flex-right" > - + diff --git a/packages/web-app-files/tests/unit/views/shares/SharedWithMe.spec.ts b/packages/web-app-files/tests/unit/views/shares/SharedWithMe.spec.ts index 18fc146fa40..5493bcb37b2 100644 --- a/packages/web-app-files/tests/unit/views/shares/SharedWithMe.spec.ts +++ b/packages/web-app-files/tests/unit/views/shares/SharedWithMe.spec.ts @@ -1,13 +1,11 @@ import SharedWithMe from '../../../../src/views/shares/SharedWithMe.vue' import { useResourcesViewDefaults } from 'web-app-files/src/composables' -import { useSort } from '@ownclouders/web-pkg' +import { InlineFilterOption, useSort } from '@ownclouders/web-pkg' import { useResourcesViewDefaultsMock } from 'web-app-files/tests/mocks/useResourcesViewDefaultsMock' -import { ShareStatus } from '@ownclouders/web-client/src/helpers/share' import { ref } from 'vue' import { defaultStubs, RouteLocation } from 'web-test-helpers' import { useSortMock } from 'web-app-files/tests/mocks/useSortMock' -import { mock, mockDeep } from 'jest-mock-extended' -import { Resource } from '@ownclouders/web-client' +import { mock } from 'jest-mock-extended' import { createStore, defaultPlugins, @@ -41,48 +39,27 @@ describe('SharedWithMe view', () => { expect(wrapper.find('oc-spinner-stub').exists()).toBeFalsy() }) }) - describe('sections', () => { - it('always shows the "accepted"- and "declined"-sections', () => { + describe('filter', () => { + it('shows the share visibility filter', () => { const { wrapper } = getMountedWrapper() - expect(wrapper.find('#files-shared-with-me-accepted-section').exists()).toBeTruthy() - expect(wrapper.find('#files-shared-with-me-declined-section').exists()).toBeTruthy() + expect(wrapper.find('.share-visibility-filter').exists()).toBeTruthy() + expect(wrapper.find('item-filter-inline-stub').exists()).toBeTruthy() }) - describe('pending', () => { - it('shows when a share is pending', () => { - const { wrapper } = getMountedWrapper({ - files: [mockDeep({ status: ShareStatus.pending })] - }) - expect(wrapper.find('#files-shared-with-me-pending-section').exists()).toBeTruthy() - }) - it('does not show when no share is pending', () => { - const { wrapper } = getMountedWrapper({ - files: [mockDeep({ status: ShareStatus.accepted })] - }) - expect(wrapper.find('#files-shared-with-me-pending-section').exists()).toBeFalsy() - }) - }) - describe('accepted', () => { - it('shows an accepted share', () => { - const { wrapper } = getMountedWrapper({ - files: [mockDeep({ status: ShareStatus.accepted })] - }) - expect(wrapper.find('#files-shared-with-me-accepted-section').exists()).toBeTruthy() - expect( - wrapper.findComponent('#files-shared-with-me-accepted-section').props().items.length - ).toEqual(1) - }) + it('shows all visible shares', () => { + const { wrapper } = getMountedWrapper() + expect(wrapper.findAll('shared-with-me-section-stub').length).toBe(1) + expect(wrapper.findComponent('shared-with-me-section-stub').props('title')).toEqual( + 'Shares' + ) }) - describe('declined', () => { - it('shows a declined share', async () => { - const { wrapper } = getMountedWrapper({ - files: [mockDeep({ status: ShareStatus.declined })] - }) - await wrapper.vm.loadResourcesTask.last - expect(wrapper.find('#files-shared-with-me-declined-section').exists()).toBeTruthy() - expect( - wrapper.findComponent('#files-shared-with-me-declined-section').props().items.length - ).toEqual(1) - }) + it('shows all hidden shares', async () => { + const { wrapper } = getMountedWrapper() + wrapper.vm.setAreHiddenFilesShown(mock({ name: 'hidden' })) + await wrapper.vm.$nextTick() + expect(wrapper.findAll('shared-with-me-section-stub').length).toBe(1) + expect(wrapper.findComponent('shared-with-me-section-stub').props('title')).toEqual( + 'Hidden Shares' + ) }) }) }) @@ -110,7 +87,7 @@ function getMountedWrapper({ mocks = {}, loading = false, files = [] } = {}) { global: { plugins: [...defaultPlugins(), store], mocks: defaultMocks, - stubs: defaultStubs + stubs: { ...defaultStubs, itemFilterInline: true } } }) } diff --git a/packages/web-client/src/helpers/resource/types.ts b/packages/web-client/src/helpers/resource/types.ts index ae26fecb8af..f7d7b5c7ec6 100644 --- a/packages/web-client/src/helpers/resource/types.ts +++ b/packages/web-client/src/helpers/resource/types.ts @@ -114,7 +114,7 @@ export interface Resource { sharedWith?: string shareOwner?: string shareOwnerDisplayname?: string - hide?: string + hidden?: boolean extension?: string share?: any diff --git a/packages/web-client/src/helpers/share/functions.ts b/packages/web-client/src/helpers/share/functions.ts index 7b6476347ab..c3d31a4920e 100644 --- a/packages/web-client/src/helpers/share/functions.ts +++ b/packages/web-client/src/helpers/share/functions.ts @@ -174,7 +174,7 @@ export function buildSharedResource( ] resource.sharedWith = share.sharedWith || [] resource.status = parseInt(share.state) - resource.hide = share.hide || 'false' + resource.hidden = share.hide === 'true' || share.hide === true resource.name = path.basename(share.file_target) if (hasShareJail) { // FIXME, HACK 1: path needs to be '/' because the share has it's own webdav endpoint (we access it's root). should ideally be removed backend side. diff --git a/packages/web-pkg/src/components/AppBar/AppBar.vue b/packages/web-pkg/src/components/AppBar/AppBar.vue index d456338351f..84192c08922 100644 --- a/packages/web-pkg/src/components/AppBar/AppBar.vue +++ b/packages/web-pkg/src/components/AppBar/AppBar.vue @@ -89,9 +89,9 @@ import ContextActions from '../FilesList/ContextActions.vue' import SidebarToggle from './SidebarToggle.vue' import { ViewMode } from '../../ui/types' import { - useFileActionsAcceptShare, + useFileActionsSyncShare, useFileActionsCopy, - useFileActionsDeclineShare, + useFileActionsUnsyncShare, useFileActionsDelete, useFileActionsDownloadArchive, useFileActionsDownloadFile, @@ -101,6 +101,7 @@ import { } from '../../composables/actions' import { useCapabilitySpacesMaxQuota, + useFileActionsToggleHideShare, useRouteMeta, useStore, ViewModeConstants @@ -165,9 +166,10 @@ export default defineComponent({ const store = useStore() const { $gettext } = useGettext() - const { actions: acceptShareActions } = useFileActionsAcceptShare({ store }) + const { actions: acceptShareActions } = useFileActionsSyncShare({ store }) + const { actions: hideShareActions } = useFileActionsToggleHideShare({ store }) const { actions: copyActions } = useFileActionsCopy({ store }) - const { actions: declineShareActions } = useFileActionsDeclineShare({ store }) + const { actions: declineShareActions } = useFileActionsUnsyncShare({ store }) const { actions: deleteActions } = useFileActionsDelete({ store }) const { actions: downloadArchiveActions } = useFileActionsDownloadArchive({ store }) const { actions: downloadFileActions } = useFileActionsDownloadFile() @@ -190,6 +192,7 @@ export default defineComponent({ const batchActions = computed(() => { let actions = [ + ...unref(hideShareActions), ...unref(acceptShareActions), ...unref(declineShareActions), ...unref(downloadArchiveActions), diff --git a/packages/web-pkg/src/components/FilesList/ContextActions.vue b/packages/web-pkg/src/components/FilesList/ContextActions.vue index 58123b10b8e..c8dc683ef0f 100644 --- a/packages/web-pkg/src/components/FilesList/ContextActions.vue +++ b/packages/web-pkg/src/components/FilesList/ContextActions.vue @@ -13,9 +13,9 @@ import { useFileActionsPaste, useFileActionsShowDetails, useFileActionsShowShares, - useFileActionsAcceptShare, + useFileActionsSyncShare, useFileActionsCopy, - useFileActionsDeclineShare, + useFileActionsUnsyncShare, useFileActionsDelete, useFileActionsDownloadArchive, useFileActionsEmptyTrashBin, @@ -48,10 +48,10 @@ export default defineComponent({ const { editorActions, loadExternalAppActions } = useFileActions() - const { actions: acceptShareActions } = useFileActionsAcceptShare({ store }) + const { actions: acceptShareActions } = useFileActionsSyncShare({ store }) const { actions: copyActions } = useFileActionsCopy({ store }) const { actions: createQuickLinkActions } = useFileActionsCreateQuickLink({ store }) - const { actions: declineShareActions } = useFileActionsDeclineShare({ store }) + const { actions: declineShareActions } = useFileActionsUnsyncShare({ store }) const { actions: deleteActions } = useFileActionsDelete({ store }) const { actions: downloadArchiveActions } = useFileActionsDownloadArchive({ store }) const { actions: downloadFileActions } = useFileActionsDownloadFile() diff --git a/packages/web-pkg/src/components/Filters/ItemFilterInline.vue b/packages/web-pkg/src/components/Filters/ItemFilterInline.vue new file mode 100644 index 00000000000..ad20badd8e7 --- /dev/null +++ b/packages/web-pkg/src/components/Filters/ItemFilterInline.vue @@ -0,0 +1,107 @@ + + + + diff --git a/packages/web-pkg/src/components/Filters/index.ts b/packages/web-pkg/src/components/Filters/index.ts new file mode 100644 index 00000000000..4784d7a7733 --- /dev/null +++ b/packages/web-pkg/src/components/Filters/index.ts @@ -0,0 +1,2 @@ +export { default as ItemFilterInline } from './ItemFilterInline.vue' +export * from './types' diff --git a/packages/web-pkg/src/components/Filters/types.ts b/packages/web-pkg/src/components/Filters/types.ts new file mode 100644 index 00000000000..c24e302dbe7 --- /dev/null +++ b/packages/web-pkg/src/components/Filters/types.ts @@ -0,0 +1,4 @@ +export type InlineFilterOption = { + name: string + label: string +} diff --git a/packages/web-pkg/src/components/index.ts b/packages/web-pkg/src/components/index.ts index abb06250542..5d219809036 100644 --- a/packages/web-pkg/src/components/index.ts +++ b/packages/web-pkg/src/components/index.ts @@ -2,6 +2,7 @@ export * from './AppBar' export * from './AppTemplates' export * from './ContextActions' export * from './FilesList' +export * from './Filters' export * from './SideBar' export * from './Search' export * from './Spaces' diff --git a/packages/web-pkg/src/composables/actions/files/index.ts b/packages/web-pkg/src/composables/actions/files/index.ts index f3d0a4c9fbc..d6cbb6ee1e1 100644 --- a/packages/web-pkg/src/composables/actions/files/index.ts +++ b/packages/web-pkg/src/composables/actions/files/index.ts @@ -1,10 +1,10 @@ export * from './useFileActions' export * from './useFileActionsSetReadme' -export * from './useFileActionsAcceptShare' -export * from './useFileActionsHideShare' +export * from './useFileActionsSyncShare' +export * from './useFileActionsToggleHideShare' export * from './useFileActionsCopy' export * from './useFileActionsCreateQuicklink' -export * from './useFileActionsDeclineShare' +export * from './useFileActionsUnsyncShare' export * from './useFileActionsDelete' export * from './useFileActionsDownloadArchive' export * from './useFileActionsDownloadFile' diff --git a/packages/web-pkg/src/composables/actions/files/useFileActions.ts b/packages/web-pkg/src/composables/actions/files/useFileActions.ts index 8e22d40e19d..9c6aba5ad1c 100644 --- a/packages/web-pkg/src/composables/actions/files/useFileActions.ts +++ b/packages/web-pkg/src/composables/actions/files/useFileActions.ts @@ -19,10 +19,10 @@ import { } from '../../actions' import { - useFileActionsAcceptShare, - useFileActionsHideShare, + useFileActionsSyncShare, + useFileActionsToggleHideShare, useFileActionsCopy, - useFileActionsDeclineShare, + useFileActionsUnsyncShare, useFileActionsDelete, useFileActionsDownloadArchive, useFileActionsDownloadFile, @@ -54,11 +54,11 @@ export const useFileActions = ({ store }: { store?: Store } = {}) => { const { openUrl } = useWindowOpen() - const { actions: acceptShareActions } = useFileActionsAcceptShare({ store }) - const { actions: hideShareActions } = useFileActionsHideShare({ store }) + const { actions: acceptShareActions } = useFileActionsSyncShare({ store }) + const { actions: hideShareActions } = useFileActionsToggleHideShare({ store }) const { actions: copyActions } = useFileActionsCopy({ store }) const { actions: deleteActions } = useFileActionsDelete({ store }) - const { actions: declineShareActions } = useFileActionsDeclineShare({ store }) + const { actions: declineShareActions } = useFileActionsUnsyncShare({ store }) const { actions: downloadArchiveActions } = useFileActionsDownloadArchive({ store }) const { actions: downloadFileActions } = useFileActionsDownloadFile() const { actions: favoriteActions } = useFileActionsFavorite({ store }) @@ -214,8 +214,6 @@ export const useFileActions = ({ store }: { store?: Store } = {}) => { } const triggerAction = (name: string, options: FileActionOptions) => { - console.log(getAllAvailableActions(options)) - const action = getAllAvailableActions(options).filter((action) => action.name === name)[0] if (!action) { throw new Error(`Action not found: '${name}'`) diff --git a/packages/web-pkg/src/composables/actions/files/useFileActionsAcceptShare.ts b/packages/web-pkg/src/composables/actions/files/useFileActionsSyncShare.ts similarity index 87% rename from packages/web-pkg/src/composables/actions/files/useFileActionsAcceptShare.ts rename to packages/web-pkg/src/composables/actions/files/useFileActionsSyncShare.ts index 7a83fb8ae72..e7795d95f74 100644 --- a/packages/web-pkg/src/composables/actions/files/useFileActionsAcceptShare.ts +++ b/packages/web-pkg/src/composables/actions/files/useFileActionsSyncShare.ts @@ -14,10 +14,10 @@ import { computed, unref } from 'vue' import { useGettext } from 'vue3-gettext' import { FileAction, FileActionOptions } from '../../actions' -export const useFileActionsAcceptShare = ({ store }: { store?: Store } = {}) => { +export const useFileActionsSyncShare = ({ store }: { store?: Store } = {}) => { store = store || useStore() const router = useRouter() - const { $ngettext } = useGettext() + const { $gettext, $ngettext } = useGettext() const hasResharing = useCapabilityFilesSharingResharing() const hasShareJail = useCapabilityShareJailEnabled() @@ -61,8 +61,8 @@ export const useFileActionsAcceptShare = ({ store }: { store?: Store } = {} if (isLocationSpacesActive(router, 'files-spaces-generic')) { store.dispatch('showMessage', { title: $ngettext( - 'The selected share was accepted successfully', - 'The selected shares were accepted successfully', + 'Sync for the selected share was enabled successfully', + 'Sync for the selected shares was enabled successfully', resources.length ) }) @@ -73,8 +73,8 @@ export const useFileActionsAcceptShare = ({ store }: { store?: Store } = {} store.dispatch('showErrorMessage', { title: $ngettext( - 'Failed to accept the selected share.', - 'Failed to accept selected shares.', + 'Failed to enable sync for the the selected share', + 'Failed to enable sync for the selected shares', resources.length ), errors @@ -83,10 +83,10 @@ export const useFileActionsAcceptShare = ({ store }: { store?: Store } = {} const actions = computed((): FileAction[] => [ { - name: 'accept-share', + name: 'sync-share', icon: 'check', handler: (args) => loadingService.addTask(() => handler(args)), - label: ({ resources }) => $ngettext('Accept share', 'Accept shares', resources.length), + label: () => $gettext('Enable sync'), isEnabled: ({ space, resources }) => { if ( !isLocationSharesActive(router, 'files-shares-with-me') && @@ -111,7 +111,7 @@ export const useFileActionsAcceptShare = ({ store }: { store?: Store } = {} return !acceptDisabled }, componentType: 'button', - class: 'oc-files-actions-accept-share-trigger' + class: 'oc-files-actions-sync-share-trigger' } ]) diff --git a/packages/web-pkg/src/composables/actions/files/useFileActionsHideShare.ts b/packages/web-pkg/src/composables/actions/files/useFileActionsToggleHideShare.ts similarity index 58% rename from packages/web-pkg/src/composables/actions/files/useFileActionsHideShare.ts rename to packages/web-pkg/src/composables/actions/files/useFileActionsToggleHideShare.ts index 6d44a82c0aa..6563c1f4179 100644 --- a/packages/web-pkg/src/composables/actions/files/useFileActionsHideShare.ts +++ b/packages/web-pkg/src/composables/actions/files/useFileActionsToggleHideShare.ts @@ -2,8 +2,7 @@ import { triggerShareAction } from '../../../helpers/share/triggerShareAction' import { Store } from 'vuex' import PQueue from 'p-queue' -import { ShareStatus } from '@ownclouders/web-client/src/helpers/share' -import { isLocationSharesActive, isLocationSpacesActive } from '../../../router' +import { isLocationSharesActive } from '../../../router' import { useCapabilityFilesSharingResharing, useCapabilityShareJailEnabled } from '../../capability' import { useClientService } from '../../clientService' import { useConfigurationManager } from '../../configuration' @@ -13,12 +12,12 @@ import { useStore } from '../../store' import { computed, unref } from 'vue' import { useGettext } from 'vue3-gettext' import { FileAction, FileActionOptions } from '../../actions' +import { Resource } from '@ownclouders/web-client' -// TODO: Replace all "accept" copy leftovers -export const useFileActionsHideShare = ({ store }: { store?: Store } = {}) => { +export const useFileActionsToggleHideShare = ({ store }: { store?: Store } = {}) => { store = store || useStore() const router = useRouter() - const { $ngettext } = useGettext() + const { $gettext } = useGettext() const hasResharing = useCapabilityFilesSharingResharing() const hasShareJail = useCapabilityShareJailEnabled() @@ -26,18 +25,22 @@ export const useFileActionsHideShare = ({ store }: { store?: Store } = {}) const loadingService = useLoadingService() const configurationManager = useConfigurationManager() + const highlightedFile = computed(() => store.getters['Files/highlightedFile']) + const handler = async ({ resources }: FileActionOptions) => { const errors = [] const triggerPromises = [] const triggerQueue = new PQueue({ concurrency: 4 }) + const hide = !resources[0].hidden + resources.forEach((resource) => { triggerPromises.push( triggerQueue.add(async () => { try { const share = await triggerShareAction({ resource, - status: ShareStatus.pending, - // visibility: 'public', + status: resource.status, + hide, hasResharing: unref(hasResharing), hasShareJail: unref(hasShareJail), client: clientService.owncloudSdk, @@ -54,63 +57,38 @@ export const useFileActionsHideShare = ({ store }: { store?: Store } = {}) }) ) }) + await Promise.all(triggerPromises) - console.log(errors) + if (errors.length === 0) { store.dispatch('Files/resetFileSelection') - - if (isLocationSpacesActive(router, 'files-spaces-generic')) { - store.dispatch('showMessage', { - title: $ngettext( - 'The selected share was accepted successfully', - 'The selected shares were accepted successfully', - resources.length - ) - }) - } + store.dispatch('showMessage', { + title: hide + ? $gettext('The share was hidden successfully') + : $gettext('The share was unhidden successfully') + }) return } store.dispatch('showErrorMessage', { - title: $ngettext( - 'Failed to accept the selected share.', - 'Failed to accept selected shares.', - resources.length - ), + title: hide ? $gettext('Failed to hide the share') : $gettext('Failed to unhide share share'), errors }) } const actions = computed((): FileAction[] => [ { - name: 'hide-share', - icon: 'check', + name: 'toggle-hide-share', + icon: 'eye-off', // FIXME: change icon based on hidden status handler: (args) => loadingService.addTask(() => handler(args)), - label: ({ resources }) => $ngettext('Accept share', 'Accept shares', resources.length), - isEnabled: ({ space, resources }) => { - if ( - !isLocationSharesActive(router, 'files-shares-with-me') && - !isLocationSpacesActive(router, 'files-spaces-generic') - ) { - return false - } + label: ({ resources }) => (resources[0].hidden ? $gettext('Unhide') : $gettext('Hide')), + isEnabled: ({ resources }) => { if (resources.length === 0) { return false } - if ( - isLocationSpacesActive(router, 'files-spaces-generic') && - (unref(space)?.driveType !== 'share' || resources.length > 1 || resources[0].path !== '/') - ) { - return false - } - - return true - // const acceptDisabled = resources.some((resource) => { - // return resource.status === ShareStatus.accepted - // }) - // return !acceptDisabled + return isLocationSharesActive(router, 'files-shares-with-me') }, componentType: 'button', class: 'oc-files-actions-hide-share-trigger' diff --git a/packages/web-pkg/src/composables/actions/files/useFileActionsDeclineShare.ts b/packages/web-pkg/src/composables/actions/files/useFileActionsUnsyncShare.ts similarity index 86% rename from packages/web-pkg/src/composables/actions/files/useFileActionsDeclineShare.ts rename to packages/web-pkg/src/composables/actions/files/useFileActionsUnsyncShare.ts index 625b8c7ccfd..b59354f4ac6 100644 --- a/packages/web-pkg/src/composables/actions/files/useFileActionsDeclineShare.ts +++ b/packages/web-pkg/src/composables/actions/files/useFileActionsUnsyncShare.ts @@ -17,10 +17,10 @@ import { computed, unref } from 'vue' import { useGettext } from 'vue3-gettext' import { FileAction, FileActionOptions } from '../types' -export const useFileActionsDeclineShare = ({ store }: { store?: Store } = {}) => { +export const useFileActionsUnsyncShare = ({ store }: { store?: Store } = {}) => { store = store || useStore() const router = useRouter() - const { $ngettext } = useGettext() + const { $gettext, $ngettext } = useGettext() const hasResharing = useCapabilityFilesSharingResharing() const hasShareJail = useCapabilityShareJailEnabled() @@ -59,13 +59,11 @@ export const useFileActionsDeclineShare = ({ store }: { store?: Store } = { await Promise.all(triggerPromises) if (errors.length === 0) { - store.dispatch('Files/resetFileSelection') - if (isLocationSpacesActive(router, 'files-spaces-generic')) { store.dispatch('showMessage', { title: $ngettext( - 'The selected share was declined successfully', - 'The selected shares were declined successfully', + 'Sync for the selected share was disabled successfully', + 'Sync for the selected shares was disabled successfully', resources.length ) }) @@ -77,8 +75,8 @@ export const useFileActionsDeclineShare = ({ store }: { store?: Store } = { store.dispatch('showErrorMessage', { title: $ngettext( - 'Failed to decline the selected share', - 'Failed to decline selected shares', + 'Failed to disable sync for the the selected share', + 'Failed to disable sync for the selected shares', resources.length ), errors @@ -87,10 +85,10 @@ export const useFileActionsDeclineShare = ({ store }: { store?: Store } = { const actions = computed((): FileAction[] => [ { - name: 'decline-share', + name: 'unsync-share', icon: 'spam-3', handler: (args) => loadingService.addTask(() => handler(args)), - label: ({ resources }) => $ngettext('Decline share', 'Decline shares', resources.length), + label: () => $gettext('Disable sync'), isEnabled: ({ space, resources }) => { if ( !isLocationSharesActive(router, 'files-shares-with-me') && @@ -115,7 +113,7 @@ export const useFileActionsDeclineShare = ({ store }: { store?: Store } = { return !declineDisabled }, componentType: 'button', - class: 'oc-files-actions-decline-share-trigger' + class: 'oc-files-actions-unsync-share-trigger' } ]) diff --git a/packages/web-pkg/src/helpers/share/triggerShareAction.ts b/packages/web-pkg/src/helpers/share/triggerShareAction.ts index 706fbac89ca..d6337fb16a4 100644 --- a/packages/web-pkg/src/helpers/share/triggerShareAction.ts +++ b/packages/web-pkg/src/helpers/share/triggerShareAction.ts @@ -6,7 +6,7 @@ import { OwnCloudSdk } from '@ownclouders/web-client/src/types' export async function triggerShareAction({ resource, status, - hide = 'false', + hide = false, hasResharing, hasShareJail, client, @@ -15,7 +15,7 @@ export async function triggerShareAction({ }: { resource: Resource status: ShareStatus - hide?: 'false' | 'true' + hide?: boolean hasResharing: boolean hasShareJail: boolean client: OwnCloudSdk @@ -30,7 +30,7 @@ export async function triggerShareAction({ // exec share action let response = await client.requests.ocs({ service: 'apps/files_sharing', - action: `api/v1/shares/pending/${resource.share.id}?hide=${hide}`, + action: `api/v1/shares/pending/${resource.share.id}?hide=${hide ? 'true' : 'false'}`, method }) diff --git a/packages/web-pkg/tests/unit/components/FilesList/ContextActions.spec.ts b/packages/web-pkg/tests/unit/components/FilesList/ContextActions.spec.ts index 8f0d74f6e9a..c4d0ac64bcf 100644 --- a/packages/web-pkg/tests/unit/components/FilesList/ContextActions.spec.ts +++ b/packages/web-pkg/tests/unit/components/FilesList/ContextActions.spec.ts @@ -11,7 +11,7 @@ import { Resource, SpaceResource } from '@ownclouders/web-client/src/helpers' import ContextActions from '../../../../src/components/FilesList/ContextActions.vue' import { - useFileActionsAcceptShare, + useFileActionsSyncShare, useFileActionsCreateQuickLink, useFileActionsRename, useFileActionsCopy @@ -46,7 +46,7 @@ describe.skip('ContextActions', () => { it('render enabled actions', () => { const enabledComposables = [ - useFileActionsAcceptShare, + useFileActionsSyncShare, useFileActionsCreateQuickLink, useFileActionsRename, useFileActionsCopy diff --git a/packages/web-pkg/tests/unit/components/Filters/ItemFilterInline.spec.ts b/packages/web-pkg/tests/unit/components/Filters/ItemFilterInline.spec.ts new file mode 100644 index 00000000000..85b3db8c469 --- /dev/null +++ b/packages/web-pkg/tests/unit/components/Filters/ItemFilterInline.spec.ts @@ -0,0 +1,70 @@ +import ItemFilterInline from '../../../../src/components/Filters/ItemFilterInline.vue' +import { InlineFilterOption } from '../../../../src/components/Filters/types' +import { defaultComponentMocks, defaultPlugins, mount } from 'web-test-helpers' +import { queryItemAsString } from '../../../../src/composables/appDefaults' +import { mock } from 'jest-mock-extended' + +jest.mock('../../../../src/composables/appDefaults', () => ({ + appDefaults: jest.fn(), + queryItemAsString: jest.fn() +})) + +const selectors = { + filterOption: '.item-inline-filter-option', + filterOptionLabel: '.item-inline-filter-option-label', + selectedOptionLabel: '.item-inline-filter-option-selected .item-inline-filter-option-label' +} + +describe('ItemFilterInline', () => { + const filterOptions = [ + mock({ name: 'filter1', label: 'filter1' }), + mock({ name: 'filter2', label: 'filter2' }) + ] + + it('renders all given options', () => { + const { wrapper } = getWrapper({ props: { filterOptions } }) + expect(wrapper.findAll(selectors.filterOption).length).toBe(filterOptions.length) + expect(wrapper.findAll(selectors.filterOption).at(0).text()).toEqual(filterOptions[0].label) + expect(wrapper.findAll(selectors.filterOption).at(1).text()).toEqual(filterOptions[1].label) + }) + it('emits the "toggleFilter"-event on click on an option', async () => { + const { wrapper } = getWrapper({ props: { filterOptions } }) + await wrapper.find(selectors.filterOption).trigger('click') + expect(wrapper.emitted('toggleFilter').length).toBeGreaterThan(0) + }) + describe('route query', () => { + it('sets the active option as query param', async () => { + const { wrapper, mocks } = getWrapper({ props: { filterOptions } }) + const currentRouteQuery = (mocks.$router.currentRoute as any).query + expect(mocks.$router.push).not.toHaveBeenCalled() + await wrapper.find(selectors.filterOption).trigger('click') + expect(currentRouteQuery[wrapper.vm.queryParam]).toBeDefined() + expect(mocks.$router.push).toHaveBeenCalled() + }) + it('sets the active optin initially when given via query param', async () => { + const initialQuery = filterOptions[1].name + const { wrapper } = getWrapper({ initialQuery, props: { filterOptions } }) + await wrapper.vm.$nextTick() + expect(wrapper.find(selectors.selectedOptionLabel).text()).toEqual(initialQuery) + }) + }) +}) + +function getWrapper({ props = {}, initialQuery = '' } = {}) { + jest.mocked(queryItemAsString).mockImplementation(() => initialQuery) + const mocks = defaultComponentMocks() + return { + mocks, + wrapper: mount(ItemFilterInline, { + props: { + filterName: 'InlineFilter', + ...props + }, + global: { + plugins: [...defaultPlugins()], + mocks, + provide: mocks + } + }) + } +} diff --git a/packages/web-pkg/tests/unit/composables/actions/files/useFileActionsAcceptShare.spec.ts b/packages/web-pkg/tests/unit/composables/actions/files/useFileActionsSyncShare.spec.ts similarity index 90% rename from packages/web-pkg/tests/unit/composables/actions/files/useFileActionsAcceptShare.spec.ts rename to packages/web-pkg/tests/unit/composables/actions/files/useFileActionsSyncShare.spec.ts index e4ba16962ca..25f31db3221 100644 --- a/packages/web-pkg/tests/unit/composables/actions/files/useFileActionsAcceptShare.spec.ts +++ b/packages/web-pkg/tests/unit/composables/actions/files/useFileActionsSyncShare.spec.ts @@ -1,6 +1,6 @@ import { mock } from 'jest-mock-extended' import { unref } from 'vue' -import { useFileActionsAcceptShare } from '../../../../../src/composables/actions/files/useFileActionsAcceptShare' +import { useFileActionsSyncShare } from '../../../../../src/composables/actions/files/useFileActionsSyncShare' import { Resource } from '@ownclouders/web-client' import { ShareStatus } from '@ownclouders/web-client/src/helpers/share' import { useStore } from '../../../../../src/composables' @@ -22,7 +22,7 @@ describe('acceptShare', () => { const { wrapper } = getWrapper({ setup: () => { const store = useStore() - const { actions } = useFileActionsAcceptShare({ store }) + const { actions } = useFileActionsSyncShare({ store }) const resources = inputData.resources expect(unref(actions)[0].isEnabled({ space: null, resources })).toBe( @@ -43,7 +43,7 @@ describe('acceptShare', () => { routeName: sharesWithOthersLocation, setup: () => { const store = useStore() - const { actions } = useFileActionsAcceptShare({ store }) + const { actions } = useFileActionsSyncShare({ store }) expect( unref(actions)[0].isEnabled({ space: null, resources: [resource] }) diff --git a/packages/web-pkg/tests/unit/helpers/share/triggerShareAction.spec.ts b/packages/web-pkg/tests/unit/helpers/share/triggerShareAction.spec.ts index c35d6570be5..d7a91f2322d 100644 --- a/packages/web-pkg/tests/unit/helpers/share/triggerShareAction.spec.ts +++ b/packages/web-pkg/tests/unit/helpers/share/triggerShareAction.spec.ts @@ -22,7 +22,7 @@ describe('method triggerShareAction', () => { await expect( triggerShareAction({ resource: null, - status: ShareStatus.pending, + status: 3 as any, hasResharing: true, hasShareJail: false, client: null diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 14e82c6971f..59c16f8a0e8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + overrides: '@uppy/companion-client': https://github.com/owncloud/uppy/releases/download/v3.12.13-owncloud/uppy-companion-client.tgz '@uppy/core': https://github.com/owncloud/uppy/releases/download/v3.12.13-owncloud/uppy-core.tgz @@ -1128,8 +1132,8 @@ importers: specifier: ^2.1.0 version: 2.1.0 owncloud-sdk: - specifier: 3.1.0-alpha.9 - version: 3.1.0-alpha.9(axios@1.4.0)(cross-fetch@3.1.4)(promise@8.1.0)(qs@6.10.3)(utf8@3.0.0)(uuid@9.0.0)(webdav@5.3.0)(xml-js@1.6.11) + specifier: file:./../../../owncloud-sdk + version: file:../owncloud-sdk(axios@1.4.0)(cross-fetch@3.1.4)(promise@8.1.0)(qs@6.10.3)(utf8@3.0.0)(uuid@9.0.0)(webdav@5.3.0)(xml-js@1.6.11) p-queue: specifier: ^6.6.2 version: 6.6.2 @@ -16789,28 +16793,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /owncloud-sdk@3.1.0-alpha.9(axios@1.4.0)(cross-fetch@3.1.4)(promise@8.1.0)(qs@6.10.3)(utf8@3.0.0)(uuid@9.0.0)(webdav@5.3.0)(xml-js@1.6.11): - resolution: {integrity: sha512-RFisWiv7ZJbWnLKSt2UyPVWbsZqYQ1crWQwpRGwsnKD0Ow5qMXvhbKzZh0EsEF6KEGiQVV3j1lfmgxUDIgBKgA==} - peerDependencies: - axios: ^0.27.2 - cross-fetch: ^3.0.6 - promise: ^8.1.0 - qs: ^6.10.3 - utf8: ^3.0.0 - uuid: ^8.2.0 - webdav: 4.10.0 - xml-js: ^1.6.11 - dependencies: - axios: 1.4.0 - cross-fetch: 3.1.4 - promise: 8.1.0 - qs: 6.10.3 - utf8: 3.0.0 - uuid: 9.0.0 - webdav: 5.3.0 - xml-js: 1.6.11 - dev: false - /p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -22594,6 +22576,31 @@ packages: preact: 10.7.1 dev: false + file:../owncloud-sdk(axios@1.4.0)(cross-fetch@3.1.4)(promise@8.1.0)(qs@6.10.3)(utf8@3.0.0)(uuid@9.0.0)(webdav@5.3.0)(xml-js@1.6.11): + resolution: {directory: ../owncloud-sdk, type: directory} + id: file:../owncloud-sdk + name: owncloud-sdk + version: 3.0.0 + peerDependencies: + axios: ^0.27.2 + cross-fetch: ^3.0.6 + promise: ^8.1.0 + qs: ^6.10.3 + utf8: ^3.0.0 + uuid: ^8.2.0 + webdav: 4.10.0 + xml-js: ^1.6.11 + dependencies: + axios: 1.4.0 + cross-fetch: 3.1.4 + promise: 8.1.0 + qs: 6.10.3 + utf8: 3.0.0 + uuid: 9.0.0 + webdav: 5.3.0 + xml-js: 1.6.11 + dev: false + github.com/dschmidt/v-calendar/3ce6e3b8afd5491cb53ee811281d5fa8a45b044d(vue@3.3.4): resolution: {tarball: https://codeload.github.com/dschmidt/v-calendar/tar.gz/3ce6e3b8afd5491cb53ee811281d5fa8a45b044d} id: github.com/dschmidt/v-calendar/3ce6e3b8afd5491cb53ee811281d5fa8a45b044d @@ -22609,7 +22616,3 @@ packages: lodash: 4.17.21 vue: 3.3.4 dev: true - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false diff --git a/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js b/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js index ba86501ae50..a774bdbd31e 100644 --- a/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js +++ b/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js @@ -226,11 +226,11 @@ module.exports = { locateStrategy: 'xpath' }, acceptShareButtonInAccordion: { - selector: '//button[contains(@class, "oc-files-actions-accept-share-trigger")]', + selector: '//button[contains(@class, "oc-files-actions-sync-share-trigger")]', locateStrategy: 'xpath' }, declineShareButtonInAccordion: { - selector: '//button[contains(@class, "oc-files-actions-decline-share-trigger")]', + selector: '//button[contains(@class, "oc-files-actions-unsync-share-trigger")]', locateStrategy: 'xpath' }, previewButtonInAccordion: { diff --git a/tests/acceptance/pageObjects/sharedWithMePage.js b/tests/acceptance/pageObjects/sharedWithMePage.js index 6b726417073..243041e824b 100644 --- a/tests/acceptance/pageObjects/sharedWithMePage.js +++ b/tests/acceptance/pageObjects/sharedWithMePage.js @@ -159,7 +159,7 @@ module.exports = { locateStrategy: 'xpath' }, batchDeclineSharesButton: { - selector: '.oc-files-actions-decline-share-trigger' + selector: '.oc-files-actions-unsync-share-trigger' } } } diff --git a/tests/e2e/support/objects/app-files/share/actions.ts b/tests/e2e/support/objects/app-files/share/actions.ts index 298246ca743..7ff7a690ae7 100644 --- a/tests/e2e/support/objects/app-files/share/actions.ts +++ b/tests/e2e/support/objects/app-files/share/actions.ts @@ -27,7 +27,7 @@ const publicLinkInputField = '/following-sibling::div//p[contains(@class,"oc-files-file-link-url")]' const showAllButton = '#files-shared-with-me-pending-section #files-shared-with-me-show-all' const selecAllCheckbox = '#files-shared-with-me-pending-section #resource-table-select-all' -const acceptButton = '.oc-files-actions-accept-share-trigger' +const acceptButton = '.oc-files-actions-sync-share-trigger' const pendingShareItem = '//div[@id="files-shared-with-me-pending-section"]//tr[contains(@class,"oc-tbody-tr")]'