diff options
Diffstat (limited to 'apps/files_sharing/src')
10 files changed, 79 insertions, 53 deletions
diff --git a/apps/files_sharing/src/components/NewFileRequestDialog/NewFileRequestDialogFinish.vue b/apps/files_sharing/src/components/NewFileRequestDialog/NewFileRequestDialogFinish.vue index 499fd773edc..7826aab581e 100644 --- a/apps/files_sharing/src/components/NewFileRequestDialog/NewFileRequestDialogFinish.vue +++ b/apps/files_sharing/src/components/NewFileRequestDialog/NewFileRequestDialogFinish.vue @@ -16,7 +16,7 @@ :label="t('files_sharing', 'Share link')" :readonly="true" :show-trailing-button="true" - :trailing-button-label="t('files_sharing', 'Copy to clipboard')" + :trailing-button-label="t('files_sharing', 'Copy')" data-cy-file-request-dialog-fieldset="link" @click="copyShareLink" @trailing-button-click="copyShareLink"> @@ -140,7 +140,7 @@ export default defineComponent({ await navigator.clipboard.writeText(this.shareLink) - showSuccess(t('files_sharing', 'Link copied to clipboard')) + showSuccess(t('files_sharing', 'Link copied')) this.isCopied = true event.target?.select?.() diff --git a/apps/files_sharing/src/components/SharingEntry.vue b/apps/files_sharing/src/components/SharingEntry.vue index 1fbe740cb11..342b40ce384 100644 --- a/apps/files_sharing/src/components/SharingEntry.vue +++ b/apps/files_sharing/src/components/SharingEntry.vue @@ -19,8 +19,9 @@ :href="share.shareWithLink" class="sharing-entry__summary__desc"> <span>{{ title }} - <span v-if="!isUnique" class="sharing-entry__summary__desc-unique"> ({{ - share.shareWithDisplayNameUnique }})</span> + <span v-if="!isUnique" class="sharing-entry__summary__desc-unique"> + ({{ share.shareWithDisplayNameUnique }}) + </span> <small v-if="hasStatus && share.status.message">({{ share.status.message }})</small> </span> </component> @@ -73,13 +74,17 @@ export default { computed: { title() { let title = this.share.shareWithDisplayName - if (this.share.type === ShareType.Group) { + + const showAsInternal = this.config.showFederatedSharesAsInternal + || (this.share.isTrustedServer && this.config.showFederatedSharesToTrustedServersAsInternal) + + if (this.share.type === ShareType.Group || (this.share.type === ShareType.RemoteGroup && showAsInternal)) { title += ` (${t('files_sharing', 'group')})` } else if (this.share.type === ShareType.Room) { title += ` (${t('files_sharing', 'conversation')})` - } else if (this.share.type === ShareType.Remote && !this.share.isTrustedServer) { + } else if (this.share.type === ShareType.Remote && !showAsInternal) { title += ` (${t('files_sharing', 'remote')})` - } else if (this.share.type === ShareType.RemoteGroup && !this.share.isTrustedServer) { + } else if (this.share.type === ShareType.RemoteGroup) { title += ` (${t('files_sharing', 'remote group')})` } else if (this.share.type === ShareType.Guest) { title += ` (${t('files_sharing', 'guest')})` diff --git a/apps/files_sharing/src/components/SharingEntryInternal.vue b/apps/files_sharing/src/components/SharingEntryInternal.vue index 2ad1256fa82..027d2a3d5c3 100644 --- a/apps/files_sharing/src/components/SharingEntryInternal.vue +++ b/apps/files_sharing/src/components/SharingEntryInternal.vue @@ -83,14 +83,11 @@ export default { } return t('files_sharing', 'Cannot copy, please copy the link manually') } - return t('files_sharing', 'Copy internal link to clipboard') + return t('files_sharing', 'Copy internal link') }, internalLinkSubtitle() { - if (this.fileInfo.type === 'dir') { - return t('files_sharing', 'Only works for people with access to this folder') - } - return t('files_sharing', 'Only works for people with access to this file') + return t('files_sharing', 'For people who already have access') }, }, diff --git a/apps/files_sharing/src/components/SharingEntryLink.vue b/apps/files_sharing/src/components/SharingEntryLink.vue index 6a456fa0a15..6865af1b864 100644 --- a/apps/files_sharing/src/components/SharingEntryLink.vue +++ b/apps/files_sharing/src/components/SharingEntryLink.vue @@ -550,7 +550,7 @@ export default { } return t('files_sharing', 'Cannot copy, please copy the link manually') } - return t('files_sharing', 'Copy public link of "{title}" to clipboard', { title: this.title }) + return t('files_sharing', 'Copy public link of "{title}"', { title: this.title }) }, /** diff --git a/apps/files_sharing/src/components/SharingInput.vue b/apps/files_sharing/src/components/SharingInput.vue index f50dc96fc08..6fb33aba6b2 100644 --- a/apps/files_sharing/src/components/SharingInput.vue +++ b/apps/files_sharing/src/components/SharingInput.vue @@ -195,17 +195,15 @@ export default { const remoteTypes = [ShareType.Remote, ShareType.RemoteGroup] const shareType = [] - const showFederatedAsInternal - = this.config.showFederatedSharesAsInternal - || this.config.showFederatedSharesToTrustedServersAsInternal - - const shouldAddRemoteTypes - // For internal users, add remote types if config says to show them as internal - = (!this.isExternal && showFederatedAsInternal) - // For external users, add them if config *doesn't* say to show them as internal - || (this.isExternal && !showFederatedAsInternal) - // Edge case: federated-to-trusted is a separate "add" trigger for external users - || (this.isExternal && this.config.showFederatedSharesToTrustedServersAsInternal) + const showFederatedAsInternal = this.config.showFederatedSharesAsInternal + || this.config.showFederatedSharesToTrustedServersAsInternal + + // For internal users, add remote types if config says to show them as internal + const shouldAddRemoteTypes = (!this.isExternal && showFederatedAsInternal) + // For external users, add them if config *doesn't* say to show them as internal + || (this.isExternal && !showFederatedAsInternal) + // Edge case: federated-to-trusted is a separate "add" trigger for external users + || (this.isExternal && this.config.showFederatedSharesToTrustedServersAsInternal) if (this.isExternal) { if (getCapabilities().files_sharing.public.enabled === true) { @@ -244,13 +242,10 @@ export default { return } - const data = request.data.ocs.data - const exact = request.data.ocs.data.exact - data.exact = [] // removing exact from general results - + const { exact, ...data } = request.data.ocs.data // flatten array of arrays - const rawExactSuggestions = Object.values(exact).reduce((arr, elem) => arr.concat(elem), []) - const rawSuggestions = Object.values(data).reduce((arr, elem) => arr.concat(elem), []) + const rawExactSuggestions = Object.values(exact).flat() + const rawSuggestions = Object.values(data).flat() // remove invalid data and format to user-select layout const exactSuggestions = this.filterOutExistingShares(rawExactSuggestions) @@ -269,7 +264,7 @@ export default { lookupEntry.push({ id: 'global-lookup', isNoUser: true, - displayName: t('files_sharing', 'Search globally'), + displayName: t('files_sharing', 'Search everywhere'), lookup: true, }) } @@ -470,14 +465,19 @@ export default { */ formatForMultiselect(result) { let subname + let displayName = result.name || result.label + if (result.value.shareType === ShareType.User && this.config.shouldAlwaysShowUnique) { subname = result.shareWithDisplayNameUnique ?? '' - } else if ((result.value.shareType === ShareType.Remote - || result.value.shareType === ShareType.RemoteGroup - ) && result.value.server) { - subname = t('files_sharing', 'on {server}', { server: result.value.server }) } else if (result.value.shareType === ShareType.Email) { subname = result.value.shareWith + } else if (result.value.shareType === ShareType.Remote || result.value.shareType === ShareType.RemoteGroup) { + if (this.config.showFederatedSharesAsInternal) { + subname = result.extra?.email?.value ?? '' + displayName = result.extra?.name?.value ?? displayName + } else if (result.value.server) { + subname = t('files_sharing', 'on {server}', { server: result.value.server }) + } } else { subname = result.shareWithDescription ?? '' } @@ -487,7 +487,7 @@ export default { shareType: result.value.shareType, user: result.uuid || result.value.shareWith, isNoUser: result.value.shareType !== ShareType.User, - displayName: result.name || result.label, + displayName, subname, shareWithDisplayNameUnique: result.shareWithDisplayNameUnique || '', ...this.shareTypeToIcon(result.value.shareType), diff --git a/apps/files_sharing/src/files_actions/sharingStatusAction.ts b/apps/files_sharing/src/files_actions/sharingStatusAction.ts index 2dfd8467c5b..18fa46d2781 100644 --- a/apps/files_sharing/src/files_actions/sharingStatusAction.ts +++ b/apps/files_sharing/src/files_actions/sharingStatusAction.ts @@ -53,7 +53,7 @@ export const action = new FileAction({ const sharees = node.attributes.sharees?.sharee as { id: string, 'display-name': string, type: ShareType }[] | undefined if (!sharees) { // No sharees so just show the default message to create a new share - return t('files_sharing', 'Show sharing options') + return t('files_sharing', 'Sharing options') } const sharee = [sharees].flat()[0] // the property is sometimes weirdly normalized, so we need to compensate diff --git a/apps/files_sharing/src/services/ConfigService.ts b/apps/files_sharing/src/services/ConfigService.ts index f75f34c7936..547038f362d 100644 --- a/apps/files_sharing/src/services/ConfigService.ts +++ b/apps/files_sharing/src/services/ConfigService.ts @@ -213,6 +213,13 @@ export default class Config { } /** + * Is federation enabled ? + */ + get isFederationEnabled(): boolean { + return this._capabilities?.files_sharing?.federation?.outgoing === true + } + + /** * Is public sharing enabled ? */ get isPublicShareAllowed(): boolean { diff --git a/apps/files_sharing/src/services/TabSections.js b/apps/files_sharing/src/services/TabSections.js index 8578f8f08d5..ab1237e7044 100644 --- a/apps/files_sharing/src/services/TabSections.js +++ b/apps/files_sharing/src/services/TabSections.js @@ -3,6 +3,14 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ +/** + * Callback to render a section in the sharing tab. + * + * @callback registerSectionCallback + * @param {undefined} el - Deprecated and will always be undefined (formerly the root element) + * @param {object} fileInfo - File info object + */ + export default class TabSections { _sections diff --git a/apps/files_sharing/src/views/SharingDetailsTab.vue b/apps/files_sharing/src/views/SharingDetailsTab.vue index ee902a24c8a..b3a3b95d92e 100644 --- a/apps/files_sharing/src/views/SharingDetailsTab.vue +++ b/apps/files_sharing/src/views/SharingDetailsTab.vue @@ -373,7 +373,7 @@ export default { title() { switch (this.share.type) { case ShareType.User: - return t('files_sharing', 'Share with {userName}', { userName: this.share.shareWithDisplayName }) + return t('files_sharing', 'Share with {user}', { user: this.share.shareWithDisplayName }) case ShareType.Email: return t('files_sharing', 'Share with email {email}', { email: this.share.shareWith }) case ShareType.Link: @@ -384,6 +384,9 @@ export default { return t('files_sharing', 'Share in conversation') case ShareType.Remote: { const [user, server] = this.share.shareWith.split('@') + if (this.config.showFederatedSharesAsInternal) { + return t('files_sharing', 'Share with {user}', { user }) + } return t('files_sharing', 'Share with {user} on remote server {server}', { user, server }) } case ShareType.RemoteGroup: diff --git a/apps/files_sharing/src/views/SharingTab.vue b/apps/files_sharing/src/views/SharingTab.vue index dc200c61df4..2ed44a4b5ad 100644 --- a/apps/files_sharing/src/views/SharingTab.vue +++ b/apps/files_sharing/src/views/SharingTab.vue @@ -127,11 +127,10 @@ </NcPopover> </div> <!-- additional entries, use it with cautious --> - <div v-for="(section, index) in sections" - :ref="'section-' + index" + <div v-for="(component, index) in sectionComponents" :key="index" class="sharingTab__additionalContent"> - <component :is="section($refs['section-'+index], fileInfo)" :file-info="fileInfo" /> + <component :is="component" :file-info="fileInfo" /> </div> <!-- projects (deprecated as of NC25 (replaced by related_resources) - see instance config "projects.enabled" ; ignore this / remove it / move into own section) --> @@ -230,9 +229,9 @@ export default { shareDetailsData: {}, returnFocusElement: null, - internalSharesHelpText: t('files_sharing', 'Use this method to share files with individuals or teams within your organization. If the recipient already has access to the share but cannot locate it, you can send them the internal share link for easy access.'), - externalSharesHelpText: t('files_sharing', 'Use this method to share files with individuals or organizations outside your organization. Files and folders can be shared via public share links and email addresses. You can also share to other Nextcloud accounts hosted on different instances using their federated cloud ID.'), - additionalSharesHelpText: t('files_sharing', 'Shares that are not part of the internal or external shares. This can be shares from apps or other sources.'), + internalSharesHelpText: t('files_sharing', 'Share files within your organization. Recipients who can already view the file can also use this link for easy access.'), + externalSharesHelpText: t('files_sharing', 'Share files with others outside your organization via public links and email addresses. You can also share to Nextcloud accounts on other instances using their federated cloud ID.'), + additionalSharesHelpText: t('files_sharing', 'Shares from apps or other sources which are not included in internal or external shares.'), } }, @@ -268,21 +267,29 @@ export default { }, internalShareInputPlaceholder() { - return this.config.showFederatedSharesAsInternal - ? t('files_sharing', 'Share with accounts, teams, federated cloud IDs') - : t('files_sharing', 'Share with accounts and teams') + return this.config.showFederatedSharesAsInternal && this.config.isFederationEnabled + // TRANSLATORS: Type as in with a keyboard + ? t('files_sharing', 'Type names, teams, federated cloud IDs') + // TRANSLATORS: Type as in with a keyboard + : t('files_sharing', 'Type names or teams') }, externalShareInputPlaceholder() { if (!this.isLinkSharingAllowed) { - return t('files_sharing', 'Federated cloud ID') + // TRANSLATORS: Type as in with a keyboard + return this.config.isFederationEnabled ? t('files_sharing', 'Type a federated cloud ID') : '' } - return this.config.showFederatedSharesAsInternal - ? t('files_sharing', 'Email') - : t('files_sharing', 'Email, federated cloud ID') + return !this.config.showFederatedSharesAsInternal && !this.config.isFederationEnabled + // TRANSLATORS: Type as in with a keyboard + ? t('files_sharing', 'Type an email') + // TRANSLATORS: Type as in with a keyboard + : t('files_sharing', 'Type an email or federated cloud ID') }, - }, + sectionComponents() { + return this.sections.map((section) => section(undefined, this.fileInfo)) + }, + }, methods: { /** * Update current fileInfo and fetch new data @@ -294,7 +301,6 @@ export default { this.resetState() this.getShares() }, - /** * Get the existing shares infos */ |