mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-27 00:52:36 +03:00
Removed need for .get()
with settings service
no issue The `settings` service has been a source of confusion when writing with modern Ember patterns because it's use of the deprecated `ProxyMixin` forced all property access/setting to go via `.get()` and `.set()` whereas the rest of the system has mostly (there are a few other uses of ProxyObjects remaining) eliminated the use of the non-native get/set methods. - removed use of `ProxyMixin` in the `settings` service by grabbing the attributes off the setting model after fetching and using `Object.defineProperty()` to add native getters/setters that pass through to the model's getters/setters. Ember's autotracking automatically works across the native getters/setters so we can then use the service as if it was any other native object - updated all code to use `settings.{attrName}` directly for getting/setting instead of `.get()` and `.set()` - removed use of observer in the `customViews` service because it was being set up before the native properties had been added on the settings service meaning autotracking wasn't able to set up properly
This commit is contained in:
parent
b5fd02c9e8
commit
060d791a63
@ -39,7 +39,7 @@ export default class ModalPostPreviewEmailComponent extends Component {
|
|||||||
|
|
||||||
get mailgunIsEnabled() {
|
get mailgunIsEnabled() {
|
||||||
return this.config.get('mailgunIsConfigured') ||
|
return this.config.get('mailgunIsConfigured') ||
|
||||||
!!(this.settings.get('mailgunApiKey') && this.settings.get('mailgunDomain') && this.settings.get('mailgunBaseUrl'));
|
!!(this.settings.mailgunApiKey && this.settings.mailgunDomain && this.settings.mailgunBaseUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -24,7 +24,7 @@ export default class ModalPostPreviewSocialComponent extends Component {
|
|||||||
get _fallbackDescription() {
|
get _fallbackDescription() {
|
||||||
return this.args.post.customExcerpt ||
|
return this.args.post.customExcerpt ||
|
||||||
this.serpDescription ||
|
this.serpDescription ||
|
||||||
this.settings.get('description');
|
this.settings.description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -107,7 +107,7 @@ export default class ModalPostPreviewSocialComponent extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get facebookImage() {
|
get facebookImage() {
|
||||||
return this.args.post.ogImage || this.args.post.featureImage || this.settings.get('ogImage') || this.settings.get('coverImage');
|
return this.args.post.ogImage || this.args.post.featureImage || this.settings.ogImage || this.settings.coverImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -166,7 +166,7 @@ export default class ModalPostPreviewSocialComponent extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get twitterImage() {
|
get twitterImage() {
|
||||||
return this.args.post.twitterImage || this.args.post.featureImage || this.settings.get('twitterImage') || this.settings.get('coverImage');
|
return this.args.post.twitterImage || this.args.post.featureImage || this.settings.twitterImage || this.settings.coverImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -66,7 +66,7 @@ export default class PublishFlowOptions extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.args.publishOptions.isScheduled) {
|
if (this.args.publishOptions.isScheduled) {
|
||||||
const scheduleMoment = moment.tz(this.args.publishOptions.scheduledAtUTC, this.settings.get('timezone'));
|
const scheduleMoment = moment.tz(this.args.publishOptions.scheduledAtUTC, this.settings.timezone);
|
||||||
buttonText += `, on ${scheduleMoment.format('MMMM Do')}`;
|
buttonText += `, on ${scheduleMoment.format('MMMM Do')}`;
|
||||||
} else {
|
} else {
|
||||||
buttonText += ', right now';
|
buttonText += ', right now';
|
||||||
|
@ -9,7 +9,7 @@ export default class PublishAtOption extends Component {
|
|||||||
@action
|
@action
|
||||||
setDate(selectedDate) {
|
setDate(selectedDate) {
|
||||||
// selectedDate is a Date object that contains the correct date string in the blog timezone
|
// selectedDate is a Date object that contains the correct date string in the blog timezone
|
||||||
const selectedMoment = moment.tz(selectedDate, this.settings.get('timezone'));
|
const selectedMoment = moment.tz(selectedDate, this.settings.timezone);
|
||||||
const {years, months, date} = selectedMoment.toObject();
|
const {years, months, date} = selectedMoment.toObject();
|
||||||
|
|
||||||
// Create a new moment from existing scheduledAtUTC _in site timezone_.
|
// Create a new moment from existing scheduledAtUTC _in site timezone_.
|
||||||
@ -17,7 +17,7 @@ export default class PublishAtOption extends Component {
|
|||||||
// to account for the converted UTC date being yesterday/tomorrow.
|
// to account for the converted UTC date being yesterday/tomorrow.
|
||||||
const newDate = moment.tz(
|
const newDate = moment.tz(
|
||||||
this.args.publishOptions.scheduledAtUTC,
|
this.args.publishOptions.scheduledAtUTC,
|
||||||
this.settings.get('timezone')
|
this.settings.timezone
|
||||||
);
|
);
|
||||||
newDate.set({years, months, date});
|
newDate.set({years, months, date});
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ export default class PublishAtOption extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
setTime(time, event) {
|
setTime(time, event) {
|
||||||
const newDate = moment.tz(this.args.publishOptions.scheduledAtUTC, this.settings.get('timezone'));
|
const newDate = moment.tz(this.args.publishOptions.scheduledAtUTC, this.settings.timezone);
|
||||||
|
|
||||||
// used to reset the time value on blur if it's invalid
|
// used to reset the time value on blur if it's invalid
|
||||||
const oldTime = newDate.format('HH:mm');
|
const oldTime = newDate.format('HH:mm');
|
||||||
|
@ -32,7 +32,7 @@ export default class GhEditorPostStatusComponent extends Component {
|
|||||||
|
|
||||||
return formatPostTime(
|
return formatPostTime(
|
||||||
this.args.post.publishedAtUTC,
|
this.args.post.publishedAtUTC,
|
||||||
{timezone: this.settings.get('timezone'), scheduled: true}
|
{timezone: this.settings.timezone, scheduled: true}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import Component from '@glimmer/component';
|
import Component from '@glimmer/component';
|
||||||
import validator from 'validator';
|
import validator from 'validator';
|
||||||
import {action} from '@ember/object';
|
import {action} from '@ember/object';
|
||||||
import {get, set} from '@ember/object';
|
|
||||||
|
|
||||||
export default class GhFacebookUrlInput extends Component {
|
export default class GhFacebookUrlInput extends Component {
|
||||||
// NOTE: `get` and `set` are required when reading/writing model properties
|
|
||||||
// because we can be dealing with proxy objects such as the settings service
|
|
||||||
get value() {
|
get value() {
|
||||||
const {model, modelProperty, scratchValue} = this.args;
|
const {model, modelProperty, scratchValue} = this.args;
|
||||||
return scratchValue || get(model, modelProperty);
|
return scratchValue || model[modelProperty];
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -28,7 +25,7 @@ export default class GhFacebookUrlInput extends Component {
|
|||||||
|
|
||||||
if (!newUrl) {
|
if (!newUrl) {
|
||||||
// Clear out the Facebook url
|
// Clear out the Facebook url
|
||||||
set(model, modelProperty, null);
|
model[modelProperty] = null;
|
||||||
this.args.setScratchValue?.(null);
|
this.args.setScratchValue?.(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -51,7 +48,7 @@ export default class GhFacebookUrlInput extends Component {
|
|||||||
throw 'invalid url';
|
throw 'invalid url';
|
||||||
}
|
}
|
||||||
|
|
||||||
set(model, modelProperty, newUrl);
|
model[modelProperty] = newUrl;
|
||||||
this.args.setScratchValue?.(null);
|
this.args.setScratchValue?.(null);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e === 'invalid url') {
|
if (e === 'invalid url') {
|
||||||
|
@ -21,7 +21,7 @@ export default class GhKoenigEditorReactComponent extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get accentColor() {
|
get accentColor() {
|
||||||
const color = this.settings.get('accentColor');
|
const color = this.settings.accentColor;
|
||||||
if (color && color[0] === '#') {
|
if (color && color[0] === '#') {
|
||||||
return color.slice(1);
|
return color.slice(1);
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ export default class GhMarkdownEditor extends Component.extend(ShortcutsMixin) {
|
|||||||
toolbar.splice(index, 1);
|
toolbar.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.get('settings.unsplash')) {
|
if (this.settings.unsplash) {
|
||||||
let image = toolbar.findBy('name', 'image');
|
let image = toolbar.findBy('name', 'image');
|
||||||
let index = toolbar.indexOf(image) + 1;
|
let index = toolbar.indexOf(image) + 1;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ export default class Email extends Component {
|
|||||||
'config.mailgunIsConfigured'
|
'config.mailgunIsConfigured'
|
||||||
)
|
)
|
||||||
get mailgunIsEnabled() {
|
get mailgunIsEnabled() {
|
||||||
return this.get('settings.mailgunApiKey') && this.get('settings.mailgunDomain') && this.get('settings.mailgunBaseUrl') || this.get('config.mailgunIsConfigured');
|
return this.settings.mailgunApiKey && this.settings.mailgunDomain && this.settings.mailgunBaseUrl || this.get('config.mailgunIsConfigured');
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -12,13 +12,13 @@ const VISIBILITIES = [
|
|||||||
@classic
|
@classic
|
||||||
export default class GhPsmVisibilityInput extends Component {
|
export default class GhPsmVisibilityInput extends Component {
|
||||||
@service settings;
|
@service settings;
|
||||||
|
|
||||||
// public attrs
|
// public attrs
|
||||||
post = null;
|
post = null;
|
||||||
|
|
||||||
@computed('post.visibility')
|
@computed('post.visibility')
|
||||||
get selectedVisibility() {
|
get selectedVisibility() {
|
||||||
return this.get('post.visibility') || this.settings.get('defaultContentVisibility');
|
return this.get('post.visibility') || this.settings.defaultContentVisibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
import Component from '@glimmer/component';
|
import Component from '@glimmer/component';
|
||||||
import {action} from '@ember/object';
|
import {action} from '@ember/object';
|
||||||
import {get, set} from '@ember/object';
|
|
||||||
|
|
||||||
export default class GhTwitterUrlInput extends Component {
|
export default class GhTwitterUrlInput extends Component {
|
||||||
// NOTE: `get` and `set` are required when reading/writing model properties
|
|
||||||
// because we can be dealing with proxy objects such as the settings service
|
|
||||||
get value() {
|
get value() {
|
||||||
const {model, modelProperty, scratchValue} = this.args;
|
const {model, modelProperty, scratchValue} = this.args;
|
||||||
return scratchValue || get(model, modelProperty);
|
return scratchValue || model[modelProperty];
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -27,7 +24,7 @@ export default class GhTwitterUrlInput extends Component {
|
|||||||
|
|
||||||
if (!newUrl) {
|
if (!newUrl) {
|
||||||
// Clear out the Twitter url
|
// Clear out the Twitter url
|
||||||
set(model, modelProperty, '');
|
model[modelProperty] = '';
|
||||||
this.args.setScratchValue?.(null);
|
this.args.setScratchValue?.(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -52,7 +49,7 @@ export default class GhTwitterUrlInput extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
set(model, modelProperty, `https://twitter.com/${username}`);
|
model[modelProperty] = `https://twitter.com/${username}`;
|
||||||
this.args.setScratchValue?.(null);
|
this.args.setScratchValue?.(null);
|
||||||
|
|
||||||
model.hasValidated.pushObject(modelProperty);
|
model.hasValidated.pushObject(modelProperty);
|
||||||
|
@ -19,7 +19,7 @@ export default class MembersActivityEventTypeFilter extends Component {
|
|||||||
|
|
||||||
get availableEventTypes() {
|
get availableEventTypes() {
|
||||||
const extended = [...ALL_EVENT_TYPES];
|
const extended = [...ALL_EVENT_TYPES];
|
||||||
if (this.settings.get('commentsEnabled') !== 'off') {
|
if (this.settings.commentsEnabled !== 'off') {
|
||||||
extended.push({event: 'comment_event', icon: 'event-comment', name: 'Comments'});
|
extended.push({event: 'comment_event', icon: 'event-comment', name: 'Comments'});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,12 +178,12 @@ export default class MembersFilter extends Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// exclude subscription filters if Stripe isn't connected
|
// exclude subscription filters if Stripe isn't connected
|
||||||
if (!this.settings.get('paidMembersEnabled')) {
|
if (!this.settings.paidMembersEnabled) {
|
||||||
availableFilters = availableFilters.reject(prop => prop.group === 'Subscription');
|
availableFilters = availableFilters.reject(prop => prop.group === 'Subscription');
|
||||||
}
|
}
|
||||||
|
|
||||||
// exclude email filters if email functionality is disabled
|
// exclude email filters if email functionality is disabled
|
||||||
if (this.settings.get('editorDefaultEmailRecipients') === 'disabled') {
|
if (this.settings.editorDefaultEmailRecipients === 'disabled') {
|
||||||
availableFilters = availableFilters.reject(prop => prop.group === 'Email');
|
availableFilters = availableFilters.reject(prop => prop.group === 'Email');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ export default class MembersFilter extends Component {
|
|||||||
} else if (filterProperty.valueType === 'date') {
|
} else if (filterProperty.valueType === 'date') {
|
||||||
let filterValue;
|
let filterValue;
|
||||||
|
|
||||||
let tzMoment = moment.tz(moment(filter.value).format('YYYY-MM-DD'), this.settings.get('timezone'));
|
let tzMoment = moment.tz(moment(filter.value).format('YYYY-MM-DD'), this.settings.timezone);
|
||||||
|
|
||||||
if (relationStr === '>') {
|
if (relationStr === '>') {
|
||||||
tzMoment = tzMoment.set({hour: 23, minute: 59, second: 59});
|
tzMoment = tzMoment.set({hour: 23, minute: 59, second: 59});
|
||||||
@ -364,7 +364,7 @@ export default class MembersFilter extends Component {
|
|||||||
relation,
|
relation,
|
||||||
relationOptions: FILTER_RELATIONS_OPTIONS[key],
|
relationOptions: FILTER_RELATIONS_OPTIONS[key],
|
||||||
value,
|
value,
|
||||||
timezone: this.settings.get('timezone')
|
timezone: this.settings.timezone
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -429,7 +429,7 @@ export default class MembersFilter extends Component {
|
|||||||
@action
|
@action
|
||||||
handleSubmitKeyup(e) {
|
handleSubmitKeyup(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
this.applyFilter();
|
this.applyFilter();
|
||||||
}
|
}
|
||||||
@ -465,7 +465,7 @@ export default class MembersFilter extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (newProp.valueType === 'date' && !defaultValue) {
|
if (newProp.valueType === 'date' && !defaultValue) {
|
||||||
defaultValue = moment(moment.tz(this.settings.get('timezone')).format('YYYY-MM-DD')).toDate();
|
defaultValue = moment(moment.tz(this.settings.timezone).format('YYYY-MM-DD')).toDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
let defaultRelation = this.availableFilterRelationsOptions[newType][0].name;
|
let defaultRelation = this.availableFilterRelationsOptions[newType][0].name;
|
||||||
@ -479,7 +479,7 @@ export default class MembersFilter extends Component {
|
|||||||
relation: defaultRelation,
|
relation: defaultRelation,
|
||||||
relationOptions: this.availableFilterRelationsOptions[newType],
|
relationOptions: this.availableFilterRelationsOptions[newType],
|
||||||
value: defaultValue,
|
value: defaultValue,
|
||||||
timezone: this.settings.get('timezone')
|
timezone: this.settings.timezone
|
||||||
});
|
});
|
||||||
|
|
||||||
const filterToSwap = this.filters.find(f => f === filter);
|
const filterToSwap = this.filters.find(f => f === filter);
|
||||||
|
@ -14,22 +14,22 @@ export default class ModalEmailDesignSettings extends ModalComponent {
|
|||||||
@service session;
|
@service session;
|
||||||
@service settings;
|
@service settings;
|
||||||
|
|
||||||
@tracked headerImage = this.settings.get('newsletterHeaderImage');
|
@tracked headerImage = this.settings.newsletterHeaderImage;
|
||||||
@tracked showHeaderIcon = this.settings.get('newsletterShowHeaderIcon');
|
@tracked showHeaderIcon = this.settings.newsletterShowHeaderIcon;
|
||||||
@tracked showHeaderTitle = this.settings.get('newsletterShowHeaderTitle');
|
@tracked showHeaderTitle = this.settings.newsletterShowHeaderTitle;
|
||||||
@tracked titleFontCategory = this.settings.get('newsletterTitleFontCategory');
|
@tracked titleFontCategory = this.settings.newsletterTitleFontCategory;
|
||||||
@tracked titleAlignment = this.settings.get('newsletterTitleAlignment');
|
@tracked titleAlignment = this.settings.newsletterTitleAlignment;
|
||||||
@tracked showFeatureImage = this.settings.get('newsletterShowFeatureImage');
|
@tracked showFeatureImage = this.settings.newsletterShowFeatureImage;
|
||||||
@tracked bodyFontCategory = this.settings.get('newsletterBodyFontCategory');
|
@tracked bodyFontCategory = this.settings.newsletterBodyFontCategory;
|
||||||
@tracked footerContent = this.settings.get('newsletterFooterContent');
|
@tracked footerContent = this.settings.newsletterFooterContent;
|
||||||
@tracked showBadge = this.settings.get('newsletterShowBadge');
|
@tracked showBadge = this.settings.newsletterShowBadge;
|
||||||
|
|
||||||
currentDate = moment().format('D MMM YYYY');
|
currentDate = moment().format('D MMM YYYY');
|
||||||
copyrightYear = new Date().getFullYear();
|
copyrightYear = new Date().getFullYear();
|
||||||
imageExtensions = IMAGE_EXTENSIONS;
|
imageExtensions = IMAGE_EXTENSIONS;
|
||||||
|
|
||||||
get showHeader() {
|
get showHeader() {
|
||||||
return (this.showHeaderIcon && this.settings.get('icon')) || this.showHeaderTitle;
|
return (this.showHeaderIcon && this.settings.icon) || this.showHeaderTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
get featureImageUrl() {
|
get featureImageUrl() {
|
||||||
@ -77,15 +77,15 @@ export default class ModalEmailDesignSettings extends ModalComponent {
|
|||||||
|
|
||||||
@task({drop: true})
|
@task({drop: true})
|
||||||
*saveSettings() {
|
*saveSettings() {
|
||||||
this.settings.set('newsletterHeaderImage', this.headerImage);
|
this.settings.newsletterHeaderImage = this.headerImage;
|
||||||
this.settings.set('newsletterShowHeaderIcon', this.showHeaderIcon);
|
this.settings.newsletterShowHeaderIcon = this.showHeaderIcon;
|
||||||
this.settings.set('newsletterShowHeaderTitle', this.showHeaderTitle);
|
this.settings.newsletterShowHeaderTitle = this.showHeaderTitle;
|
||||||
this.settings.set('newsletterTitleFontCategory', this.titleFontCategory);
|
this.settings.newsletterTitleFontCategory = this.titleFontCategory;
|
||||||
this.settings.set('newsletterTitleAlignment', this.titleAlignment);
|
this.settings.newsletterTitleAlignment = this.titleAlignment;
|
||||||
this.settings.set('newsletterShowFeatureImage', this.showFeatureImage);
|
this.settings.newsletterShowFeatureImage = this.showFeatureImage;
|
||||||
this.settings.set('newsletterBodyFontCategory', this.bodyFontCategory);
|
this.settings.newsletterBodyFontCategory = this.bodyFontCategory;
|
||||||
this.settings.set('newsletterFooterContent', this.footerContent);
|
this.settings.newsletterFooterContent = this.footerContent;
|
||||||
this.settings.set('newsletterShowBadge', this.showBadge);
|
this.settings.newsletterShowBadge = this.showBadge;
|
||||||
|
|
||||||
yield this.settings.save();
|
yield this.settings.save();
|
||||||
this.closeModal();
|
this.closeModal();
|
||||||
|
@ -30,10 +30,10 @@ export default class ModalFreeMembershipSettings extends ModalBase {
|
|||||||
this.close();
|
this.close();
|
||||||
},
|
},
|
||||||
updateName(value) {
|
updateName(value) {
|
||||||
this.settings.set('membersFreePriceName', value);
|
this.settings.membersFreePriceName = value;
|
||||||
},
|
},
|
||||||
updateDescription(value) {
|
updateDescription(value) {
|
||||||
this.settings.set('membersFreePriceDescription', value);
|
this.settings.membersFreePriceDescription = value;
|
||||||
},
|
},
|
||||||
setFreeSignupRedirect(url) {
|
setFreeSignupRedirect(url) {
|
||||||
this.freeSignupRedirect = url;
|
this.freeSignupRedirect = url;
|
||||||
@ -47,7 +47,7 @@ export default class ModalFreeMembershipSettings extends ModalBase {
|
|||||||
*save() {
|
*save() {
|
||||||
try {
|
try {
|
||||||
this.send('validateFreeSignupRedirect');
|
this.send('validateFreeSignupRedirect');
|
||||||
if (this.settings.get('errors').length !== 0) {
|
if (this.settings.errors.length !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
yield this.settings.save();
|
yield this.settings.save();
|
||||||
@ -61,12 +61,12 @@ export default class ModalFreeMembershipSettings extends ModalBase {
|
|||||||
|
|
||||||
_validateSignupRedirect(url, type) {
|
_validateSignupRedirect(url, type) {
|
||||||
let errMessage = `Please enter a valid URL`;
|
let errMessage = `Please enter a valid URL`;
|
||||||
this.settings.get('errors').remove(type);
|
this.settings.errors.remove(type);
|
||||||
this.settings.get('hasValidated').removeObject(type);
|
this.settings.hasValidated.removeObject(type);
|
||||||
|
|
||||||
if (url === null) {
|
if (url === null) {
|
||||||
this.settings.get('errors').add(type, errMessage);
|
this.settings.errors.add(type, errMessage);
|
||||||
this.settings.get('hasValidated').pushObject(type);
|
this.settings.hasValidated.pushObject(type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,9 +77,9 @@ export default class ModalFreeMembershipSettings extends ModalBase {
|
|||||||
|
|
||||||
if (url.href.startsWith(this.siteUrl)) {
|
if (url.href.startsWith(this.siteUrl)) {
|
||||||
const path = url.href.replace(this.siteUrl, '');
|
const path = url.href.replace(this.siteUrl, '');
|
||||||
this.settings.set(type, path);
|
this.settings.type = path;
|
||||||
} else {
|
} else {
|
||||||
this.settings.set(type, url.href);
|
this.settings.type = url.href;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ export default ModalComponent.extend({
|
|||||||
confirm() {},
|
confirm() {},
|
||||||
|
|
||||||
backgroundStyle: computed('settings.accentColor', function () {
|
backgroundStyle: computed('settings.accentColor', function () {
|
||||||
let color = this.settings.get('accentColor') || '#ffffff';
|
let color = this.settings.accentColor || '#ffffff';
|
||||||
return htmlSafe(`background-color: ${color}`);
|
return htmlSafe(`background-color: ${color}`);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -71,20 +71,20 @@ export default ModalComponent.extend({
|
|||||||
|
|
||||||
selectedButtonStyle: computed('settings.portalButtonStyle', function () {
|
selectedButtonStyle: computed('settings.portalButtonStyle', function () {
|
||||||
return this.buttonStyleOptions.find((buttonStyle) => {
|
return this.buttonStyleOptions.find((buttonStyle) => {
|
||||||
return (buttonStyle.name === this.settings.get('portalButtonStyle'));
|
return (buttonStyle.name === this.settings.portalButtonStyle);
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
isFreeChecked: computed('settings.{portalPlans.[],membersSignupAccess}', function () {
|
isFreeChecked: computed('settings.{portalPlans.[],membersSignupAccess}', function () {
|
||||||
const allowedPlans = this.settings.get('portalPlans') || [];
|
const allowedPlans = this.settings.portalPlans || [];
|
||||||
return (this.settings.get('membersSignupAccess') === 'all' && allowedPlans.includes('free'));
|
return (this.settings.membersSignupAccess === 'all' && allowedPlans.includes('free'));
|
||||||
}),
|
}),
|
||||||
isMonthlyChecked: computed('settings.portalPlans.[]', 'membersUtils.paidMembersEnabled', function () {
|
isMonthlyChecked: computed('settings.portalPlans.[]', 'membersUtils.paidMembersEnabled', function () {
|
||||||
const allowedPlans = this.settings.get('portalPlans') || [];
|
const allowedPlans = this.settings.portalPlans || [];
|
||||||
return (this.membersUtils.paidMembersEnabled && allowedPlans.includes('monthly'));
|
return (this.membersUtils.paidMembersEnabled && allowedPlans.includes('monthly'));
|
||||||
}),
|
}),
|
||||||
isYearlyChecked: computed('settings.portalPlans.[]', 'membersUtils.paidMembersEnabled', function () {
|
isYearlyChecked: computed('settings.portalPlans.[]', 'membersUtils.paidMembersEnabled', function () {
|
||||||
const allowedPlans = this.settings.get('portalPlans') || [];
|
const allowedPlans = this.settings.portalPlans || [];
|
||||||
return (this.membersUtils.paidMembersEnabled && allowedPlans.includes('yearly'));
|
return (this.membersUtils.paidMembersEnabled && allowedPlans.includes('yearly'));
|
||||||
}),
|
}),
|
||||||
tiers: computed('model.tiers.[]', 'changedTiers.[]', 'isPreloading', function () {
|
tiers: computed('model.tiers.[]', 'changedTiers.[]', 'isPreloading', function () {
|
||||||
@ -130,13 +130,13 @@ export default ModalComponent.extend({
|
|||||||
}];
|
}];
|
||||||
this.iconExtensions = ICON_EXTENSIONS;
|
this.iconExtensions = ICON_EXTENSIONS;
|
||||||
this.changedTiers = [];
|
this.changedTiers = [];
|
||||||
this.set('supportAddress', this.parseEmailAddress(this.settings.get('membersSupportAddress')));
|
this.set('supportAddress', this.parseEmailAddress(this.settings.membersSupportAddress));
|
||||||
this.set('openSection', 'signup-options');
|
this.set('openSection', 'signup-options');
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.settings.get('errors').clear();
|
this.settings.errors.clear();
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@ -150,11 +150,11 @@ export default ModalComponent.extend({
|
|||||||
this.updateAllowedTier(tierId, event.target.checked);
|
this.updateAllowedTier(tierId, event.target.checked);
|
||||||
},
|
},
|
||||||
togglePortalButton(showButton) {
|
togglePortalButton(showButton) {
|
||||||
this.settings.set('portalButton', showButton);
|
this.settings.portalButton = showButton;
|
||||||
},
|
},
|
||||||
|
|
||||||
togglePortalName(showSignupName) {
|
togglePortalName(showSignupName) {
|
||||||
this.settings.set('portalName', showSignupName);
|
this.settings.portalName = showSignupName;
|
||||||
},
|
},
|
||||||
toggleSection(section) {
|
toggleSection(section) {
|
||||||
if (this.get('openSection') === section) {
|
if (this.get('openSection') === section) {
|
||||||
@ -169,7 +169,7 @@ export default ModalComponent.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
isPlanSelected(plan) {
|
isPlanSelected(plan) {
|
||||||
const allowedPlans = this.settings.get('portalPlans');
|
const allowedPlans = this.settings.portalPlans;
|
||||||
return allowedPlans.includes(plan);
|
return allowedPlans.includes(plan);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -191,11 +191,11 @@ export default ModalComponent.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setButtonStyle(buttonStyle) {
|
setButtonStyle(buttonStyle) {
|
||||||
this.settings.set('portalButtonStyle', buttonStyle.name);
|
this.settings.portalButtonStyle = buttonStyle.name;
|
||||||
},
|
},
|
||||||
|
|
||||||
setSignupButtonText(event) {
|
setSignupButtonText(event) {
|
||||||
this.settings.set('portalButtonSignupText', event.target.value);
|
this.settings.portalButtonSignupText = event.target.value;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Fired after an image upload completes
|
* Fired after an image upload completes
|
||||||
@ -206,7 +206,7 @@ export default ModalComponent.extend({
|
|||||||
imageUploaded(property, results) {
|
imageUploaded(property, results) {
|
||||||
if (results[0]) {
|
if (results[0]) {
|
||||||
this.set('customIcon', results[0].url);
|
this.set('customIcon', results[0].url);
|
||||||
this.settings.set('portalButtonIcon', results[0].url);
|
this.settings.portalButtonIcon = results[0].url;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -221,11 +221,11 @@ export default ModalComponent.extend({
|
|||||||
|
|
||||||
deleteCustomIcon() {
|
deleteCustomIcon() {
|
||||||
this.set('customIcon', null);
|
this.set('customIcon', null);
|
||||||
this.settings.set('portalButtonIcon', this.membersUtils.defaultIconKeys[0]);
|
this.settings.portalButtonIcon = this.membersUtils.defaultIconKeys[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
selectDefaultIcon(icon) {
|
selectDefaultIcon(icon) {
|
||||||
this.settings.set('portalButtonIcon', icon);
|
this.settings.portalButtonIcon = icon;
|
||||||
},
|
},
|
||||||
|
|
||||||
closeLeaveSettingsModal() {
|
closeLeaveSettingsModal() {
|
||||||
@ -253,9 +253,9 @@ export default ModalComponent.extend({
|
|||||||
this.set('supportAddress', supportAddress);
|
this.set('supportAddress', supportAddress);
|
||||||
|
|
||||||
if (this.config.emailDomain && supportAddress === `noreply@${this.config.emailDomain}`) {
|
if (this.config.emailDomain && supportAddress === `noreply@${this.config.emailDomain}`) {
|
||||||
this.settings.set('membersSupportAddress', 'noreply');
|
this.settings.membersSupportAddress = 'noreply';
|
||||||
} else {
|
} else {
|
||||||
this.settings.set('membersSupportAddress', supportAddress);
|
this.settings.membersSupportAddress = supportAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -270,18 +270,18 @@ export default ModalComponent.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateAllowedPlan(plan, isChecked) {
|
updateAllowedPlan(plan, isChecked) {
|
||||||
const portalPlans = this.settings.get('portalPlans') || [];
|
const portalPlans = this.settings.portalPlans || [];
|
||||||
const allowedPlans = [...portalPlans];
|
const allowedPlans = [...portalPlans];
|
||||||
const freeTier = this.model.tiers.find(p => p.type === 'free');
|
const freeTier = this.model.tiers.find(p => p.type === 'free');
|
||||||
|
|
||||||
if (!isChecked) {
|
if (!isChecked) {
|
||||||
this.settings.set('portalPlans', allowedPlans.filter(p => p !== plan));
|
this.settings.portalPlans = allowedPlans.filter(p => p !== plan);
|
||||||
if (plan === 'free') {
|
if (plan === 'free') {
|
||||||
freeTier.set('visibility', 'none');
|
freeTier.set('visibility', 'none');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
allowedPlans.push(plan);
|
allowedPlans.push(plan);
|
||||||
this.settings.set('portalPlans', allowedPlans);
|
this.settings.portalPlans = allowedPlans;
|
||||||
if (plan === 'free') {
|
if (plan === 'free') {
|
||||||
freeTier.set('visibility', 'public');
|
freeTier.set('visibility', 'public');
|
||||||
}
|
}
|
||||||
@ -303,12 +303,12 @@ export default ModalComponent.extend({
|
|||||||
|
|
||||||
_validateSignupRedirect(url, type) {
|
_validateSignupRedirect(url, type) {
|
||||||
let errMessage = `Please enter a valid URL`;
|
let errMessage = `Please enter a valid URL`;
|
||||||
this.settings.get('errors').remove(type);
|
this.settings.errors.remove(type);
|
||||||
this.settings.get('hasValidated').removeObject(type);
|
this.settings.hasValidated.removeObject(type);
|
||||||
|
|
||||||
if (url === null) {
|
if (url === null) {
|
||||||
this.settings.get('errors').add(type, errMessage);
|
this.settings.errors.add(type, errMessage);
|
||||||
this.settings.get('hasValidated').pushObject(type);
|
this.settings.hasValidated.pushObject(type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,9 +319,9 @@ export default ModalComponent.extend({
|
|||||||
|
|
||||||
if (url.href.startsWith(this.siteUrl)) {
|
if (url.href.startsWith(this.siteUrl)) {
|
||||||
const path = url.href.replace(this.siteUrl, '');
|
const path = url.href.replace(this.siteUrl, '');
|
||||||
this.settings.set(type, path);
|
this.settings[type] = path;
|
||||||
} else {
|
} else {
|
||||||
this.settings.set(type, url.href);
|
this.settings[type] = url.href;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -330,9 +330,9 @@ export default ModalComponent.extend({
|
|||||||
await this.model.preloadTask;
|
await this.model.preloadTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
const portalButtonIcon = this.settings.get('portalButtonIcon') || '';
|
const portalButtonIcon = this.settings.portalButtonIcon || '';
|
||||||
if (portalButtonIcon && !this.membersUtils.defaultIconKeys.includes(portalButtonIcon)) {
|
if (portalButtonIcon && !this.membersUtils.defaultIconKeys.includes(portalButtonIcon)) {
|
||||||
this.set('customIcon', this.settings.get('portalButtonIcon'));
|
this.set('customIcon', this.settings.portalButtonIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.siteUrl = this.config.get('blogUrl');
|
this.siteUrl = this.config.get('blogUrl');
|
||||||
@ -360,7 +360,7 @@ export default ModalComponent.extend({
|
|||||||
this.settings.errors.remove('members_support_address');
|
this.settings.errors.remove('members_support_address');
|
||||||
this.settings.hasValidated.removeObject('members_support_address');
|
this.settings.hasValidated.removeObject('members_support_address');
|
||||||
|
|
||||||
if (this.settings.get('errors').length !== 0) {
|
if (this.settings.errors.length !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,14 +374,14 @@ export default ModalComponent.extend({
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const newEmail = this.settings.get('membersSupportAddress');
|
const newEmail = this.settings.membersSupportAddress;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = yield this.settings.save();
|
const result = yield this.settings.save();
|
||||||
if (result._meta?.sent_email_verification) {
|
if (result._meta?.sent_email_verification) {
|
||||||
yield this.modals.open(ConfirmEmailModal, {
|
yield this.modals.open(ConfirmEmailModal, {
|
||||||
newEmail,
|
newEmail,
|
||||||
currentEmail: this.settings.get('membersSupportAddress')
|
currentEmail: this.settings.membersSupportAddress
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,14 +11,14 @@ export default class ModalStripeConnect extends ModalBase {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
setStripeConnectIntegrationTokenSetting(stripeConnectIntegrationToken) {
|
setStripeConnectIntegrationTokenSetting(stripeConnectIntegrationToken) {
|
||||||
this.settings.set('stripeConnectIntegrationToken', stripeConnectIntegrationToken);
|
this.settings.stripeConnectIntegrationToken = stripeConnectIntegrationToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
reset() {
|
reset() {
|
||||||
// stripeConnectIntegrationToken is not a persisted value so we don't want
|
// stripeConnectIntegrationToken is not a persisted value so we don't want
|
||||||
// to keep it around across transitions
|
// to keep it around across transitions
|
||||||
this.settings.set('stripeConnectIntegrationToken', undefined);
|
this.settings.stripeConnectIntegrationToken = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -36,7 +36,7 @@ export default class ModalStripeConnect extends ModalBase {
|
|||||||
@action
|
@action
|
||||||
updateSuccessModifier() {
|
updateSuccessModifier() {
|
||||||
// Note, we should also check isStripeEnabled because stripeDirect option might be enabled
|
// Note, we should also check isStripeEnabled because stripeDirect option might be enabled
|
||||||
if (this.membersUtils.get('isStripeEnabled') && this.settings.get('stripeConnectAccountId')) {
|
if (this.membersUtils.get('isStripeEnabled') && this.settings.stripeConnectAccountId) {
|
||||||
if (this.modifier?.indexOf('stripe-connected') === -1) {
|
if (this.modifier?.indexOf('stripe-connected') === -1) {
|
||||||
this.updateModifier(`${this.modifier} stripe-connected`);
|
this.updateModifier(`${this.modifier} stripe-connected`);
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@ export default class ModalStripeConnect extends ModalBase {
|
|||||||
|
|
||||||
actions = {
|
actions = {
|
||||||
confirm() {
|
confirm() {
|
||||||
if (this.settings.get('stripeConnectAccountId')) {
|
if (this.settings.stripeConnectAccountId) {
|
||||||
return this.confirmAction();
|
return this.confirmAction();
|
||||||
}
|
}
|
||||||
// noop - enter key shouldn't do anything
|
// noop - enter key shouldn't do anything
|
||||||
|
@ -86,7 +86,7 @@ export default class ModalTierPrice extends ModalBase {
|
|||||||
if (this.tier.get('trialDays')) {
|
if (this.tier.get('trialDays')) {
|
||||||
this.freeTrialEnabled = true;
|
this.freeTrialEnabled = true;
|
||||||
}
|
}
|
||||||
this.accentColorStyle = htmlSafe(`color: ${this.settings.get('accentColor')}`);
|
this.accentColorStyle = htmlSafe(`color: ${this.settings.accentColor}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -179,7 +179,7 @@ export default class ModalTierPrice extends ModalBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.tier.set('benefits', this.benefits.filter(benefit => !benefit.get('isBlank')));
|
this.tier.set('benefits', this.benefits.filter(benefit => !benefit.get('isBlank')));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
yield this.tier.save();
|
yield this.tier.save();
|
||||||
this.hasSaved = true;
|
this.hasSaved = true;
|
||||||
|
@ -8,7 +8,7 @@ export default class EditNewsletterPreview extends Component {
|
|||||||
@service settings;
|
@service settings;
|
||||||
|
|
||||||
get showHeader() {
|
get showHeader() {
|
||||||
return (this.args.newsletter.showHeaderIcon && this.settings.get('icon'))
|
return (this.args.newsletter.showHeaderIcon && this.settings.icon)
|
||||||
|| this.headerTitle;
|
|| this.headerTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ export default class EditNewsletterPreview extends Component {
|
|||||||
|
|
||||||
get headerTitle() {
|
get headerTitle() {
|
||||||
if (this.args.newsletter.showHeaderTitle) {
|
if (this.args.newsletter.showHeaderTitle) {
|
||||||
return this.settings.get('title');
|
return this.settings.title;
|
||||||
} else if (this.args.newsletter.showHeaderName) {
|
} else if (this.args.newsletter.showHeaderName) {
|
||||||
return this.args.newsletter.name;
|
return this.args.newsletter.name;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ export default class VerifyEmail extends Component {
|
|||||||
|
|
||||||
yield this.ajax.put(url, {data: {token}});
|
yield this.ajax.put(url, {data: {token}});
|
||||||
yield this.settings.reload();
|
yield this.settings.reload();
|
||||||
this.email = this.settings.get('membersSupportAddress');
|
this.email = this.settings.membersSupportAddress;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.error = e.message;
|
this.error = e.message;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ export default class PostsListItemClicks extends Component {
|
|||||||
|
|
||||||
let formattedTime = formatPostTime(
|
let formattedTime = formatPostTime(
|
||||||
this.post.publishedAtUTC,
|
this.post.publishedAtUTC,
|
||||||
{timezone: this.settings.get('timezone'), scheduled: true}
|
{timezone: this.settings.timezone, scheduled: true}
|
||||||
);
|
);
|
||||||
text.push(formattedTime);
|
text.push(formattedTime);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ export default class AccentColorFormField extends Component {
|
|||||||
@service settings;
|
@service settings;
|
||||||
|
|
||||||
get accentColor() {
|
get accentColor() {
|
||||||
const color = this.settings.get('accentColor');
|
const color = this.settings.accentColor;
|
||||||
if (color && color[0] === '#') {
|
if (color && color[0] === '#') {
|
||||||
return color.slice(1);
|
return color.slice(1);
|
||||||
}
|
}
|
||||||
@ -16,7 +16,7 @@ export default class AccentColorFormField extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get accentColorPickerValue() {
|
get accentColorPickerValue() {
|
||||||
return this.settings.get('accentColor') || '#ffffff';
|
return this.settings.accentColor || '#ffffff';
|
||||||
}
|
}
|
||||||
|
|
||||||
get accentColorBgStyle() {
|
get accentColorBgStyle() {
|
||||||
@ -31,7 +31,7 @@ export default class AccentColorFormField extends Component {
|
|||||||
@action
|
@action
|
||||||
async updateAccentColor(event) {
|
async updateAccentColor(event) {
|
||||||
let newColor = event.target.value;
|
let newColor = event.target.value;
|
||||||
const oldColor = this.settings.get('accentColor');
|
const oldColor = this.settings.accentColor;
|
||||||
|
|
||||||
// reset errors and validation
|
// reset errors and validation
|
||||||
this.settings.errors.remove('accentColor');
|
this.settings.errors.remove('accentColor');
|
||||||
@ -62,7 +62,7 @@ export default class AccentColorFormField extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.settings.set('accentColor', newColor);
|
this.settings.accentColor = newColor;
|
||||||
this.args.didUpdate('accentColor', newColor);
|
this.args.didUpdate('accentColor', newColor);
|
||||||
} else {
|
} else {
|
||||||
this.settings.errors.add('accentColor', 'Please enter a color in hex format');
|
this.settings.errors.add('accentColor', 'Please enter a color in hex format');
|
||||||
|
@ -25,7 +25,7 @@ export default class PublicationCoverFormField extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
update(value) {
|
update(value) {
|
||||||
this.settings.set('coverImage', value);
|
this.settings.coverImage = value;
|
||||||
this.args.didUpdate('coverImage', value);
|
this.args.didUpdate('coverImage', value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ export default class PublicationIconFormField extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
update(value) {
|
update(value) {
|
||||||
this.settings.set('icon', value);
|
this.settings.icon = value;
|
||||||
this.args.didUpdate('icon', value);
|
this.args.didUpdate('icon', value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ export default class PublicationLogoFormField extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
update(value) {
|
update(value) {
|
||||||
this.settings.set('logo', value);
|
this.settings.logo = value;
|
||||||
this.args.didUpdate('logo', value);
|
this.args.didUpdate('logo', value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,13 @@ export default class SiteDescriptionFormField extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
update(event) {
|
update(event) {
|
||||||
this.settings.set('description', event.target.value);
|
this.settings.description = event.target.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async validate(event) {
|
async validate(event) {
|
||||||
const value = event.target.value;
|
const value = event.target.value;
|
||||||
this.settings.set('description', value);
|
this.settings.description = value;
|
||||||
await this.settings.validate({property: 'description'});
|
await this.settings.validate({property: 'description'});
|
||||||
this.args.didUpdate('description', value);
|
this.args.didUpdate('description', value);
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,12 @@ export default class SettingsMembersCommentAccess extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get selectedOption() {
|
get selectedOption() {
|
||||||
return this.options.find(o => o.value === this.settings.get('commentsEnabled'));
|
return this.options.find(o => o.value === this.settings.commentsEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setCommentAccess(option) {
|
setCommentAccess(option) {
|
||||||
this.settings.set('commentsEnabled', option.value);
|
this.settings.commentsEnabled = option.value;
|
||||||
this.args.onChange?.(option.value);
|
this.args.onChange?.(option.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,22 +37,22 @@ export default class SettingsMembersDefaultPostAccess extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get hasVisibilityFilter() {
|
get hasVisibilityFilter() {
|
||||||
return !['public', 'members', 'paid'].includes(this.settings.get('defaultContentVisibility'));
|
return !['public', 'members', 'paid'].includes(this.settings.defaultContentVisibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
get visibilityTiers() {
|
get visibilityTiers() {
|
||||||
const visibilityTiersData = this.settings.get('defaultContentVisibilityTiers');
|
const visibilityTiersData = this.settings.defaultContentVisibilityTiers;
|
||||||
return (visibilityTiersData || []).map((id) => {
|
return (visibilityTiersData || []).map((id) => {
|
||||||
return {id};
|
return {id};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get selectedOption() {
|
get selectedOption() {
|
||||||
if (this.settings.get('membersSignupAccess') === 'none') {
|
if (this.settings.membersSignupAccess === 'none') {
|
||||||
return this.options.find(o => o.value === 'public');
|
return this.options.find(o => o.value === 'public');
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.options.find(o => o.value === this.settings.get('defaultContentVisibility'));
|
return this.options.find(o => o.value === this.settings.defaultContentVisibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -61,21 +61,21 @@ export default class SettingsMembersDefaultPostAccess extends Component {
|
|||||||
const tierIds = segment?.map((tier) => {
|
const tierIds = segment?.map((tier) => {
|
||||||
return tier.id;
|
return tier.id;
|
||||||
});
|
});
|
||||||
this.settings.set('defaultContentVisibility', 'tiers');
|
this.settings.defaultContentVisibility = 'tiers';
|
||||||
this.settings.set('defaultContentVisibilityTiers', tierIds);
|
this.settings.defaultContentVisibilityTiers = tierIds;
|
||||||
this.showSegmentError = false;
|
this.showSegmentError = false;
|
||||||
} else {
|
} else {
|
||||||
this.settings.set('defaultContentVisibility', '');
|
this.settings.defaultContentVisibility = '';
|
||||||
this.showSegmentError = true;
|
this.showSegmentError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setDefaultContentVisibility(option) {
|
setDefaultContentVisibility(option) {
|
||||||
if (this.settings.get('membersSignupAccess') !== 'none') {
|
if (this.settings.membersSignupAccess !== 'none') {
|
||||||
this.settings.set('defaultContentVisibility', option.value);
|
this.settings.defaultContentVisibility = option.value;
|
||||||
if (option.value === 'tiers') {
|
if (option.value === 'tiers') {
|
||||||
this.settings.set('defaultContentVisibilityTiers', []);
|
this.settings.defaultContentVisibilityTiers = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,16 +28,16 @@ export default class SettingsMembersSubscriptionAccess extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get selectedOption() {
|
get selectedOption() {
|
||||||
return this.options.find(o => o.value === this.settings.get('membersSignupAccess'));
|
return this.options.find(o => o.value === this.settings.membersSignupAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setSignupAccess(option) {
|
setSignupAccess(option) {
|
||||||
this.settings.set('membersSignupAccess', option.value);
|
this.settings.membersSignupAccess = option.value;
|
||||||
this.args.onChange?.(option.value);
|
this.args.onChange?.(option.value);
|
||||||
|
|
||||||
if (option.value === 'none') {
|
if (option.value === 'none') {
|
||||||
this.settings.set('defaultContentVisibility', 'public');
|
this.settings.defaultContentVisibility = 'public';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,20 +57,20 @@ export default class StripeSettingsForm extends Component {
|
|||||||
|
|
||||||
/** OLD **/
|
/** OLD **/
|
||||||
get stripeDirectPublicKey() {
|
get stripeDirectPublicKey() {
|
||||||
return this.settings.get('stripePublishableKey');
|
return this.settings.stripePublishableKey;
|
||||||
}
|
}
|
||||||
get stripeDirectSecretKey() {
|
get stripeDirectSecretKey() {
|
||||||
return this.settings.settings.get('stripeSecretKey');
|
return this.settings.stripeSecretKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stripeConnectAccountId() {
|
get stripeConnectAccountId() {
|
||||||
return this.settings.get('stripeConnectAccountId');
|
return this.settings.stripeConnectAccountId;
|
||||||
}
|
}
|
||||||
get stripeConnectAccountName() {
|
get stripeConnectAccountName() {
|
||||||
return this.settings.get('stripeConnectDisplayName');
|
return this.settings.stripeConnectDisplayName;
|
||||||
}
|
}
|
||||||
get stripeConnectLivemode() {
|
get stripeConnectLivemode() {
|
||||||
return this.settings.get('stripeConnectLivemode');
|
return this.settings.stripeConnectLivemode;
|
||||||
}
|
}
|
||||||
|
|
||||||
get selectedCurrency() {
|
get selectedCurrency() {
|
||||||
@ -79,7 +79,7 @@ export default class StripeSettingsForm extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get stripePlans() {
|
get stripePlans() {
|
||||||
const plans = this.settings.get('stripePlans');
|
const plans = this.settings.stripePlans;
|
||||||
const monthly = plans.find(plan => plan.interval === 'month');
|
const monthly = plans.find(plan => plan.interval === 'month');
|
||||||
const yearly = plans.find(plan => plan.interval === 'year' && plan.name !== 'Complimentary');
|
const yearly = plans.find(plan => plan.interval === 'year' && plan.name !== 'Complimentary');
|
||||||
|
|
||||||
@ -112,14 +112,14 @@ export default class StripeSettingsForm extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
setStripeDirectPublicKey(event) {
|
setStripeDirectPublicKey(event) {
|
||||||
this.settings.set('stripeProductName', this.settings.get('title'));
|
this.settings.stripeProductName = this.settings.title;
|
||||||
this.settings.set('stripePublishableKey', event.target.value);
|
this.settings.stripePublishableKey = event.target.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setStripeDirectSecretKey(event) {
|
setStripeDirectSecretKey(event) {
|
||||||
this.settings.set('stripeProductName', this.settings.get('title'));
|
this.settings.stripeProductName = this.settings.title;
|
||||||
this.settings.set('stripeSecretKey', event.target.value);
|
this.settings.stripeSecretKey = event.target.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -130,7 +130,7 @@ export default class StripeSettingsForm extends Component {
|
|||||||
@action
|
@action
|
||||||
setStripePlansCurrency(event) {
|
setStripePlansCurrency(event) {
|
||||||
const newCurrency = event.value;
|
const newCurrency = event.value;
|
||||||
const updatedPlans = this.settings.get('stripePlans').map((plan) => {
|
const updatedPlans = this.settings.stripePlans.map((plan) => {
|
||||||
if (plan.name !== 'Complimentary') {
|
if (plan.name !== 'Complimentary') {
|
||||||
return Object.assign({}, plan, {
|
return Object.assign({}, plan, {
|
||||||
currency: newCurrency
|
currency: newCurrency
|
||||||
@ -152,7 +152,7 @@ export default class StripeSettingsForm extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.settings.set('stripePlans', updatedPlans);
|
this.settings.stripePlans = updatedPlans;
|
||||||
this._scratchStripeYearlyAmount = null;
|
this._scratchStripeYearlyAmount = null;
|
||||||
this._scratchStripeMonthlyAmount = null;
|
this._scratchStripeMonthlyAmount = null;
|
||||||
this.validateStripePlans();
|
this.validateStripePlans();
|
||||||
@ -160,7 +160,7 @@ export default class StripeSettingsForm extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
setStripeConnectIntegrationToken(event) {
|
setStripeConnectIntegrationToken(event) {
|
||||||
this.settings.set('stripeProductName', this.settings.get('title'));
|
this.settings.stripeProductName = this.settings.title;
|
||||||
this.args.setStripeConnectIntegrationTokenSetting(event.target.value);
|
this.args.setStripeConnectIntegrationTokenSetting(event.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,13 +183,13 @@ export default class StripeSettingsForm extends Component {
|
|||||||
updateStripeDirect() {
|
updateStripeDirect() {
|
||||||
// Allow disabling stripe direct keys if stripe is still enabled, while the config is disabled
|
// Allow disabling stripe direct keys if stripe is still enabled, while the config is disabled
|
||||||
this.stripeDirect = this.config.get('stripeDirect')
|
this.stripeDirect = this.config.get('stripeDirect')
|
||||||
|| (this.membersUtils.isStripeEnabled && !this.settings.get('stripeConnectAccountId'));
|
|| (this.membersUtils.isStripeEnabled && !this.settings.stripeConnectAccountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
validateStripePlans() {
|
validateStripePlans() {
|
||||||
this.settings.get('errors').remove('stripePlans');
|
this.settings.errors.remove('stripePlans');
|
||||||
this.settings.get('hasValidated').removeObject('stripePlans');
|
this.settings.hasValidated.removeObject('stripePlans');
|
||||||
|
|
||||||
if (this._scratchStripeYearlyAmount === null) {
|
if (this._scratchStripeYearlyAmount === null) {
|
||||||
this._scratchStripeYearlyAmount = this.stripePlans.yearly.amount;
|
this._scratchStripeYearlyAmount = this.stripePlans.yearly.amount;
|
||||||
@ -203,7 +203,7 @@ export default class StripeSettingsForm extends Component {
|
|||||||
const yearlyAmount = parseInt(this._scratchStripeYearlyAmount);
|
const yearlyAmount = parseInt(this._scratchStripeYearlyAmount);
|
||||||
const monthlyAmount = parseInt(this._scratchStripeMonthlyAmount);
|
const monthlyAmount = parseInt(this._scratchStripeMonthlyAmount);
|
||||||
if (!yearlyAmount || yearlyAmount < 1 || !monthlyAmount || monthlyAmount < 1) {
|
if (!yearlyAmount || yearlyAmount < 1 || !monthlyAmount || monthlyAmount < 1) {
|
||||||
const minimum = Intl.NumberFormat(this.settings.get('locale'), {
|
const minimum = Intl.NumberFormat(this.settings.locale, {
|
||||||
currency: selectedCurrency.isoCode,
|
currency: selectedCurrency.isoCode,
|
||||||
style: 'currency'
|
style: 'currency'
|
||||||
}).format(1);
|
}).format(1);
|
||||||
@ -211,7 +211,7 @@ export default class StripeSettingsForm extends Component {
|
|||||||
throw new TypeError(`Subscription amount must be at least ${minimum}`);
|
throw new TypeError(`Subscription amount must be at least ${minimum}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedPlans = this.settings.get('stripePlans').map((plan) => {
|
const updatedPlans = this.settings.stripePlans.map((plan) => {
|
||||||
if (plan.name !== 'Complimentary') {
|
if (plan.name !== 'Complimentary') {
|
||||||
let newAmount;
|
let newAmount;
|
||||||
if (plan.interval === 'year') {
|
if (plan.interval === 'year') {
|
||||||
@ -226,11 +226,11 @@ export default class StripeSettingsForm extends Component {
|
|||||||
return plan;
|
return plan;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.settings.set('stripePlans', updatedPlans);
|
this.settings.stripePlans = updatedPlans;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.settings.get('errors').add('stripePlans', err.message);
|
this.settings.errors.add('stripePlans', err.message);
|
||||||
} finally {
|
} finally {
|
||||||
this.settings.get('hasValidated').pushObject('stripePlans');
|
this.settings.hasValidated.pushObject('stripePlans');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,12 +296,12 @@ export default class StripeSettingsForm extends Component {
|
|||||||
*saveStripeSettingsTask() {
|
*saveStripeSettingsTask() {
|
||||||
this.stripeConnectError = null;
|
this.stripeConnectError = null;
|
||||||
|
|
||||||
if (this.settings.get('stripeConnectIntegrationToken')) {
|
if (this.settings.stripeConnectIntegrationToken) {
|
||||||
try {
|
try {
|
||||||
let response = yield this.settings.save();
|
let response = yield this.settings.save();
|
||||||
|
|
||||||
yield this.saveTier.perform();
|
yield this.saveTier.perform();
|
||||||
this.settings.set('portalPlans', ['free', 'monthly', 'yearly']);
|
this.settings.portalPlans = ['free', 'monthly', 'yearly'];
|
||||||
|
|
||||||
response = yield this.settings.save();
|
response = yield this.settings.save();
|
||||||
|
|
||||||
|
@ -20,46 +20,46 @@ export default class Newsletters extends Component {
|
|||||||
mailgunRegions = [US, EU];
|
mailgunRegions = [US, EU];
|
||||||
|
|
||||||
get emailNewsletterEnabled() {
|
get emailNewsletterEnabled() {
|
||||||
return this.settings.get('editorDefaultEmailRecipients') !== 'disabled';
|
return this.settings.editorDefaultEmailRecipients !== 'disabled';
|
||||||
}
|
}
|
||||||
|
|
||||||
get mailgunRegion() {
|
get mailgunRegion() {
|
||||||
if (!this.settings.get('mailgunBaseUrl')) {
|
if (!this.settings.mailgunBaseUrl) {
|
||||||
return US;
|
return US;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [US, EU].find((region) => {
|
return [US, EU].find((region) => {
|
||||||
return region.baseUrl === this.settings.get('mailgunBaseUrl');
|
return region.baseUrl === this.settings.mailgunBaseUrl;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get mailgunSettings() {
|
get mailgunSettings() {
|
||||||
return {
|
return {
|
||||||
apiKey: this.settings.get('mailgunApiKey') || '',
|
apiKey: this.settings.mailgunApiKey || '',
|
||||||
domain: this.settings.get('mailgunDomain') || '',
|
domain: this.settings.mailgunDomain || '',
|
||||||
baseUrl: this.settings.get('mailgunBaseUrl') || ''
|
baseUrl: this.settings.mailgunBaseUrl || ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setMailgunDomain(event) {
|
setMailgunDomain(event) {
|
||||||
this.settings.set('mailgunDomain', event.target.value);
|
this.settings.mailgunDomain = event.target.value;
|
||||||
if (!this.settings.get('mailgunBaseUrl')) {
|
if (!this.settings.mailgunBaseUrl) {
|
||||||
this.settings.set('mailgunBaseUrl', this.mailgunRegion.baseUrl);
|
this.settings.mailgunBaseUrl = this.mailgunRegion.baseUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setMailgunApiKey(event) {
|
setMailgunApiKey(event) {
|
||||||
this.settings.set('mailgunApiKey', event.target.value);
|
this.settings.mailgunApiKey = event.target.value;
|
||||||
if (!this.settings.get('mailgunBaseUrl')) {
|
if (!this.settings.mailgunBaseUrl) {
|
||||||
this.settings.set('mailgunBaseUrl', this.mailgunRegion.baseUrl);
|
this.settings.mailgunBaseUrl = this.mailgunRegion.baseUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setMailgunRegion(region) {
|
setMailgunRegion(region) {
|
||||||
this.settings.set('mailgunBaseUrl', region.baseUrl);
|
this.settings.mailgunBaseUrl = region.baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -67,7 +67,7 @@ export default class Newsletters extends Component {
|
|||||||
if (event) {
|
if (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
this.settings.set('emailTrackOpens', !this.settings.get('emailTrackOpens'));
|
this.settings.emailTrackOpens = !this.settings.emailTrackOpens;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -75,7 +75,7 @@ export default class Newsletters extends Component {
|
|||||||
if (event) {
|
if (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
this.settings.set('emailTrackClicks', !this.settings.get('emailTrackClicks'));
|
this.settings.emailTrackClicks = !this.settings.emailTrackClicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -87,10 +87,10 @@ export default class Newsletters extends Component {
|
|||||||
const newsletterEnabled = !this.emailNewsletterEnabled;
|
const newsletterEnabled = !this.emailNewsletterEnabled;
|
||||||
|
|
||||||
if (newsletterEnabled) {
|
if (newsletterEnabled) {
|
||||||
this.settings.set('editorDefaultEmailRecipients', 'visibility');
|
this.settings.editorDefaultEmailRecipients = 'visibility';
|
||||||
} else {
|
} else {
|
||||||
this.settings.set('editorDefaultEmailRecipients', 'disabled');
|
this.settings.editorDefaultEmailRecipients = 'disabled';
|
||||||
this.settings.set('editorDefaultEmailRecipientsFilter', null);
|
this.settings.editorDefaultEmailRecipientsFilter = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.recipientsSelectValue = this._getDerivedRecipientsSelectValue();
|
this.recipientsSelectValue = this._getDerivedRecipientsSelectValue();
|
||||||
@ -106,22 +106,22 @@ export default class Newsletters extends Component {
|
|||||||
// Update the underlying setting properties to match the selected recipients option
|
// Update the underlying setting properties to match the selected recipients option
|
||||||
|
|
||||||
if (['visibility', 'disabled'].includes(value)) {
|
if (['visibility', 'disabled'].includes(value)) {
|
||||||
this.settings.set('editorDefaultEmailRecipients', value);
|
this.settings.editorDefaultEmailRecipients = value;
|
||||||
this.settings.set('editorDefaultEmailRecipientsFilter', null);
|
this.settings.editorDefaultEmailRecipientsFilter = null;
|
||||||
} else {
|
} else {
|
||||||
this.settings.set('editorDefaultEmailRecipients', 'filter');
|
this.settings.editorDefaultEmailRecipients = 'filter';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === 'all-members') {
|
if (value === 'all-members') {
|
||||||
this.settings.set('editorDefaultEmailRecipientsFilter', 'status:free,status:-free');
|
this.settings.editorDefaultEmailRecipientsFilter = 'status:free,status:-free';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === 'paid-only') {
|
if (value === 'paid-only') {
|
||||||
this.settings.set('editorDefaultEmailRecipientsFilter', 'status:-free');
|
this.settings.editorDefaultEmailRecipientsFilter = 'status:-free';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === 'none') {
|
if (value === 'none') {
|
||||||
this.settings.set('editorDefaultEmailRecipientsFilter', null);
|
this.settings.editorDefaultEmailRecipientsFilter = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the value used to display the selected recipients option explicitly
|
// Update the value used to display the selected recipients option explicitly
|
||||||
@ -131,12 +131,12 @@ export default class Newsletters extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
setDefaultEmailRecipientsFilter(filter) {
|
setDefaultEmailRecipientsFilter(filter) {
|
||||||
this.settings.set('editorDefaultEmailRecipientsFilter', filter);
|
this.settings.editorDefaultEmailRecipientsFilter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getDerivedRecipientsSelectValue() {
|
_getDerivedRecipientsSelectValue() {
|
||||||
const defaultEmailRecipients = this.settings.get('editorDefaultEmailRecipients');
|
const defaultEmailRecipients = this.settings.editorDefaultEmailRecipients;
|
||||||
const defaultEmailRecipientsFilter = this.settings.get('editorDefaultEmailRecipientsFilter');
|
const defaultEmailRecipientsFilter = this.settings.editorDefaultEmailRecipientsFilter;
|
||||||
|
|
||||||
if (defaultEmailRecipients === 'filter') {
|
if (defaultEmailRecipients === 'filter') {
|
||||||
if (defaultEmailRecipientsFilter === 'status:free,status:-free') {
|
if (defaultEmailRecipientsFilter === 'status:free,status:-free') {
|
||||||
|
@ -21,7 +21,7 @@ export default class TagForm extends Component {
|
|||||||
@tracked codeInjectionOpen = false;
|
@tracked codeInjectionOpen = false;
|
||||||
|
|
||||||
get seoTitle() {
|
get seoTitle() {
|
||||||
const settingsTitle = this.settings.get('title') || '';
|
const settingsTitle = this.settings.title || '';
|
||||||
const tagName = settingsTitle ? `${this.args.tag.name} - ${settingsTitle}` : this.args.tag.name;
|
const tagName = settingsTitle ? `${this.args.tag.name} - ${settingsTitle}` : this.args.tag.name;
|
||||||
let metaTitle = this.args.tag.metaTitle || tagName;
|
let metaTitle = this.args.tag.metaTitle || tagName;
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ export default class TagForm extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get twitterDescription() {
|
get twitterDescription() {
|
||||||
return this.args.tag.twitterDescription || this.seoDescription || this.settings.get('metaDescription') || '';
|
return this.args.tag.twitterDescription || this.seoDescription || this.settings.metaDescription || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
get twitterImage() {
|
get twitterImage() {
|
||||||
@ -86,7 +86,7 @@ export default class TagForm extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get facebookDescription() {
|
get facebookDescription() {
|
||||||
return this.args.tag.facebookDescription || this.seoDescription || this.settings.get('metaDescription') || '';
|
return this.args.tag.facebookDescription || this.seoDescription || this.settings.metaDescription || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
get facebookImage() {
|
get facebookImage() {
|
||||||
|
@ -1039,7 +1039,7 @@ export default class EditorController extends Controller {
|
|||||||
emailOnly,
|
emailOnly,
|
||||||
newsletter
|
newsletter
|
||||||
} = this.post;
|
} = this.post;
|
||||||
let publishedAtBlogTZ = moment.tz(publishedAtUTC, this.settings.get('timezone'));
|
let publishedAtBlogTZ = moment.tz(publishedAtUTC, this.settings.timezone);
|
||||||
|
|
||||||
let title = 'Scheduled';
|
let title = 'Scheduled';
|
||||||
let description = emailOnly ? ['Will be sent'] : ['Will be published'];
|
let description = emailOnly ? ['Will be sent'] : ['Will be published'];
|
||||||
|
@ -1035,7 +1035,7 @@ export default class LexicalEditorController extends Controller {
|
|||||||
emailOnly,
|
emailOnly,
|
||||||
newsletter
|
newsletter
|
||||||
} = this.post;
|
} = this.post;
|
||||||
let publishedAtBlogTZ = moment.tz(publishedAtUTC, this.settings.get('timezone'));
|
let publishedAtBlogTZ = moment.tz(publishedAtUTC, this.settings.timezone);
|
||||||
|
|
||||||
let title = 'Scheduled';
|
let title = 'Scheduled';
|
||||||
let description = emailOnly ? ['Will be sent'] : ['Will be published'];
|
let description = emailOnly ? ['Will be sent'] : ['Will be published'];
|
||||||
|
@ -24,7 +24,7 @@ export default class MembersActivityController extends Controller {
|
|||||||
hiddenEvents.push(...EMAIL_EVENTS);
|
hiddenEvents.push(...EMAIL_EVENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.settings.get('editorDefaultEmailRecipients') === 'disabled') {
|
if (this.settings.editorDefaultEmailRecipients === 'disabled') {
|
||||||
hiddenEvents.push(...EMAIL_EVENTS, ...NEWSLETTER_EVENTS);
|
hiddenEvents.push(...EMAIL_EVENTS, ...NEWSLETTER_EVENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ export default class SettingsDesignIndexController extends Controller {
|
|||||||
@task
|
@task
|
||||||
*saveTask() {
|
*saveTask() {
|
||||||
try {
|
try {
|
||||||
if (this.settings.get('errors').length !== 0) {
|
if (this.settings.errors.length !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ export default class GeneralController extends Controller {
|
|||||||
@computed('config.blogUrl', 'settings.publicHash')
|
@computed('config.blogUrl', 'settings.publicHash')
|
||||||
get privateRSSUrl() {
|
get privateRSSUrl() {
|
||||||
let blogUrl = this.get('config.blogUrl');
|
let blogUrl = this.get('config.blogUrl');
|
||||||
let publicHash = this.get('settings.publicHash');
|
let publicHash = this.settings.publicHash;
|
||||||
|
|
||||||
return `${blogUrl}/${publicHash}/rss`;
|
return `${blogUrl}/${publicHash}/rss`;
|
||||||
}
|
}
|
||||||
@ -51,13 +51,13 @@ export default class GeneralController extends Controller {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
setTimezone(timezone) {
|
setTimezone(timezone) {
|
||||||
this.set('settings.timezone', timezone.name);
|
this.settings.timezone = timezone.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
removeImage(image) {
|
removeImage(image) {
|
||||||
// setting `null` here will error as the server treats it as "null"
|
// setting `null` here will error as the server treats it as "null"
|
||||||
this.settings.set(image, '');
|
this.settings[image] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,7 +80,7 @@ export default class GeneralController extends Controller {
|
|||||||
@action
|
@action
|
||||||
imageUploaded(property, results) {
|
imageUploaded(property, results) {
|
||||||
if (results[0]) {
|
if (results[0]) {
|
||||||
return this.settings.set(property, results[0].url);
|
return this.settings[property] = results[0].url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,18 +88,18 @@ export default class GeneralController extends Controller {
|
|||||||
toggleIsPrivate(isPrivate) {
|
toggleIsPrivate(isPrivate) {
|
||||||
let settings = this.settings;
|
let settings = this.settings;
|
||||||
|
|
||||||
settings.set('isPrivate', isPrivate);
|
settings.isPrivate = isPrivate;
|
||||||
settings.get('errors').remove('password');
|
settings.errors.remove('password');
|
||||||
|
|
||||||
let changedAttrs = settings.changedAttributes();
|
let changedAttrs = settings.changedAttributes();
|
||||||
|
|
||||||
// set a new random password when isPrivate is enabled
|
// set a new random password when isPrivate is enabled
|
||||||
if (isPrivate && changedAttrs.isPrivate) {
|
if (isPrivate && changedAttrs.isPrivate) {
|
||||||
settings.set('password', randomPassword());
|
settings.password = randomPassword();
|
||||||
|
|
||||||
// reset the password when isPrivate is disabled
|
// reset the password when isPrivate is disabled
|
||||||
} else if (changedAttrs.password) {
|
} else if (changedAttrs.password) {
|
||||||
settings.set('password', changedAttrs.password[0]);
|
settings.password = changedAttrs.password[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ export default class GeneralController extends Controller {
|
|||||||
|
|
||||||
this.clearScratchValues();
|
this.clearScratchValues();
|
||||||
|
|
||||||
config.set('blogTitle', settings.get('title'));
|
config.set('blogTitle', settings.title);
|
||||||
|
|
||||||
if (changedAttrs.password) {
|
if (changedAttrs.password) {
|
||||||
this.frontend.loginIfNeeded();
|
this.frontend.loginIfNeeded();
|
||||||
|
@ -9,7 +9,7 @@ export default class AmpController extends Controller {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
update(value) {
|
update(value) {
|
||||||
this.settings.set('amp', value);
|
this.settings.amp = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -9,7 +9,7 @@ export default class FirstpromoterController extends Controller {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
update(value) {
|
update(value) {
|
||||||
this.settings.set('firstpromoter', value);
|
this.settings.firstpromoter = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -11,7 +11,7 @@ export default class SlackController extends Controller {
|
|||||||
@service settings;
|
@service settings;
|
||||||
|
|
||||||
get testNotificationDisabled() {
|
get testNotificationDisabled() {
|
||||||
const slackUrl = this.settings.get('slackUrl');
|
const slackUrl = this.settings.slackUrl;
|
||||||
return !slackUrl;
|
return !slackUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ export default class UnsplashController extends Controller {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
update(value) {
|
update(value) {
|
||||||
this.settings.set('unsplash', value);
|
this.settings.unsplash = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -119,7 +119,7 @@ export default class LabsController extends Controller {
|
|||||||
// reload settings
|
// reload settings
|
||||||
return this.settings.reload().then((settings) => {
|
return this.settings.reload().then((settings) => {
|
||||||
this.feature.fetch();
|
this.feature.fetch();
|
||||||
this.config.set('blogTitle', settings.get('title'));
|
this.config.set('blogTitle', settings.title);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).catch((response) => {
|
}).catch((response) => {
|
||||||
|
@ -94,7 +94,7 @@ export default class MembersAccessController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get isDirty() {
|
get isDirty() {
|
||||||
return this.settings.get('hasDirtyAttributes') || this.hasChangedPrices;
|
return this.settings.hasDirtyAttributes || this.hasChangedPrices;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -239,7 +239,7 @@ export default class MembersAccessController extends Controller {
|
|||||||
// TODO: can these be worked out from settings in membersUtils?
|
// TODO: can these be worked out from settings in membersUtils?
|
||||||
const monthlyPrice = Math.round(this.stripeMonthlyAmount * 100);
|
const monthlyPrice = Math.round(this.stripeMonthlyAmount * 100);
|
||||||
const yearlyPrice = Math.round(this.stripeYearlyAmount * 100);
|
const yearlyPrice = Math.round(this.stripeYearlyAmount * 100);
|
||||||
let portalPlans = this.settings.get('portalPlans') || [];
|
let portalPlans = this.settings.portalPlans || [];
|
||||||
|
|
||||||
let isMonthlyChecked = portalPlans.includes('monthly');
|
let isMonthlyChecked = portalPlans.includes('monthly');
|
||||||
let isYearlyChecked = portalPlans.includes('yearly');
|
let isYearlyChecked = portalPlans.includes('yearly');
|
||||||
@ -339,11 +339,11 @@ export default class MembersAccessController extends Controller {
|
|||||||
|
|
||||||
@task({drop: true})
|
@task({drop: true})
|
||||||
*saveSettingsTask(options) {
|
*saveSettingsTask(options) {
|
||||||
if (this.settings.get('errors').length !== 0) {
|
if (this.settings.errors.length !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// When no filer is selected in `Specific tier(s)` option
|
// When no filer is selected in `Specific tier(s)` option
|
||||||
if (!this.settings.get('defaultContentVisibility')) {
|
if (!this.settings.defaultContentVisibility) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const result = yield this.settings.save();
|
const result = yield this.settings.save();
|
||||||
@ -353,7 +353,7 @@ export default class MembersAccessController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async saveTier() {
|
async saveTier() {
|
||||||
const paidMembersEnabled = this.settings.get('paidMembersEnabled');
|
const paidMembersEnabled = this.settings.paidMembersEnabled;
|
||||||
if (this.tier && paidMembersEnabled) {
|
if (this.tier && paidMembersEnabled) {
|
||||||
const monthlyAmount = Math.round(this.stripeMonthlyAmount * 100);
|
const monthlyAmount = Math.round(this.stripeMonthlyAmount * 100);
|
||||||
const yearlyAmount = Math.round(this.stripeYearlyAmount * 100);
|
const yearlyAmount = Math.round(this.stripeYearlyAmount * 100);
|
||||||
@ -385,12 +385,12 @@ export default class MembersAccessController extends Controller {
|
|||||||
_validateSignupRedirect(url, type) {
|
_validateSignupRedirect(url, type) {
|
||||||
const siteUrl = this.config.get('blogUrl');
|
const siteUrl = this.config.get('blogUrl');
|
||||||
let errMessage = `Please enter a valid URL`;
|
let errMessage = `Please enter a valid URL`;
|
||||||
this.settings.get('errors').remove(type);
|
this.settings.errors.remove(type);
|
||||||
this.settings.get('hasValidated').removeObject(type);
|
this.settings.hasValidated.removeObject(type);
|
||||||
|
|
||||||
if (url === null) {
|
if (url === null) {
|
||||||
this.settings.get('errors').add(type, errMessage);
|
this.settings.errors.add(type, errMessage);
|
||||||
this.settings.get('hasValidated').pushObject(type);
|
this.settings.hasValidated.pushObject(type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,9 +401,9 @@ export default class MembersAccessController extends Controller {
|
|||||||
|
|
||||||
if (url.href.startsWith(siteUrl)) {
|
if (url.href.startsWith(siteUrl)) {
|
||||||
const path = url.href.replace(siteUrl, '');
|
const path = url.href.replace(siteUrl, '');
|
||||||
this.settings.set(type, path);
|
this.settings[type] = path;
|
||||||
} else {
|
} else {
|
||||||
this.settings.set(type, url.href);
|
this.settings[type] = url.href;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ export default class NavigationController extends Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let navItems = item.isSecondary ? this.get('settings.secondaryNavigation') : this.get('settings.navigation');
|
let navItems = item.isSecondary ? this.settings.secondaryNavigation : this.settings.navigation;
|
||||||
|
|
||||||
navItems.removeObject(item);
|
navItems.removeObject(item);
|
||||||
this.set('dirtyAttributes', true);
|
this.set('dirtyAttributes', true);
|
||||||
@ -95,7 +95,7 @@ export default class NavigationController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addNewNavItem(item) {
|
addNewNavItem(item) {
|
||||||
let navItems = item.isSecondary ? this.get('settings.secondaryNavigation') : this.get('settings.navigation');
|
let navItems = item.isSecondary ? this.settings.secondaryNavigation : this.settings.navigation;
|
||||||
|
|
||||||
item.set('isNew', false);
|
item.set('isNew', false);
|
||||||
navItems.pushObject(item);
|
navItems.pushObject(item);
|
||||||
@ -112,8 +112,8 @@ export default class NavigationController extends Controller {
|
|||||||
|
|
||||||
@task
|
@task
|
||||||
*saveTask() {
|
*saveTask() {
|
||||||
let navItems = this.get('settings.navigation');
|
let navItems = this.settings.navigation;
|
||||||
let secondaryNavItems = this.get('settings.secondaryNavigation');
|
let secondaryNavItems = this.settings.secondaryNavigation;
|
||||||
|
|
||||||
let notifications = this.notifications;
|
let notifications = this.notifications;
|
||||||
let validationPromises = [];
|
let validationPromises = [];
|
||||||
|
@ -170,7 +170,7 @@ export default class TierController extends Controller {
|
|||||||
if (this.tier.get('errors').length !== 0) {
|
if (this.tier.get('errors').length !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.settings.get('errors').length !== 0) {
|
if (this.settings.errors.length !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
yield this.settings.save();
|
yield this.settings.save();
|
||||||
@ -183,12 +183,12 @@ export default class TierController extends Controller {
|
|||||||
|
|
||||||
_validateSignupRedirect(url, type) {
|
_validateSignupRedirect(url, type) {
|
||||||
let errMessage = `Please enter a valid URL`;
|
let errMessage = `Please enter a valid URL`;
|
||||||
this.settings.get('errors').remove(type);
|
this.settings.errors.remove(type);
|
||||||
this.settings.get('hasValidated').removeObject(type);
|
this.settings.hasValidated.removeObject(type);
|
||||||
|
|
||||||
if (url === null) {
|
if (url === null) {
|
||||||
this.settings.get('errors').add(type, errMessage);
|
this.settings.errors.add(type, errMessage);
|
||||||
this.settings.get('hasValidated').pushObject(type);
|
this.settings.hasValidated.pushObject(type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,9 +199,9 @@ export default class TierController extends Controller {
|
|||||||
|
|
||||||
if (url.href.startsWith(this.siteUrl)) {
|
if (url.href.startsWith(this.siteUrl)) {
|
||||||
const path = url.href.replace(this.siteUrl, '');
|
const path = url.href.replace(this.siteUrl, '');
|
||||||
this.settings.set(type, path);
|
this.settings[type] = path;
|
||||||
} else {
|
} else {
|
||||||
this.settings.set(type, url.href);
|
this.settings[type] = url.href;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import Helper from '@ember/component/helper';
|
import Helper from '@ember/component/helper';
|
||||||
import {get} from '@ember/object';
|
|
||||||
import {inject as service} from '@ember/service';
|
import {inject as service} from '@ember/service';
|
||||||
|
|
||||||
export default class GetSetting extends Helper {
|
export default class GetSetting extends Helper {
|
||||||
@service settings;
|
@service settings;
|
||||||
|
|
||||||
compute([key = '']) {
|
compute([key = '']) {
|
||||||
return get(this.settings, key);
|
return this.settings[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,6 @@ export default class GhFormatPostTimeHelper extends Helper {
|
|||||||
compute([timeago], options) {
|
compute([timeago], options) {
|
||||||
assert('You must pass a time to the gh-format-post-time helper', timeago);
|
assert('You must pass a time to the gh-format-post-time helper', timeago);
|
||||||
|
|
||||||
return formatPostTime(timeago, Object.assign({}, options, {timezone: this.settings.get('timezone')}));
|
return formatPostTime(timeago, Object.assign({}, options, {timezone: this.settings.timezone}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ export default class IsMomentToday extends Helper {
|
|||||||
@service settings;
|
@service settings;
|
||||||
|
|
||||||
compute([date]) {
|
compute([date]) {
|
||||||
const today = moment().tz(this.settings.get('timezone'));
|
const today = moment().tz(this.settings.timezone);
|
||||||
const dateMoment = moment.tz(date, this.settings.get('timezone'));
|
const dateMoment = moment.tz(date, this.settings.timezone);
|
||||||
|
|
||||||
return dateMoment.isSame(today, 'day');
|
return dateMoment.isSame(today, 'day');
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,10 @@ export default class MembersEventFilter extends Helper {
|
|||||||
) {
|
) {
|
||||||
const excludedEventsSet = new Set();
|
const excludedEventsSet = new Set();
|
||||||
|
|
||||||
if (this.settings.get('editorDefaultEmailRecipients') === 'disabled') {
|
if (this.settings.editorDefaultEmailRecipients === 'disabled') {
|
||||||
[...EMAIL_EVENTS, ...NEWSLETTER_EVENTS].forEach(type => excludedEventsSet.add(type));
|
[...EMAIL_EVENTS, ...NEWSLETTER_EVENTS].forEach(type => excludedEventsSet.add(type));
|
||||||
}
|
}
|
||||||
if (this.settings.get('commentsEnabled') === 'off') {
|
if (this.settings.commentsEnabled === 'off') {
|
||||||
excludedEventsSet.add('comment_event');
|
excludedEventsSet.add('comment_event');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,6 @@ export default class MomentSiteTz extends Helper {
|
|||||||
@service settings;
|
@service settings;
|
||||||
|
|
||||||
compute([date]) {
|
compute([date]) {
|
||||||
return moment.tz(date, this.settings.get('timezone'));
|
return moment.tz(date, this.settings.timezone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,39 +185,39 @@ export default Model.extend(Comparable, ValidationEngine, {
|
|||||||
|
|
||||||
hasBeenEmailed: computed('isPost', 'isSent', 'isPublished', 'email', function () {
|
hasBeenEmailed: computed('isPost', 'isSent', 'isPublished', 'email', function () {
|
||||||
return this.isPost
|
return this.isPost
|
||||||
&& (this.isSent || this.isPublished)
|
&& (this.isSent || this.isPublished)
|
||||||
&& this.email && this.email.status !== 'failed';
|
&& this.email && this.email.status !== 'failed';
|
||||||
}),
|
}),
|
||||||
|
|
||||||
didEmailFail: computed('isPost', 'isSent', 'isPublished', 'email.status', function () {
|
didEmailFail: computed('isPost', 'isSent', 'isPublished', 'email.status', function () {
|
||||||
return this.isPost
|
return this.isPost
|
||||||
&& (this.isSent || this.isPublished)
|
&& (this.isSent || this.isPublished)
|
||||||
&& this.email && this.email.status === 'failed';
|
&& this.email && this.email.status === 'failed';
|
||||||
}),
|
}),
|
||||||
|
|
||||||
showEmailOpenAnalytics: computed('hasBeenEmailed', 'isSent', 'isPublished', function () {
|
showEmailOpenAnalytics: computed('hasBeenEmailed', 'isSent', 'isPublished', function () {
|
||||||
return this.hasBeenEmailed
|
return this.hasBeenEmailed
|
||||||
&& !this.session.user.isContributor
|
&& !this.session.user.isContributor
|
||||||
&& this.settings.get('membersSignupAccess') !== 'none'
|
&& this.settings.membersSignupAccess !== 'none'
|
||||||
&& this.settings.get('editorDefaultEmailRecipients') !== 'disabled'
|
&& this.settings.editorDefaultEmailRecipients !== 'disabled'
|
||||||
&& this.hasBeenEmailed
|
&& this.hasBeenEmailed
|
||||||
&& this.email.trackOpens
|
&& this.email.trackOpens
|
||||||
&& this.settings.get('emailTrackOpens');
|
&& this.settings.emailTrackOpens;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
showEmailClickAnalytics: computed('hasBeenEmailed', 'isSent', 'isPublished', 'email', function () {
|
showEmailClickAnalytics: computed('hasBeenEmailed', 'isSent', 'isPublished', 'email', function () {
|
||||||
return this.hasBeenEmailed
|
return this.hasBeenEmailed
|
||||||
&& !this.session.user.isContributor
|
&& !this.session.user.isContributor
|
||||||
&& this.settings.get('membersSignupAccess') !== 'none'
|
&& this.settings.membersSignupAccess !== 'none'
|
||||||
&& this.settings.get('editorDefaultEmailRecipients') !== 'disabled'
|
&& this.settings.editorDefaultEmailRecipients !== 'disabled'
|
||||||
&& (this.isSent || this.isPublished)
|
&& (this.isSent || this.isPublished)
|
||||||
&& this.email.trackClicks
|
&& this.email.trackClicks
|
||||||
&& this.settings.get('emailTrackClicks');
|
&& this.settings.emailTrackClicks;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
showAttributionAnalytics: computed('isPage', 'emailOnly', 'isPublished', 'membersUtils.isMembersInviteOnly', function () {
|
showAttributionAnalytics: computed('isPage', 'emailOnly', 'isPublished', 'membersUtils.isMembersInviteOnly', function () {
|
||||||
return (this.isPage || !this.emailOnly)
|
return (this.isPage || !this.emailOnly)
|
||||||
&& this.isPublished
|
&& this.isPublished
|
||||||
&& this.feature.get('memberAttribution')
|
&& this.feature.get('memberAttribution')
|
||||||
&& !this.membersUtils.isMembersInviteOnly
|
&& !this.membersUtils.isMembersInviteOnly
|
||||||
&& !this.session.user.isContributor;
|
&& !this.session.user.isContributor;
|
||||||
@ -233,7 +233,7 @@ export default Model.extend(Comparable, ValidationEngine, {
|
|||||||
|| this.showAttributionAnalytics
|
|| this.showAttributionAnalytics
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
previewUrl: computed('uuid', 'ghostPaths.url', 'config.blogUrl', function () {
|
previewUrl: computed('uuid', 'ghostPaths.url', 'config.blogUrl', function () {
|
||||||
let blogUrl = this.get('config.blogUrl');
|
let blogUrl = this.get('config.blogUrl');
|
||||||
let uuid = this.uuid;
|
let uuid = this.uuid;
|
||||||
@ -252,7 +252,7 @@ export default Model.extend(Comparable, ValidationEngine, {
|
|||||||
|
|
||||||
visibilitySegment: computed('visibility', 'isPublic', 'tiers', function () {
|
visibilitySegment: computed('visibility', 'isPublic', 'tiers', function () {
|
||||||
if (this.isPublic) {
|
if (this.isPublic) {
|
||||||
return this.settings.get('defaultContentVisibility') === 'paid' ? 'status:-free' : 'status:free,status:-free';
|
return this.settings.defaultContentVisibility === 'paid' ? 'status:-free' : 'status:free,status:-free';
|
||||||
} else {
|
} else {
|
||||||
if (this.visibility === 'members') {
|
if (this.visibility === 'members') {
|
||||||
return 'status:free,status:-free';
|
return 'status:free,status:-free';
|
||||||
@ -321,7 +321,7 @@ export default Model.extend(Comparable, ValidationEngine, {
|
|||||||
let publishedAtUTC = this.publishedAtUTC;
|
let publishedAtUTC = this.publishedAtUTC;
|
||||||
let publishedAtBlogDate = this.publishedAtBlogDate;
|
let publishedAtBlogDate = this.publishedAtBlogDate;
|
||||||
let publishedAtBlogTime = this.publishedAtBlogTime;
|
let publishedAtBlogTime = this.publishedAtBlogTime;
|
||||||
let blogTimezone = this.get('settings.timezone');
|
let blogTimezone = this.settings.timezone;
|
||||||
|
|
||||||
if (!publishedAtUTC && isBlank(publishedAtBlogDate) && isBlank(publishedAtBlogTime)) {
|
if (!publishedAtUTC && isBlank(publishedAtBlogDate) && isBlank(publishedAtBlogTime)) {
|
||||||
return null;
|
return null;
|
||||||
@ -362,7 +362,7 @@ export default Model.extend(Comparable, ValidationEngine, {
|
|||||||
|
|
||||||
_setPublishedAtBlogStrings(momentDate) {
|
_setPublishedAtBlogStrings(momentDate) {
|
||||||
if (momentDate) {
|
if (momentDate) {
|
||||||
let blogTimezone = this.get('settings.timezone');
|
let blogTimezone = this.settings.timezone;
|
||||||
let publishedAtBlog = moment.tz(momentDate, blogTimezone);
|
let publishedAtBlog = moment.tz(momentDate, blogTimezone);
|
||||||
|
|
||||||
this.set('publishedAtBlogDate', publishedAtBlog.format('YYYY-MM-DD'));
|
this.set('publishedAtBlogDate', publishedAtBlog.format('YYYY-MM-DD'));
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
/* eslint-disable camelcase */
|
|
||||||
import Model, {attr} from '@ember-data/model';
|
import Model, {attr} from '@ember-data/model';
|
||||||
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
|
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
|
||||||
import {and} from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Model.extend(ValidationEngine, {
|
export default Model.extend(ValidationEngine, {
|
||||||
validationType: 'setting',
|
validationType: 'setting',
|
||||||
@ -84,8 +82,6 @@ export default Model.extend(ValidationEngine, {
|
|||||||
editorDefaultEmailRecipientsFilter: attr('members-segment-string'),
|
editorDefaultEmailRecipientsFilter: attr('members-segment-string'),
|
||||||
emailVerificationRequired: attr('boolean'),
|
emailVerificationRequired: attr('boolean'),
|
||||||
|
|
||||||
mailgunIsConfigured: and('mailgunApiKey', 'mailgunDomain', 'mailgunBaseUrl'),
|
|
||||||
|
|
||||||
// HACK - not a real model attribute but a workaround for Ember Data not
|
// HACK - not a real model attribute but a workaround for Ember Data not
|
||||||
// exposing meta from save responses
|
// exposing meta from save responses
|
||||||
_meta: attr()
|
_meta: attr()
|
||||||
|
@ -45,7 +45,7 @@ export default class CodeInjectionRoute extends AdminRoute {
|
|||||||
async confirmUnsavedChanges() {
|
async confirmUnsavedChanges() {
|
||||||
const settings = this.settings;
|
const settings = this.settings;
|
||||||
|
|
||||||
if (settings.get('hasDirtyAttributes')) {
|
if (settings.hasDirtyAttributes) {
|
||||||
this.confirmModal = this.modals
|
this.confirmModal = this.modals
|
||||||
.open(ConfirmUnsavedChangesModal)
|
.open(ConfirmUnsavedChangesModal)
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -36,7 +36,7 @@ export default class SettingsDesignIndexRoute extends AuthenticatedRoute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
confirmUnsavedChanges() {
|
confirmUnsavedChanges() {
|
||||||
if (!this.settings.get('hasDirtyAttributes') && !this.customThemeSettings.isDirty) {
|
if (!this.settings.hasDirtyAttributes && !this.customThemeSettings.isDirty) {
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ export default class GeneralSettingsRoute extends AdminRoute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async confirmUnsavedChanges() {
|
async confirmUnsavedChanges() {
|
||||||
if (this.settings.get('hasDirtyAttributes')) {
|
if (this.settings.hasDirtyAttributes) {
|
||||||
this.confirmModal = this.modals
|
this.confirmModal = this.modals
|
||||||
.open(ConfirmUnsavedChangesModal)
|
.open(ConfirmUnsavedChangesModal)
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -43,7 +43,7 @@ export default class AMPRoute extends AdminRoute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async confirmUnsavedChanges() {
|
async confirmUnsavedChanges() {
|
||||||
if (this.settings.get('hasDirtyAttributes')) {
|
if (this.settings.hasDirtyAttributes) {
|
||||||
this.confirmModal = this.modals
|
this.confirmModal = this.modals
|
||||||
.open(ConfirmUnsavedChangesModal)
|
.open(ConfirmUnsavedChangesModal)
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -43,7 +43,7 @@ export default class FirstPromotionIntegrationRoute extends AdminRoute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async confirmUnsavedChanges() {
|
async confirmUnsavedChanges() {
|
||||||
if (this.settings.get('hasDirtyAttributes')) {
|
if (this.settings.hasDirtyAttributes) {
|
||||||
this.confirmModal = this.modals
|
this.confirmModal = this.modals
|
||||||
.open(ConfirmUnsavedChangesModal)
|
.open(ConfirmUnsavedChangesModal)
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -43,7 +43,7 @@ export default class SlackIntegrationRoute extends AdminRoute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async confirmUnsavedChanges() {
|
async confirmUnsavedChanges() {
|
||||||
if (this.settings.get('hasDirtyAttributes')) {
|
if (this.settings.hasDirtyAttributes) {
|
||||||
this.confirmModal = this.modals
|
this.confirmModal = this.modals
|
||||||
.open(ConfirmUnsavedChangesModal)
|
.open(ConfirmUnsavedChangesModal)
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -43,7 +43,7 @@ export default class UnsplashIntegrationRoute extends AdminRoute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async confirmUnsavedChanges() {
|
async confirmUnsavedChanges() {
|
||||||
if (this.settings.get('hasDirtyAttributes')) {
|
if (this.settings.hasDirtyAttributes) {
|
||||||
this.confirmModal = this.modals
|
this.confirmModal = this.modals
|
||||||
.open(ConfirmUnsavedChangesModal)
|
.open(ConfirmUnsavedChangesModal)
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -58,7 +58,7 @@ export default class MembersEmailLabsRoute extends AdminRoute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
confirmUnsavedChanges() {
|
confirmUnsavedChanges() {
|
||||||
if (!this.settings.get('hasDirtyAttributes')) {
|
if (!this.settings.hasDirtyAttributes) {
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,7 @@ import EmberObject, {action} from '@ember/object';
|
|||||||
import Service, {inject as service} from '@ember/service';
|
import Service, {inject as service} from '@ember/service';
|
||||||
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
|
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
|
||||||
import {isArray} from '@ember/array';
|
import {isArray} from '@ember/array';
|
||||||
import {observes} from '@ember-decorators/object';
|
|
||||||
import {task} from 'ember-concurrency';
|
import {task} from 'ember-concurrency';
|
||||||
import {tracked} from '@glimmer/tracking';
|
|
||||||
|
|
||||||
const VIEW_COLORS = [
|
const VIEW_COLORS = [
|
||||||
'midgrey',
|
'midgrey',
|
||||||
@ -108,33 +106,23 @@ export default class CustomViewsService extends Service {
|
|||||||
@service session;
|
@service session;
|
||||||
@service settings;
|
@service settings;
|
||||||
|
|
||||||
@tracked viewList = [];
|
get viewList() {
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super(...arguments);
|
|
||||||
this.updateViewList();
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line ghost/ember/no-observers
|
|
||||||
@observes('settings.sharedViews', 'session.{isAuthenticated,user}')
|
|
||||||
async updateViewList() {
|
|
||||||
let {settings, session} = this;
|
let {settings, session} = this;
|
||||||
|
|
||||||
// avoid fetching user before authenticated otherwise the 403 can fire
|
// avoid fetching user before authenticated otherwise the 403 can fire
|
||||||
// during authentication and cause errors during setup/signin
|
// during authentication and cause errors during setup/signin
|
||||||
if (!session.isAuthenticated || !session.user) {
|
if (!session.isAuthenticated || !session.user) {
|
||||||
return;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
let views = JSON.parse(settings.get('sharedViews') || '[]');
|
let views = JSON.parse(settings.sharedViews || '[]');
|
||||||
views = isArray(views) ? views : [];
|
views = isArray(views) ? views : [];
|
||||||
|
|
||||||
let viewList = [];
|
const viewList = [];
|
||||||
|
|
||||||
// contributors can only see their own draft posts so it doesn't make
|
// contributors can only see their own draft posts so it doesn't make
|
||||||
// sense to show them default views which change the status/type filter
|
// sense to show them default views which change the status/type filter
|
||||||
let user = await session.user;
|
if (!session.user.isContributor) {
|
||||||
if (!user.isContributor) {
|
|
||||||
viewList.push(...DEFAULT_VIEWS);
|
viewList.push(...DEFAULT_VIEWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,15 +130,17 @@ export default class CustomViewsService extends Service {
|
|||||||
return CustomView.create(view);
|
return CustomView.create(view);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.viewList = viewList;
|
return viewList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@task
|
@task
|
||||||
*saveViewTask(view) {
|
*saveViewTask(view) {
|
||||||
yield view.validate();
|
yield view.validate();
|
||||||
|
|
||||||
|
const {viewList} = this;
|
||||||
|
|
||||||
// perform some ad-hoc validation of duplicate names because ValidationEngine doesn't support it
|
// perform some ad-hoc validation of duplicate names because ValidationEngine doesn't support it
|
||||||
let duplicateView = this.viewList.find((existingView) => {
|
let duplicateView = viewList.find((existingView) => {
|
||||||
return existingView.route === view.route
|
return existingView.route === view.route
|
||||||
&& existingView.name.trim().toLowerCase() === view.name.trim().toLowerCase()
|
&& existingView.name.trim().toLowerCase() === view.name.trim().toLowerCase()
|
||||||
&& !isFilterEqual(existingView.filter, view.filter);
|
&& !isFilterEqual(existingView.filter, view.filter);
|
||||||
@ -165,15 +155,15 @@ export default class CustomViewsService extends Service {
|
|||||||
// remove an older version of the view from our views list
|
// remove an older version of the view from our views list
|
||||||
// - we don't allow editing the filter and route+filter combos are unique
|
// - we don't allow editing the filter and route+filter combos are unique
|
||||||
// - we create a new instance of a view from an existing one when editing to act as a "scratch" view
|
// - we create a new instance of a view from an existing one when editing to act as a "scratch" view
|
||||||
let matchingView = this.viewList.find(existingView => isViewEqual(existingView, view));
|
let matchingView = viewList.find(existingView => isViewEqual(existingView, view));
|
||||||
if (matchingView) {
|
if (matchingView) {
|
||||||
this.viewList.replace(this.viewList.indexOf(matchingView), 1, [view]);
|
viewList.replace(viewList.indexOf(matchingView), 1, [view]);
|
||||||
} else {
|
} else {
|
||||||
this.viewList.push(view);
|
viewList.push(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rebuild the "views" array in our user settings json string
|
// rebuild the "views" array in our user settings json string
|
||||||
yield this._saveViewSettings();
|
yield this._saveViewSettings(viewList);
|
||||||
|
|
||||||
view.set('isNew', false);
|
view.set('isNew', false);
|
||||||
return view;
|
return view;
|
||||||
@ -181,10 +171,11 @@ export default class CustomViewsService extends Service {
|
|||||||
|
|
||||||
@task
|
@task
|
||||||
*deleteViewTask(view) {
|
*deleteViewTask(view) {
|
||||||
let matchingView = this.viewList.find(existingView => isViewEqual(existingView, view));
|
const {viewList} = this;
|
||||||
|
let matchingView = viewList.find(existingView => isViewEqual(existingView, view));
|
||||||
if (matchingView && !matchingView.isDefault) {
|
if (matchingView && !matchingView.isDefault) {
|
||||||
this.viewList.removeObject(matchingView);
|
viewList.removeObject(matchingView);
|
||||||
yield this._saveViewSettings();
|
yield this._saveViewSettings(viewList);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,9 +225,9 @@ export default class CustomViewsService extends Service {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _saveViewSettings() {
|
async _saveViewSettings(viewList) {
|
||||||
let sharedViews = this.viewList.reject(view => view.isDefault).map(view => view.toJSON());
|
let sharedViews = viewList.reject(view => view.isDefault).map(view => view.toJSON());
|
||||||
this.settings.set('sharedViews', JSON.stringify(sharedViews));
|
this.settings.sharedViews = JSON.stringify(sharedViews);
|
||||||
return this.settings.save();
|
return this.settings.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -366,7 +366,7 @@ export default class DashboardStatsService extends Service {
|
|||||||
this.siteStatus = {
|
this.siteStatus = {
|
||||||
hasPaidTiers,
|
hasPaidTiers,
|
||||||
hasMultipleTiers: hasPaidTiers && this.activePaidTiers.length > 1,
|
hasMultipleTiers: hasPaidTiers && this.activePaidTiers.length > 1,
|
||||||
newslettersEnabled: this.settings.get('editorDefaultEmailRecipients') !== 'disabled',
|
newslettersEnabled: this.settings.editorDefaultEmailRecipients !== 'disabled',
|
||||||
membersEnabled: this.membersUtils.isMembersEnabled
|
membersEnabled: this.membersUtils.isMembersEnabled
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ export default class FeatureService extends Service {
|
|||||||
|
|
||||||
@computed('settings.labs')
|
@computed('settings.labs')
|
||||||
get labs() {
|
get labs() {
|
||||||
let labs = this.get('settings.labs');
|
let labs = this.settings.labs;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return JSON.parse(labs) || {};
|
return JSON.parse(labs) || {};
|
||||||
|
@ -11,7 +11,7 @@ export default class FrontendService extends Service {
|
|||||||
_lastPassword = null;
|
_lastPassword = null;
|
||||||
|
|
||||||
get hasPasswordChanged() {
|
get hasPasswordChanged() {
|
||||||
return this._lastPassword !== this.settings.get('password');
|
return this._lastPassword !== this.settings.password;
|
||||||
}
|
}
|
||||||
|
|
||||||
getUrl(path) {
|
getUrl(path) {
|
||||||
@ -23,9 +23,9 @@ export default class FrontendService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loginIfNeeded() {
|
async loginIfNeeded() {
|
||||||
if (this.settings.get('isPrivate') && (this.hasPasswordChanged || !this._hasLoggedIn)) {
|
if (this.settings.isPrivate && (this.hasPasswordChanged || !this._hasLoggedIn)) {
|
||||||
const privateLoginUrl = this.getUrl('/private/?r=%2F');
|
const privateLoginUrl = this.getUrl('/private/?r=%2F');
|
||||||
this._lastPassword = this.settings.get('password');
|
this._lastPassword = this.settings.password;
|
||||||
|
|
||||||
return fetch(privateLoginUrl, {
|
return fetch(privateLoginUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -7,15 +7,15 @@ export default class MembersUtilsService extends Service {
|
|||||||
@service store;
|
@service store;
|
||||||
|
|
||||||
get isMembersEnabled() {
|
get isMembersEnabled() {
|
||||||
return this.settings.get('membersEnabled');
|
return this.settings.membersEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
get paidMembersEnabled() {
|
get paidMembersEnabled() {
|
||||||
return this.settings.get('paidMembersEnabled');
|
return this.settings.paidMembersEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isMembersInviteOnly() {
|
get isMembersInviteOnly() {
|
||||||
return this.settings.get('membersInviteOnly');
|
return this.settings.membersInviteOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,8 +24,8 @@ export default class MembersUtilsService extends Service {
|
|||||||
get isStripeEnabled() {
|
get isStripeEnabled() {
|
||||||
const stripeDirect = this.config.get('stripeDirect');
|
const stripeDirect = this.config.get('stripeDirect');
|
||||||
|
|
||||||
const hasDirectKeys = !!this.settings.get('stripeSecretKey') && !!this.settings.get('stripePublishableKey');
|
const hasDirectKeys = !!this.settings.stripeSecretKey && !!this.settings.stripePublishableKey;
|
||||||
const hasConnectKeys = !!this.settings.get('stripeConnectSecretKey') && !!this.settings.get('stripeConnectPublishableKey');
|
const hasConnectKeys = !!this.settings.stripeConnectSecretKey && !!this.settings.stripeConnectPublishableKey;
|
||||||
|
|
||||||
if (stripeDirect) {
|
if (stripeDirect) {
|
||||||
return hasDirectKeys;
|
return hasDirectKeys;
|
||||||
@ -66,23 +66,23 @@ export default class MembersUtilsService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get buttonIcon() {
|
get buttonIcon() {
|
||||||
return this.settings.get('portalButtonIcon') || this.defaultIconKeys[0];
|
return this.settings.portalButtonIcon || this.defaultIconKeys[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plan helpers ------------------------------------------------------------
|
// Plan helpers ------------------------------------------------------------
|
||||||
|
|
||||||
get isFreeChecked() {
|
get isFreeChecked() {
|
||||||
const allowedPlans = this.settings.get('portalPlans') || [];
|
const allowedPlans = this.settings.portalPlans || [];
|
||||||
return !!(this.settings.get('membersSignupAccess') === 'all' && allowedPlans.includes('free'));
|
return !!(this.settings.membersSignupAccess === 'all' && allowedPlans.includes('free'));
|
||||||
}
|
}
|
||||||
|
|
||||||
get isMonthlyChecked() {
|
get isMonthlyChecked() {
|
||||||
const allowedPlans = this.settings.get('portalPlans') || [];
|
const allowedPlans = this.settings.portalPlans || [];
|
||||||
return !!(this.isStripeConfigured && allowedPlans.includes('monthly'));
|
return !!(this.isStripeConfigured && allowedPlans.includes('monthly'));
|
||||||
}
|
}
|
||||||
|
|
||||||
get isYearlyChecked() {
|
get isYearlyChecked() {
|
||||||
const allowedPlans = this.settings.get('portalPlans') || [];
|
const allowedPlans = this.settings.portalPlans || [];
|
||||||
return !!(this.isStripeConfigured && allowedPlans.includes('yearly'));
|
return !!(this.isStripeConfigured && allowedPlans.includes('yearly'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,17 +92,17 @@ export default class MembersUtilsService extends Service {
|
|||||||
let {
|
let {
|
||||||
disableBackground = false,
|
disableBackground = false,
|
||||||
page = 'signup',
|
page = 'signup',
|
||||||
button = this.settings.get('portalButton'),
|
button = this.settings.portalButton,
|
||||||
buttonIcon = this.buttonIcon,
|
buttonIcon = this.buttonIcon,
|
||||||
isFreeChecked = this.isFreeChecked,
|
isFreeChecked = this.isFreeChecked,
|
||||||
isMonthlyChecked = this.isMonthlyChecked,
|
isMonthlyChecked = this.isMonthlyChecked,
|
||||||
isYearlyChecked = this.isYearlyChecked,
|
isYearlyChecked = this.isYearlyChecked,
|
||||||
monthlyPrice,
|
monthlyPrice,
|
||||||
yearlyPrice,
|
yearlyPrice,
|
||||||
portalPlans = this.settings.get('portalPlans'),
|
portalPlans = this.settings.portalPlans,
|
||||||
portalTiers,
|
portalTiers,
|
||||||
currency,
|
currency,
|
||||||
membersSignupAccess = this.settings.get('membersSignupAccess')
|
membersSignupAccess = this.settings.membersSignupAccess
|
||||||
} = overrides;
|
} = overrides;
|
||||||
|
|
||||||
const tiers = this.store.peekAll('tier') || [];
|
const tiers = this.store.peekAll('tier') || [];
|
||||||
@ -114,11 +114,11 @@ export default class MembersUtilsService extends Service {
|
|||||||
const baseUrl = this.config.get('blogUrl');
|
const baseUrl = this.config.get('blogUrl');
|
||||||
const portalBase = '/#/portal/preview';
|
const portalBase = '/#/portal/preview';
|
||||||
const settingsParam = new URLSearchParams();
|
const settingsParam = new URLSearchParams();
|
||||||
const signupButtonText = this.settings.get('portalButtonSignupText') || '';
|
const signupButtonText = this.settings.portalButtonSignupText || '';
|
||||||
const allowSelfSignup = membersSignupAccess === 'all' && (!this.isStripeEnabled || isFreeChecked);
|
const allowSelfSignup = membersSignupAccess === 'all' && (!this.isStripeEnabled || isFreeChecked);
|
||||||
|
|
||||||
settingsParam.append('button', button);
|
settingsParam.append('button', button);
|
||||||
settingsParam.append('name', this.settings.get('portalName'));
|
settingsParam.append('name', this.settings.portalName);
|
||||||
settingsParam.append('isFree', isFreeChecked);
|
settingsParam.append('isFree', isFreeChecked);
|
||||||
settingsParam.append('isMonthly', isMonthlyChecked);
|
settingsParam.append('isMonthly', isMonthlyChecked);
|
||||||
settingsParam.append('isYearly', isYearlyChecked);
|
settingsParam.append('isYearly', isYearlyChecked);
|
||||||
@ -136,11 +136,11 @@ export default class MembersUtilsService extends Service {
|
|||||||
settingsParam.append('portalProducts', encodeURIComponent(portalTiers));
|
settingsParam.append('portalProducts', encodeURIComponent(portalTiers));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.settings.get('accentColor') === '' || this.settings.get('accentColor')) {
|
if (this.settings.accentColor === '' || this.settings.accentColor) {
|
||||||
settingsParam.append('accentColor', encodeURIComponent(`${this.settings.get('accentColor')}`));
|
settingsParam.append('accentColor', encodeURIComponent(`${this.settings.accentColor}`));
|
||||||
}
|
}
|
||||||
if (this.settings.get('portalButtonStyle')) {
|
if (this.settings.portalButtonStyle) {
|
||||||
settingsParam.append('buttonStyle', encodeURIComponent(this.settings.get('portalButtonStyle')));
|
settingsParam.append('buttonStyle', encodeURIComponent(this.settings.portalButtonStyle));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monthlyPrice) {
|
if (monthlyPrice) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Service, {inject as service} from '@ember/service';
|
import Service, {inject as service} from '@ember/service';
|
||||||
import {action, set} from '@ember/object';
|
import {action} from '@ember/object';
|
||||||
import {observes} from '@ember-decorators/object';
|
import {observes} from '@ember-decorators/object';
|
||||||
import {tracked} from '@glimmer/tracking';
|
import {tracked} from '@glimmer/tracking';
|
||||||
|
|
||||||
@ -39,10 +39,7 @@ export default class NavigationService extends Service {
|
|||||||
this.settings.expanded = {};
|
this.settings.expanded = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// set is still needed here because we're not tracking deep keys
|
this.settings.expanded[key] = !this.settings.expanded[key];
|
||||||
// and Ember picks up that our templates are dependent on them and
|
|
||||||
// complains. TODO: can we avoid set?
|
|
||||||
set(this.settings.expanded, key, !this.settings.expanded[key]);
|
|
||||||
|
|
||||||
return await this._saveNavigationSettings();
|
return await this._saveNavigationSettings();
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
import Ember from 'ember';
|
|
||||||
import RSVP from 'rsvp';
|
|
||||||
import Service, {inject as service} from '@ember/service';
|
import Service, {inject as service} from '@ember/service';
|
||||||
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
|
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
|
||||||
import classic from 'ember-classic-decorator';
|
import {tracked} from '@glimmer/tracking';
|
||||||
import {get} from '@ember/object';
|
|
||||||
|
|
||||||
// ember-cli-shims doesn't export _ProxyMixin
|
export default class SettingsService extends Service.extend(ValidationEngine) {
|
||||||
const {_ProxyMixin} = Ember;
|
|
||||||
|
|
||||||
@classic
|
|
||||||
export default class SettingsService extends Service.extend(_ProxyMixin, ValidationEngine) {
|
|
||||||
@service store;
|
@service store;
|
||||||
|
|
||||||
// will be set to the single Settings model, it's a reference so any later
|
// will be set to the single Settings model, it's a reference so any later
|
||||||
// changes to the settings object in the store will be reflected
|
// changes to the settings object in the store will be reflected
|
||||||
content = null;
|
settingsModel = null;
|
||||||
|
|
||||||
validationType = 'setting';
|
validationType = 'setting';
|
||||||
_loadingPromise = null;
|
_loadingPromise = null;
|
||||||
|
|
||||||
// this is an odd case where we only want to react to changes that we get
|
// this is an odd case where we only want to react to changes that we get
|
||||||
// back from the API rather than local updates
|
// back from the API rather than local updates
|
||||||
settledIcon = '';
|
@tracked settledIcon = '';
|
||||||
|
|
||||||
|
get hasDirtyAttributes() {
|
||||||
|
return this.settingsModel?.hasDirtyAttributes || false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get mailgunIsConfigured() {
|
||||||
|
return this.mailgunApiKey && this.mailgunDomain && this.mailgunBaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
// the settings API endpoint is a little weird as it's singular and we have
|
// the settings API endpoint is a little weird as it's singular and we have
|
||||||
// to pass in all types - if we ever fetch settings without all types then
|
// to pass in all types - if we ever fetch settings without all types then
|
||||||
@ -39,40 +40,56 @@ export default class SettingsService extends Service.extend(_ProxyMixin, Validat
|
|||||||
return this._loadingPromise;
|
return this._loadingPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch() {
|
async fetch() {
|
||||||
if (!this.content) {
|
if (!this.settingsModel) {
|
||||||
return this.reload();
|
return this.reload();
|
||||||
} else {
|
} else {
|
||||||
return RSVP.resolve(this);
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
async reload() {
|
||||||
return this._loadSettings().then((settings) => {
|
const settingsModel = await this._loadSettings();
|
||||||
this.set('content', settings);
|
|
||||||
this.set('settledIcon', get(settings, 'icon'));
|
this.settingsModel = settingsModel;
|
||||||
return this;
|
this.settledIcon = settingsModel.icon;
|
||||||
|
|
||||||
|
settingsModel.eachAttribute((name) => {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(this, name)) {
|
||||||
|
Object.defineProperty(this, name, {
|
||||||
|
get() {
|
||||||
|
return this.settingsModel[name];
|
||||||
|
},
|
||||||
|
set(newValue) {
|
||||||
|
this.settingsModel[name] = newValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
async save() {
|
async save() {
|
||||||
let settings = this.content;
|
const {settingsModel} = this;
|
||||||
|
|
||||||
if (!settings) {
|
if (!settingsModel) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await settings.save();
|
await settingsModel.save();
|
||||||
await this.validate();
|
await this.validate();
|
||||||
this.set('settledIcon', settings.icon);
|
|
||||||
return settings;
|
this.settledIcon = settingsModel.icon;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
rollbackAttributes() {
|
rollbackAttributes() {
|
||||||
return this.content?.rollbackAttributes();
|
return this.settingsModel?.rollbackAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
changedAttributes() {
|
changedAttributes() {
|
||||||
return this.content?.changedAttributes();
|
return this.settingsModel?.changedAttributes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,11 +193,11 @@ export default class ThemeManagementService extends Service {
|
|||||||
get previewData() {
|
get previewData() {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
|
|
||||||
params.append('c', this.settings.get('accentColor') || '#ffffff');
|
params.append('c', this.settings.accentColor || '#ffffff');
|
||||||
params.append('d', this.settings.get('description'));
|
params.append('d', this.settings.description);
|
||||||
params.append('icon', this.settings.get('icon'));
|
params.append('icon', this.settings.icon);
|
||||||
params.append('logo', this.settings.get('logo'));
|
params.append('logo', this.settings.logo);
|
||||||
params.append('cover', this.settings.get('coverImage'));
|
params.append('cover', this.settings.coverImage);
|
||||||
|
|
||||||
params.append('custom', JSON.stringify(this.customThemeSettings.keyValueObject));
|
params.append('custom', JSON.stringify(this.customThemeSettings.keyValueObject));
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ export default class UiService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get adjustedAccentColor() {
|
get adjustedAccentColor() {
|
||||||
const accentColor = Color(this.settings.get('accentColor'));
|
const accentColor = Color(this.settings.accentColor);
|
||||||
const backgroundColor = Color(this.backgroundColor);
|
const backgroundColor = Color(this.backgroundColor);
|
||||||
|
|
||||||
// WCAG contrast. 1 = lowest contrast, 21 = highest contrast
|
// WCAG contrast. 1 = lowest contrast, 21 = highest contrast
|
||||||
|
@ -113,8 +113,8 @@ export default class PublishOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get emailDisabledInSettings() {
|
get emailDisabledInSettings() {
|
||||||
return get(this.settings, 'editorDefaultEmailRecipients') === 'disabled'
|
return this.settings.editorDefaultEmailRecipients === 'disabled'
|
||||||
|| get(this.settings, 'membersSignupAccess') === 'none';
|
|| this.settings.membersSignupAccess === 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish type dropdown is not shown at all
|
// publish type dropdown is not shown at all
|
||||||
@ -130,7 +130,7 @@ export default class PublishOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get mailgunIsConfigured() {
|
get mailgunIsConfigured() {
|
||||||
return get(this.settings, 'mailgunIsConfigured')
|
return this.settings.mailgunIsConfigured
|
||||||
|| get(this.config, 'mailgunIsConfigured');
|
|| get(this.config, 'mailgunIsConfigured');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,8 +168,8 @@ export default class PublishOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get defaultRecipientFilter() {
|
get defaultRecipientFilter() {
|
||||||
const recipients = this.settings.get('editorDefaultEmailRecipients');
|
const recipients = this.settings.editorDefaultEmailRecipients;
|
||||||
const filter = this.settings.get('editorDefaultEmailRecipientsFilter');
|
const filter = this.settings.editorDefaultEmailRecipientsFilter;
|
||||||
|
|
||||||
const usuallyNobody = recipients === 'filter' && filter === null;
|
const usuallyNobody = recipients === 'filter' && filter === null;
|
||||||
|
|
||||||
@ -254,8 +254,8 @@ export default class PublishOptions {
|
|||||||
// Set publish type to "Publish" but keep email recipients matching post visibility
|
// Set publish type to "Publish" but keep email recipients matching post visibility
|
||||||
// to avoid multiple clicks to turn on emailing
|
// to avoid multiple clicks to turn on emailing
|
||||||
if (
|
if (
|
||||||
this.settings.get('editorDefaultEmailRecipients') === 'filter' &&
|
this.settings.editorDefaultEmailRecipients === 'filter' &&
|
||||||
this.settings.get('editorDefaultEmailRecipientsFilter') === null
|
this.settings.editorDefaultEmailRecipientsFilter === null
|
||||||
) {
|
) {
|
||||||
this.publishType = 'publish';
|
this.publishType = 'publish';
|
||||||
}
|
}
|
||||||
@ -382,7 +382,7 @@ export default class PublishOptions {
|
|||||||
try {
|
try {
|
||||||
if (this.limit.limiter && this.limit.limiter.isLimited('emails')) {
|
if (this.limit.limiter && this.limit.limiter.isLimited('emails')) {
|
||||||
await this.limit.limiter.errorIfWouldGoOverLimit('emails');
|
await this.limit.limiter.errorIfWouldGoOverLimit('emails');
|
||||||
} else if (get(this.settings, 'emailVerificationRequired')) {
|
} else if (this.settings.emailVerificationRequired) {
|
||||||
this.emailDisabledError = 'Email sending is temporarily disabled because your account is currently in review. You should have an email about this from us already, but you can also reach us any time at support@ghost.org.';
|
this.emailDisabledError = 'Email sending is temporarily disabled because your account is currently in review. You should have an email about this from us already, but you can also reach us any time at support@ghost.org.';
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -16,8 +16,8 @@ describe('Integration: Helper: gh-format-post-time', function () {
|
|||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
let settings = this.owner.lookup('service:settings');
|
let settings = this.owner.lookup('service:settings');
|
||||||
settings.content = {};
|
settings.settingsModel = {};
|
||||||
settings.set('timezone', timezoneForTest);
|
settings.timezone = timezoneForTest;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
|
@ -50,13 +50,13 @@ describe.skip('Unit: Controller: settings/design', function () {
|
|||||||
NavItem.create({label: 'Third', url: ''})
|
NavItem.create({label: 'Third', url: ''})
|
||||||
]}));
|
]}));
|
||||||
// blank item won't get added because the last item is incomplete
|
// blank item won't get added because the last item is incomplete
|
||||||
expect(ctrl.get('settings.navigation.length')).to.equal(3);
|
expect(ctrl.settings.navigation.length).to.equal(3);
|
||||||
|
|
||||||
ctrl.get('save').perform().then(function passedValidation() {
|
ctrl.get('save').perform().then(function passedValidation() {
|
||||||
assert(false, 'navigationItems weren\'t validated on save');
|
assert(false, 'navigationItems weren\'t validated on save');
|
||||||
done();
|
done();
|
||||||
}).catch(function failedValidation() {
|
}).catch(function failedValidation() {
|
||||||
let navItems = ctrl.get('settings.navigation');
|
let navItems = ctrl.settings.navigation;
|
||||||
expect(navItems[0].get('errors').toArray()).to.be.empty;
|
expect(navItems[0].get('errors').toArray()).to.be.empty;
|
||||||
expect(navItems[1].get('errors.firstObject.attribute')).to.equal('label');
|
expect(navItems[1].get('errors.firstObject.attribute')).to.equal('label');
|
||||||
expect(navItems[2].get('errors.firstObject.attribute')).to.equal('url');
|
expect(navItems[2].get('errors.firstObject.attribute')).to.equal('url');
|
||||||
@ -74,13 +74,13 @@ describe.skip('Unit: Controller: settings/design', function () {
|
|||||||
NavItem.create({label: '', url: ''})
|
NavItem.create({label: '', url: ''})
|
||||||
]}));
|
]}));
|
||||||
|
|
||||||
expect(ctrl.get('settings.navigation.length')).to.equal(2);
|
expect(ctrl.settings.navigation.length).to.equal(2);
|
||||||
|
|
||||||
ctrl.get('save').perform().then(function passedValidation() {
|
ctrl.get('save').perform().then(function passedValidation() {
|
||||||
assert(false, 'navigationItems weren\'t validated on save');
|
assert(false, 'navigationItems weren\'t validated on save');
|
||||||
done();
|
done();
|
||||||
}).catch(function failedValidation() {
|
}).catch(function failedValidation() {
|
||||||
let navItems = ctrl.get('settings.navigation');
|
let navItems = ctrl.settings.navigation;
|
||||||
expect(navItems[0].get('errors').toArray()).to.be.empty;
|
expect(navItems[0].get('errors').toArray()).to.be.empty;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@ -96,7 +96,7 @@ describe.skip('Unit: Controller: settings/design', function () {
|
|||||||
]}));
|
]}));
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(ctrl.get('settings.navigation.length')).to.equal(1);
|
expect(ctrl.settings.navigation.length).to.equal(1);
|
||||||
|
|
||||||
ctrl.set('newNavItem.label', 'New');
|
ctrl.set('newNavItem.label', 'New');
|
||||||
ctrl.set('newNavItem.url', '/new');
|
ctrl.set('newNavItem.url', '/new');
|
||||||
@ -105,10 +105,10 @@ describe.skip('Unit: Controller: settings/design', function () {
|
|||||||
ctrl.send('addNavItem', ctrl.get('newNavItem'));
|
ctrl.send('addNavItem', ctrl.get('newNavItem'));
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(ctrl.get('settings.navigation.length')).to.equal(2);
|
expect(ctrl.settings.navigation.length).to.equal(2);
|
||||||
expect(ctrl.get('settings.navigation.lastObject.label')).to.equal('New');
|
expect(ctrl.settings.navigation.lastObject.label).to.equal('New');
|
||||||
expect(ctrl.get('settings.navigation.lastObject.url')).to.equal('/new');
|
expect(ctrl.settings.navigation.lastObject.url).to.equal('/new');
|
||||||
expect(ctrl.get('settings.navigation.lastObject.isNew')).to.be.false;
|
expect(ctrl.settings.navigation.lastObject.isNew).to.be.false;
|
||||||
expect(ctrl.get('newNavItem.label')).to.be.empty;
|
expect(ctrl.get('newNavItem.label')).to.be.empty;
|
||||||
expect(ctrl.get('newNavItem.url')).to.be.empty;
|
expect(ctrl.get('newNavItem.url')).to.be.empty;
|
||||||
expect(ctrl.get('newNavItem.isNew')).to.be.true;
|
expect(ctrl.get('newNavItem.isNew')).to.be.true;
|
||||||
@ -121,9 +121,9 @@ describe.skip('Unit: Controller: settings/design', function () {
|
|||||||
ctrl.set('settings', EmberObject.create({navigation: [
|
ctrl.set('settings', EmberObject.create({navigation: [
|
||||||
NavItem.create({label: '', url: '', last: true})
|
NavItem.create({label: '', url: '', last: true})
|
||||||
]}));
|
]}));
|
||||||
expect(ctrl.get('settings.navigation.length')).to.equal(1);
|
expect(ctrl.settings.navigation.length).to.equal(1);
|
||||||
ctrl.send('addNavItem', ctrl.get('settings.navigation.lastObject'));
|
ctrl.send('addNavItem', ctrl.settings.navigation.lastObject);
|
||||||
expect(ctrl.get('settings.navigation.length')).to.equal(1);
|
expect(ctrl.settings.navigation.length).to.equal(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -136,9 +136,9 @@ describe.skip('Unit: Controller: settings/design', function () {
|
|||||||
|
|
||||||
run(() => {
|
run(() => {
|
||||||
ctrl.set('settings', EmberObject.create({navigation: navItems}));
|
ctrl.set('settings', EmberObject.create({navigation: navItems}));
|
||||||
expect(ctrl.get('settings.navigation').mapBy('label')).to.deep.equal(['First', 'Second']);
|
expect(ctrl.settings.navigation.mapBy('label')).to.deep.equal(['First', 'Second']);
|
||||||
ctrl.send('deleteNavItem', ctrl.get('settings.navigation.firstObject'));
|
ctrl.send('deleteNavItem', ctrl.settings.navigation.firstObject);
|
||||||
expect(ctrl.get('settings.navigation').mapBy('label')).to.deep.equal(['Second']);
|
expect(ctrl.settings.navigation.mapBy('label')).to.deep.equal(['Second']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -151,9 +151,9 @@ describe.skip('Unit: Controller: settings/design', function () {
|
|||||||
|
|
||||||
run(() => {
|
run(() => {
|
||||||
ctrl.set('settings', EmberObject.create({navigation: navItems}));
|
ctrl.set('settings', EmberObject.create({navigation: navItems}));
|
||||||
expect(ctrl.get('settings.navigation').mapBy('url')).to.deep.equal(['/first', '/second']);
|
expect(ctrl.settings.navigation.mapBy('url')).to.deep.equal(['/first', '/second']);
|
||||||
ctrl.send('updateUrl', '/new', ctrl.get('settings.navigation.firstObject'));
|
ctrl.send('updateUrl', '/new', ctrl.settings.navigation.firstObject);
|
||||||
expect(ctrl.get('settings.navigation').mapBy('url')).to.deep.equal(['/new', '/second']);
|
expect(ctrl.settings.navigation.mapBy('url')).to.deep.equal(['/new', '/second']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user