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

Commit

Permalink
Added members feature to labs
Browse files Browse the repository at this point in the history
no issue

- Added new members settings/toggle to labs
  • Loading branch information
rishabhgrg committed Feb 26, 2019
1 parent 05a92de commit e6a6b09
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 13 deletions.
22 changes: 16 additions & 6 deletions app/components/gh-feature-flag.js
@@ -1,20 +1,28 @@
import Component from '@ember/component';
import {computed} from '@ember/object';
import {computed, defineProperty} from '@ember/object';
import {readOnly} from '@ember/object/computed';
import {inject as service} from '@ember/service';

const FeatureFlagComponent = Component.extend({
feature: service(),

tagName: 'label',
classNames: 'checkbox',
attributeBindings: ['for'],
_flagValue: null,

attributeBindings: ['for', 'disabled'],
disabled: computed('_disabled', function () {
if (this.get('_disabled')) {
return true;
}
return false;
}),
value: computed('_flagValue', {
get() {
return this.get('_flagValue');
},
set(key, value) {
if (this.get('flag') === 'members' && value === true) {
this.set(`feature.subscribers`, false);
}
return this.set(`feature.${this.get('flag')}`, value);
}
}),
Expand All @@ -30,12 +38,14 @@ const FeatureFlagComponent = Component.extend({
init() {
this._super(...arguments);

this.set('_flagValue', this.get(`feature.${this.get('flag')}`));
defineProperty(this, '_flagValue', readOnly(`feature.${this.get('flag')}`), function () {
return this.get(`feature.${this.get('flag')}`);
});
}
});

FeatureFlagComponent.reopenClass({
positionalParams: ['flag']
positionalParams: ['flag', '_disabled']
});

export default FeatureFlagComponent;
92 changes: 91 additions & 1 deletion app/controllers/settings/labs.js
Expand Up @@ -8,6 +8,7 @@ import {
isRequestEntityTooLargeError,
isUnsupportedMediaTypeError
} from 'ghost-admin/services/ajax';
import {computed} from '@ember/object';
import {isBlank} from '@ember/utils';
import {isArray as isEmberArray} from '@ember/array';
import {run} from '@ember/runloop';
Expand Down Expand Up @@ -45,6 +46,7 @@ export default Controller.extend({
importErrors: null,
importSuccessful: false,
showDeleteAllModal: false,
showMemberConfig: false,
submitting: false,
uploadButtonText: 'Import',

Expand All @@ -53,7 +55,6 @@ export default Controller.extend({
jsonMimeType: null,
yamlExtension: null,
yamlMimeType: null,

init() {
this._super(...arguments);
this.importMimeType = IMPORT_MIME_TYPES;
Expand All @@ -63,6 +64,23 @@ export default Controller.extend({
this.yamlMimeType = YAML_MIME_TYPE;
},

subscriptionSettings: computed('settings.membersSubscriptionSettings', function () {
let subscriptionSettings = this.parseSubscriptionSettings(this.get('settings.membersSubscriptionSettings'));
let stripeProcessor = subscriptionSettings.paymentProcessors.find((proc) => {
return (proc.adapter === 'stripe');
});
let monthlyPlan = stripeProcessor.config.plans.find(plan => plan.interval === 'month');
let yearlyPlan = stripeProcessor.config.plans.find(plan => plan.interval === 'year');
monthlyPlan.dollarAmount = (monthlyPlan.amount / 100);
yearlyPlan.dollarAmount = (yearlyPlan.amount / 100);
stripeProcessor.config.plans = {
monthly: monthlyPlan,
yearly: yearlyPlan
};
subscriptionSettings.stripeConfig = stripeProcessor.config;
return subscriptionSettings;
}),

actions: {
onUpload(file) {
let formData = new FormData();
Expand Down Expand Up @@ -143,6 +161,10 @@ export default Controller.extend({
this.toggleProperty('showDeleteAllModal');
},

toggleMemberConfig() {
this.toggleProperty('showMemberConfig');
},

/**
* Opens a file selection dialog - Triggered by "Upload x" buttons,
* searches for the hidden file input within the .gh-setting element
Expand All @@ -156,6 +178,66 @@ export default Controller.extend({
.closest('.gh-setting-action')
.find('input[type="file"]')
.click();
},

setSubscriptionSettings(key, event) {
let subscriptionSettings = this.parseSubscriptionSettings(this.get('settings.membersSubscriptionSettings'));
let stripeProcessor = subscriptionSettings.paymentProcessors.find((proc) => {
return (proc.adapter === 'stripe');
});
let stripeConfig = stripeProcessor.config;
stripeConfig.product = {
name: this.get('settings').get('title')
};
if (key === 'isPaid') {
subscriptionSettings.isPaid = event;
}
if (key === 'secret_token' || key === 'public_token') {
stripeConfig[key] = event.target.value;
}
if (key === 'month' || key === 'year') {
stripeConfig.plans = stripeConfig.plans.map((plan) => {
if (key === plan.interval) {
plan.amount = event.target.value * 100;
}
return plan;
});
}
this.set('settings.membersSubscriptionSettings', JSON.stringify(subscriptionSettings));
}
},

parseSubscriptionSettings(settingsString) {
try {
return JSON.parse(settingsString);
} catch (e) {
return {
isPaid: false,
paymentProcessors: [{
adapter: 'stripe',
config: {
secret_token: '',
public_token: '',
product: {
name: this.get('settings').get('title')
},
plans: [
{
name: 'Monthly',
currency: 'usd',
interval: 'month',
amount: ''
},
{
name: 'Yearly',
currency: 'usd',
interval: 'year',
amount: ''
}
]
}
}]
};
}
},

Expand Down Expand Up @@ -213,6 +295,14 @@ export default Controller.extend({
}
}).drop(),

saveSettings: task(function* () {
try {
return yield this.get('settings').save();
} catch (error) {
throw error;
}
}).drop(),

redirectUploadResult: task(function* (success) {
this.set('redirectSuccess', success);
this.set('redirectFailure', !success);
Expand Down
3 changes: 2 additions & 1 deletion app/models/setting.js
Expand Up @@ -29,5 +29,6 @@ export default Model.extend(ValidationEngine, {
defaultValue() {
return {isActive: true};
}
})
}),
membersSubscriptionSettings: attr('string')
});
1 change: 1 addition & 0 deletions app/services/feature.js
Expand Up @@ -52,6 +52,7 @@ export default Service.extend({

publicAPI: feature('publicAPI'),
subscribers: feature('subscribers'),
members: feature('members'),
nightShift: feature('nightShift', {user: true, onChange: '_setAdminTheme'}),

_user: null,
Expand Down
2 changes: 1 addition & 1 deletion app/services/settings.js
Expand Up @@ -27,7 +27,7 @@ export default Service.extend(_ProxyMixin, ValidationEngine, {
_loadSettings() {
if (!this._loadingPromise) {
this._loadingPromise = this.get('store')
.queryRecord('setting', {type: 'blog,theme,private'})
.queryRecord('setting', {type: 'blog,theme,private,members'})
.then((settings) => {
this._loadingPromise = null;
return settings;
Expand Down
1 change: 1 addition & 0 deletions app/styles/app-dark.css
Expand Up @@ -55,6 +55,7 @@
@import "layouts/apps.css";
@import "layouts/packages.css";
@import "layouts/subscribers.css";
@import "layouts/labs.css";


:root {
Expand Down
1 change: 1 addition & 0 deletions app/styles/app.css
Expand Up @@ -55,6 +55,7 @@
@import "layouts/apps.css";
@import "layouts/packages.css";
@import "layouts/subscribers.css";
@import "layouts/labs.css";


/* ---------------------------✈️----------------------------- */
Expand Down
70 changes: 70 additions & 0 deletions app/styles/layouts/labs.css
@@ -0,0 +1,70 @@
.gh-labs-price-label input {
padding-right: 96px;
}

.gh-labs-price-label input::-webkit-outer-spin-button, .gh-labs-price-label input::-webkit-inner-spin-button {
/* display: none; <- Crashes Chrome on hover */
-webkit-appearance: none;
margin: 0;
}

.gh-labs-price-label input[type=number] {
-moz-appearance: textfield;
/* Firefox */
}

.gh-labs-price-label::after {
position: absolute;
top: 8px;
right: 12px;
color: var(--midlightgrey);
}

.gh-labs-monthly-price::after {
content: "USD/month";
}

.gh-labs-yearly-price::after {
content: "USD/year";
}

.gh-labs-toggle-wrapper {
padding-top: 6px;
padding-bottom: 6px;
border-radius: 5px;
}

.gh-btn-labs-toggle {
border: none;
display: flex;
align-items: center;
color: var(--blue);
}

.gh-btn-labs-toggle svg {
width: 10px;
height: 10px;
margin-right: 5px;
}

.gh-btn-labs-toggle svg path {
stroke: var(--blue);
}

.gh-labs-members-radio {
cursor: pointer;
margin: 0 8px;
}

.gh-labs-members-radio.active {
background: color-mod(var(--blue) alpha(6%));
border-color: var(--blue);
}

.gh-labs-disabled .gh-setting-content, .gh-labs-disabled .gh-setting-action {
opacity: 0.25;
}

.gh-labs-disabled .for-checkbox label {
cursor: default;
}
2 changes: 1 addition & 1 deletion app/templates/components/gh-feature-flag.hbs
@@ -1,3 +1,3 @@
<input type="checkbox" checked={{value}} id={{for}} name={{name}} onclick={{action (mut value) value="target.checked"}}>
<input type="checkbox" checked={{value}} disabled={{disabled}} id={{for}} name={{name}} onclick={{action (mut value) value="target.checked"}}>
<span class="input-toggle-component"></span>
{{{yield}}}

0 comments on commit e6a6b09

Please sign in to comment.