Commit 251df827a5308d483a95242970569075ab655703

Authored by Steven Thonus
1 parent 5221dbfe

added group avatars

app/assets/images/no_group_avatar.png 0 → 100644

704 Bytes

app/assets/javascripts/groups.js.coffee
... ... @@ -4,3 +4,14 @@ class GroupMembers
4 4 $(this).fadeOut()
5 5  
6 6 @GroupMembers = GroupMembers
  7 +
  8 +$ ->
  9 + # avatar
  10 + $('.js-choose-group-avatar-button').bind "click", ->
  11 + form = $(this).closest("form")
  12 + form.find(".js-group-avatar-input").click()
  13 +
  14 + $('.js-group-avatar-input').bind "change", ->
  15 + form = $(this).closest("form")
  16 + filename = $(this).val().replace(/^.*[\\\/]/, '')
  17 + form.find(".js-avatar-filename").text(filename)
7 18 \ No newline at end of file
... ...
app/controllers/groups/avatars_controller.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class Groups::AvatarsController < ApplicationController
  2 + layout "profile"
  3 +
  4 + def destroy
  5 + @group = Group.find_by(path: params[:group_id])
  6 + @group.remove_avatar!
  7 +
  8 + @group.save
  9 +
  10 + redirect_to edit_group_path(@group)
  11 + end
  12 +end
... ...
app/helpers/application_helper.rb
... ... @@ -49,6 +49,15 @@ module ApplicationHelper
49 49 args.any? { |v| v.to_s.downcase == action_name }
50 50 end
51 51  
  52 + def group_icon(group_path)
  53 + group = Group.find_by(path: group_path)
  54 + if group && group.avatar.present?
  55 + group.avatar.url
  56 + else
  57 + '/assets/no_group_avatar.png'
  58 + end
  59 + end
  60 +
52 61 def avatar_icon(user_email = '', size = nil)
53 62 user = User.find_by(email: user_email)
54 63 if user && user.avatar.present?
... ...
app/models/group.rb
... ... @@ -12,10 +12,20 @@
12 12 # description :string(255) default(""), not null
13 13 #
14 14  
  15 +require 'carrierwave/orm/activerecord'
  16 +require 'file_size_validator'
  17 +
15 18 class Group < Namespace
16 19 has_many :users_groups, dependent: :destroy
17 20 has_many :users, through: :users_groups
18 21  
  22 + attr_accessible :avatar
  23 +
  24 + validate :avatar_type, if: ->(user) { user.avatar_changed? }
  25 + validates :avatar, file_size: { maximum: 100.kilobytes.to_i }
  26 +
  27 + mount_uploader :avatar, AttachmentUploader
  28 +
19 29 def human_name
20 30 name
21 31 end
... ... @@ -50,4 +60,10 @@ class Group &lt; Namespace
50 60 def members
51 61 users_groups
52 62 end
  63 +
  64 + def avatar_type
  65 + unless self.avatar.image?
  66 + self.errors.add :avatar, "only images allowed"
  67 + end
  68 + end
53 69 end
... ...
app/models/namespace.rb
... ... @@ -10,6 +10,7 @@
10 10 # updated_at :datetime not null
11 11 # type :string(255)
12 12 # description :string(255) default(""), not null
  13 +# avatar :string(255)
13 14 #
14 15  
15 16 class Namespace < ActiveRecord::Base
... ...
app/views/dashboard/_groups.html.haml
... ... @@ -10,6 +10,7 @@
10 10 - groups.each do |group|
11 11 %li.group-row
12 12 = link_to group_path(id: group.path), class: dom_class(group) do
  13 + = image_tag group_icon(group.path), class: "avatar s32"
13 14 %span.group-name.filter-title
14 15 = truncate(group.name, length: 35)
15 16 %span.arrow
... ...
app/views/groups/edit.html.haml
... ... @@ -20,7 +20,7 @@
20 20 %strong= @group.name
21 21 group settings:
22 22 %div.form-holder
23   - = form_for @group, html: { class: "form-horizontal" } do |f|
  23 + = form_for @group, html: { multipart: true, class: "form-horizontal" }, authenticity_token: true do |f|
24 24 - if @group.errors.any?
25 25 .alert.alert-danger
26 26 %span= @group.errors.full_messages.first
... ... @@ -35,6 +35,26 @@
35 35 .col-sm-10
36 36 = f.text_area :description, maxlength: 250, class: "form-control js-gfm-input", rows: 4
37 37  
  38 + .form-group
  39 + .col-sm-2
  40 + .col-sm-10
  41 + = image_tag group_icon(@group.to_param), alt: '', class: 'avatar s160'
  42 + %p.light
  43 + - if @group.avatar?
  44 + You can change your group avatar here
  45 + - else
  46 + You can upload an group avatar here
  47 + %a.choose-btn.btn.btn-small.js-choose-group-avatar-button
  48 + %i.icon-paper-clip
  49 + %span Choose File ...
  50 + &nbsp;
  51 + %span.file_name.js-avatar-filename File name...
  52 + = f.file_field :avatar, class: "js-group-avatar-input hidden"
  53 + .light The maximum file size allowed is 100KB.
  54 + - if @group.avatar?
  55 + %hr
  56 + = link_to 'Remove avatar', group_avatar_path(@group.to_param), data: { confirm: "Group avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar"
  57 +
38 58 .form-actions
39 59 = f.submit 'Save group', class: "btn btn-save"
40 60  
... ...
config/routes.rb
... ... @@ -156,6 +156,9 @@ Gitlab::Application.routes.draw do
156 156 end
157 157  
158 158 resources :users_groups, only: [:create, :update, :destroy]
  159 + scope module: :groups do
  160 + resource :avatar, only: [:destroy]
  161 + end
159 162 end
160 163  
161 164 resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create]
... ...
db/migrate/20140127170938_add_group_avatars.rb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +class AddGroupAvatars < ActiveRecord::Migration
  2 + def change
  3 + add_column :namespaces, :avatar, :string
  4 + end
  5 +end
... ...
db/schema.rb
... ... @@ -11,7 +11,7 @@
11 11 #
12 12 # It's strongly recommended that you check this file into your version control system.
13 13  
14   -ActiveRecord::Schema.define(version: 20140122122549) do
  14 +ActiveRecord::Schema.define(version: 20140127170938) do
15 15  
16 16 create_table "broadcast_messages", force: true do |t|
17 17 t.text "message", null: false
... ... @@ -152,6 +152,7 @@ ActiveRecord::Schema.define(version: 20140122122549) do
152 152 t.datetime "updated_at", null: false
153 153 t.string "type"
154 154 t.string "description", default: "", null: false
  155 + t.string "avatar"
155 156 end
156 157  
157 158 add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree
... ...
features/group/group.feature
... ... @@ -31,3 +31,17 @@ Feature: Groups
31 31 And I change group name
32 32 Then I should see new group name
33 33  
  34 + Scenario: I edit my group avatar
  35 + When I visit group settings page
  36 + And I change my group avatar
  37 + And I visit group settings page
  38 + Then I should see new group avatar
  39 + And I should see the "Remove avatar" button
  40 +
  41 + Scenario: I remove my group avatar
  42 + When I visit group settings page
  43 + And I have an group avatar
  44 + And I visit group settings page
  45 + And I remove my group avatar
  46 + Then I should not see my group avatar
  47 + And I should not see the "Remove avatar" button
... ...
features/steps/group/group.rb
... ... @@ -98,6 +98,40 @@ class Groups &lt; Spinach::FeatureSteps
98 98 end
99 99 end
100 100  
  101 + step 'I change my group avatar' do
  102 + attach_file(:group_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png'))
  103 + click_button "Save group"
  104 + @group.reload
  105 + end
  106 +
  107 + step 'I should see new group avatar' do
  108 + @group.avatar.should be_instance_of AttachmentUploader
  109 + @group.avatar.url.should == "/uploads/group/avatar/#{ @group.id }/gitlab_logo.png"
  110 + end
  111 +
  112 + step 'I should see the "Remove avatar" button' do
  113 + page.should have_link("Remove avatar")
  114 + end
  115 +
  116 + step 'I have an group avatar' do
  117 + attach_file(:group_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png'))
  118 + click_button "Save group"
  119 + @group.reload
  120 + end
  121 +
  122 + step 'I remove my group avatar' do
  123 + click_link "Remove avatar"
  124 + @group.reload
  125 + end
  126 +
  127 + step 'I should not see my group avatar' do
  128 + @group.avatar?.should be_false
  129 + end
  130 +
  131 + step 'I should not see the "Remove avatar" button' do
  132 + page.should_not have_link("Remove avatar")
  133 + end
  134 +
101 135 protected
102 136  
103 137 def current_group
... ...
spec/helpers/application_helper_spec.rb
... ... @@ -39,6 +39,23 @@ describe ApplicationHelper do
39 39 end
40 40 end
41 41  
  42 + describe "group_icon" do
  43 + avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png')
  44 +
  45 + it "should return an url for the avatar" do
  46 + group = create(:group)
  47 + group.avatar = File.open(avatar_file_path)
  48 + group.save!
  49 + group_icon(group.path).to_s.should == "/uploads/group/avatar/#{ group.id }/gitlab_logo.png"
  50 + end
  51 +
  52 + it "should give default avatar_icon when no avatar is present" do
  53 + group = create(:group)
  54 + group.save!
  55 + group_icon(group.path).to_s.should == "/assets/no_group_avatar.png"
  56 + end
  57 + end
  58 +
42 59 describe "avatar_icon" do
43 60 avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png')
44 61  
... ...
spec/models/group_spec.rb
... ... @@ -54,4 +54,19 @@ describe Group do
54 54 group.users_groups.guests.map(&:user).should_not include(user)
55 55 end
56 56 end
  57 +
  58 + describe :avatar_type do
  59 + let(:user) { create(:user) }
  60 + before { group.add_user(user, UsersGroup::MASTER) }
  61 +
  62 + it "should be true if avatar is image" do
  63 + group.update_attribute(:avatar, 'uploads/avatar.png')
  64 + group.avatar_type.should be_true
  65 + end
  66 +
  67 + it "should be false if avatar is html page" do
  68 + group.update_attribute(:avatar, 'uploads/avatar.html')
  69 + group.avatar_type.should == ["only images allowed"]
  70 + end
  71 + end
57 72 end
... ...