mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Wired up saving of custom theme settings
refs https://github.com/TryGhost/Team/issues/1070 - split select form component into it's own component so it's cleaner when we get to additional setting types - added change handler that updates the setting record's value when a new option is selected - added `.isDirty` to the custom-theme-settings service so we can warn of unsaved changes and revert any changed values when needed - added save of custom theme settings to the customize design modal's save routine - added missing `notifications` service import to customize design controller
This commit is contained in:
parent
1e8e0485e3
commit
d10e102de4
6 changed files with 58 additions and 24 deletions
16
ghost/admin/app/components/custom-theme-settings/select.hbs
Normal file
16
ghost/admin/app/components/custom-theme-settings/select.hbs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<div class="gh-stack-item {{if (eq @index 0) "gh-setting-first"}}">
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<label class="gh-setting-title gh-theme-setting-title" for={{this.selectId}}>
|
||||||
|
{{humanize @setting.key}}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<select class="ember-select" name={{this.selectName}} id={{this.selectId}} {{on "change" this.setSelection}}>
|
||||||
|
{{#each @setting.options as |settingOption|}}
|
||||||
|
<option value={{settingOption}} selected={{eq settingOption @setting.value}}>
|
||||||
|
{{settingOption}}
|
||||||
|
{{#if (eq settingOption setting.default)}}(default){{/if}}
|
||||||
|
</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
15
ghost/admin/app/components/custom-theme-settings/select.js
Normal file
15
ghost/admin/app/components/custom-theme-settings/select.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import Component from '@glimmer/component';
|
||||||
|
import {action} from '@ember/object';
|
||||||
|
import {camelize} from '@ember/string';
|
||||||
|
import {guidFor} from '@ember/object/internals';
|
||||||
|
|
||||||
|
export default class CustomThemeSettingsSelectComponent extends Component {
|
||||||
|
selectId = `select-${guidFor(this)}`;
|
||||||
|
selectName = camelize(this.args.setting.key);
|
||||||
|
|
||||||
|
@action
|
||||||
|
setSelection(changeEvent) {
|
||||||
|
const value = changeEvent.target.value;
|
||||||
|
this.args.setting.set('value', value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +1,9 @@
|
||||||
<div class="gh-stack">
|
<div class="gh-stack">
|
||||||
|
<form>
|
||||||
{{#each @themeSettings as |setting index|}}
|
{{#each @themeSettings as |setting index|}}
|
||||||
{{#if (eq setting.type "select")}}
|
{{#if (eq setting.type "select")}}
|
||||||
<div class="gh-stack-item gh-setting-first">
|
<CustomThemeSettings::Select @setting={{setting}} @index={{index}} />
|
||||||
<div class="flex-grow-1">
|
|
||||||
<div class="gh-setting-title gh-theme-setting-title">
|
|
||||||
{{humanize setting.key}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<select class="ember-select">
|
|
||||||
{{#each setting.options as |settingOption|}}
|
|
||||||
<option value={{option}} selected={{eq settingOption setting.value}}>
|
|
||||||
{{settingOption}}
|
|
||||||
{{#if (eq settingOption setting.default)}}(default){{/if}}
|
|
||||||
</option>
|
|
||||||
{{/each}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
|
@ -3,8 +3,10 @@ import {inject as service} from '@ember/service';
|
||||||
import {task} from 'ember-concurrency-decorators';
|
import {task} from 'ember-concurrency-decorators';
|
||||||
|
|
||||||
export default class SettingsDesignCustomizeController extends Controller {
|
export default class SettingsDesignCustomizeController extends Controller {
|
||||||
@service settings;
|
@service customThemeSettings;
|
||||||
|
@service notifications;
|
||||||
@service router;
|
@service router;
|
||||||
|
@service settings;
|
||||||
|
|
||||||
@task
|
@task
|
||||||
*saveTask() {
|
*saveTask() {
|
||||||
|
@ -12,8 +14,15 @@ export default class SettingsDesignCustomizeController extends Controller {
|
||||||
if (this.settings.get('errors').length !== 0) {
|
if (this.settings.get('errors').length !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
yield this.settings.save();
|
|
||||||
|
yield Promise.all(
|
||||||
|
this.settings.save(),
|
||||||
|
this.customThemeSettings.save()
|
||||||
|
);
|
||||||
|
|
||||||
this.router.transitionTo('settings.design');
|
this.router.transitionTo('settings.design');
|
||||||
|
|
||||||
|
// ensure task button switches to success state
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {bind} from '@ember/runloop';
|
||||||
import {inject as service} from '@ember/service';
|
import {inject as service} from '@ember/service';
|
||||||
|
|
||||||
export default class SettingsDesignCustomizeRoute extends AuthenticatedRoute {
|
export default class SettingsDesignCustomizeRoute extends AuthenticatedRoute {
|
||||||
|
@service customThemeSettings;
|
||||||
@service feature;
|
@service feature;
|
||||||
@service modals;
|
@service modals;
|
||||||
@service settings;
|
@service settings;
|
||||||
|
@ -35,7 +36,7 @@ export default class SettingsDesignCustomizeRoute extends AuthenticatedRoute {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async willTransition(transition) {
|
async willTransition(transition) {
|
||||||
if (this.settings.get('hasDirtyAttributes')) {
|
if (this.settings.get('hasDirtyAttributes') || this.customThemeSettings.isDirty) {
|
||||||
transition.abort();
|
transition.abort();
|
||||||
|
|
||||||
const shouldLeave = await this.confirmUnsavedChanges();
|
const shouldLeave = await this.confirmUnsavedChanges();
|
||||||
|
@ -73,7 +74,7 @@ export default class SettingsDesignCustomizeRoute extends AuthenticatedRoute {
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmUnsavedChanges() {
|
confirmUnsavedChanges() {
|
||||||
if (!this.settings.get('hasDirtyAttributes')) {
|
if (!this.settings.get('hasDirtyAttributes') && !this.customThemeSettings.isDirty) {
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +84,7 @@ export default class SettingsDesignCustomizeRoute extends AuthenticatedRoute {
|
||||||
}).then((discardChanges) => {
|
}).then((discardChanges) => {
|
||||||
if (discardChanges === true) {
|
if (discardChanges === true) {
|
||||||
this.settings.rollbackAttributes();
|
this.settings.rollbackAttributes();
|
||||||
|
this.customThemeSettings.rollback();
|
||||||
}
|
}
|
||||||
return discardChanges;
|
return discardChanges;
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
|
|
|
@ -9,6 +9,11 @@ export default class CustomThemeSettingsServices extends Service {
|
||||||
|
|
||||||
@tracked settings = [];
|
@tracked settings = [];
|
||||||
|
|
||||||
|
get isDirty() {
|
||||||
|
const dirtySetting = this.settings.find(setting => setting.hasDirtyAttributes);
|
||||||
|
return !!dirtySetting;
|
||||||
|
}
|
||||||
|
|
||||||
load() {
|
load() {
|
||||||
return this.loadTask.perform();
|
return this.loadTask.perform();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue