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/extensions/terraform/index.vue')
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.vue200
1 files changed, 200 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.vue b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.vue
new file mode 100644
index 00000000000..a6d12ed7aec
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.vue
@@ -0,0 +1,200 @@
+<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',
+ components: {
+ MrWidget,
+ },
+ props: {
+ mr: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ terraformData: {
+ collapsed: null,
+ expanded: null,
+ },
+ };
+ },
+ i18n: {
+ 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.'),
+ namedReportGenerated: s__(
+ 'Terraform|The job %{strong_start}%{name}%{strong_end} generated a report.',
+ ),
+ reportChanges: s__(
+ 'Terraform|Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete',
+ ),
+ reportFailed: s__('Terraform|A Terraform report failed to generate.'),
+ namedReportFailed: s__(
+ 'Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report.',
+ ),
+ reportErrored: s__('Terraform|Generating the report caused an error.'),
+ fullLog: __('Full log'),
+ },
+ computed: {
+ terraformReportsPath() {
+ return this.mr.terraformReportsPath;
+ },
+
+ summary() {
+ const { valid = [], invalid = [] } = this.terraformData.collapsed || {};
+
+ const validText = sprintf(
+ n__(
+ 'Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines',
+ 'Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines',
+ valid.length,
+ ),
+ {
+ number: valid.length,
+ },
+ false,
+ );
+
+ const invalidText = sprintf(
+ n__(
+ 'Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate',
+ 'Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate',
+ invalid.length,
+ ),
+ {
+ number: invalid.length,
+ },
+ false,
+ );
+
+ return {
+ title: valid.length ? validText : invalidText,
+ subtitle: valid.length && invalid.length ? invalidText : undefined,
+ };
+ },
+ },
+ methods: {
+ fetchCollapsedData() {
+ return axios
+ .get(this.terraformReportsPath)
+ .then((res) => {
+ const reports = Object.keys(res.data).map((key) => {
+ return res.data[key];
+ });
+
+ const formattedData = this.prepareReports(reports);
+
+ const { valid, invalid } = formattedData;
+ this.terraformData.collapsed = formattedData;
+ this.terraformData.expanded = [...valid, ...invalid];
+
+ return {
+ ...res,
+ data: formattedData,
+ };
+ })
+ .catch(() => {
+ const formattedData = this.prepareReports([{ tf_report_error: 'api_error' }]);
+ this.terraformData.collapsed = formattedData;
+ return { data: formattedData };
+ });
+ },
+ createReportRow(report, iconName) {
+ const addNum = Number(report.create);
+ const changeNum = Number(report.update);
+ const deleteNum = Number(report.delete);
+ const validPlanValues = addNum + changeNum + deleteNum >= 0;
+
+ const actions = [];
+
+ let title;
+ let subtitle;
+
+ if (report.job_path) {
+ const action = {
+ href: report.job_path,
+ text: this.$options.i18n.fullLog,
+ target: '_blank',
+ trackFullReportClicked: true,
+ };
+ actions.push(action);
+ }
+
+ if (validPlanValues) {
+ if (report.job_name) {
+ title = sprintf(
+ this.$options.i18n.namedReportGenerated,
+ {
+ name: report.job_name,
+ },
+ false,
+ );
+ } else {
+ title = this.$options.i18n.reportGenerated;
+ }
+
+ subtitle = sprintf(`%{small_start}${this.$options.i18n.reportChanges}%{small_end}`, {
+ addNum,
+ changeNum,
+ deleteNum,
+ });
+ } else {
+ if (report.job_name) {
+ title = sprintf(
+ this.$options.i18n.namedReportFailed,
+ {
+ name: report.job_name,
+ },
+ false,
+ );
+ } else {
+ title = this.$options.i18n.reportFailed;
+ }
+
+ subtitle = sprintf(`%{small_start}${this.$options.i18n.reportErrored}%{small_end}`);
+ }
+
+ return {
+ text: title,
+ supportingText: subtitle,
+ icon: { name: iconName },
+ actions,
+ };
+ },
+ prepareReports(reports) {
+ const valid = [];
+ const invalid = [];
+
+ reports.forEach((report) => {
+ if (report.tf_report_error) {
+ invalid.push(this.createReportRow(report, EXTENSION_ICONS.error));
+ } else {
+ valid.push(this.createReportRow(report, EXTENSION_ICONS.success));
+ }
+ });
+
+ 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>