diff options
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js')
-rw-r--r-- | app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js new file mode 100644 index 00000000000..d32db50874c --- /dev/null +++ b/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js @@ -0,0 +1,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); + }, + }, +}; |