Commit 825efd40 authored by mfluharty's avatar mfluharty

Add code quality tab to pipeline view

Initialize vue app to display codequality report
Reuse components from codequality MR widget
parent 53ff399b
...@@ -1090,6 +1090,20 @@ button.mini-pipeline-graph-dropdown-toggle { ...@@ -1090,6 +1090,20 @@ button.mini-pipeline-graph-dropdown-toggle {
} }
} }
.codequality-report {
> .media {
padding: $gl-padding;
}
.media-body {
flex-direction: row;
}
.report-block-container {
height: auto !important;
}
}
.progress-bar.bg-primary { .progress-bar.bg-primary {
background-color: $blue-500 !important; background-color: $blue-500 !important;
} }
......
<script>
import axios from 'axios';
import reportsMixin from 'ee/vue_shared/security_reports/mixins/reports_mixin';
import { componentNames } from 'ee/reports/components/issue_body';
import ReportSection from '~/reports/components/report_section.vue';
import CodequalityIssueBody from 'ee/vue_merge_request_widget/components/codequality_issue_body.vue';
import { n__, s__, sprintf } from '~/locale';
import MergeRequestStore from 'ee/vue_merge_request_widget/stores/mr_widget_store';
export default {
name: 'CodequalityReport',
components: {
ReportSection,
CodequalityIssueBody,
},
mixins: [reportsMixin],
componentNames,
props: {
codequalityReportDownloadPath: {
type: String,
required: true,
},
blobPath: {
type: String,
required: true,
},
},
data() {
return {
issues: [],
};
},
computed: {
hasCodequalityIssues() {
return this.issues.length > 0;
},
codequalityText() {
const text = [];
const { issues } = this;
if (!issues.length) {
return s__('ciReport|No code quality issues found');
} else if (issues.length) {
return sprintf(s__('ciReport|Found %{issuesWithCount}'), {
issuesWithCount: n__('%d code quality issue', '%d code quality issues', issues.length),
});
}
return text.join('');
},
codequalityStatus() {
return this.checkReportStatus(this.isLoadingCodequality, this.loadingCodequalityFailed);
},
},
created() {
return axios.get(this.codequalityReportDownloadPath).then(res => {
this.issues = MergeRequestStore.parseCodeclimateMetrics(res.data, this.blobPath);
});
},
methods: {
translateText(type) {
return {
error: sprintf(s__('ciReport|Failed to load %{reportName} report'), {
reportName: type,
}),
loading: sprintf(s__('ciReport|Loading %{reportName} report'), {
reportName: type,
}),
};
},
},
};
</script>
<template>
<div>
<report-section
always-open
:status="codequalityStatus"
:loading-text="translateText('codeclimate').loading"
:error-text="translateText('codeclimate').error"
:success-text="codequalityText"
:unresolved-issues="issues"
:resolved-issues="[]"
:has-issues="true"
:component="$options.componentNames.CodequalityIssueBody"
class="codequality-report"
/>
</div>
</template>
// /codequality_report is an alias for show
import '../show/index';
import Vue from 'vue';
import CodequalityReportApp from 'ee/codequality_report/codequality_report.vue';
import Translate from '~/vue_shared/translate';
Vue.use(Translate);
export default () => {
const codequalityTab = document.getElementById('js-pipeline-codequality-report');
if (codequalityTab) {
const { codequalityReportDownloadPath, blobPath } = codequalityTab.dataset;
// eslint-disable-next-line no-new
new Vue({
el: codequalityTab,
components: {
CodequalityReportApp,
},
render(createElement) {
return createElement('codequality-report-app', {
props: {
codequalityReportDownloadPath,
blobPath,
},
});
},
});
}
};
...@@ -2,10 +2,12 @@ import initPipelineDetails from '~/pipelines/pipeline_details_bundle'; ...@@ -2,10 +2,12 @@ import initPipelineDetails from '~/pipelines/pipeline_details_bundle';
import initPipelines from '~/pages/projects/pipelines/init_pipelines'; import initPipelines from '~/pages/projects/pipelines/init_pipelines';
import initSecurityReport from './security_report'; import initSecurityReport from './security_report';
import initLicenseReport from './license_report'; import initLicenseReport from './license_report';
import initCodequalityReport from './codequality_report';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
initPipelines(); initPipelines();
initPipelineDetails(); initPipelineDetails();
initSecurityReport(); initSecurityReport();
initLicenseReport(); initLicenseReport();
initCodequalityReport();
}); });
...@@ -30,6 +30,10 @@ module EE ...@@ -30,6 +30,10 @@ module EE
end end
end end
end end
def codequality_report
render_show
end
end end
end end
end end
...@@ -23,3 +23,7 @@ ...@@ -23,3 +23,7 @@
license_management_settings_path: license_management_settings_path, license_management_settings_path: license_management_settings_path,
licenses_api_path: licenses_api_path, licenses_api_path: licenses_api_path,
can_manage_licenses: can?(current_user, :admin_software_license_policy, project).to_s } } can_manage_licenses: can?(current_user, :admin_software_license_policy, project).to_s } }
#js-tab-codequality.tab-pane
#js-pipeline-codequality-report{ data: { codequality_report_download_path: pipeline.downloadable_path_for_report_type(:codequality),
blob_path: project_blob_path(project, pipeline.ref) } }
...@@ -11,3 +11,7 @@ ...@@ -11,3 +11,7 @@
= link_to licenses_project_pipeline_path(project, pipeline), data: { target: '#js-tab-licenses', action: 'licenses', toggle: 'tab', qa_selector: 'licenses_tab' }, class: 'licenses-tab' do = link_to licenses_project_pipeline_path(project, pipeline), data: { target: '#js-tab-licenses', action: 'licenses', toggle: 'tab', qa_selector: 'licenses_tab' }, class: 'licenses-tab' do
= _("Licenses") = _("Licenses")
%span.badge.badge-pill.js-licenses-counter.hidden{ data: { qa_selector: 'licenses_counter' } } %span.badge.badge-pill.js-licenses-counter.hidden{ data: { qa_selector: 'licenses_counter' } }
%li.js-codequality-tab-link
= link_to codequality_report_namespace_project_pipeline_path(@project.namespace, @project, @pipeline), data: { target: '#js-tab-codequality', action: 'codequality_report', toggle: 'tab'}, class: 'codequality-tab' do
= _('Code Quality')
...@@ -154,6 +154,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do ...@@ -154,6 +154,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
member do member do
get :security get :security
get :licenses get :licenses
get :codequality_report
end end
end end
......
...@@ -68,6 +68,11 @@ msgstr "" ...@@ -68,6 +68,11 @@ msgstr ""
msgid "\"%{path}\" did not exist on \"%{ref}\"" msgid "\"%{path}\" did not exist on \"%{ref}\""
msgstr "" msgstr ""
msgid "%d code quality issue"
msgid_plural "%d code quality issues"
msgstr[0] ""
msgstr[1] ""
msgid "%d comment" msgid "%d comment"
msgid_plural "%d comments" msgid_plural "%d comments"
msgstr[0] "" msgstr[0] ""
...@@ -4832,6 +4837,9 @@ msgstr "" ...@@ -4832,6 +4837,9 @@ msgstr ""
msgid "Code Owners to the merge request changes." msgid "Code Owners to the merge request changes."
msgstr "" msgstr ""
msgid "Code Quality"
msgstr ""
msgid "Code Review" msgid "Code Review"
msgstr "" msgstr ""
...@@ -23083,6 +23091,9 @@ msgstr "" ...@@ -23083,6 +23091,9 @@ msgstr ""
msgid "ciReport|Fixed:" msgid "ciReport|Fixed:"
msgstr "" msgstr ""
msgid "ciReport|Found %{issuesWithCount}"
msgstr ""
msgid "ciReport|Investigate this vulnerability by creating an issue" msgid "ciReport|Investigate this vulnerability by creating an issue"
msgstr "" msgstr ""
...@@ -23101,6 +23112,9 @@ msgstr "" ...@@ -23101,6 +23112,9 @@ msgstr ""
msgid "ciReport|No changes to performance metrics" msgid "ciReport|No changes to performance metrics"
msgstr "" msgstr ""
msgid "ciReport|No code quality issues found"
msgstr ""
msgid "ciReport|Performance metrics" msgid "ciReport|Performance metrics"
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment