Commit b842d10a authored by Andrei Stoicescu's avatar Andrei Stoicescu

Add metrics settings button to dashboard header

 - add button
 - refactor dashboard header
parent df90c6e4
......@@ -2,6 +2,7 @@
import { debounce } from 'lodash';
import { mapActions, mapState, mapGetters } from 'vuex';
import {
GlButton,
GlIcon,
GlDeprecatedButton,
GlDropdown,
......@@ -37,6 +38,7 @@ import { timezones } from '../format_date';
export default {
components: {
Icon,
GlButton,
GlIcon,
GlDeprecatedButton,
GlDropdown,
......@@ -123,6 +125,8 @@ export default {
'showEmptyState',
'dashboardTimezone',
'projectPath',
'canAccessOperationsSettings',
'operationsSettingsPath',
]),
...mapGetters('monitoringDashboard', ['selectedDashboard', 'filteredEnvironments']),
isSystemDashboard() {
......@@ -150,6 +154,9 @@ export default {
shouldShowActionsMenu() {
return Boolean(this.projectPath);
},
shouldShowSettingsButton() {
return this.canAccessOperationsSettings && this.operationsSettingsPath;
},
},
methods: {
...mapActions('monitoringDashboard', ['filterEnvironments', 'toggleStarredValue']),
......@@ -381,44 +388,57 @@ export default {
</gl-deprecated-button>
</div>
<template v-if="shouldShowActionsMenu">
<span aria-hidden="true" class="gl-pl-3 border-left gl-mb-3 d-none d-sm-block"></span>
<!-- This separator should be displayed only if at least one of the action menu or settings button are displayed -->
<span
v-if="shouldShowActionsMenu || shouldShowSettingsButton"
aria-hidden="true"
class="gl-pl-3 border-left gl-mb-3 d-none d-sm-block"
></span>
<div class="gl-mb-3 gl-mr-3 d-flex d-sm-block">
<gl-new-dropdown
v-gl-tooltip
right
class="gl-flex-grow-1"
data-testid="actions-menu"
:title="s__('Metrics|Create dashboard')"
:icon="'plus-square'"
<div v-if="shouldShowActionsMenu" class="gl-mb-3 gl-mr-3 d-flex d-sm-block">
<gl-new-dropdown
v-gl-tooltip
right
class="gl-flex-grow-1"
data-testid="actions-menu"
:title="s__('Metrics|Create dashboard')"
:icon="'plus-square'"
>
<gl-new-dropdown-item
v-gl-modal="$options.modalIds.createDashboard"
data-testid="action-create-dashboard"
>{{ s__('Metrics|Create new dashboard') }}</gl-new-dropdown-item
>
<create-dashboard-modal
data-testid="create-dashboard-modal"
:add-dashboard-documentation-path="addDashboardDocumentationPath"
:modal-id="$options.modalIds.createDashboard"
:project-path="projectPath"
/>
<template v-if="isSystemDashboard">
<gl-new-dropdown-divider />
<gl-new-dropdown-item
v-gl-modal="$options.modalIds.createDashboard"
data-testid="action-create-dashboard"
>{{ s__('Metrics|Create new dashboard') }}</gl-new-dropdown-item
ref="duplicateDashboardItem"
v-gl-modal="$options.modalIds.duplicateDashboard"
data-testid="action-duplicate-dashboard"
>
{{ s__('Metrics|Duplicate current dashboard') }}
</gl-new-dropdown-item>
</template>
</gl-new-dropdown>
</div>
<create-dashboard-modal
data-testid="create-dashboard-modal"
:add-dashboard-documentation-path="addDashboardDocumentationPath"
:modal-id="$options.modalIds.createDashboard"
:project-path="projectPath"
/>
<template v-if="isSystemDashboard">
<gl-new-dropdown-divider />
<gl-new-dropdown-item
ref="duplicateDashboardItem"
v-gl-modal="$options.modalIds.duplicateDashboard"
data-testid="action-duplicate-dashboard"
>
{{ s__('Metrics|Duplicate current dashboard') }}
</gl-new-dropdown-item>
</template>
</gl-new-dropdown>
</div>
</template>
<div v-if="shouldShowSettingsButton" class="mb-2 mr-2 d-flex d-sm-block">
<gl-button
v-gl-tooltip
data-testid="metrics-settings-button"
icon="settings"
:href="operationsSettingsPath"
:title="s__('Metrics|Metrics Settings')"
/>
</div>
</div>
<duplicate-dashboard-modal
:default-branch="defaultBranch"
......
......@@ -64,8 +64,16 @@ export default () => ({
// GitLab paths to other pages
projectPath: null,
operationsSettingsPath: '',
logsPath: invalidUrl,
// static paths
customDashboardBasePath: '',
// current user data
/**
* Flag that denotes if the currently logged user can access
* the project Settings -> Operations
*/
canAccessOperationsSettings: false,
});
......@@ -25,6 +25,8 @@ export const stateAndPropsFromDataset = (dataset = {}) => {
dashboardEndpoint,
dashboardsEndpoint,
dashboardTimezone,
canAccessOperationsSettings,
operationsSettingsPath,
projectPath,
logsPath,
currentEnvironmentName,
......@@ -44,6 +46,8 @@ export const stateAndPropsFromDataset = (dataset = {}) => {
dashboardEndpoint,
dashboardsEndpoint,
dashboardTimezone,
canAccessOperationsSettings,
operationsSettingsPath,
projectPath,
logsPath,
currentEnvironmentName,
......
......@@ -84,8 +84,9 @@ module EnvironmentsHelper
'metrics-endpoint' => additional_metrics_project_environment_path(project, environment, format: :json),
'dashboard-endpoint' => metrics_dashboard_project_environment_path(project, environment, format: :json),
'deployments-endpoint' => project_environment_deployments_path(project, environment, format: :json),
'alerts-endpoint' => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json)
'alerts-endpoint' => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json),
'operations-settings-path' => project_settings_operations_path(project),
'can-access-operations-settings' => can?(current_user, :admin_operations, project).to_s
}
end
......
---
title: Add a metrics settings button to the dashboard header
merge_request: 35848
author:
type: added
......@@ -8,6 +8,10 @@ RSpec.describe EnvironmentsHelper do
let(:user) { create(:user) }
describe '#metrics_data' do
before do
allow(helper).to receive(:can?).and_return(false)
end
subject { helper.metrics_data(project, environment) }
context 'user has all accesses' do
......
......@@ -14577,6 +14577,9 @@ msgstr ""
msgid "Metrics|Max"
msgstr ""
msgid "Metrics|Metrics Settings"
msgstr ""
msgid "Metrics|Min"
msgstr ""
......
......@@ -129,6 +129,10 @@ exports[`Dashboard template matches the default snapshot 1`] = `
<!---->
<!---->
<!---->
<!---->
</div>
<duplicate-dashboard-modal-stub
......
......@@ -157,4 +157,52 @@ describe('Dashboard header', () => {
});
});
});
describe('metrics settings button', () => {
const findSettingsButton = () => wrapper.find('[data-testid="metrics-settings-button"]');
const url = 'https://path/to/project/settings';
beforeEach(() => {
createShallowWrapper();
store.state.monitoringDashboard.canAccessOperationsSettings = false;
store.state.monitoringDashboard.operationsSettingsPath = '';
});
it('is rendered when the user can access the project settings and path to settings is available', () => {
store.state.monitoringDashboard.canAccessOperationsSettings = true;
store.state.monitoringDashboard.operationsSettingsPath = url;
return wrapper.vm.$nextTick(() => {
expect(findSettingsButton().exists()).toBe(true);
});
});
it('is not rendered when the user can not access the project settings', () => {
store.state.monitoringDashboard.canAccessOperationsSettings = false;
store.state.monitoringDashboard.operationsSettingsPath = url;
return wrapper.vm.$nextTick(() => {
expect(findSettingsButton().exists()).toBe(false);
});
});
it('is not rendered when the path to settings is unavailable', () => {
store.state.monitoringDashboard.canAccessOperationsSettings = false;
store.state.monitoringDashboard.operationsSettingsPath = '';
return wrapper.vm.$nextTick(() => {
expect(findSettingsButton().exists()).toBe(false);
});
});
it('leads to the project settings page', () => {
store.state.monitoringDashboard.canAccessOperationsSettings = true;
store.state.monitoringDashboard.operationsSettingsPath = url;
return wrapper.vm.$nextTick(() => {
expect(findSettingsButton().attributes('href')).toBe(url);
});
});
});
});
......@@ -42,10 +42,26 @@ RSpec.describe EnvironmentsHelper do
'custom-metrics-available' => 'true',
'alerts-endpoint' => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json),
'prometheus-alerts-available' => 'true',
'custom-dashboard-base-path' => Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT
'custom-dashboard-base-path' => Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT,
'operations-settings-path' => project_settings_operations_path(project),
'can-access-operations-settings' => 'true'
)
end
context 'without admin_operations permission' do
before do
allow(helper).to receive(:can?)
.with(user, :admin_operations, project)
.and_return(false)
end
specify do
expect(metrics_data).to include(
'can-access-operations-settings' => 'false'
)
end
end
context 'without read_prometheus_alerts permission' do
before do
allow(helper).to receive(:can?)
......
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