summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReuben Pereira <rpereira@gitlab.com>2019-06-26 14:53:55 +0000
committerPhil Hughes <me@iamphill.com>2019-06-26 14:53:55 +0000
commitb13cd6737a2cb175c1f4501c1c5e0d01c060fa39 (patch)
treef7eec0d426e9253418d8960e90f83516ab4d01bd
parent5b97ea3e6ae872a5c72695a425083affad2d1dfc (diff)
downloadgitlab-ce-b13cd6737a2cb175c1f4501c1c5e0d01c060fa39.tar.gz
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.
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue77
-rw-r--r--changelogs/unreleased/always-display-environment-selector.yml5
-rw-r--r--spec/features/projects/environments/environment_metrics_spec.rb39
-rw-r--r--spec/javascripts/monitoring/dashboard_spec.js46
-rw-r--r--spec/support/helpers/prometheus_helpers.rb4
5 files changed, 123 insertions, 48 deletions
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index 0a652329dfe..973fa346a4f 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -234,7 +234,7 @@ export default {
</script>
<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
v-if="environmentsEndpoint"
@@ -253,11 +253,12 @@ export default {
:key="environment.id"
:active="environment.name === currentEnvironmentName"
active-class="is-active"
+ :href="environment.metrics_path"
>{{ environment.name }}</gl-dropdown-item
>
</gl-dropdown>
</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>
<gl-dropdown
class="prepend-left-10 js-time-window-dropdown"
@@ -276,7 +277,7 @@ export default {
</div>
</div>
<div class="d-flex">
- <div v-if="isEE && canAddMetrics">
+ <div v-if="isEE && canAddMetrics && !showEmptyState">
<gl-button
v-gl-modal-directive="$options.addMetric.modalId"
class="js-add-metric-button text-success border-success"
@@ -317,40 +318,42 @@ export default {
</gl-button>
</div>
</div>
- <graph-group
- v-for="(groupData, index) in groupsWithData"
- :key="index"
- :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"
+ <div v-if="!showEmptyState">
+ <graph-group
+ v-for="(groupData, index) in groupsWithData"
+ :key="index"
+ :name="groupData.group"
+ :show-panels="showPanels"
>
- <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>
+ <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
+ 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>
- <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>
diff --git a/changelogs/unreleased/always-display-environment-selector.yml b/changelogs/unreleased/always-display-environment-selector.yml
new file mode 100644
index 00000000000..7a55e8f3e5d
--- /dev/null
+++ b/changelogs/unreleased/always-display-environment-selector.yml
@@ -0,0 +1,5 @@
+---
+title: Fix broken environment selector and always display it on monitoring dashboard
+merge_request: 29705
+author:
+type: fixed
diff --git a/spec/features/projects/environments/environment_metrics_spec.rb b/spec/features/projects/environments/environment_metrics_spec.rb
index edbab14f7c1..b08ccdc2a7c 100644
--- a/spec/features/projects/environments/environment_metrics_spec.rb
+++ b/spec/features/projects/environments/environment_metrics_spec.rb
@@ -9,11 +9,11 @@ describe 'Environment > Metrics' do
let(:build) { create(:ci_build, pipeline: pipeline) }
let(:environment) { create(:environment, project: project) }
let(:current_time) { Time.now.utc }
+ let!(:staging) { create(:environment, name: 'staging', project: project) }
before do
project.add_developer(user)
- create(:deployment, environment: environment, deployable: build)
- stub_all_prometheus_requests(environment.slug)
+ stub_any_prometheus_request
sign_in(user)
visit_environment(environment)
@@ -23,15 +23,50 @@ describe 'Environment > Metrics' do
Timecop.freeze(current_time) { example.run }
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
+ before do
+ create(:deployment, environment: environment, deployable: build)
+ end
+
it 'shows metrics' do
click_link('See metrics')
expect(page).to have_css('div#prometheus-graphs')
end
+
+ it_behaves_like 'has environment selector'
end
def visit_environment(environment)
visit project_environment_path(environment.project, environment)
end
+
+ def have_metrics_path(environment)
+ have_current_path(metrics_project_environment_path(project, id: environment.id))
+ end
end
diff --git a/spec/javascripts/monitoring/dashboard_spec.js b/spec/javascripts/monitoring/dashboard_spec.js
index f4166987aed..cf72cce1781 100644
--- a/spec/javascripts/monitoring/dashboard_spec.js
+++ b/spec/javascripts/monitoring/dashboard_spec.js
@@ -62,16 +62,34 @@ describe('Dashboard', () => {
});
describe('no metrics are available yet', () => {
- it('shows a getting started empty state when no metrics are present', () => {
+ beforeEach(() => {
component = new DashboardComponent({
el: document.querySelector('.prometheus-graphs'),
propsData: { ...propsData },
store,
});
+ });
+ it('shows a getting started empty state when no metrics are present', () => {
expect(component.$el.querySelector('.prometheus-graphs')).toBe(null);
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', () => {
@@ -150,14 +168,24 @@ describe('Dashboard', () => {
singleGroupResponse,
);
- setTimeout(() => {
- const dropdownMenuEnvironments = component.$el.querySelectorAll(
- '.js-environments-dropdown .dropdown-item',
- );
+ Vue.nextTick()
+ .then(() => {
+ const dropdownMenuEnvironments = component.$el.querySelectorAll(
+ '.js-environments-dropdown .dropdown-item',
+ );
- expect(dropdownMenuEnvironments.length).toEqual(component.environments.length);
- done();
- });
+ expect(component.environments.length).toEqual(environmentData.length);
+ 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 => {
@@ -212,7 +240,7 @@ describe('Dashboard', () => {
Vue.nextTick()
.then(() => {
const dropdownItems = component.$el.querySelectorAll(
- '.js-environments-dropdown .dropdown-item[active="true"]',
+ '.js-environments-dropdown .dropdown-item.is-active',
);
expect(dropdownItems.length).toEqual(1);
diff --git a/spec/support/helpers/prometheus_helpers.rb b/spec/support/helpers/prometheus_helpers.rb
index 87f825152cf..db662836013 100644
--- a/spec/support/helpers/prometheus_helpers.rb
+++ b/spec/support/helpers/prometheus_helpers.rb
@@ -70,6 +70,10 @@ module PrometheusHelpers
WebMock.stub_request(:get, url).to_raise(exception_type)
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)
stub_prometheus_request(
prometheus_query_with_time_url(prometheus_memory_query(environment_slug), Time.now.utc),