diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-25 15:07:31 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-25 15:07:31 +0300 |
commit | 89474d2468f108c909e440efcbe2ce9f7090d19a (patch) | |
tree | a8ae7833900e43320347b23b410ced5103953cbf /app/assets/javascripts/vue_merge_request_widget | |
parent | f15cf65c53f00e5d3a8bad666a95c076c0e4e262 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget')
4 files changed, 147 insertions, 6 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/action_buttons.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/action_buttons.vue new file mode 100644 index 00000000000..6655af92a55 --- /dev/null +++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/action_buttons.vue @@ -0,0 +1,134 @@ +<script> +import { GlButton, GlDropdown, GlDropdownItem, GlTooltipDirective } from '@gitlab/ui'; +import { sprintf, __ } from '~/locale'; + +export default { + components: { + GlButton, + GlDropdown, + GlDropdownItem, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + widget: { + type: String, + required: false, + default: '', + }, + tertiaryButtons: { + type: Array, + required: false, + default: () => [], + }, + }, + data: () => { + return { + timeout: null, + updatingTooltip: false, + }; + }, + computed: { + dropdownLabel() { + if (!this.widget) return undefined; + + return sprintf(__('%{widget} options'), { widget: this.widget }); + }, + }, + methods: { + onClickAction(action) { + this.$emit('clickedAction', action); + + if (action.onClick) { + action.onClick(); + } + + if (action.tooltipOnClick) { + this.updatingTooltip = true; + this.$root.$emit('bv::show::tooltip', action.id); + + clearTimeout(this.timeout); + + this.timeout = setTimeout(() => { + this.updatingTooltip = false; + this.$root.$emit('bv::hide::tooltip', action.id); + }, 1000); + } + }, + setTooltip(btn) { + if (this.updatingTooltip && btn.tooltipOnClick) { + return btn.tooltipOnClick; + } + + return btn.tooltipText; + }, + actionButtonQaSelector(btn) { + if (btn.dataQaSelector) { + return btn.dataQaSelector; + } + return 'mr_widget_extension_actions_button'; + }, + }, +}; +</script> + +<template> + <div class="gl-display-flex gl-align-items-flex-start"> + <gl-dropdown + v-if="tertiaryButtons.length" + v-gl-tooltip + :title="__('Options')" + :text="dropdownLabel" + icon="ellipsis_v" + no-caret + category="tertiary" + right + lazy + text-sr-only + size="small" + toggle-class="gl-p-2!" + class="gl-display-block gl-md-display-none!" + > + <gl-dropdown-item + v-for="(btn, index) in tertiaryButtons" + :key="index" + :href="btn.href" + :target="btn.target" + :data-clipboard-text="btn.dataClipboardText" + :data-method="btn.dataMethod" + @click="onClickAction(btn)" + > + {{ btn.text }} + </gl-dropdown-item> + </gl-dropdown> + <template v-if="tertiaryButtons.length"> + <gl-button + v-for="(btn, index) in tertiaryButtons" + :id="btn.id" + :key="index" + v-gl-tooltip.hover + :title="setTooltip(btn)" + :href="btn.href" + :target="btn.target" + :class="[{ 'gl-mr-3': index !== tertiaryButtons.length - 1 }, btn.class]" + :data-clipboard-text="btn.dataClipboardText" + :data-qa-selector="actionButtonQaSelector(btn)" + :data-method="btn.dataMethod" + :icon="btn.icon" + :data-testid="btn.testId || 'extension-actions-button'" + :variant="btn.variant || 'confirm'" + :loading="btn.loading" + :disabled="btn.loading" + category="tertiary" + size="small" + class="gl-display-none gl-md-display-block gl-float-left" + @click="onClickAction(btn)" + > + <template v-if="btn.text"> + {{ btn.text }} + </template> + </gl-button> + </template> + </div> +</template> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/dynamic_content.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/dynamic_content.vue index 067c29efc3d..2913fcf75e2 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/widget/dynamic_content.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/dynamic_content.vue @@ -1,9 +1,9 @@ <script> import { GlBadge, GlLink } from '@gitlab/ui'; import SafeHtml from '~/vue_shared/directives/safe_html'; -import Actions from '../action_buttons.vue'; import { generateText } from '../extensions/utils'; import ContentRow from './widget_content_row.vue'; +import Actions from './action_buttons.vue'; export default { name: 'DynamicContent', diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue index d4562f48806..301d61aeee9 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue @@ -6,12 +6,12 @@ import SafeHtml from '~/vue_shared/directives/safe_html'; import { sprintf, __ } from '~/locale'; import Poll from '~/lib/utils/poll'; import HelpPopover from '~/vue_shared/components/help_popover.vue'; -import ActionButtons from '../action_buttons.vue'; import { EXTENSION_ICONS } from '../../constants'; import { createTelemetryHub } from '../extensions/telemetry'; import ContentRow from './widget_content_row.vue'; import DynamicContent from './dynamic_content.vue'; import StatusIcon from './status_icon.vue'; +import ActionButtons from './action_buttons.vue'; const FETCH_TYPE_COLLAPSED = 'collapsed'; const FETCH_TYPE_EXPANDED = 'expanded'; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue index 0bca89ffc1d..63a902c49cc 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue @@ -3,9 +3,9 @@ import { GlLink } from '@gitlab/ui'; import { __ } from '~/locale'; import HelpPopover from '~/vue_shared/components/help_popover.vue'; import SafeHtml from '~/vue_shared/directives/safe_html'; -import ActionButtons from '../action_buttons.vue'; import { EXTENSION_ICONS } from '../../constants'; import { generateText } from '../extensions/utils'; +import ActionButtons from './action_buttons.vue'; import StatusIcon from './status_icon.vue'; export default { @@ -68,6 +68,9 @@ export default { shouldShowHeaderActions() { return Boolean(this.helpPopover) || this.actionButtons?.length > 0; }, + hasActionButtons() { + return this.actionButtons.length > 0; + }, }, i18n: { learnMore: __('Learn more'), @@ -96,7 +99,12 @@ export default { v-if="shouldShowHeaderActions" class="gl-ml-auto gl-display-flex gl-align-items-baseline" > - <help-popover v-if="helpPopover" :options="helpPopover.options" icon="information-o"> + <help-popover + v-if="helpPopover" + :options="helpPopover.options" + :class="{ 'gl-mr-3': hasActionButtons }" + icon="information-o" + > <template v-if="helpPopover.content"> <p v-if="helpPopover.content.text" @@ -113,10 +121,9 @@ export default { </template> </help-popover> <action-buttons - v-if="actionButtons.length > 0" + v-if="hasActionButtons" :widget="widgetName" :tertiary-buttons="actionButtons" - :class="{ 'gl-ml-2': helpPopover }" /> </div> </div> |