summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js
blob: d32db50874c42ebe037020a009d9b9fe9d3574ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { n__, s__, sprintf } from '~/locale';
import axios from '~/lib/utils/axios_utils';
import { EXTENSION_ICONS } from '~/vue_merge_request_widget/constants';
import { SEVERITY_ICONS_EXTENSION } from '~/reports/codequality_report/constants';
import { parseCodeclimateMetrics } from '~/reports/codequality_report/store/utils/codequality_parser';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';

export default {
  name: 'WidgetCodeQuality',
  props: ['codeQuality', 'blobPath'],
  i18n: {
    label: s__('ciReport|Code Quality'),
    loading: s__('ciReport|Code Quality test metrics results are being parsed'),
    error: s__('ciReport|Code Quality failed loading results'),
  },
  expandEvent: 'i_testing_code_quality_widget_total',
  computed: {
    summary() {
      const { newErrors, resolvedErrors, errorSummary } = this.collapsedData;
      if (errorSummary.errored >= 1 && errorSummary.resolved >= 1) {
        const improvements = sprintf(
          n__(
            '%{strongOpen}%{errors}%{strongClose} point',
            '%{strongOpen}%{errors}%{strongClose} points',
            resolvedErrors.length,
          ),
          {
            errors: resolvedErrors.length,
            strongOpen: '<strong>',
            strongClose: '</strong>',
          },
          false,
        );

        const degradations = sprintf(
          n__(
            '%{strongOpen}%{errors}%{strongClose} point',
            '%{strongOpen}%{errors}%{strongClose} points',
            newErrors.length,
          ),
          { errors: newErrors.length, strongOpen: '<strong>', strongClose: '</strong>' },
          false,
        );
        return sprintf(
          s__(`ciReport|Code Quality improved on ${improvements} and degraded on ${degradations}.`),
        );
      } else if (errorSummary.resolved >= 1) {
        const improvements = n__('%d point', '%d points', resolvedErrors.length);
        return sprintf(s__(`ciReport|Code Quality improved on ${improvements}.`));
      } else if (errorSummary.errored >= 1) {
        const degradations = n__('%d point', '%d points', newErrors.length);
        return sprintf(s__(`ciReport|Code Quality degraded on ${degradations}.`));
      }
      return s__(`ciReport|No changes to Code Quality.`);
    },
    statusIcon() {
      if (this.collapsedData.errorSummary?.errored >= 1) {
        return EXTENSION_ICONS.warning;
      }
      return EXTENSION_ICONS.success;
    },
  },
  methods: {
    fetchCollapsedData() {
      return Promise.all([this.fetchReport(this.codeQuality)]).then((values) => {
        return {
          resolvedErrors: parseCodeclimateMetrics(
            values[0].resolved_errors,
            this.blobPath.head_path,
          ),
          newErrors: parseCodeclimateMetrics(values[0].new_errors, this.blobPath.head_path),
          existingErrors: parseCodeclimateMetrics(
            values[0].existing_errors,
            this.blobPath.head_path,
          ),
          errorSummary: values[0].summary,
        };
      });
    },
    fetchFullData() {
      const fullData = [];

      this.collapsedData.newErrors.map((e) => {
        return fullData.push({
          text: `${capitalizeFirstCharacter(e.severity)} - ${e.description}`,
          subtext: sprintf(
            s__(`ciReport|in %{open_link}${e.file_path}:${e.line}%{close_link}`),
            {
              open_link: `<a class="gl-text-decoration-underline" href="${e.urlPath}">`,
              close_link: '</a>',
            },
            false,
          ),
          icon: {
            name: SEVERITY_ICONS_EXTENSION[e.severity],
          },
        });
      });

      this.collapsedData.resolvedErrors.map((e) => {
        return fullData.push({
          text: `${capitalizeFirstCharacter(e.severity)} - ${e.description}`,
          subtext: sprintf(
            s__(`ciReport|in %{open_link}${e.file_path}:${e.line}%{close_link}`),
            {
              open_link: `<a class="gl-text-decoration-underline" href="${e.urlPath}">`,
              close_link: '</a>',
            },
            false,
          ),
          icon: {
            name: SEVERITY_ICONS_EXTENSION[e.severity],
          },
        });
      });

      return Promise.resolve(fullData);
    },
    fetchReport(endpoint) {
      return axios.get(endpoint).then((res) => res.data);
    },
  },
};