Skip to content

Commit 9a6f840

Browse files
committed
feat(files_sharing): use the unified sharing dialog in the sidebar
Gated by the sharing_dialog_enabled killswitch (default on): - SharingTab: hide both legacy SharingInputs, add a single Share button that opens the new dialog to create a share. - SharingEntry (internal): replace the details 3-dots button with an Edit + Delete dual button and hide the quick-share permission select. - SharingEntryLink: hide the quick-share select and route Customize link to the new dialog. Edit opens the share in the new dialog by id (resolved via the upcoming legacy->unified bridge). The legacy UI stays intact behind the killswitch. Assisted-by: ClaudeCode:claude-opus-4-8 Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
1 parent 5bbb850 commit 9a6f840

4 files changed

Lines changed: 123 additions & 4 deletions

File tree

apps/files_sharing/src/components/SharingEntry.vue

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,14 @@
2828
</span>
2929
</component>
3030
<SharingEntryQuickShareSelect
31+
v-if="!config.sharingDialogEnabled"
3132
:share="share"
3233
:file-info="fileInfo"
3334
@open-sharing-details="openShareDetailsForCustomSettings(share)" />
3435
</div>
3536
<ShareExpiryTime v-if="share && share.expireDate" :share="share" />
3637
<NcButton
37-
v-if="share.canEdit"
38+
v-if="share.canEdit && !config.sharingDialogEnabled"
3839
class="sharing-entry__action"
3940
data-cy-files-sharing-share-actions
4041
:aria-label="t('files_sharing', 'Open Sharing Details')"
@@ -44,6 +45,29 @@
4445
<DotsHorizontalIcon :size="20" />
4546
</template>
4647
</NcButton>
48+
<!-- Unified dialog: edit + delete as a simple dual button -->
49+
<template v-else-if="config.sharingDialogEnabled">
50+
<NcButton
51+
v-if="share.canEdit"
52+
class="sharing-entry__action"
53+
:aria-label="t('files_sharing', 'Edit share')"
54+
variant="tertiary"
55+
@click="openEditDialog">
56+
<template #icon>
57+
<PencilIcon :size="20" />
58+
</template>
59+
</NcButton>
60+
<NcButton
61+
v-if="share.canDelete"
62+
class="sharing-entry__action"
63+
:aria-label="t('files_sharing', 'Delete share')"
64+
variant="tertiary"
65+
@click="onDelete">
66+
<template #icon>
67+
<DeleteIcon :size="20" />
68+
</template>
69+
</NcButton>
70+
</template>
4771
</li>
4872
</template>
4973

