aboutsummaryrefslogtreecommitdiffstats
path: root/apps/federatedfilesharing/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'apps/federatedfilesharing/src/components')
-rw-r--r--apps/federatedfilesharing/src/components/AdminSettings.vue153
-rw-r--r--apps/federatedfilesharing/src/components/PersonalSettings.vue182
-rw-r--r--apps/federatedfilesharing/src/components/RemoteShareDialog.cy.ts123
-rw-r--r--apps/federatedfilesharing/src/components/RemoteShareDialog.vue67
4 files changed, 408 insertions, 117 deletions
diff --git a/apps/federatedfilesharing/src/components/AdminSettings.vue b/apps/federatedfilesharing/src/components/AdminSettings.vue
index f9de2e0858c..84bf6b565a3 100644
--- a/apps/federatedfilesharing/src/components/AdminSettings.vue
+++ b/apps/federatedfilesharing/src/components/AdminSettings.vue
@@ -1,25 +1,7 @@
<!--
- - @copyright 2022 Carl Schwan <carl@carlschwan.eu>
- -
- - @author Carl Schwan <carl@carlschwan.eu>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - This program is distributed in the hope that it will be useful,
- - but WITHOUT ANY WARRANTY; without even the implied warranty of
- - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- - GNU Affero General Public License for more details.
- -
- - You should have received a copy of the GNU Affero General Public License
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
- -
+ - SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
-->
-
<template>
<NcSettingsSection :name="t('federatedfilesharing', 'Federated Cloud Sharing')"
:description="t('federatedfilesharing', 'Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing.')"
@@ -50,28 +32,47 @@
{{ t('federatedfilesharing', 'Allow people on this server to receive group shares from other servers') }}
</NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch type="switch"
- :checked.sync="lookupServerEnabled"
- @update:checked="update('lookupServerEnabled', lookupServerEnabled)">
- {{ t('federatedfilesharing', 'Search global and public address book for people') }}
- </NcCheckboxRadioSwitch>
+ <fieldset>
+ <legend>{{ t('federatedfilesharing', 'The lookup server is only available for global scale.') }}</legend>
- <NcCheckboxRadioSwitch type="switch"
- :checked.sync="lookupServerUploadEnabled"
- @update:checked="update('lookupServerUploadEnabled', lookupServerUploadEnabled)">
- {{ t('federatedfilesharing', 'Allow people to publish their data to a global and public address book') }}
- </NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch type="switch"
+ :checked="lookupServerEnabled"
+ disabled
+ @update:checked="showLookupServerConfirmation">
+ {{ t('federatedfilesharing', 'Search global and public address book for people') }}
+ </NcCheckboxRadioSwitch>
+
+ <NcCheckboxRadioSwitch type="switch"
+ :checked="lookupServerUploadEnabled"
+ disabled
+ @update:checked="showLookupServerUploadConfirmation">
+ {{ t('federatedfilesharing', 'Allow people to publish their data to a global and public address book') }}
+ </NcCheckboxRadioSwitch>
+ </fieldset>
+
+ <!-- Trusted server handling -->
+ <div class="settings-subsection">
+ <h3 class="settings-subsection__name">
+ {{ t('federatedfilesharing', 'Trusted federation') }}
+ </h3>
+ <NcCheckboxRadioSwitch type="switch"
+ :checked.sync="federatedTrustedShareAutoAccept"
+ @update:checked="update('federatedTrustedShareAutoAccept', federatedTrustedShareAutoAccept)">
+ {{ t('federatedfilesharing', 'Automatically accept shares from trusted federated accounts and groups by default') }}
+ </NcCheckboxRadioSwitch>
+ </div>
</NcSettingsSection>
</template>
<script>
-import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
-import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
import { loadState } from '@nextcloud/initial-state'
-import { showError } from '@nextcloud/dialogs'
-import axios from '@nextcloud/axios'
+import { DialogBuilder, DialogSeverity, showError } from '@nextcloud/dialogs'
import { generateOcsUrl } from '@nextcloud/router'
import { confirmPassword } from '@nextcloud/password-confirmation'
+import axios from '@nextcloud/axios'
+import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
+import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'
+
import '@nextcloud/password-confirmation/dist/style.css'
export default {
@@ -91,11 +92,80 @@ export default {
federatedGroupSharingSupported: loadState('federatedfilesharing', 'federatedGroupSharingSupported'),
lookupServerEnabled: loadState('federatedfilesharing', 'lookupServerEnabled'),
lookupServerUploadEnabled: loadState('federatedfilesharing', 'lookupServerUploadEnabled'),
+ federatedTrustedShareAutoAccept: loadState('federatedfilesharing', 'federatedTrustedShareAutoAccept'),
internalOnly: loadState('federatedfilesharing', 'internalOnly'),
sharingFederatedDocUrl: loadState('federatedfilesharing', 'sharingFederatedDocUrl'),
}
},
methods: {
+ setLookupServerUploadEnabled(state) {
+ if (state === this.lookupServerUploadEnabled) {
+ return
+ }
+ this.lookupServerUploadEnabled = state
+ this.update('lookupServerUploadEnabled', state)
+ },
+
+ async showLookupServerUploadConfirmation(state) {
+ // No confirmation needed for disabling
+ if (state === false) {
+ return this.setLookupServerUploadEnabled(false)
+ }
+
+ const dialog = new DialogBuilder(t('federatedfilesharing', 'Confirm data upload to lookup server'))
+ await dialog
+ .setSeverity(DialogSeverity.Warning)
+ .setText(
+ t('federatedfilesharing', 'When enabled, all account properties (e.g. email address) with scope visibility set to "published", will be automatically synced and transmitted to an external system and made available in a public, global address book.'),
+ )
+ .addButton({
+ callback: () => this.setLookupServerUploadEnabled(false),
+ label: t('federatedfilesharing', 'Disable upload'),
+ })
+ .addButton({
+ callback: () => this.setLookupServerUploadEnabled(true),
+ label: t('federatedfilesharing', 'Enable data upload'),
+ type: 'error',
+ })
+ .build()
+ .show()
+ },
+
+ setLookupServerEnabled(state) {
+ if (state === this.lookupServerEnabled) {
+ return
+ }
+ this.lookupServerEnabled = state
+ this.update('lookupServerEnabled', state)
+ },
+
+ async showLookupServerConfirmation(state) {
+ // No confirmation needed for disabling
+ if (state === false) {
+ return this.setLookupServerEnabled(false)
+ }
+
+ const dialog = new DialogBuilder(t('federatedfilesharing', 'Confirm querying lookup server'))
+ await dialog
+ .setSeverity(DialogSeverity.Warning)
+ .setText(
+ t('federatedfilesharing', 'When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book.')
+ + t('federatedfilesharing', 'This is used to retrieve the federated cloud ID to make federated sharing easier.')
+ + t('federatedfilesharing', 'Moreover, email addresses of users might be sent to that system in order to verify them.'),
+ )
+ .addButton({
+ callback: () => this.setLookupServerEnabled(false),
+ label: t('federatedfilesharing', 'Disable querying'),
+ })
+ .addButton({
+ callback: () => this.setLookupServerEnabled(true),
+ label: t('federatedfilesharing', 'Enable querying'),
+ type: 'error',
+ })
+ .build()
+ .show()
+ },
+
async update(key, value) {
await confirmPassword()
@@ -128,3 +198,18 @@ export default {
},
}
</script>
+<style scoped>
+.settings-subsection {
+ margin-top: 20px;
+}
+
+.settings-subsection__name {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 16px;
+ font-weight: bold;
+ max-width: 900px;
+ margin-top: 0;
+}
+</style>
diff --git a/apps/federatedfilesharing/src/components/PersonalSettings.vue b/apps/federatedfilesharing/src/components/PersonalSettings.vue
index 4af9d799f6a..e58031d5653 100644
--- a/apps/federatedfilesharing/src/components/PersonalSettings.vue
+++ b/apps/federatedfilesharing/src/components/PersonalSettings.vue
@@ -1,67 +1,57 @@
<!--
-SPDX-FileLicenseText: 2022 Carl Schwan <carl@carlschwan.eu>
-SPDX-License-Identifier: AGPL-3.0-or-later
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
+ - SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<NcSettingsSection :name="t('federatedfilesharing', 'Federated Cloud')"
:description="t('federatedfilesharing', 'You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com')"
:doc-url="docUrlFederated">
- <p class="cloud-id-text">
- {{ t('federatedfilesharing', 'Your Federated Cloud ID:') }}
- <strong id="cloudid">{{ cloudId }}</strong>
- <NcButton ref="clipboard"
- :title="copyLinkTooltip"
- :aria-label="copyLinkTooltip"
- class="clipboard"
- type="tertiary-no-background"
- @click.prevent="copyCloudId">
- <template #icon>
- <Clipboard :size="20" />
- </template>
- </NcButton>
- </p>
+ <NcInputField class="federated-cloud__cloud-id"
+ readonly
+ :label="t('federatedfilesharing', 'Your Federated Cloud ID')"
+ :value="cloudId"
+ :success="isCopied"
+ show-trailing-button
+ :trailing-button-label="copyLinkTooltip"
+ @trailing-button-click="copyCloudId">
+ <template #trailing-button-icon>
+ <IconCheck v-if="isCopied" :size="20" fill-color="var(--color-success)" />
+ <IconClipboard v-else :size="20" />
+ </template>
+ </NcInputField>
<p class="social-button">
{{ t('federatedfilesharing', 'Share it so your friends can share files with you:') }}<br>
- <NcButton @click="goTo(shareFacebookUrl)">
+ <NcButton :href="shareFacebookUrl">
{{ t('federatedfilesharing', 'Facebook') }}
<template #icon>
- <Facebook :size="20" />
+ <img class="social-button__icon social-button__icon--bright" :src="urlFacebookIcon">
</template>
</NcButton>
- <NcButton @click="goTo(shareTwitterUrl)">
- {{ t('federatedfilesharing', 'Twitter') }}
+ <NcButton :aria-label="t('federatedfilesharing', 'X (formerly Twitter)')"
+ :href="shareXUrl">
+ {{ t('federatedfilesharing', 'formerly Twitter') }}
<template #icon>
- <Twitter :size="20" />
+ <img class="social-button__icon" :src="urlXIcon">
</template>
</NcButton>
- <NcButton @click="goTo(shareDiasporaUrl)">
- {{ t('federatedfilesharing', 'Diaspora') }}
+ <NcButton :href="shareMastodonUrl">
+ {{ t('federatedfilesharing', 'Mastodon') }}
<template #icon>
- <svg width="20"
- height="20"
- viewBox="-10 -5 1034 1034"
- xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M502 197q-96 0-96.5 1.5t-1.5 137-1.5 138-2 2.5T266 432.5 132.5 390t-30 94T74 578l232 77q21 8 21 10t-79.5 117.5T168 899t79.5 56.5T328 1011t81-110 82-110 41 55l83 115q43 60 44 60t79.5-58 79-59-76-112.5-76-113.5T795 632.5t129.5-44-28-94T867 400t-128 42-128.5 43-2.5-7.5-1-38.5l-3-108q-4-133-5-133.5t-97-.5z" /></svg>
+ <img class="social-button__icon" :src="urlMastodonIcon">
</template>
</NcButton>
- <NcButton @click="showHtml = !showHtml"
- class="social-button__website-button">
+ <NcButton :href="shareBlueSkyUrl">
+ {{ t('federatedfilesharing', 'Bluesky') }}
<template #icon>
- <Web :size="20" />
+ <img class="social-button__icon" :src="urlBlueSkyIcon">
+ </template>
+ </NcButton>
+ <NcButton class="social-button__website-button"
+ @click="showHtml = !showHtml">
+ <template #icon>
+ <IconWeb :size="20" />
</template>
{{ t('federatedfilesharing', 'Add to your website') }}
</NcButton>
@@ -87,33 +77,45 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</NcSettingsSection>
</template>
-<script>
-import { showError, showSuccess } from '@nextcloud/dialogs'
+<script lang="ts">
+import { showSuccess } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
-import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
-import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
-import Twitter from 'vue-material-design-icons/Twitter.vue'
-import Facebook from 'vue-material-design-icons/Facebook.vue'
-import Web from 'vue-material-design-icons/Web.vue'
-import Clipboard from 'vue-material-design-icons/Clipboard.vue'
+import { t } from '@nextcloud/l10n'
+import { imagePath } from '@nextcloud/router'
+import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'
+import NcButton from '@nextcloud/vue/components/NcButton'
+import NcInputField from '@nextcloud/vue/components/NcInputField'
+import IconWeb from 'vue-material-design-icons/Web.vue'
+import IconCheck from 'vue-material-design-icons/Check.vue'
+import IconClipboard from 'vue-material-design-icons/ContentCopy.vue'
export default {
name: 'PersonalSettings',
components: {
NcButton,
+ NcInputField,
NcSettingsSection,
- Twitter,
- Facebook,
- Web,
- Clipboard,
+ IconCheck,
+ IconClipboard,
+ IconWeb,
+ },
+ setup() {
+ return {
+ t,
+
+ cloudId: loadState<string>('federatedfilesharing', 'cloudId'),
+ reference: loadState<string>('federatedfilesharing', 'reference'),
+ urlFacebookIcon: imagePath('core', 'facebook'),
+ urlMastodonIcon: imagePath('core', 'mastodon'),
+ urlBlueSkyIcon: imagePath('core', 'bluesky'),
+ urlXIcon: imagePath('core', 'x'),
+ }
},
data() {
return {
color: loadState('federatedfilesharing', 'color'),
textColor: loadState('federatedfilesharing', 'textColor'),
logoPath: loadState('federatedfilesharing', 'logoPath'),
- reference: loadState('federatedfilesharing', 'reference'),
- cloudId: loadState('federatedfilesharing', 'cloudId'),
docUrlFederated: loadState('federatedfilesharing', 'docUrlFederated'),
showHtml: false,
isCopied: false,
@@ -126,20 +128,23 @@ export default {
messageWithoutURL() {
return t('federatedfilesharing', 'Share with me through my #Nextcloud Federated Cloud ID')
},
- shareDiasporaUrl() {
- return `https://share.diasporafoundation.org/?title=${encodeURIComponent(this.messageWithoutURL)}&url=${encodeURIComponent(this.reference)}`
+ shareMastodonUrl() {
+ return `https://mastodon.social/?text=${encodeURIComponent(this.messageWithoutURL)}&url=${encodeURIComponent(this.reference)}`
},
- shareTwitterUrl() {
- return `https://twitter.com/intent/tweet?text=${encodeURIComponent(this.messageWithURL)}`
+ shareXUrl() {
+ return `https://x.com/intent/tweet?text=${encodeURIComponent(this.messageWithURL)}`
},
shareFacebookUrl() {
return `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(this.reference)}`
},
+ shareBlueSkyUrl() {
+ return `https://bsky.app/intent/compose?text=${encodeURIComponent(this.messageWithURL)}`
+ },
logoPathAbsolute() {
return window.location.protocol + '//' + window.location.host + this.logoPath
},
backgroundStyle() {
- return `padding:10px;background-color:${this.color};color:${this.textColor};border-radius:3px;padding-left:4px;`
+ return `padding:10px;background-color:${this.color};color:${this.textColor};border-radius:3px;padding-inline-start:4px;`
},
linkStyle() {
return `background-image:url(${this.logoPathAbsolute});width:50px;height:30px;position:relative;top:8px;background-size:contain;display:inline-block;background-repeat:no-repeat; background-position: center center;`
@@ -151,22 +156,26 @@ export default {
</a>`
},
copyLinkTooltip() {
- return this.isCopied ? t('federatedfilesharing', 'Cloud ID copied to the clipboard') : t('federatedfilesharing', 'Copy to clipboard')
+ return this.isCopied ? t('federatedfilesharing', 'Cloud ID copied') : t('federatedfilesharing', 'Copy')
},
},
methods: {
- async copyCloudId() {
- if (!navigator.clipboard) {
- // Clipboard API not available
- showError(t('federatedfilesharing', 'Clipboard is not available'))
- return
+ async copyCloudId(): Promise<void> {
+ try {
+ await navigator.clipboard.writeText(this.cloudId)
+ showSuccess(t('federatedfilesharing', 'Cloud ID copied'))
+ } catch (e) {
+ // no secure context or really old browser - need a fallback
+ window.prompt(t('federatedfilesharing', 'Clipboard not available. Please copy the cloud ID manually.'), this.reference)
}
- await navigator.clipboard.writeText(this.cloudId)
this.isCopied = true
showSuccess(t('federatedfilesharing', 'Copied!'))
- this.$refs.clipboard.$el.focus()
+ setTimeout(() => {
+ this.isCopied = false
+ }, 2000)
},
- goTo(url) {
+
+ goTo(url: string): void {
window.location.href = url
},
},
@@ -176,28 +185,35 @@ export default {
<style lang="scss" scoped>
.social-button {
margin-top: 0.5rem;
- button {
+
+ button, a {
display: inline-flex;
- margin-left: 0.5rem;
+ margin-inline-start: 0.5rem;
margin-top: 1rem;
}
+
&__website-button {
width: min(100%, 400px) !important;
}
- }
- .cloud-id-text {
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- button {
- display: inline-flex;
+
+ &__icon {
+ height: 20px;
+ width: 20px;
+ filter: var(--background-invert-if-dark);
+
+ &--bright {
+ // Some logos like the Facebook logo have bright color schema
+ filter: var(--background-invert-if-bright);
+ }
}
}
+
+ .federated-cloud__cloud-id {
+ max-width: 300px;
+ }
+
pre {
margin-top: 0;
white-space: pre-wrap;
}
- #cloudid {
- margin-left: 0.25rem;
- }
</style>
diff --git a/apps/federatedfilesharing/src/components/RemoteShareDialog.cy.ts b/apps/federatedfilesharing/src/components/RemoteShareDialog.cy.ts
new file mode 100644
index 00000000000..79b5138327a
--- /dev/null
+++ b/apps/federatedfilesharing/src/components/RemoteShareDialog.cy.ts
@@ -0,0 +1,123 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import RemoteShareDialog from './RemoteShareDialog.vue'
+
+describe('RemoteShareDialog', () => {
+ it('can be mounted', () => {
+ cy.mount(RemoteShareDialog, {
+ propsData: {
+ owner: 'user123',
+ name: 'my-photos',
+ remote: 'nextcloud.local',
+ passwordRequired: false,
+ },
+ })
+
+ cy.findByRole('dialog')
+ .should('be.visible')
+ .and('contain.text', 'user123@nextcloud.local')
+ .and('contain.text', 'my-photos')
+ cy.findByRole('button', { name: 'Cancel' })
+ .should('be.visible')
+ cy.findByRole('button', { name: /add remote share/i })
+ .should('be.visible')
+ })
+
+ it('does not show password input if not enabled', () => {
+ cy.mount(RemoteShareDialog, {
+ propsData: {
+ owner: 'user123',
+ name: 'my-photos',
+ remote: 'nextcloud.local',
+ passwordRequired: false,
+ },
+ })
+
+ cy.findByRole('dialog')
+ .should('be.visible')
+ .find('input[type="password"]')
+ .should('not.exist')
+ })
+
+ it('emits true when accepted', () => {
+ const onClose = cy.spy().as('onClose')
+
+ cy.mount(RemoteShareDialog, {
+ listeners: {
+ close: onClose,
+ },
+ propsData: {
+ owner: 'user123',
+ name: 'my-photos',
+ remote: 'nextcloud.local',
+ passwordRequired: false,
+ },
+ })
+
+ cy.findByRole('button', { name: 'Cancel' }).click()
+ cy.get('@onClose')
+ .should('have.been.calledWith', false)
+ })
+
+ it('show password input if needed', () => {
+ cy.mount(RemoteShareDialog, {
+ propsData: {
+ owner: 'admin',
+ name: 'secret-data',
+ remote: 'nextcloud.local',
+ passwordRequired: true,
+ },
+ })
+
+ cy.findByRole('dialog')
+ .should('be.visible')
+ .find('input[type="password"]')
+ .should('be.visible')
+ })
+
+ it('emits the submitted password', () => {
+ const onClose = cy.spy().as('onClose')
+
+ cy.mount(RemoteShareDialog, {
+ listeners: {
+ close: onClose,
+ },
+ propsData: {
+ owner: 'admin',
+ name: 'secret-data',
+ remote: 'nextcloud.local',
+ passwordRequired: true,
+ },
+ })
+
+ cy.get('input[type="password"]')
+ .type('my password{enter}')
+ cy.get('@onClose')
+ .should('have.been.calledWith', true, 'my password')
+ })
+
+ it('emits no password if cancelled', () => {
+ const onClose = cy.spy().as('onClose')
+
+ cy.mount(RemoteShareDialog, {
+ listeners: {
+ close: onClose,
+ },
+ propsData: {
+ owner: 'admin',
+ name: 'secret-data',
+ remote: 'nextcloud.local',
+ passwordRequired: true,
+ },
+ })
+
+ cy.get('input[type="password"]')
+ .type('my password')
+ cy.findByRole('button', { name: 'Cancel' }).click()
+ cy.get('@onClose')
+ .should('have.been.calledWith', false)
+ })
+})
diff --git a/apps/federatedfilesharing/src/components/RemoteShareDialog.vue b/apps/federatedfilesharing/src/components/RemoteShareDialog.vue
new file mode 100644
index 00000000000..9ee44f586bf
--- /dev/null
+++ b/apps/federatedfilesharing/src/components/RemoteShareDialog.vue
@@ -0,0 +1,67 @@
+<!--
+ - SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+<script setup lang="ts">
+import { t } from '@nextcloud/l10n'
+import { computed, ref } from 'vue'
+import NcDialog from '@nextcloud/vue/components/NcDialog'
+import NcPasswordField from '@nextcloud/vue/components/NcPasswordField'
+
+const props = defineProps<{
+ /** Name of the share */
+ name: string
+ /** Display name of the owner */
+ owner: string
+ /** The remote instance name */
+ remote: string
+ /** True if the user should enter a password */
+ passwordRequired: boolean
+}>()
+
+const emit = defineEmits<{
+ (e: 'close', state: boolean, password?: string): void
+}>()
+
+const password = ref('')
+
+/**
+ * The dialog buttons
+ */
+const buttons = computed(() => [
+ {
+ label: t('federatedfilesharing', 'Cancel'),
+ callback: () => emit('close', false),
+ },
+ {
+ label: t('federatedfilesharing', 'Add remote share'),
+ nativeType: props.passwordRequired ? 'submit' : undefined,
+ type: 'primary',
+ callback: () => emit('close', true, password.value),
+ },
+])
+</script>
+
+<template>
+ <NcDialog :buttons="buttons"
+ :is-form="passwordRequired"
+ :name="t('federatedfilesharing', 'Remote share')"
+ @submit="emit('close', true, password)">
+ <p>
+ {{ t('federatedfilesharing', 'Do you want to add the remote share {name} from {owner}@{remote}?', { name, owner, remote }) }}
+ </p>
+ <NcPasswordField v-if="passwordRequired"
+ class="remote-share-dialog__password"
+ :label="t('federatedfilesharing', 'Remote share password')"
+ :value.sync="password" />
+ </NcDialog>
+</template>
+
+<style scoped lang="scss">
+.remote-share-dialog {
+
+ &__password {
+ margin-block: 1em .5em;
+ }
+}
+</style>