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')
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/action_buttons.vue58
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue11
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/dynamic_content.vue18
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue69
4 files changed, 94 insertions, 62 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
index c38c253564a..9dd4e76befe 100644
--- 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
@@ -19,8 +19,7 @@ export default {
},
tertiaryButtons: {
type: Array,
- required: false,
- default: () => [],
+ required: true,
},
},
data() {
@@ -76,7 +75,6 @@ export default {
<template>
<div class="gl-display-flex gl-align-items-flex-start">
<gl-dropdown
- v-if="tertiaryButtons.length"
v-gl-tooltip
:title="__('Options')"
:text="dropdownLabel"
@@ -102,33 +100,31 @@ export default {
{{ 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>
+ <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>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue
index 258fa4edcda..9bb39ba22e0 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue
@@ -5,8 +5,9 @@ export default {
import(
'~/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue'
),
-
MrTerraformWidget: () => import('~/vue_merge_request_widget/extensions/terraform/index.vue'),
+ MrCodeQualityWidget: () =>
+ import('~/vue_merge_request_widget/extensions/code_quality/index.vue'),
},
props: {
@@ -21,8 +22,14 @@ export default {
return this.mr.terraformReportsPath && 'MrTerraformWidget';
},
+ codeQualityWidget() {
+ return this.mr.codequalityReportsPath ? 'MrCodeQualityWidget' : undefined;
+ },
+
widgets() {
- return [this.terraformPlansWidget, 'MrSecurityWidget'].filter((w) => w);
+ return [this.codeQualityWidget, this.terraformPlansWidget, 'MrSecurityWidget'].filter(
+ (w) => w,
+ );
},
},
};
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 ec979861283..618d1e71f81 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
@@ -52,6 +52,9 @@ export default {
shouldShowThirdLevel() {
return this.data.children?.length > 0 && this.level === 2;
},
+ hasActionButtons() {
+ return this.data.actions?.length > 0;
+ },
},
methods: {
onClickedAction(action) {
@@ -73,15 +76,22 @@ export default {
<template #body>
<div class="gl-w-full gl-display-flex" :class="{ 'gl-flex-direction-column': level === 1 }">
<div class="gl-display-flex gl-flex-grow-1">
- <div class="gl-display-flex gl-flex-grow-1 gl-flex-direction-column">
- <p v-safe-html="generatedText" class="gl-mb-0 gl-mr-1"></p>
- <gl-link v-if="data.link" :href="data.link.href">{{ data.link.text }}</gl-link>
- <p v-if="data.supportingText" v-safe-html="generatedSupportingText" class="gl-mb-0"></p>
+ <div class="gl-display-flex gl-flex-grow-1 gl-align-items-baseline">
+ <div>
+ <p v-safe-html="generatedText" class="gl-mb-0 gl-mr-1"></p>
+ <gl-link v-if="data.link" :href="data.link.href">{{ data.link.text }}</gl-link>
+ <p
+ v-if="data.supportingText"
+ v-safe-html="generatedSupportingText"
+ class="gl-mb-0"
+ ></p>
+ </div>
<gl-badge v-if="data.badge" :variant="data.badge.variant || 'info'">
{{ data.badge.text }}
</gl-badge>
</div>
<actions
+ v-if="hasActionButtons"
:widget="widgetName"
:tertiary-buttons="data.actions"
class="gl-ml-auto gl-pl-3"
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 e327d848d8f..2c8bf90064e 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,3 +1,4 @@
+<!-- eslint-disable vue/multi-word-component-names -->
<script>
import { GlButton, GlLink, GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
@@ -16,14 +17,19 @@ 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';
const WIDGET_PREFIX = 'Widget';
const MISSING_RESPONSE_HEADERS =
'MR Widget: raesponse object should contain status and headers object. Make sure to include that in your `fetchCollapsedData` and `fetchExpandedData` functions.';
+const LOADING_STATE_COLLAPSED = 'collapsed';
+const LOADING_STATE_EXPANDED = 'expanded';
+const LOADING_STATE_STATUS_ICON = 'status_icon';
+
export default {
MISSING_RESPONSE_HEADERS,
+ LOADING_STATE_COLLAPSED,
+ LOADING_STATE_EXPANDED,
+ LOADING_STATE_STATUS_ICON,
components: {
ActionButtons,
@@ -42,20 +48,29 @@ export default {
SafeHtml,
},
props: {
- /**
- * @param {value.collapsed} Object
- * @param {value.expanded} Object
- */
- value: {
- type: Object,
- required: false,
- default: () => ({}),
- },
loadingText: {
type: String,
required: false,
default: __('Loading'),
},
+ // Use this property when you need to control the loading state from the
+ // parent component.
+ loadingState: {
+ type: String,
+ required: false,
+ default: undefined,
+ validator: (s) => {
+ if (!s) {
+ return true;
+ }
+
+ return [
+ LOADING_STATE_EXPANDED,
+ LOADING_STATE_COLLAPSED,
+ LOADING_STATE_STATUS_ICON,
+ ].includes(s);
+ },
+ },
errorText: {
type: String,
required: false,
@@ -158,7 +173,7 @@ export default {
return {
isExpandedForTheFirstTime: true,
isCollapsed: true,
- isLoading: true,
+ isLoadingCollapsedContent: true,
isLoadingExpandedContent: false,
summaryError: null,
contentError: null,
@@ -166,6 +181,12 @@ export default {
};
},
computed: {
+ isSummaryLoading() {
+ return this.isLoadingCollapsedContent || this.loadingState === LOADING_STATE_COLLAPSED;
+ },
+ shouldShowLoadingIcon() {
+ return this.isSummaryLoading || this.loadingState === LOADING_STATE_STATUS_ICON;
+ },
generatedSummary() {
return generateText(this.summary?.title || '');
},
@@ -192,7 +213,7 @@ export default {
},
immediate: true,
},
- isLoading(newValue) {
+ isLoadingCollapsedContent(newValue) {
this.$emit('is-loading', newValue);
},
},
@@ -202,18 +223,18 @@ export default {
}
},
async mounted() {
- this.isLoading = true;
+ this.isLoadingCollapsedContent = true;
this.telemetryHub?.viewed();
try {
if (this.fetchCollapsedData) {
- await this.fetch(this.fetchCollapsedData, FETCH_TYPE_COLLAPSED);
+ await this.fetch(this.fetchCollapsedData);
}
} catch {
this.summaryError = this.errorText;
}
- this.isLoading = false;
+ this.isLoadingCollapsedContent = false;
},
methods: {
onActionClick(action) {
@@ -240,7 +261,7 @@ export default {
this.contentError = null;
try {
- await this.fetch(this.fetchExpandedData, FETCH_TYPE_EXPANDED);
+ await this.fetch(this.fetchExpandedData);
} catch {
this.contentError = this.errorText;
@@ -251,7 +272,7 @@ export default {
this.isLoadingExpandedContent = false;
},
- fetch(handler, dataType) {
+ fetch(handler) {
const requests = this.multiPolling ? handler() : [handler];
const promises = requests.map((request) => {
@@ -288,9 +309,7 @@ export default {
});
});
- return Promise.all(promises).then((data) => {
- this.$emit('input', { ...this.value, [dataType]: this.multiPolling ? data : data[0] });
- });
+ return Promise.all(promises);
},
},
failedStatusIcon: EXTENSION_ICONS.failed,
@@ -306,7 +325,7 @@ export default {
<status-icon
:level="1"
:name="widgetName"
- :is-loading="isLoading"
+ :is-loading="shouldShowLoadingIcon"
:icon-name="summaryStatusIcon"
/>
<div
@@ -316,9 +335,9 @@ export default {
<div class="gl-flex-grow-1" data-testid="widget-extension-top-level-summary">
<span v-if="summaryError">{{ summaryError }}</span>
<slot v-else name="summary"
- ><div v-safe-html="isLoading ? loadingText : generatedSummary"></div>
+ ><div v-safe-html="isSummaryLoading ? loadingText : generatedSummary"></div>
<div
- v-if="!isLoading && generatedSubSummary"
+ v-if="!isSummaryLoading && generatedSubSummary"
v-safe-html="generatedSubSummary"
class="gl-font-sm gl-text-gray-700"
></div
@@ -356,7 +375,7 @@ export default {
</slot>
</div>
<div
- v-if="isCollapsible && !isLoading"
+ v-if="isCollapsible && !isSummaryLoading"
class="gl-border-l-1 gl-border-l-solid gl-border-gray-100 gl-ml-3 gl-pl-3 gl-h-6"
>
<gl-button