diff --git a/ee/app/assets/javascripts/security_dashboard/components/shared/group_risk_score_panel.vue b/ee/app/assets/javascripts/security_dashboard/components/shared/group_risk_score_panel.vue index fa3f06cd0792d906df3795349c2cefa01156d0dd..ebf298f8d810e2fd788425e231afc8a919401ff4 100644 --- a/ee/app/assets/javascripts/security_dashboard/components/shared/group_risk_score_panel.vue +++ b/ee/app/assets/javascripts/security_dashboard/components/shared/group_risk_score_panel.vue @@ -1,12 +1,18 @@ diff --git a/ee/app/assets/javascripts/security_dashboard/components/shared/security_dashboard_filtered_search/filtered_search.vue b/ee/app/assets/javascripts/security_dashboard/components/shared/security_dashboard_filtered_search/filtered_search.vue index 596b334c0819d2af461fbd8391b8196d849d8de1..34d5f93fb4bfbdcb4cbcd2e444f2bb2ed13b7966 100644 --- a/ee/app/assets/javascripts/security_dashboard/components/shared/security_dashboard_filtered_search/filtered_search.vue +++ b/ee/app/assets/javascripts/security_dashboard/components/shared/security_dashboard_filtered_search/filtered_search.vue @@ -2,6 +2,7 @@ import { nextTick } from 'vue'; import { GlFilteredSearch } from '@gitlab/ui'; import { isEqual } from 'lodash'; +import { setUrlParams, updateHistory } from '~/lib/utils/url_utility'; import { ALL_ID } from 'ee/security_dashboard/components/shared/filters/constants'; export default { @@ -26,7 +27,7 @@ export default { const { initialValue, newFilters } = this.tokens.reduce( (acc, token) => { const paramValue = params.get(token.type); - const data = paramValue?.split(',').filter(Boolean); + const data = paramValue?.split(',').filter((i) => i !== ''); if (data?.length > 0) { acc.newFilters[token.type] = data; @@ -62,17 +63,16 @@ export default { const params = this.tokens.reduce((acc, { type }) => { const filterValue = this.filters[type]; if (filterValue?.length > 0) { - acc.set(type, filterValue.join(',')); + acc[type] = filterValue.join(','); } else { - acc.delete(type); + acc[type] = undefined; } return acc; - }, new URLSearchParams(window.location.search)); + }, {}); + // Passing true for last param to make sure params are decoded + const url = setUrlParams(params, window.location.href, false, false, true); - const newUrl = params.toString() - ? `${window.location.pathname}?${params.toString()}` - : window.location.pathname; - window.history.pushState({}, '', newUrl); + updateHistory({ url, replace: true }); }, async handleTokenComplete({ type }) { // Need to wait for `this.value` to have been updated diff --git a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerabilities_over_time_panel.vue b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerabilities_over_time_panel.vue index 1ae8c4496f2dc22245d03af9831a4c9b763d0f17..3155b9c135a6823fd2c291563a9dd7100f849b0d 100644 --- a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerabilities_over_time_panel.vue +++ b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerabilities_over_time_panel.vue @@ -2,6 +2,7 @@ import ExtendedDashboardPanel from '~/vue_shared/components/customizable_dashboard/extended_dashboard_panel.vue'; import { s__ } from '~/locale'; import { formatDate, getDateInPast } from '~/lib/utils/datetime_utility'; +import { readFromUrl, writeToUrl } from 'ee/security_dashboard/utils/panel_state_url_sync'; import VulnerabilitiesOverTimeChart from 'ee/security_dashboard/components/shared/charts/open_vulnerabilities_over_time.vue'; import projectVulnerabilitiesOverTime from 'ee/security_dashboard/graphql/queries/project_vulnerabilities_over_time.query.graphql'; import groupVulnerabilitiesOverTime from 'ee/security_dashboard/graphql/queries/group_vulnerabilities_over_time.query.graphql'; @@ -16,6 +17,10 @@ const TIME_PERIODS = { NINETY_DAYS: { key: 'ninetyDays', startDays: 90, endDays: 61 }, }; +const PANEL_ID = 'vulnerabilitiesOverTime'; +const GROUP_BY_DEFAULT = 'severity'; +const TIME_PERIOD_DEFAULT = 30; + const SCOPE_CONFIG = { project: { query: projectVulnerabilitiesOverTime, @@ -56,17 +61,27 @@ export default { data() { return { fetchError: false, - groupedBy: 'severity', - selectedTimePeriod: 30, + groupedBy: readFromUrl({ + panelId: PANEL_ID, + paramName: 'groupBy', + defaultValue: GROUP_BY_DEFAULT, + }), + selectedTimePeriod: readFromUrl({ + panelId: PANEL_ID, + paramName: 'timePeriod', + defaultValue: TIME_PERIOD_DEFAULT, + }), + severity: readFromUrl({ + panelId: PANEL_ID, + paramName: 'severity', + defaultValue: [], + }), isLoading: false, chartData: { thirtyDays: [], sixtyDays: [], ninetyDays: [], }, - panelLevelFilters: { - severity: [], - }, }; }, computed: { @@ -76,7 +91,7 @@ export default { combinedFilters() { return { ...this.filters, - ...this.panelLevelFilters, + severity: this.severity, }; }, hasChartData() { @@ -93,7 +108,7 @@ export default { }, baseQueryVariables() { const baseVariables = { - severity: this.panelLevelFilters.severity, + severity: this.severity, includeBySeverity: this.groupedBy === 'severity', includeByReportType: this.groupedBy === 'reportType', fullPath: this.fullPath, @@ -121,9 +136,31 @@ export default { deep: true, immediate: true, }, - selectedTimePeriod() { + selectedTimePeriod(value) { + writeToUrl({ + panelId: PANEL_ID, + paramName: 'timePeriod', + value, + defaultValue: TIME_PERIOD_DEFAULT, + }); this.fetchChartData(); }, + groupedBy(value) { + writeToUrl({ + panelId: PANEL_ID, + paramName: 'groupBy', + value, + defaultValue: GROUP_BY_DEFAULT, + }); + }, + severity(value) { + writeToUrl({ + panelId: PANEL_ID, + paramName: 'severity', + value, + defaultValue: [], + }); + }, }, methods: { async fetchChartData() { @@ -173,7 +210,7 @@ export default { >