Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-07-24 18:10:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-07-24 18:10:11 +0300
commit7308ec9d13fb69018200a40f287e76ef499ed47c (patch)
tree06c75f7ddceebd61d09f925a48fef2789338f3cd /app/assets/javascripts/vue_shared/components
parentf296f23500b4b3758670ae0c5ce2e1779f533e8b (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_shared/components')
-rw-r--r--app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js7
-rw-r--r--app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue64
2 files changed, 58 insertions, 13 deletions
diff --git a/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js
index 377f1e7c136..531ed5fe0ea 100644
--- a/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js
+++ b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js
@@ -8,16 +8,21 @@ export default {
const defaultProps = {
value: 'hR8x1fuJbzwu5uFKLf9e',
formInputGroupProps: { class: 'gl-form-input-xl' },
+ readonly: false,
};
const Template = (args, { argTypes }) => ({
components: { InputCopyToggleVisibility },
+ data() {
+ return { value: args.value };
+ },
props: Object.keys(argTypes),
template: `<input-copy-toggle-visibility
- :value="value"
+ v-model="value"
:initial-visibility="initialVisibility"
:show-toggle-visibility-button="showToggleVisibilityButton"
:show-copy-button="showCopyButton"
+ :readonly="readonly"
:form-input-group-props="formInputGroupProps"
:copy-button-title="copyButtonTitle"
/>`,
diff --git a/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue
index dea279890b1..c371c1aeff9 100644
--- a/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue
+++ b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue
@@ -8,6 +8,7 @@ import {
} from '@gitlab/ui';
import { __ } from '~/locale';
+import { Mousetrap, MOUSETRAP_COPY_KEYBOARD_SHORTCUT } from '~/lib/mousetrap';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
export default {
@@ -52,6 +53,11 @@ export default {
required: false,
default: __('Copy'),
},
+ readonly: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
formInputGroupProps: {
type: Object,
required: false,
@@ -61,6 +67,12 @@ export default {
},
},
data() {
+ if (!this.readonly && !this.value) {
+ return {
+ valueIsVisible: true,
+ };
+ }
+
return {
valueIsVisible: this.initialVisibility,
};
@@ -77,33 +89,60 @@ export default {
computedValueIsVisible() {
return !this.showToggleVisibilityButton || this.valueIsVisible;
},
- displayedValue() {
- return this.computedValueIsVisible ? this.value : '*'.repeat(this.value.length || 20);
+ inputType() {
+ return this.computedValueIsVisible ? 'text' : 'password';
},
},
+ mounted() {
+ this.$options.mousetrap = new Mousetrap(this.$refs.input.$el);
+ this.$options.mousetrap.bind(MOUSETRAP_COPY_KEYBOARD_SHORTCUT, this.handleFormInputCopy);
+ },
+ beforeDestroy() {
+ this.$options.mousetrap?.unbind(MOUSETRAP_COPY_KEYBOARD_SHORTCUT);
+ },
+
methods: {
handleToggleVisibilityButtonClick() {
this.valueIsVisible = !this.valueIsVisible;
this.$emit('visibility-change', this.valueIsVisible);
},
- handleClick() {
- this.$refs.input.$el.select();
+ async handleClick() {
+ if (this.readonly) {
+ this.$refs.input.$el.select();
+ } else if (!this.valueIsVisible) {
+ const { selectionStart, selectionEnd } = this.$refs.input.$el;
+ this.handleToggleVisibilityButtonClick();
+
+ setTimeout(() => {
+ // When the input type is changed from 'password'' to 'text', cursor position is reset in some browsers.
+ // This makes clicking to edit difficult due to typing in unexpected location, so we preserve the cursor position / selection
+ this.$refs.input.$el.setSelectionRange(selectionStart, selectionEnd);
+ }, 0);
+ }
},
handleCopyButtonClick() {
this.$emit('copy');
},
- handleFormInputCopy(event) {
- this.handleCopyButtonClick();
-
+ async handleFormInputCopy() {
+ // Value will be copied by native browser behavior
if (this.computedValueIsVisible) {
return;
}
- event.clipboardData.setData('text/plain', this.value);
- event.preventDefault();
+ try {
+ // user is trying to copy from the password input, set their clipboard for them
+ await navigator.clipboard?.writeText(this.value);
+ this.handleCopyButtonClick();
+ } catch (e) {
+ // Nothing we can do here, best effort to set clipboard value
+ }
+ },
+ handleInput(newValue) {
+ this.$emit('input', newValue);
},
},
+ mousetrap: null,
};
</script>
<template>
@@ -111,11 +150,12 @@ export default {
<gl-form-input-group>
<gl-form-input
ref="input"
- readonly
+ :readonly="readonly"
class="gl-font-monospace! gl-cursor-default!"
v-bind="formInputGroupProps"
- :value="displayedValue"
- @copy="handleFormInputCopy"
+ :value="value"
+ :type="inputType"
+ @input="handleInput"
@click="handleClick"
/>