Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
087d90af
Commit
087d90af
authored
Apr 30, 2021
by
Francisco Javier López
Committed by
Arturo Herrero
Apr 30, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add `Operations` menu to the new sidebar
parent
08344e29
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
823 additions
and
418 deletions
+823
-418
app/helpers/projects_helper.rb
app/helpers/projects_helper.rb
+0
-42
app/helpers/sidebars_helper.rb
app/helpers/sidebars_helper.rb
+2
-1
app/views/layouts/nav/sidebar/_project_menus.html.haml
app/views/layouts/nav/sidebar/_project_menus.html.haml
+0
-95
app/views/layouts/nav/sidebar/_tracing_link.html.haml
app/views/layouts/nav/sidebar/_tracing_link.html.haml
+0
-7
ee/app/helpers/ee/projects_helper.rb
ee/app/helpers/ee/projects_helper.rb
+0
-7
ee/app/views/projects/sidebar/_oncall_schedules.html.haml
ee/app/views/projects/sidebar/_oncall_schedules.html.haml
+0
-6
ee/lib/ee/sidebars/projects/menus/operations_menu.rb
ee/lib/ee/sidebars/projects/menus/operations_menu.rb
+35
-0
ee/spec/helpers/projects_helper_spec.rb
ee/spec/helpers/projects_helper_spec.rb
+0
-69
ee/spec/lib/ee/sidebars/projects/menus/operations_menu_spec.rb
...ec/lib/ee/sidebars/projects/menus/operations_menu_spec.rb
+25
-0
ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
+25
-35
lib/sidebars/projects/menus/operations_menu.rb
lib/sidebars/projects/menus/operations_menu.rb
+217
-0
lib/sidebars/projects/panel.rb
lib/sidebars/projects/panel.rb
+1
-0
qa/qa/page/project/sub_menus/operations.rb
qa/qa/page/project/sub_menus/operations.rb
+5
-12
spec/features/operations_sidebar_link_spec.rb
spec/features/operations_sidebar_link_spec.rb
+50
-49
spec/helpers/projects_helper_spec.rb
spec/helpers/projects_helper_spec.rb
+0
-37
spec/lib/sidebars/projects/menus/operations_menu_spec.rb
spec/lib/sidebars/projects/menus/operations_menu_spec.rb
+205
-0
spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
+258
-58
No files found.
app/helpers/projects_helper.rb
View file @
087d90af
...
@@ -404,14 +404,6 @@ module ProjectsHelper
...
@@ -404,14 +404,6 @@ module ProjectsHelper
nav_tabs
<<
:pipelines
nav_tabs
<<
:pipelines
end
end
if
can_view_operations_tab?
(
current_user
,
project
)
nav_tabs
<<
:operations
end
if
can_view_product_analytics?
(
current_user
,
project
)
nav_tabs
<<
:product_analytics
end
tab_ability_map
.
each
do
|
tab
,
ability
|
tab_ability_map
.
each
do
|
tab
,
ability
|
if
can?
(
current_user
,
ability
,
project
)
if
can?
(
current_user
,
ability
,
project
)
nav_tabs
<<
tab
nav_tabs
<<
tab
...
@@ -470,32 +462,6 @@ module ProjectsHelper
...
@@ -470,32 +462,6 @@ module ProjectsHelper
}
}
end
end
def
view_operations_tab_ability
[
:metrics_dashboard
,
:read_alert_management_alert
,
:read_environment
,
:read_issue
,
:read_sentry_issue
,
:read_cluster
,
:read_feature_flag
,
:read_terraform_state
]
end
def
can_view_operations_tab?
(
current_user
,
project
)
return
false
unless
project
.
feature_available?
(
:operations
,
current_user
)
view_operations_tab_ability
.
any?
do
|
ability
|
can?
(
current_user
,
ability
,
project
)
end
end
def
can_view_product_analytics?
(
current_user
,
project
)
Feature
.
enabled?
(
:product_analytics
,
project
)
&&
can?
(
current_user
,
:read_product_analytics
,
project
)
end
def
search_tab_ability_map
def
search_tab_ability_map
@search_tab_ability_map
||=
tab_ability_map
.
merge
(
@search_tab_ability_map
||=
tab_ability_map
.
merge
(
blobs: :download_code
,
blobs: :download_code
,
...
@@ -563,14 +529,6 @@ module ProjectsHelper
...
@@ -563,14 +529,6 @@ module ProjectsHelper
end
end
end
end
def
sidebar_operations_link_path
(
project
=
@project
)
if
can?
(
current_user
,
:read_environment
,
project
)
metrics_project_environments_path
(
project
)
else
project_feature_flags_path
(
project
)
end
end
def
project_last_activity
(
project
)
def
project_last_activity
(
project
)
if
project
.
last_activity_at
if
project
.
last_activity_at
time_ago_with_tooltip
(
project
.
last_activity_at
,
placement:
'bottom'
,
html_class:
'last_activity_time_ago'
)
time_ago_with_tooltip
(
project
.
last_activity_at
,
placement:
'bottom'
,
html_class:
'last_activity_time_ago'
)
...
...
app/helpers/sidebars_helper.rb
View file @
087d90af
...
@@ -41,7 +41,8 @@ module SidebarsHelper
...
@@ -41,7 +41,8 @@ module SidebarsHelper
learn_gitlab_experiment_enabled:
learn_gitlab_experiment_enabled?
(
project
),
learn_gitlab_experiment_enabled:
learn_gitlab_experiment_enabled?
(
project
),
current_ref:
current_ref
,
current_ref:
current_ref
,
jira_issues_integration:
project_jira_issues_integration?
,
jira_issues_integration:
project_jira_issues_integration?
,
can_view_pipeline_editor:
can_view_pipeline_editor?
(
project
)
can_view_pipeline_editor:
can_view_pipeline_editor?
(
project
),
show_cluster_hint:
show_gke_cluster_integration_callout?
(
project
)
}
}
end
end
end
end
...
...
app/views/layouts/nav/sidebar/_project_menus.html.haml
View file @
087d90af
-
if
project_nav_tab?
:operations
=
nav_link
(
controller:
sidebar_operations_paths
)
do
=
link_to
sidebar_operations_link_path
,
class:
'shortcuts-operations'
,
data:
{
qa_selector:
'operations_link'
}
do
.nav-icon-container
=
sprite_icon
(
'cloud-gear'
)
%span
.nav-item-name
=
_
(
'Operations'
)
%ul
.sidebar-sub-level-items
=
nav_link
(
controller:
sidebar_operations_paths
,
html_options:
{
class:
"fly-out-top-item"
}
)
do
=
link_to
sidebar_operations_link_path
do
%strong
.fly-out-top-item-name
=
_
(
'Operations'
)
%li
.divider.fly-out-top-item
-
if
project_nav_tab?
:metrics_dashboards
=
nav_link
(
controller: :metrics_dashboard
,
action:
[
:show
])
do
=
link_to
project_metrics_dashboard_path
(
@project
),
title:
_
(
'Metrics'
),
class:
'shortcuts-metrics'
,
data:
{
qa_selector:
'operations_metrics_link'
}
do
%span
=
_
(
'Metrics'
)
-
if
project_nav_tab?
(
:environments
)
&&
can?
(
current_user
,
:read_pod_logs
,
@project
)
=
nav_link
(
controller: :logs
,
action:
[
:index
])
do
=
link_to
project_logs_path
(
@project
),
title:
_
(
'Logs'
)
do
%span
=
_
(
'Logs'
)
-
if
project_nav_tab?
:environments
=
render
"layouts/nav/sidebar/tracing_link"
-
if
project_nav_tab?
(
:error_tracking
)
=
nav_link
(
controller: :error_tracking
)
do
=
link_to
project_error_tracking_index_path
(
@project
),
title:
_
(
'Error Tracking'
)
do
%span
=
_
(
'Error Tracking'
)
-
if
project_nav_tab?
(
:alert_management
)
=
nav_link
(
controller: :alert_management
)
do
=
link_to
project_alert_management_index_path
(
@project
),
title:
_
(
'Alerts'
)
do
%span
=
_
(
'Alerts'
)
-
if
project_nav_tab?
(
:incidents
)
=
nav_link
(
controller: :incidents
)
do
=
link_to
project_incidents_path
(
@project
),
title:
_
(
'Incidents'
),
data:
{
qa_selector:
'operations_incidents_link'
}
do
%span
=
_
(
'Incidents'
)
=
render_if_exists
'projects/sidebar/oncall_schedules'
-
if
project_nav_tab?
:serverless
=
nav_link
(
controller: :functions
)
do
=
link_to
project_serverless_functions_path
(
@project
),
title:
_
(
'Serverless'
)
do
%span
=
_
(
'Serverless'
)
-
if
project_nav_tab?
:terraform
=
nav_link
(
controller: :terraform
)
do
=
link_to
project_terraform_index_path
(
@project
),
title:
_
(
'Terraform'
)
do
%span
=
_
(
'Terraform'
)
-
if
project_nav_tab?
:clusters
-
show_cluster_hint
=
show_gke_cluster_integration_callout?
(
@project
)
=
nav_link
(
controller:
[
:cluster_agents
,
:clusters
])
do
=
link_to
project_clusters_path
(
@project
),
title:
_
(
'Kubernetes'
),
class:
'shortcuts-kubernetes'
do
%span
=
_
(
'Kubernetes'
)
-
if
show_cluster_hint
.js-feature-highlight
{
disabled:
true
,
data:
{
trigger:
'manual'
,
container:
'body'
,
placement:
'right'
,
highlight:
UserCalloutsHelper
::
GKE_CLUSTER_INTEGRATION
,
highlight_priority:
UserCallout
.
feature_names
[
:GKE_CLUSTER_INTEGRATION
],
dismiss_endpoint:
user_callouts_path
,
auto_devops_help_path:
help_page_path
(
'topics/autodevops/index.md'
)
}
}
-
if
project_nav_tab?
:environments
=
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 qa-operations-environments-link'
do
%span
=
_
(
'Environments'
)
-
if
project_nav_tab?
:feature_flags
=
nav_link
(
controller: :feature_flags
)
do
=
link_to
project_feature_flags_path
(
@project
),
title:
_
(
'Feature Flags'
),
class:
'shortcuts-feature-flags'
do
%span
=
_
(
'Feature Flags'
)
-
if
project_nav_tab?
(
:product_analytics
)
=
nav_link
(
controller: :product_analytics
)
do
=
link_to
project_product_analytics_path
(
@project
),
title:
_
(
'Product Analytics'
)
do
%span
=
_
(
'Product Analytics'
)
=
render_if_exists
'layouts/nav/sidebar/project_packages_link'
=
render_if_exists
'layouts/nav/sidebar/project_packages_link'
-
if
project_nav_tab?
:analytics
-
if
project_nav_tab?
:analytics
...
...
app/views/layouts/nav/sidebar/_tracing_link.html.haml
deleted
100644 → 0
View file @
08344e29
-
return
unless
can?
(
current_user
,
:read_environment
,
@project
)
-
if
project_nav_tab?
:settings
=
nav_link
(
controller: :tracings
,
action:
[
:show
])
do
=
link_to
project_tracing_path
(
@project
),
title:
_
(
'Tracing'
)
do
%span
=
_
(
'Tracing'
)
ee/app/helpers/ee/projects_helper.rb
View file @
087d90af
...
@@ -302,12 +302,5 @@ module EE
...
@@ -302,12 +302,5 @@ module EE
}
}
}
}
end
end
override
:view_operations_tab_ability
def
view_operations_tab_ability
super
+
[
:read_incident_management_oncall_schedule
]
end
end
end
end
end
ee/app/views/projects/sidebar/_oncall_schedules.html.haml
deleted
100644 → 0
View file @
08344e29
-
return
unless
project_nav_tab?
:oncall_schedule
=
nav_link
(
controller: :oncall_schedules
)
do
=
link_to
project_incident_management_oncall_schedules_path
(
@project
),
title:
_
(
'On-call Schedules'
)
do
%span
=
_
(
'On-call Schedules'
)
ee/lib/ee/sidebars/projects/menus/operations_menu.rb
0 → 100644
View file @
087d90af
# frozen_string_literal: true
module
EE
module
Sidebars
module
Projects
module
Menus
module
OperationsMenu
extend
::
Gitlab
::
Utils
::
Override
override
:configure_menu_items
def
configure_menu_items
return
false
unless
super
insert_item_after
(
:incidents
,
on_call_schedules_menu_item
)
true
end
private
def
on_call_schedules_menu_item
return
unless
can?
(
context
.
current_user
,
:read_incident_management_oncall_schedule
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'On-call Schedules'
),
link:
project_incident_management_oncall_schedules_path
(
context
.
project
),
active_routes:
{
controller: :oncall_schedules
},
item_id: :on_call_schedules
)
end
end
end
end
end
end
ee/spec/helpers/projects_helper_spec.rb
View file @
087d90af
...
@@ -209,41 +209,6 @@ RSpec.describe ProjectsHelper do
...
@@ -209,41 +209,6 @@ RSpec.describe ProjectsHelper do
end
end
end
end
describe
'#get_project_nav_tabs'
do
using
RSpec
::
Parameterized
::
TableSyntax
let_it_be
(
:user
)
{
create
(
:user
)
}
subject
{
helper
.
get_project_nav_tabs
(
project
,
user
)
}
before
do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
helper
).
to
receive
(
:can?
).
and_return
(
false
)
allow
(
helper
).
to
receive
(
:can?
).
with
(
user
,
ability
,
project
).
and_return
(
feature_available?
)
end
describe
'tabs'
do
where
(
:ability
,
:nav_tabs
)
do
:read_feature_flag
|
[
:operations
]
:read_incident_management_oncall_schedule
|
[
:oncall_schedule
]
end
with_them
do
context
'when the feature is available'
do
let
(
:feature_available?
)
{
true
}
it
{
is_expected
.
to
include
(
*
nav_tabs
)
}
end
context
'when the feature is not available'
do
let
(
:feature_available?
)
{
false
}
it
{
is_expected
.
not_to
include
(
*
nav_tabs
)
}
end
end
end
end
describe
'#show_discover_project_security?'
do
describe
'#show_discover_project_security?'
do
using
RSpec
::
Parameterized
::
TableSyntax
using
RSpec
::
Parameterized
::
TableSyntax
...
@@ -308,40 +273,6 @@ RSpec.describe ProjectsHelper do
...
@@ -308,40 +273,6 @@ RSpec.describe ProjectsHelper do
end
end
end
end
describe
'#can_view_operations_tab?'
do
let_it_be
(
:user
)
{
create
(
:user
)
}
before
do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
helper
).
to
receive
(
:can?
).
and_return
(
false
)
end
subject
{
helper
.
send
(
:can_view_operations_tab?
,
user
,
project
)
}
where
(
:ability
)
do
[
:read_incident_management_oncall_schedule
]
end
with_them
do
it
'includes operations tab'
do
allow
(
helper
).
to
receive
(
:can?
).
with
(
user
,
ability
,
project
).
and_return
(
true
)
is_expected
.
to
be
(
true
)
end
context
'when operations feature is disabled'
do
it
'does not include operations tab'
do
allow
(
helper
).
to
receive
(
:can?
).
with
(
user
,
ability
,
project
).
and_return
(
true
)
project
.
project_feature
.
update_attribute
(
:operations_access_level
,
ProjectFeature
::
DISABLED
)
is_expected
.
to
be
(
false
)
end
end
end
end
describe
'#project_permissions_settings'
do
describe
'#project_permissions_settings'
do
using
RSpec
::
Parameterized
::
TableSyntax
using
RSpec
::
Parameterized
::
TableSyntax
...
...
ee/spec/lib/ee/sidebars/projects/menus/operations_menu_spec.rb
0 → 100644
View file @
087d90af
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Sidebars
::
Projects
::
Menus
::
OperationsMenu
do
let
(
:project
)
{
build
(
:project
)
}
let
(
:user
)
{
project
.
owner
}
let
(
:context
)
{
Sidebars
::
Projects
::
Context
.
new
(
current_user:
user
,
container:
project
,
show_cluster_hint:
true
)
}
describe
'On-call Schedules'
do
subject
{
described_class
.
new
(
context
).
items
.
index
{
|
e
|
e
.
item_id
==
:on_call_schedules
}
}
before
do
stub_licensed_features
(
oncall_schedules:
true
)
end
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
end
ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
View file @
087d90af
...
@@ -180,41 +180,6 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
...
@@ -180,41 +180,6 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
end
end
describe
'Operations > Pod logs'
do
before
do
allow
(
view
).
to
receive
(
:can?
).
with
(
nil
,
:read_environment
,
project
).
and_return
(
can_read_environment
)
allow
(
view
).
to
receive
(
:can?
).
with
(
nil
,
:read_pod_logs
,
project
).
and_return
(
can_read_pod_logs
)
render
end
describe
'when the user can read environments and logs'
do
let
(
:can_read_environment
)
{
true
}
let
(
:can_read_pod_logs
)
{
true
}
it
'link is visible'
do
expect
(
rendered
).
to
have_link
(
'Logs'
,
href:
project_logs_path
(
project
))
end
end
describe
'when the user cannot read environment or logs'
do
let
(
:can_read_environment
)
{
false
}
let
(
:can_read_pod_logs
)
{
false
}
it
'link is not visible'
do
expect
(
rendered
).
not_to
have_link
'Logs'
end
end
describe
'when the user can read environment but not logs'
do
let
(
:can_read_environment
)
{
true
}
let
(
:can_read_pod_logs
)
{
false
}
it
'link is not visible'
do
expect
(
rendered
).
not_to
have_link
'Logs'
end
end
end
describe
'Security and Compliance'
do
describe
'Security and Compliance'
do
describe
'when user does not have permissions'
do
describe
'when user does not have permissions'
do
before
do
before
do
...
@@ -296,6 +261,31 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
...
@@ -296,6 +261,31 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
end
end
describe
'Operations'
do
describe
'On-call schedules'
do
before
do
allow
(
view
).
to
receive
(
:current_user
).
and_return
(
user
)
stub_licensed_features
(
oncall_schedules:
true
)
end
it
'has a link to the on-call schedules page'
do
render
expect
(
rendered
).
to
have_link
(
'On-call Schedules'
,
href:
project_incident_management_oncall_schedules_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the on-call schedules page'
do
render
expect
(
rendered
).
not_to
have_link
(
'On-call Schedules'
)
end
end
end
end
describe
'Settings > Operations'
do
describe
'Settings > Operations'
do
it
'is not visible when no valid license'
do
it
'is not visible when no valid license'
do
allow
(
view
).
to
receive
(
:can?
).
and_return
(
true
)
allow
(
view
).
to
receive
(
:can?
).
and_return
(
true
)
...
...
lib/sidebars/projects/menus/operations_menu.rb
0 → 100644
View file @
087d90af
# frozen_string_literal: true
module
Sidebars
module
Projects
module
Menus
class
OperationsMenu
<
::
Sidebars
::
Menu
override
:configure_menu_items
def
configure_menu_items
return
false
unless
context
.
project
.
feature_available?
(
:operations
,
context
.
current_user
)
add_item
(
metrics_dashboard_menu_item
)
add_item
(
logs_menu_item
)
add_item
(
tracing_menu_item
)
add_item
(
error_tracking_menu_item
)
add_item
(
alert_management_menu_item
)
add_item
(
incidents_menu_item
)
add_item
(
serverless_menu_item
)
add_item
(
terraform_menu_item
)
add_item
(
kubernetes_menu_item
)
add_item
(
environments_menu_item
)
add_item
(
feature_flags_menu_item
)
add_item
(
product_analytics_menu_item
)
true
end
override
:link
def
link
if
can?
(
context
.
current_user
,
:read_environment
,
context
.
project
)
metrics_project_environments_path
(
context
.
project
)
else
project_feature_flags_path
(
context
.
project
)
end
end
override
:extra_container_html_options
def
extra_container_html_options
{
class:
'shortcuts-operations'
}
end
override
:title
def
title
_
(
'Operations'
)
end
override
:sprite_icon
def
sprite_icon
'cloud-gear'
end
override
:active_routes
def
active_routes
{
controller:
[
:user
,
:gcp
]
}
end
private
def
metrics_dashboard_menu_item
return
unless
can?
(
context
.
current_user
,
:metrics_dashboard
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Metrics'
),
link:
project_metrics_dashboard_path
(
context
.
project
),
active_routes:
{
path:
'metrics_dashboard#show'
},
container_html_options:
{
class:
'shortcuts-metrics'
},
item_id: :metrics
)
end
def
logs_menu_item
return
unless
can?
(
context
.
current_user
,
:read_environment
,
context
.
project
)
return
unless
can?
(
context
.
current_user
,
:read_pod_logs
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Logs'
),
link:
project_logs_path
(
context
.
project
),
active_routes:
{
path:
'logs#index'
},
item_id: :logs
)
end
def
tracing_menu_item
return
unless
can?
(
context
.
current_user
,
:read_environment
,
context
.
project
)
return
unless
can?
(
context
.
current_user
,
:admin_project
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Tracing'
),
link:
project_tracing_path
(
context
.
project
),
active_routes:
{
path:
'tracings#show'
},
item_id: :tracing
)
end
def
error_tracking_menu_item
return
unless
can?
(
context
.
current_user
,
:read_sentry_issue
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Error Tracking'
),
link:
project_error_tracking_index_path
(
context
.
project
),
active_routes:
{
controller: :error_tracking
},
item_id: :error_tracking
)
end
def
alert_management_menu_item
return
unless
can?
(
context
.
current_user
,
:read_alert_management_alert
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Alerts'
),
link:
project_alert_management_index_path
(
context
.
project
),
active_routes:
{
controller: :alert_management
},
item_id: :alert_management
)
end
def
incidents_menu_item
return
unless
can?
(
context
.
current_user
,
:read_issue
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Incidents'
),
link:
project_incidents_path
(
context
.
project
),
active_routes:
{
controller:
[
:incidents
,
:incident_management
]
},
item_id: :incidents
)
end
def
serverless_menu_item
return
unless
can?
(
context
.
current_user
,
:read_cluster
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Serverless'
),
link:
project_serverless_functions_path
(
context
.
project
),
active_routes:
{
controller: :functions
},
item_id: :serverless
)
end
def
terraform_menu_item
return
unless
can?
(
context
.
current_user
,
:read_terraform_state
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Terraform'
),
link:
project_terraform_index_path
(
context
.
project
),
active_routes:
{
controller: :terraform
},
item_id: :terraform
)
end
def
kubernetes_menu_item
return
unless
can?
(
context
.
current_user
,
:read_cluster
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Kubernetes'
),
link:
project_clusters_path
(
context
.
project
),
active_routes:
{
controller:
[
:cluster_agents
,
:clusters
]
},
container_html_options:
{
class:
'shortcuts-kubernetes'
},
hint_html_options:
kubernetes_hint_html_options
,
item_id: :kubernetes
)
end
def
kubernetes_hint_html_options
return
{}
unless
context
.
show_cluster_hint
{
disabled:
true
,
data:
{
trigger:
'manual'
,
container:
'body'
,
placement:
'right'
,
highlight:
UserCalloutsHelper
::
GKE_CLUSTER_INTEGRATION
,
highlight_priority:
UserCallout
.
feature_names
[
:GKE_CLUSTER_INTEGRATION
],
dismiss_endpoint:
user_callouts_path
,
auto_devops_help_path:
help_page_path
(
'topics/autodevops/index.md'
)
}
}
end
def
environments_menu_item
return
unless
can?
(
context
.
current_user
,
:read_environment
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Environments'
),
link:
project_environments_path
(
context
.
project
),
active_routes:
{
controller: :environments
},
container_html_options:
{
class:
'shortcuts-environments'
},
item_id: :environments
)
end
def
feature_flags_menu_item
return
unless
can?
(
context
.
current_user
,
:read_feature_flag
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Feature Flags'
),
link:
project_feature_flags_path
(
context
.
project
),
active_routes:
{
controller: :feature_flags
},
container_html_options:
{
class:
'shortcuts-feature-flags'
},
item_id: :feature_flags
)
end
def
product_analytics_menu_item
return
if
Feature
.
disabled?
(
:product_analytics
,
context
.
project
)
return
unless
can?
(
context
.
current_user
,
:read_product_analytics
,
context
.
project
)
::
Sidebars
::
MenuItem
.
new
(
title:
_
(
'Product Analytics'
),
link:
project_product_analytics_path
(
context
.
project
),
active_routes:
{
controller: :product_analytics
},
item_id: :product_analytics
)
end
end
end
end
end
Sidebars
::
Projects
::
Menus
::
OperationsMenu
.
prepend_if_ee
(
'EE::Sidebars::Projects::Menus::OperationsMenu'
)
lib/sidebars/projects/panel.rb
View file @
087d90af
...
@@ -16,6 +16,7 @@ module Sidebars
...
@@ -16,6 +16,7 @@ module Sidebars
add_menu
(
Sidebars
::
Projects
::
Menus
::
MergeRequestsMenu
.
new
(
context
))
add_menu
(
Sidebars
::
Projects
::
Menus
::
MergeRequestsMenu
.
new
(
context
))
add_menu
(
Sidebars
::
Projects
::
Menus
::
CiCdMenu
.
new
(
context
))
add_menu
(
Sidebars
::
Projects
::
Menus
::
CiCdMenu
.
new
(
context
))
add_menu
(
Sidebars
::
Projects
::
Menus
::
SecurityComplianceMenu
.
new
(
context
))
add_menu
(
Sidebars
::
Projects
::
Menus
::
SecurityComplianceMenu
.
new
(
context
))
add_menu
(
Sidebars
::
Projects
::
Menus
::
OperationsMenu
.
new
(
context
))
end
end
override
:render_raw_menus_partial
override
:render_raw_menus_partial
...
...
qa/qa/page/project/sub_menus/operations.rb
View file @
087d90af
...
@@ -12,20 +12,13 @@ module QA
...
@@ -12,20 +12,13 @@ module QA
base
.
class_eval
do
base
.
class_eval
do
include
QA
::
Page
::
Project
::
SubMenus
::
Common
include
QA
::
Page
::
Project
::
SubMenus
::
Common
view
'app/views/layouts/nav/sidebar/_project_menus.html.haml'
do
element
:operations_link
element
:operations_environments_link
element
:operations_metrics_link
element
:operations_incidents_link
end
end
end
end
end
def
go_to_operations_environments
def
go_to_operations_environments
hover_operations
do
hover_operations
do
within_submenu
do
within_submenu
do
click_element
(
:
operations_environments_link
)
click_element
(
:
sidebar_menu_item_link
,
menu_item:
'Environments'
)
end
end
end
end
end
end
...
@@ -33,7 +26,7 @@ module QA
...
@@ -33,7 +26,7 @@ module QA
def
go_to_operations_metrics
def
go_to_operations_metrics
hover_operations
do
hover_operations
do
within_submenu
do
within_submenu
do
click_element
(
:
operations_metrics_link
)
click_element
(
:
sidebar_menu_item_link
,
menu_item:
'Metrics'
)
end
end
end
end
end
end
...
@@ -49,7 +42,7 @@ module QA
...
@@ -49,7 +42,7 @@ module QA
def
go_to_operations_incidents
def
go_to_operations_incidents
hover_operations
do
hover_operations
do
within_submenu
do
within_submenu
do
click_element
(
:
operations_incidents_link
)
click_element
(
:
sidebar_menu_item_link
,
menu_item:
'Incidents'
)
end
end
end
end
end
end
...
@@ -58,8 +51,8 @@ module QA
...
@@ -58,8 +51,8 @@ module QA
def
hover_operations
def
hover_operations
within_sidebar
do
within_sidebar
do
scroll_to_element
(
:
operations_link
)
scroll_to_element
(
:
sidebar_menu_link
,
menu_item:
'Operations'
)
find_element
(
:
operations_link
).
hover
find_element
(
:
sidebar_menu_link
,
menu_item:
'Operations'
).
hover
yield
yield
end
end
...
...
spec/features/operations_sidebar_link_spec.rb
View file @
087d90af
This diff is collapsed.
Click to expand it.
spec/helpers/projects_helper_spec.rb
View file @
087d90af
...
@@ -477,43 +477,6 @@ RSpec.describe ProjectsHelper do
...
@@ -477,43 +477,6 @@ RSpec.describe ProjectsHelper do
end
end
end
end
describe
'#can_view_operations_tab?'
do
before
do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
helper
).
to
receive
(
:can?
).
and_return
(
false
)
end
subject
{
helper
.
send
(
:can_view_operations_tab?
,
user
,
project
)
}
where
(
:ability
)
do
[
:metrics_dashboard
,
:read_alert_management_alert
,
:read_environment
,
:read_issue
,
:read_sentry_issue
,
:read_cluster
]
end
with_them
do
it
'includes operations tab'
do
allow
(
helper
).
to
receive
(
:can?
).
with
(
user
,
ability
,
project
).
and_return
(
true
)
is_expected
.
to
be
(
true
)
end
context
'when operations feature is disabled'
do
it
'does not include operations tab'
do
allow
(
helper
).
to
receive
(
:can?
).
with
(
user
,
ability
,
project
).
and_return
(
true
)
project
.
project_feature
.
update_attribute
(
:operations_access_level
,
ProjectFeature
::
DISABLED
)
is_expected
.
to
be
(
false
)
end
end
end
end
describe
'#show_projects'
do
describe
'#show_projects'
do
let
(
:projects
)
do
let
(
:projects
)
do
Project
.
all
Project
.
all
...
...
spec/lib/sidebars/projects/menus/operations_menu_spec.rb
0 → 100644
View file @
087d90af
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Sidebars
::
Projects
::
Menus
::
OperationsMenu
do
let_it_be_with_refind
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
project
.
owner
}
let
(
:show_cluster_hint
)
{
true
}
let
(
:context
)
{
Sidebars
::
Projects
::
Context
.
new
(
current_user:
user
,
container:
project
,
show_cluster_hint:
show_cluster_hint
)
}
subject
{
described_class
.
new
(
context
)
}
describe
'#render?'
do
context
'when operations feature is disabled'
do
it
'returns false'
do
project
.
project_feature
.
update!
(
operations_access_level:
Featurable
::
DISABLED
)
expect
(
subject
.
render?
).
to
be
false
end
end
context
'when operation feature is enabled'
do
context
'when menu does not have any menu items'
do
it
'returns false'
do
allow
(
subject
).
to
receive
(
:has_items?
).
and_return
(
false
)
expect
(
subject
.
render?
).
to
be
false
end
end
context
'when menu has menu items'
do
it
'returns true'
do
expect
(
subject
.
render?
).
to
be
true
end
end
end
end
describe
'#link'
do
context
'when metrics dashboard is visible'
do
it
'returns link to the metrics dashboard page'
do
expect
(
subject
.
link
).
to
include
(
'/-/environments/metrics'
)
end
end
context
'when metrics dashboard is not visible'
do
it
'returns link to the feature flags page'
do
project
.
project_feature
.
update!
(
operations_access_level:
Featurable
::
DISABLED
)
expect
(
subject
.
link
).
to
include
(
'/-/feature_flags'
)
end
end
end
context
'Menu items'
do
subject
{
described_class
.
new
(
context
).
items
.
index
{
|
e
|
e
.
item_id
==
item_id
}
}
describe
'Metrics Dashboard'
do
let
(
:item_id
)
{
:metrics
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Logs'
do
let
(
:item_id
)
{
:logs
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Tracing'
do
let
(
:item_id
)
{
:tracing
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Error Tracking'
do
let
(
:item_id
)
{
:error_tracking
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Alert Management'
do
let
(
:item_id
)
{
:alert_management
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Incidents'
do
let
(
:item_id
)
{
:incidents
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Serverless'
do
let
(
:item_id
)
{
:serverless
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Terraform'
do
let
(
:item_id
)
{
:terraform
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Kubernetes'
do
let
(
:item_id
)
{
:kubernetes
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Environments'
do
let
(
:item_id
)
{
:environments
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Feature Flags'
do
let
(
:item_id
)
{
:feature_flags
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
specify
{
is_expected
.
to
be_nil
}
end
end
describe
'Product Analytics'
do
let
(
:item_id
)
{
:product_analytics
}
specify
{
is_expected
.
not_to
be_nil
}
describe
'when feature flag :product_analytics is disabled'
do
specify
do
stub_feature_flags
(
product_analytics:
false
)
is_expected
.
to
be_nil
end
end
end
end
end
spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
View file @
087d90af
...
@@ -348,6 +348,238 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
...
@@ -348,6 +348,238 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
end
end
describe
'Operations'
do
it
'top level navigation link is visible for user with permissions'
do
render
expect
(
rendered
).
to
have_link
(
'Operations'
)
end
describe
'Metrics Dashboard'
do
it
'has a link to the metrics dashboard page'
do
render
expect
(
rendered
).
to
have_link
(
'Metrics'
,
href:
project_metrics_dashboard_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the metrics page'
do
render
expect
(
rendered
).
not_to
have_link
(
'Metrics'
)
end
end
end
describe
'Logs'
do
it
'has a link to the pod logs page'
do
render
expect
(
rendered
).
to
have_link
(
'Logs'
,
href:
project_logs_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the pod logs page'
do
render
expect
(
rendered
).
not_to
have_link
(
'Logs'
)
end
end
end
describe
'Tracing'
do
it
'has a link to the tracing page'
do
render
expect
(
rendered
).
to
have_link
(
'Tracing'
,
href:
project_tracing_path
(
project
))
end
context
'without project.tracing_external_url'
do
it
'has a link to the tracing page'
do
render
expect
(
rendered
).
to
have_link
(
'Tracing'
,
href:
project_tracing_path
(
project
))
end
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the tracing page'
do
render
expect
(
rendered
).
not_to
have_text
'Tracing'
end
end
end
describe
'Error Tracking'
do
it
'has a link to the error tracking page'
do
render
expect
(
rendered
).
to
have_link
(
'Error Tracking'
,
href:
project_error_tracking_index_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the error tracking page'
do
render
expect
(
rendered
).
not_to
have_link
(
'Error Tracking'
)
end
end
end
describe
'Alert Management'
do
it
'has a link to the alert management page'
do
render
expect
(
rendered
).
to
have_link
(
'Alerts'
,
href:
project_alert_management_index_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the alert management page'
do
render
expect
(
rendered
).
not_to
have_link
(
'Alerts'
)
end
end
end
describe
'Incidents'
do
it
'has a link to the incidents page'
do
render
expect
(
rendered
).
to
have_link
(
'Incidents'
,
href:
project_incidents_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the incidents page'
do
render
expect
(
rendered
).
not_to
have_link
(
'Incidents'
)
end
end
end
describe
'Serverless'
do
it
'has a link to the serverless page'
do
render
expect
(
rendered
).
to
have_link
(
'Serverless'
,
href:
project_serverless_functions_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the serverless page'
do
render
expect
(
rendered
).
not_to
have_link
(
'Serverless'
)
end
end
end
describe
'Terraform'
do
it
'has a link to the terraform page'
do
render
expect
(
rendered
).
to
have_link
(
'Terraform'
,
href:
project_terraform_index_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the terraform page'
do
render
expect
(
rendered
).
not_to
have_link
(
'Terraform'
)
end
end
end
describe
'Kubernetes'
do
it
'has a link to the kubernetes page'
do
render
expect
(
rendered
).
to
have_link
(
'Kubernetes'
,
href:
project_clusters_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the kubernetes page'
do
render
expect
(
rendered
).
not_to
have_link
(
'Kubernetes'
)
end
end
end
describe
'Environments'
do
it
'has a link to the environments page'
do
render
expect
(
rendered
).
to
have_link
(
'Environments'
,
href:
project_environments_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the environments page'
do
render
expect
(
rendered
).
not_to
have_link
(
'Environments'
)
end
end
end
describe
'Feature Flags'
do
it
'has a link to the feature flags page'
do
render
expect
(
rendered
).
to
have_link
(
'Feature Flags'
,
href:
project_feature_flags_path
(
project
))
end
describe
'when the user does not have access'
do
let
(
:user
)
{
nil
}
it
'does not have a link to the feature flags page'
do
render
expect
(
rendered
).
not_to
have_link
(
'Feature Flags'
)
end
end
end
describe
'Product Analytics'
do
it
'has a link to the product analytics page'
do
render
expect
(
rendered
).
to
have_link
(
'Product Analytics'
,
href:
project_product_analytics_path
(
project
))
end
describe
'when feature flag :product_analytics is disabled'
do
it
'does not have a link to the feature flags page'
do
stub_feature_flags
(
product_analytics:
false
)
render
expect
(
rendered
).
not_to
have_link
(
'Product Analytics'
)
end
end
end
end
describe
'packages tab'
do
describe
'packages tab'
do
before
do
before
do
stub_container_registry_config
(
enabled:
true
)
stub_container_registry_config
(
enabled:
true
)
...
@@ -510,6 +742,32 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
...
@@ -510,6 +742,32 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
end
end
describe
'value stream analytics entry'
do
let
(
:read_cycle_analytics
)
{
true
}
before
do
allow
(
view
).
to
receive
(
:can?
).
with
(
user
,
:read_cycle_analytics
,
project
).
and_return
(
read_cycle_analytics
)
end
describe
'when value stream analytics is enabled'
do
it
'shows the value stream analytics entry'
do
render
expect
(
rendered
).
to
have_link
(
'Value Stream'
,
href:
project_cycle_analytics_path
(
project
))
end
end
describe
'when value stream analytics is disabled'
do
let
(
:read_cycle_analytics
)
{
false
}
it
'does not show the value stream analytics entry'
do
render
expect
(
rendered
).
not_to
have_link
(
'Value Stream'
,
href:
project_cycle_analytics_path
(
project
))
end
end
end
describe
'operations settings tab'
do
describe
'operations settings tab'
do
describe
'archive projects'
do
describe
'archive projects'
do
before
do
before
do
...
@@ -536,64 +794,6 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
...
@@ -536,64 +794,6 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
end
end
end
end
describe
'Tracing'
do
it
'is not visible to unauthorized user'
do
allow
(
view
).
to
receive
(
:can?
).
and_return
(
false
)
render
expect
(
rendered
).
not_to
have_text
'Tracing'
end
it
'links to Tracing page'
do
render
expect
(
rendered
).
to
have_link
(
'Tracing'
,
href:
project_tracing_path
(
project
))
end
context
'without project.tracing_external_url'
do
it
'links to Tracing page'
do
render
expect
(
rendered
).
to
have_link
(
'Tracing'
,
href:
project_tracing_path
(
project
))
end
end
end
describe
'Alert Management'
do
it
'shows the Alerts sidebar entry'
do
render
expect
(
rendered
).
to
have_css
(
'a[title="Alerts"]'
)
end
end
end
describe
'value stream analytics entry'
do
let
(
:read_cycle_analytics
)
{
true
}
before
do
allow
(
view
).
to
receive
(
:can?
).
with
(
user
,
:read_cycle_analytics
,
project
).
and_return
(
read_cycle_analytics
)
end
describe
'when value stream analytics is enabled'
do
it
'shows the value stream analytics entry'
do
render
expect
(
rendered
).
to
have_link
(
'Value Stream'
,
href:
project_cycle_analytics_path
(
project
))
end
end
describe
'when value stream analytics is disabled'
do
let
(
:read_cycle_analytics
)
{
false
}
it
'does not show the value stream analytics entry'
do
render
expect
(
rendered
).
not_to
have_link
(
'Value Stream'
,
href:
project_cycle_analytics_path
(
project
))
end
end
end
end
describe
'project access tokens'
do
describe
'project access tokens'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment