Commit d6450bb2 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'dz-nested-groups-improvements-2' into 'master'

Nested groups improvements pt 2

See merge request !8827
parents 4468104f ba2d7eda
...@@ -59,11 +59,11 @@ ...@@ -59,11 +59,11 @@
} else { } else {
avatar = gon.default_avatar_url; avatar = gon.default_avatar_url;
} }
return "<div class='group-result'> <div class='group-name'>" + group.name + "</div> <div class='group-path'>" + group.path + "</div> </div>"; return "<div class='group-result'> <div class='group-name'>" + group.full_name + "</div> <div class='group-path'>" + group.full_path + "</div> </div>";
}; };
GroupsSelect.prototype.formatSelection = function(group) { GroupsSelect.prototype.formatSelection = function(group) {
return group.name; return group.full_name;
}; };
return GroupsSelect; return GroupsSelect;
......
...@@ -13,12 +13,12 @@ ...@@ -13,12 +13,12 @@
filterable: true, filterable: true,
fieldName: 'group_id', fieldName: 'group_id',
search: { search: {
fields: ['name'] fields: ['full_name']
}, },
data: function(term, callback) { data: function(term, callback) {
return Api.groups(term, {}, function(data) { return Api.groups(term, {}, function(data) {
data.unshift({ data.unshift({
name: 'Any' full_name: 'Any'
}); });
data.splice(1, 0, 'divider'); data.splice(1, 0, 'divider');
return callback(data); return callback(data);
...@@ -28,10 +28,10 @@ ...@@ -28,10 +28,10 @@
return obj.id; return obj.id;
}, },
text: function(obj) { text: function(obj) {
return obj.name; return obj.full_name;
}, },
toggleLabel: function(obj) { toggleLabel: function(obj) {
return ($groupDropdown.data('default-label')) + " " + obj.name; return ($groupDropdown.data('default-label')) + " " + obj.full_name;
}, },
clicked: (function(_this) { clicked: (function(_this) {
return function() { return function() {
......
...@@ -89,7 +89,7 @@ module SearchHelper ...@@ -89,7 +89,7 @@ module SearchHelper
{ {
category: "Groups", category: "Groups",
id: group.id, id: group.id,
label: "#{search_result_sanitize(group.name)}", label: "#{search_result_sanitize(group.full_name)}",
url: group_path(group) url: group_path(group)
} }
end end
......
...@@ -225,6 +225,7 @@ class Project < ActiveRecord::Base ...@@ -225,6 +225,7 @@ class Project < ActiveRecord::Base
scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') } scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') }
scope :with_statistics, -> { includes(:statistics) } scope :with_statistics, -> { includes(:statistics) }
scope :with_shared_runners, -> { where(shared_runners_enabled: true) } scope :with_shared_runners, -> { where(shared_runners_enabled: true) }
scope :inside_path, ->(path) { joins(:route).where('routes.path LIKE ?', "#{path}/%") }
# "enabled" here means "not disabled". It includes private features! # "enabled" here means "not disabled". It includes private features!
scope :with_feature_enabled, ->(feature) { scope :with_feature_enabled, ->(feature) {
......
...@@ -9,7 +9,10 @@ module Search ...@@ -9,7 +9,10 @@ module Search
def execute def execute
group = Group.find_by(id: params[:group_id]) if params[:group_id].present? group = Group.find_by(id: params[:group_id]) if params[:group_id].present?
projects = ProjectsFinder.new.execute(current_user) projects = ProjectsFinder.new.execute(current_user)
projects = projects.in_namespace(group.id) if group
if group
projects = projects.inside_path(group.full_path)
end
Gitlab::SearchResults.new(current_user, projects, params[:search]) Gitlab::SearchResults.new(current_user, projects, params[:search])
end end
......
---
title: Add read-only full_path and full_name attributes to Group API
merge_request: 8827
author:
...@@ -25,7 +25,14 @@ GET /groups ...@@ -25,7 +25,14 @@ GET /groups
"id": 1, "id": 1,
"name": "Foobar Group", "name": "Foobar Group",
"path": "foo-bar", "path": "foo-bar",
"description": "An interesting group" "description": "An interesting group",
"visibility_level": 20,
"lfs_enabled": true,
"avatar_url": "http://localhost:3000/uploads/group/avatar/1/foo.jpg",
"web_url": "http://localhost:3000/groups/foo-bar",
"request_access_enabled": false,
"full_name": "Foobar Group",
"full_path": "foo-bar"
} }
] ]
``` ```
...@@ -149,6 +156,8 @@ Example response: ...@@ -149,6 +156,8 @@ Example response:
"avatar_url": null, "avatar_url": null,
"web_url": "https://gitlab.example.com/groups/twitter", "web_url": "https://gitlab.example.com/groups/twitter",
"request_access_enabled": false, "request_access_enabled": false,
"full_name": "Foobar Group",
"full_path": "foo-bar",
"projects": [ "projects": [
{ {
"id": 7, "id": 7,
...@@ -372,6 +381,8 @@ Example response: ...@@ -372,6 +381,8 @@ Example response:
"avatar_url": null, "avatar_url": null,
"web_url": "http://gitlab.example.com/groups/h5bp", "web_url": "http://gitlab.example.com/groups/h5bp",
"request_access_enabled": false, "request_access_enabled": false,
"full_name": "Foobar Group",
"full_path": "foo-bar",
"projects": [ "projects": [
{ {
"id": 9, "id": 9,
......
...@@ -137,6 +137,7 @@ module API ...@@ -137,6 +137,7 @@ module API
expose :avatar_url expose :avatar_url
expose :web_url expose :web_url
expose :request_access_enabled expose :request_access_enabled
expose :full_name, :full_path
expose :statistics, if: :statistics do expose :statistics, if: :statistics do
with_options format_with: -> (value) { value.to_i } do with_options format_with: -> (value) { value.to_i } do
......
...@@ -41,6 +41,11 @@ describe SearchHelper do ...@@ -41,6 +41,11 @@ describe SearchHelper do
expect(search_autocomplete_opts("gro").size).to eq(1) expect(search_autocomplete_opts("gro").size).to eq(1)
end end
it "includes nested group" do
create(:group, :nested, name: 'foo').add_owner(user)
expect(search_autocomplete_opts('foo').size).to eq(1)
end
it "includes the user's projects" do it "includes the user's projects" do
project = create(:empty_project, namespace: create(:namespace, owner: user)) project = create(:empty_project, namespace: create(:namespace, owner: user))
expect(search_autocomplete_opts(project.name).size).to eq(1) expect(search_autocomplete_opts(project.name).size).to eq(1)
......
...@@ -1833,6 +1833,14 @@ describe Project, models: true do ...@@ -1833,6 +1833,14 @@ describe Project, models: true do
end end
end end
describe 'inside_path' do
let!(:project1) { create(:empty_project) }
let!(:project2) { create(:empty_project) }
let!(:path) { project1.namespace.path }
it { expect(Project.inside_path(path)).to eq([project1]) }
end
def enable_lfs def enable_lfs
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true) allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
end end
......
...@@ -176,6 +176,9 @@ describe API::Groups, api: true do ...@@ -176,6 +176,9 @@ describe API::Groups, api: true do
expect(json_response['visibility_level']).to eq(group1.visibility_level) expect(json_response['visibility_level']).to eq(group1.visibility_level)
expect(json_response['avatar_url']).to eq(group1.avatar_url) expect(json_response['avatar_url']).to eq(group1.avatar_url)
expect(json_response['web_url']).to eq(group1.web_url) expect(json_response['web_url']).to eq(group1.web_url)
expect(json_response['request_access_enabled']).to eq(group1.request_access_enabled)
expect(json_response['full_name']).to eq(group1.full_name)
expect(json_response['full_path']).to eq(group1.full_path)
expect(json_response['projects']).to be_an Array expect(json_response['projects']).to be_an Array
expect(json_response['projects'].length).to eq(2) expect(json_response['projects'].length).to eq(2)
expect(json_response['shared_projects']).to be_an Array expect(json_response['shared_projects']).to be_an Array
......
...@@ -41,6 +41,25 @@ describe 'Search::GlobalService', services: true do ...@@ -41,6 +41,25 @@ describe 'Search::GlobalService', services: true do
results = context.execute results = context.execute
expect(results.objects('projects')).to match_array [found_project] expect(results.objects('projects')).to match_array [found_project]
end end
context 'nested group' do
let!(:nested_group) { create(:group, :nested) }
let!(:project) { create(:project, namespace: nested_group) }
before { project.add_master(user) }
it 'returns result from nested group' do
context = Search::GlobalService.new(user, search: project.path)
results = context.execute
expect(results.objects('projects')).to match_array [project]
end
it 'returns result from descendants when search inside group' do
context = Search::GlobalService.new(user, search: project.path, group_id: nested_group.parent)
results = context.execute
expect(results.objects('projects')).to match_array [project]
end
end
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment