Commit e9dd17cd authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch '235188-add-add-panel-btn' into 'master'

Add "Add panel" item to dashboard actions menu

See merge request gitlab-org/gitlab!39194
parents 54cc5381 a1f25133
......@@ -11,6 +11,8 @@ import {
GlTooltipDirective,
} from '@gitlab/ui';
import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { PANEL_NEW_PAGE } from '../router/constants';
import DuplicateDashboardModal from './duplicate_dashboard_modal.vue';
import CreateDashboardModal from './create_dashboard_modal.vue';
import { s__ } from '~/locale';
......@@ -36,6 +38,7 @@ export default {
GlTooltip: GlTooltipDirective,
TrackEvent: TrackEventDirective,
},
mixins: [glFeatureFlagsMixin()],
props: {
addingMetricsAvailable: {
type: Boolean,
......@@ -56,6 +59,10 @@ export default {
type: String,
required: true,
},
isOotbDashboard: {
type: Boolean,
required: true,
},
},
data() {
return { customMetricsFormIsValid: null };
......@@ -72,15 +79,22 @@ export default {
},
isMenuItemEnabled() {
return {
addPanel: !this.isOotbDashboard,
createDashboard: Boolean(this.projectPath),
editDashboard: this.selectedDashboard?.can_edit,
};
},
isMenuItemShown() {
return {
addPanel: this.glFeatures.metricsDashboardNewPanelPage,
duplicateDashboard: this.isOutOfTheBoxDashboard,
};
},
newPanelPageLocation() {
// Retains params/query if any
const { params, query } = this.$route ?? {};
return { name: PANEL_NEW_PAGE, params, query };
},
},
methods: {
...mapActions('monitoringDashboard', ['toggleStarredValue']),
......@@ -117,7 +131,9 @@ export default {
starDashboard: s__('Metrics|Star dashboard'),
unstarDashboard: s__('Metrics|Unstar dashboard'),
addMetric: s__('Metrics|Add metric'),
editDashboardInfo: s__('Metrics|Duplicate this dashboard to edit dashboard YAML'),
addPanel: s__('Metrics|Add panel'),
addPanelInfo: s__('Metrics|Duplicate this dashboard to add panel or edit dashboard YAML.'),
editDashboardInfo: s__('Metrics|Duplicate this dashboard to add panel or edit dashboard YAML.'),
editDashboard: s__('Metrics|Edit dashboard YAML'),
createDashboard: s__('Metrics|Create new dashboard'),
},
......@@ -176,6 +192,32 @@ export default {
</gl-modal>
</template>
<template v-if="isMenuItemShown.addPanel">
<gl-new-dropdown-item
v-if="isMenuItemEnabled.addPanel"
data-testid="add-panel-item-enabled"
:to="newPanelPageLocation"
>
{{ $options.i18n.addPanel }}
</gl-new-dropdown-item>
<!--
wrapper for tooltip as button can be `disabled`
https://bootstrap-vue.org/docs/components/tooltip#disabled-elements
-->
<div v-else v-gl-tooltip :title="$options.i18n.addPanelInfo">
<gl-new-dropdown-item
:alt="$options.i18n.addPanelInfo"
:to="newPanelPageLocation"
data-testid="add-panel-item-disabled"
disabled
class="gl-cursor-not-allowed"
>
<span class="gl-text-gray-400">{{ $options.i18n.addPanel }}</span>
</gl-new-dropdown-item>
</div>
</template>
<gl-new-dropdown-item
v-if="isMenuItemEnabled.editDashboard"
:href="selectedDashboard ? selectedDashboard.project_blob_path : null"
......
......@@ -118,6 +118,9 @@ export default {
shouldShowSettingsButton() {
return this.canAccessOperationsSettings && this.operationsSettingsPath;
},
isOOTBDashboard() {
return this.selectedDashboard?.out_of_the_box_dashboard ?? false;
},
},
methods: {
...mapActions('monitoringDashboard', ['filterEnvironments']),
......@@ -266,6 +269,7 @@ export default {
:custom-metrics-path="customMetricsPath"
:validate-query-path="validateQueryPath"
:default-branch="defaultBranch"
:is-ootb-dashboard="isOOTBDashboard"
/>
</div>
......
......@@ -5,6 +5,7 @@ query getAnnotations(
$startingFrom: Time!
) {
project(fullPath: $projectPath) {
id
environments(name: $environmentName) {
nodes {
id
......
query getEnvironments($projectPath: ID!, $search: String, $states: [String!]) {
project(fullPath: $projectPath) {
id
data: environments(search: $search, states: $states) {
environments: nodes {
name
......
......@@ -13,12 +13,12 @@ import { DASHBOARD_PAGE, PANEL_NEW_PAGE } from './constants';
export default [
{
name: PANEL_NEW_PAGE,
path: '/:dashboard(.*)?/panel/new',
path: '/:dashboard(.+)?/panel/new',
component: PanelNewPage,
},
{
name: DASHBOARD_PAGE,
path: '/:dashboard(.*)?',
path: '/:dashboard(.+)?',
component: DashboardPage,
},
];
......@@ -15,6 +15,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
push_frontend_feature_flag(:prometheus_computed_alerts)
push_frontend_feature_flag(:disable_metric_dashboard_refresh_rate)
push_frontend_feature_flag(:alert_runbooks)
push_frontend_feature_flag(:metrics_dashboard_new_panel_page)
end
before_action :authorize_read_environment!, except: [:metrics, :additional_metrics, :metrics_dashboard, :metrics_redirect]
before_action :authorize_create_environment!, only: [:new, :create]
......
......@@ -11,6 +11,7 @@ module Projects
push_frontend_feature_flag(:prometheus_computed_alerts)
push_frontend_feature_flag(:disable_metric_dashboard_refresh_rate)
push_frontend_feature_flag(:alert_runbooks)
push_frontend_feature_flag(:metrics_dashboard_new_panel_page)
end
def show
......
......@@ -15245,7 +15245,7 @@ msgstr ""
msgid "Metrics|Duplicate dashboard"
msgstr ""
msgid "Metrics|Duplicate this dashboard to edit dashboard YAML"
msgid "Metrics|Duplicate this dashboard to add panel or edit dashboard YAML."
msgstr ""
msgid "Metrics|Duplicating..."
......
......@@ -109,6 +109,7 @@ exports[`Dashboard template matches the default snapshot 1`] = `
<actions-menu-stub
custommetricspath="/monitoring/monitor-project/prometheus/metrics"
defaultbranch="master"
isootbdashboard="true"
validatequerypath="/monitoring/monitor-project/prometheus/metrics/validate_query"
/>
</div>
......
import { shallowMount } from '@vue/test-utils';
import { GlNewDropdownItem } from '@gitlab/ui';
import { createStore } from '~/monitoring/stores';
import { DASHBOARD_PAGE, PANEL_NEW_PAGE } from '~/monitoring/router/constants';
import { setupAllDashboards, setupStoreWithData } from '../store_utils';
import { redirectTo } from '~/lib/utils/url_utility';
import Tracking from '~/tracking';
......@@ -21,6 +23,8 @@ describe('Actions menu', () => {
let wrapper;
const findAddMetricItem = () => wrapper.find('[data-testid="add-metric-item"]');
const findAddPanelItemEnabled = () => wrapper.find('[data-testid="add-panel-item-enabled"]');
const findAddPanelItemDisabled = () => wrapper.find('[data-testid="add-panel-item-disabled"]');
const findAddMetricModal = () => wrapper.find('[data-testid="add-metric-modal"]');
const findAddMetricModalSubmitButton = () =>
wrapper.find('[data-testid="add-metric-modal-submit-button"]');
......@@ -38,6 +42,9 @@ describe('Actions menu', () => {
const createShallowWrapper = (props = {}, options = {}) => {
wrapper = shallowMount(ActionsMenu, {
propsData: { ...dashboardActionsMenuProps, ...props },
provide: {
glFeatures: { metricsDashboardNewPanelPage: true },
},
store,
...options,
});
......@@ -141,6 +148,54 @@ describe('Actions menu', () => {
});
});
describe('add panel item', () => {
const GlNewDropdownItemStub = {
extends: GlNewDropdownItem,
props: {
to: [String, Object],
},
};
let $route;
beforeEach(() => {
$route = { name: DASHBOARD_PAGE, params: { dashboard: 'my_dashboard.yml' } };
createShallowWrapper(
{
isOotbDashboard: false,
},
{
mocks: { $route },
stubs: { GlNewDropdownItem: GlNewDropdownItemStub },
},
);
});
it('is disabled for ootb dashboards', () => {
createShallowWrapper({
isOotbDashboard: true,
});
return wrapper.vm.$nextTick(() => {
expect(findAddPanelItemDisabled().exists()).toBe(true);
});
});
it('is visible for custom dashboards', () => {
expect(findAddPanelItemEnabled().exists()).toBe(true);
});
it('renders a link to the new panel page for custom dashboards', () => {
expect(findAddPanelItemEnabled().props('to')).toEqual({
name: PANEL_NEW_PAGE,
params: {
dashboard: 'my_dashboard.yml',
},
});
});
});
describe('edit dashboard yml item', () => {
beforeEach(() => {
createShallowWrapper();
......
......@@ -628,4 +628,5 @@ export const dashboardActionsMenuProps = {
addingMetricsAvailable: true,
customMetricsPath: 'https://path/to/customMetrics',
validateQueryPath: 'https://path/to/validateQuery',
isOotbDashboard: true,
};
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