diff options
14 files changed, 163 insertions, 16 deletions
diff --git a/app/assets/javascripts/environments/components/environment_actions.js b/app/assets/javascripts/environments/components/environment_actions.js index 455a8819549..385085c03e2 100644 --- a/app/assets/javascripts/environments/components/environment_actions.js +++ b/app/assets/javascripts/environments/components/environment_actions.js @@ -25,6 +25,12 @@ export default { }; }, + computed: { + title() { + return 'Deploy to...'; + }, + }, + methods: { onClickAction(endpoint) { this.isLoading = true; @@ -44,8 +50,11 @@ export default { template: ` <div class="btn-group" role="group"> <button - class="dropdown btn btn-default dropdown-new js-dropdown-play-icon-container" + class="dropdown btn btn-default dropdown-new js-dropdown-play-icon-container has-tooltip" + data-container="body" data-toggle="dropdown" + :title="title" + :aria-label="title" :disabled="isLoading"> <span> <span v-html="playIconSvg"></span> diff --git a/app/assets/javascripts/environments/components/environment_external_url.js b/app/assets/javascripts/environments/components/environment_external_url.js index b4f9eb357fd..d79b916c360 100644 --- a/app/assets/javascripts/environments/components/environment_external_url.js +++ b/app/assets/javascripts/environments/components/environment_external_url.js @@ -9,13 +9,21 @@ export default { }, }, + computed: { + title() { + return 'Open'; + }, + }, + template: ` <a - class="btn external_url" + class="btn external-url has-tooltip" + data-container="body" :href="externalUrl" target="_blank" - rel="noopener noreferrer" - title="Environment external URL"> + rel="noopener noreferrer nofollow" + :title="title" + :aria-label="title"> <i class="fa fa-external-link" aria-hidden="true"></i> </a> `, diff --git a/app/assets/javascripts/environments/components/environment_item.js b/app/assets/javascripts/environments/components/environment_item.js index 66ed10e19d1..9c196562c6c 100644 --- a/app/assets/javascripts/environments/components/environment_item.js +++ b/app/assets/javascripts/environments/components/environment_item.js @@ -5,6 +5,7 @@ import ExternalUrlComponent from './environment_external_url'; import StopComponent from './environment_stop'; import RollbackComponent from './environment_rollback'; import TerminalButtonComponent from './environment_terminal_button'; +import MonitoringButtonComponent from './environment_monitoring'; import CommitComponent from '../../vue_shared/components/commit'; /** @@ -22,6 +23,7 @@ export default { 'stop-component': StopComponent, 'rollback-component': RollbackComponent, 'terminal-button-component': TerminalButtonComponent, + 'monitoring-button-component': MonitoringButtonComponent, }, props: { @@ -392,6 +394,14 @@ export default { return ''; }, + monitoringUrl() { + if (this.model && this.model.metrics_path) { + return this.model.metrics_path; + } + + return ''; + }, + /** * Constructs folder URL based on the current location and the folder id. * @@ -496,13 +506,16 @@ export default { <external-url-component v-if="externalURL && canReadEnvironment" :external-url="externalURL"/> - <stop-component v-if="hasStopAction && canCreateDeployment" - :stop-url="model.stop_path" - :service="service"/> + <monitoring-button-component v-if="monitoringUrl && canReadEnvironment" + :monitoring-url="monitoringUrl"/> <terminal-button-component v-if="model && model.terminal_path" :terminal-path="model.terminal_path"/> + <stop-component v-if="hasStopAction && canCreateDeployment" + :stop-url="model.stop_path" + :service="service"/> + <rollback-component v-if="canRetry && canCreateDeployment" :is-last-deployment="isLastDeployment" :retry-url="retryUrl" diff --git a/app/assets/javascripts/environments/components/environment_monitoring.js b/app/assets/javascripts/environments/components/environment_monitoring.js new file mode 100644 index 00000000000..064e2fc7434 --- /dev/null +++ b/app/assets/javascripts/environments/components/environment_monitoring.js @@ -0,0 +1,31 @@ +/** + * Renders the Monitoring (Metrics) link in environments table. + */ +export default { + props: { + monitoringUrl: { + type: String, + default: '', + required: true, + }, + }, + + computed: { + title() { + return 'Monitoring'; + }, + }, + + template: ` + <a + class="btn monitoring-url has-tooltip" + data-container="body" + :href="monitoringUrl" + target="_blank" + rel="noopener noreferrer nofollow" + :title="title" + :aria-label="title"> + <i class="fa fa-area-chart" aria-hidden="true"></i> + </a> + `, +}; diff --git a/app/assets/javascripts/environments/components/environment_stop.js b/app/assets/javascripts/environments/components/environment_stop.js index 5404d647745..47102692024 100644 --- a/app/assets/javascripts/environments/components/environment_stop.js +++ b/app/assets/javascripts/environments/components/environment_stop.js @@ -25,6 +25,12 @@ export default { }; }, + computed: { + title() { + return 'Stop'; + }, + }, + methods: { onClick() { if (confirm('Are you sure you want to stop this environment?')) { @@ -45,10 +51,12 @@ export default { template: ` <button type="button" - class="btn stop-env-link" + class="btn stop-env-link has-tooltip" + data-container="body" @click="onClick" :disabled="isLoading" - title="Stop Environment"> + :title="title" + :aria-label="title"> <i class="fa fa-stop stop-env-icon" aria-hidden="true"></i> <i v-if="isLoading" class="fa fa-spinner fa-spin" aria-hidden="true"></i> </button> diff --git a/app/assets/javascripts/environments/components/environment_terminal_button.js b/app/assets/javascripts/environments/components/environment_terminal_button.js index 66a71faa02f..092a50a0d6f 100644 --- a/app/assets/javascripts/environments/components/environment_terminal_button.js +++ b/app/assets/javascripts/environments/components/environment_terminal_button.js @@ -14,12 +14,22 @@ export default { }, data() { - return { terminalIconSvg }; + return { + terminalIconSvg, + }; + }, + + computed: { + title() { + return 'Terminal'; + }, }, template: ` - <a class="btn terminal-button" - title="Open web terminal" + <a class="btn terminal-button has-tooltip" + data-container="body" + :title="title" + :aria-label="title" :href="terminalPath"> ${terminalIconSvg} </a> diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index 25be7f408d0..3d91e0b22d8 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -26,7 +26,7 @@ .table.ci-table { .environments-actions { - min-width: 200px; + min-width: 300px; } .environments-commit, @@ -222,3 +222,12 @@ stroke: $black; stroke-width: 1; } + +.environments-actions { + .external-url, + .monitoring-url, + .terminal-button, + .stop-env-link { + width: 38px; + } +} diff --git a/app/serializers/environment_entity.rb b/app/serializers/environment_entity.rb index 4c017960628..4ff15a78115 100644 --- a/app/serializers/environment_entity.rb +++ b/app/serializers/environment_entity.rb @@ -9,6 +9,13 @@ class EnvironmentEntity < Grape::Entity expose :last_deployment, using: DeploymentEntity expose :stop_action? + expose :metrics_path, if: -> (environment, _) { environment.has_metrics? } do |environment| + metrics_namespace_project_environment_path( + environment.project.namespace, + environment.project, + environment) + end + expose :environment_path do |environment| namespace_project_environment_path( environment.project.namespace, diff --git a/changelogs/unreleased/29341-add-metrics-button-env-overview.yml b/changelogs/unreleased/29341-add-metrics-button-env-overview.yml new file mode 100644 index 00000000000..16b69235dff --- /dev/null +++ b/changelogs/unreleased/29341-add-metrics-button-env-overview.yml @@ -0,0 +1,4 @@ +--- +title: Add metrics button to environments overview page +merge_request: 10234 +author: diff --git a/spec/javascripts/environments/environment_actions_spec.js b/spec/javascripts/environments/environment_actions_spec.js index 85b73f1d4e2..13840b42bd6 100644 --- a/spec/javascripts/environments/environment_actions_spec.js +++ b/spec/javascripts/environments/environment_actions_spec.js @@ -32,7 +32,12 @@ describe('Actions Component', () => { }).$mount(); }); - it('should render a dropdown with the provided actions', () => { + it('should render a dropdown button with icon and title attribute', () => { + expect(component.$el.querySelector('.fa-caret-down')).toBeDefined(); + expect(component.$el.querySelector('.dropdown-new').getAttribute('title')).toEqual('Deploy to...'); + }); + + it('should render a dropdown with the provided list of actions', () => { expect( component.$el.querySelectorAll('.dropdown-menu li').length, ).toEqual(actionsMock.length); diff --git a/spec/javascripts/environments/environment_monitoring_spec.js b/spec/javascripts/environments/environment_monitoring_spec.js new file mode 100644 index 00000000000..fc451cce641 --- /dev/null +++ b/spec/javascripts/environments/environment_monitoring_spec.js @@ -0,0 +1,23 @@ +import Vue from 'vue'; +import monitoringComp from '~/environments/components/environment_monitoring'; + +describe('Monitoring Component', () => { + let MonitoringComponent; + + beforeEach(() => { + MonitoringComponent = Vue.extend(monitoringComp); + }); + + it('should render a link to environment monitoring page', () => { + const monitoringUrl = 'https://gitlab.com'; + const component = new MonitoringComponent({ + propsData: { + monitoringUrl, + }, + }).$mount(); + + expect(component.$el.getAttribute('href')).toEqual(monitoringUrl); + expect(component.$el.querySelector('.fa-area-chart')).toBeDefined(); + expect(component.$el.getAttribute('title')).toEqual('Monitoring'); + }); +}); diff --git a/spec/javascripts/environments/environment_stop_spec.js b/spec/javascripts/environments/environment_stop_spec.js index 8f79b88f3df..01055e3f255 100644 --- a/spec/javascripts/environments/environment_stop_spec.js +++ b/spec/javascripts/environments/environment_stop_spec.js @@ -24,7 +24,7 @@ describe('Stop Component', () => { it('should render a button to stop the environment', () => { expect(component.$el.tagName).toEqual('BUTTON'); - expect(component.$el.getAttribute('title')).toEqual('Stop Environment'); + expect(component.$el.getAttribute('title')).toEqual('Stop'); }); it('should call the service when an action is clicked', () => { diff --git a/spec/javascripts/environments/environment_terminal_button_spec.js b/spec/javascripts/environments/environment_terminal_button_spec.js index b07aa4e1745..be2289edc2b 100644 --- a/spec/javascripts/environments/environment_terminal_button_spec.js +++ b/spec/javascripts/environments/environment_terminal_button_spec.js @@ -18,7 +18,7 @@ describe('Stop Component', () => { it('should render a link to open a web terminal with the provided path', () => { expect(component.$el.tagName).toEqual('A'); - expect(component.$el.getAttribute('title')).toEqual('Open web terminal'); + expect(component.$el.getAttribute('title')).toEqual('Terminal'); expect(component.$el.getAttribute('href')).toEqual(terminalPath); }); }); diff --git a/spec/serializers/environment_entity_spec.rb b/spec/serializers/environment_entity_spec.rb index 57728ce3181..979d9921941 100644 --- a/spec/serializers/environment_entity_spec.rb +++ b/spec/serializers/environment_entity_spec.rb @@ -15,4 +15,24 @@ describe EnvironmentEntity do it 'exposes core elements of environment' do expect(subject).to include(:id, :name, :state, :environment_path) end + + context 'metrics disabled' do + before do + allow(environment).to receive(:has_metrics?).and_return(false) + end + + it "doesn't expose metrics path" do + expect(subject).not_to include(:metrics_path) + end + end + + context 'metrics enabled' do + before do + allow(environment).to receive(:has_metrics?).and_return(true) + end + + it 'exposes metrics path' do + expect(subject).to include(:metrics_path) + end + end end |