diff --git a/app/assets/javascripts/shortcuts_navigation.js b/app/assets/javascripts/shortcuts_navigation.js index 78f7353eb0d..6b595764bc5 100644 --- a/app/assets/javascripts/shortcuts_navigation.js +++ b/app/assets/javascripts/shortcuts_navigation.js @@ -20,6 +20,7 @@ export default class ShortcutsNavigation extends Shortcuts { Mousetrap.bind('g s', () => findAndFollowLink('.shortcuts-snippets')); Mousetrap.bind('g k', () => findAndFollowLink('.shortcuts-kubernetes')); Mousetrap.bind('g e', () => findAndFollowLink('.shortcuts-environments')); + Mousetrap.bind('g l', () => findAndFollowLink('.shortcuts-metrics')); Mousetrap.bind('i', () => findAndFollowLink('.shortcuts-new-issue')); this.enabledHelp.push('.hidden-shortcut.project'); diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 0821362f5df..27b7425b965 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -120,6 +120,16 @@ class Projects::EnvironmentsController < Projects::ApplicationController end end + def metrics_redirect + environment = project.default_environment + + if environment + redirect_to environment_metrics_path(environment) + else + render :empty + end + end + def metrics # Currently, this acts as a hint to load the metrics details into the cache # if they aren't there already diff --git a/app/models/project.rb b/app/models/project.rb index 7304ab7b909..8f40470de82 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1774,6 +1774,15 @@ class Project < ActiveRecord::Base end end + def default_environment + production_first = "(CASE WHEN name = 'production' THEN 0 ELSE 1 END), id ASC" + + environments + .with_state(:available) + .reorder(production_first) + .first + end + def secret_variables_for(ref:, environment: nil) # EE would use the environment if protected_for?(ref) diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml index c23fe0b5c49..37b56f92030 100644 --- a/app/views/help/_shortcuts.html.haml +++ b/app/views/help/_shortcuts.html.haml @@ -179,6 +179,12 @@ %kbd e %td Go to environments + %tr + %td.shortcut + %kbd g + %kbd l + %td + Go to metrics %tr %td.shortcut %kbd g diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml index 33416bf76d7..00d75b3399b 100644 --- a/app/views/layouts/nav/sidebar/_project.html.haml +++ b/app/views/layouts/nav/sidebar/_project.html.haml @@ -196,7 +196,7 @@ - if project_nav_tab? :operations = nav_link(controller: [:environments, :clusters, :user, :gcp]) do - = link_to project_environments_path(@project), class: 'shortcuts-operations' do + = link_to metrics_project_environments_path(@project), class: 'shortcuts-operations' do .nav-icon-container = sprite_icon('cloud-gear') %span.nav-item-name @@ -204,14 +204,19 @@ %ul.sidebar-sub-level-items = nav_link(controller: [:environments, :clusters, :user, :gcp], html_options: { class: "fly-out-top-item" } ) do - = link_to project_environments_path(@project) do + = link_to metrics_project_environments_path(@project) do %strong.fly-out-top-item-name = _('Operations') %li.divider.fly-out-top-item - if project_nav_tab? :environments - = nav_link(controller: :environments) do - = link_to project_environments_path(@project), title: 'Environments', class: 'shortcuts-environments' do + = nav_link(controller: :environments, action: [:metrics, :metrics_redirect]) do + = link_to metrics_project_environments_path(@project), title: _('Metrics'), class: 'shortcuts-metrics' do + %span + = _('Metrics') + + = nav_link(controller: :environments, action: [:index, :folder, :show, :new, :edit, :create, :update, :stop, :terminal]) do + = link_to project_environments_path(@project), title: _('Environments'), class: 'shortcuts-environments' do %span = _('Environments') diff --git a/app/views/projects/environments/empty.html.haml b/app/views/projects/environments/empty.html.haml new file mode 100644 index 00000000000..1413930ebdb --- /dev/null +++ b/app/views/projects/environments/empty.html.haml @@ -0,0 +1,14 @@ +- page_title _("Metrics") + +.row + .col-sm-12 + .svg-content + = image_tag 'illustrations/operations_metrics_empty.svg' +.row.empty-environments + .col-sm-12.text-center + %h4 + = s_('Metrics|No deployed environments') + .state-description + = s_('Metrics|Check out the CI/CD documentation on deploying to an environment') + .prepend-top-10 + = link_to s_("Metrics|Learn about environments"), help_page_path('ci/environments'), class: 'btn btn-success' diff --git a/config/routes/project.rb b/config/routes/project.rb index a9cff7ff028..2ebf84f2ecf 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -229,6 +229,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do end collection do + get :metrics, action: :metrics_redirect get :folder, path: 'folders/*id', constraints: { format: /(html|json)/ } end diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 47d4942acbd..63cef579864 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -277,6 +277,25 @@ describe Projects::EnvironmentsController do end end + describe 'GET #metrics_redirect' do + let(:project) { create(:project) } + + it 'redirects to environment if it exists' do + environment = create(:environment, name: 'production', project: project) + + get :metrics_redirect, namespace_id: project.namespace, project_id: project + + expect(response).to redirect_to(environment_metrics_path(environment)) + end + + it 'redirects to empty page if no environment exists' do + get :metrics_redirect, namespace_id: project.namespace, project_id: project + + expect(response).to be_ok + expect(response).to render_template 'empty' + end + end + describe 'GET #metrics' do before do allow(controller).to receive(:environment).and_return(environment) diff --git a/spec/features/projects/user_uses_shortcuts_spec.rb b/spec/features/projects/user_uses_shortcuts_spec.rb index 495a010b32c..c8b3104b9fe 100644 --- a/spec/features/projects/user_uses_shortcuts_spec.rb +++ b/spec/features/projects/user_uses_shortcuts_spec.rb @@ -110,6 +110,14 @@ describe 'User uses shortcuts', :js do end context 'when navigating to the Operations pages' do + it 'redirects to the Metrics page' do + find('body').native.send_key('g') + find('body').native.send_key('l') + + expect(page).to have_active_navigation('Operations') + expect(page).to have_active_sub_navigation('Metrics') + end + it 'redirects to the Environments page' do find('body').native.send_key('g') find('body').native.send_key('e') diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index abdc65336ca..c3aa6cd6fed 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2292,6 +2292,28 @@ describe Project do end end + describe '#default_environment' do + let(:project) { create(:project) } + + it 'returns production environment when it exists' do + production = create(:environment, name: "production", project: project) + create(:environment, name: 'staging', project: project) + + expect(project.default_environment).to eq(production) + end + + it 'returns first environment when no production environment exists' do + create(:environment, name: 'staging', project: project) + create(:environment, name: 'foo', project: project) + + expect(project.default_environment).to eq(project.environments.first) + end + + it 'returns nil when no available environment exists' do + expect(project.default_environment).to be_nil + end + end + describe '#secret_variables_for' do let(:project) { create(:project) }