2016-05-24 15:06:59 +03:00
import AuthenticatedRoute from 'ghost-admin/routes/authenticated' ;
2024-07-29 19:19:28 +03:00
import RSVP from 'rsvp' ;
2022-01-17 12:34:55 +03:00
import { action } from '@ember/object' ;
2017-08-22 10:53:26 +03:00
import { assign } from '@ember/polyfills' ;
import { isBlank } from '@ember/utils' ;
2018-07-02 16:38:27 +03:00
import { inject as service } from '@ember/service' ;
2014-03-02 18:30:35 +04:00
2022-01-17 12:34:55 +03:00
export default class PostsRoute extends AuthenticatedRoute {
@ service infinity ;
@ service router ;
2022-08-22 14:03:23 +03:00
@ service feature ;
2017-02-23 21:47:52 +03:00
2022-01-17 12:34:55 +03:00
queryParams = {
2019-08-29 13:10:09 +03:00
type : { refreshModel : true } ,
2020-06-09 14:19:25 +03:00
visibility : { refreshModel : true } ,
2019-08-29 13:10:09 +03:00
author : { refreshModel : true } ,
tag : { refreshModel : true } ,
order : { refreshModel : true }
2022-01-17 12:34:55 +03:00
} ;
2017-03-02 21:35:09 +03:00
2022-01-17 12:34:55 +03:00
modelName = 'post' ;
perPage = 30 ;
2018-01-11 20:43:23 +03:00
2022-01-17 12:34:55 +03:00
constructor ( ) {
super ( ... arguments ) ;
2019-08-29 13:10:09 +03:00
// if we're already on this route and we're transiting _to_ this route
// then the filters are being changed and we shouldn't create a new
// browser history entry
// see https://github.com/TryGhost/Ghost/issues/11057
this . router . on ( 'routeWillChange' , ( transition ) => {
if ( transition . to && ( this . routeName === 'posts' || this . routeName === 'pages' ) ) {
let toThisRoute = transition . to . find ( route => route . name === this . routeName ) ;
if ( transition . from && transition . from . name === this . routeName && toThisRoute ) {
transition . method ( 'replace' ) ;
}
}
} ) ;
2022-01-17 12:34:55 +03:00
}
2019-08-29 13:10:09 +03:00
2017-02-23 21:47:52 +03:00
model ( params ) {
2021-07-08 16:37:31 +03:00
const user = this . session . user ;
let filterParams = { tag : params . tag , visibility : params . visibility } ;
let paginationParams = {
perPageParam : 'limit' ,
totalPagesParam : 'meta.pagination.pages'
} ;
2024-07-29 19:19:28 +03:00
// type filters are actually mapping statuses
2021-07-08 16:37:31 +03:00
assign ( filterParams , this . _getTypeFilters ( params . type ) ) ;
2024-07-29 19:19:28 +03:00
2021-07-08 16:37:31 +03:00
if ( params . type === 'featured' ) {
filterParams . featured = true ;
}
2024-07-29 19:19:28 +03:00
// authors and contributors can only view their own posts
2021-07-08 16:37:31 +03:00
if ( user . isAuthor ) {
filterParams . authors = user . slug ;
} else if ( user . isContributor ) {
filterParams . authors = user . slug ;
2024-07-29 19:19:28 +03:00
// otherwise we need to filter by author if present
2021-07-08 16:37:31 +03:00
} else if ( params . author ) {
filterParams . authors = params . author ;
}
2024-07-29 19:19:28 +03:00
let perPage = this . perPage ;
const filterStatuses = filterParams . status ;
let queryParams = { allFilter : this . _filterString ( { ... filterParams } ) } ; // pass along the parent filter so it's easier to apply the params filter to each infinity model
let models = { } ;
if ( filterStatuses . includes ( 'scheduled' ) ) {
let scheduledInfinityModelParams = { ... queryParams , order : params . order || 'published_at desc' , filter : this . _filterString ( { ... filterParams , status : 'scheduled' } ) } ;
models . scheduledInfinityModel = this . infinity . model ( this . modelName , assign ( { perPage , startingPage : 1 } , paginationParams , scheduledInfinityModelParams ) ) ;
2024-07-18 00:55:47 +03:00
}
2024-07-29 19:19:28 +03:00
if ( filterStatuses . includes ( 'draft' ) ) {
let draftInfinityModelParams = { ... queryParams , order : params . order || 'updated_at desc' , filter : this . _filterString ( { ... filterParams , status : 'draft' } ) } ;
models . draftInfinityModel = this . infinity . model ( this . modelName , assign ( { perPage , startingPage : 1 } , paginationParams , draftInfinityModelParams ) ) ;
}
if ( filterStatuses . includes ( 'published' ) || filterStatuses . includes ( 'sent' ) ) {
let publishedAndSentInfinityModelParams ;
if ( filterStatuses . includes ( 'published' ) && filterStatuses . includes ( 'sent' ) ) {
publishedAndSentInfinityModelParams = { ... queryParams , order : params . order || 'published_at desc' , filter : this . _filterString ( { ... filterParams , status : '[published,sent]' } ) } ;
} else {
publishedAndSentInfinityModelParams = { ... queryParams , order : params . order || 'published_at desc' , filter : this . _filterString ( { ... filterParams , status : filterStatuses . includes ( 'published' ) ? 'published' : 'sent' } ) } ;
}
models . publishedAndSentInfinityModel = this . infinity . model ( this . modelName , assign ( { perPage , startingPage : 1 } , paginationParams , publishedAndSentInfinityModelParams ) ) ;
2021-07-08 16:37:31 +03:00
}
2017-02-23 21:47:52 +03:00
2024-07-29 19:19:28 +03:00
return RSVP . hash ( models ) ;
2022-01-17 12:34:55 +03:00
}
2017-02-23 21:47:52 +03:00
2022-10-07 20:39:34 +03:00
// trigger a background load of all tags and authors for use in filter dropdowns
2023-04-11 16:53:01 +03:00
setupController ( controller , model ) {
2022-01-17 12:34:55 +03:00
super . setupController ( ... arguments ) ;
2018-01-11 20:43:23 +03:00
if ( ! controller . _hasLoadedTags ) {
2019-02-22 06:17:33 +03:00
this . store . query ( 'tag' , { limit : 'all' } ) . then ( ( ) => {
2018-01-11 20:43:23 +03:00
controller . _hasLoadedTags = true ;
} ) ;
}
2021-07-08 16:37:31 +03:00
if ( ! this . session . user . isAuthorOrContributor && ! controller . _hasLoadedAuthors ) {
this . store . query ( 'user' , { limit : 'all' } ) . then ( ( ) => {
controller . _hasLoadedAuthors = true ;
} ) ;
}
2023-04-11 16:53:01 +03:00
if ( controller . selectionList ) {
2023-04-11 17:32:11 +03:00
if ( this . session . user . isAuthorOrContributor ) {
controller . selectionList . enabled = false ;
}
2023-04-11 16:53:01 +03:00
controller . selectionList . infinityModel = model ;
controller . selectionList . clearSelection ( ) ;
}
2022-01-17 12:34:55 +03:00
}
2018-01-11 20:43:23 +03:00
2022-01-17 12:34:55 +03:00
@ action
queryParamsDidChange ( ) {
// scroll back to the top
let contentList = document . querySelector ( '.content-list' ) ;
if ( contentList ) {
contentList . scrollTop = 0 ;
2018-01-11 20:43:23 +03:00
}
2022-01-17 12:34:55 +03:00
super . actions . queryParamsDidChange . call ( this , ... arguments ) ;
}
2018-01-11 20:43:23 +03:00
2019-05-20 18:16:19 +03:00
buildRouteInfoMetadata ( ) {
return {
2022-09-23 18:19:19 +03:00
titleToken : 'Posts'
2019-05-20 18:16:19 +03:00
} ;
2022-01-17 12:34:55 +03:00
}
2019-05-20 18:16:19 +03:00
2024-07-29 19:19:28 +03:00
/ * *
* Returns an object containing the status filter based on the given type .
*
* @ param { string } type - The type of filter to generate ( draft , published , scheduled , sent ) .
* @ returns { Object } - An object containing the status filter .
* /
2018-07-20 13:57:53 +03:00
_getTypeFilters ( type ) {
2021-08-13 16:16:57 +03:00
let status = '[draft,scheduled,published,sent]' ;
2017-02-23 21:47:52 +03:00
switch ( type ) {
case 'draft' :
status = 'draft' ;
break ;
case 'published' :
status = 'published' ;
break ;
case 'scheduled' :
status = 'scheduled' ;
break ;
2021-08-13 16:16:57 +03:00
case 'sent' :
status = 'sent' ;
break ;
2017-02-23 21:47:52 +03:00
}
return {
2019-02-22 06:17:33 +03:00
status
2017-02-23 21:47:52 +03:00
} ;
2022-01-17 12:34:55 +03:00
}
2017-03-02 21:35:09 +03:00
_filterString ( filter ) {
return Object . keys ( filter ) . map ( ( key ) => {
let value = filter [ key ] ;
if ( ! isBlank ( value ) ) {
return ` ${ key } : ${ filter [ key ] } ` ;
}
2022-08-03 14:21:16 +03:00
return undefined ;
2017-03-02 21:35:09 +03:00
} ) . compact ( ) . join ( '+' ) ;
2017-02-23 21:47:52 +03:00
}
2022-01-17 12:34:55 +03:00
}