@vertical-insure/web-components
Version:
Vertical Insure Web Components using Lit and Open Web Standards
263 lines (255 loc) • 9.5 kB
JavaScript
import { OfferRadioButtonType } from "../../common/offer-radio-button.js";
import { BaseElement } from "../../lib/base-element.js";
import { OfferPaymentMixin } from "../../lib/mixin/offer-payment-mixin.js";
import offerBoxStyles from "../../lib/offer-box-styles.js";
import { ProductController } from "../../lib/product-display-controller.js";
import { SelectedState } from "../../lib/selected-state.js";
import { ControllerStatus, FRIENDLY_ERROR_MESSAGE } from "../../lib/utils.js";
import { html, css } from "lit";
import { property, queryAssignedElements, state, customElement } from "lit/decorators.js";
import { styleMap } from "lit/directives/style-map.js";
import { when } from "lit/directives/when.js";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result) __defProp(target, key, result);
return result;
};
let MultiOfferWrapperElement = class extends OfferPaymentMixin(BaseElement) {
constructor() {
super();
this.hideOnError = false;
this.quotes = [];
this.error = false;
this.hidden = false;
this.selectedState = SelectedState.UNKNOWN;
this.productController = new ProductController(this, () => {
var _a, _b, _c, _d, _e;
this.quoteForProductDisplay = (_a = this.productController) == null ? void 0 : _a.value;
if ((_c = (_b = this.productController) == null ? void 0 : _b.value) == null ? void 0 : _c.offer_id) {
this.offerId = (_e = (_d = this.productController) == null ? void 0 : _d.value) == null ? void 0 : _e.offer_id;
}
});
}
/**
* @ignore
*/
updated() {
var _a;
if ((((_a = this.productController) == null ? void 0 : _a.status) === ControllerStatus.ERROR || this.childElementCount === 0 || this._productElements.length > 0 && this._productElements.every((node) => {
var _a2;
return ((_a2 = node.quoteController) == null ? void 0 : _a2.error) !== void 0;
})) && !this.error) {
this.error = true;
this.dispatchEvent(new CustomEvent("empty-offer-error"));
if (this.debug) {
console.log("Fired empty-off-error: all child components encountered an error");
}
}
if (this.hideOnError && this.error && !this.hidden) {
this.hidden = true;
if (this.debug) {
console.log("Offer is hidden: all child components encountered an error and hide-on-error=true");
}
}
}
/**
* @ignore
*/
handleSlotchange() {
this._productElements.forEach((node, index) => {
node.clientId = this.clientId;
node.multiMode = true;
node.debug = false;
node.dataset.uniqueId = index.toString();
node.addEventListener("quote-error", () => {
this.requestUpdate();
});
node.addEventListener("offer-state-change", (e) => {
e.stopPropagation();
e.stopImmediatePropagation();
this.errors = [];
const shouldResetDeclinedState = this.quotes.every((q) => (q == null ? void 0 : q.selectedState) === SelectedState[SelectedState.DECLINED]) && e.detail.selectedState !== SelectedState[SelectedState.DECLINED];
const quoteUpdates = shouldResetDeclinedState ? [...this.quotes.map((q) => q ? {
quote: q == null ? void 0 : q.quote,
selectedState: SelectedState[SelectedState.UNKNOWN]
} : void 0)] : [...this.quotes];
quoteUpdates[index] = e.detail;
this.quotes = quoteUpdates;
this.selectedState = this.quotes.some((q) => (q == null ? void 0 : q.selectedState) === SelectedState[SelectedState.ACCEPTED]) ? SelectedState.ACCEPTED : this.selectedState === SelectedState.DECLINED ? SelectedState.DECLINED : SelectedState.UNKNOWN;
if (!this.quotes.includes(void 0)) {
this.dispatchEvent(new CustomEvent("offer-state-change", {
detail: quoteUpdates
}));
if (this.debug) {
console.debug("Fired offer-state-change event", quoteUpdates);
}
}
});
});
}
/**
* @ignore
*/
_hasErrors() {
return this._productElements.some((node) => {
var _a;
return (_a = node.quoteController) == null ? void 0 : _a.error;
});
}
/**
* @ignore
*/
_getErrorDisplayMessage() {
var _a, _b;
const error = (_b = (_a = this._productElements.find((node) => {
var _a2;
return (_a2 = node.quoteController) == null ? void 0 : _a2.error;
})) == null ? void 0 : _a.quoteController) == null ? void 0 : _b.error;
if ((error == null ? void 0 : error.cause) === "StateNotAvailable" || (error == null ? void 0 : error.cause) === "ActivityNotAvailable") {
return error.message;
}
}
_shouldHideActions() {
return this.quotes.length === 0;
}
/**
* @ignore
*/
get offerId() {
return localStorage.getItem(this.offerIdStorageKey);
}
/**
* @ignore
*/
set offerId(offerId) {
if (offerId) localStorage.setItem(this.offerIdStorageKey, offerId);
}
/**
* @ignore
*/
get offerIdStorageKey() {
return "_vi_offer_id:" + this.product;
}
async declineMultiOffer() {
if (this.selectedState !== SelectedState.DECLINED) {
this.selectedState = SelectedState.DECLINED;
this.errors = [];
const quoteUpdates = [...this.quotes];
for await (const [index, node] of this._productElements.entries()) {
node.selectedState = SelectedState.DECLINED;
await node.updateComplete;
quoteUpdates[index] = {
quote: node.quote,
selectedState: SelectedState[node.selectedState]
};
}
this.quotes = quoteUpdates;
if (!this.quotes.includes(void 0)) {
this.dispatchEvent(new CustomEvent("offer-state-change", {
detail: this.quotes
}));
if (this.debug) {
console.debug("Fired offer-state-change event", this.quotes);
}
}
}
}
render() {
var _a;
return (_a = this.productController) == null ? void 0 : _a.render({
complete: () => html`
<div id="offer-display" style=${styleMap({ display: this.hidden ? "none" : "flex" })}>
<div id="offer-tag-wrapper">
<div id="offer-tag">Recommended</div>
</div>
<offer-header .quote=${this.quoteForProductDisplay}></offer-header>
${when(this._hasErrors(), () => html`
<div class="error-message" id="quote-errors">
${this._getErrorDisplayMessage()}
</div>
`)}
<section id="offer-content">
<descriptor-list .quote=${this.quoteForProductDisplay} .declined=${this.selectedState === SelectedState.DECLINED}></descriptor-list>
<section id="actions" style=${styleMap({ display: this._shouldHideActions() ? "none" : "block" })}>
<div id="action-header"><span class="option-required">*</span> Required: Choose or decline coverage</div>
<slot @slotchange=${this.handleSlotchange}></slot>
<offer-radio-button type=${OfferRadioButtonType.DECLINED} @click=${this.declineMultiOffer} .checked=${this.selectedState === SelectedState.DECLINED} .display=${"checkbox"}>
Decline Coverage
</offer-radio-button>
${when(this.errors.length > 0 && this.errors.some((v) => v in FRIENDLY_ERROR_MESSAGE), () => html`
<section id="errors" class="error-message">
${this.errors.map((e) => html`<p>${FRIENDLY_ERROR_MESSAGE[e]}</p>`)}
</section>
`)}
</section>
</section>
${this.renderPaymentElement()}
<legal-disclaimer .quote=${this.quoteForProductDisplay}></legal-disclaimer>
</div>
`,
error: () => html``
});
}
};
MultiOfferWrapperElement.styles = [
offerBoxStyles,
css`
:host {
height: 100%;
margin-top: 10px;
}
slot {
display: grid;
flex: 1;
row-gap: var(--default-vi-action-spacing);
}
::slotted(*) {
margin: 0;
}
section#actions {
display: block;
}
section#actions slot {
margin-bottom: 10px;
}
section#errors {
margin-top: 10px;
}
#quote-errors {
margin-bottom: 10px;
color: var(--default-vi-danger-color);
}
`
];
__decorateClass([
property({ attribute: "product" })
], MultiOfferWrapperElement.prototype, "product", 2);
__decorateClass([
property({ type: Boolean, attribute: "hide-on-error" })
], MultiOfferWrapperElement.prototype, "hideOnError", 2);
__decorateClass([
queryAssignedElements()
], MultiOfferWrapperElement.prototype, "_productElements", 2);
__decorateClass([
state()
], MultiOfferWrapperElement.prototype, "quoteForProductDisplay", 2);
__decorateClass([
state()
], MultiOfferWrapperElement.prototype, "quotes", 2);
__decorateClass([
state()
], MultiOfferWrapperElement.prototype, "error", 2);
__decorateClass([
state()
], MultiOfferWrapperElement.prototype, "hidden", 2);
MultiOfferWrapperElement = __decorateClass([
customElement("multi-offer")
], MultiOfferWrapperElement);
export {
MultiOfferWrapperElement
};