diff options
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue')
-rw-r--r-- | app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue b/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue new file mode 100644 index 00000000000..f6e21dc1ec1 --- /dev/null +++ b/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue @@ -0,0 +1,140 @@ +<script> +import { n__ } from '~/locale'; +import { GlSkeletonLoading, GlSprintf } from '@gitlab/ui'; +import axios from '~/lib/utils/axios_utils'; +import MrWidgetExpanableSection from '../mr_widget_expandable_section.vue'; +import Poll from '~/lib/utils/poll'; +import TerraformPlan from './terraform_plan.vue'; + +export default { + name: 'MRWidgetTerraformContainer', + components: { + GlSkeletonLoading, + GlSprintf, + MrWidgetExpanableSection, + TerraformPlan, + }, + props: { + endpoint: { + type: String, + required: true, + }, + }, + data() { + return { + loading: true, + plansObject: {}, + poll: null, + }; + }, + computed: { + inValidPlanCountText() { + if (this.numberOfInvalidPlans === 0) { + return null; + } + + return n__( + 'Terraform|%{number} Terraform report failed to generate', + 'Terraform|%{number} Terraform reports failed to generate', + this.numberOfInvalidPlans, + ); + }, + numberOfInvalidPlans() { + return Object.values(this.plansObject).filter(plan => plan.tf_report_error).length; + }, + numberOfPlans() { + return Object.keys(this.plansObject).length; + }, + numberOfValidPlans() { + return this.numberOfPlans - this.numberOfInvalidPlans; + }, + validPlanCountText() { + if (this.numberOfValidPlans === 0) { + return null; + } + + return n__( + 'Terraform|%{number} Terraform report was generated in your pipelines', + 'Terraform|%{number} Terraform reports were generated in your pipelines', + this.numberOfValidPlans, + ); + }, + }, + created() { + this.fetchPlans(); + }, + beforeDestroy() { + this.poll.stop(); + }, + methods: { + fetchPlans() { + this.loading = true; + + this.poll = new Poll({ + resource: { + fetchPlans: () => axios.get(this.endpoint), + }, + data: this.endpoint, + method: 'fetchPlans', + successCallback: ({ data }) => { + this.plansObject = data; + + if (this.numberOfPlans > 0) { + this.loading = false; + this.poll.stop(); + } + }, + errorCallback: () => { + this.plansObject = { bad_plan: { tf_report_error: 'api_error' } }; + this.loading = false; + this.poll.stop(); + }, + }); + + this.poll.makeRequest(); + }, + }, +}; +</script> + +<template> + <section class="mr-widget-section"> + <div v-if="loading" class="mr-widget-body"> + <gl-skeleton-loading /> + </div> + + <mr-widget-expanable-section v-else> + <template #header> + <div + data-testid="terraform-header-text" + class="gl-flex-fill-1 gl-display-flex gl-flex-direction-column" + > + <p v-if="validPlanCountText" class="gl-m-0"> + <gl-sprintf :message="validPlanCountText"> + <template #number> + <strong>{{ numberOfValidPlans }}</strong> + </template> + </gl-sprintf> + </p> + + <p v-if="inValidPlanCountText" class="gl-m-0"> + <gl-sprintf :message="inValidPlanCountText"> + <template #number> + <strong>{{ numberOfInvalidPlans }}</strong> + </template> + </gl-sprintf> + </p> + </div> + </template> + + <template #content> + <terraform-plan + v-for="(plan, key) in plansObject" + :key="key" + :plan="plan" + class="mr-widget-body" + /> + </template> + </mr-widget-expanable-section> + </section> +</template> |