diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2014-07-23 16:01:57 +0000 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2014-07-23 16:01:57 +0000 |
commit | ac9b5bc07815f3db03ebe856b9d91d36aab73995 (patch) | |
tree | d092ec754656245ecfc1835c3a23fdaf81496ea6 | |
parent | 326fb383326f03d89af9dcf7d1fb72e0fab59a0f (diff) | |
parent | 001096cab8fb8462f8bc3f4bf7073ccca6de7ad3 (diff) | |
download | gitlab-ce-ac9b5bc07815f3db03ebe856b9d91d36aab73995.tar.gz |
Merge branch '7-2-dev' into 'master'
Explore area
Fixes #1426
See merge request !987
26 files changed, 303 insertions, 131 deletions
diff --git a/app/assets/stylesheets/sections/explore.scss b/app/assets/stylesheets/sections/explore.scss new file mode 100644 index 00000000000..9b92128624c --- /dev/null +++ b/app/assets/stylesheets/sections/explore.scss @@ -0,0 +1,8 @@ +.explore-title { + text-align: center; + + h3 { + font-weight: normal; + font-size: 30px; + } +} diff --git a/app/controllers/explore/groups_controller.rb b/app/controllers/explore/groups_controller.rb new file mode 100644 index 00000000000..f8e1a31e0b3 --- /dev/null +++ b/app/controllers/explore/groups_controller.rb @@ -0,0 +1,14 @@ +class Explore::GroupsController < ApplicationController + skip_before_filter :authenticate_user!, + :reject_blocked, :set_current_user_for_observers, + :add_abilities + + layout "explore" + + def index + @groups = GroupsFinder.new.execute(current_user) + @groups = @groups.search(params[:search]) if params[:search].present? + @groups = @groups.sort(@sort = params[:sort]) + @groups = @groups.page(params[:page]).per(20) + end +end diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb new file mode 100644 index 00000000000..05b3289682b --- /dev/null +++ b/app/controllers/explore/projects_controller.rb @@ -0,0 +1,19 @@ +class Explore::ProjectsController < ApplicationController + skip_before_filter :authenticate_user!, + :reject_blocked, + :add_abilities + + layout 'explore' + + def index + @projects = ProjectsFinder.new.execute(current_user) + @projects = @projects.search(params[:search]) if params[:search].present? + @projects = @projects.sort(@sort = params[:sort]) + @projects = @projects.includes(:namespace).page(params[:page]).per(20) + end + + def trending + @trending_projects = TrendingProjectsFinder.new.execute(current_user) + @trending_projects = @trending_projects.page(params[:page]).per(10) + end +end diff --git a/app/controllers/public/projects_controller.rb b/app/controllers/public/projects_controller.rb deleted file mode 100644 index d6238f79547..00000000000 --- a/app/controllers/public/projects_controller.rb +++ /dev/null @@ -1,14 +0,0 @@ -class Public::ProjectsController < ApplicationController - skip_before_filter :authenticate_user!, - :reject_blocked, :set_current_user_for_observers, - :add_abilities - - layout 'public' - - def index - @projects = Project.publicish(current_user) - @projects = @projects.search(params[:search]) if params[:search].present? - @projects = @projects.sort(@sort = params[:sort]) - @projects = @projects.includes(:namespace).page(params[:page]).per(20) - end -end diff --git a/app/finders/trending_projects_finder.rb b/app/finders/trending_projects_finder.rb new file mode 100644 index 00000000000..32d7968924a --- /dev/null +++ b/app/finders/trending_projects_finder.rb @@ -0,0 +1,19 @@ +class TrendingProjectsFinder + def execute(current_user, start_date = nil) + start_date ||= Date.today - 1.month + + projects = projects_for(current_user) + + # Determine trending projects based on comments count + # for period of time - ex. month + projects.joins(:notes).where('notes.created_at > ?', start_date). + select("projects.*, count(notes.id) as ncount"). + group("projects.id").order("ncount DESC") + end + + private + + def projects_for(current_user) + ProjectsFinder.new.execute(current_user) + end +end diff --git a/app/models/group.rb b/app/models/group.rb index 3a5c5e11354..66239f7fe6f 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -73,4 +73,20 @@ class Group < Namespace def public_profile? projects.public_only.any? end + + class << self + def search(query) + where("LOWER(namespaces.name) LIKE :query", query: "%#{query.downcase}%") + end + + def sort(method) + case method.to_s + when "newest" then reorder("namespaces.created_at DESC") + when "oldest" then reorder("namespaces.created_at ASC") + when "recently_updated" then reorder("namespaces.updated_at DESC") + when "last_updated" then reorder("namespaces.updated_at ASC") + else reorder("namespaces.path, namespaces.name ASC") + end + end + end end diff --git a/app/views/dashboard/_zero_authorized_projects.html.haml b/app/views/dashboard/_zero_authorized_projects.html.haml index ee086d88e3e..ff85e32bc4e 100644 --- a/app/views/dashboard/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/_zero_authorized_projects.html.haml @@ -46,5 +46,5 @@ %br Public projects are an easy way to allow everyone to have read-only access. .link_holder - = link_to public_projects_path, class: "btn btn-new" do + = link_to explore_projects_path, class: "btn btn-new" do Browse public projects ยป diff --git a/app/views/explore/groups/index.html.haml b/app/views/explore/groups/index.html.haml new file mode 100644 index 00000000000..80ddd5c1bde --- /dev/null +++ b/app/views/explore/groups/index.html.haml @@ -0,0 +1,51 @@ +.clearfix + .pull-left + = form_tag explore_groups_path, method: :get, class: 'form-inline form-tiny' do |f| + .form-group + = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input input-mn-300", id: "groups_search" + .form-group + = submit_tag 'Search', class: "btn btn-primary wide" + + .pull-right + .dropdown.inline + %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} + %span.light sort: + - if @sort.present? + = @sort.humanize + - else + Name + %b.caret + %ul.dropdown-menu + %li + = link_to explore_groups_path(sort: nil) do + Name + = link_to explore_groups_path(sort: 'newest') do + Newest + = link_to explore_groups_path(sort: 'oldest') do + Oldest + = link_to explore_groups_path(sort: 'recently_updated') do + Recently updated + = link_to explore_groups_path(sort: 'last_updated') do + Last updated + +%hr + +%ul.bordered-list + - @groups.each do |group| + %li + .clearfix + %h4 + = link_to group_path(id: group.path) do + %i.icon-group + = group.name + .clearfix + %p + = truncate group.description, length: 150 + .clearfix + %p.light + #{pluralize(group.members.size, 'member')}, #{pluralize(group.projects.count, 'project')} + - unless @groups.present? + .nothing-here-block No public groups + + += paginate @groups, theme: "gitlab" diff --git a/app/views/explore/projects/_project.html.haml b/app/views/explore/projects/_project.html.haml new file mode 100644 index 00000000000..665d111bead --- /dev/null +++ b/app/views/explore/projects/_project.html.haml @@ -0,0 +1,20 @@ +%li + %h4.project-title + .project-access-icon + = visibility_level_icon(project.visibility_level) + = link_to project.name_with_namespace, project + + - if project.description.present? + %p.project-description.str-truncated + = project.description + + .repo-info + - unless project.empty_repo? + = link_to pluralize(project.repository.round_commit_count, 'commit'), project_commits_path(project, project.default_branch) + · + = link_to pluralize(project.repository.branch_names.count, 'branch'), project_branches_path(project) + · + = link_to pluralize(project.repository.tag_names.count, 'tag'), project_tags_path(project) + - else + %i.icon-warning-sign + Empty repository diff --git a/app/views/explore/projects/index.html.haml b/app/views/explore/projects/index.html.haml new file mode 100644 index 00000000000..c8bf78385e8 --- /dev/null +++ b/app/views/explore/projects/index.html.haml @@ -0,0 +1,38 @@ +.clearfix + .pull-left + = form_tag explore_projects_path, method: :get, class: 'form-inline form-tiny' do |f| + .form-group + = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input input-mn-300", id: "projects_search" + .form-group + = submit_tag 'Search', class: "btn btn-primary wide" + + .pull-right + .dropdown.inline + %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} + %span.light sort: + - if @sort.present? + = @sort.humanize + - else + Name + %b.caret + %ul.dropdown-menu + %li + = link_to explore_projects_path(sort: nil) do + Name + = link_to explore_projects_path(sort: 'newest') do + Newest + = link_to explore_projects_path(sort: 'oldest') do + Oldest + = link_to explore_projects_path(sort: 'recently_updated') do + Recently updated + = link_to explore_projects_path(sort: 'last_updated') do + Last updated + +%hr +.public-projects + %ul.bordered-list.top-list + = render @projects + - unless @projects.present? + .nothing-here-block No public projects + + = paginate @projects, theme: "gitlab" diff --git a/app/views/explore/projects/trending.html.haml b/app/views/explore/projects/trending.html.haml new file mode 100644 index 00000000000..18bb1ac0ba4 --- /dev/null +++ b/app/views/explore/projects/trending.html.haml @@ -0,0 +1,11 @@ +.explore-trending-block + %p.lead + %i.icon-comments-alt + See most discussed projects for last month + %hr + .public-projects + %ul.bordered-list + = render @trending_projects + + .center + = link_to 'Show all projects', explore_projects_path, class: 'btn btn-primary' diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml index fba56b5dc3b..7c727aca785 100644 --- a/app/views/layouts/_head_panel.html.haml +++ b/app/views/layouts/_head_panel.html.haml @@ -24,7 +24,7 @@ 'data-original-title' => 'Help' do %i.icon-question-sign %li - = link_to public_root_path, title: "Public area", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do + = link_to explore_root_path, title: "Explore", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do %i.icon-globe %li = link_to user_snippets_path(current_user), title: "My snippets", class: 'has_bottom_tooltip', 'data-original-title' => 'My snippets' do diff --git a/app/views/layouts/_public_head_panel.html.haml b/app/views/layouts/_public_head_panel.html.haml index 63992a22f32..5d7f72e6b31 100644 --- a/app/views/layouts/_public_head_panel.html.haml +++ b/app/views/layouts/_public_head_panel.html.haml @@ -3,7 +3,7 @@ .container %div.app_logo %span.separator - = link_to public_root_path, class: "home" do + = link_to explore_root_path, class: "home" do %h1 GITLAB %span.separator %h1.title= title diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml index ff27fcc0f40..00b1959912f 100644 --- a/app/views/layouts/devise.html.haml +++ b/app/views/layouts/devise.html.haml @@ -33,6 +33,6 @@ %hr .container .footer-links - = link_to "Explore public projects", public_projects_path + = link_to "Explore", explore_root_path = link_to "Documentation", "http://doc.gitlab.com/" = link_to "About GitLab", "https://about.gitlab.com/" diff --git a/app/views/layouts/explore.html.haml b/app/views/layouts/explore.html.haml new file mode 100644 index 00000000000..73b4940e3d3 --- /dev/null +++ b/app/views/layouts/explore.html.haml @@ -0,0 +1,28 @@ +- page_title = 'Explore' +!!! 5 +%html{ lang: "en"} + = render "layouts/head", title: page_title + %body{class: "#{app_theme} application", :'data-page' => body_data_page} + = render "layouts/broadcast" + - if current_user + = render "layouts/head_panel", title: page_title + - else + = render "layouts/public_head_panel", title: page_title + .container.navless-container + .content + .explore-title + %h3 + Explore GitLab + %p.lead + Discover projects and groups. Share your projects with others + + + %ul.nav.nav-tabs + = nav_link(path: 'projects#trending') do + = link_to 'Trending Projects', explore_root_path + = nav_link(path: 'projects#index') do + = link_to 'All Projects', explore_projects_path + = nav_link(controller: :groups) do + = link_to 'All Groups', explore_groups_path + + = yield diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml deleted file mode 100644 index 3c76bbb9575..00000000000 --- a/app/views/layouts/public.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: "Public Projects" - %body{class: "#{app_theme} application", :'data-page' => body_data_page} - = render "layouts/broadcast" - - if current_user - = render "layouts/head_panel", title: "Public Projects" - - else - = render "layouts/public_head_panel", title: "Public Projects" - .container.navless-container - .content= yield diff --git a/app/views/public/projects/index.html.haml b/app/views/public/projects/index.html.haml deleted file mode 100644 index 7d4d94ce42b..00000000000 --- a/app/views/public/projects/index.html.haml +++ /dev/null @@ -1,68 +0,0 @@ -%h3.page-title - Projects (#{@projects.total_count}) -.light - You can browse public projects in read-only mode until signed in. -%hr -.clearfix - .pull-left - = form_tag public_projects_path, method: :get, class: 'form-inline form-tiny' do |f| - .form-group - = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input input-mn-300", id: "projects_search" - .form-group - = submit_tag 'Search', class: "btn btn-primary wide" - - .pull-right - .dropdown.inline - %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - %span.light sort: - - if @sort.present? - = @sort.humanize - - else - Name - %b.caret - %ul.dropdown-menu - %li - = link_to public_projects_path(sort: nil) do - Name - = link_to public_projects_path(sort: 'newest') do - Newest - = link_to public_projects_path(sort: 'oldest') do - Oldest - = link_to public_projects_path(sort: 'recently_updated') do - Recently updated - = link_to public_projects_path(sort: 'last_updated') do - Last updated - -%hr -.public-projects - %ul.bordered-list.top-list - - @projects.each do |project| - %li - %h4 - = link_to project_path(project) do - = project.name_with_namespace - - if project.internal? - %small.access-icon - = internal_icon - Internal - .pull-right.hidden-sm.hidden-xs - %pre.public-clone git clone #{project.http_url_to_repo} - - - if project.description.present? - %p - = project.description - - .repo-info - - unless project.empty_repo? - = link_to pluralize(project.repository.round_commit_count, 'commit'), project_commits_path(project, project.default_branch) - · - = link_to pluralize(project.repository.branch_names.count, 'branch'), project_branches_path(project) - · - = link_to pluralize(project.repository.tag_names.count, 'tag'), project_tags_path(project) - - else - %i.icon-warning-sign - Empty repository - - unless @projects.present? - .nothing-here-block No public projects - - = paginate @projects, theme: "gitlab" diff --git a/config/routes.rb b/config/routes.rb index f73fd7a87fa..f54f9ea5341 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -47,13 +47,23 @@ Gitlab::Application.routes.draw do get "/s/:username" => "snippets#user_index", as: :user_snippets, constraints: { username: /.*/ } # - # Public namespace + # Explroe area # - namespace :public do - resources :projects, only: [:index] - root to: "projects#index" + namespace :explore do + resources :projects, only: [:index] do + collection do + get :trending + end + end + + resources :groups, only: [:index] + root to: "projects#trending" end + # Compatibility with old routing + get 'public' => "explore/projects#index" + get 'public/projects' => "explore/projects#index" + # # Attachments serving # diff --git a/features/public/projects.feature b/features/explore/projects.feature index c7bb3b4f8ce..2ed9707ec39 100644 --- a/features/public/projects.feature +++ b/features/explore/projects.feature @@ -1,5 +1,5 @@ @public -Feature: Public Projects Feature +Feature: Explore Projects Feature Background: Given public project "Community" And internal project "Internal" diff --git a/features/public/public_groups.feature b/features/explore/public_groups.feature index 8bbda8cb6d4..825e3da934e 100644 --- a/features/public/public_groups.feature +++ b/features/explore/public_groups.feature @@ -1,5 +1,5 @@ @public -Feature: Public Projects Feature +Feature: Explore Groups Feature Background: Given group "TestGroup" has private project "Enterprise" @@ -117,3 +117,35 @@ Feature: Public Projects Feature And I visit group "TestGroup" members page Then I should see group member "John Doe" And I should not see member roles + + Scenario: I should see group with public project in public groups area + Given group "TestGroup" has public project "Community" + When I visit the public groups area + Then I should see group "TestGroup" + + Scenario: I should not see group with internal project in public groups area + Given group "TestGroup" has internal project "Internal" + When I visit the public groups area + Then I should not see group "TestGroup" + + Scenario: I should not see group with private project in public groups area + When I visit the public groups area + Then I should not see group "TestGroup" + + Scenario: I should see group with public project in public groups area as user + Given group "TestGroup" has public project "Community" + When I sign in as a user + And I visit the public groups area + Then I should see group "TestGroup" + + Scenario: I should see group with internal project in public groups area as user + Given group "TestGroup" has internal project "Internal" + When I sign in as a user + And I visit the public groups area + Then I should see group "TestGroup" + + Scenario: I should not see group with private project in public groups area as user + When I sign in as a user + And I visit the public groups area + Then I should not see group "TestGroup" + diff --git a/features/project/public.feature b/features/project/public.feature deleted file mode 100644 index c5a9da14c54..00000000000 --- a/features/project/public.feature +++ /dev/null @@ -1,8 +0,0 @@ -Feature: Public Projects - Background: - Given I sign in as a user - - Scenario: I should see the list of public projects - When I visit the public projects area - Then I should see the list of public projects - diff --git a/features/steps/public/groups_feature.rb b/features/steps/explore/groups_feature.rb index 015deca5427..48486a83424 100644 --- a/features/steps/public/groups_feature.rb +++ b/features/steps/explore/groups_feature.rb @@ -1,4 +1,4 @@ -class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps +class Spinach::Features::ExploreGroupsFeature < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedGroup @@ -15,7 +15,7 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps step 'group "TestGroup" has public project "Community"' do group_has_project("TestGroup", "Community", Gitlab::VisibilityLevel::PUBLIC) end - + step '"John Doe" is owner of group "TestGroup"' do group = Group.find_by(name: "TestGroup") || create(:group, name: "TestGroup") user = create(:user, name: "John Doe") @@ -37,31 +37,31 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps step 'I visit group "TestGroup" members page' do visit members_group_path(Group.find_by(name: "TestGroup")) end - + step 'I should not see project "Enterprise" items' do page.should_not have_content "Enterprise" end - + step 'I should see project "Internal" items' do page.should have_content "Internal" end - + step 'I should not see project "Internal" items' do page.should_not have_content "Internal" end - + step 'I should see project "Community" items' do page.should have_content "Community" end - + step 'I change filter to Everyone\'s' do click_link "Everyone's" end - + step 'I should see group member "John Doe"' do page.should have_content "John Doe" end - + step 'I should not see member roles' do page.body.should_not match(%r{owner|developer|reporter|guest}i) end diff --git a/features/steps/public/projects.rb b/features/steps/explore/projects.rb index 7c7311bb91c..8aa2916014b 100644 --- a/features/steps/public/projects.rb +++ b/features/steps/explore/projects.rb @@ -1,4 +1,4 @@ -class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps +class Spinach::Features::ExploreProjectsFeature < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedProject diff --git a/features/steps/project/public.rb b/features/steps/project/public.rb deleted file mode 100644 index 7063e7d56ae..00000000000 --- a/features/steps/project/public.rb +++ /dev/null @@ -1,9 +0,0 @@ -class PublicProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - Then 'I should see the list of public projects' do - page.should have_content "Public Projects" - end -end diff --git a/features/steps/shared/group.rb b/features/steps/shared/group.rb index 6b4c47312a7..1b225dd61a6 100644 --- a/features/steps/shared/group.rb +++ b/features/steps/shared/group.rb @@ -21,6 +21,14 @@ module SharedGroup is_member_of("Mary Jane", "Guest", Gitlab::Access::GUEST) end + step 'I should see group "TestGroup"' do + page.should have_content "TestGroup" + end + + step 'I should not see group "TestGroup"' do + page.should_not have_content "TestGroup" + end + protected def is_member_of(username, groupname, role) diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 2090b642059..a0b4099ab3e 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -324,7 +324,7 @@ module SharedPaths # ---------------------------------------- step 'I visit the public projects area' do - visit public_root_path + visit explore_projects_path end step 'I visit public page for "Community" project' do @@ -332,6 +332,14 @@ module SharedPaths end # ---------------------------------------- + # Public Groups + # ---------------------------------------- + + step 'I visit the public groups area' do + visit explore_groups_path + end + + # ---------------------------------------- # Snippets # ---------------------------------------- |