Use small actions for moving posts
This commit is contained in:
parent
cf91bca0cd
commit
76aa0795b3
|
@ -10,7 +10,8 @@ const icons = {
|
|||
'pinned_globally.enabled': 'thumb-tack',
|
||||
'pinned_globally.disabled': 'thumb-tack unpinned',
|
||||
'visible.enabled': 'eye',
|
||||
'visible.disabled': 'eye-slash'
|
||||
'visible.disabled': 'eye-slash',
|
||||
'split_topic': 'sign-out'
|
||||
};
|
||||
|
||||
export function actionDescription(actionCode, createdAt) {
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import Presence from 'discourse/mixins/presence';
|
||||
import SelectedPostsCount from 'discourse/mixins/selected-posts-count';
|
||||
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
||||
import ObjectController from 'discourse/controllers/object';
|
||||
import { movePosts, mergeTopic } from 'discourse/models/topic';
|
||||
|
||||
// Modal related to merging of topics
|
||||
export default ObjectController.extend(SelectedPostsCount, ModalFunctionality, Presence, {
|
||||
export default Ember.Controller.extend(SelectedPostsCount, ModalFunctionality, Presence, {
|
||||
needs: ['topic'],
|
||||
|
||||
saving: false,
|
||||
selectedTopicId: null,
|
||||
|
||||
topicController: Em.computed.alias('controllers.topic'),
|
||||
selectedPosts: Em.computed.alias('topicController.selectedPosts'),
|
||||
selectedReplies: Em.computed.alias('topicController.selectedReplies'),
|
||||
|
@ -22,38 +25,40 @@ export default ObjectController.extend(SelectedPostsCount, ModalFunctionality, P
|
|||
return I18n.t('topic.merge_topic.title');
|
||||
}.property('saving'),
|
||||
|
||||
onShow: function() {
|
||||
onShow() {
|
||||
this.set('controllers.modal.modalClass', 'split-modal');
|
||||
},
|
||||
|
||||
actions: {
|
||||
movePostsToExistingTopic: function() {
|
||||
movePostsToExistingTopic() {
|
||||
const topicId = this.get('model.id');
|
||||
|
||||
this.set('saving', true);
|
||||
|
||||
var promise = null;
|
||||
let promise = null;
|
||||
if (this.get('allPostsSelected')) {
|
||||
promise = Discourse.Topic.mergeTopic(this.get('id'), this.get('selectedTopicId'));
|
||||
promise = mergeTopic(topicId, this.get('selectedTopicId'));
|
||||
} else {
|
||||
var postIds = this.get('selectedPosts').map(function(p) { return p.get('id'); }),
|
||||
replyPostIds = this.get('selectedReplies').map(function(p) { return p.get('id'); });
|
||||
const postIds = this.get('selectedPosts').map(function(p) { return p.get('id'); });
|
||||
const replyPostIds = this.get('selectedReplies').map(function(p) { return p.get('id'); });
|
||||
|
||||
promise = Discourse.Topic.movePosts(this.get('id'), {
|
||||
promise = movePosts(topicId, {
|
||||
destination_topic_id: this.get('selectedTopicId'),
|
||||
post_ids: postIds,
|
||||
reply_post_ids: replyPostIds
|
||||
});
|
||||
}
|
||||
|
||||
var mergeTopicController = this;
|
||||
const self = this;
|
||||
promise.then(function(result) {
|
||||
// Posts moved
|
||||
mergeTopicController.send('closeModal');
|
||||
mergeTopicController.get('topicController').send('toggleMultiSelect');
|
||||
self.send('closeModal');
|
||||
self.get('topicController').send('toggleMultiSelect');
|
||||
Em.run.next(function() { Discourse.URL.routeTo(result.url); });
|
||||
}, function() {
|
||||
// Error moving posts
|
||||
mergeTopicController.flash(I18n.t('topic.merge_topic.error'));
|
||||
mergeTopicController.set('saving', false);
|
||||
}).catch(function() {
|
||||
self.flash(I18n.t('topic.merge_topic.error'));
|
||||
}).finally(function() {
|
||||
self.set('saving', false);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
import Presence from 'discourse/mixins/presence';
|
||||
import SelectedPostsCount from 'discourse/mixins/selected-posts-count';
|
||||
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
||||
import ObjectController from 'discourse/controllers/object';
|
||||
import { extractError } from 'discourse/lib/ajax-error';
|
||||
import { movePosts } from 'discourse/models/topic';
|
||||
|
||||
// Modal related to auto closing of topics
|
||||
export default ObjectController.extend(SelectedPostsCount, ModalFunctionality, Presence, {
|
||||
export default Ember.Controller.extend(SelectedPostsCount, ModalFunctionality, Presence, {
|
||||
needs: ['topic'],
|
||||
topicName: null,
|
||||
saving: false,
|
||||
categoryId: null,
|
||||
|
||||
topicController: Em.computed.alias('controllers.topic'),
|
||||
selectedPosts: Em.computed.alias('topicController.selectedPosts'),
|
||||
selectedReplies: Em.computed.alias('topicController.selectedReplies'),
|
||||
allPostsSelected: Em.computed.alias('topicController.allPostsSelected'),
|
||||
|
||||
buttonDisabled: function() {
|
||||
if (this.get('saving')) return true;
|
||||
|
@ -21,7 +26,7 @@ export default ObjectController.extend(SelectedPostsCount, ModalFunctionality, P
|
|||
return I18n.t('topic.split_topic.action');
|
||||
}.property('saving'),
|
||||
|
||||
onShow: function() {
|
||||
onShow() {
|
||||
this.setProperties({
|
||||
'controllers.modal.modalClass': 'split-modal',
|
||||
saving: false,
|
||||
|
@ -31,39 +36,29 @@ export default ObjectController.extend(SelectedPostsCount, ModalFunctionality, P
|
|||
},
|
||||
|
||||
actions: {
|
||||
movePostsToNewTopic: function() {
|
||||
movePostsToNewTopic() {
|
||||
this.set('saving', true);
|
||||
|
||||
var postIds = this.get('selectedPosts').map(function(p) { return p.get('id'); }),
|
||||
replyPostIds = this.get('selectedReplies').map(function(p) { return p.get('id'); }),
|
||||
self = this,
|
||||
categoryId = this.get('categoryId'),
|
||||
saveOpts = {
|
||||
title: this.get('topicName'),
|
||||
post_ids: postIds,
|
||||
reply_post_ids: replyPostIds
|
||||
};
|
||||
const postIds = this.get('selectedPosts').map(function(p) { return p.get('id'); }),
|
||||
replyPostIds = this.get('selectedReplies').map(function(p) { return p.get('id'); }),
|
||||
self = this,
|
||||
categoryId = this.get('categoryId'),
|
||||
saveOpts = {
|
||||
title: this.get('topicName'),
|
||||
post_ids: postIds,
|
||||
reply_post_ids: replyPostIds
|
||||
};
|
||||
|
||||
if (!Ember.isNone(categoryId)) { saveOpts.category_id = categoryId; }
|
||||
|
||||
Discourse.Topic.movePosts(this.get('id'), saveOpts).then(function(result) {
|
||||
movePosts(this.get('model.id'), saveOpts).then(function(result) {
|
||||
// Posts moved
|
||||
self.send('closeModal');
|
||||
self.get('topicController').send('toggleMultiSelect');
|
||||
Em.run.next(function() { Discourse.URL.routeTo(result.url); });
|
||||
Ember.run.next(function() { Discourse.URL.routeTo(result.url); });
|
||||
}).catch(function(xhr) {
|
||||
|
||||
var error = I18n.t('topic.split_topic.error');
|
||||
|
||||
if (xhr) {
|
||||
var json = xhr.responseJSON;
|
||||
if (json && json.errors) {
|
||||
error = json.errors[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Error moving posts
|
||||
self.flash(error);
|
||||
self.flash(extractError(xhr, I18n.t('topic.split_topic.error')));
|
||||
}).finally(function() {
|
||||
self.set('saving', false);
|
||||
});
|
||||
return false;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
function extractError(error) {
|
||||
export function extractError(error, defaultMessage) {
|
||||
if (error instanceof Error) {
|
||||
Ember.Logger.error(error.stack);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ function extractError(error) {
|
|||
}
|
||||
}
|
||||
|
||||
return parsedError || I18n.t('generic_error');
|
||||
return parsedError || defaultMessage || I18n.t('generic_error');
|
||||
}
|
||||
|
||||
export function throwAjaxError(undoCallback) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { flushMap } from 'discourse/models/store';
|
||||
import RestModel from 'discourse/models/rest';
|
||||
|
||||
const Topic = RestModel.extend({
|
||||
|
@ -462,28 +463,6 @@ Topic.reopenClass({
|
|||
return Discourse.ajax(url + ".json", {data: data});
|
||||
},
|
||||
|
||||
mergeTopic(topicId, destinationTopicId) {
|
||||
const promise = Discourse.ajax("/t/" + topicId + "/merge-topic", {
|
||||
type: 'POST',
|
||||
data: {destination_topic_id: destinationTopicId}
|
||||
}).then(function (result) {
|
||||
if (result.success) return result;
|
||||
promise.reject(new Error("error merging topic"));
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
|
||||
movePosts(topicId, opts) {
|
||||
const promise = Discourse.ajax("/t/" + topicId + "/move-posts", {
|
||||
type: 'POST',
|
||||
data: opts
|
||||
}).then(function (result) {
|
||||
if (result.success) return result;
|
||||
promise.reject(new Error("error moving posts topic"));
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
|
||||
changeOwners(topicId, opts) {
|
||||
const promise = Discourse.ajax("/t/" + topicId + "/change-owner", {
|
||||
type: 'POST',
|
||||
|
@ -523,4 +502,24 @@ Topic.reopenClass({
|
|||
}
|
||||
});
|
||||
|
||||
function moveResult(result) {
|
||||
if (result.success) {
|
||||
// We should be hesitant to flush the map but moving ids is one rare case
|
||||
flushMap();
|
||||
return result;
|
||||
}
|
||||
throw "error moving posts topic";
|
||||
}
|
||||
|
||||
export function movePosts(topicId, data) {
|
||||
return Discourse.ajax("/t/" + topicId + "/move-posts", { type: 'POST', data }).then(moveResult);
|
||||
}
|
||||
|
||||
export function mergeTopic(topicId, destinationTopicId) {
|
||||
return Discourse.ajax("/t/" + topicId + "/merge-topic", {
|
||||
type: 'POST',
|
||||
data: {destination_topic_id: destinationTopicId}
|
||||
}).then(moveResult);
|
||||
}
|
||||
|
||||
export default Topic;
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
<div id='move-selected' class="modal-body">
|
||||
{{#if error}}
|
||||
<div class="alert alert-error">
|
||||
<button class="close" data-dismiss="alert">×</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<p>{{{i18n 'topic.merge_topic.instructions' count=selectedPostsCount}}}</p>
|
||||
|
||||
<form>
|
||||
|
@ -13,5 +7,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class='btn btn-primary' {{bind-attr disabled="buttonDisabled"}} {{action "movePostsToExistingTopic"}}><i class="fa fa-sign-out"></i>{{buttonTitle}}</button>
|
||||
{{#d-button class="btn-primary" disabled=buttonDisabled action="movePostsToExistingTopic"}}
|
||||
{{fa-icon 'sign-out'}} {{buttonTitle}}
|
||||
{{/d-button}}
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
<div id='move-selected' class="modal-body">
|
||||
{{#if error}}
|
||||
<div class="alert alert-error">
|
||||
<button class="close" data-dismiss="alert">×</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{{i18n 'topic.split_topic.instructions' count=selectedPostsCount}}}
|
||||
|
||||
<form>
|
||||
|
@ -18,5 +12,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class='btn btn-primary' {{bind-attr disabled="buttonDisabled"}} {{action "movePostsToNewTopic"}}><i class='fa fa-sign-out'></i>{{buttonTitle}}</button>
|
||||
{{#d-button class="btn-primary" disabled=buttonDisabled action="movePostsToNewTopic"}}
|
||||
{{fa-icon 'sign-out'}} {{buttonTitle}}
|
||||
{{/d-button}}
|
||||
</div>
|
|
@ -2,6 +2,6 @@ import SelectedPostsCount from 'discourse/mixins/selected-posts-count';
|
|||
import ModalBodyView from "discourse/views/modal-body";
|
||||
|
||||
export default ModalBodyView.extend(SelectedPostsCount, {
|
||||
templateName: 'modal/split_topic',
|
||||
templateName: 'modal/split-topic',
|
||||
title: I18n.t('topic.split_topic.title')
|
||||
});
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
//= require_tree ./discourse/adapters
|
||||
//= require ./discourse/models/rest
|
||||
//= require ./discourse/models/model
|
||||
//= require ./discourse/models/result-set
|
||||
//= require ./discourse/models/store
|
||||
//= require ./discourse/models/post-action-type
|
||||
//= require ./discourse/models/action-summary
|
||||
//= require ./discourse/models/post
|
||||
|
|
|
@ -123,11 +123,15 @@ class PostMover
|
|||
end
|
||||
|
||||
def create_moderator_post_in_original_topic
|
||||
move_type_str = PostMover.move_types[@move_type].to_s
|
||||
|
||||
original_topic.add_moderator_post(
|
||||
user,
|
||||
I18n.t("move_posts.#{PostMover.move_types[@move_type]}_moderator_post",
|
||||
I18n.t("move_posts.#{move_type_str}_moderator_post",
|
||||
count: post_ids.count,
|
||||
topic_link: "[#{destination_topic.title}](#{destination_topic.url})"),
|
||||
topic_link: "[#{destination_topic.title}](#{destination_topic.relative_url})"),
|
||||
post_type: Post.types[:small_action],
|
||||
action_code: "split_topic",
|
||||
post_number: @first_post_number_moved
|
||||
)
|
||||
end
|
||||
|
|
|
@ -120,6 +120,7 @@ en:
|
|||
email: 'send this link in an email'
|
||||
|
||||
action_codes:
|
||||
split_topic: "split this topic"
|
||||
autoclosed:
|
||||
enabled: 'closed this topic %{when}'
|
||||
disabled: 'opened this topic %{when}'
|
||||
|
|
|
@ -1242,11 +1242,11 @@ en:
|
|||
|
||||
move_posts:
|
||||
new_topic_moderator_post:
|
||||
one: "I moved a post to a new topic: %{topic_link}"
|
||||
other: "I moved %{count} posts to a new topic: %{topic_link}"
|
||||
one: "A post was split to a new topic: %{topic_link}"
|
||||
other: "%{count} posts were split to a new topic: %{topic_link}"
|
||||
existing_topic_moderator_post:
|
||||
one: "I moved a post to an existing topic: %{topic_link}"
|
||||
other: "I moved %{count} posts to an existing topic: %{topic_link}"
|
||||
one: "A post was merged into an existing topic: %{topic_link}"
|
||||
other: "%{count} posts were merged into an existing topic: %{topic_link}"
|
||||
|
||||
change_owner:
|
||||
post_revision_text: "Ownership transferred from %{old_user} to %{new_user}"
|
||||
|
|
Loading…
Reference in New Issue