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

Commit

Permalink
fetch themes from /themes endpoint (#542)
Browse files Browse the repository at this point in the history
refs TryGhost/Ghost#8022

- use `/themes` API endpoint to fetch list of themes instead of `settings[0].availableThemes`
  • Loading branch information
kevinansfield authored and ErisDS committed Feb 21, 2017
1 parent 5674498 commit c43974c
Show file tree
Hide file tree
Showing 18 changed files with 88 additions and 87 deletions.
18 changes: 11 additions & 7 deletions app/components/gh-theme-table.js
@@ -1,18 +1,22 @@
import Component from 'ember-component';
import computed from 'ember-computed';
import get from 'ember-metal/get';

export default Component.extend({

availableThemes: null,
themes: null,
activeTheme: null,

themes: computed('availableThemes', function () {
let themes = this.get('availableThemes').map((t) => {
sortedThemes: computed('themes.[]', 'activeTheme', function () {
let activeTheme = get(this, 'activeTheme');
let themes = get(this, 'themes').map((t) => {
let theme = {};
let themePackage = get(t, 'package');

theme.name = t.name;
theme.label = t.package ? `${t.package.name} - ${t.package.version}` : t.name;
theme.package = t.package;
theme.active = !!t.active;
theme.name = get(t, 'name');
theme.label = themePackage ? `${themePackage.name} - ${themePackage.version}` : theme.name;
theme.package = themePackage;
theme.active = theme.name === activeTheme;
theme.isDeletable = !theme.active;

return theme;
Expand Down
9 changes: 5 additions & 4 deletions app/components/modals/upload-theme.js
Expand Up @@ -14,7 +14,7 @@ export default ModalComponent.extend({

accept: ['application/zip', 'application/x-zip-compressed'],
extensions: ['zip'],
availableThemes: null,
themes: null,
closeDisabled: false,
file: null,
theme: false,
Expand All @@ -34,7 +34,7 @@ export default ModalComponent.extend({
return t.package ? `${t.package.name} - ${t.package.version}` : t.name;
}),

availableThemeNames: mapBy('model.availableThemes', 'name'),
currentThemeNames: mapBy('model.themes', 'name'),

fileThemeName: computed('file', function () {
let file = this.get('file');
Expand All @@ -43,14 +43,15 @@ export default ModalComponent.extend({

canActivateTheme: computed('theme', function () {
let theme = this.get('theme');
// TODO: do we still get theme.active back or do we need to check settings.activeTheme?
return theme && !theme.active;
}),

actions: {
validateTheme(file) {
let themeName = file.name.replace(/\.zip$/, '').replace(/[^\w@.]/gi, '-');

let availableThemeNames = this.get('availableThemeNames');
let currentThemeNames = this.get('currentThemeNames');

this.set('file', file);

Expand All @@ -65,7 +66,7 @@ export default ModalComponent.extend({
return {errors: [{message: 'Sorry, the default Casper theme cannot be overwritten.<br>Please rename your zip file and try again.'}]};
}

if (!this._allowOverwrite && availableThemeNames.includes(themeName)) {
if (!this._allowOverwrite && currentThemeNames.includes(themeName)) {
this.set('displayOverwriteWarning', true);
return false;
}
Expand Down
8 changes: 3 additions & 5 deletions app/controllers/settings/general.js
Expand Up @@ -9,6 +9,7 @@ import $ from 'jquery';

export default Controller.extend(SettingsSaveMixin, {

themes: null,
availableTimezones: null,
themeToDelete: null,

Expand Down Expand Up @@ -51,16 +52,13 @@ export default Controller.extend(SettingsSaveMixin, {
}),

_deleteTheme() {
let theme = this.get('themeToDelete');
let themeURL = `${this.get('ghostPaths.apiRoot')}/themes/${theme.name}/`;
let theme = this.get('store').peekRecord('theme', this.get('themeToDelete').name);

if (!theme) {
return;
}

return this.get('ajax').del(themeURL).then(() => {
this.send('reloadSettings');
}).catch((error) => {
return theme.destroyRecord().catch((error) => {
this.get('notifications').showAPIError(error);
});
},
Expand Down
1 change: 0 additions & 1 deletion app/models/setting.js
Expand Up @@ -16,7 +16,6 @@ export default Model.extend(ValidationEngine, {
forceI18n: attr('boolean'),
permalinks: attr('string'),
activeTheme: attr('string'),
availableThemes: attr(),
activeTimezone: attr('string', {defaultValue: 'Etc/UTC'}),
ghost_head: attr('string'),
ghost_foot: attr('string'),
Expand Down
7 changes: 7 additions & 0 deletions app/models/theme.js
@@ -0,0 +1,7 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';

export default Model.extend({
name: attr('string'),
package: attr('raw')
});
8 changes: 7 additions & 1 deletion app/routes/settings/general.js
Expand Up @@ -26,12 +26,14 @@ export default AuthenticatedRoute.extend(styleBody, CurrentUserSettings, {
model() {
return RSVP.hash({
settings: this.querySettings(),
themes: this.get('store').findAll('theme'),
availableTimezones: this.get('config.availableTimezones')
});
},

setupController(controller, models) {
controller.set('model', models.settings);
controller.set('themes', this.get('store').peekAll('theme'));
controller.set('availableTimezones', models.availableTimezones);
},

Expand All @@ -42,10 +44,14 @@ export default AuthenticatedRoute.extend(styleBody, CurrentUserSettings, {

reloadSettings() {
return this.querySettings((settings) => {
this.set('controller.model', settings);
this.get('controller').set('model', settings);
});
},

reloadThemes() {
return this.get('store').findAll('theme');
},

activateTheme(theme) {
return this.get('controller').send('setTheme', theme);
}
Expand Down
2 changes: 1 addition & 1 deletion app/routes/settings/general/uploadtheme.js
Expand Up @@ -3,7 +3,7 @@ import AuthenticatedRoute from 'ghost-admin/routes/authenticated';
export default AuthenticatedRoute.extend({

model() {
return this.modelFor('settings.general').settings.get('availableThemes');
return this.get('store').findAll('theme');
},

actions: {
Expand Down
5 changes: 5 additions & 0 deletions app/serializers/theme.js
@@ -0,0 +1,5 @@
import ApplicationSerializer from './application';

export default ApplicationSerializer.extend({
primaryKey: 'name'
});
4 changes: 2 additions & 2 deletions app/templates/components/gh-theme-table.hbs
@@ -1,6 +1,6 @@
{{#if themes}}
{{#if sortedThemes}}
<div class="theme-list">
{{#each themes as |theme|}}
{{#each sortedThemes as |theme|}}
<div class="theme-list-item {{if theme.active "theme-list-item--active"}}">
<div class="theme-list-item-body">
<span class="name">{{theme.label}}</span>
Expand Down
3 changes: 2 additions & 1 deletion app/templates/settings/general.hbs
Expand Up @@ -175,7 +175,8 @@
<h3 id="themes">Themes</h3>

{{gh-theme-table
availableThemes=model.availableThemes
themes=themes
activeTheme=model.activeTheme
activateTheme=(action "setTheme")
downloadTheme=(action "downloadTheme")
deleteTheme=(action "deleteTheme")}}
Expand Down
4 changes: 2 additions & 2 deletions app/templates/settings/general/uploadtheme.hbs
@@ -1,7 +1,7 @@
{{gh-fullscreen-modal "upload-theme"
model=(hash
availableThemes=model
uploadSuccess=(route-action 'reloadSettings')
themes=model
uploadSuccess=(route-action 'reloadThemes')
activate=(route-action 'activateTheme')
)
close=(route-action "cancel")
Expand Down
13 changes: 0 additions & 13 deletions mirage/config/settings.js
Expand Up @@ -32,19 +32,6 @@ export default function mockSettings(server) {
db.settings.update({key}, newSetting);
});

let [activeTheme] = db.settings.where({key: 'activeTheme'});
let [availableThemes] = db.settings.where({key: 'availableThemes'});

availableThemes.value.forEach((theme) => {
if (theme.name === activeTheme.value) {
theme.active = true;
} else {
theme.active = false;
}
});

db.settings.update({key: 'availableThemes'}, availableThemes);

return {
meta: {},
settings: db.settings
Expand Down
21 changes: 7 additions & 14 deletions mirage/config/themes.js
Expand Up @@ -3,37 +3,30 @@ import {Response} from 'ember-cli-mirage';
let themeCount = 1;

export default function mockThemes(server) {
server.post('/themes/upload/', function ({db}) {
let [availableThemes] = db.settings.where({key: 'availableThemes'});
server.get('/themes');

server.post('/themes/upload/', function ({themes}) {
// pretender/mirage doesn't currently process FormData so we can't use
// any info passed in through the request
let theme = {
name: `test-${themeCount}`,
package: {
name: `Test ${themeCount}`,
version: '0.1'
},
active: false
}
};

themeCount++;

availableThemes.value.pushObject(theme);
db.settings.update({key: 'availableThemes'}, availableThemes);
theme = themes.create(theme);

return {
themes: [theme]
};
});

server.del('/themes/:theme/', function ({db}, {params}) {
let [availableThemes] = db.settings.where({key: 'availableThemes'});

availableThemes.value = availableThemes.value.filter((theme) => {
return theme.name !== params.theme;
});

db.settings.update({key: 'availableThemes'}, availableThemes);
server.del('/themes/:theme/', function ({themes}, {params}) {
themes.findBy({name: params.theme}).destroy();

return new Response(204, {}, null);
});
Expand Down
25 changes: 0 additions & 25 deletions mirage/fixtures/settings.js
Expand Up @@ -193,31 +193,6 @@ export default [
updated_by: 1,
value: 'Etc/UTC'
},
{
id: 20,
key: 'availableThemes',
value: [
{
name: 'casper',
package: {
name: 'Blog',
version: '1.0'
},
active: true
},
{
name: 'foo',
package: {
name: 'Foo',
version: '0.1'
}
},
{
name: 'bar'
}
],
type: 'theme'
},
{
id: 21,
created_at: '2017-01-09T08:40:59.000Z',
Expand Down
19 changes: 19 additions & 0 deletions mirage/fixtures/themes.js
@@ -0,0 +1,19 @@
export default [
{
name: 'casper',
package: {
name: 'Blog',
version: '1.0'
}
},
{
name: 'foo',
package: {
name: 'Foo',
version: '0.1'
}
},
{
name: 'bar'
}
];
4 changes: 4 additions & 0 deletions mirage/models/theme.js
@@ -0,0 +1,4 @@
import {Model} from 'ember-cli-mirage';

export default Model.extend({
});
1 change: 1 addition & 0 deletions tests/acceptance/settings/general-test.js
Expand Up @@ -380,6 +380,7 @@ describe('Acceptance: Settings - General', function () {
// - displays modal
// - deletes theme and refreshes list

server.loadFixtures('themes');
visit('/settings/general');

// lists available themes (themes are specified in mirage/fixtures/settings)
Expand Down

0 comments on commit c43974c

Please sign in to comment.