mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Use Ember.Comparable mixin to sort posts
closes https://github.com/TryGhost/Ghost/issues/7002 - move sorting logic out of the controller and into the Post model This is a quick attempt at implementing the refactoring referenced in https://github.com/TryGhost/Ghost/issues/7002. The client-side sorting is working but we still have the problem of scheduled posts not appearing in the list until you scroll to the very first published post because the server is returning posts in the wrong order.
This commit is contained in:
parent
f1c68e48c8
commit
a109c1c3db
2 changed files with 100 additions and 100 deletions
|
@ -8,101 +8,6 @@ const {
|
|||
} = Ember;
|
||||
const {equal} = computed;
|
||||
|
||||
// a custom sort function is needed in order to sort the posts list the same way the server would:
|
||||
// status: scheduled, draft, published
|
||||
// publishedAtUTC: DESC
|
||||
// updatedAtUTC: DESC
|
||||
// id: DESC
|
||||
function comparator(item1, item2) {
|
||||
let updated1 = item1.get('updatedAtUTC');
|
||||
let updated2 = item2.get('updatedAtUTC');
|
||||
let idResult,
|
||||
publishedAtResult,
|
||||
statusResult,
|
||||
updatedAtResult;
|
||||
|
||||
// when `updatedAt` is undefined, the model is still
|
||||
// being written to with the results from the server
|
||||
if (item1.get('isNew') || !updated1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (item2.get('isNew') || !updated2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
idResult = compare(parseInt(item1.get('id')), parseInt(item2.get('id')));
|
||||
statusResult = statusCompare(item1, item2);
|
||||
updatedAtResult = compare(updated1.valueOf(), updated2.valueOf());
|
||||
publishedAtResult = publishedAtCompare(item1, item2);
|
||||
|
||||
if (statusResult === 0) {
|
||||
if (publishedAtResult === 0) {
|
||||
if (updatedAtResult === 0) {
|
||||
// This should be DESC
|
||||
return idResult * -1;
|
||||
}
|
||||
// This should be DESC
|
||||
return updatedAtResult * -1;
|
||||
}
|
||||
// This should be DESC
|
||||
return publishedAtResult * -1;
|
||||
}
|
||||
|
||||
return statusResult;
|
||||
}
|
||||
|
||||
function statusCompare(item1, item2) {
|
||||
let status1 = item1.get('status');
|
||||
let status2 = item2.get('status');
|
||||
|
||||
// if any of those is empty
|
||||
if (!status1 && !status2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!status1 && status2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!status2 && status1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// We have to make sure, that scheduled posts will be listed first
|
||||
// after that, draft and published will be sorted alphabetically and don't need
|
||||
// any manual comparison.
|
||||
|
||||
if (status1 === 'scheduled' && (status2 === 'draft' || status2 === 'published')) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status2 === 'scheduled' && (status1 === 'draft' || status1 === 'published')) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return compare(status1.valueOf(), status2.valueOf());
|
||||
}
|
||||
|
||||
function publishedAtCompare(item1, item2) {
|
||||
let published1 = item1.get('publishedAtUTC');
|
||||
let published2 = item2.get('publishedAtUTC');
|
||||
|
||||
if (!published1 && !published2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!published1 && published2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!published2 && published1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return compare(published1.valueOf(), published2.valueOf());
|
||||
}
|
||||
|
||||
export default Controller.extend({
|
||||
feature: service(),
|
||||
|
||||
|
@ -112,10 +17,8 @@ export default Controller.extend({
|
|||
postListFocused: equal('keyboardFocus', 'postList'),
|
||||
postContentFocused: equal('keyboardFocus', 'postContent'),
|
||||
|
||||
sortedPosts: computed('model.@each.status', 'model.@each.publishedAtUTC', 'model.@each.isNew', 'model.@each.updatedAtUTC', function () {
|
||||
let postsArray = this.get('model').toArray();
|
||||
|
||||
return postsArray.sort(comparator);
|
||||
sortedPosts: computed('model.@each.{status,publishedAtUTC,isNew,updatedAtUTC}', function () {
|
||||
return this.get('model').toArray().sort(compare);
|
||||
}),
|
||||
|
||||
actions: {
|
||||
|
|
|
@ -6,12 +6,65 @@ import { belongsTo, hasMany } from 'ember-data/relationships';
|
|||
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
|
||||
|
||||
const {
|
||||
Comparable,
|
||||
compare,
|
||||
computed,
|
||||
inject: {service}
|
||||
} = Ember;
|
||||
const {equal, filterBy} = computed;
|
||||
|
||||
export default Model.extend(ValidationEngine, {
|
||||
function statusCompare(postA, postB) {
|
||||
let status1 = postA.get('status');
|
||||
let status2 = postB.get('status');
|
||||
|
||||
// if any of those is empty
|
||||
if (!status1 && !status2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!status1 && status2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!status2 && status1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// We have to make sure, that scheduled posts will be listed first
|
||||
// after that, draft and published will be sorted alphabetically and don't need
|
||||
// any manual comparison.
|
||||
|
||||
if (status1 === 'scheduled' && (status2 === 'draft' || status2 === 'published')) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status2 === 'scheduled' && (status1 === 'draft' || status1 === 'published')) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return compare(status1.valueOf(), status2.valueOf());
|
||||
}
|
||||
|
||||
function publishedAtCompare(postA, postB) {
|
||||
let published1 = postA.get('publishedAtUTC');
|
||||
let published2 = postB.get('publishedAtUTC');
|
||||
|
||||
if (!published1 && !published2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!published1 && published2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!published2 && published1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return compare(published1.valueOf(), published2.valueOf());
|
||||
}
|
||||
|
||||
export default Model.extend(Comparable, ValidationEngine, {
|
||||
validationType: 'post',
|
||||
|
||||
uuid: attr('string'),
|
||||
|
@ -95,5 +148,49 @@ export default Model.extend(ValidationEngine, {
|
|||
|
||||
isAuthoredByUser(user) {
|
||||
return parseInt(user.get('id'), 10) === parseInt(this.get('authorId'), 10);
|
||||
},
|
||||
|
||||
// a custom sort function is needed in order to sort the posts list the same way the server would:
|
||||
// status: scheduled, draft, published
|
||||
// publishedAt: DESC
|
||||
// updatedAt: DESC
|
||||
// id: DESC
|
||||
compare(postA, postB) {
|
||||
let updated1 = postA.get('updatedAtUTC');
|
||||
let updated2 = postB.get('updatedAtUTC');
|
||||
let idResult,
|
||||
publishedAtResult,
|
||||
statusResult,
|
||||
updatedAtResult;
|
||||
|
||||
// when `updatedAt` is undefined, the model is still
|
||||
// being written to with the results from the server
|
||||
if (postA.get('isNew') || !updated1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (postB.get('isNew') || !updated2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
idResult = compare(parseInt(postA.get('id')), parseInt(postB.get('id')));
|
||||
statusResult = statusCompare(postA, postB);
|
||||
updatedAtResult = compare(updated1.valueOf(), updated2.valueOf());
|
||||
publishedAtResult = publishedAtCompare(postA, postB);
|
||||
|
||||
if (statusResult === 0) {
|
||||
if (publishedAtResult === 0) {
|
||||
if (updatedAtResult === 0) {
|
||||
// This should be DESC
|
||||
return idResult * -1;
|
||||
}
|
||||
// This should be DESC
|
||||
return updatedAtResult * -1;
|
||||
}
|
||||
// This should be DESC
|
||||
return publishedAtResult * -1;
|
||||
}
|
||||
|
||||
return statusResult;
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue