FEATURE: Option to update category preferences of all users when site setting changed (#8180)
This commit is contained in:
parent
c3cc96084c
commit
b2f682f35e
|
@ -1,10 +1,54 @@
|
||||||
import BufferedContent from "discourse/mixins/buffered-content";
|
import BufferedContent from "discourse/mixins/buffered-content";
|
||||||
import SiteSetting from "admin/models/site-setting";
|
import SiteSetting from "admin/models/site-setting";
|
||||||
import SettingComponent from "admin/mixins/setting-component";
|
import SettingComponent from "admin/mixins/setting-component";
|
||||||
|
import showModal from "discourse/lib/show-modal";
|
||||||
|
import AboutRoute from "discourse/routes/about";
|
||||||
|
|
||||||
export default Ember.Component.extend(BufferedContent, SettingComponent, {
|
export default Ember.Component.extend(BufferedContent, SettingComponent, {
|
||||||
_save() {
|
update(key, value, updateExistingUsers = false) {
|
||||||
|
if (updateExistingUsers) {
|
||||||
|
return SiteSetting.update(key, value, { updateExistingUsers: true });
|
||||||
|
} else {
|
||||||
|
return SiteSetting.update(key, value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_save(callback) {
|
||||||
|
const defaultCategoriesSettings = [
|
||||||
|
"default_categories_watching",
|
||||||
|
"default_categories_tracking",
|
||||||
|
"default_categories_muted",
|
||||||
|
"default_categories_watching_first_post"
|
||||||
|
];
|
||||||
const setting = this.buffered;
|
const setting = this.buffered;
|
||||||
return SiteSetting.update(setting.get("setting"), setting.get("value"));
|
const key = setting.get("setting");
|
||||||
|
const value = setting.get("value");
|
||||||
|
|
||||||
|
if (defaultCategoriesSettings.includes(key)) {
|
||||||
|
AboutRoute.create()
|
||||||
|
.model()
|
||||||
|
.then(result => {
|
||||||
|
const controller = showModal("site-setting-default-categories", {
|
||||||
|
model: {
|
||||||
|
count: result.stats.user_count,
|
||||||
|
key: key.replace(/_/g, " ")
|
||||||
|
},
|
||||||
|
admin: true
|
||||||
|
});
|
||||||
|
|
||||||
|
controller.setProperties({
|
||||||
|
onClose: () => {
|
||||||
|
const updateExistingUsers = controller.get("updateExistingUsers");
|
||||||
|
if (updateExistingUsers === true) {
|
||||||
|
callback(this.update(key, value, true));
|
||||||
|
} else if (updateExistingUsers === false) {
|
||||||
|
callback(this.update(key, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(this.update(key, value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||||
|
|
||||||
|
export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
|
onShow() {
|
||||||
|
this.set("updateExistingUsers", null);
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
updateExistingUsers() {
|
||||||
|
this.set("updateExistingUsers", true);
|
||||||
|
this.send("closeModal");
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.set("updateExistingUsers", false);
|
||||||
|
this.send("closeModal");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -111,21 +111,23 @@ export default Ember.Mixin.create({
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
save() {
|
save() {
|
||||||
this._save()
|
this._save(result => {
|
||||||
.then(() => {
|
result
|
||||||
this.set("validationMessage", null);
|
.then(() => {
|
||||||
this.commitBuffer();
|
this.set("validationMessage", null);
|
||||||
if (AUTO_REFRESH_ON_SAVE.includes(this.get("setting.setting"))) {
|
this.commitBuffer();
|
||||||
this.afterSave();
|
if (AUTO_REFRESH_ON_SAVE.includes(this.get("setting.setting"))) {
|
||||||
}
|
this.afterSave();
|
||||||
})
|
}
|
||||||
.catch(e => {
|
})
|
||||||
if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
|
.catch(e => {
|
||||||
this.set("validationMessage", e.jqXHR.responseJSON.errors[0]);
|
if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
|
||||||
} else {
|
this.set("validationMessage", e.jqXHR.responseJSON.errors[0]);
|
||||||
this.set("validationMessage", I18n.t("generic_error"));
|
} else {
|
||||||
}
|
this.set("validationMessage", I18n.t("generic_error"));
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
|
|
|
@ -25,9 +25,14 @@ SiteSetting.reopenClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
update(key, value) {
|
update(key, value, opts = {}) {
|
||||||
const data = {};
|
const data = {};
|
||||||
data[key] = value;
|
data[key] = value;
|
||||||
|
|
||||||
|
if (opts["updateExistingUsers"] === true) {
|
||||||
|
data["updateExistingUsers"] = true;
|
||||||
|
}
|
||||||
|
|
||||||
return ajax(`/admin/site_settings/${key}`, { type: "PUT", data });
|
return ajax(`/admin/site_settings/${key}`, { type: "PUT", data });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
{{#d-modal-body class="incoming-emails" rawTitle=model.key}}
|
||||||
|
{{i18n "admin.site_settings.default_categories.modal_description" count=model.count}}
|
||||||
|
{{/d-modal-body}}
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
{{d-button action=(action "updateExistingUsers") class='btn btn-primary' label='admin.site_settings.default_categories.modal_yes'}}
|
||||||
|
{{d-button action=(action "cancel") class='btn' label='admin.site_settings.default_categories.modal_no'}}
|
||||||
|
</div>
|
|
@ -20,7 +20,42 @@ class Admin::SiteSettingsController < Admin::AdminController
|
||||||
value = Upload.find_by(url: value) || ''
|
value = Upload.find_by(url: value) || ''
|
||||||
end
|
end
|
||||||
|
|
||||||
|
update_existing_users = params[:updateExistingUsers].present?
|
||||||
|
previous_category_ids = (SiteSetting.send(id) || "").split("|") if update_existing_users
|
||||||
|
|
||||||
SiteSetting.set_and_log(id, value, current_user)
|
SiteSetting.set_and_log(id, value, current_user)
|
||||||
|
|
||||||
|
if update_existing_users
|
||||||
|
new_category_ids = (value || "").split("|")
|
||||||
|
|
||||||
|
case id
|
||||||
|
when "default_categories_watching"
|
||||||
|
notification_level = NotificationLevels.all[:watching]
|
||||||
|
when "default_categories_tracking"
|
||||||
|
notification_level = NotificationLevels.all[:tracking]
|
||||||
|
when "default_categories_muted"
|
||||||
|
notification_level = NotificationLevels.all[:muted]
|
||||||
|
when "default_categories_watching_first_post"
|
||||||
|
notification_level = NotificationLevels.all[:watching_first_post]
|
||||||
|
end
|
||||||
|
|
||||||
|
(previous_category_ids - new_category_ids).each do |category_id|
|
||||||
|
CategoryUser.where(category_id: category_id, notification_level: notification_level).delete_all
|
||||||
|
end
|
||||||
|
|
||||||
|
(new_category_ids - previous_category_ids).each do |category_id|
|
||||||
|
skip_user_ids = CategoryUser.where(category_id: category_id).pluck(:user_id)
|
||||||
|
|
||||||
|
User.where.not(id: skip_user_ids).select(:id).find_in_batches do |users|
|
||||||
|
category_users = []
|
||||||
|
users.each { |user| category_users << { category_id: category_id, user_id: user.id, notification_level: notification_level } }
|
||||||
|
CategoryUser.insert_all!(category_users)
|
||||||
|
end
|
||||||
|
|
||||||
|
CategoryUser.where(category_id: category_id, notification_level: notification_level).first_or_create!(notification_level: notification_level)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
render body: nil
|
render body: nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4304,6 +4304,10 @@ en:
|
||||||
dashboard: "Dashboard"
|
dashboard: "Dashboard"
|
||||||
secret_list:
|
secret_list:
|
||||||
invalid_input: "Input fields cannot be empty or contain vertical bar character."
|
invalid_input: "Input fields cannot be empty or contain vertical bar character."
|
||||||
|
default_categories:
|
||||||
|
modal_description: "Would you like to apply this change historically? This will change preferences for %{count} existing users."
|
||||||
|
modal_yes: "Yes"
|
||||||
|
modal_no: "No, only apply change going forward"
|
||||||
|
|
||||||
badges:
|
badges:
|
||||||
title: Badges
|
title: Badges
|
||||||
|
|
|
@ -53,6 +53,44 @@ describe Admin::SiteSettingsController do
|
||||||
expect(SiteSetting.test_setting).to eq('')
|
expect(SiteSetting.test_setting).to eq('')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'default categories' do
|
||||||
|
let(:user1) { Fabricate(:user) }
|
||||||
|
let(:user2) { Fabricate(:user) }
|
||||||
|
let(:watching) { NotificationLevels.all[:watching] }
|
||||||
|
let(:tracking) { NotificationLevels.all[:tracking] }
|
||||||
|
|
||||||
|
let(:category_ids) { 3.times.collect { Fabricate(:category).id } }
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.setting(:default_categories_watching, category_ids.first(2).join("|"))
|
||||||
|
CategoryUser.create!(category_id: category_ids.last, notification_level: tracking, user: user2)
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
SiteSetting.setting(:default_categories_watching, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should update existing users user preference' do
|
||||||
|
put "/admin/site_settings/default_categories_watching.json", params: {
|
||||||
|
default_categories_watching: category_ids.last(2).join("|"),
|
||||||
|
updateExistingUsers: true
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(CategoryUser.where(category_id: category_ids.first, notification_level: watching).count).to eq(0)
|
||||||
|
expect(CategoryUser.where(category_id: category_ids.last, notification_level: watching).count).to eq(User.count - 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not update existing users user preference' do
|
||||||
|
expect {
|
||||||
|
put "/admin/site_settings/default_categories_watching.json", params: {
|
||||||
|
default_categories_watching: category_ids.last(2).join("|")
|
||||||
|
}
|
||||||
|
}.to change { CategoryUser.where(category_id: category_ids.first, notification_level: watching).count }.by(0)
|
||||||
|
|
||||||
|
expect(CategoryUser.where(category_id: category_ids.last, notification_level: watching).count).to eq(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'upload site settings' do
|
describe 'upload site settings' do
|
||||||
it 'can remove the site setting' do
|
it 'can remove the site setting' do
|
||||||
SiteSetting.test_upload = Fabricate(:upload)
|
SiteSetting.test_upload = Fabricate(:upload)
|
||||||
|
|
Loading…
Reference in New Issue