Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
🎨 Separated post and page list screens
Browse files Browse the repository at this point in the history
no issue
- added `page` model
- removed `page` param from Post model
- added pages screen with associated links
- added `:type` param to editor screens to work with the right models
- removed post<->page toggle and associated tour item
  • Loading branch information
kevinansfield committed Feb 22, 2019
1 parent b18625b commit f3a8d73
Show file tree
Hide file tree
Showing 39 changed files with 561 additions and 239 deletions.
4 changes: 2 additions & 2 deletions app/components/gh-date-time-picker.js
Expand Up @@ -33,7 +33,7 @@ export default Component.extend({
let errors = this.get('errors');
let property = this.get('dateErrorProperty');

if (!isEmpty(errors.errorsFor(property))) {
if (errors && !isEmpty(errors.errorsFor(property))) {
return errors.errorsFor(property).get('firstObject').message;
}
}),
Expand All @@ -42,7 +42,7 @@ export default Component.extend({
let errors = this.get('errors');
let property = this.get('timeErrorProperty');

if (!isEmpty(errors.errorsFor(property))) {
if (errors && !isEmpty(errors.errorsFor(property))) {
return errors.errorsFor(property).get('firstObject').message;
}
}),
Expand Down
15 changes: 0 additions & 15 deletions app/components/gh-post-settings-menu.js
Expand Up @@ -137,21 +137,6 @@ export default Component.extend(SettingsMenuMixin, {
return false;
},

togglePage() {
this.toggleProperty('post.page');

// If this is a new post. Don't save the post. Defer the save
// to the user pressing the save button
if (this.get('post.isNew')) {
return;
}

this.get('savePost').perform().catch((error) => {
this.showError(error);
this.get('post').rollbackAttributes();
});
},

toggleFeatured() {
this.toggleProperty('post.featured');

Expand Down
2 changes: 1 addition & 1 deletion app/components/gh-psm-template-select.js
Expand Up @@ -31,7 +31,7 @@ export default Component.extend({

matchedSlugTemplate: computed('post.{page,slug}', 'activeTheme.slugTemplates.[]', function () {
let slug = this.get('post.slug');
let type = this.get('post.page') ? 'page' : 'post';
let type = this.post.constructor.modelName;

let [matchedTemplate] = this.get('activeTheme.slugTemplates').filter(function (template) {
return template.for.includes(type) && template.slug === slug;
Expand Down
35 changes: 29 additions & 6 deletions app/components/gh-search-input.js
Expand Up @@ -33,7 +33,7 @@ export default Component.extend({
currentSearch: '',
selection: null,

posts: computedGroup('Stories'),
posts: computedGroup('Posts'),
pages: computedGroup('Pages'),
users: computedGroup('Users'),
tags: computedGroup('Tags'),
Expand All @@ -42,7 +42,7 @@ export default Component.extend({
let groups = [];

if (!isEmpty(this.get('posts'))) {
groups.pushObject({groupName: 'Stories', options: this.get('posts')});
groups.pushObject({groupName: 'Posts', options: this.get('posts')});
}

if (!isEmpty(this.get('pages'))) {
Expand Down Expand Up @@ -71,9 +71,14 @@ export default Component.extend({
return;
}

if (selected.category === 'Stories' || selected.category === 'Pages') {
if (selected.category === 'Posts') {
let id = selected.id.replace('post.', '');
this.get('router').transitionTo('editor.edit', id);
this.get('router').transitionTo('editor.edit', 'post', id);
}

if (selected.category === 'Pages') {
let id = selected.id.replace('page.', '');
this.get('router').transitionTo('editor.edit', 'page', id);
}

if (selected.category === 'Users') {
Expand Down Expand Up @@ -132,6 +137,7 @@ export default Component.extend({

this.set('content', []);
promises.pushObject(this._loadPosts());
promises.pushObject(this._loadPages());
promises.pushObject(this._loadUsers());
promises.pushObject(this._loadTags());

Expand All @@ -149,14 +155,31 @@ export default Component.extend({
_loadPosts() {
let store = this.get('store');
let postsUrl = `${store.adapterFor('post').urlForQuery({}, 'post')}/`;
let postsQuery = {fields: 'id,title,page', limit: 'all', status: 'all', filter: 'page:[true,false]'};
let postsQuery = {fields: 'id,title,page', limit: 'all', status: 'all'};
let content = this.get('content');

return this.get('ajax').request(postsUrl, {data: postsQuery}).then((posts) => {
content.pushObjects(posts.posts.map(post => ({
id: `post.${post.id}`,
title: post.title,
category: post.page ? 'Pages' : 'Stories'
category: 'Posts'
})));
}).catch((error) => {
this.get('notifications').showAPIError(error, {key: 'search.loadPosts.error'});
});
},

_loadPages() {
let store = this.get('store');
let pagesUrl = `${store.adapterFor('page').urlForQuery({}, 'page')}/`;
let pagesQuery = {fields: 'id,title,page', limit: 'all', status: 'all'};
let content = this.get('content');

return this.get('ajax').request(pagesUrl, {data: pagesQuery}).then((pages) => {
content.pushObjects(pages.pages.map(page => ({
id: `page.${page.id}`,
title: page.title,
category: 'Pages'
})));
}).catch((error) => {
this.get('notifications').showAPIError(error, {key: 'search.loadPosts.error'});
Expand Down
7 changes: 7 additions & 0 deletions app/controllers/pages-loading.js
@@ -0,0 +1,7 @@
import PostsLoadingController from './posts-loading';
import {inject as controller} from '@ember/controller';

/* eslint-disable ghost/ember/alias-model-in-controller */
export default PostsLoadingController.extend({
postsController: controller('pages')
});
44 changes: 44 additions & 0 deletions app/controllers/pages.js
@@ -0,0 +1,44 @@
import PostsController from './posts';

const TYPES = [{
name: 'All pages',
value: null
}, {
name: 'Draft pages',
value: 'draft'
}, {
name: 'Published pages',
value: 'published'
}, {
name: 'Scheduled pages',
value: 'scheduled'
}, {
name: 'Featured pages',
value: 'featured'
}];

const ORDERS = [{
name: 'Newest',
value: null
}, {
name: 'Oldest',
value: 'published_at asc'
}, {
name: 'Recently updated',
value: 'updated_at desc'
}];

/* eslint-disable ghost/ember/alias-model-in-controller */
export default PostsController.extend({
init() {
this._super(...arguments);
this.availableTypes = TYPES;
this.availableOrders = ORDERS;
},

actions: {
openEditor(page) {
this.transitionToRoute('editor.edit', 'page', page.get('id'));
}
}
});
2 changes: 1 addition & 1 deletion app/controllers/posts-loading.js
@@ -1,8 +1,8 @@
/* eslint-disable ghost/ember/alias-model-in-controller */
import Controller, {inject as controller} from '@ember/controller';
import {readOnly} from '@ember/object/computed';
import {inject as service} from '@ember/service';

/* eslint-disable ghost/ember/alias-model-in-controller */
export default Controller.extend({

postsController: controller('posts'),
Expand Down
5 changes: 1 addition & 4 deletions app/controllers/posts.js
Expand Up @@ -19,9 +19,6 @@ const TYPES = [{
}, {
name: 'Featured posts',
value: 'featured'
}, {
name: 'Pages',
value: 'page'
}];

const ORDERS = [{
Expand Down Expand Up @@ -137,7 +134,7 @@ export default Controller.extend({
},

openEditor(post) {
this.transitionToRoute('editor.edit', post.get('id'));
this.transitionToRoute('editor.edit', 'post', post.get('id'));
}
}
});
5 changes: 5 additions & 0 deletions app/models/page.js
@@ -0,0 +1,5 @@
import PostModel from './post';

export default PostModel.extend({
displayName: 'page'
});
2 changes: 1 addition & 1 deletion app/models/post.js
Expand Up @@ -72,6 +72,7 @@ export default Model.extend(Comparable, ValidationEngine, {
clock: service(),
settings: service(),

displayName: 'post',
validationType: 'post',

createdAtUTC: attr('moment-utc'),
Expand All @@ -92,7 +93,6 @@ export default Model.extend(Comparable, ValidationEngine, {
metaDescription: attr('string'),
metaTitle: attr('string'),
mobiledoc: attr('json-string'),
page: attr('boolean', {defaultValue: false}),
plaintext: attr('string'),
publishedAtUTC: attr('moment-utc'),
slug: attr('string'),
Expand Down
5 changes: 3 additions & 2 deletions app/router.js
Expand Up @@ -32,10 +32,11 @@ Router.map(function () {
this.route('about', {path: '/about'});

this.route('posts', {path: '/'}, function () {});
this.route('pages', {path: '/pages'}, function () {});

this.route('editor', function () {
this.route('new', {path: ''});
this.route('edit', {path: ':post_id'});
this.route('new', {path: ':type'});
this.route('edit', {path: ':type/:post_id'});
});

this.route('team', {path: '/team'}, function () {
Expand Down
17 changes: 13 additions & 4 deletions app/routes/editor/edit.js
@@ -1,4 +1,5 @@
import AuthenticatedRoute from 'ghost-admin/routes/authenticated';
import {pluralize} from 'ember-inflector';

export default AuthenticatedRoute.extend({
beforeModel(transition) {
Expand All @@ -17,11 +18,10 @@ export default AuthenticatedRoute.extend({
let query = {
id: params.post_id,
status: 'all',
filter: 'page:[true,false]',
formats: 'mobiledoc,plaintext'
};

return this.store.query('post', query)
return this.store.query(params.type, query)
.then(records => records.get('firstObject'));
},

Expand All @@ -32,17 +32,26 @@ export default AuthenticatedRoute.extend({
this._super(...arguments);

return this.get('session.user').then((user) => {
let returnRoute = `${pluralize(post.constructor.modelName)}.index`;

if (user.get('isAuthorOrContributor') && !post.isAuthoredByUser(user)) {
return this.replaceWith('posts.index');
return this.replaceWith(returnRoute);
}

// If the post is not a draft and user is contributor, redirect to index
if (user.get('isContributor') && !post.get('isDraft')) {
return this.replaceWith('posts.index');
return this.replaceWith(returnRoute);
}
});
},

serialize(model) {
return {
type: model.constructor.modelName,
post_id: model.id
};
},

// there's no specific controller for this route, instead all editor
// handling is done on the editor route/controler
setupController(controller, post) {
Expand Down
8 changes: 8 additions & 0 deletions app/routes/editor/index.js
@@ -0,0 +1,8 @@
import AuthenticatedRoute from 'ghost-admin/routes/authenticated';

export default AuthenticatedRoute.extend({
beforeModel() {
this._super(...arguments);
this.replaceWith('editor.new', 'post');
}
});
4 changes: 2 additions & 2 deletions app/routes/editor/new.js
@@ -1,9 +1,9 @@
import AuthenticatedRoute from 'ghost-admin/routes/authenticated';

export default AuthenticatedRoute.extend({
model() {
model(params) {
return this.get('session.user').then(user => (
this.store.createRecord('post', {authors: [user]})
this.store.createRecord(params.type, {authors: [user]})
));
},

Expand Down
6 changes: 6 additions & 0 deletions app/routes/pages.js
@@ -0,0 +1,6 @@
import PostsRoute from './posts';

export default PostsRoute.extend({
titleToken: 'Pages',
modelName: 'page'
});

0 comments on commit f3a8d73

Please sign in to comment.