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-06-22 15:10:55 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-06-22 15:10:55 +0300
commita27c21b5af4f60ff11706f85289065272c616a0c (patch)
tree73ac1a10bfe1bd6a4c486f58fb663b262580627b /app/assets/javascripts/vue_merge_request_widget
parent0b54de365bc766260093c9584c7470aff96d14fd (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget')
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/action_buttons.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/dynamic_content.vue32
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue37
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue5
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.vue (renamed from app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js)77
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue14
7 files changed, 113 insertions, 64 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 6655af92a55..c38c253564a 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
@@ -23,7 +23,7 @@ export default {
default: () => [],
},
},
- data: () => {
+ data() {
return {
timeout: null,
updatingTooltip: false,
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 334fc01c9f7..258fa4edcda 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,16 +5,24 @@ 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'),
},
+
props: {
mr: {
type: Object,
required: true,
},
},
+
computed: {
+ terraformPlansWidget() {
+ return this.mr.terraformReportsPath && 'MrTerraformWidget';
+ },
+
widgets() {
- return ['MrSecurityWidget'];
+ return [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 cdce7c6625a..ec979861283 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
@@ -30,6 +30,11 @@ export default {
required: false,
default: 2,
},
+ rowIndex: {
+ type: Number,
+ required: false,
+ default: -1,
+ },
},
computed: {
statusIcon() {
@@ -44,6 +49,9 @@ export default {
generatedSupportingText() {
return generateText(this.data.supportingText);
},
+ shouldShowThirdLevel() {
+ return this.data.children?.length > 0 && this.level === 2;
+ },
},
methods: {
onClickedAction(action) {
@@ -60,16 +68,19 @@ export default {
:widget-name="widgetName"
:header="data.header"
:help-popover="data.helpPopover"
+ :class="{ 'gl-border-top-0': rowIndex === 0 }"
>
<template #body>
- <div class="gl-display-flex gl-flex-direction-column">
- <div>
- <p v-safe-html="generatedText" class="gl-mb-0"></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>
- <gl-badge v-if="data.badge" :variant="data.badge.variant || 'info'">
- {{ data.badge.text }}
- </gl-badge>
+ <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>
+ <gl-badge v-if="data.badge" :variant="data.badge.variant || 'info'">
+ {{ data.badge.text }}
+ </gl-badge>
+ </div>
<actions
:widget="widgetName"
:tertiary-buttons="data.actions"
@@ -78,10 +89,7 @@ export default {
/>
<p v-if="data.subtext" v-safe-html="generatedSubtext" class="gl-m-0 gl-font-sm"></p>
</div>
- <ul
- v-if="data.children && data.children.length > 0 && level === 2"
- class="gl-m-0 gl-p-0 gl-list-style-none"
- >
+ <ul v-if="shouldShowThirdLevel" class="gl-m-0 gl-p-0 gl-list-style-none">
<li v-for="(childData, index) in data.children" :key="childData.id || index">
<dynamic-content
:data="childData"
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 54eb15c8ac8..e327d848d8f 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
@@ -10,6 +10,7 @@ import HelpPopover from '~/vue_shared/components/help_popover.vue';
import { DynamicScroller, DynamicScrollerItem } from 'vendor/vue-virtual-scroller';
import { EXTENSION_ICONS } from '../../constants';
import { createTelemetryHub } from '../extensions/telemetry';
+import { generateText } from '../extensions/utils';
import ContentRow from './widget_content_row.vue';
import DynamicContent from './dynamic_content.vue';
import StatusIcon from './status_icon.vue';
@@ -72,9 +73,12 @@ export default {
},
// If the summary slot is not used, this value will be used as a fallback.
summary: {
- type: String,
+ type: Object,
required: false,
default: undefined,
+ validator: (s) => {
+ return Boolean(s.title);
+ },
},
// If the content slot is not used, this value will be used as a fallback.
content: {
@@ -154,7 +158,7 @@ export default {
return {
isExpandedForTheFirstTime: true,
isCollapsed: true,
- isLoading: false,
+ isLoading: true,
isLoadingExpandedContent: false,
summaryError: null,
contentError: null,
@@ -162,6 +166,12 @@ export default {
};
},
computed: {
+ generatedSummary() {
+ return generateText(this.summary?.title || '');
+ },
+ generatedSubSummary() {
+ return generateText(this.summary?.subtitle || '');
+ },
collapseButtonLabel() {
return sprintf(this.isCollapsed ? __('Show details') : __('Hide details'));
},
@@ -171,6 +181,9 @@ export default {
hasActionButtons() {
return this.actionButtons.length > 0 || Boolean(this.$scopedSlots['action-buttons']);
},
+ contentWithKeyField() {
+ return this.content?.map((item, index) => ({ ...item, id: item.id || index }));
+ },
},
watch: {
hasError: {
@@ -289,7 +302,7 @@ export default {
<template>
<section class="media-section" data-testid="widget-extension">
- <div class="gl-px-5 gl-pr-4 gl-py-4 gl-align-items-center gl-display-flex">
+ <div class="gl-px-5 gl-pr-4 gl-py-4 gl-display-flex">
<status-icon
:level="1"
:name="widgetName"
@@ -302,7 +315,14 @@ 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">{{ isLoading ? loadingText : summary }}</slot>
+ <slot v-else name="summary"
+ ><div v-safe-html="isLoading ? loadingText : generatedSummary"></div>
+ <div
+ v-if="!isLoading && generatedSubSummary"
+ v-safe-html="generatedSubSummary"
+ class="gl-font-sm gl-text-gray-700"
+ ></div
+ ></slot>
</div>
<div class="gl-display-flex">
<help-popover
@@ -336,7 +356,7 @@ export default {
</slot>
</div>
<div
- v-if="isCollapsible"
+ v-if="isCollapsible && !isLoading"
class="gl-border-l-1 gl-border-l-solid gl-border-gray-100 gl-ml-3 gl-pl-3 gl-h-6"
>
<gl-button
@@ -376,8 +396,8 @@ export default {
<div v-else class="gl-w-full">
<slot name="content">
<dynamic-scroller
- v-if="content"
- :items="content"
+ v-if="contentWithKeyField"
+ :items="contentWithKeyField"
:min-item-size="32"
:style="{ maxHeight: '170px' }"
data-testid="dynamic-content-scroller"
@@ -390,6 +410,9 @@ export default {
:data="item"
:widget-name="widgetName"
:level="2"
+ :row-index="index"
+ data-testid="extension-list-item"
+ @clickedAction="onActionClick"
/>
</dynamic-scroller-item>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue b/app/assets/javascripts/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue
index 6155a912683..e7d8de97f20 100644
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue
@@ -73,6 +73,9 @@ export default {
hasSecurityReports() {
return this.artifacts.length > 0;
},
+ summary() {
+ return { title: this.$options.i18n.scansHaveRun };
+ },
},
methods: {
handleIsLoading(value) {
@@ -109,7 +112,7 @@ export default {
:widget-name="$options.name"
:is-collapsible="false"
:help-popover="$options.widgetHelpPopover"
- :summary="$options.i18n.scansHaveRun"
+ :summary="summary"
@is-loading="handleIsLoading"
>
<template #action-buttons>
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.vue
index c5cbed4a280..a6d12ed7aec 100644
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.vue
@@ -1,12 +1,29 @@
+<script>
import { __, n__, s__, sprintf } from '~/locale';
import axios from '~/lib/utils/axios_utils';
+import MrWidget from '~/vue_merge_request_widget/components/widget/widget.vue';
import { EXTENSION_ICONS } from '../../constants';
export default {
name: 'WidgetTerraform',
- enablePolling: true,
+ components: {
+ MrWidget,
+ },
+ props: {
+ mr: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ terraformData: {
+ collapsed: null,
+ expanded: null,
+ },
+ };
+ },
i18n: {
- label: s__('Terraform|Terraform reports'),
loading: s__('Terraform|Loading Terraform reports...'),
error: s__('Terraform|Failed to load Terraform reports'),
reportGenerated: s__('Terraform|A Terraform report was generated in your pipelines.'),
@@ -23,18 +40,13 @@ export default {
reportErrored: s__('Terraform|Generating the report caused an error.'),
fullLog: __('Full log'),
},
- props: ['terraformReportsPath'],
computed: {
- // Extension computed props
- statusIcon() {
- return EXTENSION_ICONS.warning;
+ terraformReportsPath() {
+ return this.mr.terraformReportsPath;
},
- },
- methods: {
- // Extension methods
- summary({ valid = [], invalid = [] }) {
- let title;
- let subtitle = '';
+
+ summary() {
+ const { valid = [], invalid = [] } = this.terraformData.collapsed || {};
const validText = sprintf(
n__(
@@ -60,20 +72,13 @@ export default {
false,
);
- if (valid.length) {
- title = validText;
- if (invalid.length) {
- subtitle = invalidText;
- }
- } else {
- title = invalidText;
- }
-
return {
- subject: title,
- meta: subtitle,
+ title: valid.length ? validText : invalidText,
+ subtitle: valid.length && invalid.length ? invalidText : undefined,
};
},
+ },
+ methods: {
fetchCollapsedData() {
return axios
.get(this.terraformReportsPath)
@@ -84,6 +89,10 @@ export default {
const formattedData = this.prepareReports(reports);
+ const { valid, invalid } = formattedData;
+ this.terraformData.collapsed = formattedData;
+ this.terraformData.expanded = [...valid, ...invalid];
+
return {
...res,
data: formattedData,
@@ -91,14 +100,10 @@ export default {
})
.catch(() => {
const formattedData = this.prepareReports([{ tf_report_error: 'api_error' }]);
-
+ this.terraformData.collapsed = formattedData;
return { data: formattedData };
});
},
- fetchFullData() {
- const { valid, invalid } = this.collapsedData;
- return Promise.resolve([...valid, ...invalid]);
- },
createReportRow(report, iconName) {
const addNum = Number(report.create);
const changeNum = Number(report.update);
@@ -176,4 +181,20 @@ export default {
return { valid, invalid };
},
},
+
+ WARNING_ICON: EXTENSION_ICONS.warning,
};
+</script>
+
+<template>
+ <mr-widget
+ :error-text="$options.i18n.error"
+ :status-icon-name="$options.WARNING_ICON"
+ :loading-text="$options.i18n.loading"
+ :widget-name="$options.name"
+ :is-collapsible="Boolean(terraformData.collapsed)"
+ :summary="summary"
+ :content="terraformData.expanded"
+ :fetch-collapsed-data="fetchCollapsedData"
+ />
+</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index af9e303594a..9baa2ed15d6 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -55,7 +55,6 @@ import eventHub from './event_hub';
import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variables';
import getStateQuery from './queries/get_state.query.graphql';
import getStateSubscription from './queries/get_state.subscription.graphql';
-import terraformExtension from './extensions/terraform';
import accessibilityExtension from './extensions/accessibility';
import codeQualityExtension from './extensions/code_quality';
import testReportExtension from './extensions/test_report';
@@ -238,9 +237,6 @@ export default {
this.mr.mergePipelinesEnabled && this.mr.sourceProjectId !== this.mr.targetProjectId,
);
},
- shouldRenderTerraformPlans() {
- return Boolean(this.mr?.terraformReportsPath);
- },
shouldRenderTestReport() {
return Boolean(this.mr?.testResultsPath);
},
@@ -292,11 +288,6 @@ export default {
this.initPostMergeDeploymentsPolling();
}
},
- shouldRenderTerraformPlans(newVal) {
- if (newVal) {
- this.registerTerraformPlans();
- }
- },
shouldRenderCodeQuality(newVal) {
if (newVal) {
this.registerCodeQualityExtension();
@@ -546,11 +537,6 @@ export default {
dismissSuggestPipelines() {
this.mr.isDismissedSuggestPipeline = true;
},
- registerTerraformPlans() {
- if (this.shouldRenderTerraformPlans) {
- registerExtension(terraformExtension);
- }
- },
registerAccessibilityExtension() {
if (this.shouldShowAccessibilityReport) {
registerExtension(accessibilityExtension);