Browse Source
feat(files_sharing): provide web-components based sidebar API
feat(files_sharing): provide web-components based sidebar API
This fixes apps providing vue components, which is invalid and does not always work - and never work with Vue 3. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>pull/54788/head
committed by
Carl Schwan
9 changed files with 256 additions and 32 deletions
-
32apps/files_sharing/src/components/SharingEntryLink.vue
-
71apps/files_sharing/src/components/SidebarTabExternal/SidebarTabExternalAction.vue
-
8apps/files_sharing/src/components/SidebarTabExternal/SidebarTabExternalActionLegacy.vue
-
33apps/files_sharing/src/components/SidebarTabExternal/SidebarTabExternalSection.vue
-
33apps/files_sharing/src/components/SidebarTabExternal/SidebarTabExternalSectionLegacy.vue
-
8apps/files_sharing/src/services/ExternalLinkActions.js
-
10apps/files_sharing/src/services/ExternalShareActions.js
-
44apps/files_sharing/src/views/SharingDetailsTab.vue
-
49apps/files_sharing/src/views/SharingTab.vue
@ -0,0 +1,71 @@ |
|||
<!-- |
|||
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors |
|||
- SPDX-License-Identifier: AGPL-3.0-or-later |
|||
--> |
|||
|
|||
<template> |
|||
<component :is="action.element" |
|||
:key="action.id" |
|||
ref="actionElement" |
|||
:share.prop="share" |
|||
:node.prop="node" |
|||
:on-save.prop="onSave" /> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import type { INode } from '@nextcloud/files' |
|||
import type { IShare } from '@nextcloud/sharing' |
|||
import type { ISidebarAction } from '@nextcloud/sharing/ui' |
|||
import type { PropType } from 'vue' |
|||
|
|||
import { ref, toRaw, watchEffect } from 'vue' |
|||
|
|||
const props = defineProps({ |
|||
action: { |
|||
type: Object as PropType<ISidebarAction>, |
|||
required: true, |
|||
}, |
|||
node: { |
|||
type: Object as PropType<INode>, |
|||
required: true, |
|||
}, |
|||
share: { |
|||
type: Object as PropType<IShare | undefined>, |
|||
required: true, |
|||
}, |
|||
}) |
|||
|
|||
defineExpose({ save }) |
|||
|
|||
const actionElement = ref() |
|||
const savingCallback = ref() |
|||
|
|||
watchEffect(() => { |
|||
if (!actionElement.value) { |
|||
return |
|||
} |
|||
|
|||
// This seems to be only needed in Vue 2 as the .prop modifier does not really work on the vue 2 version of web components |
|||
// TODO: Remove with Vue 3 |
|||
actionElement.value.node = toRaw(props.node) |
|||
actionElement.value.onSave = onSave |
|||
actionElement.value.share = toRaw(props.share) |
|||
}) |
|||
|
|||
/** |
|||
* The share is reset thus save the state of the component. |
|||
*/ |
|||
async function save() { |
|||
await savingCallback.value?.() |
|||
} |
|||
|
|||
/** |
|||
* Vue does not allow to call methods on wrapped web components |
|||
* so we need to pass it per callback. |
|||
* |
|||
* @param callback - The callback to be called on save |
|||
*/ |
|||
function onSave(callback: () => Promise<void>) { |
|||
savingCallback.value = callback |
|||
} |
|||
</script> |
|||
@ -0,0 +1,33 @@ |
|||
<!-- |
|||
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors |
|||
- SPDX-License-Identifier: AGPL-3.0-or-later |
|||
--> |
|||
|
|||
<template> |
|||
<component :is="section.element" ref="sectionElement" :node.prop="node" /> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import type { INode } from '@nextcloud/files' |
|||
import type { ISidebarSection } from '@nextcloud/sharing/ui' |
|||
import type { PropType } from 'vue' |
|||
|
|||
import { ref, watchEffect } from 'vue' |
|||
|
|||
const props = defineProps({ |
|||
node: { |
|||
type: Object as PropType<INode>, |
|||
required: true, |
|||
}, |
|||
section: { |
|||
type: Object as PropType<ISidebarSection>, |
|||
required: true, |
|||
}, |
|||
}) |
|||
|
|||
// TOOD: Remove with Vue 3 |
|||
const sectionElement = ref() |
|||
watchEffect(() => { |
|||
sectionElement.value.node = props.node |
|||
}) |
|||
</script> |
|||
@ -0,0 +1,33 @@ |
|||
<!-- |
|||
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors |
|||
- SPDX-License-Identifier: AGPL-3.0-or-later |
|||
--> |
|||
|
|||
<template> |
|||
<div class="sharing-tab-external-section-legacy"> |
|||
<component :is="component" :file-info="fileInfo" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { computed, type Component, type PropType } from 'vue' |
|||
|
|||
const props = defineProps({ |
|||
fileInfo: { |
|||
type: Object, |
|||
required: true, |
|||
}, |
|||
sectionCallback: { |
|||
type: Function as PropType<(el: HTMLElement | undefined, fileInfo: unknown) => Component>, |
|||
required: true, |
|||
}, |
|||
}) |
|||
|
|||
const component = computed(() => props.sectionCallback(undefined, props.fileInfo)) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.sharing-tab-external-section-legacy { |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue