summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2017-02-09 08:32:40 +0000
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2017-02-09 08:32:40 +0000
commit059d1ae4c847aa9018c89900b39c2782aa9b623e (patch)
treeb545c97a885ec40ef238c168515629b251e40fbb
parent3d20670058eba11b470bfd318a4842197b3bb122 (diff)
parentf39dbf3d3d4d5c99910043e8793a96246f0039fe (diff)
downloadgitlab-ce-059d1ae4c847aa9018c89900b39c2782aa9b623e.tar.gz
Merge branch 'dz-create-nested-groups-via-ui' into 'master'
Allow creating nested group via UI See merge request !8786
-rw-r--r--app/controllers/groups_controller.rb33
-rw-r--r--app/views/groups/_home_panel.html.haml17
-rw-r--r--app/views/groups/_show_nav.html.haml7
-rw-r--r--app/views/groups/show.html.haml43
-rw-r--r--app/views/groups/subgroups.html.haml20
-rw-r--r--app/views/shared/_group_form.html.haml7
-rw-r--r--app/views/shared/groups/_group.html.haml6
-rw-r--r--app/views/shared/projects/_dropdown.html.haml12
-rw-r--r--changelogs/unreleased/dz-create-nested-groups-via-ui.yml4
-rw-r--r--config/routes/group.rb1
-rw-r--r--spec/features/groups_spec.rb19
11 files changed, 115 insertions, 54 deletions
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 9b6c3dd33b8..7ed54479599 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -13,9 +13,11 @@ class GroupsController < Groups::ApplicationController
before_action :authorize_create_group!, only: [:new, :create]
# Load group projects
- before_action :group_projects, only: [:show, :projects, :activity, :issues, :merge_requests]
+ before_action :group_projects, only: [:projects, :activity, :issues, :merge_requests]
before_action :event_filter, only: [:activity]
+ before_action :user_actions, only: [:show, :subgroups]
+
layout :determine_layout
def index
@@ -37,13 +39,6 @@ class GroupsController < Groups::ApplicationController
end
def show
- if current_user
- @last_push = current_user.recent_push
- @notification_setting = current_user.notification_settings_for(group)
- end
-
- @nested_groups = group.children
-
setup_projects
respond_to do |format|
@@ -62,6 +57,11 @@ class GroupsController < Groups::ApplicationController
end
end
+ def subgroups
+ @nested_groups = group.children
+ @nested_groups = @nested_groups.search(params[:filter_groups]) if params[:filter_groups].present?
+ end
+
def activity
respond_to do |format|
format.html
@@ -99,13 +99,16 @@ class GroupsController < Groups::ApplicationController
protected
def setup_projects
+ options = {}
+ options[:only_owned] = true if params[:shared] == '0'
+ options[:only_shared] = true if params[:shared] == '1'
+
+ @projects = GroupProjectsFinder.new(group, options).execute(current_user)
@projects = @projects.includes(:namespace)
@projects = @projects.sorted_by_activity
@projects = filter_projects(@projects)
@projects = @projects.sort(@sort = params[:sort])
@projects = @projects.page(params[:page]) if params[:filter_projects].blank?
-
- @shared_projects = GroupProjectsFinder.new(group, only_shared: true).execute(current_user)
end
def authorize_create_group!
@@ -138,7 +141,8 @@ class GroupsController < Groups::ApplicationController
:public,
:request_access_enabled,
:share_with_group_lock,
- :visibility_level
+ :visibility_level,
+ :parent_id
]
end
@@ -147,4 +151,11 @@ class GroupsController < Groups::ApplicationController
@events = event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0)
end
+
+ def user_actions
+ if current_user
+ @last_push = current_user.recent_push
+ @notification_setting = current_user.notification_settings_for(group)
+ end
+ end
end
diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml
new file mode 100644
index 00000000000..41f54f6bf42
--- /dev/null
+++ b/app/views/groups/_home_panel.html.haml
@@ -0,0 +1,17 @@
+.group-home-panel.text-center
+ %div{ class: container_class }
+ .avatar-container.s70.group-avatar
+ = image_tag group_icon(@group), class: "avatar s70 avatar-tile"
+ %h1.group-title
+ @#{@group.path}
+ %span.visibility-icon.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) }
+ = visibility_level_icon(@group.visibility_level, fw: false)
+
+ - if @group.description.present?
+ .group-home-desc
+ = markdown_field(@group, :description)
+
+ - if current_user
+ .group-buttons
+ = render 'shared/members/access_request_buttons', source: @group
+ = render 'shared/notifications/button', notification_setting: @notification_setting
diff --git a/app/views/groups/_show_nav.html.haml b/app/views/groups/_show_nav.html.haml
new file mode 100644
index 00000000000..b2097e88741
--- /dev/null
+++ b/app/views/groups/_show_nav.html.haml
@@ -0,0 +1,7 @@
+%ul.nav-links
+ = nav_link(page: group_path(@group)) do
+ = link_to group_path(@group) do
+ Projects
+ = nav_link(page: subgroups_group_path(@group)) do
+ = link_to subgroups_group_path(@group) do
+ Subgroups
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index d256d14609e..b040f404ac4 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -4,38 +4,12 @@
- if current_user
= auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
-.group-home-panel.text-center
- %div{ class: container_class }
- .avatar-container.s70.group-avatar
- = image_tag group_icon(@group), class: "avatar s70 avatar-tile"
- %h1.group-title
- @#{@group.path}
- %span.visibility-icon.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) }
- = visibility_level_icon(@group.visibility_level, fw: false)
+= render 'groups/home_panel'
- - if @group.description.present?
- .group-home-desc
- = markdown_field(@group, :description)
-
- - if current_user
- .group-buttons
- = render 'shared/members/access_request_buttons', source: @group
- = render 'shared/notifications/button', notification_setting: @notification_setting
.groups-header{ class: container_class }
.top-area
- %ul.nav-links
- %li.active
- = link_to "#projects", 'data-toggle' => 'tab' do
- All Projects
- - if @shared_projects.present?
- %li
- = link_to "#shared", 'data-toggle' => 'tab' do
- Shared Projects
- - if @nested_groups.present?
- %li
- = link_to "#groups", 'data-toggle' => 'tab' do
- Subgroups
+ = render 'groups/show_nav'
.nav-controls
= form_tag request.path, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f|
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control', spellcheck: false
@@ -44,15 +18,4 @@
= link_to new_project_path(namespace_id: @group.id), class: 'btn btn-new pull-right' do
New Project
- .tab-content
- .tab-pane.active#projects
- = render "projects", projects: @projects
-
- - if @shared_projects.present?
- .tab-pane#shared
- = render "shared_projects", projects: @shared_projects
-
- - if @nested_groups.present?
- .tab-pane#groups
- %ul.content-list
- = render partial: 'shared/groups/group', collection: @nested_groups
+ = render "projects", projects: @projects
diff --git a/app/views/groups/subgroups.html.haml b/app/views/groups/subgroups.html.haml
new file mode 100644
index 00000000000..8610ae7e0ef
--- /dev/null
+++ b/app/views/groups/subgroups.html.haml
@@ -0,0 +1,20 @@
+- @no_container = true
+
+= render 'groups/home_panel'
+
+.groups-header{ class: container_class }
+ .top-area
+ = render 'groups/show_nav'
+ .nav-controls
+ = form_tag request.path, method: :get do |f|
+ = search_field_tag :filter_groups, params[:filter_groups], placeholder: 'Filter by name', class: 'form-control', spellcheck: false
+ - if can? current_user, :admin_group, @group
+ = link_to new_group_path(parent_id: @group.id), class: 'btn btn-new pull-right' do
+ New Subgroup
+
+ - if @nested_groups.present?
+ %ul.content-list
+ = render partial: 'shared/groups/group', collection: @nested_groups, locals: { full_name: false }
+ - else
+ .nothing-here-block
+ There are no subgroups to show.
diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml
index 0bc851b4256..efb207b9916 100644
--- a/app/views/shared/_group_form.html.haml
+++ b/app/views/shared/_group_form.html.haml
@@ -1,3 +1,4 @@
+- parent = Group.find_by(id: params[:parent_id] || @group.parent_id)
- if @group.persisted?
.form-group
= f.label :name, class: 'control-label' do
@@ -11,11 +12,15 @@
.col-sm-10
.input-group.gl-field-error-anchor
.input-group-addon
- = root_url
+ %span>= root_url
+ - if parent
+ %strong= parent.full_path + '/'
= f.text_field :path, placeholder: 'open-source', class: 'form-control',
autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::Regex::NAMESPACE_REGEX_STR_SIMPLE,
title: 'Please choose a group name with no special characters.'
+ - if parent
+ = f.hidden_field :parent_id, value: parent.id
- if @group.persisted?
.alert.alert-warning.prepend-top-10
diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml
index dd9e433491b..60ca23ef680 100644
--- a/app/views/shared/groups/_group.html.haml
+++ b/app/views/shared/groups/_group.html.haml
@@ -1,4 +1,5 @@
- group_member = local_assigns[:group_member]
+- full_name = true unless local_assigns[:full_name] == false
- css_class = '' unless local_assigns[:css_class]
- css_class += " no-description" if group.description.blank?
@@ -28,7 +29,10 @@
= image_tag group_icon(group), class: "avatar s40 hidden-xs"
.title
= link_to group, class: 'group-name' do
- = group.full_name
+ - if full_name
+ = group.full_name
+ - else
+ = group.name
- if group_member
as
diff --git a/app/views/shared/projects/_dropdown.html.haml b/app/views/shared/projects/_dropdown.html.haml
index ac028f18e50..c19697802ce 100644
--- a/app/views/shared/projects/_dropdown.html.haml
+++ b/app/views/shared/projects/_dropdown.html.haml
@@ -1,6 +1,7 @@
- @sort ||= sort_value_recently_updated
- personal = params[:personal]
- archived = params[:archived]
+- shared = params[:shared]
- namespace_id = params[:namespace_id]
.dropdown
- toggle_text = projects_sort_options_hash[@sort]
@@ -28,3 +29,14 @@
%li
= link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, personal: true), class: ("is-active" if personal.present?) do
Owned by me
+ - if @group && @group.shared_projects.present?
+ %li.divider
+ %li
+ = link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, shared: nil), class: ("is-active" unless shared.present?) do
+ All projects
+ %li
+ = link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, shared: 0), class: ("is-active" if shared == '0') do
+ Hide shared projects
+ %li
+ = link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, shared: 1), class: ("is-active" if shared == '1') do
+ Hide group projects
diff --git a/changelogs/unreleased/dz-create-nested-groups-via-ui.yml b/changelogs/unreleased/dz-create-nested-groups-via-ui.yml
new file mode 100644
index 00000000000..f9529a5941a
--- /dev/null
+++ b/changelogs/unreleased/dz-create-nested-groups-via-ui.yml
@@ -0,0 +1,4 @@
+---
+title: Allow creating nested groups via UI
+merge_request: 8786
+author:
diff --git a/config/routes/group.rb b/config/routes/group.rb
index 60a1175fe80..73f69d76995 100644
--- a/config/routes/group.rb
+++ b/config/routes/group.rb
@@ -25,5 +25,6 @@ scope(path: 'groups/*id',
get :merge_requests, as: :merge_requests_group
get :projects, as: :projects_group
get :activity, as: :activity_group
+ get :subgroups, as: :subgroups_group
get '/', action: :show, as: :group_canonical
end
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index a515c92db37..37b7c20239f 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -45,6 +45,23 @@ feature 'Group', feature: true do
end
end
+ describe 'create a nested group' do
+ let(:group) { create(:group, path: 'foo') }
+
+ before do
+ visit subgroups_group_path(group)
+ click_link 'New Subgroup'
+ end
+
+ it 'creates a nested group' do
+ fill_in 'Group path', with: 'bar'
+ click_button 'Create group'
+
+ expect(current_path).to eq(group_path('foo/bar'))
+ expect(page).to have_content("Group 'bar' was successfully created.")
+ end
+ end
+
describe 'group edit' do
let(:group) { create(:group) }
let(:path) { edit_group_path(group) }
@@ -117,7 +134,7 @@ feature 'Group', feature: true do
visit path
click_link 'Subgroups'
- expect(page).to have_content(nested_group.full_name)
+ expect(page).to have_content(nested_group.name)
end
end
end