aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/src
diff options
context:
space:
mode:
authorChristopher Ng <chrng8@gmail.com>2024-02-28 18:59:05 -0800
committerJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2024-03-06 21:22:59 +0100
commit1260c8552a8ac37df6ba3df7f5165e5a40401119 (patch)
tree9181e59a28c626392d3b502136800cf7fa66257b /apps/files_sharing/src
parent8fded1d4b78d87490a7fb7555f8d8ca748ae1180 (diff)
downloadnextcloud-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.vue4
-rw-r--r--apps/files_sharing/src/services/ExternalShareActions.js8
-rw-r--r--apps/files_sharing/src/views/SharingDetailsTab.vue34
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')
},
/**