Skip to content

Commit

Permalink
fix(files): add "Link to file or folder" and "Upload" buttons
Browse files Browse the repository at this point in the history
Signed-off-by: julia.kirschenheuter <julia.kirschenheuter@nextcloud.com>
  • Loading branch information
JuliaKirschenheuter committed Jan 29, 2025
1 parent 75f5b86 commit dcdd7c7
Showing 1 changed file with 107 additions and 7 deletions.
114 changes: 107 additions & 7 deletions src/components/SuggestionsBar.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<template>
<div class="container-suggestions">
<NcButton type="tertiary"
<NcButton ref="linkFileOrFolder"
type="tertiary"
size="normal"
@click="$callChooseLocalAttachment">
@click="linkFile">
<template #icon>
<Document :size="20" />
</template>
{{ t('text', 'Add image') }}
{{ t('text', 'Link to file or folder') }}
</NcButton>

<NcButton ref="suggestButtonFile"
type="tertiary"
<NcButton type="tertiary"
size="normal"
@click="$callChooseLocalAttachment">
<template #icon>
<Document :size="20" />
</template>
{{ t('text', 'Link to file') }}
{{ t('text', 'Upload') }}
</NcButton>

<NcButton type="tertiary"
Expand Down Expand Up @@ -44,7 +44,9 @@ import { NcButton } from '@nextcloud/vue'
import { Document, Table, Shape } from './icons.js'
import { useActionChooseLocalAttachmentMixin } from './Editor/MediaHandler.provider.js'
import { getLinkWithPicker } from '@nextcloud/vue/dist/Components/NcRichText.js'
import { useEditorMixin } from './Editor.provider.js'
import { useEditorMixin, useFileMixin } from './Editor.provider.js'
import { FilePickerType, getFilePickerBuilder } from '@nextcloud/dialogs'
import { generateUrl } from '@nextcloud/router'

Check warning on line 49 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L43-L49

Added lines #L43 - L49 were not covered by tests
export default {
name: 'SuggestionsBar',
Expand All @@ -57,9 +59,26 @@ export default {
mixins: [
useActionChooseLocalAttachmentMixin,
useEditorMixin,
useFileMixin,
],

Check warning on line 63 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L51-L63

Added lines #L51 - L63 were not covered by tests
data: () => {
return {
startPath: null,
}
},

Check warning on line 69 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L65-L69

Added lines #L65 - L69 were not covered by tests
computed: {
relativePath() {
return this.$file?.relativePath ?? '/'
},
},

Check warning on line 75 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L71-L75

Added lines #L71 - L75 were not covered by tests
methods: {
/**
* Open smart picker dialog
* Triggered by the "Smart Picker" button
*/
linkPicker() {
getLinkWithPicker(null, true)
.then(link => {
Expand All @@ -74,9 +93,90 @@ export default {
console.error('Smart picker promise rejected', error)
})
},

Check warning on line 95 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L77-L95

Added lines #L77 - L95 were not covered by tests
/**
* Insert table
* Triggered by the "Insert table" button
*/
insertTable() {
this.$editor.chain().focus().insertTable()?.run()
},

Check warning on line 103 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L97-L103

Added lines #L97 - L103 were not covered by tests
/**
* Open dialog and ask user which file to link to
* Triggered by the "link to file or folder" button
*/
linkFile() {
if (this.startPath === null) {
this.startPath = this.relativePath.split('/').slice(0, -1).join('/')
}

Check warning on line 112 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L105-L112

Added lines #L105 - L112 were not covered by tests
const filePicker = getFilePickerBuilder(t('text', 'Select file or folder to link to'))
.startAt(this.startPath)
.allowDirectories(true)
.setMultiSelect(false)
.setType(FilePickerType.Choose)
.build()

Check warning on line 119 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L114-L119

Added lines #L114 - L119 were not covered by tests
filePicker.pick()
.then((file) => {
const client = OC.Files.getClient()
client.getFileInfo(file).then((_status, fileInfo) => {
const url = new URL(generateUrl(`/f/${fileInfo.id}`), window.origin)
this.setLink(url.href, fileInfo.name)
this.startPath = fileInfo.path + (fileInfo.type === 'dir' ? `/${fileInfo.name}/` : '')
})
})
.catch(() => {
// do not close menu but keep focus
this.$refs.linkFileOrFolder.$el.focus()
})
},

Check warning on line 134 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L121-L134

Added lines #L121 - L134 were not covered by tests
/**
* Save user entered URL as a link markup
* Triggered when the user submits the ActionInput
*
* @param {string} url href attribute of the link
* @param {string} text Text part of the link
*/
setLink(url, text) {
// Heuristics for determining if we need a https:// prefix.
const noPrefixes = [
/^[a-zA-Z]+:/, // url with protocol ("mailTo:email@domain.tld")
/^\//, // absolute path
/\?fileId=/, // relative link with fileId
/^\.\.?\//, // relative link starting with ./ or ../
/^[^.]*[/$]/, // no dots before first '/' - not a domain name
/^#/, // url fragment
]
if (url && !noPrefixes.find(regex => url.match(regex))) {
url = 'https://' + url
}

Check warning on line 155 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L136-L155

Added lines #L136 - L155 were not covered by tests
// Avoid issues when parsing urls later on in markdown that might be entered in an invalid format (e.g. "mailto: example@example.com")
const href = url.replaceAll(' ', '%20')
const chain = this.$editor.chain()
// Check if any text is selected, if not insert the link using the given text property
if (this.$editor.view.state?.selection.empty) {
chain.insertContent({
type: 'paragraph',
content: [{
type: 'text',
marks: [{
type: 'link',
attrs: {
href,
},
}],
text,
}],
})
} else {
chain.setLink({ href })
}
chain.focus().run()
},
},

Check warning on line 180 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L157-L180

Added lines #L157 - L180 were not covered by tests
}

Check warning on line 182 in src/components/SuggestionsBar.vue

View check run for this annotation

Codecov / codecov/patch

src/components/SuggestionsBar.vue#L182

Added line #L182 was not covered by tests
Expand Down

0 comments on commit dcdd7c7

Please sign in to comment.