Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Action toasts #5147

Merged
merged 7 commits into from
May 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelog/unreleased/bugfix-copy-to-clipboard-with-keyboard
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Bugfix: Keyboard navigation for copy to clipboard

We've fixed that the buttons for copying (private/public) links to the clipboard were not usable via keyboard.

https://github.com/owncloud/web/pull/5147
5 changes: 5 additions & 0 deletions changelog/unreleased/enhancement-copy-link-toasts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Enhancement: Confirmation message when copying links

We've added confirmation messages (toasts) when a private or public link is copied to the clipboard.

https://github.com/owncloud/web/pull/5147
21 changes: 0 additions & 21 deletions packages/web-app-files/src/components/FileLinkSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -230,27 +230,6 @@ export default {
}
}
</script>
<style scoped>
/* FIXME: Move to design system */
._clipboard-success-animation {
animation-name: _clipboard-success-animation;
animation-duration: 0.5s;
animation-timing-function: ease-out;
animation-fill-mode: both;
}

@keyframes _clipboard-success-animation {
0% {
opacity: 1;
}
50% {
opacity: 0.9;
}
100% {
opacity: 0;
}
}
</style>
<style>
/* FIXME: Move to design system (copied from FileSharingSidebar.vue) */
.oc-app-side-bar .oc-label {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<template>
<oc-button
v-oc-tooltip="label"
:aria-label="label"
appearance="raw"
@click="copyValueToClipboard"
>
<oc-icon
v-if="copied"
key="oc-copy-to-clipboard-copied"
name="ready"
class="_clipboard-success-animation"
/>
<oc-icon v-else key="oc-copy-to-clipboard-copy" name="copy_to_clipboard" />
</oc-button>
</template>

<script>
import { mapActions } from 'vuex'
import copyToClipboard from 'copy-to-clipboard'

export default {
props: {
/**
* Content which is to be copied to the clipboard
*/
value: {
type: String,
required: true
},
/**
* Tooltip and aria-label for the button (describing the action, e.g. "Copy link to clipboard")
*/
label: {
type: String,
required: true
},
/**
* Title for the success message toast
*/
successMsgTitle: {
type: String,
required: true
},
/**
* Content for the success message toast
*/
successMsgText: {
type: String,
required: true
}
},
data: () => ({
copied: false,
timeout: null
}),
methods: {
...mapActions(['showMessage']),
copyValueToClipboard() {
copyToClipboard(this.value)
this.clipboardSuccessHandler()
this.showMessage({
title: this.successMsgTitle,
desc: this.successMsgText,
status: 'success',
autoClose: {
enabled: true
}
})
},
clipboardSuccessHandler() {
this.copied = true
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
this.copied = false
}, 550)
}
}
}
</script>

<style scoped>
._clipboard-success-animation {
animation-name: _clipboard-success-animation;
animation-duration: 0.5s;
animation-timing-function: ease-out;
animation-fill-mode: both;
}

