mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Added error handling for price modal
refs https://github.com/TryGhost/Team/issues/678 Covers error handling for missing name/amount/billing period for a price modal when adding a new price or editing existing price.
This commit is contained in:
parent
42463e4fdd
commit
d3efc29f08
3 changed files with 52 additions and 26 deletions
|
@ -9,7 +9,7 @@
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="gh-main-section-block">
|
<div class="gh-main-section-block">
|
||||||
<div class="gh-main-section-content grey gh-product-priceform-block">
|
<div class="gh-main-section-content grey gh-product-priceform-block">
|
||||||
<GhFormGroup @errors={{this.price.errors}} @hasValidated={{this.price.hasValidated}} @property="name">
|
<GhFormGroup @errors={{this.errors}} @property="name">
|
||||||
<label for="name" class="fw6">Name</label>
|
<label for="name" class="fw6">Name</label>
|
||||||
<GhTextInput
|
<GhTextInput
|
||||||
@value={{readonly this.price.nickname}}
|
@value={{readonly this.price.nickname}}
|
||||||
|
@ -17,9 +17,9 @@
|
||||||
@name="name"
|
@name="name"
|
||||||
@id="name"
|
@id="name"
|
||||||
@class="gh-input" />
|
@class="gh-input" />
|
||||||
<GhErrorMessage @errors={{this.price.errors}} @property="name" />
|
<GhErrorMessage @errors={{this.errors}} @property="name" />
|
||||||
</GhFormGroup>
|
</GhFormGroup>
|
||||||
<GhFormGroup @errors={{this.price.errors}} @hasValidated={{this.price.hasValidated}} @property="description">
|
<GhFormGroup @errors={{this.errors}} @property="description">
|
||||||
<label for="description" class="fw6">Description</label>
|
<label for="description" class="fw6">Description</label>
|
||||||
<GhTextInput
|
<GhTextInput
|
||||||
@value={{readonly this.price.description}}
|
@value={{readonly this.price.description}}
|
||||||
|
@ -27,20 +27,21 @@
|
||||||
@name="description"
|
@name="description"
|
||||||
@id="description"
|
@id="description"
|
||||||
@class="gh-input" />
|
@class="gh-input" />
|
||||||
<GhErrorMessage @errors={{this.price.errors}} @property="description" />
|
<GhErrorMessage @errors={{this.errors}} @property="description" />
|
||||||
</GhFormGroup>
|
</GhFormGroup>
|
||||||
<div class="gh-product-priceform-pricecurrency">
|
<div class="gh-product-priceform-pricecurrency">
|
||||||
<GhFormGroup @errors={{this.price.errors}} @hasValidated={{this.price.hasValidated}} @property="price">
|
<GhFormGroup @errors={{this.errors}} @property="amount">
|
||||||
<label for="price" class="fw6">Price</label>
|
<label for="amount" class="fw6">Price</label>
|
||||||
<div class="flex items-center justify-center gh-labs-price-label">
|
<div class="flex items-center justify-center gh-labs-price-label">
|
||||||
<GhTextInput
|
<GhTextInput
|
||||||
|
@id="amount"
|
||||||
@value={{this.price.amount}}
|
@value={{this.price.amount}}
|
||||||
@type="number"
|
@type="number"
|
||||||
@disabled={{this.isExistingPrice}}
|
@disabled={{this.isExistingPrice}}
|
||||||
@input={{action "setAmount" value="target.value"}}
|
@input={{action "setAmount" value="target.value"}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<GhErrorMessage @errors={{this.price.errors}} @property="price" />
|
<GhErrorMessage @errors={{this.errors}} @property="amount" />
|
||||||
</GhFormGroup>
|
</GhFormGroup>
|
||||||
<GhFormGroup @class="for-select">
|
<GhFormGroup @class="for-select">
|
||||||
<label class="fw6 f8"for="currency">Plan currency</label>
|
<label class="fw6 f8"for="currency">Plan currency</label>
|
||||||
|
@ -65,6 +66,7 @@
|
||||||
@triggerId="period-input"
|
@triggerId="period-input"
|
||||||
@value={{this.price.interval}} @disabled={{this.isExistingPrice}}
|
@value={{this.price.interval}} @disabled={{this.isExistingPrice}}
|
||||||
/>
|
/>
|
||||||
|
<GhErrorMessage @errors={{this.errors}} @property="interval" />
|
||||||
</GhFormGroup>
|
</GhFormGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
import EmberObject, {action} from '@ember/object';
|
||||||
import ModalBase from 'ghost-admin/components/modal-base';
|
import ModalBase from 'ghost-admin/components/modal-base';
|
||||||
import classic from 'ember-classic-decorator';
|
import classic from 'ember-classic-decorator';
|
||||||
import {action} from '@ember/object';
|
|
||||||
import {currencies} from 'ghost-admin/utils/currency';
|
import {currencies} from 'ghost-admin/utils/currency';
|
||||||
|
import {isEmpty} from '@ember/utils';
|
||||||
import {task} from 'ember-concurrency-decorators';
|
import {task} from 'ember-concurrency-decorators';
|
||||||
import {tracked} from '@glimmer/tracking';
|
import {tracked} from '@glimmer/tracking';
|
||||||
|
|
||||||
|
@ -12,6 +13,7 @@ export default class ModalProductPrice extends ModalBase {
|
||||||
@tracked price;
|
@tracked price;
|
||||||
@tracked currencyVal;
|
@tracked currencyVal;
|
||||||
@tracked periodVal;
|
@tracked periodVal;
|
||||||
|
@tracked errors = EmberObject.create();
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
super.init(...arguments);
|
super.init(...arguments);
|
||||||
|
@ -80,7 +82,10 @@ export default class ModalProductPrice extends ModalBase {
|
||||||
|
|
||||||
@task({drop: true})
|
@task({drop: true})
|
||||||
*savePrice() {
|
*savePrice() {
|
||||||
try {
|
this.validatePriceData();
|
||||||
|
if (!isEmpty(this.errors) && Object.keys(this.errors).length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const priceObj = {
|
const priceObj = {
|
||||||
...this.price,
|
...this.price,
|
||||||
amount: (this.price.amount || 0) * 100
|
amount: (this.price.amount || 0) * 100
|
||||||
|
@ -92,11 +97,26 @@ export default class ModalProductPrice extends ModalBase {
|
||||||
priceObj.type = 'recurring';
|
priceObj.type = 'recurring';
|
||||||
}
|
}
|
||||||
yield this.confirm(priceObj);
|
yield this.confirm(priceObj);
|
||||||
} catch (error) {
|
|
||||||
this.notifications.showAPIError(error, {key: 'price.save.failed'});
|
|
||||||
} finally {
|
|
||||||
this.send('closeModal');
|
this.send('closeModal');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validatePriceData() {
|
||||||
|
this.errors = EmberObject.create();
|
||||||
|
if (!this.price.nickname) {
|
||||||
|
this.errors.set('name', [{
|
||||||
|
message: 'Please enter name'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (isNaN(this.price.amount)) {
|
||||||
|
this.errors.set('amount', [{
|
||||||
|
message: 'Please enter amount'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (!this.price.interval || !['month', 'year'].includes(this.price.interval)) {
|
||||||
|
this.errors.set('interval', [{
|
||||||
|
message: 'Please enter billing interval'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actions = {
|
actions = {
|
||||||
|
|
|
@ -168,7 +168,11 @@ export default class ProductController extends Controller {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
yield this.settings.save();
|
yield this.settings.save();
|
||||||
return yield this.product.save();
|
const response = yield this.product.save();
|
||||||
|
if (this.showPriceModal) {
|
||||||
|
this.closePriceModal();
|
||||||
|
}
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
_validateSignupRedirect(url, type) {
|
_validateSignupRedirect(url, type) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue