Commit b13cd673 authored by Reuben Pereira's avatar Reuben Pereira Committed by Phil Hughes

Always display environment selector

On the metrics dashboard, always display the environment selector,
even if there is no data to display for that environment. This allows
the user to switch to the metrics dashboard of another environment.
parent 5b97ea3e
...@@ -234,7 +234,7 @@ export default { ...@@ -234,7 +234,7 @@ export default {
</script> </script>
<template> <template>
<div v-if="!showEmptyState" class="prometheus-graphs"> <div class="prometheus-graphs">
<div class="gl-p-3 border-bottom bg-gray-light d-flex justify-content-between"> <div class="gl-p-3 border-bottom bg-gray-light d-flex justify-content-between">
<div <div
v-if="environmentsEndpoint" v-if="environmentsEndpoint"
...@@ -253,11 +253,12 @@ export default { ...@@ -253,11 +253,12 @@ export default {
:key="environment.id" :key="environment.id"
:active="environment.name === currentEnvironmentName" :active="environment.name === currentEnvironmentName"
active-class="is-active" active-class="is-active"
:href="environment.metrics_path"
>{{ environment.name }}</gl-dropdown-item >{{ environment.name }}</gl-dropdown-item
> >
</gl-dropdown> </gl-dropdown>
</div> </div>
<div class="d-flex align-items-center prepend-left-8"> <div v-if="!showEmptyState" class="d-flex align-items-center prepend-left-8">
<strong>{{ s__('Metrics|Show last') }}</strong> <strong>{{ s__('Metrics|Show last') }}</strong>
<gl-dropdown <gl-dropdown
class="prepend-left-10 js-time-window-dropdown" class="prepend-left-10 js-time-window-dropdown"
...@@ -276,7 +277,7 @@ export default { ...@@ -276,7 +277,7 @@ export default {
</div> </div>
</div> </div>
<div class="d-flex"> <div class="d-flex">
<div v-if="isEE && canAddMetrics"> <div v-if="isEE && canAddMetrics && !showEmptyState">
<gl-button <gl-button
v-gl-modal-directive="$options.addMetric.modalId" v-gl-modal-directive="$options.addMetric.modalId"
class="js-add-metric-button text-success border-success" class="js-add-metric-button text-success border-success"
...@@ -317,40 +318,42 @@ export default { ...@@ -317,40 +318,42 @@ export default {
</gl-button> </gl-button>
</div> </div>
</div> </div>
<graph-group <div v-if="!showEmptyState">
v-for="(groupData, index) in groupsWithData" <graph-group
:key="index" v-for="(groupData, index) in groupsWithData"
:name="groupData.group" :key="index"
:show-panels="showPanels" :name="groupData.group"
> :show-panels="showPanels"
<monitor-area-chart
v-for="(graphData, graphIndex) in chartsWithData(groupData.metrics)"
:key="graphIndex"
:graph-data="graphData"
:deployment-data="deploymentData"
:thresholds="getGraphAlertValues(graphData.queries)"
:container-width="elWidth"
group-id="monitor-area-chart"
> >
<alert-widget <monitor-area-chart
v-if="isEE && prometheusAlertsAvailable && alertsEndpoint && graphData" v-for="(graphData, graphIndex) in chartsWithData(groupData.metrics)"
:alerts-endpoint="alertsEndpoint" :key="graphIndex"
:relevant-queries="graphData.queries" :graph-data="graphData"
:alerts-to-manage="getGraphAlerts(graphData.queries)" :deployment-data="deploymentData"
@setAlerts="setAlerts" :thresholds="getGraphAlertValues(graphData.queries)"
/> :container-width="elWidth"
</monitor-area-chart> group-id="monitor-area-chart"
</graph-group> >
<alert-widget
v-if="isEE && prometheusAlertsAvailable && alertsEndpoint && graphData"
:alerts-endpoint="alertsEndpoint"
:relevant-queries="graphData.queries"
:alerts-to-manage="getGraphAlerts(graphData.queries)"
@setAlerts="setAlerts"
/>
</monitor-area-chart>
</graph-group>
</div>
<empty-state
v-else
:selected-state="emptyState"
:documentation-path="documentationPath"
:settings-path="settingsPath"
:clusters-path="clustersPath"
:empty-getting-started-svg-path="emptyGettingStartedSvgPath"
:empty-loading-svg-path="emptyLoadingSvgPath"
:empty-no-data-svg-path="emptyNoDataSvgPath"
:empty-unable-to-connect-svg-path="emptyUnableToConnectSvgPath"
/>
</div> </div>
<empty-state
v-else
:selected-state="emptyState"
:documentation-path="documentationPath"
:settings-path="settingsPath"
:clusters-path="clustersPath"
:empty-getting-started-svg-path="emptyGettingStartedSvgPath"
:empty-loading-svg-path="emptyLoadingSvgPath"
:empty-no-data-svg-path="emptyNoDataSvgPath"
:empty-unable-to-connect-svg-path="emptyUnableToConnectSvgPath"
/>
</template> </template>
---
title: Fix broken environment selector and always display it on monitoring dashboard
merge_request: 29705
author:
type: fixed
...@@ -9,11 +9,11 @@ describe 'Environment > Metrics' do ...@@ -9,11 +9,11 @@ describe 'Environment > Metrics' do
let(:build) { create(:ci_build, pipeline: pipeline) } let(:build) { create(:ci_build, pipeline: pipeline) }
let(:environment) { create(:environment, project: project) } let(:environment) { create(:environment, project: project) }
let(:current_time) { Time.now.utc } let(:current_time) { Time.now.utc }
let!(:staging) { create(:environment, name: 'staging', project: project) }
before do before do
project.add_developer(user) project.add_developer(user)
create(:deployment, environment: environment, deployable: build) stub_any_prometheus_request
stub_all_prometheus_requests(environment.slug)
sign_in(user) sign_in(user)
visit_environment(environment) visit_environment(environment)
...@@ -23,15 +23,50 @@ describe 'Environment > Metrics' do ...@@ -23,15 +23,50 @@ describe 'Environment > Metrics' do
Timecop.freeze(current_time) { example.run } Timecop.freeze(current_time) { example.run }
end end
shared_examples 'has environment selector' do
it 'has a working environment selector', :js do
click_link('See metrics')
expect(page).to have_metrics_path(environment)
expect(page).to have_css('div.js-environments-dropdown')
within('div.js-environments-dropdown') do
# Click on the dropdown
click_on(environment.name)
# Select the staging environment
click_on(staging.name)
end
expect(page).to have_metrics_path(staging)
wait_for_requests
end
end
context 'without deployments' do
it_behaves_like 'has environment selector'
end
context 'with deployments and related deployable present' do context 'with deployments and related deployable present' do
before do
create(:deployment, environment: environment, deployable: build)
end
it 'shows metrics' do it 'shows metrics' do
click_link('See metrics') click_link('See metrics')
expect(page).to have_css('div#prometheus-graphs') expect(page).to have_css('div#prometheus-graphs')
end end
it_behaves_like 'has environment selector'
end end
def visit_environment(environment) def visit_environment(environment)
visit project_environment_path(environment.project, environment) visit project_environment_path(environment.project, environment)
end end
def have_metrics_path(environment)
have_current_path(metrics_project_environment_path(project, id: environment.id))
end
end end
...@@ -62,16 +62,34 @@ describe('Dashboard', () => { ...@@ -62,16 +62,34 @@ describe('Dashboard', () => {
}); });
describe('no metrics are available yet', () => { describe('no metrics are available yet', () => {
it('shows a getting started empty state when no metrics are present', () => { beforeEach(() => {
component = new DashboardComponent({ component = new DashboardComponent({
el: document.querySelector('.prometheus-graphs'), el: document.querySelector('.prometheus-graphs'),
propsData: { ...propsData }, propsData: { ...propsData },
store, store,
}); });
});
it('shows a getting started empty state when no metrics are present', () => {
expect(component.$el.querySelector('.prometheus-graphs')).toBe(null); expect(component.$el.querySelector('.prometheus-graphs')).toBe(null);
expect(component.emptyState).toEqual('gettingStarted'); expect(component.emptyState).toEqual('gettingStarted');
}); });
it('shows the environment selector', () => {
expect(component.$el.querySelector('.js-environments-dropdown')).toBeTruthy();
});
});
describe('no data found', () => {
it('shows the environment selector dropdown', () => {
component = new DashboardComponent({
el: document.querySelector('.prometheus-graphs'),
propsData: { ...propsData, showEmptyState: true },
store,
});
expect(component.$el.querySelector('.js-environments-dropdown')).toBeTruthy();
});
}); });
describe('requests information to the server', () => { describe('requests information to the server', () => {
...@@ -150,14 +168,24 @@ describe('Dashboard', () => { ...@@ -150,14 +168,24 @@ describe('Dashboard', () => {
singleGroupResponse, singleGroupResponse,
); );
setTimeout(() => { Vue.nextTick()
const dropdownMenuEnvironments = component.$el.querySelectorAll( .then(() => {
'.js-environments-dropdown .dropdown-item', const dropdownMenuEnvironments = component.$el.querySelectorAll(
); '.js-environments-dropdown .dropdown-item',
);
expect(dropdownMenuEnvironments.length).toEqual(component.environments.length); expect(component.environments.length).toEqual(environmentData.length);
done(); expect(dropdownMenuEnvironments.length).toEqual(component.environments.length);
});
Array.from(dropdownMenuEnvironments).forEach((value, index) => {
if (environmentData[index].metrics_path) {
expect(value).toHaveAttr('href', environmentData[index].metrics_path);
}
});
done();
})
.catch(done.fail);
}); });
it('hides the environments dropdown list when there is no environments', done => { it('hides the environments dropdown list when there is no environments', done => {
...@@ -212,7 +240,7 @@ describe('Dashboard', () => { ...@@ -212,7 +240,7 @@ describe('Dashboard', () => {
Vue.nextTick() Vue.nextTick()
.then(() => { .then(() => {
const dropdownItems = component.$el.querySelectorAll( const dropdownItems = component.$el.querySelectorAll(
'.js-environments-dropdown .dropdown-item[active="true"]', '.js-environments-dropdown .dropdown-item.is-active',
); );
expect(dropdownItems.length).toEqual(1); expect(dropdownItems.length).toEqual(1);
......
...@@ -70,6 +70,10 @@ module PrometheusHelpers ...@@ -70,6 +70,10 @@ module PrometheusHelpers
WebMock.stub_request(:get, url).to_raise(exception_type) WebMock.stub_request(:get, url).to_raise(exception_type)
end end
def stub_any_prometheus_request
WebMock.stub_request(:any, /prometheus.example.com/)
end
def stub_all_prometheus_requests(environment_slug, body: nil, status: 200) def stub_all_prometheus_requests(environment_slug, body: nil, status: 200)
stub_prometheus_request( stub_prometheus_request(
prometheus_query_with_time_url(prometheus_memory_query(environment_slug), Time.now.utc), prometheus_query_with_time_url(prometheus_memory_query(environment_slug), Time.now.utc),
......
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