From fa3ae24ca7a11f3d87c8838cf05a95dfecfa4c5c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 2 Oct 2012 18:17:12 +0300 Subject: [PATCH 01/10] Group entity. Group has many projects --- app/models/group.rb | 22 +++++++++++++++++++ app/models/project.rb | 3 +++ db/migrate/20121002150926_create_groups.rb | 11 ++++++++++ .../20121002151033_add_group_id_to_project.rb | 5 +++++ db/schema.rb | 11 +++++++++- spec/factories/groups.rb | 21 ++++++++++++++++++ spec/models/group_spec.rb | 22 +++++++++++++++++++ spec/models/project_spec.rb | 22 +++++++++++++++++++ 8 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 app/models/group.rb create mode 100644 db/migrate/20121002150926_create_groups.rb create mode 100644 db/migrate/20121002151033_add_group_id_to_project.rb create mode 100644 spec/factories/groups.rb create mode 100644 spec/models/group_spec.rb diff --git a/app/models/group.rb b/app/models/group.rb new file mode 100644 index 00000000..f18b7d57 --- /dev/null +++ b/app/models/group.rb @@ -0,0 +1,22 @@ +# == Schema Information +# +# Table name: groups +# +# id :integer not null, primary key +# name :string(255) not null +# code :string(255) not null +# owner_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class Group < ActiveRecord::Base + attr_accessible :code, :name, :owner_id + + has_many :projects + belongs_to :owner, class_name: "User" + + validates :name, presence: true, uniqueness: true + validates :code, presence: true, uniqueness: true + validates :owner_id, presence: true +end diff --git a/app/models/project.rb b/app/models/project.rb index 9b13de62..9d2b99e5 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -11,6 +11,7 @@ class Project < ActiveRecord::Base attr_accessor :error_code # Relations + belongs_to :group belongs_to :owner, class_name: "User" has_many :users, through: :users_projects has_many :events, dependent: :destroy @@ -173,4 +174,6 @@ end # wall_enabled :boolean default(TRUE), not null # merge_requests_enabled :boolean default(TRUE), not null # wiki_enabled :boolean default(TRUE), not null +# group_id :integer # + diff --git a/db/migrate/20121002150926_create_groups.rb b/db/migrate/20121002150926_create_groups.rb new file mode 100644 index 00000000..ac178294 --- /dev/null +++ b/db/migrate/20121002150926_create_groups.rb @@ -0,0 +1,11 @@ +class CreateGroups < ActiveRecord::Migration + def change + create_table :groups do |t| + t.string :name, null: false + t.string :code, null: false + t.integer :owner_id, null: false + + t.timestamps + end + end +end diff --git a/db/migrate/20121002151033_add_group_id_to_project.rb b/db/migrate/20121002151033_add_group_id_to_project.rb new file mode 100644 index 00000000..683fbfec --- /dev/null +++ b/db/migrate/20121002151033_add_group_id_to_project.rb @@ -0,0 +1,5 @@ +class AddGroupIdToProject < ActiveRecord::Migration + def change + add_column :projects, :group_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 00bb5523..ec4729c0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120905043334) do +ActiveRecord::Schema.define(:version => 20121002151033) do create_table "events", :force => true do |t| t.string "target_type" @@ -25,6 +25,14 @@ ActiveRecord::Schema.define(:version => 20120905043334) do t.integer "author_id" end + create_table "groups", :force => true do |t| + t.string "name", :null => false + t.string "code", :null => false + t.integer "owner_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "issues", :force => true do |t| t.string "title" t.integer "assignee_id" @@ -108,6 +116,7 @@ ActiveRecord::Schema.define(:version => 20120905043334) do t.boolean "wall_enabled", :default => true, :null => false t.boolean "merge_requests_enabled", :default => true, :null => false t.boolean "wiki_enabled", :default => true, :null => false + t.integer "group_id" end create_table "protected_branches", :force => true do |t| diff --git a/spec/factories/groups.rb b/spec/factories/groups.rb new file mode 100644 index 00000000..d583b186 --- /dev/null +++ b/spec/factories/groups.rb @@ -0,0 +1,21 @@ +# == Schema Information +# +# Table name: groups +# +# id :integer not null, primary key +# name :string(255) not null +# code :string(255) not null +# owner_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# + +# Read about factories at https://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :group do + name "MyString" + code "MyString" + owner_id 1 + end +end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb new file mode 100644 index 00000000..eea196fd --- /dev/null +++ b/spec/models/group_spec.rb @@ -0,0 +1,22 @@ +# == Schema Information +# +# Table name: groups +# +# id :integer not null, primary key +# name :string(255) not null +# code :string(255) not null +# owner_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# + +require 'spec_helper' + +describe Group do + it { should have_many :projects } + it { should validate_presence_of :name } + it { should validate_uniqueness_of(:name) } + it { should validate_presence_of :code } + it { should validate_uniqueness_of(:code) } + it { should validate_presence_of :owner_id } +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index bb975a93..b7d846e8 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1,7 +1,29 @@ +# == Schema Information +# +# Table name: projects +# +# id :integer not null, primary key +# name :string(255) +# path :string(255) +# description :text +# created_at :datetime not null +# updated_at :datetime not null +# private_flag :boolean default(TRUE), not null +# code :string(255) +# owner_id :integer +# default_branch :string(255) +# issues_enabled :boolean default(TRUE), not null +# wall_enabled :boolean default(TRUE), not null +# merge_requests_enabled :boolean default(TRUE), not null +# wiki_enabled :boolean default(TRUE), not null +# group_id :integer +# + require 'spec_helper' describe Project do describe "Associations" do + it { should belong_to(:group) } it { should belong_to(:owner).class_name('User') } it { should have_many(:users) } it { should have_many(:events).dependent(:destroy) } From d683ce5c10ee84d9fde153329d08425c7e99941f Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 2 Oct 2012 18:20:46 +0300 Subject: [PATCH 02/10] refactored factory + fixed tests --- spec/factories.rb | 6 ++++++ spec/factories/groups.rb | 21 --------------------- spec/models/group_spec.rb | 2 ++ 3 files changed, 8 insertions(+), 21 deletions(-) delete mode 100644 spec/factories/groups.rb diff --git a/spec/factories.rb b/spec/factories.rb index 760465aa..82d73fec 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -47,6 +47,12 @@ FactoryGirl.define do owner end + factory :group do + sequence(:name) { |n| "group#{n}" } + code { name.downcase.gsub(/\s/, '_') } + owner + end + factory :users_project do user project diff --git a/spec/factories/groups.rb b/spec/factories/groups.rb deleted file mode 100644 index d583b186..00000000 --- a/spec/factories/groups.rb +++ /dev/null @@ -1,21 +0,0 @@ -# == Schema Information -# -# Table name: groups -# -# id :integer not null, primary key -# name :string(255) not null -# code :string(255) not null -# owner_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null -# - -# Read about factories at https://github.com/thoughtbot/factory_girl - -FactoryGirl.define do - factory :group do - name "MyString" - code "MyString" - owner_id 1 - end -end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index eea196fd..fd7db4b2 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -13,6 +13,8 @@ require 'spec_helper' describe Group do + let!(:group) { create(:group) } + it { should have_many :projects } it { should validate_presence_of :name } it { should validate_uniqueness_of(:name) } From d6363e935933551b7f9edb4063d0b0fbcea3c824 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 2 Oct 2012 19:01:40 +0300 Subject: [PATCH 03/10] Admin Group scaffold -> new, show, index --- app/controllers/admin/groups_controller.rb | 66 ++++++++++++++++++++++ app/models/group.rb | 6 ++ app/models/project.rb | 5 +- app/views/admin/groups/_form.html.haml | 19 +++++++ app/views/admin/groups/index.html.haml | 24 ++++++++ app/views/admin/groups/new.html.haml | 3 + app/views/admin/groups/show.html.haml | 48 ++++++++++++++++ config/routes.rb | 5 ++ 8 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 app/controllers/admin/groups_controller.rb create mode 100644 app/views/admin/groups/_form.html.haml create mode 100644 app/views/admin/groups/index.html.haml create mode 100644 app/views/admin/groups/new.html.haml create mode 100644 app/views/admin/groups/show.html.haml diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb new file mode 100644 index 00000000..612abf8c --- /dev/null +++ b/app/controllers/admin/groups_controller.rb @@ -0,0 +1,66 @@ +class Admin::GroupsController < AdminController + before_filter :group, only: [:edit, :show, :update, :destroy, :project_update] + + def index + @groups = Group.scoped + @groups = @groups.search(params[:name]) if params[:name].present? + @groups = @groups.page(params[:page]).per(20) + end + + def show + @projects = Project.scoped + @projects = @projects.not_in_group(@group) if @group.projects.present? + @projects = @projects.all + end + + def new + @group = Group.new + end + + def edit + end + + def create + @group = Group.new(params[:group]) + @group.owner = current_user + + if @group.save + redirect_to [:admin, @group], notice: 'Group was successfully created.' + else + render action: "new" + end + end + + def update + owner_id = params[:group].delete(:owner_id) + + if owner_id + @group.owner = User.find(owner_id) + end + + if @group.update_attributes(params[:group]) + redirect_to [:admin, @group], notice: 'Group was successfully updated.' + else + render action: "edit" + end + end + + def project_update + project_ids = params[:project_ids] + Project.where(id: project_ids).update_all(group_id: @group.id) + + redirect_to :back, notice: 'Group was successfully updated.' + end + + def destroy + @group.destroy + + redirect_to groups_url, notice: 'Group was successfully deleted.' + end + + private + + def group + @group = Group.find_by_code(params[:id]) + end +end diff --git a/app/models/group.rb b/app/models/group.rb index f18b7d57..43283066 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -19,4 +19,10 @@ class Group < ActiveRecord::Base validates :name, presence: true, uniqueness: true validates :code, presence: true, uniqueness: true validates :owner_id, presence: true + + delegate :name, to: :owner, allow_nil: true, prefix: true + + def to_param + code + end end diff --git a/app/models/project.rb b/app/models/project.rb index 9d2b99e5..f525f292 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -26,9 +26,12 @@ class Project < ActiveRecord::Base has_many :wikis, dependent: :destroy has_many :protected_branches, dependent: :destroy + delegate :name, to: :owner, allow_nil: true, prefix: true + # Scopes scope :public_only, where(private_flag: false) - scope :without_user, lambda { |user| where("id not in (:ids)", ids: user.projects.map(&:id) ) } + scope :without_user, ->(user) { where("id not in (:ids)", ids: user.projects.map(&:id) ) } + scope :not_in_group, ->(group) { where("id not in (:ids)", ids: group.project_ids ) } def self.active joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC") diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml new file mode 100644 index 00000000..a1ba9406 --- /dev/null +++ b/app/views/admin/groups/_form.html.haml @@ -0,0 +1,19 @@ += form_for [:admin, @group] do |f| + - if @group.errors.any? + .alert-message.block-message.error + %span= @group.errors.full_messages.first + .clearfix.group_name_holder + = f.label :name do + Group name is + .input + = f.text_field :name, placeholder: "Example Group", class: "xxlarge" + .clearfix + = f.label :code do + URL + .input + .input-prepend + %span.add-on= web_app_url + = f.text_field :code, placeholder: "example" + + .form-actions + = f.submit 'Create group', class: "btn primary" diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml new file mode 100644 index 00000000..b90efc83 --- /dev/null +++ b/app/views/admin/groups/index.html.haml @@ -0,0 +1,24 @@ +%h3.page_title + Groups + = link_to 'New Group', new_admin_group_path, class: "btn small right" +%br += form_tag admin_groups_path, method: :get, class: 'form-inline' do + = text_field_tag :name, params[:name], class: "xlarge" + = submit_tag "Search", class: "btn submit primary" + +%table + %thead + %th Name + %th Path + %th Projects + %th Edit + %th.cred Danger Zone! + + - @groups.each do |group| + %tr + %td= link_to group.name, [:admin, group] + %td= group.path + %td= group.projects.count + %td= link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn small" + %td.bgred= link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn small danger" += paginate @groups, theme: "admin" diff --git a/app/views/admin/groups/new.html.haml b/app/views/admin/groups/new.html.haml new file mode 100644 index 00000000..d6b6ea15 --- /dev/null +++ b/app/views/admin/groups/new.html.haml @@ -0,0 +1,3 @@ +%h3.page_title New Group +%br += render 'form' diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml new file mode 100644 index 00000000..5d348eec --- /dev/null +++ b/app/views/admin/groups/show.html.haml @@ -0,0 +1,48 @@ +%h3.page_title + Group: #{@group.name} + = link_to edit_admin_group_path(@group), class: "btn right" do + %i.icon-edit + Edit + +%br +%table.zebra-striped + %thead + %tr + %th Group + %th + %tr + %td + %b + Name: + %td + = @group.name + %tr + %td + %b + Code: + %td + = @group.code + %tr + %td + %b + Owner: + %td + = @group.owner_name +.ui-box + %h5 + Projects + %small + (#{@group.projects.count}) + %ul.unstyled + - @group.projects.each do |project| + %li.wll + %strong + = link_to project.name, [:admin, project] + +%br +%h3 Add new project +%br += form_tag project_update_admin_group_path(@group), class: "bulk_import", method: :put do + = select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5' + .form-actions + = submit_tag 'Add', class: "btn primary" diff --git a/config/routes.rb b/config/routes.rb index 21521a97..2b923379 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -43,6 +43,11 @@ Gitlab::Application.routes.draw do put :unblock end end + resources :groups, constraints: { id: /[^\/]+/ } do + member do + put :project_update + end + end resources :projects, constraints: { id: /[^\/]+/ } do member do get :team From f9eda9b33a72cae91e51c5733fdf2c0d7b37d149 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 2 Oct 2012 19:37:53 +0300 Subject: [PATCH 04/10] Group filtering on dashboard --- app/controllers/dashboard_controller.rb | 20 ++++++++++++++++++-- app/views/admin/groups/index.html.haml | 4 ++-- app/views/dashboard/_groups.html.haml | 15 +++++++++++++++ app/views/dashboard/_projects.html.haml | 21 +++++++++++++++++++++ app/views/dashboard/index.html.haml | 25 +++---------------------- app/views/layouts/group.html.haml | 24 ++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 app/views/dashboard/_groups.html.haml create mode 100644 app/views/dashboard/_projects.html.haml create mode 100644 app/views/layouts/group.html.haml diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 7696e97a..75cf726d 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -2,12 +2,22 @@ class DashboardController < ApplicationController respond_to :html def index - @projects = current_user.projects_with_events.page(params[:page]).per(40) + @groups = Group.where(id: current_user.projects.pluck(:group_id)) + + @projects = current_user.projects_with_events + + if params[:group].present? + @group = Group.find_by_code(params[:group]) + @projects = @projects.where(group_id: @group.id) + end + + @projects = @projects.page(params[:page]).per(40) + @events = Event.recent_for_user(current_user).limit(20).offset(params[:offset] || 0) @last_push = current_user.recent_push respond_to do |format| - format.html + format.html { render 'index', layout: determine_layout } format.js format.atom { render layout: false } end @@ -31,4 +41,10 @@ class DashboardController < ApplicationController format.atom { render layout: false } end end + + protected + + def determine_layout + @group ? 'group' : 'application' + end end diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml index b90efc83..6952c4c9 100644 --- a/app/views/admin/groups/index.html.haml +++ b/app/views/admin/groups/index.html.haml @@ -9,7 +9,7 @@ %table %thead %th Name - %th Path + %th Code %th Projects %th Edit %th.cred Danger Zone! @@ -17,7 +17,7 @@ - @groups.each do |group| %tr %td= link_to group.name, [:admin, group] - %td= group.path + %td= group.code %td= group.projects.count %td= link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn small" %td.bgred= link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn small danger" diff --git a/app/views/dashboard/_groups.html.haml b/app/views/dashboard/_groups.html.haml new file mode 100644 index 00000000..b46f675f --- /dev/null +++ b/app/views/dashboard/_groups.html.haml @@ -0,0 +1,15 @@ +.projects_box + %h5 + Groups + %small + (#{groups.count}) + %ul.unstyled + - groups.each do |group| + %li.wll + = link_to dashboard_path(group: group), class: dom_class(group) do + %strong.group_name= truncate(group.name, length: 25) + %span.arrow + → + %span.last_activity + %strong Projects: + %span= group.projects.count diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/_projects.html.haml new file mode 100644 index 00000000..00f19ccd --- /dev/null +++ b/app/views/dashboard/_projects.html.haml @@ -0,0 +1,21 @@ +.projects_box + %h5 + Projects + %small + (#{projects.total_count}) + - if current_user.can_create_project? + %span.right + = link_to new_project_path, class: "btn very_small info" do + %i.icon-plus + New Project + %ul.unstyled + - projects.each do |project| + %li.wll + = link_to project_path(project), class: dom_class(project) do + %strong.project_name= truncate(project.name, length: 25) + %span.arrow + → + %span.last_activity + %strong Last activity: + %span= project_last_activity(project) + .bottom= paginate projects, theme: "gitlab" diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml index 791c18e3..aa53ebfd 100644 --- a/app/views/dashboard/index.html.haml +++ b/app/views/dashboard/index.html.haml @@ -9,28 +9,9 @@ .loading.hide .side = render "events/event_last_push", event: @last_push - .projects_box - %h5 - Projects - %small - (#{@projects.total_count}) - - if current_user.can_create_project? - %span.right - = link_to new_project_path, class: "btn very_small info" do - %i.icon-plus - New Project - %ul.unstyled - - @projects.each do |project| - %li.wll - = link_to project_path(project), class: dom_class(project) do - %strong.project_name= truncate(project.name, length: 25) - %span.arrow - → - %span.last_activity - %strong Last activity: - %span= project_last_activity(project) - .bottom= paginate @projects, theme: "gitlab" - + - unless @group + = render "groups", groups: @groups + = render "projects", projects: @projects %div %span.rss-icon = link_to dashboard_path(:atom, { private_token: current_user.private_token }) do diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml new file mode 100644 index 00000000..810c296e --- /dev/null +++ b/app/views/layouts/group.html.haml @@ -0,0 +1,24 @@ +!!! 5 +%html{ lang: "en"} + = render "layouts/head" + %body{class: "#{app_theme} application"} + = render "layouts/flash" + = render "layouts/head_panel", title: "#{@group.name}:Dashboard" + .container + %ul.main_menu + = nav_link(path: 'dashboard#index', html_options: {class: 'home'}) do + = link_to "Home", root_path, title: "Home" + = nav_link(path: 'dashboard#issues') do + = link_to dashboard_issues_path(group: @group) do + Issues + %span.count= current_user.assigned_issues.opened.count + = nav_link(path: 'dashboard#merge_requests') do + = link_to dashboard_merge_requests_path(group: @group) do + Merge Requests + %span.count= current_user.cared_merge_requests.count + = nav_link(path: 'search#show') do + = link_to "People", "#" + = nav_link(path: 'help#index') do + = link_to "Help", help_path + + .content= yield From 1b6a3dfec9bdadb8c607bf57e4b6699c4ab3a80b Mon Sep 17 00:00:00 2001 From: randx Date: Tue, 2 Oct 2012 20:42:15 +0300 Subject: [PATCH 05/10] Move all stuff to groups controller --- app/assets/stylesheets/sections/projects.scss | 2 + app/controllers/dashboard_controller.rb | 15 +--- app/controllers/groups_controller.rb | 69 +++++++++++++++++ app/views/dashboard/_groups.html.haml | 2 +- app/views/dashboard/index.html.haml | 2 +- app/views/groups/_projects.html.haml | 20 +++++ app/views/groups/issues.atom.builder | 24 ++++++ app/views/groups/issues.html.haml | 19 +++++ app/views/groups/merge_requests.html.haml | 18 +++++ app/views/groups/people.html.haml | 12 +++ app/views/groups/search.html.haml | 75 +++++++++++++++++++ app/views/groups/show.atom.builder | 29 +++++++ app/views/groups/show.html.haml | 42 +++++++++++ app/views/groups/show.js.haml | 2 + app/views/layouts/group.html.haml | 22 +++--- config/routes.rb | 13 ++++ 16 files changed, 339 insertions(+), 27 deletions(-) create mode 100644 app/controllers/groups_controller.rb create mode 100644 app/views/groups/_projects.html.haml create mode 100644 app/views/groups/issues.atom.builder create mode 100644 app/views/groups/issues.html.haml create mode 100644 app/views/groups/merge_requests.html.haml create mode 100644 app/views/groups/people.html.haml create mode 100644 app/views/groups/search.html.haml create mode 100644 app/views/groups/show.atom.builder create mode 100644 app/views/groups/show.html.haml create mode 100644 app/views/groups/show.js.haml diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss index a29504ec..53a7c2bc 100644 --- a/app/assets/stylesheets/sections/projects.scss +++ b/app/assets/stylesheets/sections/projects.scss @@ -13,6 +13,8 @@ font-size:16px; text-shadow: 0 1px 1px #fff; padding: 2px 10px; + line-height:32px; + font-size:14px; } ul { li { diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 75cf726d..1f142dae 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -3,21 +3,14 @@ class DashboardController < ApplicationController def index @groups = Group.where(id: current_user.projects.pluck(:group_id)) - @projects = current_user.projects_with_events - - if params[:group].present? - @group = Group.find_by_code(params[:group]) - @projects = @projects.where(group_id: @group.id) - end - @projects = @projects.page(params[:page]).per(40) @events = Event.recent_for_user(current_user).limit(20).offset(params[:offset] || 0) @last_push = current_user.recent_push respond_to do |format| - format.html { render 'index', layout: determine_layout } + format.html format.js format.atom { render layout: false } end @@ -41,10 +34,4 @@ class DashboardController < ApplicationController format.atom { render layout: false } end end - - protected - - def determine_layout - @group ? 'group' : 'application' - end end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb new file mode 100644 index 00000000..486b0bee --- /dev/null +++ b/app/controllers/groups_controller.rb @@ -0,0 +1,69 @@ +class GroupsController < ApplicationController + respond_to :html + layout 'group' + + before_filter :group + before_filter :projects + + def show + @events = Event.where(project_id: project_ids). + order('id DESC'). + limit(20).offset(params[:offset] || 0) + + @last_push = current_user.recent_push + + respond_to do |format| + format.html + format.js + format.atom { render layout: false } + end + end + + # Get authored or assigned open merge requests + def merge_requests + @merge_requests = current_user.cared_merge_requests.order("created_at DESC").page(params[:page]).per(20) + end + + # Get only assigned issues + def issues + @user = current_user + @issues = current_user.assigned_issues.opened.order("created_at DESC").page(params[:page]).per(20) + @issues = @issues.includes(:author, :project) + + respond_to do |format| + format.html + format.atom { render layout: false } + end + end + + def search + query = params[:search] + + @merge_requests = [] + @issues = [] + + if query.present? + @projects = @projects.search(query).limit(10) + @merge_requests = MergeRequest.where(project_id: project_ids).search(query).limit(10) + @issues = Issue.where(project_id: project_ids).search(query).limit(10) + end + end + + def people + @users = group.projects.map(&:users).flatten.uniq + end + + protected + + def group + @group ||= Group.find_by_code(params[:id]) + end + + def projects + @projects ||= current_user.projects_with_events.where(group_id: @group.id) + end + + def project_ids + projects.map(&:id) + end +end diff --git a/app/views/dashboard/_groups.html.haml b/app/views/dashboard/_groups.html.haml index b46f675f..5180bfa0 100644 --- a/app/views/dashboard/_groups.html.haml +++ b/app/views/dashboard/_groups.html.haml @@ -6,7 +6,7 @@ %ul.unstyled - groups.each do |group| %li.wll - = link_to dashboard_path(group: group), class: dom_class(group) do + = link_to group_path(id: group.code), class: dom_class(group) do %strong.group_name= truncate(group.name, length: 25) %span.arrow → diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml index aa53ebfd..dc520a22 100644 --- a/app/views/dashboard/index.html.haml +++ b/app/views/dashboard/index.html.haml @@ -9,7 +9,7 @@ .loading.hide .side = render "events/event_last_push", event: @last_push - - unless @group + - if @groups.present? = render "groups", groups: @groups = render "projects", projects: @projects %div diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml new file mode 100644 index 00000000..35433057 --- /dev/null +++ b/app/views/groups/_projects.html.haml @@ -0,0 +1,20 @@ +.projects_box + %h5 + Projects + %small + (#{projects.count}) + - if current_user.can_create_project? + %span.right + = link_to new_project_path, class: "btn very_small info" do + %i.icon-plus + New Project + %ul.unstyled + - projects.each do |project| + %li.wll + = link_to project_path(project), class: dom_class(project) do + %strong.project_name= truncate(project.name, length: 25) + %span.arrow + → + %span.last_activity + %strong Last activity: + %span= project_last_activity(project) diff --git a/app/views/groups/issues.atom.builder b/app/views/groups/issues.atom.builder new file mode 100644 index 00000000..5bd07bcd --- /dev/null +++ b/app/views/groups/issues.atom.builder @@ -0,0 +1,24 @@ +xml.instruct! +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do + xml.title "#{@user.name} issues" + xml.link :href => dashboard_issues_url(:atom, :private_token => @user.private_token), :rel => "self", :type => "application/atom+xml" + xml.link :href => dashboard_issues_url(:private_token => @user.private_token), :rel => "alternate", :type => "text/html" + xml.id dashboard_issues_url(:private_token => @user.private_token) + xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? + + @issues.each do |issue| + xml.entry do + xml.id project_issue_url(issue.project, issue) + xml.link :href => project_issue_url(issue.project, issue) + xml.title truncate(issue.title, :length => 80) + xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") + xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(issue.author_email) + xml.author do |author| + xml.name issue.author_name + xml.email issue.author_email + end + xml.summary issue.title + end + end +end + diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml new file mode 100644 index 00000000..cc488d57 --- /dev/null +++ b/app/views/groups/issues.html.haml @@ -0,0 +1,19 @@ +%h3.page_title + Issues + %small (assigned to you) + %small.right #{@issues.total_count} issues + +%br +.clearfix +- if @issues.any? + - @issues.group_by(&:project).each do |group| + %div.ui-box + - @project = group[0] + %h5= @project.name + %ul.unstyled.issues_table + - group[1].each do |issue| + = render(partial: 'issues/show', locals: {issue: issue}) + %hr + = paginate @issues, theme: "gitlab" +- else + %h3.nothing_here_message Nothing to show here diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml new file mode 100644 index 00000000..23a7e722 --- /dev/null +++ b/app/views/groups/merge_requests.html.haml @@ -0,0 +1,18 @@ +%h3.page_title + Merge Requests + %small (authored by or assigned to you) + %small.right #{@merge_requests.total_count} merge requests + +%br +- if @merge_requests.any? + - @merge_requests.group_by(&:project).each do |group| + %ul.unstyled.ui-box + - @project = group[0] + %h5= @project.name + - group[1].each do |merge_request| + = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request}) + %hr + = paginate @merge_requests, theme: "gitlab" + +- else + %h3.nothing_here_message Nothing to show here diff --git a/app/views/groups/people.html.haml b/app/views/groups/people.html.haml new file mode 100644 index 00000000..4c1865a2 --- /dev/null +++ b/app/views/groups/people.html.haml @@ -0,0 +1,12 @@ +.ui-box + %h5 + People + %small + (#{@users.count}) + %ul.unstyled + - @users.each do |user| + %li.wll + = image_tag gravatar_icon(user.email, 16), class: "avatar s16" + %strong= user.name + %span.cgray= user.email + diff --git a/app/views/groups/search.html.haml b/app/views/groups/search.html.haml new file mode 100644 index 00000000..6ca5630f --- /dev/null +++ b/app/views/groups/search.html.haml @@ -0,0 +1,75 @@ += form_tag search_group_path(@group), method: :get, class: 'form-inline' do |f| + .padded + = label_tag :search do + %strong Looking for + .input + = search_field_tag :search, params[:search], placeholder: "issue 143", class: "input-xxlarge search-text-input", id: "dashboard_search" + = submit_tag 'Search', class: "btn primary wide" +- if params[:search].present? + %br + %h3 + Search results + %small (#{@projects.count + @merge_requests.count + @issues.count}) + %hr + .search_results + .row + .span6 + %table + %thead + %tr + %th Projects + %tbody + - @projects.each do |project| + %tr + %td + = link_to project do + %strong.term= project.name + %small.cgray + last activity at + = project.last_activity_date.stamp("Aug 25, 2011") + - if @projects.blank? + %tr + %td + %h4.nothing_here_message No Projects + %br + %table + %thead + %tr + %th Merge Requests + %tbody + - @merge_requests.each do |merge_request| + %tr + %td + = link_to [merge_request.project, merge_request] do + %span.badge.badge-info ##{merge_request.id} + – + %strong.term= truncate merge_request.title, length: 50 + %strong.right + %span.label= merge_request.project.name + - if @merge_requests.blank? + %tr + %td + %h4.nothing_here_message No Merge Requests + .span6 + %table + %thead + %tr + %th Issues + %tbody + - @issues.each do |issue| + %tr + %td + = link_to [issue.project, issue] do + %span.badge.badge-info ##{issue.id} + – + %strong.term= truncate issue.title, length: 40 + %strong.right + %span.label= issue.project.name + - if @issues.blank? + %tr + %td + %h4.nothing_here_message No Issues + :javascript + $(function() { + $(".search_results .term").highlight("#{params[:search]}"); + }) diff --git a/app/views/groups/show.atom.builder b/app/views/groups/show.atom.builder new file mode 100644 index 00000000..fa3bfade --- /dev/null +++ b/app/views/groups/show.atom.builder @@ -0,0 +1,29 @@ +xml.instruct! +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do + xml.title "Dashboard feed#{" - #{current_user.name}" if current_user.name.present?}" + xml.link :href => projects_url(:atom), :rel => "self", :type => "application/atom+xml" + xml.link :href => projects_url, :rel => "alternate", :type => "text/html" + xml.id projects_url + xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? + + @events.each do |event| + if event.allowed? + event = EventDecorator.decorate(event) + xml.entry do + event_link = event.feed_url + event_title = event.feed_title + + xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}" + xml.link :href => event_link + xml.title truncate(event_title, :length => 80) + xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") + xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(event.author_email) + xml.author do |author| + xml.name event.author_name + xml.email event.author_email + end + xml.summary event_title + end + end + end +end diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml new file mode 100644 index 00000000..7552128e --- /dev/null +++ b/app/views/groups/show.html.haml @@ -0,0 +1,42 @@ +- if @projects.any? + .projects + .activities.span8 + = render 'shared/no_ssh' + - if @events.any? + .content_list= render @events + - else + %h4.nothing_here_message Projects activity will be displayed here + .loading.hide + .side + = render "events/event_last_push", event: @last_push + = render "projects", projects: @projects + %div + %span.rss-icon + = link_to dashboard_path(:atom, { private_token: current_user.private_token }) do + = image_tag "rss_ui.png", title: "feed" + %strong News Feed + + %hr + .gitlab-promo + = link_to "Homepage", "http://gitlabhq.com" + = link_to "Blog", "http://blog.gitlabhq.com" + = link_to "@gitlabhq", "https://twitter.com/gitlabhq" + + +- else + %h3.nothing_here_message There are no projects you have access to. + %br + %h4.nothing_here_message + - if current_user.can_create_project? + You can create up to + = current_user.projects_limit + projects. Click on button below to add a new one + .link_holder + = link_to new_project_path, class: "btn primary" do + New Project » + - else + If you will be added to project - it will be displayed here + + +:javascript + $(function(){ Pager.init(20); }); diff --git a/app/views/groups/show.js.haml b/app/views/groups/show.js.haml new file mode 100644 index 00000000..7e5a148e --- /dev/null +++ b/app/views/groups/show.js.haml @@ -0,0 +1,2 @@ +:plain + Pager.append(#{@events.count}, "#{escape_javascript(render(@events))}"); diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml index 810c296e..e4277eff 100644 --- a/app/views/layouts/group.html.haml +++ b/app/views/layouts/group.html.haml @@ -3,22 +3,22 @@ = render "layouts/head" %body{class: "#{app_theme} application"} = render "layouts/flash" - = render "layouts/head_panel", title: "#{@group.name}:Dashboard" + = render "layouts/head_panel", title: "#{@group.name}" .container %ul.main_menu - = nav_link(path: 'dashboard#index', html_options: {class: 'home'}) do - = link_to "Home", root_path, title: "Home" - = nav_link(path: 'dashboard#issues') do - = link_to dashboard_issues_path(group: @group) do + = nav_link(path: 'groups#show', html_options: {class: 'home'}) do + = link_to "Home", group_path(@group), title: "Home" + = nav_link(path: 'groups#issues') do + = link_to issues_group_path(@group) do Issues %span.count= current_user.assigned_issues.opened.count - = nav_link(path: 'dashboard#merge_requests') do - = link_to dashboard_merge_requests_path(group: @group) do + = nav_link(path: 'groups#merge_requests') do + = link_to merge_requests_group_path(@group) do Merge Requests %span.count= current_user.cared_merge_requests.count - = nav_link(path: 'search#show') do - = link_to "People", "#" - = nav_link(path: 'help#index') do - = link_to "Help", help_path + = nav_link(path: 'groups#search') do + = link_to "Search", search_group_path(@group) + = nav_link(path: 'groups#people') do + = link_to "People", people_group_path(@group) .content= yield diff --git a/config/routes.rb b/config/routes.rb index 2b923379..f6bebc6b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -86,6 +86,19 @@ Gitlab::Application.routes.draw do get "dashboard/issues" => "dashboard#issues" get "dashboard/merge_requests" => "dashboard#merge_requests" + + # + # Groups Area + # + resources :groups, constraints: { id: /[^\/]+/ }, only: [:show] do + member do + get :issues + get :merge_requests + get :search + get :people + end + end + resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create] devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks } From 010ac2b17f1e4bd0e104a90fd8bfc8c7bcb67ac8 Mon Sep 17 00:00:00 2001 From: randx Date: Tue, 2 Oct 2012 22:08:30 +0300 Subject: [PATCH 06/10] Added back link. cleanup group show page --- app/views/groups/show.html.haml | 60 +++++++++++++-------------------- 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 7552128e..074288a9 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,42 +1,28 @@ -- if @projects.any? - .projects - .activities.span8 - = render 'shared/no_ssh' - - if @events.any? - .content_list= render @events - - else - %h4.nothing_here_message Projects activity will be displayed here - .loading.hide - .side - = render "events/event_last_push", event: @last_push - = render "projects", projects: @projects - %div - %span.rss-icon - = link_to dashboard_path(:atom, { private_token: current_user.private_token }) do - = image_tag "rss_ui.png", title: "feed" - %strong News Feed - - %hr - .gitlab-promo - = link_to "Homepage", "http://gitlabhq.com" - = link_to "Blog", "http://blog.gitlabhq.com" - = link_to "@gitlabhq", "https://twitter.com/gitlabhq" - - -- else - %h3.nothing_here_message There are no projects you have access to. - %br - %h4.nothing_here_message - - if current_user.can_create_project? - You can create up to - = current_user.projects_limit - projects. Click on button below to add a new one - .link_holder - = link_to new_project_path, class: "btn primary" do - New Project » +.projects + .activities.span8 + .back_link + = link_to dashboard_path do + ← To dashboard + = render 'shared/no_ssh' + - if @events.any? + .content_list= render @events - else - If you will be added to project - it will be displayed here + %h4.nothing_here_message Projects activity will be displayed here + .loading.hide + .side + = render "events/event_last_push", event: @last_push + = render "projects", projects: @projects + %div + %span.rss-icon + = link_to dashboard_path(:atom, { private_token: current_user.private_token }) do + = image_tag "rss_ui.png", title: "feed" + %strong News Feed + %hr + .gitlab-promo + = link_to "Homepage", "http://gitlabhq.com" + = link_to "Blog", "http://blog.gitlabhq.com" + = link_to "@gitlabhq", "https://twitter.com/gitlabhq" :javascript $(function(){ Pager.init(20); }); From 224fb5770ce71061861f5c2bddb01924d668a841 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 3 Oct 2012 12:49:43 +0300 Subject: [PATCH 07/10] Added ability to manage groups from admin --- app/controllers/admin/groups_controller.rb | 8 ++++++++ app/views/admin/groups/_form.html.haml | 2 +- app/views/admin/groups/edit.html.haml | 3 +++ app/views/admin/groups/index.html.haml | 1 + app/views/admin/groups/show.html.haml | 4 ++++ app/views/admin/projects/index.html.haml | 1 + app/views/admin/projects/show.html.haml | 1 + app/views/admin/shared/_projects_head.html.haml | 5 +++++ app/views/groups/_projects.html.haml | 5 ----- app/views/layouts/admin.html.haml | 2 +- config/routes.rb | 1 + 11 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 app/views/admin/groups/edit.html.haml create mode 100644 app/views/admin/shared/_projects_head.html.haml diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 612abf8c..49082e1d 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -52,6 +52,14 @@ class Admin::GroupsController < AdminController redirect_to :back, notice: 'Group was successfully updated.' end + def remove_project + @project = Project.find(params[:project_id]) + @project.group_id = nil + @project.save + + redirect_to :back, notice: 'Group was successfully updated.' + end + def destroy @group.destroy diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml index a1ba9406..46c59563 100644 --- a/app/views/admin/groups/_form.html.haml +++ b/app/views/admin/groups/_form.html.haml @@ -16,4 +16,4 @@ = f.text_field :code, placeholder: "example" .form-actions - = f.submit 'Create group', class: "btn primary" + = f.submit 'Save group', class: "btn save-btn" diff --git a/app/views/admin/groups/edit.html.haml b/app/views/admin/groups/edit.html.haml new file mode 100644 index 00000000..9904122c --- /dev/null +++ b/app/views/admin/groups/edit.html.haml @@ -0,0 +1,3 @@ +%h3.page_title Edit Group +%br += render 'form' diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml index 6952c4c9..25efc9ee 100644 --- a/app/views/admin/groups/index.html.haml +++ b/app/views/admin/groups/index.html.haml @@ -1,3 +1,4 @@ += render 'admin/shared/projects_head' %h3.page_title Groups = link_to 'New Group', new_admin_group_path, class: "btn small right" diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 5d348eec..309a10e5 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -1,3 +1,4 @@ += render 'admin/shared/projects_head' %h3.page_title Group: #{@group.name} = link_to edit_admin_group_path(@group), class: "btn right" do @@ -38,6 +39,9 @@ %li.wll %strong = link_to project.name, [:admin, project] + .right + = link_to 'Remove from group', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Are you sure?', method: :delete, class: "btn danger small" + .clearfix %br %h3 Add new project diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index bd38ae72..13b0b44a 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -1,3 +1,4 @@ += render 'admin/shared/projects_head' %h3.page_title Projects = link_to 'New Project', new_admin_project_path, class: "btn small right" diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index ede48ea2..f16a0211 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -1,3 +1,4 @@ += render 'admin/shared/projects_head' %h3.page_title Project: #{@admin_project.name} = link_to edit_admin_project_path(@admin_project), class: "btn right" do diff --git a/app/views/admin/shared/_projects_head.html.haml b/app/views/admin/shared/_projects_head.html.haml new file mode 100644 index 00000000..3f5c34c5 --- /dev/null +++ b/app/views/admin/shared/_projects_head.html.haml @@ -0,0 +1,5 @@ +%ul.nav.nav-tabs + = nav_link(controller: :projects) do + = link_to 'Projects', admin_projects_path, class: "tab" + = nav_link(controller: :groups) do + = link_to 'Groups', admin_groups_path, class: "tab" diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml index 35433057..b565dad3 100644 --- a/app/views/groups/_projects.html.haml +++ b/app/views/groups/_projects.html.haml @@ -3,11 +3,6 @@ Projects %small (#{projects.count}) - - if current_user.can_create_project? - %span.right - = link_to new_project_path, class: "btn very_small info" do - %i.icon-plus - New Project %ul.unstyled - projects.each do |project| %li.wll diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml index dbb6939d..582f86ba 100644 --- a/app/views/layouts/admin.html.haml +++ b/app/views/layouts/admin.html.haml @@ -8,7 +8,7 @@ %ul.main_menu = nav_link(controller: :dashboard, html_options: {class: 'home'}) do = link_to "Stats", admin_root_path - = nav_link(controller: :projects) do + = nav_link(controller: [:projects, :groups]) do = link_to "Projects", admin_projects_path = nav_link(controller: :users) do = link_to "Users", admin_users_path diff --git a/config/routes.rb b/config/routes.rb index f6bebc6b..060fbf16 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -46,6 +46,7 @@ Gitlab::Application.routes.draw do resources :groups, constraints: { id: /[^\/]+/ } do member do put :project_update + delete :remove_project end end resources :projects, constraints: { id: /[^\/]+/ } do From 8b76e30656954c2dd95121fff46c4bc6cc81bb74 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 3 Oct 2012 13:42:17 +0300 Subject: [PATCH 08/10] Spianch test for group dashboard --- app/models/group.rb | 4 ++++ app/views/groups/show.html.haml | 8 ++++--- app/views/snippets/show.html.haml | 23 +++++++++++--------- features/dashboard/dashboard.feature | 5 +++++ features/group/group.feature | 9 ++++++++ features/steps/group/group.rb | 32 ++++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 13 deletions(-) create mode 100644 features/group/group.feature create mode 100644 features/steps/group/group.rb diff --git a/app/models/group.rb b/app/models/group.rb index 43283066..1bb805e8 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -22,6 +22,10 @@ class Group < ActiveRecord::Base delegate :name, to: :owner, allow_nil: true, prefix: true + def self.search query + where("name like :query or code like :query", query: "%#{query}%") + end + def to_param code end diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 074288a9..cd86a01f 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,8 +1,10 @@ .projects .activities.span8 - .back_link - = link_to dashboard_path do - ← To dashboard + = link_to dashboard_path, class: 'btn very_small' do + ← To dashboard +   + %span.cgray Events and projects are filtered in scope of group + %hr = render 'shared/no_ssh' - if @events.any? .content_list= render @events diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index 4188a9f1..1b8701e9 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -7,14 +7,17 @@ = link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn small right" %br -.file_holder - .file_title - %i.icon-file - %strong= @snippet.file_name - %span.options - = link_to "raw", raw_project_snippet_path(@project, @snippet), class: "btn very_small", target: "_blank" - .file_content.code - %div{class: current_user.dark_scheme ? "black" : ""} - = raw @snippet.colorize(options: { linenos: 'True'}) +%div + .file_holder + .file_title + %i.icon-file + %strong= @snippet.file_name + %span.options + = link_to "raw", raw_project_snippet_path(@project, @snippet), class: "btn very_small", target: "_blank" + .file_content.code + %div{class: current_user.dark_scheme ? "black" : ""} + = raw @snippet.colorize(options: { linenos: 'True'}) -= render "notes/notes_with_form", tid: @snippet.id, tt: "snippet" + +%div + = render "notes/notes_with_form", tid: @snippet.id, tt: "snippet" diff --git a/features/dashboard/dashboard.feature b/features/dashboard/dashboard.feature index 40217a7d..24296f46 100644 --- a/features/dashboard/dashboard.feature +++ b/features/dashboard/dashboard.feature @@ -10,6 +10,11 @@ Feature: Dashboard Then I should see "Shop" project link Then I should see project "Shop" activity feed + Scenario: I should see groups list + Given I have group with projects + And I visit dashboard page + Then I should see groups list + Scenario: I should see last push widget Then I should see last push widget And I click "Create Merge Request" link diff --git a/features/group/group.feature b/features/group/group.feature new file mode 100644 index 00000000..dbddb92c --- /dev/null +++ b/features/group/group.feature @@ -0,0 +1,9 @@ +Feature: Groups + Background: + Given I sign in as a user + And I have group with projects + + Scenario: I should see group dashboard list + When I visit group page + Then I should see projects list + And I should see projects activity feed diff --git a/features/steps/group/group.rb b/features/steps/group/group.rb new file mode 100644 index 00000000..798c62c3 --- /dev/null +++ b/features/steps/group/group.rb @@ -0,0 +1,32 @@ +class Groups < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + + When 'I visit group page' do + visit group_path(current_group) + end + + Then 'I should see projects list' do + current_user.projects.each do |project| + page.should have_link project.name + end + end + + And 'I have group with projects' do + @group = Factory :group + @project = Factory :project, group: @group + @event = Factory :closed_issue_event, project: @project + + @project.add_access current_user, :admin + end + + And 'I should see projects activity feed' do + page.should have_content 'closed issue' + end + + protected + + def current_group + @group ||= Group.first + end +end From ce1b79afa9faa8ffaae7392f9e48273c230753c4 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 3 Oct 2012 14:26:37 +0300 Subject: [PATCH 09/10] SQL Fixes --- app/controllers/groups_controller.rb | 2 +- app/models/group.rb | 6 +++++- app/models/project.rb | 6 +++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 486b0bee..4a05434c 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -50,7 +50,7 @@ class GroupsController < ApplicationController end def people - @users = group.projects.map(&:users).flatten.uniq + @users = group.users end protected diff --git a/app/models/group.rb b/app/models/group.rb index 1bb805e8..628d0009 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -23,10 +23,14 @@ class Group < ActiveRecord::Base delegate :name, to: :owner, allow_nil: true, prefix: true def self.search query - where("name like :query or code like :query", query: "%#{query}%") + where("name like :query OR code like :query", query: "%#{query}%") end def to_param code end + + def users + User.joins(:users_projects).where('users_projects.project_id' => project_ids).uniq + end end diff --git a/app/models/project.rb b/app/models/project.rb index f525f292..c00bb456 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -30,15 +30,15 @@ class Project < ActiveRecord::Base # Scopes scope :public_only, where(private_flag: false) - scope :without_user, ->(user) { where("id not in (:ids)", ids: user.projects.map(&:id) ) } - scope :not_in_group, ->(group) { where("id not in (:ids)", ids: group.project_ids ) } + scope :without_user, ->(user) { where("id NOT IN (:ids)", ids: user.projects.map(&:id) ) } + scope :not_in_group, ->(group) { where("id NOT IN (:ids)", ids: group.project_ids ) } def self.active joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC") end def self.search query - where("name like :query or code like :query or path like :query", query: "%#{query}%") + where("name like :query OR code like :query OR path like :query", query: "%#{query}%") end def self.create_by_user(params, user) From c8412bc9edbbed7a38cc4880f0d8cbb9091eb1d9 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 3 Oct 2012 15:02:02 +0300 Subject: [PATCH 10/10] Dont change params hash. Use dup instead --- app/controllers/admin/groups_controller.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 49082e1d..bfde6548 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -32,13 +32,14 @@ class Admin::GroupsController < AdminController end def update - owner_id = params[:group].delete(:owner_id) + group_params = params[:group].dup + owner_id =group_params.delete(:owner_id) if owner_id @group.owner = User.find(owner_id) end - if @group.update_attributes(params[:group]) + if @group.update_attributes(group_params) redirect_to [:admin, @group], notice: 'Group was successfully updated.' else render action: "edit"