diff options
Diffstat (limited to 'app/helpers/nav')
-rw-r--r-- | app/helpers/nav/new_dropdown_helper.rb | 188 | ||||
-rw-r--r-- | app/helpers/nav/top_nav_helper.rb | 148 |
2 files changed, 285 insertions, 51 deletions
diff --git a/app/helpers/nav/new_dropdown_helper.rb b/app/helpers/nav/new_dropdown_helper.rb new file mode 100644 index 00000000000..b952aeacb13 --- /dev/null +++ b/app/helpers/nav/new_dropdown_helper.rb @@ -0,0 +1,188 @@ +# frozen_string_literal: true + +module Nav + module NewDropdownHelper + def new_dropdown_view_model(group:, project:) + return unless current_user + + menu_sections = [] + + if group&.persisted? + menu_sections.push(group_menu_section(group)) + elsif project&.persisted? + menu_sections.push(project_menu_section(project)) + end + + menu_sections.push(general_menu_section) + + { + title: _("New..."), + menu_sections: menu_sections.select { |x| x.fetch(:menu_items).any? } + } + end + + def new_repo_experiment_text + experiment(:new_repo, user: current_user) do |e| + e.use { _('New project') } + e.try { _('New project/repository') } + end.run + end + + private + + def group_menu_section(group) + menu_items = [] + + if can?(current_user, :create_projects, group) + menu_items.push( + ::Gitlab::Nav::TopNavMenuItem.build( + id: 'new_project', + title: new_repo_experiment_text, + href: new_project_path(namespace_id: group.id), + data: { track_experiment: 'new_repo', track_event: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' } + ) + ) + end + + if can?(current_user, :create_subgroup, group) + menu_items.push( + ::Gitlab::Nav::TopNavMenuItem.build( + id: 'new_subgroup', + title: _('New subgroup'), + href: new_group_path(parent_id: group.id), + data: { track_event: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' } + ) + ) + end + + menu_items.push(create_epic_menu_item(group)) + + if Gitlab::Experimentation.active?(:invite_members_new_dropdown) && can?(current_user, :admin_group_member, group) + menu_items.push( + invite_members_menu_item( + href: group_group_members_path(group) + ) + ) + end + + { + title: _('This group'), + menu_items: menu_items.compact + } + end + + def project_menu_section(project) + menu_items = [] + merge_project = merge_request_source_project_for_project(project) + + if show_new_issue_link?(project) + menu_items.push( + ::Gitlab::Nav::TopNavMenuItem.build( + id: 'new_issue', + title: _('New issue'), + href: new_project_issue_path(project), + data: { track_event: 'click_link_new_issue', track_label: 'plus_menu_dropdown', qa_selector: 'new_issue_link' } + ) + ) + end + + if merge_project + menu_items.push( + ::Gitlab::Nav::TopNavMenuItem.build( + id: 'new_mr', + title: _('New merge request'), + href: project_new_merge_request_path(merge_project), + data: { track_event: 'click_link_new_mr', track_label: 'plus_menu_dropdown' } + ) + ) + end + + if can?(current_user, :create_snippet, project) + menu_items.push( + ::Gitlab::Nav::TopNavMenuItem.build( + id: 'new_snippet', + title: _('New snippet'), + href: new_project_snippet_path(project), + data: { track_event: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' } + ) + ) + end + + if Gitlab::Experimentation.active?(:invite_members_new_dropdown) && can_import_members? + menu_items.push( + invite_members_menu_item( + href: project_project_members_path(project) + ) + ) + end + + { + title: _('This project'), + menu_items: menu_items + } + end + + def general_menu_section + menu_items = [] + + if current_user.can_create_project? + menu_items.push( + ::Gitlab::Nav::TopNavMenuItem.build( + id: 'general_new_project', + title: new_repo_experiment_text, + href: new_project_path, + data: { track_experiment: 'new_repo', track_event: 'click_link_new_project', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_project_link' } + ) + ) + end + + if current_user.can_create_group? + menu_items.push( + ::Gitlab::Nav::TopNavMenuItem.build( + id: 'general_new_group', + title: _('New group'), + href: new_group_path, + data: { track_event: 'click_link_new_group', track_label: 'plus_menu_dropdown' } + ) + ) + end + + if current_user.can?(:create_snippet) + menu_items.push( + ::Gitlab::Nav::TopNavMenuItem.build( + id: 'general_new_snippet', + title: _('New snippet'), + href: new_snippet_path, + data: { track_event: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_snippet_link' } + ) + ) + end + + { + title: _('GitLab'), + menu_items: menu_items + } + end + + def invite_members_menu_item(href:) + ::Gitlab::Nav::TopNavMenuItem.build( + id: 'invite', + title: s_('InviteMember|Invite members'), + emoji: ('shaking_hands' if experiment_enabled?(:invite_members_new_dropdown)), + href: href, + data: { + track_event: 'click_link', + track_label: tracking_label, + track_property: experiment_tracking_category_and_group(:invite_members_new_dropdown) + } + ) + end + + # Overridden in EE + def create_epic_menu_item(group) + nil + end + end +end + +Nav::NewDropdownHelper.prepend_mod diff --git a/app/helpers/nav/top_nav_helper.rb b/app/helpers/nav/top_nav_helper.rb index 159b7ca87f9..b8ddb932b73 100644 --- a/app/helpers/nav/top_nav_helper.rb +++ b/app/helpers/nav/top_nav_helper.rb @@ -4,52 +4,90 @@ module Nav module TopNavHelper PROJECTS_VIEW = :projects GROUPS_VIEW = :groups + NEW_VIEW = :new + SEARCH_VIEW = :search def top_nav_view_model(project:, group:) builder = ::Gitlab::Nav::TopNavViewModelBuilder.new - if current_user - build_view_model(builder: builder, project: project, group: group) - else - build_anonymous_view_model(builder: builder) + build_base_view_model(builder: builder, project: project, group: group) + + builder.build + end + + def top_nav_responsive_view_model(project:, group:) + builder = ::Gitlab::Nav::TopNavViewModelBuilder.new + + build_base_view_model(builder: builder, project: project, group: group) + + new_view_model = new_dropdown_view_model(project: project, group: group) + + if new_view_model + builder.add_view(NEW_VIEW, new_view_model) + end + + if top_nav_show_search + builder.add_view(SEARCH_VIEW, ::Gitlab::Nav::TopNavMenuItem.build(**top_nav_search_menu_item_attrs)) end builder.build end + def top_nav_show_search + header_link?(:search) + end + + def top_nav_search_menu_item_attrs + { + id: 'search', + title: _('Search'), + icon: 'search', + href: search_context.search_url + } + end + private + def build_base_view_model(builder:, project:, group:) + if current_user + build_view_model(builder: builder, project: project, group: group) + else + build_anonymous_view_model(builder: builder) + end + end + def build_anonymous_view_model(builder:) # These come from `app/views/layouts/nav/_explore.html.ham` if explore_nav_link?(:projects) - builder.add_primary_menu_item( - **projects_menu_item_attrs.merge( - { - active: active_nav_link?(path: %w[dashboard#show root#show projects#trending projects#starred projects#index]), - href: explore_root_path - }) + builder.add_primary_menu_item_with_shortcut( + href: explore_root_path, + active: nav == 'project' || active_nav_link?(path: %w[dashboard#show root#show projects#trending projects#starred projects#index]), + **projects_menu_item_attrs ) end if explore_nav_link?(:groups) - builder.add_primary_menu_item( - **groups_menu_item_attrs.merge( - { - active: active_nav_link?(controller: [:groups, 'groups/milestones', 'groups/group_members']), - href: explore_groups_path - }) + builder.add_primary_menu_item_with_shortcut( + href: explore_groups_path, + active: nav == 'group' || active_nav_link?(controller: [:groups, 'groups/milestones', 'groups/group_members']), + **groups_menu_item_attrs ) end if explore_nav_link?(:snippets) - builder.add_primary_menu_item( - **snippets_menu_item_attrs.merge( - { - active: active_nav_link?(controller: :snippets), - href: explore_snippets_path - }) + builder.add_primary_menu_item_with_shortcut( + active: active_nav_link?(controller: :snippets), + href: explore_snippets_path, + **snippets_menu_item_attrs ) end + + builder.add_secondary_menu_item( + id: 'help', + title: _('Help'), + icon: 'question-o', + href: help_path + ) end def build_view_model(builder:, project:, group:) @@ -57,13 +95,13 @@ module Nav if dashboard_nav_link?(:projects) current_item = project ? current_project(project: project) : {} - builder.add_primary_menu_item( - **projects_menu_item_attrs.merge({ - active: active_nav_link?(path: %w[root#index projects#trending projects#starred dashboard/projects#index]), - css_class: 'qa-projects-dropdown', - data: { track_label: "projects_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" }, - view: PROJECTS_VIEW - }) + builder.add_primary_menu_item_with_shortcut( + active: nav == 'project' || active_nav_link?(path: %w[root#index projects#trending projects#starred dashboard/projects#index]), + css_class: 'qa-projects-dropdown', + data: { track_label: "projects_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" }, + view: PROJECTS_VIEW, + shortcut_href: dashboard_projects_path, + **projects_menu_item_attrs ) builder.add_view(PROJECTS_VIEW, container_view_props(namespace: 'projects', current_item: current_item, submenu: projects_submenu)) end @@ -71,46 +109,47 @@ module Nav if dashboard_nav_link?(:groups) current_item = group ? current_group(group: group) : {} - builder.add_primary_menu_item( - **groups_menu_item_attrs.merge({ - active: active_nav_link?(path: %w[dashboard/groups explore/groups]), - css_class: 'qa-groups-dropdown', - data: { track_label: "groups_dropdown", track_event: "click_dropdown" }, - view: GROUPS_VIEW - }) + builder.add_primary_menu_item_with_shortcut( + active: nav == 'group' || active_nav_link?(path: %w[dashboard/groups explore/groups]), + css_class: 'qa-groups-dropdown', + data: { track_label: "groups_dropdown", track_event: "click_dropdown" }, + view: GROUPS_VIEW, + shortcut_href: dashboard_groups_path, + **groups_menu_item_attrs ) builder.add_view(GROUPS_VIEW, container_view_props(namespace: 'groups', current_item: current_item, submenu: groups_submenu)) end if dashboard_nav_link?(:milestones) - builder.add_primary_menu_item( + builder.add_primary_menu_item_with_shortcut( id: 'milestones', title: 'Milestones', + href: dashboard_milestones_path, active: active_nav_link?(controller: 'dashboard/milestones'), icon: 'clock', data: { qa_selector: 'milestones_link' }, - href: dashboard_milestones_path + shortcut_class: 'dashboard-shortcuts-milestones' ) end if dashboard_nav_link?(:snippets) - builder.add_primary_menu_item( - **snippets_menu_item_attrs.merge({ - active: active_nav_link?(controller: 'dashboard/snippets'), - data: { qa_selector: 'snippets_link' }, - href: dashboard_snippets_path - }) + builder.add_primary_menu_item_with_shortcut( + active: active_nav_link?(controller: 'dashboard/snippets'), + data: { qa_selector: 'snippets_link' }, + href: dashboard_snippets_path, + **snippets_menu_item_attrs ) end if dashboard_nav_link?(:activity) - builder.add_primary_menu_item( + builder.add_primary_menu_item_with_shortcut( id: 'activity', title: 'Activity', + href: activity_dashboard_path, active: active_nav_link?(path: 'dashboard#activity'), icon: 'history', data: { qa_selector: 'activity_link' }, - href: activity_dashboard_path + shortcut_class: 'dashboard-shortcuts-activity' ) end @@ -137,7 +176,7 @@ module Nav active: active_nav_link?(controller: 'admin/sessions'), icon: 'lock-open', href: destroy_admin_session_path, - method: :post + data: { method: 'post' } ) elsif current_user.admin? builder.add_secondary_menu_item( @@ -165,7 +204,8 @@ module Nav { id: 'project', title: _('Projects'), - icon: 'project' + icon: 'project', + shortcut_class: 'dashboard-shortcuts-projects' } end @@ -173,7 +213,8 @@ module Nav { id: 'groups', title: 'Groups', - icon: 'group' + icon: 'group', + shortcut_class: 'dashboard-shortcuts-groups' } end @@ -181,7 +222,8 @@ module Nav { id: 'snippets', title: _('Snippets'), - icon: 'snippet' + icon: 'snippet', + shortcut_class: 'dashboard-shortcuts-snippets' } end @@ -234,7 +276,11 @@ module Nav builder = ::Gitlab::Nav::TopNavMenuBuilder.new builder.add_primary_menu_item(id: 'your', title: _('Your groups'), href: dashboard_groups_path) builder.add_primary_menu_item(id: 'explore', title: _('Explore groups'), href: explore_groups_path) - builder.add_secondary_menu_item(id: 'create', title: _('Create group'), href: new_group_path(anchor: 'create-group-pane')) + + if current_user.can_create_group? + builder.add_secondary_menu_item(id: 'create', title: _('Create group'), href: new_group_path) + end + builder.build end end |