AMP app integration (#483)

refs TryGhost/Ghost#7769
- adds Google AMP to `apps` in order to disable and enable it on request.
This commit is contained in:
Aileen Nowak 2017-01-20 16:33:54 +07:00 committed by Kevin Ansfield
parent 928aa46de8
commit 683dbaa376
11 changed files with 150 additions and 8 deletions

View File

@ -0,0 +1,37 @@
import Controller from 'ember-controller';
import injectService from 'ember-service/inject';
export default Controller.extend({
notifications: injectService(),
// will be set by route
settings: null,
isSaving: false,
actions: {
update(value) {
this.set('model', value);
},
save() {
let amp = this.get('model');
let settings = this.get('settings');
if (this.get('isSaving')) {
return;
}
settings.set('amp', amp);
this.set('isSaving', true);
return settings.save().catch((err) => {
this.get('notifications').showAPIError(err);
throw err;
}).finally(() => {
this.set('isSaving', false);
});
}
}
});

View File

@ -5,5 +5,6 @@ import {alias} from 'ember-computed';
export default Controller.extend({ export default Controller.extend({
appsController: injectController('settings.apps'), appsController: injectController('settings.apps'),
slack: alias('appsController.model.slack.firstObject') slack: alias('appsController.model.slack.firstObject'),
amp: alias('appsController.model.amp')
}); });

View File

@ -25,5 +25,6 @@ export default Model.extend(ValidationEngine, {
navigation: attr('navigation-settings'), navigation: attr('navigation-settings'),
isPrivate: attr('boolean'), isPrivate: attr('boolean'),
password: attr('string'), password: attr('string'),
slack: attr('slack-settings') slack: attr('slack-settings'),
amp: attr('boolean')
}); });

View File

@ -56,9 +56,10 @@ GhostRouter.map(function () {
this.route('settings.navigation', {path: '/settings/navigation'}); this.route('settings.navigation', {path: '/settings/navigation'});
this.route('settings.apps', {path: '/settings/apps'}, function () { this.route('settings.apps', {path: '/settings/apps'}, function () {
this.route('slack', {path: 'slack'}); this.route('slack', {path: 'slack'});
this.route('amp', {path: 'amp'});
}); });
this.route('subscribers', function() { this.route('subscribers', function () {
this.route('new'); this.route('new');
this.route('import'); this.route('import');
}); });

View File

@ -0,0 +1,19 @@
import AuthenticatedRoute from 'ghost-admin/routes/authenticated';
import CurrentUserSettings from 'ghost-admin/mixins/current-user-settings';
import styleBody from 'ghost-admin/mixins/style-body';
export default AuthenticatedRoute.extend(styleBody, CurrentUserSettings, {
titleToken: 'Settings - Apps - AMP',
classNames: ['settings-view-apps-amp'],
model() {
return this.modelFor('settings.apps').get('amp');
},
setupController(controller) {
this._super(...arguments);
controller.set('settings', this.modelFor('settings.apps'));
}
});

View File

@ -54,6 +54,10 @@
transition: background 0.3s ease; transition: background 0.3s ease;
} }
.apps-card-app:not(last-child) {
border-bottom: rgba(0,0,0,0.1) 1px solid;
}
.apps-card-app:first-of-type { .apps-card-app:first-of-type {
border-top: none; border-top: none;
} }

View File

@ -0,0 +1,35 @@
<header class="view-header">
{{#gh-view-title openMobileMenu="openMobileMenu"}}<span style="padding-left:1px">{{#link-to "settings.apps.index"}}Apps{{/link-to}} <i class="icon-arrow-right" style="display:inline"></i> AMP</span>{{/gh-view-title}}
<section class="view-actions">
{{#gh-spin-button id="saveSlackIntegration" class="btn btn-green" action=(action "save") submitting=isSaving}}
Save
{{/gh-spin-button}}
</section>
</header>
<section class="view-container">
<section class="view-content">
<section class="app-grid">
<div class="app-cell">
<img class="app-icon" src="{{gh-path 'asset' '/img/ampicon.png'}}" />
</div>
<div class="app-cell">
<h3>AMP</h3>
<p>Accelerated Mobile Pages</p>
</div>
</section>
<section class="app-subtitle">
<p>Enable <a href="https://ampproject.org">Google Accelerated Mobile Pages </a>for your site?</p>
</section>
<form class="app-config-form" id="amp-settings" novalidate="novalidate">
<div class="form-group for-checkbox">
<label for="amp">AMP support for your publications</label>
<label class="checkbox" for="amp">
{{one-way-checkbox model id="amp" name="amp" type="checkbox" update=(action "update")}}
<span class="input-toggle-component"></span>
<p>Enable AMP support</p>
</label>
</div>
</form>
</section>
</section>

View File

@ -27,6 +27,28 @@
</article> </article>
{{/link-to}} {{/link-to}}
</div> </div>
<div class="apps-grid-cell">
{{#link-to "settings.apps.amp" id="amp-link"}}
<article class="apps-card-app">
<div class="apps-card-content">
<figure class="apps-card-app-icon" style="background-image:url({{gh-path 'asset' '/img/ampicon.png'}})"></figure>
<div class="apps-card-meta">
<h3 class="apps-card-app-title">AMP</h3>
<p class="apps-card-app-desc">Google Accelerated Mobile Pages</p>
</div>
<div class="apps-configured">
{{#if amp}}
<span class="green">Active</span>
{{else}}
<span>Configure</span>
{{/if}}
<i class="icon-arrow-right"></i>
</div>
</div>
</article>
{{/link-to}}
</div>
</div> </div>
<p class="apps-grid-note">(More coming soon!)</p> <p class="apps-grid-note">(More coming soon!)</p>
</section> </section>

View File

@ -217,5 +217,15 @@ export default [
} }
], ],
type: 'theme' type: 'theme'
},
{
id: 21,
created_at: '2017-01-09T08:40:59.000Z',
created_by: 1,
key: 'amp',
type: 'blog',
updated_at: '2017-01-09T08:49:42.991Z',
updated_by: 1,
value: 'true'
} }
]; ];

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -13,11 +13,11 @@ import {invalidateSession, authenticateSession} from 'ghost-admin/tests/helpers/
describe('Acceptance: Settings - Apps', function () { describe('Acceptance: Settings - Apps', function () {
let application; let application;
beforeEach(function() { beforeEach(function () {
application = startApp(); application = startApp();
}); });
afterEach(function() { afterEach(function () {
destroyApp(application); destroyApp(application);
}); });
@ -25,7 +25,7 @@ describe('Acceptance: Settings - Apps', function () {
invalidateSession(application); invalidateSession(application);
visit('/settings/apps'); visit('/settings/apps');
andThen(function() { andThen(function () {
expect(currentURL(), 'currentURL').to.equal('/signin'); expect(currentURL(), 'currentURL').to.equal('/signin');
}); });
}); });
@ -68,7 +68,6 @@ describe('Acceptance: Settings - Apps', function () {
andThen(() => { andThen(() => {
// has correct url // has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/apps'); expect(currentURL(), 'currentURL').to.equal('/settings/apps');
}); });
click('#slack-link'); click('#slack-link');
@ -77,8 +76,21 @@ describe('Acceptance: Settings - Apps', function () {
// has correct url // has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/apps/slack'); expect(currentURL(), 'currentURL').to.equal('/settings/apps/slack');
}); });
}); });
it('it redirects to AMP when clicking on the grid', function () {
visit('/settings/apps');
andThen(() => {
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/apps');
});
click('#amp-link');
andThen(() => {
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/apps/amp');
});
});
}); });
}); });