diff --git a/ghost/admin/app/controllers/posts.js b/ghost/admin/app/controllers/posts.js index 9952aebbb2..bc5811e2e1 100644 --- a/ghost/admin/app/controllers/posts.js +++ b/ghost/admin/app/controllers/posts.js @@ -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: { diff --git a/ghost/admin/app/models/post.js b/ghost/admin/app/models/post.js index 804cdafec5..629b689403 100644 --- a/ghost/admin/app/models/post.js +++ b/ghost/admin/app/models/post.js @@ -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; } });