Commit 251df827a5308d483a95242970569075ab655703
1 parent
5221dbfe
Exists in
spb-stable
and in
3 other branches
added group avatars
Showing
15 changed files
with
161 additions
and
2 deletions
Show diff stats
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/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 < 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
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 | + | |
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/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 < 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 | ... | ... |