From e29315a7405a74e0df77a2ebf14658c61853a7c5 Mon Sep 17 00:00:00 2001 From: Jannik Stehle Date: Mon, 13 Oct 2025 13:11:27 +0200 Subject: [PATCH 1/2] feat: show disabled delete button for locked files And adds a tooltip explaining why the file can't be deleted. This is helpful when opening a file with Collabora. --- .../actions/files/useFileActionsDelete.ts | 8 ++--- .../files/useFileActionsDelete.spec.ts | 32 +++++++++++++------ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/packages/web-pkg/src/composables/actions/files/useFileActionsDelete.ts b/packages/web-pkg/src/composables/actions/files/useFileActionsDelete.ts index 46f3e398b1..1058dc802d 100644 --- a/packages/web-pkg/src/composables/actions/files/useFileActionsDelete.ts +++ b/packages/web-pkg/src/composables/actions/files/useFileActionsDelete.ts @@ -67,10 +67,6 @@ export const useFileActionsDelete = () => { return false } - if (resources.length === 1 && resources[0].locked) { - return false - } - if (isLocationCommonActive(router, 'files-common-search')) { return resources.some( (r) => r.canBeDeleted() && !r.isShareRoot() && !isProjectSpaceResource(r) @@ -81,6 +77,10 @@ export const useFileActionsDelete = () => { return !resource.canBeDeleted() || isProjectSpaceResource(resource) }) }, + isDisabled: ({ resources }) => { + return resources.length === 1 && resources[0].locked + }, + disabledTooltip: () => $gettext("File can't be deleted because it is currently locked."), class: 'oc-files-actions-delete-trigger' }, { diff --git a/packages/web-pkg/tests/unit/composables/actions/files/useFileActionsDelete.spec.ts b/packages/web-pkg/tests/unit/composables/actions/files/useFileActionsDelete.spec.ts index 406291e5a5..ee25063327 100644 --- a/packages/web-pkg/tests/unit/composables/actions/files/useFileActionsDelete.spec.ts +++ b/packages/web-pkg/tests/unit/composables/actions/files/useFileActionsDelete.spec.ts @@ -32,22 +32,36 @@ describe('delete', () => { resources: [{ canBeDeleted: () => false }] as Resource[], invalidLocation: false, expectedStatus: false + } + ])('should be set correctly', ({ resources, expectedStatus, invalidLocation }) => { + getWrapper({ + invalidLocation, + setup: () => { + const { actions } = useFileActionsDelete() + expect(unref(actions)[0].isVisible({ space: null, resources })).toBe(expectedStatus) + } + }) + }) + }) + describe('delete isDisabled property of returned element', () => { + it.each<{ resources: Resource[]; expectedStatus: boolean }>([ + { + resources: [{ locked: true } as Resource], + expectedStatus: true }, { - resources: [{ canBeDeleted: () => true, locked: true }] as Resource[], - invalidLocation: false, + resources: [{ locked: false } as Resource], + expectedStatus: false + }, + { + resources: [{ locked: true }, { locked: false }] as Resource[], expectedStatus: false } - ])('should be set correctly', (inputData) => { + ])('should be set correctly', ({ resources, expectedStatus }) => { getWrapper({ - invalidLocation: inputData.invalidLocation, setup: () => { const { actions } = useFileActionsDelete() - - const resources = inputData.resources - expect(unref(actions)[0].isVisible({ space: null, resources })).toBe( - inputData.expectedStatus - ) + expect(unref(actions)[0].isDisabled({ space: null, resources })).toBe(expectedStatus) } }) }) From e9a87a879e101c875e0f2fe94a1de3998d15aee7 Mon Sep 17 00:00:00 2001 From: Jannik Stehle Date: Tue, 14 Oct 2025 10:15:03 +0200 Subject: [PATCH 2/2] test(e2e): exclude disabled sidebar actions from clickable ones --- tests/e2e/support/objects/app-files/resource/actions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/support/objects/app-files/resource/actions.ts b/tests/e2e/support/objects/app-files/resource/actions.ts index ad9b16d3e7..5de23a1b42 100644 --- a/tests/e2e/support/objects/app-files/resource/actions.ts +++ b/tests/e2e/support/objects/app-files/resource/actions.ts @@ -114,7 +114,7 @@ const sharesNavigationButtonSelector = '.oc-sidebar-nav [data-nav-name="files-sh const keepBothButton = '.oc-modal-body-actions-confirm' const mediaNavigationButton = `//button[contains(@class, "preview-controls-%s")]` const sideBarActions = - '//ul[@id="oc-files-actions-sidebar"]//span[contains(@class,"oc-files-context-action-label")]/span' + '//ul[@id="oc-files-actions-sidebar"]//button[not(@disabled)]//span[contains(@class,"oc-files-context-action-label")]/span' const selectAllCheckbox = '//input[@type="checkbox" and (@id="tiles-view-select-all" or @id="resource-table-select-all")]' const firstResourceCheckbox =