diff --git a/apps/files_sharing/lib/Listener/LoadSidebarListener.php b/apps/files_sharing/lib/Listener/LoadSidebarListener.php index e6a30a5688173..4768f2e0657ca 100644 --- a/apps/files_sharing/lib/Listener/LoadSidebarListener.php +++ b/apps/files_sharing/lib/Listener/LoadSidebarListener.php @@ -38,6 +38,10 @@ public function handle(Event $event): void { return; } Util::addScript(Application::APP_ID, 'files_sharing_tab', 'files'); + // Vue 3 bridge exposing the unified sharing dialog on OCA.Sharing for the + // (Vue 2) sidebar to trigger without bundling Vue 3. + Util::addStyle(Application::APP_ID, 'sharing-dialog'); + Util::addScript(Application::APP_ID, 'sharing-dialog', 'files'); $appConfig = Server::get(IAppConfig::class); $gsConfig = Server::get(IConfig::class); diff --git a/apps/files_sharing/src/components/SharingEntry.vue b/apps/files_sharing/src/components/SharingEntry.vue index 28ad1d4d89f33..4b0d66732a37f 100644 --- a/apps/files_sharing/src/components/SharingEntry.vue +++ b/apps/files_sharing/src/components/SharingEntry.vue @@ -28,13 +28,14 @@ + + diff --git a/apps/files_sharing/src/components/SharingEntryLink.vue b/apps/files_sharing/src/components/SharingEntryLink.vue index e67b3447335e1..e2bb0e4e48f72 100644 --- a/apps/files_sharing/src/components/SharingEntryLink.vue +++ b/apps/files_sharing/src/components/SharingEntryLink.vue @@ -21,7 +21,7 @@ {{ subtitle }}

@@ -151,6 +151,7 @@ + openShareEditDialog(shareId: string | number, node?: Node): Promise +} + +/** + * Get the sharing dialog API registered by the Vue 3 bridge, if loaded. + */ +function sharingDialogApi(): SharingDialogApi | undefined { + return (window.OCA?.Sharing as Partial | undefined) as SharingDialogApi | undefined +} + +/** + * Whether the server provides the unified sharing API this dialog talks to. + * Mirrors the library check so the sidebar can gate on it without importing + * the Vue 3 code. + */ +export function isSharingDialogAvailable(): boolean { + const capabilities = getCapabilities() as { sharing?: { api_versions?: unknown[] } } + return (capabilities.sharing?.api_versions?.length ?? 0) > 0 +} + +/** + * Open the unified sharing dialog to create a new share for a node. + * + * @param node The file or folder to share + */ +export function openShareCreateDialog(node: Node): Promise { + const api = sharingDialogApi() + if (!api?.openSharingDialog) { + return Promise.reject(new Error('The unified sharing dialog is not available')) + } + return api.openSharingDialog(node) +} + +/** + * Open the unified sharing dialog to edit an existing share. + * + * @param shareId The share id (mapped to the unified API by the legacy bridge) + * @param node The backing node, used for the dialog title + */ +export function openShareEditDialog(shareId: string | number, node?: Node): Promise { + const api = sharingDialogApi() + if (!api?.openShareEditDialog) { + return Promise.reject(new Error('The unified sharing dialog is not available')) + } + return api.openShareEditDialog(shareId, node) +} diff --git a/apps/files_sharing/src/sharing-dialog-bridge.ts b/apps/files_sharing/src/sharing-dialog-bridge.ts new file mode 100644 index 0000000000000..2cd81c671b9d9 --- /dev/null +++ b/apps/files_sharing/src/sharing-dialog-bridge.ts @@ -0,0 +1,39 @@ +/** + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import type { Node } from '@nextcloud/files' + +import { getShare, isSharingDialogAvailable, openSharingDialog } from '@nextcloud/sharing/dialog' + +/** + * Bridge the Vue 3 unified sharing dialog into the global `OCA.Sharing` + * namespace so the (still Vue 2) files_sharing sidebar can trigger it without + * importing Vue 3 code into its bundle. The dialog spawns its own Vue 3 app, + * so it must be registered from this Vue 3 entry point where `vue` and + * `@nextcloud/vue` resolve to their Vue 3 versions. + * + * Once files_sharing is migrated to Vue 3 this bridge can be dropped and the + * library imported directly. + */ + +window.OCA ??= {} +window.OCA.Sharing ??= {} + +Object.assign(window.OCA.Sharing, { + openSharingDialog, + + /** + * Open the unified sharing dialog to edit an existing share. + * + * @param shareId The share id (mapped to the unified API by the legacy bridge) + * @param node The backing node, used for the dialog title + */ + async openShareEditDialog(shareId: string | number, node?: Node): Promise { + const share = await getShare(String(shareId)) + return share.showDialog(node) + }, + + isSharingDialogAvailable, +}) diff --git a/apps/files_sharing/src/views/SharingTab.vue b/apps/files_sharing/src/views/SharingTab.vue index 0463a9969d28f..230454e761cef 100644 --- a/apps/files_sharing/src/views/SharingTab.vue +++ b/apps/files_sharing/src/views/SharingTab.vue @@ -27,6 +27,19 @@ + + +

{{ t('files_sharing', 'Internal shares') }}

@@ -48,7 +61,7 @@
=0.10.0" @@ -8945,7 +8934,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -9005,7 +8994,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -10508,7 +10497,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -10522,7 +10511,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -10815,7 +10804,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, "license": "MIT", "optional": true }, @@ -11824,6 +11812,15 @@ "dev": true, "license": "MIT" }, + "node_modules/qrcode.vue": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-3.10.0.tgz", + "integrity": "sha512-1bjeBds9hRKMszZuBuYQZor9HdJYWtb0S44HG1JofZ9uicpJpdF+TtDvqo3+2ZlH0k80WVIkmiKB4hq0/N6/rA==", + "license": "MIT", + "peerDependencies": { + "vue": "^3.0.0" + } + }, "node_modules/qs": { "version": "6.15.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", @@ -12461,7 +12458,7 @@ "version": "1.102.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.102.0.tgz", "integrity": "sha512-NSOyTnaQF7rTAEOtI2fwb386vL+akyiQLBZu8Na7hXCb+umJy0GAqlcMIaqACZ6Z1VgTBS4K9PG6B3IdjHGJsw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "chokidar": "^5.0.0", @@ -13914,7 +13911,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -14142,7 +14139,7 @@ "version": "8.3.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/unicorn-magic": { @@ -14641,7 +14638,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14658,7 +14654,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14675,7 +14670,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14692,7 +14686,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14709,7 +14702,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14726,7 +14718,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14743,7 +14734,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14760,7 +14750,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14777,7 +14766,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14794,7 +14782,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14811,7 +14798,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14828,7 +14814,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14845,7 +14830,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14862,7 +14846,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14879,7 +14862,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14896,7 +14878,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14913,7 +14894,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14930,7 +14910,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14947,7 +14926,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14964,7 +14942,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14981,7 +14958,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -14998,7 +14974,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -15015,7 +14990,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -15032,7 +15006,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -15049,7 +15022,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -15066,7 +15038,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ diff --git a/package.json b/package.json index 7db9296f7e47b..8c80c3b77408c 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@nextcloud/password-confirmation": "^6.1.0", "@nextcloud/paths": "^3.1.0", "@nextcloud/router": "^3.1.0", - "@nextcloud/sharing": "^0.4.0", + "@nextcloud/sharing": "^1.0.0-beta.1", "@nextcloud/vue": "^9.3.1", "@vueuse/core": "^14.1.0", "@vueuse/integrations": "^14.1.0",