Skip to content

Commit

Permalink
feat: show modal when creating links in embed mode
Browse files Browse the repository at this point in the history
Adds a modal that pops up after clicking "Share links" in embed mode where the user can specify the props of the link(s) they want to create: password, role, name. It also changes the behavior so there will be always new links created instead of re-using existing links.
  • Loading branch information
JammingBen committed Nov 28, 2023
1 parent cb4d481 commit 202876a
Show file tree
Hide file tree
Showing 18 changed files with 928 additions and 381 deletions.
90 changes: 16 additions & 74 deletions packages/web-app-files/src/components/EmbedActions/EmbedActions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
data-testid="button-share"
variation="inverse"
appearance="filled"
:disabled="areSelectActionsDisabled || !canCreatePublicLinks"
@click="sharePublicLinks"
:disabled="
areSelectActionsDisabled || !createLinkAction.isEnabled({ resources: selectedFiles, space })
"
@click="createLinkAction.handler({ resources: selectedFiles, space })"
>{{ $gettext('Share links') }}</oc-button
>
<oc-button
Expand All @@ -25,30 +27,25 @@
</template>

<script lang="ts">
import { computed } from 'vue'
import { computed, unref } from 'vue'
import {
createQuicklink,
getDefaultLinkPermissions,
showQuickLinkPasswordModal,
FileAction,
useAbility,
useClientService,
useEmbedMode,
usePasswordPolicyService,
useFileActionsCreateLink,
useStore
} from '@ownclouders/web-pkg'
import { Resource } from '@ownclouders/web-client'
import { Resource, SpaceResource } from '@ownclouders/web-client'
import { useGettext } from 'vue3-gettext'
import { SharePermissionBit } from '@ownclouders/web-client/src/helpers'
export default {
setup() {
const store = useStore()
const ability = useAbility()
const clientService = useClientService()
const passwordPolicyService = usePasswordPolicyService()
const language = useGettext()
const { isLocationPicker, postMessage } = useEmbedMode()
const space = computed<SpaceResource>(() => store.getters['runtime/spaces/currentSpace'])
const selectedFiles = computed<Resource[]>(() => {
if (isLocationPicker.value) {
return [store.getters['Files/currentFolder']]
Expand All @@ -57,6 +54,9 @@ export default {
return store.getters['Files/selectedFiles']
})
const { actions: createLinkActions } = useFileActionsCreateLink({ store })
const createLinkAction = computed<FileAction>(() => unref(createLinkActions)[0])
const areSelectActionsDisabled = computed<boolean>(() => selectedFiles.value.length < 1)
const canCreatePublicLinks = computed<boolean>(() => ability.can('create-all', 'PublicLink'))
Expand All @@ -76,74 +76,16 @@ export default {
postMessage<null>('owncloud-embed:cancel', null)
}
const emitShare = (links: string[]): void => {
if (!canCreatePublicLinks.value) return
postMessage<string[]>('owncloud-embed:share', links)
}
const sharePublicLinks = async (): Promise<string[]> => {
if (!canCreatePublicLinks.value) return
try {
const passwordEnforced: boolean =
store.getters.capabilities?.files_sharing?.public?.password?.enforced_for?.read_only ===
true
const permissions = getDefaultLinkPermissions({ ability, store })
if (passwordEnforced && permissions > SharePermissionBit.Internal) {
showQuickLinkPasswordModal(
{ store, $gettext: language.$gettext, passwordPolicyService },
async (password) => {
const links: string[] = await Promise.all(
selectedFiles.value.map(
async (resource) =>
(
await createQuicklink({
ability,
resource,
clientService,
language,
store,
password
})
).url
)
)
emitShare(links)
}
)
return
}
const links: string[] = await Promise.all(
selectedFiles.value.map(
async (resource) =>
(await createQuicklink({ ability, resource, clientService, language, store })).url
)
)
emitShare(links)
} catch (error) {
console.error(error)
store.dispatch('showErrorMessage', {
title: language.$gettext('Sharing links failed...'),
error
})
}
}
return {
selectedFiles,
areSelectActionsDisabled,
canCreatePublicLinks,
isLocationPicker,
selectLabel,
sharePublicLinks,
emitCancel,
emitSelect
emitSelect,
space,
createLinkAction
}
}
}
Expand Down
60 changes: 14 additions & 46 deletions packages/web-app-files/src/components/SideBar/Shares/FileLinks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
<name-and-copy v-if="quicklink" :link="quicklink" />
<create-quick-link
v-else-if="canCreateLinks"
:expiration-date="expirationDate"
:expiration-date="expirationRules"
@create-public-link="checkLinkToCreate"
/>
<details-and-edit
v-if="quicklink"
:available-role-options="getAvailableRoleOptions(quicklink)"
:can-rename="false"
:expiration-date="expirationDate"
:expiration-date="expirationRules"
:is-folder-share="resource.isFolder"
:is-modifiable="canEditLink(quicklink)"
:is-password-enforced="isPasswordEnforcedFor(quicklink)"
Expand Down Expand Up @@ -54,7 +54,7 @@
<details-and-edit
:available-role-options="getAvailableRoleOptions(link)"
:can-rename="true"
:expiration-date="expirationDate"
:expiration-date="expirationRules"
:is-folder-share="resource.isFolder"
:is-modifiable="canEditLink(link)"
:is-password-enforced="isPasswordEnforcedFor(link)"
Expand Down Expand Up @@ -89,7 +89,7 @@
<name-and-copy :link="link" />
<details-and-edit
:available-role-options="getAvailableRoleOptions(link)"
:expiration-date="expirationDate"
:expiration-date="expirationRules"
:is-folder-share="true"
:is-modifiable="false"
:link="link"
Expand Down Expand Up @@ -123,6 +123,8 @@ import {
useCapabilityFilesSharingPublicAlias,
useAbility,
usePasswordPolicyService,
useCapabilityFilesSharingPublicPasswordEnforcedFor,
getExpirationRules,
getDefaultLinkPermissions
} from '@ownclouders/web-pkg'
import { shareViaLinkHelp, shareViaIndirectLinkHelp } from '../../../helpers/contextualHelpers'
Expand All @@ -149,6 +151,7 @@ import {
import { isLocationSharesActive } from '@ownclouders/web-pkg'
import { useShares } from 'web-app-files/src/composables'
import { configurationManager } from '@ownclouders/web-pkg'
import { useGettext } from 'vue3-gettext'
export default defineComponent({
name: 'FileLinks',
Expand All @@ -160,6 +163,7 @@ export default defineComponent({
setup() {
const store = useStore()
const ability = useAbility()
const { current: currentLanguage } = useGettext()
const { can } = ability
const passwordPolicyService = usePasswordPolicyService()
const hasResharing = useCapabilityFilesSharingResharing()
Expand Down Expand Up @@ -218,6 +222,8 @@ export default defineComponent({
)
}
const expirationRules = computed(() => getExpirationRules({ store, currentLanguage }))
return {
$store: store,
ability,
Expand All @@ -229,6 +235,7 @@ export default defineComponent({
hasPublicLinkEditing: useCapabilityFilesSharingPublicCanEdit(),
hasPublicLinkContribute: useCapabilityFilesSharingPublicCanContribute(),
hasPublicLinkAliasSupport: useCapabilityFilesSharingPublicAlias(),
passwordEnforced: useCapabilityFilesSharingPublicPasswordEnforcedFor(),
indirectLinkListCollapsed,
linkListCollapsed,
outgoingLinks,
Expand All @@ -239,7 +246,8 @@ export default defineComponent({
configurationManager,
passwordPolicyService,
canCreateLinks,
canEditLink
canEditLink,
expirationRules
}
},
computed: {
Expand All @@ -262,46 +270,6 @@ export default defineComponent({
return this.outgoingLinks.find((link) => link.quicklink === true && !link.indirect)
},
expirationDate() {
const expireDate = this.capabilities.files_sharing.public.expire_date
let defaultExpireDate = null
let maxExpireDateFromCaps = null
if (expireDate.days) {
const days = parseInt(expireDate.days)
defaultExpireDate = DateTime.now()
.setLocale(getLocaleFromLanguage(this.$language.current))
.plus({ days })
.toJSDate()
}
if (expireDate.enforced) {
const days = parseInt(expireDate.days)
maxExpireDateFromCaps = DateTime.now()
.setLocale(getLocaleFromLanguage(this.$language.current))
.plus({ days })
.toJSDate()
}
return {
enforced: expireDate.enforced,
default: defaultExpireDate,
min: DateTime.now().setLocale(getLocaleFromLanguage(this.$language.current)).toJSDate(),
max: maxExpireDateFromCaps
}
},
passwordEnforced() {
return (
this.capabilities.files_sharing.public.password?.enforced_for || {
read_only: false,
upload_only: false,
read_write: false
}
)
},
helpersEnabled() {
return this.configuration?.options?.contextHelpers
},
Expand Down Expand Up @@ -423,7 +391,7 @@ export default defineComponent({
ability: this.ability,
store: this.$store
}).toString(),
expiration: this.expirationDate.default,
expiration: this.expirationRules.default,
password: false
}
})
Expand Down
Loading

0 comments on commit 202876a

Please sign in to comment.