@keyframes _clipboard-success-animation {
0% {
opacity: 1;
}
50% {
opacity: 0.9;
}
100% {
opacity: 0;
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,16 @@
<a
:href="link.url"
target="_blank"
class="oc-files-file-link-url oc-mr-xs uk-text-truncate"
class="oc-files-file-link-url uk-text-truncate"
v-text="link.url"
/>
<oc-button
v-oc-tooltip="copyLabel"
:aria-label="copyLabel"
appearance="raw"
class="oc-files-file-link-copy-url"
>
<oc-icon
v-if="linkCopied"
key="copy-link-icon-copied"
name="ready"
class="oc-files-file-link-copied-url _clipboard-success-animation"
/>
<oc-icon
v-else
key="copy-link-icon"
v-clipboard:copy="link.url"
v-clipboard:success="clipboardSuccessHandler"
name="copy_to_clipboard"
/>
</oc-button>
<copy-to-clipboard-button
class="oc-files-public-link-copy-url oc-ml-xs"
:value="link.url"
:label="copyToClipboardLabel"
:success-msg-title="copyToClipboardSuccessMsgTitle"
:success-msg-text="getCopyToClipboardSuccessMsgText(link)"
/>
</div>
</div>
<oc-grid gutter="small">
Expand Down Expand Up @@ -73,10 +60,11 @@
<script>
import { basename, dirname } from 'path'
import Mixins from '../../mixins'
import CopyToClipboardButton from './CopyToClipboardButton.vue'

export default {
name: 'LinkInfo',

components: { CopyToClipboardButton },
mixins: [Mixins],

props: {
Expand All @@ -86,21 +74,11 @@ export default {
}
},

data: () => ({
linkCopied: false
}),

computed: {
linkName() {
return this.link.name ? this.link.name : this.link.token
},

copyLabel() {
return this.linkCopied
? this.$gettext('Public link successfully copied')
: this.$gettext('Copy public link url')
},

roleTagIcon() {
switch (this.link.description) {
case 'Viewer':
Expand Down Expand Up @@ -146,16 +124,29 @@ export default {

viaTooltip() {
return this.$gettext('Navigate to the parent')
},

copyToClipboardLabel() {
return this.$gettext('Copy link to clipboard')
},

copyToClipboardSuccessMsgTitle() {
return this.$gettext('Public link copied')
}
},

methods: {
clipboardSuccessHandler() {
this.linkCopied = true

setTimeout(() => {
this.linkCopied = false
}, 550)
getCopyToClipboardSuccessMsgText(link) {
const translated = this.$gettext(
'The public link "%{linkName}" has been copied to your clipboard.'
)
return this.$gettextInterpolate(
translated,
{
linkName: link.name
},
true
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,29 @@
<p v-translate class="oc-text-muted oc-my-rm">Only invited people can use this link.</p>
<div class="uk-width-1-1 uk-flex uk-flex-middle">
<a :href="link" target="_blank" class="uk-text-truncate" v-text="link" />
<oc-button v-oc-tooltip="copyLabel" :aria-label="copyLabel" appearance="raw" class="oc-ml-s">
<oc-icon
v-if="linkCopied"
id="files-sidebar-private-link-icon-copied"
key="private-link-copy-icon-copied"
name="ready"
class="_clipboard-success-animation"
/>
<oc-icon
v-else
id="files-sidebar-private-link-label"
key="private-link-copy-icon"
v-clipboard:copy="link"
v-clipboard:success="clipboardSuccessHandler"
name="copy_to_clipboard"
/>
</oc-button>
<copy-to-clipboard-button
class="oc-files-private-link-copy-url oc-ml-xs"
:value="link"
:label="copyToClipboardLabel"
:success-msg-title="copyToClipboardSuccessMsgTitle"
:success-msg-text="copyToClipboardSuccessMsgText"
/>
</div>
<hr />
</div>
</template>

<script>
import { mapGetters } from 'vuex'
import CopyToClipboardButton from './CopyToClipboardButton.vue'

export default {
name: 'PrivateLinkItem',

data: () => ({
linkCopied: false
}),

components: { CopyToClipboardButton },
computed: {
...mapGetters('Files', ['highlightedFile']),
...mapGetters(['capabilities']),

copyLabel() {
return this.$gettext('Copy private link url')
},

link() {
if (this.highlightedFile.isMounted()) {
const file = encodeURIComponent(this.highlightedFile.name)
Expand All @@ -56,16 +39,17 @@ export default {

privateLinkEnabled() {
return this.capabilities.files.privateLinks
}
},
},

methods: {
clipboardSuccessHandler() {
this.linkCopied = true
copyToClipboardLabel() {
return this.$gettext('Copy private link to clipboard')
},

setTimeout(() => {
this.linkCopied = false
}, 550)
copyToClipboardSuccessMsgTitle() {
return this.$gettext('Private link copied')
},
copyToClipboardSuccessMsgText() {
return this.$gettext('The private link has been copied to your clipboard.')
}
}
}
Expand Down
1 change: 0 additions & 1 deletion packages/web-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"uikit": "3.5.16",
"vue": "^2.6.10",
"vue-axe": "^2.4.4",
"vue-clipboard2": "^0.3.1",
"vue-datetime": "^1.0.0-beta.10",
"vue-drag-drop": "^1.1.4",
"vue-events": "^3.1.0",
Expand Down
2 changes: 0 additions & 2 deletions packages/web-runtime/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import router from './router'
import VueResize from 'vue-resize'
import VueEvents from 'vue-events'
import VueRouter from 'vue-router'
import VueClipboard from 'vue-clipboard2'
import VueScrollTo from 'vue-scrollto'
import VueMeta from 'vue-meta'
import Vue2TouchEvents from 'vue2-touch-events'
Expand Down Expand Up @@ -66,7 +65,6 @@ Vue.prototype.$client = new OwnCloud()

Vue.use(VueEvents)
Vue.use(VueRouter)
Vue.use(VueClipboard)
Vue.use(VueScrollTo)
Vue.use(MediaSource)
Vue.use(WebPlugin)
Expand Down
15 changes: 4 additions & 11 deletions tests/acceptance/pageObjects/FilesPageElement/publicLinksDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,12 +335,8 @@ module.exports = {
return this.waitForElementVisible(this.api.page.personalPage().elements.sideBar)
.waitForElementVisible(linksAccordionItem)
.click(linksAccordionItem)
.waitForElementVisible('@sidebarPrivateLinkLabel')
.waitForElementVisible('@privateLinkURLCopyButton')
.click('@sidebarPrivateLinkLabel')
.waitForElementNotPresent('@sidebarPrivateLinkLabel')
.waitForElementVisible('@sidebarPrivateLinkIconCopied')
.waitForElementNotPresent('@sidebarPrivateLinkIconCopied')
.waitForElementVisible('@sidebarPrivateLinkLabel')
}
},
elements: {
Expand Down Expand Up @@ -410,7 +406,7 @@ module.exports = {
},
publicLinkURLCopyButton: {
selector:
'//div[contains(@class, "oc-files-file-link-name") and text()="%s"]/../../..//button[contains(@class, "oc-files-file-link-copy-url")]',
'//div[contains(@class, "oc-files-file-link-name") and text()="%s"]/../../..//button[contains(@class, "oc-files-public-link-copy-url")]',
locateStrategy: 'xpath'
},
publicLinkPasswordField: {
Expand All @@ -426,11 +422,8 @@ module.exports = {
publicLinkSaveButton: {
selector: '#oc-files-file-link-save'
},
sidebarPrivateLinkLabel: {
selector: '#files-sidebar-private-link-label'
},
sidebarPrivateLinkIconCopied: {
selector: '#files-sidebar-private-link-icon-copied'
privateLinkURLCopyButton: {
selector: '.oc-files-private-link-copy-url'
},
publicLinkRoleSelectionDropdown: {
selector: '//div[contains(@class, "files-file-link-role-button-wrapper")]//span[.="%s"]',
Expand Down
Loading