mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-26 12:21:36 +03:00
Wired benefits section to API (#2023)
refs https://github.com/TryGhost/Team/issues/792 - updates product benefit to use `name` instead of `label` attribute for benefit text - updates model/serializer/validator to correctly handle benefit attributes - added `+` button for adding new labels as the enter behavior is closing the popup(needs fix)
This commit is contained in:
parent
386d59d709
commit
46b311b561
@ -10,19 +10,19 @@
|
||||
@tagName="span"
|
||||
@class="gh-blognav-label"
|
||||
@errors={{this.benefitItem.errors}}
|
||||
@property="label"
|
||||
@property="name"
|
||||
@hasValidated={{this.benefitItem.hasValidated}}
|
||||
>
|
||||
<GhTrimFocusInput
|
||||
@shouldFocus={{this.benefitItem.last}}
|
||||
@placeholder="Add benefit"
|
||||
@value={{readonly this.label}}
|
||||
@value={{readonly this.name}}
|
||||
@input={{action "updateLabel" value="target.value"}}
|
||||
@keyPress={{action "clearLabelErrors"}}
|
||||
@focus-out={{action "updateLabel" this.label}} data-test-input="label" />
|
||||
@focus-out={{action "updateLabel" this.name}} data-test-input="name" />
|
||||
<GhErrorMessage
|
||||
@errors={{this.benefitItem.errors}}
|
||||
@property="label" data-test-error="label" />
|
||||
@property="name" data-test-error="name" />
|
||||
</GhValidationStatusContainer>
|
||||
</div>
|
||||
|
||||
|
@ -15,7 +15,7 @@ export default Component.extend(ValidationState, {
|
||||
addItem() {},
|
||||
deleteItem() {},
|
||||
updateLabel() {},
|
||||
label: boundOneWay('benefitItem.label'),
|
||||
name: boundOneWay('benefitItem.name'),
|
||||
|
||||
errors: readOnly('benefitItem.errors'),
|
||||
|
||||
@ -33,13 +33,19 @@ export default Component.extend(ValidationState, {
|
||||
},
|
||||
|
||||
updateLabel(value) {
|
||||
this.set('label', value);
|
||||
this.set('name', value);
|
||||
return this.updateLabel(value, this.benefitItem);
|
||||
},
|
||||
|
||||
clearLabelErrors() {
|
||||
if (this.get('benefitItem.errors')) {
|
||||
this.get('benefitItem.errors').remove('label');
|
||||
clearLabelErrors(event) {
|
||||
// enter key
|
||||
if (event.keyCode === 13 && this.get('benefitItem.isNew')) {
|
||||
event.preventDefault();
|
||||
run.scheduleOnce('actions', this, this.send, 'addItem', this.benefitItem);
|
||||
} else {
|
||||
if (this.get('benefitItem.errors')) {
|
||||
this.get('benefitItem.errors').remove('name');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -17,14 +17,11 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="gh-product-card-block">
|
||||
<h4>Benefits <span class="counter">(3)</span></h4>
|
||||
<h4>Benefits <span class="counter">({{product.benefits.length}})</span></h4>
|
||||
<ul class="benefits">
|
||||
{{#each product.benefits as |benefit|}}
|
||||
<li>{{svg-jar "check"}} {{benefit.label}} </li>
|
||||
<li>{{svg-jar "check"}} {{benefit.name}} </li>
|
||||
{{/each}}
|
||||
<li>{{svg-jar "check"}} Access to all J&A Watch J&A episodes, past and future!</li>
|
||||
<li>{{svg-jar "check"}} An exclusive AD-FREE extra video episode of J&A AMA every other week!</li>
|
||||
<li>{{svg-jar "check"}} Includes Discord benefits</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="gh-product-card-block">
|
||||
|
@ -19,25 +19,25 @@ const CURRENCIES = currencies.map((currency) => {
|
||||
|
||||
let BENEFITSDATA = emberA([
|
||||
ProductBenefitItem.create({
|
||||
label: 'Benefit 1'
|
||||
name: 'Benefit 1'
|
||||
}),
|
||||
ProductBenefitItem.create({
|
||||
label: 'Benefit 2'
|
||||
name: 'Benefit 2'
|
||||
}),
|
||||
ProductBenefitItem.create({
|
||||
label: 'Benefit 3'
|
||||
name: 'Benefit 3'
|
||||
}),
|
||||
ProductBenefitItem.create({
|
||||
label: 'Benefit 4'
|
||||
name: 'Benefit 4'
|
||||
}),
|
||||
ProductBenefitItem.create({
|
||||
label: 'Benefit 5'
|
||||
name: 'Benefit 5'
|
||||
}),
|
||||
ProductBenefitItem.create({
|
||||
label: 'Benefit 6'
|
||||
name: 'Benefit 6'
|
||||
}),
|
||||
ProductBenefitItem.create({
|
||||
label: 'Benefit 7'
|
||||
name: 'Benefit 7'
|
||||
})
|
||||
]);
|
||||
|
||||
@ -81,7 +81,7 @@ export default class ModalProductPrice extends ModalBase {
|
||||
this.benefits = this.product.get('benefits') || BENEFITSDATA;
|
||||
this.newBenefit = ProductBenefitItem.create({
|
||||
isNew: true,
|
||||
label: ''
|
||||
name: ''
|
||||
});
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ export default class ModalProductPrice extends ModalBase {
|
||||
item.set('isNew', false);
|
||||
this.benefits.pushObject(item);
|
||||
|
||||
this.newBenefit = ProductBenefitItem.create({isNew: true, label: ''});
|
||||
this.newBenefit = ProductBenefitItem.create({isNew: true, name: ''});
|
||||
}
|
||||
|
||||
actions = {
|
||||
@ -186,8 +186,8 @@ export default class ModalProductPrice extends ModalBase {
|
||||
return;
|
||||
}
|
||||
|
||||
if (benefitItem.get('label') !== label) {
|
||||
benefitItem.set('label', label);
|
||||
if (benefitItem.get('name') !== label) {
|
||||
benefitItem.set('name', label);
|
||||
}
|
||||
},
|
||||
confirm() {
|
||||
|
@ -309,7 +309,7 @@ export default class MembersAccessController extends Controller {
|
||||
|
||||
@task({drop: true})
|
||||
*fetchProducts() {
|
||||
this.products = yield this.store.query('product', {include: 'monthly_price,yearly_price'});
|
||||
this.products = yield this.store.query('product', {include: 'monthly_price,yearly_price,benefits'});
|
||||
this.product = this.products.firstObject;
|
||||
this.setupPortalProduct(this.product);
|
||||
}
|
||||
|
@ -4,20 +4,20 @@ import {computed} from '@ember/object';
|
||||
import {isBlank} from '@ember/utils';
|
||||
|
||||
export default EmberObject.extend(ValidationEngine, {
|
||||
label: '',
|
||||
name: '',
|
||||
isNew: false,
|
||||
|
||||
validationType: 'productBenefitItem',
|
||||
|
||||
isComplete: computed('label', function () {
|
||||
let {label} = this;
|
||||
isComplete: computed('name', function () {
|
||||
let {name} = this;
|
||||
|
||||
return !isBlank(label);
|
||||
return !isBlank(name);
|
||||
}),
|
||||
|
||||
isBlank: computed('label', function () {
|
||||
let {label} = this;
|
||||
isBlank: computed('name', function () {
|
||||
let {name} = this;
|
||||
|
||||
return isBlank(label);
|
||||
return isBlank(name);
|
||||
})
|
||||
});
|
||||
|
@ -424,9 +424,9 @@
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.gh-product-benefits .gh-blognav-add {
|
||||
/* .gh-product-benefits .gh-blognav-add {
|
||||
display: none;
|
||||
}
|
||||
} */
|
||||
|
||||
.gh-product-benefits .gh-blognav-grab {
|
||||
text-indent: 0px;
|
||||
@ -440,4 +440,4 @@
|
||||
|
||||
.gh-product-benefits .gh-blognav-item:not(.gh-blognav-item--sortable) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
@ -6,11 +6,7 @@ export default Transform.extend({
|
||||
deserialize(serialized, options) {
|
||||
let benefitsItems, benefitsArray;
|
||||
|
||||
try {
|
||||
benefitsArray = JSON.parse(serialized) || [];
|
||||
} catch (e) {
|
||||
benefitsArray = [];
|
||||
}
|
||||
benefitsArray = serialized || [];
|
||||
|
||||
benefitsItems = benefitsArray.map((itemDetails) => {
|
||||
itemDetails.isSecondary = options && options.isSecondary || false;
|
||||
@ -25,13 +21,13 @@ export default Transform.extend({
|
||||
|
||||
if (isEmberArray(deserialized)) {
|
||||
benefitsArray = deserialized.map((item) => {
|
||||
let label = item.get('label').trim();
|
||||
return {label};
|
||||
let name = item.get('name').trim();
|
||||
return {name};
|
||||
}).compact();
|
||||
} else {
|
||||
benefitsArray = [];
|
||||
}
|
||||
|
||||
return JSON.stringify(benefitsArray);
|
||||
return benefitsArray;
|
||||
}
|
||||
});
|
||||
|
@ -2,17 +2,17 @@ import BaseValidator from './base';
|
||||
import {isBlank} from '@ember/utils';
|
||||
|
||||
export default BaseValidator.create({
|
||||
properties: ['label'],
|
||||
properties: ['name'],
|
||||
|
||||
label(model) {
|
||||
let label = model.get('label');
|
||||
name(model) {
|
||||
let name = model.get('name');
|
||||
let hasValidated = model.get('hasValidated');
|
||||
|
||||
if (isBlank(label)) {
|
||||
model.get('errors').add('label', 'You must specify a label');
|
||||
if (isBlank(name)) {
|
||||
model.get('errors').add('name', 'You must specify a name');
|
||||
this.invalidate();
|
||||
}
|
||||
|
||||
hasValidated.addObject('label');
|
||||
hasValidated.addObject('name');
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user