mirror of
https://github.com/discourse/discourse.git
synced 2025-02-22 00:55:25 +08:00
Split out bulk operations modal and Discourse.Route.showModal
This makes it easier to share bulk topic operations, for example from a plugin's custom topic list.
This commit is contained in:
parent
e9b04170c6
commit
f50280a889
@ -19,7 +19,7 @@ export default ObjectController.extend(ModalFunctionality, {
|
|||||||
window.location.reload();
|
window.location.reload();
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
var error = I18n.t('admin.user.suspend_failed', { error: "http: " + e.status + " - " + e.body });
|
var error = I18n.t('admin.user.suspend_failed', { error: "http: " + e.status + " - " + e.body });
|
||||||
bootbox.alert(error, function() { self.send('showModal'); });
|
bootbox.alert(error, function() { self.send('reopenModal'); });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
Discourse.AdminBackupsRoute = Discourse.Route.extend({
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
|
export default Discourse.Route.extend({
|
||||||
|
|
||||||
LOG_CHANNEL: "/admin/backups/logs",
|
LOG_CHANNEL: "/admin/backups/logs",
|
||||||
|
|
||||||
activate: function() {
|
activate() {
|
||||||
Discourse.MessageBus.subscribe(this.LOG_CHANNEL, this._processLogMessage.bind(this));
|
Discourse.MessageBus.subscribe(this.LOG_CHANNEL, this._processLogMessage.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
_processLogMessage: function(log) {
|
_processLogMessage(log) {
|
||||||
if (log.message === "[STARTED]") {
|
if (log.message === "[STARTED]") {
|
||||||
this.controllerFor("adminBackups").set("isOperationRunning", true);
|
this.controllerFor("adminBackups").set("isOperationRunning", true);
|
||||||
this.controllerFor("adminBackupsLogs").clear();
|
this.controllerFor("adminBackupsLogs").clear();
|
||||||
@ -25,7 +27,7 @@ Discourse.AdminBackupsRoute = Discourse.Route.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
model: function() {
|
model() {
|
||||||
return PreloadStore.getAndRemove("operations_status", function() {
|
return PreloadStore.getAndRemove("operations_status", function() {
|
||||||
return Discourse.ajax("/admin/backups/status.json");
|
return Discourse.ajax("/admin/backups/status.json");
|
||||||
}).then(function (status) {
|
}).then(function (status) {
|
||||||
@ -37,35 +39,24 @@ Discourse.AdminBackupsRoute = Discourse.Route.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
deactivate: function() {
|
deactivate() {
|
||||||
Discourse.MessageBus.unsubscribe(this.LOG_CHANNEL);
|
Discourse.MessageBus.unsubscribe(this.LOG_CHANNEL);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
/**
|
startBackup() {
|
||||||
Starts a backup and redirect the user to the logs tab
|
showModal('admin_start_backup');
|
||||||
|
|
||||||
@method startBackup
|
|
||||||
**/
|
|
||||||
startBackup: function() {
|
|
||||||
Discourse.Route.showModal(this, 'admin_start_backup');
|
|
||||||
this.controllerFor('modal').set('modalClass', 'start-backup-modal');
|
this.controllerFor('modal').set('modalClass', 'start-backup-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
backupStarted: function () {
|
backupStarted() {
|
||||||
this.modelFor("adminBackups").set("isOperationRunning", true);
|
this.modelFor("adminBackups").set("isOperationRunning", true);
|
||||||
this.transitionTo("admin.backups.logs");
|
this.transitionTo("admin.backups.logs");
|
||||||
this.send("closeModal");
|
this.send("closeModal");
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
destroyBackup(backup) {
|
||||||
Destroys a backup
|
const self = this;
|
||||||
|
|
||||||
@method destroyBackup
|
|
||||||
@param {Discourse.Backup} backup the backup to destroy
|
|
||||||
**/
|
|
||||||
destroyBackup: function(backup) {
|
|
||||||
var self = this;
|
|
||||||
bootbox.confirm(
|
bootbox.confirm(
|
||||||
I18n.t("admin.backups.operations.destroy.confirm"),
|
I18n.t("admin.backups.operations.destroy.confirm"),
|
||||||
I18n.t("no_value"),
|
I18n.t("no_value"),
|
||||||
@ -80,14 +71,8 @@ Discourse.AdminBackupsRoute = Discourse.Route.extend({
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
startRestore(backup) {
|
||||||
Start a restore and redirect the user to the logs tab
|
const self = this;
|
||||||
|
|
||||||
@method startRestore
|
|
||||||
@param {Discourse.Backup} backup the backup to restore
|
|
||||||
**/
|
|
||||||
startRestore: function(backup) {
|
|
||||||
var self = this;
|
|
||||||
bootbox.confirm(
|
bootbox.confirm(
|
||||||
I18n.t("admin.backups.operations.restore.confirm"),
|
I18n.t("admin.backups.operations.restore.confirm"),
|
||||||
I18n.t("no_value"),
|
I18n.t("no_value"),
|
||||||
@ -105,13 +90,8 @@ Discourse.AdminBackupsRoute = Discourse.Route.extend({
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
cancelOperation() {
|
||||||
Cancels the current operation
|
const self = this;
|
||||||
|
|
||||||
@method cancelOperation
|
|
||||||
**/
|
|
||||||
cancelOperation: function() {
|
|
||||||
var self = this;
|
|
||||||
bootbox.confirm(
|
bootbox.confirm(
|
||||||
I18n.t("admin.backups.operations.cancel.confirm"),
|
I18n.t("admin.backups.operations.cancel.confirm"),
|
||||||
I18n.t("no_value"),
|
I18n.t("no_value"),
|
||||||
@ -126,12 +106,7 @@ Discourse.AdminBackupsRoute = Discourse.Route.extend({
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
rollback() {
|
||||||
Rollback to previous working state
|
|
||||||
|
|
||||||
@method rollback
|
|
||||||
**/
|
|
||||||
rollback: function() {
|
|
||||||
bootbox.confirm(
|
bootbox.confirm(
|
||||||
I18n.t("admin.backups.operations.rollback.confirm"),
|
I18n.t("admin.backups.operations.rollback.confirm"),
|
||||||
I18n.t("no_value"),
|
I18n.t("no_value"),
|
||||||
@ -142,8 +117,8 @@ Discourse.AdminBackupsRoute = Discourse.Route.extend({
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadSuccess: function(filename) {
|
uploadSuccess(filename) {
|
||||||
var self = this;
|
const self = this;
|
||||||
bootbox.alert(I18n.t("admin.backups.upload.success", { filename: filename }), function() {
|
bootbox.alert(I18n.t("admin.backups.upload.success", { filename: filename }), function() {
|
||||||
Discourse.Backup.find().then(function (backups) {
|
Discourse.Backup.find().then(function (backups) {
|
||||||
self.controllerFor("adminBackupsIndex").set("model", backups);
|
self.controllerFor("adminBackupsIndex").set("model", backups);
|
||||||
@ -151,7 +126,7 @@ Discourse.AdminBackupsRoute = Discourse.Route.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadError: function(filename, message) {
|
uploadError(filename, message) {
|
||||||
bootbox.alert(I18n.t("admin.backups.upload.error", { filename: filename, message: message }));
|
bootbox.alert(I18n.t("admin.backups.upload.error", { filename: filename, message: message }));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,11 @@
|
|||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
serialize: function(m) {
|
serialize(m) {
|
||||||
return {badge_id: Em.get(m, 'id') || 'new'};
|
return {badge_id: Em.get(m, 'id') || 'new'};
|
||||||
},
|
},
|
||||||
|
|
||||||
model: function(params) {
|
model(params) {
|
||||||
if (params.badge_id === "new") {
|
if (params.badge_id === "new") {
|
||||||
return Discourse.Badge.create({
|
return Discourse.Badge.create({
|
||||||
name: I18n.t('admin.badges.new_badge')
|
name: I18n.t('admin.badges.new_badge')
|
||||||
@ -13,22 +15,20 @@ export default Ember.Route.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
saveError: function(e) {
|
saveError(e) {
|
||||||
var msg = I18n.t("generic_error");
|
let msg = I18n.t("generic_error");
|
||||||
if (e.responseJSON && e.responseJSON.errors) {
|
if (e.responseJSON && e.responseJSON.errors) {
|
||||||
msg = I18n.t("generic_error_with_reason", {error: e.responseJSON.errors.join('. ')});
|
msg = I18n.t("generic_error_with_reason", {error: e.responseJSON.errors.join('. ')});
|
||||||
}
|
}
|
||||||
bootbox.alert(msg);
|
bootbox.alert(msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
editGroupings: function() {
|
editGroupings() {
|
||||||
var groupings = this.controllerFor('admin-badges').get('badgeGroupings');
|
const groupings = this.controllerFor('admin-badges').get('badgeGroupings');
|
||||||
Discourse.Route.showModal(this, 'admin_edit_badge_groupings', groupings);
|
showModal('admin_edit_badge_groupings', groupings);
|
||||||
},
|
},
|
||||||
|
|
||||||
preview: function(badge, explain) {
|
preview(badge, explain) {
|
||||||
var self = this;
|
|
||||||
|
|
||||||
badge.set('preview_loading', true);
|
badge.set('preview_loading', true);
|
||||||
Discourse.ajax('/admin/badges/preview.json', {
|
Discourse.ajax('/admin/badges/preview.json', {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -36,11 +36,11 @@ export default Ember.Route.extend({
|
|||||||
sql: badge.get('query'),
|
sql: badge.get('query'),
|
||||||
target_posts: !!badge.get('target_posts'),
|
target_posts: !!badge.get('target_posts'),
|
||||||
trigger: badge.get('trigger'),
|
trigger: badge.get('trigger'),
|
||||||
explain: explain
|
explain
|
||||||
}
|
}
|
||||||
}).then(function(json) {
|
}).then(function(json) {
|
||||||
badge.set('preview_loading', false);
|
badge.set('preview_loading', false);
|
||||||
Discourse.Route.showModal(self, 'admin_badge_preview', json);
|
showModal('admin_badge_preview', json);
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
badge.set('preview_loading', false);
|
badge.set('preview_loading', false);
|
||||||
Em.Logger.error(error);
|
Em.Logger.error(error);
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
model: function(params) {
|
model(params) {
|
||||||
this.filter = params.filter;
|
this.filter = params.filter;
|
||||||
return Discourse.FlaggedPost.findAll(params.filter);
|
return Discourse.FlaggedPost.findAll(params.filter);
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController: function(controller, model) {
|
setupController(controller, model) {
|
||||||
controller.set('model', model);
|
controller.set('model', model);
|
||||||
controller.set('query', this.filter);
|
controller.set('query', this.filter);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showAgreeFlagModal: function (flaggedPost) {
|
showAgreeFlagModal(flaggedPost) {
|
||||||
Discourse.Route.showModal(this, 'admin_agree_flag', flaggedPost);
|
showModal('admin_agree_flag', flaggedPost);
|
||||||
this.controllerFor('modal').set('modalClass', 'agree-flag-modal');
|
this.controllerFor('modal').set('modalClass', 'agree-flag-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
showDeleteFlagModal: function (flaggedPost) {
|
showDeleteFlagModal(flaggedPost) {
|
||||||
Discourse.Route.showModal(this, 'admin_delete_flag', flaggedPost);
|
showModal('admin_delete_flag', flaggedPost);
|
||||||
this.controllerFor('modal').set('modalClass', 'delete-flag-modal');
|
this.controllerFor('modal').set('modalClass', 'delete-flag-modal');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
// TODO: make this automatic using an `{{outlet}}`
|
// TODO: make this automatic using an `{{outlet}}`
|
||||||
renderTemplate: function() {
|
renderTemplate: function() {
|
||||||
@ -10,13 +12,13 @@ export default Discourse.Route.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showDetailsModal: function(logRecord) {
|
showDetailsModal(logRecord) {
|
||||||
Discourse.Route.showModal(this, 'admin_staff_action_log_details', logRecord);
|
showModal('admin_staff_action_log_details', logRecord);
|
||||||
this.controllerFor('modal').set('modalClass', 'log-details-modal');
|
this.controllerFor('modal').set('modalClass', 'log-details-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
showCustomDetailsModal: function(logRecord) {
|
showCustomDetailsModal(logRecord) {
|
||||||
Discourse.Route.showModal(this, logRecord.action_name + '_details', logRecord);
|
showModal(logRecord.action_name + '_details', logRecord);
|
||||||
this.controllerFor('modal').set('modalClass', 'tabbed-modal log-details-modal');
|
this.controllerFor('modal').set('modalClass', 'tabbed-modal log-details-modal');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
app/assets/javascripts/admin/routes/admin-user-index.js.es6
Normal file
32
app/assets/javascripts/admin/routes/admin-user-index.js.es6
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
|
export default Discourse.Route.extend({
|
||||||
|
model() {
|
||||||
|
return this.modelFor('adminUser');
|
||||||
|
},
|
||||||
|
|
||||||
|
afterModel(model) {
|
||||||
|
if (this.currentUser.get('admin')) {
|
||||||
|
const self = this;
|
||||||
|
return Discourse.Group.findAll().then(function(groups){
|
||||||
|
self._availableGroups = groups.filterBy('automatic', false);
|
||||||
|
return model;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController(controller, model) {
|
||||||
|
controller.setProperties({
|
||||||
|
originalPrimaryGroupId: model.get('primary_group_id'),
|
||||||
|
availableGroups: this._availableGroups,
|
||||||
|
model
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
showSuspendModal(user) {
|
||||||
|
showModal('admin_suspend_user', user);
|
||||||
|
this.controllerFor('modal').set('modalClass', 'suspend-user-modal');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
20
app/assets/javascripts/admin/routes/admin-user.js.es6
Normal file
20
app/assets/javascripts/admin/routes/admin-user.js.es6
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export default Discourse.Route.extend({
|
||||||
|
serialize(model) {
|
||||||
|
return { username: model.get('username').toLowerCase() };
|
||||||
|
},
|
||||||
|
|
||||||
|
model(params) {
|
||||||
|
return Discourse.AdminUser.find(Em.get(params, 'username').toLowerCase());
|
||||||
|
},
|
||||||
|
|
||||||
|
renderTemplate() {
|
||||||
|
this.render({into: 'admin'});
|
||||||
|
},
|
||||||
|
|
||||||
|
afterModel(adminUser) {
|
||||||
|
return adminUser.loadDetails().then(function () {
|
||||||
|
adminUser.setOriginalTrustLevel();
|
||||||
|
return adminUser;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -1,51 +0,0 @@
|
|||||||
Discourse.AdminUserRoute = Discourse.Route.extend({
|
|
||||||
serialize: function(model) {
|
|
||||||
return { username: model.get('username').toLowerCase() };
|
|
||||||
},
|
|
||||||
|
|
||||||
model: function(params) {
|
|
||||||
return Discourse.AdminUser.find(Em.get(params, 'username').toLowerCase());
|
|
||||||
},
|
|
||||||
|
|
||||||
renderTemplate: function() {
|
|
||||||
this.render({into: 'admin'});
|
|
||||||
},
|
|
||||||
|
|
||||||
afterModel: function(adminUser) {
|
|
||||||
return adminUser.loadDetails().then(function () {
|
|
||||||
adminUser.setOriginalTrustLevel();
|
|
||||||
return adminUser;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Discourse.AdminUserIndexRoute = Discourse.Route.extend({
|
|
||||||
model: function() {
|
|
||||||
return this.modelFor('adminUser');
|
|
||||||
},
|
|
||||||
|
|
||||||
afterModel: function(model) {
|
|
||||||
if(Discourse.User.currentProp('admin')) {
|
|
||||||
var self = this;
|
|
||||||
return Discourse.Group.findAll().then(function(groups){
|
|
||||||
self._availableGroups = groups.filterBy('automatic', false);
|
|
||||||
return model;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setupController: function(controller, model) {
|
|
||||||
controller.setProperties({
|
|
||||||
originalPrimaryGroupId: model.get('primary_group_id'),
|
|
||||||
availableGroups: this._availableGroups,
|
|
||||||
model: model
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
showSuspendModal: function(user) {
|
|
||||||
Discourse.Route.showModal(this, 'admin_suspend_user', user);
|
|
||||||
this.controllerFor('modal').set('modalClass', 'suspend-user-modal');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
@ -0,0 +1,10 @@
|
|||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
actions: {
|
||||||
|
showBulkActions() {
|
||||||
|
const controller = showModal('topicBulkActions', this.get('selected'));
|
||||||
|
controller.set('refreshTarget', this.get('refreshTarget'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -1,11 +1,9 @@
|
|||||||
import DiscoveryController from 'discourse/controllers/discovery';
|
import DiscoveryController from 'discourse/controllers/discovery';
|
||||||
import { queryParams } from 'discourse/controllers/discovery-sortable';
|
import { queryParams } from 'discourse/controllers/discovery-sortable';
|
||||||
import NotificationLevels from 'discourse/lib/notification-levels';
|
import BulkTopicSelection from 'discourse/mixins/bulk-topic-selection';
|
||||||
|
|
||||||
var controllerOpts = {
|
var controllerOpts = {
|
||||||
needs: ['discovery'],
|
needs: ['discovery'],
|
||||||
bulkSelectEnabled: false,
|
|
||||||
selected: [],
|
|
||||||
period: null,
|
period: null,
|
||||||
|
|
||||||
canStar: Em.computed.alias('controllers.discovery/topics.currentUser.id'),
|
canStar: Em.computed.alias('controllers.discovery/topics.currentUser.id'),
|
||||||
@ -53,7 +51,8 @@ var controllerOpts = {
|
|||||||
Discourse.TopicList.find(filter).then(function(list) {
|
Discourse.TopicList.find(filter).then(function(list) {
|
||||||
Discourse.TopicList.hideUniformCategory(list, self.get('category'));
|
Discourse.TopicList.hideUniformCategory(list, self.get('category'));
|
||||||
|
|
||||||
self.setProperties({ model: list, selected: [] });
|
self.setProperties({ model: list });
|
||||||
|
self.resetSelected();
|
||||||
|
|
||||||
var tracking = Discourse.TopicTrackingState.current();
|
var tracking = Discourse.TopicTrackingState.current();
|
||||||
if (tracking) {
|
if (tracking) {
|
||||||
@ -64,10 +63,6 @@ var controllerOpts = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleBulkSelect: function() {
|
|
||||||
this.toggleProperty('bulkSelectEnabled');
|
|
||||||
this.get('selected').clear();
|
|
||||||
},
|
|
||||||
|
|
||||||
resetNew: function() {
|
resetNew: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -76,40 +71,9 @@ var controllerOpts = {
|
|||||||
Discourse.Topic.resetNew().then(function() {
|
Discourse.Topic.resetNew().then(function() {
|
||||||
self.send('refresh');
|
self.send('refresh');
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
dismissRead: function(operationType) {
|
|
||||||
var self = this,
|
|
||||||
selected = this.get('selected'),
|
|
||||||
operation;
|
|
||||||
|
|
||||||
if(operationType === "posts"){
|
|
||||||
operation = { type: 'dismiss_posts' };
|
|
||||||
} else {
|
|
||||||
operation = { type: 'change_notification_level',
|
|
||||||
notification_level_id: NotificationLevels.REGULAR };
|
|
||||||
}
|
|
||||||
|
|
||||||
var promise;
|
|
||||||
if (selected.length > 0) {
|
|
||||||
promise = Discourse.Topic.bulkOperation(selected, operation);
|
|
||||||
} else {
|
|
||||||
promise = Discourse.Topic.bulkOperationByFilter('unread', operation, this.get('category.id'));
|
|
||||||
}
|
|
||||||
promise.then(function(result) {
|
|
||||||
if (result && result.topic_ids) {
|
|
||||||
var tracker = Discourse.TopicTrackingState.current();
|
|
||||||
result.topic_ids.forEach(function(t) {
|
|
||||||
tracker.removeTopic(t);
|
|
||||||
});
|
|
||||||
tracker.incrementMessageCount();
|
|
||||||
}
|
|
||||||
self.send('refresh');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
topicTrackingState: function() {
|
topicTrackingState: function() {
|
||||||
return Discourse.TopicTrackingState.current();
|
return Discourse.TopicTrackingState.current();
|
||||||
}.property(),
|
}.property(),
|
||||||
@ -132,7 +96,6 @@ var controllerOpts = {
|
|||||||
this.get('topics.length') >= 30;
|
this.get('topics.length') >= 30;
|
||||||
}.property('filter', 'topics.length'),
|
}.property('filter', 'topics.length'),
|
||||||
|
|
||||||
canBulkSelect: Em.computed.alias('currentUser.staff'),
|
|
||||||
hasTopics: Em.computed.gt('topics.length', 0),
|
hasTopics: Em.computed.gt('topics.length', 0),
|
||||||
allLoaded: Em.computed.empty('more_topics_url'),
|
allLoaded: Em.computed.empty('more_topics_url'),
|
||||||
latest: Discourse.computed.endWith('filter', 'latest'),
|
latest: Discourse.computed.endWith('filter', 'latest'),
|
||||||
@ -187,4 +150,4 @@ Ember.keys(queryParams).forEach(function(p) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default DiscoveryController.extend(controllerOpts);
|
export default DiscoveryController.extend(controllerOpts, BulkTopicSelection);
|
||||||
|
@ -174,12 +174,12 @@ export default ObjectController.extend(ModalFunctionality, {
|
|||||||
self.flash(I18n.t('generic_error'));
|
self.flash(I18n.t('generic_error'));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.send('showModal');
|
self.send('reopenModal');
|
||||||
self.displayErrors([I18n.t("category.delete_error")]);
|
self.displayErrors([I18n.t("category.delete_error")]);
|
||||||
self.set('deleting', false);
|
self.set('deleting', false);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.send('showModal');
|
self.send('reopenModal');
|
||||||
self.set('deleting', false);
|
self.set('deleting', false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -43,10 +43,10 @@ export default ObjectController.extend(ModalFunctionality, {
|
|||||||
self.set('details.auto_close_at', result.auto_close_at);
|
self.set('details.auto_close_at', result.auto_close_at);
|
||||||
self.set('details.auto_close_hours', result.auto_close_hours);
|
self.set('details.auto_close_hours', result.auto_close_hours);
|
||||||
} else {
|
} else {
|
||||||
bootbox.alert(I18n.t('composer.auto_close.error'), function() { self.send('showModal'); } );
|
bootbox.alert(I18n.t('composer.auto_close.error'), function() { self.send('reopenModal'); } );
|
||||||
}
|
}
|
||||||
}, function () {
|
}, function () {
|
||||||
bootbox.alert(I18n.t('composer.auto_close.error'), function() { self.send('showModal'); } );
|
bootbox.alert(I18n.t('composer.auto_close.error'), function() { self.send('reopenModal'); } );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
||||||
import DiscourseController from 'discourse/controllers/controller';
|
import DiscourseController from 'discourse/controllers/controller';
|
||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
// This is happening outside of the app via popup
|
// This is happening outside of the app via popup
|
||||||
function showModal(modal) {
|
|
||||||
const route = Discourse.__container__.lookup('route:application');
|
|
||||||
Discourse.Route.showModal(route, modal);
|
|
||||||
}
|
|
||||||
const AuthErrors =
|
const AuthErrors =
|
||||||
['requires_invite', 'awaiting_approval', 'awaiting_confirmation', 'admin_not_allowed_from_ip_address',
|
['requires_invite', 'awaiting_approval', 'awaiting_confirmation', 'admin_not_allowed_from_ip_address',
|
||||||
'not_allowed_from_ip_address'];
|
'not_allowed_from_ip_address'];
|
||||||
|
@ -16,7 +16,6 @@ addBulkButton('resetRead', 'reset_read');
|
|||||||
|
|
||||||
// Modal for performing bulk actions on topics
|
// Modal for performing bulk actions on topics
|
||||||
export default Ember.ArrayController.extend(ModalFunctionality, {
|
export default Ember.ArrayController.extend(ModalFunctionality, {
|
||||||
needs: ['discovery/topics'],
|
|
||||||
buttonRows: null,
|
buttonRows: null,
|
||||||
|
|
||||||
onShow: function() {
|
onShow: function() {
|
||||||
@ -34,6 +33,7 @@ export default Ember.ArrayController.extend(ModalFunctionality, {
|
|||||||
if (row.length) { buttonRows.push(row); }
|
if (row.length) { buttonRows.push(row); }
|
||||||
|
|
||||||
this.set('buttonRows', buttonRows);
|
this.set('buttonRows', buttonRows);
|
||||||
|
this.send('changeBulkTemplate', 'modal/bulk_actions_buttons');
|
||||||
},
|
},
|
||||||
|
|
||||||
perform: function(operation) {
|
perform: function(operation) {
|
||||||
@ -66,9 +66,10 @@ export default Ember.ArrayController.extend(ModalFunctionality, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
performAndRefresh: function(operation) {
|
performAndRefresh: function(operation) {
|
||||||
var self = this;
|
const self = this;
|
||||||
return this.perform(operation).then(function() {
|
return this.perform(operation).then(function() {
|
||||||
self.get('controllers.discovery/topics').send('refresh');
|
const refreshTarget = self.get('refreshTarget');
|
||||||
|
if (refreshTarget) { refreshTarget.send('refresh'); }
|
||||||
self.send('closeModal');
|
self.send('closeModal');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -107,7 +108,8 @@ export default Ember.ArrayController.extend(ModalFunctionality, {
|
|||||||
topics.forEach(function(t) {
|
topics.forEach(function(t) {
|
||||||
t.set('category', category);
|
t.set('category', category);
|
||||||
});
|
});
|
||||||
self.get('controllers.discovery/topics').send('refresh');
|
const refreshTarget = self.get('refreshTarget');
|
||||||
|
if (refreshTarget) { refreshTarget.send('refresh'); }
|
||||||
self.send('closeModal');
|
self.send('closeModal');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
20
app/assets/javascripts/discourse/lib/show-modal.js.es6
Normal file
20
app/assets/javascripts/discourse/lib/show-modal.js.es6
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export default function showModal(name, model) {
|
||||||
|
|
||||||
|
// We use the container here because modals are like singletons
|
||||||
|
// in Discourse. Only one can be shown with a particular state.
|
||||||
|
const route = Discourse.__container__.lookup('route:application');
|
||||||
|
|
||||||
|
route.controllerFor('modal').set('modalClass', null);
|
||||||
|
route.render(name, {into: 'modal', outlet: 'modalBody'});
|
||||||
|
const controller = route.controllerFor(name);
|
||||||
|
if (controller) {
|
||||||
|
if (model) {
|
||||||
|
controller.set('model', model);
|
||||||
|
}
|
||||||
|
if (controller.onShow) {
|
||||||
|
controller.onShow();
|
||||||
|
}
|
||||||
|
controller.set('flashMessage', null);
|
||||||
|
}
|
||||||
|
return controller;
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
import NotificationLevels from 'discourse/lib/notification-levels';
|
||||||
|
|
||||||
|
export default Ember.Mixin.create({
|
||||||
|
bulkSelectEnabled: false,
|
||||||
|
selected: null,
|
||||||
|
|
||||||
|
canBulkSelect: Em.computed.alias('currentUser.staff'),
|
||||||
|
|
||||||
|
resetSelected: function() {
|
||||||
|
this.set('selected', []);
|
||||||
|
}.on('init'),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
toggleBulkSelect() {
|
||||||
|
this.toggleProperty('bulkSelectEnabled');
|
||||||
|
this.get('selected').clear();
|
||||||
|
},
|
||||||
|
|
||||||
|
dismissRead(operationType) {
|
||||||
|
const self = this,
|
||||||
|
selected = this.get('selected');
|
||||||
|
|
||||||
|
let operation;
|
||||||
|
if(operationType === "posts"){
|
||||||
|
operation = { type: 'dismiss_posts' };
|
||||||
|
} else {
|
||||||
|
operation = { type: 'change_notification_level',
|
||||||
|
notification_level_id: NotificationLevels.REGULAR };
|
||||||
|
}
|
||||||
|
|
||||||
|
let promise;
|
||||||
|
if (selected.length > 0) {
|
||||||
|
promise = Discourse.Topic.bulkOperation(selected, operation);
|
||||||
|
} else {
|
||||||
|
promise = Discourse.Topic.bulkOperationByFilter('unread', operation, this.get('category.id'));
|
||||||
|
}
|
||||||
|
promise.then(function(result) {
|
||||||
|
if (result && result.topic_ids) {
|
||||||
|
const tracker = Discourse.TopicTrackingState.current();
|
||||||
|
result.topic_ids.forEach(function(t) {
|
||||||
|
tracker.removeTopic(t);
|
||||||
|
});
|
||||||
|
tracker.incrementMessageCount();
|
||||||
|
}
|
||||||
|
self.send('refresh');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -1,3 +1,5 @@
|
|||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
function unlessReadOnly(method) {
|
function unlessReadOnly(method) {
|
||||||
return function() {
|
return function() {
|
||||||
if (this.site.get("isReadOnly")) {
|
if (this.site.get("isReadOnly")) {
|
||||||
@ -74,31 +76,28 @@ const ApplicationRoute = Discourse.Route.extend({
|
|||||||
showCreateAccount: unlessReadOnly('handleShowCreateAccount'),
|
showCreateAccount: unlessReadOnly('handleShowCreateAccount'),
|
||||||
|
|
||||||
showForgotPassword() {
|
showForgotPassword() {
|
||||||
Discourse.Route.showModal(this, 'forgotPassword');
|
showModal('forgotPassword');
|
||||||
},
|
},
|
||||||
|
|
||||||
showNotActivated(props) {
|
showNotActivated(props) {
|
||||||
Discourse.Route.showModal(this, 'notActivated');
|
showModal('notActivated');
|
||||||
this.controllerFor('notActivated').setProperties(props);
|
this.controllerFor('notActivated').setProperties(props);
|
||||||
},
|
},
|
||||||
|
|
||||||
showUploadSelector(composerView) {
|
showUploadSelector(composerView) {
|
||||||
Discourse.Route.showModal(this, 'uploadSelector');
|
showModal('uploadSelector');
|
||||||
this.controllerFor('upload-selector').setProperties({ composerView: composerView });
|
this.controllerFor('upload-selector').setProperties({ composerView: composerView });
|
||||||
},
|
},
|
||||||
|
|
||||||
showKeyboardShortcutsHelp() {
|
showKeyboardShortcutsHelp() {
|
||||||
Discourse.Route.showModal(this, 'keyboardShortcutsHelp');
|
showModal('keyboardShortcutsHelp');
|
||||||
},
|
},
|
||||||
|
|
||||||
showSearchHelp() {
|
showSearchHelp() {
|
||||||
const self = this;
|
|
||||||
|
|
||||||
// TODO: @EvitTrout how do we get a loading indicator here?
|
// TODO: @EvitTrout how do we get a loading indicator here?
|
||||||
Discourse.ajax("/static/search_help.html", { dataType: 'html' }).then(function(html){
|
Discourse.ajax("/static/search_help.html", { dataType: 'html' }).then(function(html){
|
||||||
Discourse.Route.showModal(self, 'searchHelp', html);
|
showModal('searchHelp', html);
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Close the current modal, and destroy its state.
|
// Close the current modal, and destroy its state.
|
||||||
@ -109,13 +108,13 @@ const ApplicationRoute = Discourse.Route.extend({
|
|||||||
/**
|
/**
|
||||||
Hide the modal, but keep it with all its state so that it can be shown again later.
|
Hide the modal, but keep it with all its state so that it can be shown again later.
|
||||||
This is useful if you want to prompt for confirmation. hideModal, ask "Are you sure?",
|
This is useful if you want to prompt for confirmation. hideModal, ask "Are you sure?",
|
||||||
user clicks "No", showModal. If user clicks "Yes", be sure to call closeModal.
|
user clicks "No", reopenModal. If user clicks "Yes", be sure to call closeModal.
|
||||||
**/
|
**/
|
||||||
hideModal() {
|
hideModal() {
|
||||||
$('#discourse-modal').modal('hide');
|
$('#discourse-modal').modal('hide');
|
||||||
},
|
},
|
||||||
|
|
||||||
showModal() {
|
reopenModal() {
|
||||||
$('#discourse-modal').modal('show');
|
$('#discourse-modal').modal('show');
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -123,7 +122,7 @@ const ApplicationRoute = Discourse.Route.extend({
|
|||||||
const self = this;
|
const self = this;
|
||||||
Discourse.Category.reloadById(category.get('id')).then(function (c) {
|
Discourse.Category.reloadById(category.get('id')).then(function (c) {
|
||||||
self.site.updateCategory(c);
|
self.site.updateCategory(c);
|
||||||
Discourse.Route.showModal(self, 'editCategory', c);
|
showModal(self, 'editCategory', c);
|
||||||
self.controllerFor('editCategory').set('selectedTab', 'general');
|
self.controllerFor('editCategory').set('selectedTab', 'general');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -135,6 +134,13 @@ const ApplicationRoute = Discourse.Route.extend({
|
|||||||
|
|
||||||
checkEmail: function (user) {
|
checkEmail: function (user) {
|
||||||
user.checkEmail();
|
user.checkEmail();
|
||||||
|
},
|
||||||
|
|
||||||
|
changeBulkTemplate(w) {
|
||||||
|
const controllerName = w.replace('modal/', ''),
|
||||||
|
factory = this.container.lookupFactory('controller:' + controllerName);
|
||||||
|
|
||||||
|
this.render(w, {into: 'topicBulkActions', outlet: 'bulkOutlet', controller: factory ? controllerName : 'topic-bulk-actions'});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -164,7 +170,7 @@ const ApplicationRoute = Discourse.Route.extend({
|
|||||||
if (!this.siteSettings.enable_local_logins && methods.length === 1) {
|
if (!this.siteSettings.enable_local_logins && methods.length === 1) {
|
||||||
this.controllerFor('login').send('externalLogin', methods[0]);
|
this.controllerFor('login').send('externalLogin', methods[0]);
|
||||||
} else {
|
} else {
|
||||||
Discourse.Route.showModal(this, modal);
|
showModal(modal);
|
||||||
if (notAuto) { notAuto(); }
|
if (notAuto) { notAuto(); }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,24 +1,45 @@
|
|||||||
/**
|
import showModal from 'discourse/lib/show-modal';
|
||||||
The base route for all routes on Discourse. Includes global enter functionality.
|
|
||||||
|
|
||||||
@class Route
|
const DiscourseRoute = Ember.Route.extend({
|
||||||
@extends Em.Route
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
Discourse.Route = Ember.Route.extend({
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
NOT called every time we enter a route on Discourse.
|
NOT called every time we enter a route on Discourse.
|
||||||
Only called the FIRST time we enter a route.
|
Only called the FIRST time we enter a route.
|
||||||
So, when going from one topic to another, activate will only be called on the
|
So, when going from one topic to another, activate will only be called on the
|
||||||
TopicRoute for the first topic.
|
TopicRoute for the first topic.
|
||||||
|
|
||||||
@method activate
|
|
||||||
**/
|
**/
|
||||||
activate: function() {
|
activate: function() {
|
||||||
this._super();
|
this._super();
|
||||||
Em.run.scheduleOnce('afterRender', Discourse.Route, 'cleanDOM');
|
Em.run.scheduleOnce('afterRender', Ember.Route, this._cleanDOM);
|
||||||
|
},
|
||||||
|
|
||||||
|
_cleanDOM() {
|
||||||
|
// Close mini profiler
|
||||||
|
$('.profiler-results .profiler-result').remove();
|
||||||
|
|
||||||
|
// Close some elements that may be open
|
||||||
|
$('.d-dropdown').hide();
|
||||||
|
$('header ul.icons li').removeClass('active');
|
||||||
|
$('[data-toggle="dropdown"]').parent().removeClass('open');
|
||||||
|
// close the lightbox
|
||||||
|
if ($.magnificPopup && $.magnificPopup.instance) {
|
||||||
|
$.magnificPopup.instance.close();
|
||||||
|
$('body').removeClass('mfp-zoom-out-cur');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove any link focus
|
||||||
|
// NOTE: the '.not("body")' is here to prevent a bug in IE10 on Win7
|
||||||
|
// cf. https://stackoverflow.com/questions/5657371/ie9-window-loses-focus-due-to-jquery-mobile
|
||||||
|
$(document.activeElement).not("body").blur();
|
||||||
|
|
||||||
|
Discourse.set('notifyCount',0);
|
||||||
|
$('#discourse-modal').modal('hide');
|
||||||
|
var hideDropDownFunction = $('html').data('hide-dropdown');
|
||||||
|
if (hideDropDownFunction) { hideDropDownFunction(); }
|
||||||
|
|
||||||
|
// TODO: Avoid container lookup here
|
||||||
|
var appEvents = Discourse.__container__.lookup('app-events:main');
|
||||||
|
appEvents.trigger('dom:clean');
|
||||||
},
|
},
|
||||||
|
|
||||||
_refreshTitleOnce: function() {
|
_refreshTitleOnce: function() {
|
||||||
@ -79,7 +100,7 @@ Discourse.Route = Ember.Route.extend({
|
|||||||
|
|
||||||
var routeBuilder;
|
var routeBuilder;
|
||||||
|
|
||||||
Discourse.Route.reopenClass({
|
DiscourseRoute.reopenClass({
|
||||||
|
|
||||||
buildRoutes: function(builder) {
|
buildRoutes: function(builder) {
|
||||||
var oldBuilder = routeBuilder;
|
var oldBuilder = routeBuilder;
|
||||||
@ -174,48 +195,11 @@ Discourse.Route.reopenClass({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
cleanDOM: function() {
|
|
||||||
// Close mini profiler
|
|
||||||
$('.profiler-results .profiler-result').remove();
|
|
||||||
|
|
||||||
// Close some elements that may be open
|
|
||||||
$('.d-dropdown').hide();
|
|
||||||
$('header ul.icons li').removeClass('active');
|
|
||||||
$('[data-toggle="dropdown"]').parent().removeClass('open');
|
|
||||||
// close the lightbox
|
|
||||||
if ($.magnificPopup && $.magnificPopup.instance) {
|
|
||||||
$.magnificPopup.instance.close();
|
|
||||||
$('body').removeClass('mfp-zoom-out-cur');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove any link focus
|
|
||||||
// NOTE: the '.not("body")' is here to prevent a bug in IE10 on Win7
|
|
||||||
// cf. https://stackoverflow.com/questions/5657371/ie9-window-loses-focus-due-to-jquery-mobile
|
|
||||||
$(document.activeElement).not("body").blur();
|
|
||||||
|
|
||||||
Discourse.set('notifyCount',0);
|
|
||||||
$('#discourse-modal').modal('hide');
|
|
||||||
var hideDropDownFunction = $('html').data('hide-dropdown');
|
|
||||||
if (hideDropDownFunction) { hideDropDownFunction(); }
|
|
||||||
|
|
||||||
// TODO: Avoid container lookup here
|
|
||||||
var appEvents = Discourse.__container__.lookup('app-events:main');
|
|
||||||
appEvents.trigger('dom:clean');
|
|
||||||
},
|
|
||||||
|
|
||||||
showModal: function(route, name, model) {
|
showModal: function(route, name, model) {
|
||||||
route.controllerFor('modal').set('modalClass', null);
|
Ember.warn('DEPRECATED `Discourse.Route.showModal` - use `showModal` instead');
|
||||||
route.render(name, {into: 'modal', outlet: 'modalBody'});
|
showModal(name, model);
|
||||||
var controller = route.controllerFor(name);
|
|
||||||
if (controller) {
|
|
||||||
if (model) {
|
|
||||||
controller.set('model', model);
|
|
||||||
}
|
|
||||||
if(controller && controller.onShow) {
|
|
||||||
controller.onShow();
|
|
||||||
}
|
|
||||||
controller.set('flashMessage', null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default DiscourseRoute;
|
@ -1,4 +1,5 @@
|
|||||||
import ShowFooter from "discourse/mixins/show-footer";
|
import ShowFooter from 'discourse/mixins/show-footer';
|
||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
Discourse.DiscoveryCategoriesRoute = Discourse.Route.extend(Discourse.OpenComposer, ShowFooter, {
|
Discourse.DiscoveryCategoriesRoute = Discourse.Route.extend(Discourse.OpenComposer, ShowFooter, {
|
||||||
renderTemplate() {
|
renderTemplate() {
|
||||||
@ -45,7 +46,7 @@ Discourse.DiscoveryCategoriesRoute = Discourse.Route.extend(Discourse.OpenCompos
|
|||||||
const groups = this.site.groups,
|
const groups = this.site.groups,
|
||||||
everyoneName = groups.findBy('id', 0).name;
|
everyoneName = groups.findBy('id', 0).name;
|
||||||
|
|
||||||
Discourse.Route.showModal(this, 'editCategory', Discourse.Category.create({
|
showModal('editCategory', Discourse.Category.create({
|
||||||
color: 'AB9364', text_color: 'FFFFFF', group_permissions: [{group_name: everyoneName, permission_type: 1}],
|
color: 'AB9364', text_color: 'FFFFFF', group_permissions: [{group_name: everyoneName, permission_type: 1}],
|
||||||
available_groups: groups.map(g => g.name),
|
available_groups: groups.map(g => g.name),
|
||||||
allow_badges: true
|
allow_badges: true
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import ShowFooter from "discourse/mixins/show-footer";
|
import ShowFooter from "discourse/mixins/show-footer";
|
||||||
|
|
||||||
Discourse.DiscoveryRoute = Discourse.Route.extend(Discourse.ScrollTop, Discourse.OpenComposer, ShowFooter, {
|
const DiscoveryRoute = Discourse.Route.extend(Discourse.ScrollTop, Discourse.OpenComposer, ShowFooter, {
|
||||||
redirect: function() { return this.redirectIfLoginRequired(); },
|
redirect: function() { return this.redirectIfLoginRequired(); },
|
||||||
|
|
||||||
beforeModel: function(transition) {
|
beforeModel: function(transition) {
|
||||||
@ -42,22 +42,9 @@ Discourse.DiscoveryRoute = Discourse.Route.extend(Discourse.ScrollTop, Discourse
|
|||||||
|
|
||||||
createTopic: function() {
|
createTopic: function() {
|
||||||
this.openComposer(this.controllerFor('discovery/topics'));
|
this.openComposer(this.controllerFor('discovery/topics'));
|
||||||
},
|
|
||||||
|
|
||||||
changeBulkTemplate: function(w) {
|
|
||||||
var controllerName = w.replace('modal/', ''),
|
|
||||||
factory = this.container.lookupFactory('controller:' + controllerName);
|
|
||||||
|
|
||||||
this.render(w, {into: 'topicBulkActions', outlet: 'bulkOutlet', controller: factory ? controllerName : 'topic-bulk-actions'});
|
|
||||||
},
|
|
||||||
|
|
||||||
showBulkActions: function() {
|
|
||||||
var selected = this.controllerFor('discovery/topics').get('selected');
|
|
||||||
Discourse.Route.showModal(this, 'topicBulkActions', selected);
|
|
||||||
this.send('changeBulkTemplate', 'modal/bulk_actions_buttons');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Discourse.DiscoveryRoute;
|
export default DiscoveryRoute;
|
@ -1,23 +1,24 @@
|
|||||||
import ShowFooter from "discourse/mixins/show-footer";
|
import ShowFooter from "discourse/mixins/show-footer";
|
||||||
import RestrictedUserRoute from "discourse/routes/restricted-user";
|
import RestrictedUserRoute from "discourse/routes/restricted-user";
|
||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
export default RestrictedUserRoute.extend(ShowFooter, {
|
export default RestrictedUserRoute.extend(ShowFooter, {
|
||||||
model: function() {
|
model() {
|
||||||
return this.modelFor('user');
|
return this.modelFor('user');
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController: function(controller, user) {
|
setupController(controller, user) {
|
||||||
controller.setProperties({ model: user, newNameInput: user.get('name') });
|
controller.setProperties({ model: user, newNameInput: user.get('name') });
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showAvatarSelector: function() {
|
showAvatarSelector() {
|
||||||
Discourse.Route.showModal(this, 'avatar-selector');
|
showModal('avatar-selector');
|
||||||
|
|
||||||
// all the properties needed for displaying the avatar selector modal
|
// all the properties needed for displaying the avatar selector modal
|
||||||
var controller = this.controllerFor('avatar-selector');
|
const controller = this.controllerFor('avatar-selector');
|
||||||
var user = this.modelFor('user');
|
const user = this.modelFor('user');
|
||||||
var props = user.getProperties(
|
const props = user.getProperties(
|
||||||
'username', 'email',
|
'username', 'email',
|
||||||
'uploaded_avatar_id',
|
'uploaded_avatar_id',
|
||||||
'system_avatar_upload_id',
|
'system_avatar_upload_id',
|
||||||
@ -40,8 +41,8 @@ export default RestrictedUserRoute.extend(ShowFooter, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
saveAvatarSelection: function() {
|
saveAvatarSelection: function() {
|
||||||
var user = this.modelFor('user');
|
const user = this.modelFor('user');
|
||||||
var avatarSelector = this.controllerFor('avatar-selector');
|
const avatarSelector = this.controllerFor('avatar-selector');
|
||||||
|
|
||||||
// sends the information to the server if it has changed
|
// sends the information to the server if it has changed
|
||||||
if (avatarSelector.get('selectedUploadId') !== user.get('uploaded_avatar_id')) {
|
if (avatarSelector.get('selectedUploadId') !== user.get('uploaded_avatar_id')) {
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
var isTransitioning = false,
|
let isTransitioning = false,
|
||||||
scheduledReplace = null,
|
scheduledReplace = null,
|
||||||
lastScrollPos = null,
|
lastScrollPos = null;
|
||||||
SCROLL_DELAY = 500;
|
|
||||||
|
const SCROLL_DELAY = 500;
|
||||||
|
|
||||||
import ShowFooter from "discourse/mixins/show-footer";
|
import ShowFooter from "discourse/mixins/show-footer";
|
||||||
import Topic from 'discourse/models/topic';
|
import Topic from 'discourse/models/topic';
|
||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
const TopicRoute = Discourse.Route.extend(ShowFooter, {
|
||||||
redirect() { return this.redirectIfLoginRequired(); },
|
redirect() { return this.redirectIfLoginRequired(); },
|
||||||
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
@ -16,16 +18,16 @@ var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
titleToken() {
|
titleToken() {
|
||||||
var model = this.modelFor('topic');
|
const model = this.modelFor('topic');
|
||||||
if (model) {
|
if (model) {
|
||||||
var result = model.get('title'),
|
const result = model.get('title'),
|
||||||
cat = model.get('category');
|
cat = model.get('category');
|
||||||
|
|
||||||
// Only display uncategorized in the title tag if it was renamed
|
// Only display uncategorized in the title tag if it was renamed
|
||||||
if (cat && !(cat.get('isUncategorizedCategory') && cat.get('name').toLowerCase() === "uncategorized")) {
|
if (cat && !(cat.get('isUncategorizedCategory') && cat.get('name').toLowerCase() === "uncategorized")) {
|
||||||
var catName = cat.get('name'),
|
let catName = cat.get('name');
|
||||||
parentCategory = cat.get('parentCategory');
|
|
||||||
|
|
||||||
|
const parentCategory = cat.get('parentCategory');
|
||||||
if (parentCategory) {
|
if (parentCategory) {
|
||||||
catName = parentCategory.get('name') + " / " + catName;
|
catName = parentCategory.get('name') + " / " + catName;
|
||||||
}
|
}
|
||||||
@ -43,27 +45,27 @@ var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
showFlags(post) {
|
showFlags(post) {
|
||||||
Discourse.Route.showModal(this, 'flag', post);
|
showModal('flag', post);
|
||||||
this.controllerFor('flag').setProperties({ selected: null });
|
this.controllerFor('flag').setProperties({ selected: null });
|
||||||
},
|
},
|
||||||
|
|
||||||
showFlagTopic(topic) {
|
showFlagTopic(topic) {
|
||||||
Discourse.Route.showModal(this, 'flag', topic);
|
showModal('flag', topic);
|
||||||
this.controllerFor('flag').setProperties({ selected: null, flagTopic: true });
|
this.controllerFor('flag').setProperties({ selected: null, flagTopic: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
showAutoClose() {
|
showAutoClose() {
|
||||||
Discourse.Route.showModal(this, 'editTopicAutoClose', this.modelFor('topic'));
|
showModal('editTopicAutoClose', this.modelFor('topic'));
|
||||||
this.controllerFor('modal').set('modalClass', 'edit-auto-close-modal');
|
this.controllerFor('modal').set('modalClass', 'edit-auto-close-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
showInvite() {
|
showInvite() {
|
||||||
Discourse.Route.showModal(this, 'invite', this.modelFor('topic'));
|
showModal('invite', this.modelFor('topic'));
|
||||||
this.controllerFor('invite').reset();
|
this.controllerFor('invite').reset();
|
||||||
},
|
},
|
||||||
|
|
||||||
showPrivateInvite() {
|
showPrivateInvite() {
|
||||||
Discourse.Route.showModal(this, 'invitePrivate', this.modelFor('topic'));
|
showModal('invitePrivate', this.modelFor('topic'));
|
||||||
this.controllerFor('invitePrivate').setProperties({
|
this.controllerFor('invitePrivate').setProperties({
|
||||||
email: null,
|
email: null,
|
||||||
error: false,
|
error: false,
|
||||||
@ -73,26 +75,26 @@ var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
showHistory(post) {
|
showHistory(post) {
|
||||||
Discourse.Route.showModal(this, 'history', post);
|
showModal('history', post);
|
||||||
this.controllerFor('history').refresh(post.get("id"), "latest");
|
this.controllerFor('history').refresh(post.get("id"), "latest");
|
||||||
this.controllerFor('modal').set('modalClass', 'history-modal');
|
this.controllerFor('modal').set('modalClass', 'history-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
showRawEmail(post) {
|
showRawEmail(post) {
|
||||||
Discourse.Route.showModal(this, 'raw-email', post);
|
showModal('raw-email', post);
|
||||||
this.controllerFor('raw_email').loadRawEmail(post.get("id"));
|
this.controllerFor('raw_email').loadRawEmail(post.get("id"));
|
||||||
},
|
},
|
||||||
|
|
||||||
mergeTopic() {
|
mergeTopic() {
|
||||||
Discourse.Route.showModal(this, 'mergeTopic', this.modelFor('topic'));
|
showModal('mergeTopic', this.modelFor('topic'));
|
||||||
},
|
},
|
||||||
|
|
||||||
splitTopic() {
|
splitTopic() {
|
||||||
Discourse.Route.showModal(this, 'split-topic', this.modelFor('topic'));
|
showModal('split-topic', this.modelFor('topic'));
|
||||||
},
|
},
|
||||||
|
|
||||||
changeOwner() {
|
changeOwner() {
|
||||||
Discourse.Route.showModal(this, 'changeOwner', this.modelFor('topic'));
|
showModal('changeOwner', this.modelFor('topic'));
|
||||||
},
|
},
|
||||||
|
|
||||||
// Use replaceState to update the URL once it changes
|
// Use replaceState to update the URL once it changes
|
||||||
@ -100,9 +102,9 @@ var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
|||||||
// do nothing if we are transitioning to another route
|
// do nothing if we are transitioning to another route
|
||||||
if (isTransitioning || Discourse.TopicRoute.disableReplaceState) { return; }
|
if (isTransitioning || Discourse.TopicRoute.disableReplaceState) { return; }
|
||||||
|
|
||||||
var topic = this.modelFor('topic');
|
const topic = this.modelFor('topic');
|
||||||
if (topic && currentPost) {
|
if (topic && currentPost) {
|
||||||
var postUrl = topic.get('url');
|
let postUrl = topic.get('url');
|
||||||
if (currentPost > 1) { postUrl += "/" + currentPost; }
|
if (currentPost > 1) { postUrl += "/" + currentPost; }
|
||||||
|
|
||||||
Em.run.cancel(scheduledReplace);
|
Em.run.cancel(scheduledReplace);
|
||||||
@ -128,7 +130,7 @@ var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
|||||||
// replaceState can be very slow on Android Chrome. This function debounces replaceState
|
// replaceState can be very slow on Android Chrome. This function debounces replaceState
|
||||||
// within a topic until scrolling stops
|
// within a topic until scrolling stops
|
||||||
_replaceUnlessScrolling(url) {
|
_replaceUnlessScrolling(url) {
|
||||||
var currentPos = parseInt($(document).scrollTop(), 10);
|
const currentPos = parseInt($(document).scrollTop(), 10);
|
||||||
if (currentPos === lastScrollPos) {
|
if (currentPos === lastScrollPos) {
|
||||||
Discourse.URL.replaceState(url);
|
Discourse.URL.replaceState(url);
|
||||||
return;
|
return;
|
||||||
@ -138,11 +140,11 @@ var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setupParams(topic, params) {
|
setupParams(topic, params) {
|
||||||
var postStream = topic.get('postStream');
|
const postStream = topic.get('postStream');
|
||||||
postStream.set('summary', Em.get(params, 'filter') === 'summary');
|
postStream.set('summary', Em.get(params, 'filter') === 'summary');
|
||||||
postStream.set('show_deleted', !!Em.get(params, 'show_deleted'));
|
postStream.set('show_deleted', !!Em.get(params, 'show_deleted'));
|
||||||
|
|
||||||
var usernames = Em.get(params, 'username_filters'),
|
const usernames = Em.get(params, 'username_filters'),
|
||||||
userFilters = postStream.get('userFilters');
|
userFilters = postStream.get('userFilters');
|
||||||
|
|
||||||
userFilters.clear();
|
userFilters.clear();
|
||||||
@ -154,9 +156,9 @@ var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
model(params, transition) {
|
model(params, transition) {
|
||||||
var queryParams = transition.queryParams;
|
const queryParams = transition.queryParams;
|
||||||
|
|
||||||
var topic = this.modelFor('topic');
|
const topic = this.modelFor('topic');
|
||||||
if (topic && (topic.get('id') === parseInt(params.id, 10))) {
|
if (topic && (topic.get('id') === parseInt(params.id, 10))) {
|
||||||
this.setupParams(topic, queryParams);
|
this.setupParams(topic, queryParams);
|
||||||
// If we have the existing model, refresh it
|
// If we have the existing model, refresh it
|
||||||
@ -172,7 +174,7 @@ var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
|||||||
this._super();
|
this._super();
|
||||||
isTransitioning = false;
|
isTransitioning = false;
|
||||||
|
|
||||||
var topic = this.modelFor('topic');
|
const topic = this.modelFor('topic');
|
||||||
this.session.set('lastTopicIdViewed', parseInt(topic.get('id'), 10));
|
this.session.set('lastTopicIdViewed', parseInt(topic.get('id'), 10));
|
||||||
this.controllerFor('search').set('searchContext', topic.get('searchContext'));
|
this.controllerFor('search').set('searchContext', topic.get('searchContext'));
|
||||||
},
|
},
|
||||||
@ -184,7 +186,7 @@ var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
|||||||
this.controllerFor('search').set('searchContext', null);
|
this.controllerFor('search').set('searchContext', null);
|
||||||
this.controllerFor('user-card').set('visible', false);
|
this.controllerFor('user-card').set('visible', false);
|
||||||
|
|
||||||
var topicController = this.controllerFor('topic'),
|
const topicController = this.controllerFor('topic'),
|
||||||
postStream = topicController.get('postStream');
|
postStream = topicController.get('postStream');
|
||||||
postStream.cancelFilter();
|
postStream.cancelFilter();
|
||||||
|
|
||||||
@ -193,8 +195,8 @@ var TopicRoute = Discourse.Route.extend(ShowFooter, {
|
|||||||
this.controllerFor('composer').set('topic', null);
|
this.controllerFor('composer').set('topic', null);
|
||||||
Discourse.ScreenTrack.current().stop();
|
Discourse.ScreenTrack.current().stop();
|
||||||
|
|
||||||
var headerController;
|
const headerController = this.controllerFor('header');
|
||||||
if (headerController = this.controllerFor('header')) {
|
if (headerController) {
|
||||||
headerController.set('topic', null);
|
headerController.set('topic', null);
|
||||||
headerController.set('showExtraInfo', false);
|
headerController.set('showExtraInfo', false);
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
import ShowFooter from "discourse/mixins/show-footer";
|
import ShowFooter from 'discourse/mixins/show-footer';
|
||||||
|
import showModal from 'discourse/lib/show-modal';
|
||||||
|
|
||||||
export default Discourse.Route.extend(ShowFooter, {
|
export default Discourse.Route.extend(ShowFooter, {
|
||||||
renderTemplate: function() {
|
renderTemplate() {
|
||||||
this.render({ into: 'user' });
|
this.render({ into: 'user' });
|
||||||
},
|
},
|
||||||
|
|
||||||
model: function() {
|
model() {
|
||||||
return Discourse.Invite.findInvitedBy(this.modelFor('user'));
|
return Discourse.Invite.findInvitedBy(this.modelFor('user'));
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController: function(controller, model) {
|
setupController(controller, model) {
|
||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
model: model,
|
model: model,
|
||||||
user: this.controllerFor('user').get('model'),
|
user: this.controllerFor('user').get('model'),
|
||||||
@ -19,16 +20,16 @@ export default Discourse.Route.extend(ShowFooter, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showInvite: function() {
|
showInvite() {
|
||||||
Discourse.Route.showModal(this, 'invite', Discourse.User.current());
|
showModal('invite', Discourse.User.current());
|
||||||
this.controllerFor('invite').reset();
|
this.controllerFor('invite').reset();
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadSuccess: function(filename) {
|
uploadSuccess(filename) {
|
||||||
bootbox.alert(I18n.t("user.invited.bulk_invite.success", { filename: filename }));
|
bootbox.alert(I18n.t("user.invited.bulk_invite.success", { filename: filename }));
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadError: function(filename, message) {
|
uploadError(filename, message) {
|
||||||
bootbox.alert(I18n.t("user.invited.bulk_invite.error", { filename: filename, message: message }));
|
bootbox.alert(I18n.t("user.invited.bulk_invite.error", { filename: filename, message: message }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
{{#if selected}}
|
||||||
|
<div id='bulk-select'>
|
||||||
|
{{d-button action="showBulkActions" icon="wrench" class="no-text"}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
@ -14,11 +14,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if selected}}
|
{{bulk-select-button selected=selected refreshTarget=controller}}
|
||||||
<div id='bulk-select'>
|
|
||||||
{{d-button action="showBulkActions" icon="wrench" class="no-text"}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<div class='contents'>
|
<div class='contents'>
|
||||||
{{#if top}}
|
{{#if top}}
|
||||||
|
@ -49,7 +49,8 @@
|
|||||||
//= require ./discourse/components/notifications-button
|
//= require ./discourse/components/notifications-button
|
||||||
//= require ./discourse/components/topic-notifications-button
|
//= require ./discourse/components/topic-notifications-button
|
||||||
//= require ./discourse/views/composer
|
//= require ./discourse/views/composer
|
||||||
//= require ./discourse/routes/discourse_route
|
//= require ./discourse/lib/show-modal
|
||||||
|
//= require ./discourse/routes/discourse
|
||||||
//= require ./discourse/routes/build-topic-route
|
//= require ./discourse/routes/build-topic-route
|
||||||
//= require ./discourse/routes/restricted-user
|
//= require ./discourse/routes/restricted-user
|
||||||
//= require ./discourse/routes/user-topic-list
|
//= require ./discourse/routes/user-topic-list
|
||||||
|
@ -106,6 +106,7 @@ module Tilt
|
|||||||
|
|
||||||
# HAX
|
# HAX
|
||||||
result = "Controller" if result == "ControllerController"
|
result = "Controller" if result == "ControllerController"
|
||||||
|
result = "Route" if result == "DiscourseRoute"
|
||||||
result.gsub!(/Mixin$/, '')
|
result.gsub!(/Mixin$/, '')
|
||||||
result.gsub!(/Model$/, '')
|
result.gsub!(/Model$/, '')
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user