mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-29 13:52:10 +03: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
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">
|
||||
{{#each @themeSettings as |setting index|}}
|
||||
{{#if (eq setting.type "select")}}
|
||||
<div class="gh-stack-item gh-setting-first">
|
||||
<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}}
|
||||
{{/each}}
|
||||
<form>
|
||||
{{#each @themeSettings as |setting index|}}
|
||||
{{#if (eq setting.type "select")}}
|
||||
<CustomThemeSettings::Select @setting={{setting}} @index={{index}} />
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</form>
|
||||
</div>
|
@ -3,8 +3,10 @@ import {inject as service} from '@ember/service';
|
||||
import {task} from 'ember-concurrency-decorators';
|
||||
|
||||
export default class SettingsDesignCustomizeController extends Controller {
|
||||
@service settings;
|
||||
@service customThemeSettings;
|
||||
@service notifications;
|
||||
@service router;
|
||||
@service settings;
|
||||
|
||||
@task
|
||||
*saveTask() {
|
||||
@ -12,8 +14,15 @@ export default class SettingsDesignCustomizeController extends Controller {
|
||||
if (this.settings.get('errors').length !== 0) {
|
||||
return;
|
||||
}
|
||||
yield this.settings.save();
|
||||
|
||||
yield Promise.all(
|
||||
this.settings.save(),
|
||||
this.customThemeSettings.save()
|
||||
);
|
||||
|
||||
this.router.transitionTo('settings.design');
|
||||
|
||||
// ensure task button switches to success state
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error) {
|
||||
|
@ -4,6 +4,7 @@ import {bind} from '@ember/runloop';
|
||||
import {inject as service} from '@ember/service';
|
||||
|
||||
export default class SettingsDesignCustomizeRoute extends AuthenticatedRoute {
|
||||
@service customThemeSettings;
|
||||
@service feature;
|
||||
@service modals;
|
||||
@service settings;
|
||||
@ -35,7 +36,7 @@ export default class SettingsDesignCustomizeRoute extends AuthenticatedRoute {
|
||||
|
||||
@action
|
||||
async willTransition(transition) {
|
||||
if (this.settings.get('hasDirtyAttributes')) {
|
||||
if (this.settings.get('hasDirtyAttributes') || this.customThemeSettings.isDirty) {
|
||||
transition.abort();
|
||||
|
||||
const shouldLeave = await this.confirmUnsavedChanges();
|
||||
@ -73,7 +74,7 @@ export default class SettingsDesignCustomizeRoute extends AuthenticatedRoute {
|
||||
}
|
||||
|
||||
confirmUnsavedChanges() {
|
||||
if (!this.settings.get('hasDirtyAttributes')) {
|
||||
if (!this.settings.get('hasDirtyAttributes') && !this.customThemeSettings.isDirty) {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
@ -83,6 +84,7 @@ export default class SettingsDesignCustomizeRoute extends AuthenticatedRoute {
|
||||
}).then((discardChanges) => {
|
||||
if (discardChanges === true) {
|
||||
this.settings.rollbackAttributes();
|
||||
this.customThemeSettings.rollback();
|
||||
}
|
||||
return discardChanges;
|
||||
}).finally(() => {
|
||||
|
@ -9,6 +9,11 @@ export default class CustomThemeSettingsServices extends Service {
|
||||
|
||||
@tracked settings = [];
|
||||
|
||||
get isDirty() {
|
||||
const dirtySetting = this.settings.find(setting => setting.hasDirtyAttributes);
|
||||
return !!dirtySetting;
|
||||
}
|
||||
|
||||
load() {
|
||||
return this.loadTask.perform();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user