mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-15 23:56:09 +10:00
Merge branch '7-2-dev' into 'master'
Explore area Fixes #1426 See merge request !987
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
.explore-title {
|
||||
text-align: center;
|
||||
|
||||
h3 {
|
||||
font-weight: normal;
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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 »
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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'
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
+14
-4
@@ -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
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@public
|
||||
Feature: Public Projects Feature
|
||||
Feature: Explore Projects Feature
|
||||
Background:
|
||||
Given public project "Community"
|
||||
And internal project "Internal"
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1,4 +1,4 @@
|
||||
class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps
|
||||
class Spinach::Features::ExploreProjectsFeature < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedPaths
|
||||
include SharedProject
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -324,13 +324,21 @@ 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
|
||||
visit public_project_path(Project.find_by(name: "Community"))
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Public Groups
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I visit the public groups area' do
|
||||
visit explore_groups_path
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Snippets
|
||||
# ----------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user