Commit b06b17c3 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '230413-remove-edit-dashboard-button' into 'master'

Remove project selector logic from dashboard

See merge request gitlab-org/gitlab!39631
parents cf00a6bc 92fc5fc3
...@@ -131,14 +131,14 @@ bar at the top of the page. Under **More**, select **Security**. ...@@ -131,14 +131,14 @@ bar at the top of the page. Under **More**, select **Security**.
To add projects to the dashboard: To add projects to the dashboard:
1. Click the **Edit dashboard** button on the Instance Security Dashboard page. 1. Click **Settings** in the left navigation bar.
1. Search for and add one or more projects using the **Search your projects** field. 1. Search for and add one or more projects using the **Search your projects** field.
1. Click the **Add projects** button. 1. Click the **Add projects** button.
Once added, the Security Dashboard displays the vulnerabilities found in your chosen projects' After you add projects, the Security Dashboard displays the vulnerabilities found in those projects'
default branches. default branches.
![Instance Security Dashboard with projects](img/instance_security_dashboard_with_projects_v13_2_sm.png) ![Uninitialized Instance Security Dashboard](img/instance_security_dashboard_empty_v13_3.png)
## Export vulnerabilities ## Export vulnerabilities
......
...@@ -7,12 +7,7 @@ export default { ...@@ -7,12 +7,7 @@ export default {
GlButton, GlButton,
GlLink, GlLink,
}, },
inject: ['dashboardDocumentation', 'emptyStateSvgPath'], inject: ['dashboardDocumentation', 'emptyStateSvgPath', 'instanceDashboardSettingsPath'],
methods: {
handleAddProjectsClick() {
this.$emit('handleAddProjectsClick');
},
},
}; };
</script> </script>
...@@ -32,7 +27,7 @@ export default { ...@@ -32,7 +27,7 @@ export default {
}}</gl-link> }}</gl-link>
</template> </template>
<template #actions> <template #actions>
<gl-button variant="success" @click="handleAddProjectsClick"> <gl-button variant="success" :href="instanceDashboardSettingsPath">
{{ s__('SecurityReports|Add projects') }} {{ s__('SecurityReports|Add projects') }}
</gl-button> </gl-button>
</template> </template>
......
<script> <script>
import { GlLoadingIcon, GlButton } from '@gitlab/ui';
import SecurityDashboardLayout from 'ee/security_dashboard/components/security_dashboard_layout.vue'; import SecurityDashboardLayout from 'ee/security_dashboard/components/security_dashboard_layout.vue';
import VulnerabilitySeverities from 'ee/security_dashboard/components/first_class_vulnerability_severities.vue'; import VulnerabilitySeverities from 'ee/security_dashboard/components/first_class_vulnerability_severities.vue';
import VulnerabilityChart from 'ee/security_dashboard/components/first_class_vulnerability_chart.vue'; import VulnerabilityChart from 'ee/security_dashboard/components/first_class_vulnerability_chart.vue';
import Filters from 'ee/security_dashboard/components/first_class_vulnerability_filters.vue'; import Filters from 'ee/security_dashboard/components/first_class_vulnerability_filters.vue';
import projectsQuery from 'ee/security_dashboard/graphql/get_instance_security_dashboard_projects.query.graphql'; import projectsQuery from 'ee/security_dashboard/graphql/get_instance_security_dashboard_projects.query.graphql';
import InstanceSecurityVulnerabilities from './first_class_instance_security_dashboard_vulnerabilities.vue'; import InstanceSecurityVulnerabilities from './first_class_instance_security_dashboard_vulnerabilities.vue';
import { __, s__ } from '~/locale'; import { __ } from '~/locale';
import { deprecatedCreateFlash as createFlash } from '~/flash'; import { deprecatedCreateFlash as createFlash } from '~/flash';
import ProjectManager from './first_class_project_manager/project_manager.vue';
import CsvExportButton from './csv_export_button.vue'; import CsvExportButton from './csv_export_button.vue';
import vulnerabilityHistoryQuery from '../graphql/instance_vulnerability_history.query.graphql'; import vulnerabilityHistoryQuery from '../graphql/instance_vulnerability_history.query.graphql';
import vulnerabilityGradesQuery from '../graphql/instance_vulnerability_grades.query.graphql'; import vulnerabilityGradesQuery from '../graphql/instance_vulnerability_grades.query.graphql';
...@@ -16,15 +14,12 @@ import DashboardNotConfigured from './empty_states/instance_dashboard_not_config ...@@ -16,15 +14,12 @@ import DashboardNotConfigured from './empty_states/instance_dashboard_not_config
export default { export default {
components: { components: {
ProjectManager,
CsvExportButton, CsvExportButton,
SecurityDashboardLayout, SecurityDashboardLayout,
InstanceSecurityVulnerabilities, InstanceSecurityVulnerabilities,
VulnerabilitySeverities, VulnerabilitySeverities,
VulnerabilityChart, VulnerabilityChart,
Filters, Filters,
GlLoadingIcon,
GlButton,
DashboardNotConfigured, DashboardNotConfigured,
}, },
props: { props: {
...@@ -47,49 +42,29 @@ export default { ...@@ -47,49 +42,29 @@ export default {
data() { data() {
return { return {
filters: {}, filters: {},
showProjectSelector: false,
vulnerabilityHistoryQuery, vulnerabilityHistoryQuery,
vulnerabilityGradesQuery, vulnerabilityGradesQuery,
projects: [], projects: [],
isManipulatingProjects: false,
}; };
}, },
computed: { computed: {
isLoadingProjects() { isLoadingProjects() {
return this.$apollo.queries.projects.loading; return this.$apollo.queries.projects.loading;
}, },
isUpdatingProjects() {
return this.isLoadingProjects || this.isManipulatingProjects;
},
hasProjectsData() { hasProjectsData() {
return !this.isUpdatingProjects && this.projects.length > 0; return !this.isLoadingProjects && this.projects.length > 0;
}, },
shouldShowDashboard() { shouldShowDashboard() {
return this.hasProjectsData && !this.showProjectSelector; return this.hasProjectsData;
}, },
shouldShowEmptyState() { shouldShowEmptyState() {
return !this.hasProjectsData && !this.showProjectSelector && !this.isUpdatingProjects; return !this.isLoadingProjects && this.projects.length === 0;
},
toggleButtonProps() {
return this.showProjectSelector
? {
text: s__('SecurityReports|Return to dashboard'),
}
: {
text: s__('SecurityReports|Edit dashboard'),
};
}, },
}, },
methods: { methods: {
handleFilterChange(filters) { handleFilterChange(filters) {
this.filters = filters; this.filters = filters;
}, },
toggleProjectSelector() {
this.showProjectSelector = !this.showProjectSelector;
},
handleProjectManipulation(value) {
this.isManipulatingProjects = value;
},
}, },
}; };
</script> </script>
...@@ -103,12 +78,6 @@ export default { ...@@ -103,12 +78,6 @@ export default {
v-if="shouldShowDashboard" v-if="shouldShowDashboard"
:vulnerabilities-export-endpoint="vulnerabilitiesExportEndpoint" :vulnerabilities-export-endpoint="vulnerabilitiesExportEndpoint"
/> />
<gl-button
class="page-title-controls ml-2"
:variant="toggleButtonProps.variant"
@click="toggleProjectSelector"
>{{ toggleButtonProps.text }}</gl-button
>
</header> </header>
</template> </template>
<template #sticky> <template #sticky>
...@@ -119,19 +88,7 @@ export default { ...@@ -119,19 +88,7 @@ export default {
:projects="projects" :projects="projects"
:filters="filters" :filters="filters"
/> />
<dashboard-not-configured <dashboard-not-configured v-else-if="shouldShowEmptyState" />
v-else-if="shouldShowEmptyState"
@handleAddProjectsClick="toggleProjectSelector"
/>
<div v-else class="d-flex justify-content-center">
<project-manager
v-if="showProjectSelector"
:projects="projects"
:is-manipulating-projects="isManipulatingProjects"
@handle-project-manipulation="handleProjectManipulation"
/>
<gl-loading-icon v-else size="lg" class="mt-4" />
</div>
<template #aside> <template #aside>
<template v-if="shouldShowDashboard"> <template v-if="shouldShowDashboard">
<vulnerability-chart :query="vulnerabilityHistoryQuery" class="mb-4" /> <vulnerability-chart :query="vulnerabilityHistoryQuery" class="mb-4" />
......
...@@ -27,6 +27,7 @@ export default (el, dashboardType) => { ...@@ -27,6 +27,7 @@ export default (el, dashboardType) => {
}); });
} }
const provide = {};
const props = { const props = {
hasVulnerabilities: Boolean(el.dataset.hasVulnerabilities), hasVulnerabilities: Boolean(el.dataset.hasVulnerabilities),
securityDashboardHelpPath: el.dataset.securityDashboardHelpPath, securityDashboardHelpPath: el.dataset.securityDashboardHelpPath,
...@@ -45,6 +46,7 @@ export default (el, dashboardType) => { ...@@ -45,6 +46,7 @@ export default (el, dashboardType) => {
component = FirstClassGroupSecurityDashboard; component = FirstClassGroupSecurityDashboard;
props.groupFullPath = el.dataset.groupFullPath; props.groupFullPath = el.dataset.groupFullPath;
} else if (dashboardType === DASHBOARD_TYPES.INSTANCE) { } else if (dashboardType === DASHBOARD_TYPES.INSTANCE) {
provide.instanceDashboardSettingsPath = el.dataset.instanceDashboardSettingsPath;
component = FirstClassInstanceSecurityDashboard; component = FirstClassInstanceSecurityDashboard;
} }
...@@ -62,6 +64,7 @@ export default (el, dashboardType) => { ...@@ -62,6 +64,7 @@ export default (el, dashboardType) => {
emptyStateSvgPath: el.dataset.emptyStateSvgPath, emptyStateSvgPath: el.dataset.emptyStateSvgPath,
notEnabledScannersHelpPath: el.dataset.notEnabledScannersHelpPath, notEnabledScannersHelpPath: el.dataset.notEnabledScannersHelpPath,
noPipelineRunScannersHelpPath: el.dataset.noPipelineRunScannersHelpPath, noPipelineRunScannersHelpPath: el.dataset.noPipelineRunScannersHelpPath,
...provide,
}), }),
render(createElement) { render(createElement) {
return createElement(component, { props }); return createElement(component, { props });
......
...@@ -10,6 +10,7 @@ module SecurityHelper ...@@ -10,6 +10,7 @@ module SecurityHelper
project_add_endpoint: security_projects_path, project_add_endpoint: security_projects_path,
project_list_endpoint: security_projects_path, project_list_endpoint: security_projects_path,
vulnerable_projects_endpoint: security_vulnerable_projects_path, vulnerable_projects_endpoint: security_vulnerable_projects_path,
instance_dashboard_settings_path: security_settings_dashboard_path,
vulnerability_feedback_help_path: help_page_path('user/application_security/index', anchor: 'interacting-with-the-vulnerabilities'), vulnerability_feedback_help_path: help_page_path('user/application_security/index', anchor: 'interacting-with-the-vulnerabilities'),
vulnerabilities_export_endpoint: expose_path(api_v4_security_vulnerability_exports_path) vulnerabilities_export_endpoint: expose_path(api_v4_security_vulnerability_exports_path)
} }
......
---
title: Remove project selector logic from instance security dashboard
merge_request: 39631
author:
type: changed
...@@ -4,6 +4,7 @@ import DashboardNotConfigured from 'ee/security_dashboard/components/empty_state ...@@ -4,6 +4,7 @@ import DashboardNotConfigured from 'ee/security_dashboard/components/empty_state
describe('first class instance security dashboard empty state', () => { describe('first class instance security dashboard empty state', () => {
let wrapper; let wrapper;
const instanceDashboardSettingsPath = '/path/to/dashboard/settings';
const dashboardDocumentation = '/path/to/dashboard/documentation'; const dashboardDocumentation = '/path/to/dashboard/documentation';
const emptyStateSvgPath = '/placeholder.svg'; const emptyStateSvgPath = '/placeholder.svg';
...@@ -12,6 +13,7 @@ describe('first class instance security dashboard empty state', () => { ...@@ -12,6 +13,7 @@ describe('first class instance security dashboard empty state', () => {
provide: { provide: {
dashboardDocumentation, dashboardDocumentation,
emptyStateSvgPath, emptyStateSvgPath,
instanceDashboardSettingsPath,
}, },
}); });
...@@ -36,16 +38,7 @@ describe('first class instance security dashboard empty state', () => { ...@@ -36,16 +38,7 @@ describe('first class instance security dashboard empty state', () => {
expect(findLink().attributes('href')).toBe(dashboardDocumentation); expect(findLink().attributes('href')).toBe(dashboardDocumentation);
}); });
it('contains a GlButton', () => { it('contains a GlButton with a link to settings page', () => {
expect(findButton().exists()).toBe(true); expect(findButton().attributes('href')).toBe(instanceDashboardSettingsPath);
});
it('emits `handleAddProjectsClick` on button click', async () => {
const eventName = 'handleAddProjectsClick';
findButton().trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.emitted()).toHaveProperty(eventName);
}); });
}); });
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlButton } from '@gitlab/ui';
import SecurityDashboardLayout from 'ee/security_dashboard/components/security_dashboard_layout.vue'; import SecurityDashboardLayout from 'ee/security_dashboard/components/security_dashboard_layout.vue';
import FirstClassInstanceDashboard from 'ee/security_dashboard/components/first_class_instance_security_dashboard.vue'; import FirstClassInstanceDashboard from 'ee/security_dashboard/components/first_class_instance_security_dashboard.vue';
import FirstClassInstanceVulnerabilities from 'ee/security_dashboard/components/first_class_instance_security_dashboard_vulnerabilities.vue'; import FirstClassInstanceVulnerabilities from 'ee/security_dashboard/components/first_class_instance_security_dashboard_vulnerabilities.vue';
...@@ -7,7 +6,6 @@ import VulnerabilitySeverity from 'ee/security_dashboard/components/first_class_ ...@@ -7,7 +6,6 @@ import VulnerabilitySeverity from 'ee/security_dashboard/components/first_class_
import VulnerabilityChart from 'ee/security_dashboard/components/first_class_vulnerability_chart.vue'; import VulnerabilityChart from 'ee/security_dashboard/components/first_class_vulnerability_chart.vue';
import CsvExportButton from 'ee/security_dashboard/components/csv_export_button.vue'; import CsvExportButton from 'ee/security_dashboard/components/csv_export_button.vue';
import Filters from 'ee/security_dashboard/components/first_class_vulnerability_filters.vue'; import Filters from 'ee/security_dashboard/components/first_class_vulnerability_filters.vue';
import ProjectManager from 'ee/security_dashboard/components/first_class_project_manager/project_manager.vue';
import DashboardNotConfigured from 'ee/security_dashboard/components/empty_states/instance_dashboard_not_configured.vue'; import DashboardNotConfigured from 'ee/security_dashboard/components/empty_states/instance_dashboard_not_configured.vue';
describe('First Class Instance Dashboard Component', () => { describe('First Class Instance Dashboard Component', () => {
...@@ -23,7 +21,6 @@ describe('First Class Instance Dashboard Component', () => { ...@@ -23,7 +21,6 @@ describe('First Class Instance Dashboard Component', () => {
const findVulnerabilitySeverity = () => wrapper.find(VulnerabilitySeverity); const findVulnerabilitySeverity = () => wrapper.find(VulnerabilitySeverity);
const findVulnerabilityChart = () => wrapper.find(VulnerabilityChart); const findVulnerabilityChart = () => wrapper.find(VulnerabilityChart);
const findCsvExportButton = () => wrapper.find(CsvExportButton); const findCsvExportButton = () => wrapper.find(CsvExportButton);
const findProjectManager = () => wrapper.find(ProjectManager);
const findEmptyState = () => wrapper.find(DashboardNotConfigured); const findEmptyState = () => wrapper.find(DashboardNotConfigured);
const findFilters = () => wrapper.find(Filters); const findFilters = () => wrapper.find(Filters);
...@@ -134,14 +131,6 @@ describe('First Class Instance Dashboard Component', () => { ...@@ -134,14 +131,6 @@ describe('First Class Instance Dashboard Component', () => {
it('does not display the vulnerability severity in an aside', () => { it('does not display the vulnerability severity in an aside', () => {
expect(findVulnerabilitySeverity().exists()).toBe(false); expect(findVulnerabilitySeverity().exists()).toBe(false);
}); });
it('displays the project manager when the button in empty state is clicked', () => {
expect(findProjectManager().exists()).toBe(false);
wrapper.find(GlButton).vm.$emit('click');
return wrapper.vm.$nextTick(() => {
expect(findProjectManager().exists()).toBe(true);
});
});
}); });
describe('always', () => { describe('always', () => {
...@@ -152,13 +141,5 @@ describe('First Class Instance Dashboard Component', () => { ...@@ -152,13 +141,5 @@ describe('First Class Instance Dashboard Component', () => {
it('has the security dashboard title', () => { it('has the security dashboard title', () => {
expect(wrapper.find('.page-title').text()).toBe('Security Dashboard'); expect(wrapper.find('.page-title').text()).toBe('Security Dashboard');
}); });
it('displays the project manager when the edit dashboard button is clicked', () => {
expect(findProjectManager().exists()).toBe(false);
wrapper.find(GlButton).vm.$emit('click');
return wrapper.vm.$nextTick(() => {
expect(findProjectManager().exists()).toBe(true);
});
});
}); });
}); });
...@@ -15,6 +15,7 @@ RSpec.describe SecurityHelper do ...@@ -15,6 +15,7 @@ RSpec.describe SecurityHelper do
project_add_endpoint: security_projects_path, project_add_endpoint: security_projects_path,
project_list_endpoint: security_projects_path, project_list_endpoint: security_projects_path,
vulnerable_projects_endpoint: security_vulnerable_projects_path, vulnerable_projects_endpoint: security_vulnerable_projects_path,
instance_dashboard_settings_path: security_settings_dashboard_path,
vulnerability_feedback_help_path: help_page_path('user/application_security/index', anchor: 'interacting-with-the-vulnerabilities'), vulnerability_feedback_help_path: help_page_path('user/application_security/index', anchor: 'interacting-with-the-vulnerabilities'),
vulnerabilities_export_endpoint: api_v4_security_vulnerability_exports_path vulnerabilities_export_endpoint: api_v4_security_vulnerability_exports_path
}) })
......
...@@ -21777,9 +21777,6 @@ msgstr "" ...@@ -21777,9 +21777,6 @@ msgstr ""
msgid "SecurityReports|Download Report" msgid "SecurityReports|Download Report"
msgstr "" msgstr ""
msgid "SecurityReports|Edit dashboard"
msgstr ""
msgid "SecurityReports|Either you don't have permission to view this dashboard or the dashboard has not been setup. Please check your permission settings with your administrator or check your dashboard configurations to proceed." msgid "SecurityReports|Either you don't have permission to view this dashboard or the dashboard has not been setup. Please check your permission settings with your administrator or check your dashboard configurations to proceed."
msgstr "" msgstr ""
...@@ -21837,9 +21834,6 @@ msgstr "" ...@@ -21837,9 +21834,6 @@ msgstr ""
msgid "SecurityReports|Remove project from dashboard" msgid "SecurityReports|Remove project from dashboard"
msgstr "" msgstr ""
msgid "SecurityReports|Return to dashboard"
msgstr ""
msgid "SecurityReports|Scan details" msgid "SecurityReports|Scan details"
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