UX: Editing a shared draft was confusing in the composer
Now when you edit a shared draft it looks like creating one, where the destination category id appears in the dropdown.
This commit is contained in:
parent
c9216626d8
commit
05dc1f65ab
|
@ -1,11 +1,19 @@
|
||||||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||||
import { PRIVATE_MESSAGE, CREATE_TOPIC, CREATE_SHARED_DRAFT, REPLY, EDIT } from "discourse/models/composer";
|
import {
|
||||||
|
PRIVATE_MESSAGE,
|
||||||
|
CREATE_TOPIC,
|
||||||
|
CREATE_SHARED_DRAFT,
|
||||||
|
REPLY,
|
||||||
|
EDIT,
|
||||||
|
EDIT_SHARED_DRAFT
|
||||||
|
} from "discourse/models/composer";
|
||||||
import { iconHTML } from 'discourse-common/lib/icon-library';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
|
|
||||||
const TITLES = {
|
const TITLES = {
|
||||||
[PRIVATE_MESSAGE]: 'topic.private_message',
|
[PRIVATE_MESSAGE]: 'topic.private_message',
|
||||||
[CREATE_TOPIC]: 'topic.create_long',
|
[CREATE_TOPIC]: 'topic.create_long',
|
||||||
[CREATE_SHARED_DRAFT]: 'composer.create_shared_draft'
|
[CREATE_SHARED_DRAFT]: 'composer.create_shared_draft',
|
||||||
|
[EDIT_SHARED_DRAFT]: 'composer.edit_shared_draft'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
|
|
|
@ -13,10 +13,7 @@ export default Ember.Component.extend({
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
updateDestinationCategory(category) {
|
updateDestinationCategory(category) {
|
||||||
ajax(`/t/${this.get('topic.id')}/shared-draft`, {
|
return this.get('topic').updateDestinationCategory(category.get('id'));
|
||||||
method: 'PUT',
|
|
||||||
data: { category_id: category.get('id') }
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
publish() {
|
publish() {
|
||||||
|
|
|
@ -519,7 +519,7 @@ export default Ember.Controller.extend({
|
||||||
if (result.responseJson.action === "create_post" || this.get('replyAsNewTopicDraft') || this.get('replyAsNewPrivateMessageDraft')) {
|
if (result.responseJson.action === "create_post" || this.get('replyAsNewTopicDraft') || this.get('replyAsNewPrivateMessageDraft')) {
|
||||||
this.destroyDraft();
|
this.destroyDraft();
|
||||||
}
|
}
|
||||||
if (this.get('model.action') === 'edit') {
|
if (this.get('model.editingPost')) {
|
||||||
this.appEvents.trigger('post-stream:refresh', { id: parseInt(result.responseJson.id) });
|
this.appEvents.trigger('post-stream:refresh', { id: parseInt(result.responseJson.id) });
|
||||||
if (result.responseJson.post.post_number === 1) {
|
if (result.responseJson.post.post_number === 1) {
|
||||||
this.appEvents.trigger('header:update-topic', composer.get('topic'));
|
this.appEvents.trigger('header:update-topic', composer.get('topic'));
|
||||||
|
|
|
@ -409,16 +409,29 @@ export default Ember.Controller.extend(BufferedContent, {
|
||||||
}
|
}
|
||||||
|
|
||||||
const composer = this.get("composer");
|
const composer = this.get("composer");
|
||||||
|
let topic = this.get('model');
|
||||||
const composerModel = composer.get("model");
|
const composerModel = composer.get("model");
|
||||||
|
let editingFirst = composerModel && (post.get('firstPost') || composerModel.get('editingFirstPost'));
|
||||||
|
|
||||||
|
let editingSharedDraft = false;
|
||||||
|
let draftsCategoryId = this.get('site.shared_drafts_category_id');
|
||||||
|
if (draftsCategoryId && draftsCategoryId === topic.get('category.id')) {
|
||||||
|
editingSharedDraft = post.get('firstPost');
|
||||||
|
}
|
||||||
|
|
||||||
const opts = {
|
const opts = {
|
||||||
post,
|
post,
|
||||||
action: Composer.EDIT,
|
action: editingSharedDraft ? Composer.EDIT_SHARED_DRAFT : Composer.EDIT,
|
||||||
draftKey: post.get("topic.draft_key"),
|
draftKey: post.get("topic.draft_key"),
|
||||||
draftSequence: post.get("topic.draft_sequence")
|
draftSequence: post.get("topic.draft_sequence")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (editingSharedDraft) {
|
||||||
|
opts.destinationCategoryId = topic.get('destination_category_id');
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel and reopen the composer for the first post
|
// Cancel and reopen the composer for the first post
|
||||||
if (composerModel && (post.get('firstPost') || composerModel.get('editingFirstPost'))) {
|
if (editingFirst) {
|
||||||
composer.cancelComposer().then(() => composer.open(opts));
|
composer.cancelComposer().then(() => composer.open(opts));
|
||||||
} else {
|
} else {
|
||||||
composer.open(opts);
|
composer.open(opts);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { escapeExpression, tinyAvatar } from 'discourse/lib/utilities';
|
||||||
export const
|
export const
|
||||||
CREATE_TOPIC = 'createTopic',
|
CREATE_TOPIC = 'createTopic',
|
||||||
CREATE_SHARED_DRAFT = 'createSharedDraft',
|
CREATE_SHARED_DRAFT = 'createSharedDraft',
|
||||||
|
EDIT_SHARED_DRAFT = 'editSharedDraft',
|
||||||
PRIVATE_MESSAGE = 'privateMessage',
|
PRIVATE_MESSAGE = 'privateMessage',
|
||||||
NEW_PRIVATE_MESSAGE_KEY = 'new_private_message',
|
NEW_PRIVATE_MESSAGE_KEY = 'new_private_message',
|
||||||
REPLY = 'reply',
|
REPLY = 'reply',
|
||||||
|
@ -17,6 +18,10 @@ export const
|
||||||
REPLY_AS_NEW_TOPIC_KEY = "reply_as_new_topic",
|
REPLY_AS_NEW_TOPIC_KEY = "reply_as_new_topic",
|
||||||
REPLY_AS_NEW_PRIVATE_MESSAGE_KEY = "reply_as_new_private_message";
|
REPLY_AS_NEW_PRIVATE_MESSAGE_KEY = "reply_as_new_private_message";
|
||||||
|
|
||||||
|
function isEdit(action) {
|
||||||
|
return action === EDIT || action === EDIT_SHARED_DRAFT;
|
||||||
|
}
|
||||||
|
|
||||||
const CLOSED = 'closed',
|
const CLOSED = 'closed',
|
||||||
SAVING = 'saving',
|
SAVING = 'saving',
|
||||||
OPEN = 'open',
|
OPEN = 'open',
|
||||||
|
@ -52,11 +57,13 @@ const SAVE_LABELS = {
|
||||||
[REPLY]: 'composer.reply',
|
[REPLY]: 'composer.reply',
|
||||||
[CREATE_TOPIC]: 'composer.create_topic',
|
[CREATE_TOPIC]: 'composer.create_topic',
|
||||||
[PRIVATE_MESSAGE]: 'composer.create_pm',
|
[PRIVATE_MESSAGE]: 'composer.create_pm',
|
||||||
[CREATE_SHARED_DRAFT]: 'composer.create_shared_draft'
|
[CREATE_SHARED_DRAFT]: 'composer.create_shared_draft',
|
||||||
|
[EDIT_SHARED_DRAFT]: 'composer.save_edit'
|
||||||
};
|
};
|
||||||
|
|
||||||
const SAVE_ICONS = {
|
const SAVE_ICONS = {
|
||||||
[EDIT]: 'pencil',
|
[EDIT]: 'pencil',
|
||||||
|
[EDIT_SHARED_DRAFT]: 'clipboard',
|
||||||
[REPLY]: 'reply',
|
[REPLY]: 'reply',
|
||||||
[CREATE_TOPIC]: 'plus',
|
[CREATE_TOPIC]: 'plus',
|
||||||
[PRIVATE_MESSAGE]: 'envelope',
|
[PRIVATE_MESSAGE]: 'envelope',
|
||||||
|
@ -116,13 +123,14 @@ const Composer = RestModel.extend({
|
||||||
|
|
||||||
topicFirstPost: Em.computed.or('creatingTopic', 'editingFirstPost'),
|
topicFirstPost: Em.computed.or('creatingTopic', 'editingFirstPost'),
|
||||||
|
|
||||||
editingPost: Em.computed.equal('action', EDIT),
|
@computed('action')
|
||||||
|
editingPost: isEdit,
|
||||||
|
|
||||||
replyingToTopic: Em.computed.equal('action', REPLY),
|
replyingToTopic: Em.computed.equal('action', REPLY),
|
||||||
|
|
||||||
viewOpen: Em.computed.equal('composeState', OPEN),
|
viewOpen: Em.computed.equal('composeState', OPEN),
|
||||||
viewDraft: Em.computed.equal('composeState', DRAFT),
|
viewDraft: Em.computed.equal('composeState', DRAFT),
|
||||||
|
|
||||||
|
|
||||||
composeStateChanged: function() {
|
composeStateChanged: function() {
|
||||||
var oldOpen = this.get('composerOpened');
|
var oldOpen = this.get('composerOpened');
|
||||||
|
|
||||||
|
@ -212,7 +220,7 @@ const Composer = RestModel.extend({
|
||||||
if (!this.site.mobileView) {
|
if (!this.site.mobileView) {
|
||||||
const originalUserName = post.get('reply_to_user.username');
|
const originalUserName = post.get('reply_to_user.username');
|
||||||
const originalUserAvatar = post.get('reply_to_user.avatar_template');
|
const originalUserAvatar = post.get('reply_to_user.avatar_template');
|
||||||
if (originalUserName && originalUserAvatar && action === EDIT) {
|
if (originalUserName && originalUserAvatar && isEdit(action)) {
|
||||||
options.originalUser = {
|
options.originalUser = {
|
||||||
username: originalUserName,
|
username: originalUserName,
|
||||||
avatar: tinyAvatar(originalUserAvatar)
|
avatar: tinyAvatar(originalUserAvatar)
|
||||||
|
@ -471,11 +479,11 @@ const Composer = RestModel.extend({
|
||||||
|
|
||||||
const composer = this;
|
const composer = this;
|
||||||
if (!replyBlank &&
|
if (!replyBlank &&
|
||||||
((opts.reply || opts.action === EDIT) && this.get('replyDirty'))) {
|
((opts.reply || isEdit(opts.action)) && this.get('replyDirty'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.action === REPLY && this.get('action') === EDIT) this.set('reply', '');
|
if (opts.action === REPLY && isEdit(this.get('action'))) this.set('reply', '');
|
||||||
if (!opts.draftKey) throw 'draft key is required';
|
if (!opts.draftKey) throw 'draft key is required';
|
||||||
if (opts.draftSequence === null) throw 'draft sequence is required';
|
if (opts.draftSequence === null) throw 'draft sequence is required';
|
||||||
|
|
||||||
|
@ -527,11 +535,15 @@ const Composer = RestModel.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are editing a post, load it.
|
// If we are editing a post, load it.
|
||||||
if (opts.action === EDIT && opts.post) {
|
if (isEdit(opts.action) && opts.post) {
|
||||||
|
|
||||||
const topicProps = this.serialize(_edit_topic_serializer);
|
const topicProps = this.serialize(_edit_topic_serializer);
|
||||||
topicProps.loading = true;
|
topicProps.loading = true;
|
||||||
|
|
||||||
|
// When editing a shared draft, use its category
|
||||||
|
if (opts.action === EDIT_SHARED_DRAFT && opts.destinationCategoryId) {
|
||||||
|
topicProps.categoryId = opts.destinationCategoryId;
|
||||||
|
}
|
||||||
this.setProperties(topicProps);
|
this.setProperties(topicProps);
|
||||||
|
|
||||||
this.store.find('post', opts.post.get('id')).then(function(post) {
|
this.store.find('post', opts.post.get('id')).then(function(post) {
|
||||||
|
@ -591,21 +603,25 @@ const Composer = RestModel.extend({
|
||||||
|
|
||||||
// When you edit a post
|
// When you edit a post
|
||||||
editPost(opts) {
|
editPost(opts) {
|
||||||
const post = this.get('post'),
|
let post = this.get('post');
|
||||||
oldCooked = post.get('cooked'),
|
let oldCooked = post.get('cooked');
|
||||||
self = this;
|
let promise = Ember.RSVP.resolve();
|
||||||
|
|
||||||
let promise;
|
// Update the topic if we're editing the first post
|
||||||
|
|
||||||
// Update the title if we've changed it, otherwise consider it a
|
|
||||||
// successful resolved promise
|
|
||||||
if (this.get('title') &&
|
if (this.get('title') &&
|
||||||
post.get('post_number') === 1 &&
|
post.get('post_number') === 1 &&
|
||||||
this.get('topic.details.can_edit')) {
|
this.get('topic.details.can_edit')) {
|
||||||
const topicProps = this.getProperties(Object.keys(_edit_topic_serializer));
|
const topicProps = this.getProperties(Object.keys(_edit_topic_serializer));
|
||||||
promise = Topic.update(this.get('topic'), topicProps);
|
|
||||||
} else {
|
let topic = this.get('topic');
|
||||||
promise = Ember.RSVP.resolve();
|
|
||||||
|
// If we're editing a shared draft, keep the original category
|
||||||
|
if (this.get('action') === EDIT_SHARED_DRAFT) {
|
||||||
|
let destinationCategoryId = topicProps.categoryId;
|
||||||
|
promise = promise.then(() => topic.updateDestinationCategory(destinationCategoryId));
|
||||||
|
topicProps.categoryId = topic.get('category.id');
|
||||||
|
}
|
||||||
|
promise = promise.then(() => Topic.update(topic, topicProps));
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
|
@ -617,18 +633,18 @@ const Composer = RestModel.extend({
|
||||||
|
|
||||||
this.set('composeState', SAVING);
|
this.set('composeState', SAVING);
|
||||||
|
|
||||||
var rollback = throwAjaxError(function(){
|
let rollback = throwAjaxError(() => {
|
||||||
post.set('cooked', oldCooked);
|
post.set('cooked', oldCooked);
|
||||||
self.set('composeState', OPEN);
|
this.set('composeState', OPEN);
|
||||||
});
|
});
|
||||||
|
|
||||||
return promise.then(function() {
|
return promise.then(() => {
|
||||||
// rest model only sets props after it is saved
|
// rest model only sets props after it is saved
|
||||||
post.set("cooked", props.cooked);
|
post.set("cooked", props.cooked);
|
||||||
return post.save(props).then(function(result) {
|
return post.save(props).then(result => {
|
||||||
self.clearState();
|
this.clearState();
|
||||||
return result;
|
return result;
|
||||||
}).catch(function(error) {
|
}).catch(error => {
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
}).catch(rollback);
|
}).catch(rollback);
|
||||||
|
@ -867,6 +883,8 @@ Composer.reopenClass({
|
||||||
|
|
||||||
// The actions the composer can take
|
// The actions the composer can take
|
||||||
CREATE_TOPIC,
|
CREATE_TOPIC,
|
||||||
|
CREATE_SHARED_DRAFT,
|
||||||
|
EDIT_SHARED_DRAFT,
|
||||||
PRIVATE_MESSAGE,
|
PRIVATE_MESSAGE,
|
||||||
REPLY,
|
REPLY,
|
||||||
EDIT,
|
EDIT,
|
||||||
|
|
|
@ -488,6 +488,14 @@ const Topic = RestModel.extend({
|
||||||
}).catch(popupAjaxError);
|
}).catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateDestinationCategory(categoryId) {
|
||||||
|
this.set('destination_category_id', categoryId);
|
||||||
|
return ajax(`/t/${this.get('id')}/shared-draft`, {
|
||||||
|
method: 'PUT',
|
||||||
|
data: { category_id: categoryId }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
convertTopic(type) {
|
convertTopic(type) {
|
||||||
return ajax(`/t/${this.get('id')}/convert-topic/${type}`, {type: 'PUT'}).then(() => {
|
return ajax(`/t/${this.get('id')}/convert-topic/${type}`, {type: 'PUT'}).then(() => {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
{{composer-messages composer=model
|
{{composer-messages composer=model
|
||||||
messageCount=messageCount
|
messageCount=messageCount
|
||||||
addLinkLookup="addLinkLookup"}}
|
addLinkLookup="addLinkLookup"}}
|
||||||
|
|
||||||
{{#if model.viewOpen}}
|
{{#if model.viewOpen}}
|
||||||
<div class="reply-area {{if canEditTags 'with-tags'}}">
|
<div class="reply-area {{if canEditTags 'with-tags'}}">
|
||||||
<div class='composer-fields'>
|
<div class='composer-fields'>
|
||||||
|
|
|
@ -1314,6 +1314,7 @@ en:
|
||||||
create_pm: "Message"
|
create_pm: "Message"
|
||||||
create_whisper: "Whisper"
|
create_whisper: "Whisper"
|
||||||
create_shared_draft: "Create Shared Draft"
|
create_shared_draft: "Create Shared Draft"
|
||||||
|
edit_shared_draft: "Edit Shared Draft"
|
||||||
title: "Or press Ctrl+Enter"
|
title: "Or press Ctrl+Enter"
|
||||||
|
|
||||||
users_placeholder: "Add a user"
|
users_placeholder: "Add a user"
|
||||||
|
|
Loading…
Reference in New Issue