Render dynamic content
What does this MR do and why?
This MR adds support for dynamic data rendering. It takes an object as defined in https://docs.gitlab.com/ee/development/fe_guide/merge_request_widget_extensions.html#data-structure and renders it using widget components.
Screenshots or screen recordings
How to set up and validate locally
Requirements:
- You'll need an EE License
- You'll need to have runners enabled (See $2408961 for setting up a runner)
Enable :refactor_security_extension
to turn this feature on.
echo "Feature.enable(:refactor_security_extension)" | rails c
Populate findings
- Import https://gitlab.com/gitlab-examples/security/security-reports
- Create a new MR by editing a file
- This will trigger a new pipeline and you should see in the MR a list of findings.
Note: If the runner that was previously working is not working anymore, simply go to /admin/runners and remove that runner and register a new one.
Finally use the following diff to simulate a case where the dynamic content is generated:
diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue b/ee/app/assets/javascripts/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue
index 7636fcf3975..9f97cb26862 100644
--- a/ee/app/assets/javascripts/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue
+++ b/ee/app/assets/javascripts/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue
@@ -1,7 +1,11 @@
<script>
import axios from '~/lib/utils/axios_utils';
+import { SEVERITY_LEVELS } from 'ee/security_dashboard/store/constants';
+import { __ } from '~/locale';
import MrWidget from '~/vue_merge_request_widget/components/widget/widget.vue';
+import { EXTENSION_ICONS } from '~/vue_merge_request_widget/constants';
import { CRITICAL, HIGH } from '~/vulnerabilities/constants';
+import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
import SummaryText from './summary_text.vue';
import SummaryHighlights from './summary_highlights.vue';
import i18n from './i18n';
@@ -30,6 +34,20 @@ export default {
};
},
computed: {
+ dynamicContent() {
+ return this.vulnerabilities.collapsed?.map((data) => ({
+ id: data.reportType,
+ text: __(`${data.reportType} detected xyz vulnerabilities`),
+ icon: {
+ name: data.added?.length ? EXTENSION_ICONS.warning : EXTENSION_ICONS.success,
+ },
+ children: [
+ ...this.listVulnerabilities(data.added, this.$options.i18n.new),
+ ...this.listVulnerabilities(data.fixed, this.$options.i18n.fixed),
+ ],
+ }));
+ },
+
isCollapsible() {
if (!this.vulnerabilities.collapsed) {
return false;
@@ -94,12 +112,26 @@ export default {
},
},
methods: {
- handleIsLoading(value) {
- this.isLoading = value;
+ listVulnerabilities(vulns, header) {
+ if (!vulns?.length) {
+ return [];
+ }
+
+ return [
+ {
+ text: `<b class="gl-display-inline-block">${header}</b>`,
+ },
+ ...vulns.map((vuln) => ({
+ text: `${SEVERITY_LEVELS[vuln.severity]} ${vuln.name}`,
+ icon: {
+ name: EXTENSION_ICONS[`severity${capitalizeFirstCharacter(vuln.severity)}`],
+ },
+ })),
+ ];
},
- fetchExpandedData() {
- return this.fetchCollapsedData();
+ handleIsLoading(value) {
+ this.isLoading = value;
},
fetchCollapsedData() {
@@ -127,9 +159,9 @@ export default {
v-model="vulnerabilities"
:error-text="$options.i18n.error"
:fetch-collapsed-data="fetchCollapsedData"
- :fetch-expanded-data="fetchExpandedData"
:status-icon-name="statusIconName"
:widget-name="$options.name"
+ :content="dynamicContent"
:is-collapsible="isCollapsible"
multi-polling
@is-loading="handleIsLoading"
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Related to #368592 (closed)
Edited by Savas Vedova