diff options
author | Christopher Ng <chrng8@gmail.com> | 2024-02-28 18:59:05 -0800 |
---|---|---|
committer | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2024-03-06 21:22:59 +0100 |
commit | 1260c8552a8ac37df6ba3df7f5165e5a40401119 (patch) | |
tree | 9181e59a28c626392d3b502136800cf7fa66257b /apps/files_sharing/src | |
parent | 8fded1d4b78d87490a7fb7555f8d8ca748ae1180 (diff) | |
download | nextcloud-server-1260c8552a8ac37df6ba3df7f5165e5a40401119.tar.gz nextcloud-server-1260c8552a8ac37df6ba3df7f5165e5a40401119.zip |
feat: Allow registration of advanced external share actions
Signed-off-by: Christopher Ng <chrng8@gmail.com>
Diffstat (limited to 'apps/files_sharing/src')
-rw-r--r-- | apps/files_sharing/src/components/SharingEntryLink.vue | 4 | ||||
-rw-r--r-- | apps/files_sharing/src/services/ExternalShareActions.js | 8 | ||||
-rw-r--r-- | apps/files_sharing/src/views/SharingDetailsTab.vue | 34 |
3 files changed, 43 insertions, 3 deletions
diff --git a/apps/files_sharing/src/components/SharingEntryLink.vue b/apps/files_sharing/src/components/SharingEntryLink.vue index bf9e0203f9e..041a9b16ad6 100644 --- a/apps/files_sharing/src/components/SharingEntryLink.vue +++ b/apps/files_sharing/src/components/SharingEntryLink.vue @@ -525,10 +525,10 @@ export default { * @return {Array} */ externalLinkActions() { + const filterValidAction = (action) => (action.shareType.includes(ShareTypes.SHARE_TYPE_LINK) || action.shareType.includes(ShareTypes.SHARE_TYPE_EMAIL)) && !action.advanced // filter only the registered actions for said link return this.ExternalShareActions.actions - .filter(action => action.shareType.includes(ShareTypes.SHARE_TYPE_LINK) - || action.shareType.includes(ShareTypes.SHARE_TYPE_EMAIL)) + .filter(filterValidAction) }, isPasswordPolicyEnabled() { diff --git a/apps/files_sharing/src/services/ExternalShareActions.js b/apps/files_sharing/src/services/ExternalShareActions.js index 6167346699e..89a46e7e692 100644 --- a/apps/files_sharing/src/services/ExternalShareActions.js +++ b/apps/files_sharing/src/services/ExternalShareActions.js @@ -45,12 +45,18 @@ export default class ExternalShareActions { } /** + * @typedef ExternalShareActionData + * @property {import('vue').Component} is Vue component to render, for advanced actions the `async onSave` method of the component will be called when saved + */ + + /** * Register a new option/entry for the a given share type * * @param {object} action new action component to register * @param {string} action.id unique action id - * @param {Function} action.data data to bind the component to + * @param {(data: any) => ExternalShareActionData & Record<string, unknown>} action.data data to bind the component to * @param {Array} action.shareType list of \@nextcloud/sharing.Types.SHARE_XXX to be mounted on + * @param {boolean} action.advanced `true` if the action entry should be rendered within advanced settings * @param {object} action.handlers list of listeners * @return {boolean} */ diff --git a/apps/files_sharing/src/views/SharingDetailsTab.vue b/apps/files_sharing/src/views/SharingDetailsTab.vue index 83e3dc3706f..b7d87a88b0e 100644 --- a/apps/files_sharing/src/views/SharingDetailsTab.vue +++ b/apps/files_sharing/src/views/SharingDetailsTab.vue @@ -164,6 +164,13 @@ </label> <textarea id="share-note-textarea" :value="share.note" @input="share.note = $event.target.value" /> </template> + <ExternalShareAction v-for="action in externalLinkActions" + :id="action.id" + ref="externalLinkActions" + :key="action.id" + :action="action" + :file-info="fileInfo" + :share="share" /> <NcCheckboxRadioSwitch :checked.sync="setCustomPermissions"> {{ t('files_sharing', 'Custom permissions') }} </NcCheckboxRadioSwitch> @@ -234,6 +241,7 @@ <script> import { getLanguage } from '@nextcloud/l10n' +import { Type as ShareType } from '@nextcloud/sharing' import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' import NcInputField from '@nextcloud/vue/dist/Components/NcInputField.js' @@ -256,6 +264,8 @@ import MenuDownIcon from 'vue-material-design-icons/MenuDown.vue' import MenuUpIcon from 'vue-material-design-icons/MenuUp.vue' import DotsHorizontalIcon from 'vue-material-design-icons/DotsHorizontal.vue' +import ExternalShareAction from '../components/ExternalShareAction.vue' + import GeneratePassword from '../utils/GeneratePassword.js' import Share from '../models/Share.js' import ShareRequests from '../mixins/ShareRequests.js' @@ -281,6 +291,7 @@ export default { CloseIcon, CircleIcon, EditIcon, + ExternalShareAction, LinkIcon, GroupIcon, ShareIcon, @@ -318,6 +329,8 @@ export default { isFirstComponentLoad: true, test: false, creating: false, + + ExternalShareActions: OCA.Sharing.ExternalShareActions.state, } }, @@ -670,6 +683,18 @@ export default { } return undefined }, + + /** + * Additional actions for the menu + * + * @return {Array} + */ + externalLinkActions() { + const filterValidAction = (action) => (action.shareType.includes(ShareType.SHARE_TYPE_LINK) || action.shareType.includes(ShareType.SHARE_TYPE_EMAIL)) && action.advanced + // filter only the advanced registered actions for said link + return this.ExternalShareActions.actions + .filter(filterValidAction) + }, }, watch: { setCustomPermissions(isChecked) { @@ -860,6 +885,15 @@ export default { this.queueUpdate(...permissionsAndAttributes) } + if (this.$refs.externalLinkActions?.length > 0) { + await Promise.allSettled(this.$refs.externalLinkActions.map((action) => { + if (typeof action.$children.at(0)?.onSave !== 'function') { + return Promise.resolve() + } + return action.$children.at(0)?.onSave?.() + })) + } + this.$emit('close-sharing-details') }, /** |