FEATURE: Stage post edits immediately (#13249)

After editing a post, it is refreshed by two ways. One of them is
triggered by the client side which will route the client to the edited
post and force a reload this way. The other way is via Message Bus.

This commit ignores both of the ways and tries to update the post
immediately and then refresh the post stream.
This commit is contained in:
Bianca Nenciu 2021-06-02 17:30:36 +03:00 committed by GitHub
parent 2672358b72
commit e81a5182b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 5 deletions

View File

@ -148,6 +148,7 @@ export default function transformPost(
postAtts.actionCodeWho = post.action_code_who;
postAtts.topicUrl = topic.get("url");
postAtts.isSaving = post.isSaving;
postAtts.staged = post.staged;
if (post.notice) {
postAtts.notice = post.notice;

View File

@ -961,23 +961,29 @@ const Composer = RestModel.extend({
this.set("composeState", SAVING);
const rollback = throwAjaxError((error) => {
post.set("cooked", oldCooked);
post.setProperties({ cooked: oldCooked, staged: false });
this.appEvents.trigger("post-stream:refresh", { id: post.id });
this.set("composeState", OPEN);
if (error.jqXHR && error.jqXHR.status === 409) {
this.set("editConflict", true);
}
});
post.setProperties({ cooked: props.cooked, staged: true });
this.appEvents.trigger("post-stream:refresh", { id: post.id });
return promise
.then(() => {
// rest model only sets props after it is saved
post.set("cooked", props.cooked);
return post.save(props).then((result) => {
this.clearState();
return result;
});
})
.catch(rollback);
.catch(rollback)
.finally(() => {
post.set("staged", false);
});
},
serialize(serializer, dest) {

View File

@ -735,7 +735,7 @@ export default createWidget("post", {
}
const classNames = ["topic-post", "clearfix"];
if (attrs.id === -1 || attrs.isSaving) {
if (attrs.id === -1 || attrs.isSaving || attrs.staged) {
classNames.push("staged");
}
if (attrs.selected) {

View File

@ -346,6 +346,43 @@ acceptance("Composer", function (needs) {
);
});
test("Editing a post stages new content", async function (assert) {
await visit("/t/internationalization-localization/280");
await click(".topic-post:nth-of-type(1) button.show-more-actions");
await click(".topic-post:nth-of-type(1) button.edit");
await fillIn(".d-editor-input", "will return empty json");
await fillIn("#reply-title", "This is the new text for the title");
await click("#reply-control button.create");
assert.equal(find(".topic-post.staged").length, 1);
assert.ok(
find(".topic-post:nth-of-type(1)")[0].className.includes("staged")
);
assert.equal(
find(".topic-post.staged .cooked").text().trim(),
"will return empty json"
);
});
test("Editing a post can rollback to old content", async function (assert) {
await visit("/t/internationalization-localization/280");
await click(".topic-post:nth-of-type(1) button.show-more-actions");
await click(".topic-post:nth-of-type(1) button.edit");
await fillIn(".d-editor-input", "this will 409");
await fillIn("#reply-title", "This is the new text for the title");
await click("#reply-control button.create");
assert.equal(find(".topic-post.staged").length, 0);
assert.equal(
find(".topic-post .cooked")[0].innerText,
"Any plans to support localization of UI elements, so that I (for example) could set up a completely German speaking forum?"
);
await click(".bootbox.modal .btn-primary");
});
test("Composer can switch between edits", async function (assert) {
await visit("/t/this-is-a-test-topic/9");

View File

@ -479,6 +479,8 @@ export function applyDefaultHandlers(pretender) {
const data = parsePostData(request.requestBody);
if (data.post.raw === "this will 409") {
return response(409, { errors: ["edit conflict"] });
} else if (data.post.raw === "will return empty json") {
return response(200, {});
}
data.post.id = request.params.post_id;
data.post.version = 2;