This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/components/reviewable-item.js.es6
Robin Ward cbc311e4ed UX: Update the reviewable count before the message bus
In certain edge cases, the message bus won't send the message to the
user about the updated review count and it can go out of sync.

This patch synchronizes the review count every time:

1. The user visits the "Needs Review" page

2. Every time the user performs an action
2019-04-05 10:35:38 -04:00

159 lines
4.3 KiB
JavaScript

import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators";
import Category from "discourse/models/category";
import optionalService from "discourse/lib/optional-service";
let _components = {};
export default Ember.Component.extend({
adminTools: optionalService(),
tagName: "",
updating: null,
editing: false,
_updates: null,
@computed("reviewable.type")
customClass(type) {
return type.dasherize();
},
// Find a component to render, if one exists. For example:
// `ReviewableUser` will return `reviewable-user`
@computed("reviewable.type")
reviewableComponent(type) {
if (_components[type] !== undefined) {
return _components[type];
}
let dasherized = Ember.String.dasherize(type);
let templatePath = `components/${dasherized}`;
let template =
Ember.TEMPLATES[`${templatePath}`] ||
Ember.TEMPLATES[`javascripts/${templatePath}`];
_components[type] = template ? dasherized : null;
return _components[type];
},
_performConfirmed(action) {
let reviewable = this.get("reviewable");
let performAction = () => {
let version = reviewable.get("version");
this.set("updating", true);
return ajax(
`/review/${reviewable.id}/perform/${action.id}?version=${version}`,
{
method: "PUT"
}
)
.then(result => {
let performResult = result.reviewable_perform_result;
// "fast track" to update the current user's reviewable count before the message bus finds out.
if (performResult.reviewable_count !== undefined) {
this.currentUser.set("reviewable_count", result.reviewable_count);
}
this.attrs.remove(performResult.remove_reviewable_ids);
})
.catch(popupAjaxError)
.finally(() => this.set("updating", false));
};
if (action.client_action) {
let actionMethod = this[`client${action.client_action.classify()}`];
if (actionMethod) {
return actionMethod.call(this, reviewable, performAction);
} else {
// eslint-disable-next-line no-console
console.error(`No handler for ${action.client_action} found`);
return;
}
return;
} else {
return performAction();
}
},
clientSuspend(reviewable, performAction) {
this._penalize("showSuspendModal", reviewable, performAction);
},
clientSilence(reviewable, performAction) {
this._penalize("showSilenceModal", reviewable, performAction);
},
_penalize(adminToolMethod, reviewable, performAction) {
let adminTools = this.get("adminTools");
if (adminTools) {
let createdBy = reviewable.get("target_created_by");
let postId = reviewable.get("post_id");
let postEdit = reviewable.get("raw");
return adminTools[adminToolMethod](createdBy, {
postId,
postEdit,
before: performAction
});
}
},
actions: {
edit() {
this.set("editing", true);
this._updates = { payload: {} };
},
cancelEdit() {
this.set("editing", false);
},
saveEdit() {
let updates = this._updates;
// Remove empty objects
Object.keys(updates).forEach(name => {
let attr = updates[name];
if (typeof attr === "object" && Object.keys(attr).length === 0) {
delete updates[name];
}
});
this.set("updating", true);
return this.get("reviewable")
.update(updates)
.then(() => this.set("editing", false))
.catch(popupAjaxError)
.finally(() => this.set("updating", false));
},
categoryChanged(category) {
if (!category) {
category = Category.findUncategorized();
}
this._updates.category_id = category.id;
},
valueChanged(fieldId, event) {
Ember.set(this._updates, fieldId, event.target.value);
},
perform(action) {
if (this.get("updating")) {
return;
}
let msg = action.get("confirm_message");
if (msg) {
bootbox.confirm(msg, answer => {
if (answer) {
return this._performConfirmed(action);
}
});
} else {
return this._performConfirmed(action);
}
}
}
});