@@ -52,19 +76,25 @@ import { ShareType } from '@nextcloud/sharing'
5276
import NcAvatar from '@nextcloud/vue/components/NcAvatar'
5377
import NcButton from '@nextcloud/vue/components/NcButton'
5478
import NcSelect from '@nextcloud/vue/components/NcSelect'
79+
import DeleteIcon from 'vue-material-design-icons/Delete.vue'
5580
import DotsHorizontalIcon from 'vue-material-design-icons/DotsHorizontal.vue'
81+
import PencilIcon from 'vue-material-design-icons/Pencil.vue'
5682
import ShareExpiryTime from './ShareExpiryTime.vue'
5783
import SharingEntryQuickShareSelect from './SharingEntryQuickShareSelect.vue'
5884
import ShareDetails from '../mixins/ShareDetails.js'
5985
import SharesMixin from '../mixins/SharesMixin.js'
86+
import { openShareEditDialog } from '../services/SharingDialog.ts'
87+
import logger from '../services/logger.ts'
6088
6189
export default {
6290
name: 'SharingEntry',
6391
6492
components: {
6593
NcButton,
6694
NcAvatar,
95+
DeleteIcon,
6796
DotsHorizontalIcon,
97+
PencilIcon,
6898
NcSelect,
6999
ShareExpiryTime,
70100
SharingEntryQuickShareSelect,
@@ -130,6 +160,17 @@ export default {
130160
},
131161
132162
methods: {
163+
/**
164+
* Open the unified sharing dialog to edit this share.
165+
*/
166+
async openEditDialog() {
167+
try {
168+
await openShareEditDialog(this.share.id, this.fileInfo.node)
169+
} catch (error) {
170+
logger.error('Failed to open the sharing dialog', { error })
171+
}
172+
},
173+
133174
/**
134175
* Save potential changed data on menu close
135176
*/

apps/files_sharing/src/components/SharingEntryLink.vue

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
{{ subtitle }}
2222
</p>
2323
<SharingEntryQuickShareSelect
24-
v-if="share && share.permissions !== undefined"
24+
v-if="share && share.permissions !== undefined && !config.sharingDialogEnabled"
2525
:share="share"
2626
:file-info="fileInfo"
2727
@open-sharing-details="openShareDetailsForCustomSettings(share)" />
@@ -152,6 +152,7 @@
152152
<template v-if="share">
153153
<template v-if="share.canEdit && canReshare">
154154
<NcActionButton
155+
v-if="!config.sharingDialogEnabled"
155156
:disabled="saving"
156157
:close-after-click="true"
157158
@click.prevent="openSharingDetails">
@@ -160,6 +161,16 @@
160161
</template>
161162
{{ t('files_sharing', 'Customize link') }}
162163
</NcActionButton>
164+
<NcActionButton
165+
v-else
166+
:disabled="saving"
167+
:close-after-click="true"
168+
@click.prevent="openEditDialog">
169+
<template #icon>
170+
<Tune :size="20" />
171+
</template>
172+
{{ t('files_sharing', 'Customize link') }}
173+
</NcActionButton>
163174
</template>
164175

165176
<NcActionButton
@@ -279,6 +290,7 @@ import SidebarTabExternalActionLegacy from './SidebarTabExternal/SidebarTabExter
279290
import ShareDetails from '../mixins/ShareDetails.js'
280291
import SharesMixin from '../mixins/SharesMixin.js'
281292
import Share from '../models/Share.ts'
293+
import { openShareEditDialog } from '../services/SharingDialog.ts'
282294
import logger from '../services/logger.ts'
283295
import GeneratePassword from '../utils/GeneratePassword.ts'
284296
@@ -628,6 +640,17 @@ export default {
628640
},
629641
630642
methods: {
643+
/**
644+
* Open the unified sharing dialog to edit this link share.
645+
*/
646+
async openEditDialog() {
647+
try {
648+
await openShareEditDialog(this.share.id, this.fileInfo.node)
649+
} catch (error) {
650+
logger.error('Failed to open the sharing dialog', { error })
651+
}
652+
},
653+
631654
/**
632655
* Check if the share requires review
633656
*
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import type { Node } from '@nextcloud/files'
7+
8+
import { getShare, openSharingDialog } from '@nextcloud/sharing/dialog'
9+
10+
/**
11+
* Open the unified sharing dialog to create a new share for a node.
12+
*
13+
* @param node The file or folder to share
14+
*/
15+
export async function openShareCreateDialog(node: Node): Promise<unknown> {
16+
return openSharingDialog(node)
17+
}
18+
19+
/**
20+
* Open the unified sharing dialog to edit an existing share.
21+
*
22+
* @param shareId The share id (mapped to the unified API by the legacy bridge)
23+
* @param node The backing node, used for the dialog title
24+
*/
25+
export async function openShareEditDialog(shareId: string | number, node?: Node): Promise<unknown> {
26+
const share = await getShare(String(shareId))
27+
return share.showDialog(node)
28+
}

apps/files_sharing/src/views/SharingTab.vue

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@
2727
</SharingEntrySimple>
2828
</ul>
2929

30+
<!-- Unified sharing dialog entry point (replaces the inline inputs) -->
31+
<NcButton
32+
v-if="config.sharingDialogEnabled"
33+
class="sharingTab__share-button"
34+
variant="primary"
35+
wide
36+
@click="openShareDialog">
37+
<template #icon>
38+
<ShareVariantIcon :size="20" />
39+
</template>
40+
{{ t('files_sharing', 'Share') }}
41+
</NcButton>
42+
3043
<section>
3144
<div class="section-header">
3245
<h4>{{ t('files_sharing', 'Internal shares') }}</h4>
@@ -48,7 +61,7 @@
4861
</div>
4962
<!-- add new share input -->
5063
<SharingInput
51-
v-if="!loading"
64+
v-if="!loading && !config.sharingDialogEnabled"
5265
:can-reshare="canReshare"
5366
:file-info="fileInfo"
5467
:link-shares="linkShares"
@@ -92,7 +105,7 @@
92105
</NcPopover>
93106
</div>
94107
<SharingInput
95-
v-if="!loading"
108+
v-if="!loading && !config.sharingDialogEnabled"
96109
:can-reshare="canReshare"
97110
:file-info="fileInfo"
98111
:link-shares="linkShares"
@@ -191,6 +204,7 @@ import NcButton from '@nextcloud/vue/components/NcButton'
191204
import NcCollectionList from '@nextcloud/vue/components/NcCollectionList'
192205
import NcPopover from '@nextcloud/vue/components/NcPopover'
193206
import InfoIcon from 'vue-material-design-icons/InformationOutline.vue'
207+
import ShareVariantIcon from 'vue-material-design-icons/ShareVariant.vue'
194208
import SharingEntryInternal from '../components/SharingEntryInternal.vue'
195209
import SharingEntrySimple from '../components/SharingEntrySimple.vue'
196210
import SharingInput from '../components/SharingInput.vue'
@@ -203,6 +217,7 @@ import SharingList from './SharingList.vue'
203217
import ShareDetails from '../mixins/ShareDetails.js'
204218
import Share from '../models/Share.ts'
205219
import Config from '../services/ConfigService.ts'
220+
import { openShareCreateDialog } from '../services/SharingDialog.ts'
206221
import logger from '../services/logger.ts'
207222
import { shareWithTitle } from '../utils/SharedWithMe.js'
208223
@@ -217,6 +232,7 @@ export default {
217232
NcButton,
218233
NcCollectionList,
219234
NcPopover,
235+
ShareVariantIcon,
220236
SharingEntryInternal,
221237
SharingEntrySimple,
222238
SharingInherited,
@@ -346,6 +362,17 @@ export default {
346362
},
347363
348364
methods: {
365+
/**
366+
* Open the unified sharing dialog to create a share for the current node.
367+
*/
368+
async openShareDialog() {
369+
try {
370+
await openShareCreateDialog(this.fileInfo.node)
371+
} catch (error) {
372+
logger.error('Failed to open the sharing dialog', { error })
373+
}
374+
},
375+
349376
/**
350377
* Get the existing shares infos
351378
*/

0 commit comments

Comments
 (0)