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:
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue')
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue94
1 files changed, 84 insertions, 10 deletions
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 94359d7d6ac..cea7fb8260a 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
@@ -1,29 +1,41 @@
<script>
-import { GlButton, GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui';
+import {
+ GlButton,
+ GlLink,
+ GlTooltipDirective,
+ GlLoadingIcon,
+ GlSafeHtmlDirective,
+} from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { normalizeHeaders } from '~/lib/utils/common_utils';
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';
const FETCH_TYPE_COLLAPSED = 'collapsed';
const FETCH_TYPE_EXPANDED = 'expanded';
+const WIDGET_PREFIX = 'Widget';
export default {
components: {
ActionButtons,
StatusIcon,
+ GlLink,
GlButton,
GlLoadingIcon,
ContentRow,
DynamicContent,
+ HelpPopover,
},
directives: {
GlTooltip: GlTooltipDirective,
+ SafeHtml: GlSafeHtmlDirective,
},
props: {
/**
@@ -72,8 +84,8 @@ export default {
},
statusIconName: {
type: String,
- default: 'neutral',
required: false,
+ default: 'neutral',
validator: (value) => Object.keys(EXTENSION_ICONS).indexOf(value) > -1,
},
isCollapsible: {
@@ -88,6 +100,26 @@ export default {
widgetName: {
type: String,
required: true,
+ // see https://docs.gitlab.com/ee/development/fe_guide/merge_request_widget_extensions.html#add-new-widgets
+ validator: (val) => val.startsWith(WIDGET_PREFIX),
+ },
+ telemetry: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ /**
+ * @typedef {Object} helpPopover
+ * @property {Object} options
+ * @property {String} options.title
+ * @property {Object} content
+ * @property {String} content.text
+ * @property {String} content.learnMorePath
+ */
+ helpPopover: {
+ type: Object,
+ required: false,
+ default: null,
},
},
data() {
@@ -98,6 +130,7 @@ export default {
isLoadingExpandedContent: false,
summaryError: null,
contentError: null,
+ telemetryHub: null,
};
},
computed: {
@@ -113,8 +146,14 @@ export default {
this.$emit('is-loading', newValue);
},
},
+ created() {
+ if (this.telemetry) {
+ this.telemetryHub = createTelemetryHub(this.widgetName);
+ }
+ },
async mounted() {
this.isLoading = true;
+ this.telemetryHub?.viewed();
try {
await this.fetch(this.fetchCollapsedData, FETCH_TYPE_COLLAPSED);
@@ -125,12 +164,21 @@ export default {
this.isLoading = false;
},
methods: {
+ onActionClick(action) {
+ if (action.fullReport) {
+ this.telemetryHub?.fullReportClicked();
+ }
+ },
toggleCollapsed() {
this.isCollapsed = !this.isCollapsed;
- if (this.isExpandedForTheFirstTime && typeof this.fetchExpandedData === 'function') {
- this.isExpandedForTheFirstTime = false;
- this.fetchExpandedContent();
+ if (this.isExpandedForTheFirstTime) {
+ this.telemetryHub?.expanded({ type: this.summaryStatusIcon });
+
+ if (typeof this.fetchExpandedData === 'function') {
+ this.isExpandedForTheFirstTime = false;
+ this.fetchExpandedContent();
+ }
}
},
async fetchExpandedContent() {
@@ -184,6 +232,9 @@ export default {
},
},
failedStatusIcon: EXTENSION_ICONS.failed,
+ i18n: {
+ learnMore: __('Learn more'),
+ },
};
</script>
@@ -204,11 +255,34 @@ export default {
<span v-if="summaryError">{{ summaryError }}</span>
<slot v-else name="summary">{{ isLoading ? loadingText : summary }}</slot>
</div>
- <action-buttons
- v-if="actionButtons.length > 0"
- :widget="widgetName"
- :tertiary-buttons="actionButtons"
- />
+ <div class="gl-display-flex">
+ <help-popover
+ v-if="helpPopover"
+ :options="helpPopover.options"
+ :class="{ 'gl-mr-3': actionButtons.length > 0 }"
+ >
+ <template v-if="helpPopover.content">
+ <p
+ v-if="helpPopover.content.text"
+ v-safe-html="helpPopover.content.text"
+ class="gl-mb-0"
+ ></p>
+ <gl-link
+ v-if="helpPopover.content.learnMorePath"
+ :href="helpPopover.content.learnMorePath"
+ target="_blank"
+ class="gl-font-sm"
+ >{{ $options.i18n.learnMore }}</gl-link
+ >
+ </template>
+ </help-popover>
+ <action-buttons
+ v-if="actionButtons.length > 0"
+ :widget="widgetName"
+ :tertiary-buttons="actionButtons"
+ @clickedAction="onActionClick"
+ />
+ </div>
<div
v-if="isCollapsible"
class="gl-border-l-1 gl-border-l-solid gl-border-gray-100 gl-ml-3 gl-pl-3 gl-h-6"