mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-12-02 11:59:17 -05:00
FEATURE: allow admins to choose a group as a primary group
FEATURE: allow admins to set a default title for a group
This commit is contained in:
parent
e143eb595f
commit
75890aed26
11 changed files with 220 additions and 19 deletions
|
@ -38,6 +38,15 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{#unless automatic}}
|
||||||
|
<div>
|
||||||
|
<label for="primary_group">
|
||||||
|
{{input type="checkbox" checked=primary_group}}
|
||||||
|
{{i18n 'admin.groups.primary_group'}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{{/unless}}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="alias">{{i18n 'groups.alias_levels.title'}}</label>
|
<label for="alias">{{i18n 'groups.alias_levels.title'}}</label>
|
||||||
{{combo-box name="alias" valueAttribute="value" value=alias_level content=aliasLevelOptions}}
|
{{combo-box name="alias" valueAttribute="value" value=alias_level content=aliasLevelOptions}}
|
||||||
|
@ -52,6 +61,13 @@
|
||||||
{{i18n 'admin.groups.automatic_membership_retroactive'}}
|
{{i18n 'admin.groups.automatic_membership_retroactive'}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="title">
|
||||||
|
{{i18n 'admin.groups.default_title'}}
|
||||||
|
</label>
|
||||||
|
{{input value=title}}
|
||||||
|
</div>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
|
||||||
<div class='buttons'>
|
<div class='buttons'>
|
||||||
|
|
|
@ -61,7 +61,9 @@ const Group = Discourse.Model.extend({
|
||||||
alias_level: this.get('alias_level'),
|
alias_level: this.get('alias_level'),
|
||||||
visible: !!this.get('visible'),
|
visible: !!this.get('visible'),
|
||||||
automatic_membership_email_domains: this.get('emailDomains'),
|
automatic_membership_email_domains: this.get('emailDomains'),
|
||||||
automatic_membership_retroactive: !!this.get('automatic_membership_retroactive')
|
automatic_membership_retroactive: !!this.get('automatic_membership_retroactive'),
|
||||||
|
title: this.get('title'),
|
||||||
|
primary_group: !!this.get('primary_group')
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -23,16 +23,7 @@ class Admin::GroupsController < Admin::AdminController
|
||||||
group = Group.new
|
group = Group.new
|
||||||
|
|
||||||
group.name = (params[:name] || '').strip
|
group.name = (params[:name] || '').strip
|
||||||
group.alias_level = params[:alias_level].to_i if params[:alias_level].present?
|
save_group(group)
|
||||||
group.visible = params[:visible] == "true"
|
|
||||||
group.automatic_membership_email_domains = params[:automatic_membership_email_domains]
|
|
||||||
group.automatic_membership_retroactive = params[:automatic_membership_retroactive] == "true"
|
|
||||||
|
|
||||||
if group.save
|
|
||||||
render_serialized(group, BasicGroupSerializer)
|
|
||||||
else
|
|
||||||
render_json_error group
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
@ -40,10 +31,20 @@ class Admin::GroupsController < Admin::AdminController
|
||||||
|
|
||||||
# group rename is ignored for automatic groups
|
# group rename is ignored for automatic groups
|
||||||
group.name = params[:name] if params[:name] && !group.automatic
|
group.name = params[:name] if params[:name] && !group.automatic
|
||||||
|
save_group(group)
|
||||||
|
end
|
||||||
|
|
||||||
|
def save_group(group)
|
||||||
group.alias_level = params[:alias_level].to_i if params[:alias_level].present?
|
group.alias_level = params[:alias_level].to_i if params[:alias_level].present?
|
||||||
group.visible = params[:visible] == "true"
|
group.visible = params[:visible] == "true"
|
||||||
group.automatic_membership_email_domains = params[:automatic_membership_email_domains]
|
|
||||||
group.automatic_membership_retroactive = params[:automatic_membership_retroactive] == "true"
|
group.automatic_membership_email_domains = params[:automatic_membership_email_domains] unless group.automatic
|
||||||
|
group.automatic_membership_retroactive = params[:automatic_membership_retroactive] == "true" unless group.automatic
|
||||||
|
|
||||||
|
group.primary_group = group.automatic ? false : params["primary_group"] == "true"
|
||||||
|
|
||||||
|
title = params[:title] if params[:title].present?
|
||||||
|
group.title = group.automatic ? nil : title
|
||||||
|
|
||||||
if group.save
|
if group.save
|
||||||
render_serialized(group, BasicGroupSerializer)
|
render_serialized(group, BasicGroupSerializer)
|
||||||
|
|
|
@ -12,6 +12,8 @@ class Group < ActiveRecord::Base
|
||||||
|
|
||||||
after_save :destroy_deletions
|
after_save :destroy_deletions
|
||||||
after_save :automatic_group_membership
|
after_save :automatic_group_membership
|
||||||
|
after_save :update_primary_group
|
||||||
|
after_save :update_title
|
||||||
|
|
||||||
validate :name_format_validator
|
validate :name_format_validator
|
||||||
validates_uniqueness_of :name, case_sensitive: false
|
validates_uniqueness_of :name, case_sensitive: false
|
||||||
|
@ -301,6 +303,59 @@ class Group < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_title
|
||||||
|
return if new_record? && !self.title.present?
|
||||||
|
|
||||||
|
if self.title_changed?
|
||||||
|
sql = <<SQL
|
||||||
|
UPDATE users SET title = :title
|
||||||
|
WHERE (title = :title_was OR
|
||||||
|
title = '' OR
|
||||||
|
title IS NULL) AND
|
||||||
|
COALESCE(title,'') <> COALESCE(:title,'') AND
|
||||||
|
id IN (
|
||||||
|
SELECT user_id
|
||||||
|
FROM group_users
|
||||||
|
WHERE group_id = :id
|
||||||
|
)
|
||||||
|
SQL
|
||||||
|
|
||||||
|
self.class.exec_sql(sql,
|
||||||
|
title: title,
|
||||||
|
title_was: title_was,
|
||||||
|
id: id
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_primary_group
|
||||||
|
return if new_record? && !self.primary_group?
|
||||||
|
|
||||||
|
if self.primary_group_changed?
|
||||||
|
sql = <<SQL
|
||||||
|
UPDATE users
|
||||||
|
/*set*/
|
||||||
|
/*where*/
|
||||||
|
SQL
|
||||||
|
|
||||||
|
builder = SqlBuilder.new(sql)
|
||||||
|
builder.where("
|
||||||
|
id IN (
|
||||||
|
SELECT user_id
|
||||||
|
FROM group_users
|
||||||
|
WHERE group_id = :id
|
||||||
|
)", id: id)
|
||||||
|
|
||||||
|
if primary_group
|
||||||
|
builder.set("primary_group_id = :id")
|
||||||
|
else
|
||||||
|
builder.set("primary_group_id = NULL")
|
||||||
|
builder.where("primary_group_id = :id")
|
||||||
|
end
|
||||||
|
|
||||||
|
builder.exec
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
|
|
|
@ -1,6 +1,49 @@
|
||||||
class GroupUser < ActiveRecord::Base
|
class GroupUser < ActiveRecord::Base
|
||||||
belongs_to :group, counter_cache: "user_count"
|
belongs_to :group, counter_cache: "user_count"
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
||||||
|
after_save :update_title
|
||||||
|
after_destroy :remove_title
|
||||||
|
|
||||||
|
after_save :set_primary_group
|
||||||
|
after_destroy :remove_primary_group
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def set_primary_group
|
||||||
|
if group.primary_group
|
||||||
|
self.class.exec_sql("UPDATE users
|
||||||
|
SET primary_group_id = :id
|
||||||
|
WHERE id = :user_id",
|
||||||
|
id: group.id, user_id: user_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_primary_group
|
||||||
|
self.class.exec_sql("UPDATE users
|
||||||
|
SET primary_group_id = NULL
|
||||||
|
WHERE id = :user_id AND primary_group_id = :id",
|
||||||
|
id: group.id, user_id: user_id)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_title
|
||||||
|
if group.title.present?
|
||||||
|
self.class.exec_sql("UPDATE users SET title = NULL
|
||||||
|
WHERE title = :title AND id = :id",
|
||||||
|
id: user_id,
|
||||||
|
title: group.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_title
|
||||||
|
if group.title.present?
|
||||||
|
self.class.exec_sql("UPDATE users SET title = :title
|
||||||
|
WHERE (title IS NULL OR title = '') AND id = :id",
|
||||||
|
id: user_id,
|
||||||
|
title: group.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
|
|
|
@ -6,5 +6,7 @@ class BasicGroupSerializer < ApplicationSerializer
|
||||||
:alias_level,
|
:alias_level,
|
||||||
:visible,
|
:visible,
|
||||||
:automatic_membership_email_domains,
|
:automatic_membership_email_domains,
|
||||||
:automatic_membership_retroactive
|
:automatic_membership_retroactive,
|
||||||
|
:primary_group,
|
||||||
|
:title
|
||||||
end
|
end
|
||||||
|
|
|
@ -1728,6 +1728,8 @@ en:
|
||||||
automatic: "Automatic"
|
automatic: "Automatic"
|
||||||
automatic_membership_email_domains: "Users who register with an email domain that exactly matches one in this list will be automatically added to this group:"
|
automatic_membership_email_domains: "Users who register with an email domain that exactly matches one in this list will be automatically added to this group:"
|
||||||
automatic_membership_retroactive: "Apply the same email domain rule to add existing registered users"
|
automatic_membership_retroactive: "Apply the same email domain rule to add existing registered users"
|
||||||
|
default_title: "Default title for all users in this group"
|
||||||
|
primary_group: "Automatically set as primary group"
|
||||||
|
|
||||||
api:
|
api:
|
||||||
generate_master: "Generate Master API Key"
|
generate_master: "Generate Master API Key"
|
||||||
|
|
5
db/migrate/20150410002033_add_primary_group_to_groups.rb
Normal file
5
db/migrate/20150410002033_add_primary_group_to_groups.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddPrimaryGroupToGroups < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :groups, :primary_group, :boolean, default: false, null: false
|
||||||
|
end
|
||||||
|
end
|
5
db/migrate/20150410002551_add_title_to_groups.rb
Normal file
5
db/migrate/20150410002551_add_title_to_groups.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddTitleToGroups < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :groups, :title, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -27,7 +27,9 @@ describe Admin::GroupsController do
|
||||||
"alias_level"=>0,
|
"alias_level"=>0,
|
||||||
"visible"=>true,
|
"visible"=>true,
|
||||||
"automatic_membership_email_domains"=>nil,
|
"automatic_membership_email_domains"=>nil,
|
||||||
"automatic_membership_retroactive"=>false
|
"automatic_membership_retroactive"=>false,
|
||||||
|
"title"=>nil,
|
||||||
|
"primary_group"=>false
|
||||||
}])
|
}])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -61,13 +63,15 @@ describe Admin::GroupsController do
|
||||||
|
|
||||||
it "doesn't launch the 'automatic group membership' job when it's not retroactive" do
|
it "doesn't launch the 'automatic group membership' job when it's not retroactive" do
|
||||||
Jobs.expects(:enqueue).never
|
Jobs.expects(:enqueue).never
|
||||||
xhr :put, :update, id: 1, automatic_membership_retroactive: "false"
|
group = Fabricate(:group)
|
||||||
|
xhr :put, :update, id: group.id, automatic_membership_retroactive: "false"
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
end
|
end
|
||||||
|
|
||||||
it "launches the 'automatic group membership' job when it's retroactive" do
|
it "launches the 'automatic group membership' job when it's retroactive" do
|
||||||
Jobs.expects(:enqueue).with(:automatic_group_membership, group_id: 1)
|
group = Fabricate(:group)
|
||||||
xhr :put, :update, id: 1, automatic_membership_retroactive: "true"
|
Jobs.expects(:enqueue).with(:automatic_group_membership, group_id: group.id)
|
||||||
|
xhr :put, :update, id: group.id, automatic_membership_retroactive: "true"
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,73 @@ describe Group do
|
||||||
Group[:staff].user_ids - [-1]
|
Group[:staff].user_ids - [-1]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Correctly handles primary group" do
|
it "Correctly handles primary groups" do
|
||||||
|
group = Fabricate(:group, primary_group: true)
|
||||||
|
user = Fabricate(:user)
|
||||||
|
|
||||||
|
group.add(user)
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.primary_group_id).to eq group.id
|
||||||
|
|
||||||
|
group.remove(user)
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.primary_group_id).to eq nil
|
||||||
|
|
||||||
|
group.add(user)
|
||||||
|
group.primary_group = false
|
||||||
|
group.save
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.primary_group_id).to eq nil
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
it "Correctly handles title" do
|
||||||
|
|
||||||
|
group = Fabricate(:group, title: 'Super Awesome')
|
||||||
|
user = Fabricate(:user)
|
||||||
|
|
||||||
|
expect(user.title).to eq nil
|
||||||
|
|
||||||
|
group.add(user)
|
||||||
|
user.reload
|
||||||
|
|
||||||
|
expect(user.title).to eq 'Super Awesome'
|
||||||
|
|
||||||
|
group.title = 'BOOM'
|
||||||
|
group.save
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.title).to eq 'BOOM'
|
||||||
|
|
||||||
|
group.title = nil
|
||||||
|
group.save
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.title).to eq nil
|
||||||
|
|
||||||
|
group.title = "BOB"
|
||||||
|
group.save
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.title).to eq "BOB"
|
||||||
|
|
||||||
|
group.remove(user)
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.title).to eq nil
|
||||||
|
|
||||||
|
group.add(user)
|
||||||
|
group.destroy
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.title).to eq nil
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
it "Correctly handles removal of primary group" do
|
||||||
group = Fabricate(:group)
|
group = Fabricate(:group)
|
||||||
user = Fabricate(:user)
|
user = Fabricate(:user)
|
||||||
group.add(user)
|
group.add(user)
|
||||||
|
|
Loading…
Reference in a new issue