Added option to disable member subscriptions (#1925)

refs https://github.com/TryGhost/Team/issues/579

- new Access settings screen that moves subscription access and default post visibility from the Payments settings screen
- expanded "Free signup" toggle into three signup access options
  - "anyone" - same as previous "allow free member signup" option set to `true`
  - "invite only" -  same as previous "allow free member signup" option set to `false`
  - "nobody" - completely disables member signup and login. Removes injected portal and stripe scripts on the front-end and hides member related sections on the admin dashboard

(this commit moves the above changes out from behind the developer experiments flag and cleans up now-unused code)
This commit is contained in:
Kevin Ansfield 2021-04-21 12:09:40 +01:00 committed by GitHub
parent dda67edd82
commit 58759b3069
7 changed files with 12 additions and 110 deletions

View File

@ -66,7 +66,7 @@
checked={{this.isFreeChecked}}
id="free-plan"
name="free-plan"
disabled={{not this.settings.membersAllowFreeSignup}}
disabled={{not (eq this.settings.membersSignupAccess "all")}}
class="gh-input post-settings-featured"
{{on "click" this.toggleFreePlan}}
data-test-checkbox="featured"

View File

@ -46,7 +46,7 @@ export default class GhLaunchWizardSetPricingComponent extends Component {
get isFreeChecked() {
const allowedPlans = this.settings.get('portalPlans') || [];
return (this.settings.get('membersAllowFreeSignup') && allowedPlans.includes('free'));
return (this.settings.get('membersSignupAccess') === 'all' && allowedPlans.includes('free'));
}
get isMonthlyChecked() {

View File

@ -216,70 +216,6 @@
</section>
</div>
{{#unless (enable-developer-experiments)}}
<div class="gh-main-section">
<h4 class="gh-main-section-header small bn">Access</h4>
<section class="gh-expandable">
<div class="gh-expandable-block">
<div class="gh-expandable-header">
<div>
<h4 class="gh-expandable-title">Allow free member signup</h4>
<p class="gh-expandable-description">If disabled, members can only be signed up via payment checkout or API integration</p>
</div>
<div class="for-switch">
<label class="switch" for="members-allow-self-signup" {{action "toggleSelfSignup" bubbles="false"}}>
<input type="checkbox" checked={{this.allowSelfSignup}} class="gh-input" onclick={{action "toggleSelfSignup"}} data-test-checkbox="members-allow-self-signup">
<span class="input-toggle-component mt1"></span>
</label>
</div>
</div>
</div>
<div class="gh-expandable-block">
<div class="gh-expandable-header">
<div>
<h4 class="gh-expandable-title">Default post access</h4>
<p class="gh-expandable-description">When a new post is created, who should have access to it?</p>
</div>
<button type="button" class="gh-btn" {{action (toggle "membersPostAccessOpen" this)}} data-test-toggle-memberspostaccess><span>{{if this.membersPostAccessOpen "Close" "Expand"}}</span></button>
</div>
<div class="gh-expandable-content">
{{#liquid-if this.membersPostAccessOpen}}
<div class="flex flex-column w-50 flex">
<div class="gh-radio {{if (eq settings.defaultContentVisibility "public") "active"}}"
{{action "setDefaultContentVisibility" "public" on="click"}}>
<div class="gh-radio-button" data-test-publishmenu-unpublished-option></div>
<div class="gh-radio-content">
<div class="gh-radio-label">Public<br>
<small class="midgrey">All site visitors to your site, no login required</small></div>
</div>
</div>
<div class="gh-radio {{if (eq settings.defaultContentVisibility "members") "active"}}"
{{action "setDefaultContentVisibility" "members" on="click"}}>
<div class="gh-radio-button" data-test-publishmenu-published-option></div>
<div class="gh-radio-content">
<div class="gh-radio-label">Members only<br>
<small class="midgrey">All logged-in members</small></div>
</div>
</div>
<div class="gh-radio {{if (eq settings.defaultContentVisibility "paid") "active"}}"
{{action "setDefaultContentVisibility" "paid" on="click"}}>
<div class="gh-radio-button" data-test-publishmenu-published-option></div>
<div class="gh-radio-content">
<div class="gh-radio-label">Paid-members only<br>
<small class="midgrey">Only logged-in members with an active Stripe subscription</small></div>
</div>
</div>
</div>
{{/liquid-if}}
</div>
</div>
</section>
</div>
{{/unless}}
{{#if this.showDisconnectStripeConnectModal}}
<GhFullscreenModal @modal="disconnect-stripe"
@model={{hash

View File

@ -6,9 +6,7 @@ import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
export default Component.extend({
feature: service(),
config: service(),
mediaQueries: service(),
ghostPaths: service(),
ajax: service(),
settings: service(),
@ -23,12 +21,8 @@ export default Component.extend({
// passed in actions
setStripeConnectIntegrationTokenSetting() {},
defaultContentVisibility: reads('settings.defaultContentVisibility'),
stripeDirect: reads('config.stripeDirect'),
allowSelfSignup: reads('settings.membersAllowFreeSignup'),
/** OLD **/
stripeDirectPublicKey: reads('settings.stripePublishableKey'),
stripeDirectSecretKey: reads('settings.stripeSecretKey'),
@ -41,12 +35,6 @@ export default Component.extend({
return this.get('currencies').findBy('value', this.get('stripePlans.monthly.currency')) || this.get('topCurrencies').findBy('value', this.get('stripePlans.monthly.currency'));
}),
blogDomain: computed('config.blogDomain', function () {
let blogDomain = this.config.blogDomain || '';
const domainExp = blogDomain.replace('https://', '').replace('http://', '').match(new RegExp('^([^/:?#]+)(?:[/:?#]|$)', 'i'));
return (domainExp && domainExp[1]) || '';
}),
stripePlans: computed('settings.stripePlans', function () {
const plans = this.settings.get('stripePlans');
const monthly = plans.find(plan => plan.interval === 'month');
@ -103,14 +91,6 @@ export default Component.extend({
},
actions: {
setDefaultContentVisibility(value) {
this.setDefaultContentVisibility(value);
},
toggleSelfSignup() {
this.set('settings.membersAllowFreeSignup', !this.get('allowSelfSignup'));
},
setStripeDirectPublicKey(event) {
this.set('settings.stripeProductName', this.get('settings.title'));
this.set('settings.stripePublishableKey', event.target.value);

View File

@ -1,8 +1,8 @@
import $ from 'jquery';
import ModalComponent from 'ghost-admin/components/modal-base';
import copyTextToClipboard from 'ghost-admin/utils/copy-text-to-clipboard';
import {alias, reads} from '@ember/object/computed';
import {computed} from '@ember/object';
import {equal, reads} from '@ember/object/computed';
import {htmlSafe} from '@ember/string';
import {run} from '@ember/runloop';
import {inject as service} from '@ember/service';
@ -49,7 +49,7 @@ export default ModalComponent.extend({
confirm() {},
allowSelfSignup: alias('settings.membersAllowFreeSignup'),
allowSelfSignup: equal('settings.membersSignupAccess', 'all'),
isStripeConfigured: reads('membersUtils.isStripeEnabled'),

View File

@ -1,7 +1,6 @@
/* eslint-disable camelcase */
import Model, {attr} from '@ember-data/model';
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
import {computed} from '@ember/object';
export default Model.extend(ValidationEngine, {
validationType: 'setting',
@ -75,18 +74,5 @@ export default Model.extend(ValidationEngine, {
newsletterShowHeader: attr('boolean'),
newsletterBodyFontCategory: attr('string'),
newsletterShowBadge: attr('boolean'),
newsletterFooterContent: attr('string'),
// TODO: remove when Access screen with "Nobody" option is out of dev experiments
membersAllowFreeSignup: computed('membersSignupAccess', {
get() {
const signupAccess = this.membersSignupAccess;
return signupAccess === 'all' ? true : false;
},
set(key, allowFreeSignup) {
const signupAccess = allowFreeSignup ? 'all' : 'invite';
this.set('membersSignupAccess', signupAccess);
return allowFreeSignup;
}
})
newsletterFooterContent: attr('string')
});

View File

@ -40,14 +40,14 @@
<div class="gh-setting-header">Members</div>
<div class="gh-settings-main-grid">
<LinkTo class="gh-setting-group" @route="settings.members-access" data-test-nav="members-access">
<span class="blue">{{svg-jar "eye"}}</span>
<div>
<h4>Access</h4>
<p>Configure members usage and default access levels</p>
</div>
</LinkTo>
{{#if (enable-developer-experiments)}}
<LinkTo class="gh-setting-group" @route="settings.members-access" data-test-nav="members-access">
<span class="blue">{{svg-jar "eye"}}</span>
<div>
<h4>Access</h4>
<p>Configure members usage and default access levels</p>
</div>
</LinkTo>
<LinkTo class="gh-setting-group" @route="settings.products" data-test-nav="members-access">
<span class="green">{{svg-jar "module"}}</span>
<div>