@internetarchive/donation-form 0.5.15-a1 → 0.5.15-a3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/demo/braintree-endpoint-manager.js +1 -1
- package/dist/demo/braintree-endpoint-manager.js.map +1 -1
- package/dist/demo/demo-analytics-handler.d.ts +15 -4
- package/dist/demo/demo-analytics-handler.js +9 -8
- package/dist/demo/demo-analytics-handler.js.map +1 -1
- package/dist/src/donation-form-controller.d.ts +2 -2
- package/dist/src/donation-form-controller.js +6 -2
- package/dist/src/donation-form-controller.js.map +1 -1
- package/dist/src/payment-flow-handlers/donation-flow-modal-manager.js.map +1 -1
- package/dist/test/tests/donation-form-controller.test.js +30 -27
- package/dist/test/tests/donation-form-controller.test.js.map +1 -1
- package/package.json +2 -1
- package/src/@types/analytics-handler/index.d.ts +0 -38
- package/src/donation-form-controller.ts +10 -5
- package/src/payment-flow-handlers/donation-flow-modal-manager.ts +1 -1
|
@@ -5,7 +5,7 @@ import currency from 'currency.js';
|
|
|
5
5
|
export class BraintreeEndpointManager {
|
|
6
6
|
submitData(request) {
|
|
7
7
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8
|
-
const response = yield fetch('https://
|
|
8
|
+
const response = yield fetch('https://ia-petabox.archive.org/services/donations/braintree-charge.php?debug=true', {
|
|
9
9
|
method: 'POST',
|
|
10
10
|
headers: {
|
|
11
11
|
'Content-Type': 'application/json',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"braintree-endpoint-manager.js","sourceRoot":"","sources":["../../demo/braintree-endpoint-manager.ts"],"names":[],"mappings":";AAAA,iDAAiD;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,QAAQ,MAAM,aAAa,CAAC;AAUnC,MAAM,OAAO,wBAAwB;IAC7B,UAAU,CAAC,OAAwB;;YACvC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,mFAAmF,EACnF;gBACE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,MAAM,EAAE,kBAAkB;iBAC3B;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAC9B,CACF,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC;QACd,CAAC;KAAA;IAED,kBAAkB,CAAC,OAGlB;QACC,MAAM,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC;QACzC,MAAM,cAAc,GAAG,OAAO,CAAC,qBAAqB,CAAC;QAErD,MAAM,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEhD,MAAM,OAAO,GAA0C;YACrD,MAAM,EAAE,GAAG,aAAa,EAAE;YAC1B,WAAW,EAAE,QAAQ,CAAC,cAAc;YACpC,eAAe,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY;YAClE,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS;YACvC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,QAAQ;YACrC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK;SAC/B,CAAC;QAEF,IAAI,cAAc,EAAE;YAClB,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC;YAC3C,MAAM,cAAc,GAAG,cAAc,CAAC,cAAc,CAAC;YACrD,MAAM,mBAAmB,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;YACnD,OAAO,CAAC,eAAe,CAAC,GAAG,GAAG,mBAAmB,EAAE,CAAC;YACpD,OAAO,CAAC,kBAAkB,CAAC,GAAG,cAAc,CAAC;SAC9C;QAED,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAEpD,cAAc,CAAC;YACb,MAAM,EAAE,8DAA8D,OAAO,EAAE;YAC/E,MAAM,EAAE,OAAO;SAChB,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["/* eslint-disable @typescript-eslint/camelcase */\nimport { submitFormWith } from './submit-form-with';\nimport currency from 'currency.js';\n\nimport {\n SuccessResponse,\n DonationRequest,\n DonationResponse,\n} from '@internetarchive/donation-form-data-models';\n\nimport { BraintreeEndpointManagerInterface } from '../index';\n\nexport class BraintreeEndpointManager implements BraintreeEndpointManagerInterface {\n async submitData(request: DonationRequest): Promise<DonationResponse> {\n const response = await fetch(\n 'https://
|
|
1
|
+
{"version":3,"file":"braintree-endpoint-manager.js","sourceRoot":"","sources":["../../demo/braintree-endpoint-manager.ts"],"names":[],"mappings":";AAAA,iDAAiD;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,QAAQ,MAAM,aAAa,CAAC;AAUnC,MAAM,OAAO,wBAAwB;IAC7B,UAAU,CAAC,OAAwB;;YACvC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,mFAAmF,EACnF;gBACE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,MAAM,EAAE,kBAAkB;iBAC3B;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAC9B,CACF,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC;QACd,CAAC;KAAA;IAED,kBAAkB,CAAC,OAGlB;QACC,MAAM,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC;QACzC,MAAM,cAAc,GAAG,OAAO,CAAC,qBAAqB,CAAC;QAErD,MAAM,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEhD,MAAM,OAAO,GAA0C;YACrD,MAAM,EAAE,GAAG,aAAa,EAAE;YAC1B,WAAW,EAAE,QAAQ,CAAC,cAAc;YACpC,eAAe,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY;YAClE,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS;YACvC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,QAAQ;YACrC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK;SAC/B,CAAC;QAEF,IAAI,cAAc,EAAE;YAClB,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC;YAC3C,MAAM,cAAc,GAAG,cAAc,CAAC,cAAc,CAAC;YACrD,MAAM,mBAAmB,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;YACnD,OAAO,CAAC,eAAe,CAAC,GAAG,GAAG,mBAAmB,EAAE,CAAC;YACpD,OAAO,CAAC,kBAAkB,CAAC,GAAG,cAAc,CAAC;SAC9C;QAED,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAEpD,cAAc,CAAC;YACb,MAAM,EAAE,8DAA8D,OAAO,EAAE;YAC/E,MAAM,EAAE,OAAO;SAChB,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["/* eslint-disable @typescript-eslint/camelcase */\nimport { submitFormWith } from './submit-form-with';\nimport currency from 'currency.js';\n\nimport {\n SuccessResponse,\n DonationRequest,\n DonationResponse,\n} from '@internetarchive/donation-form-data-models';\n\nimport { BraintreeEndpointManagerInterface } from '../index';\n\nexport class BraintreeEndpointManager implements BraintreeEndpointManagerInterface {\n async submitData(request: DonationRequest): Promise<DonationResponse> {\n const response = await fetch(\n 'https://ia-petabox.archive.org/services/donations/braintree-charge.php?debug=true',\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify(request),\n },\n );\n const json = await response.json();\n return json;\n }\n\n donationSuccessful(options: {\n successResponse: SuccessResponse;\n upsellSuccessResponse?: SuccessResponse;\n }): void {\n const response = options.successResponse;\n const upsellResponse = options.upsellSuccessResponse;\n\n const displayAmount = currency(response.amount);\n\n const payload: { [key: string]: string | undefined } = {\n amount: `${displayAmount}`,\n 'charge-id': response.transaction_id,\n 'donation-type': upsellResponse ? 'upsell' : response.donationType,\n first_name: response.customer.firstName,\n last_name: response.customer.lastName,\n email: response.customer.email,\n };\n\n if (upsellResponse) {\n const upsellAmount = upsellResponse.amount;\n const upsellChargeId = upsellResponse.transaction_id;\n const displayUpsellAmount = currency(upsellAmount);\n payload['upsell-amount'] = `${displayUpsellAmount}`;\n payload['upsell-charge-id'] = upsellChargeId;\n }\n\n const service = encodeURI(response.paymentProvider);\n\n submitFormWith({\n action: `https://www-jasonb.archive.org/services/donate.php?service=${service}`,\n fields: payload,\n });\n }\n}\n"]}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare class DemoAnalyticsHandler implements
|
|
1
|
+
import { AnalyticsManagerInterface } from '@internetarchive/analytics-manager';
|
|
2
|
+
export declare class DemoAnalyticsHandler implements AnalyticsManagerInterface {
|
|
3
3
|
nodeToUpdate: HTMLElement;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
sendEvent(options: {
|
|
5
|
+
category: string;
|
|
6
|
+
action: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
additionalEventParams?: object;
|
|
9
|
+
}): void;
|
|
10
|
+
sendEventNoSampling(options: {
|
|
11
|
+
category: string;
|
|
12
|
+
action: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
additionalEventParams?: object;
|
|
15
|
+
}): void;
|
|
16
|
+
sendPing(values: Record<string, any>): void;
|
|
6
17
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
export class DemoAnalyticsHandler {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
console.debug('DemoAnalyticsHandler',
|
|
2
|
+
sendEvent(options) {
|
|
3
|
+
this.nodeToUpdate.innerHTML = `Category: ${options.category} - Action: ${options.action} - Label: ${options.label}`;
|
|
4
|
+
console.debug('DemoAnalyticsHandler -- sendEvent ', Object.assign({}, options), this.nodeToUpdate.innerHTML);
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
console.debug('DemoAnalyticsHandler',
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
sendEventNoSampling(options) {
|
|
7
|
+
this.nodeToUpdate.innerHTML = `Category: ${options.category} - Action: ${options.action} - Label: ${options.label}`;
|
|
8
|
+
console.debug('DemoAnalyticsHandler -- sendEventNoSampling ', Object.assign({}, options), this.nodeToUpdate.innerHTML);
|
|
9
|
+
}
|
|
10
|
+
sendPing(values) {
|
|
11
|
+
console.debug('DemoAnalyticsHandler -- sendPing ', Object.assign({}, values));
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
14
|
//# sourceMappingURL=demo-analytics-handler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"demo-analytics-handler.js","sourceRoot":"","sources":["../../demo/demo-analytics-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"demo-analytics-handler.js","sourceRoot":"","sources":["../../demo/demo-analytics-handler.ts"],"names":[],"mappings":"AACA,MAAM,OAAO,oBAAoB;IAG/B,SAAS,CAAC,OAKT;QACC,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,aAAa,OAAO,CAAC,QAAQ,cAAc,OAAO,CAAC,MAAM,aAAa,OAAO,CAAC,KAAK,EAAE,CAAC;QACpH,OAAO,CAAC,KAAK,CAAC,oCAAoC,oBAAO,OAAO,GAAI,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACnG,CAAC;IAED,mBAAmB,CACjB,OAKC;QACC,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,aAAa,OAAO,CAAC,QAAQ,cAAc,OAAO,CAAC,MAAM,aAAa,OAAO,CAAC,KAAK,EAAE,CAAC;QACpH,OAAO,CAAC,KAAK,CAAC,8CAA8C,oBAAO,OAAO,GAAI,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAC/G,CAAC;IAED,QAAQ,CAAC,MAA2B;QAClC,OAAO,CAAC,KAAK,CAAC,mCAAmC,oBAAO,MAAM,EAAG,CAAC;IACpE,CAAC;CACF","sourcesContent":["import { AnalyticsManagerInterface } from '@internetarchive/analytics-manager';\nexport class DemoAnalyticsHandler implements AnalyticsManagerInterface {\n nodeToUpdate!: HTMLElement;\n\n sendEvent(options: {\n category: string;\n action: string;\n label?: string;\n additionalEventParams?: object;\n }): void {\n this.nodeToUpdate.innerHTML = `Category: ${options.category} - Action: ${options.action} - Label: ${options.label}`;\n console.debug('DemoAnalyticsHandler -- sendEvent ', { ...options }, this.nodeToUpdate.innerHTML);\n }\n\n sendEventNoSampling(\n options: {\n category: string;\n action: string;\n label?: string;\n additionalEventParams?: object;\n }): void {\n this.nodeToUpdate.innerHTML = `Category: ${options.category} - Action: ${options.action} - Label: ${options.label}`;\n console.debug('DemoAnalyticsHandler -- sendEventNoSampling ', { ...options }, this.nodeToUpdate.innerHTML);\n }\n\n sendPing(values: Record<string, any>): void {\n console.debug('DemoAnalyticsHandler -- sendPing ', { ...values });\n }\n}\n"]}
|
|
@@ -7,7 +7,7 @@ import { PaymentFlowHandlersInterface } from './payment-flow-handlers/payment-fl
|
|
|
7
7
|
import { RecaptchaManagerInterface } from './recaptcha-manager/recaptcha-manager';
|
|
8
8
|
import './form-elements/badged-input';
|
|
9
9
|
import './form-elements/contact-form/contact-form';
|
|
10
|
-
import {
|
|
10
|
+
import { AnalyticsManagerInterface } from '@internetarchive/analytics-manager';
|
|
11
11
|
import { EditDonationAmountSelectionLayout, EditDonationFrequencySelectionMode } from '@internetarchive/donation-form-edit-donation';
|
|
12
12
|
import { DonationPaymentInfo, DonationType } from '@internetarchive/donation-form-data-models';
|
|
13
13
|
import { UpsellModalCTAMode } from './modals/upsell-modal-content';
|
|
@@ -34,7 +34,7 @@ export declare class DonationFormController extends LitElement {
|
|
|
34
34
|
loggedInUser?: string;
|
|
35
35
|
origin?: string;
|
|
36
36
|
endpointManager?: BraintreeEndpointManagerInterface;
|
|
37
|
-
analyticsHandler?:
|
|
37
|
+
analyticsHandler?: AnalyticsManagerInterface;
|
|
38
38
|
modalManager?: ModalManagerInterface;
|
|
39
39
|
recaptchaElement?: HTMLElement;
|
|
40
40
|
braintreeManager?: BraintreeManagerInterface;
|
|
@@ -40,12 +40,14 @@ let DonationFormController = class DonationFormController extends LitElement {
|
|
|
40
40
|
var _a, _b, _c;
|
|
41
41
|
if (changedProperties.has('referrer') && this.referrer) {
|
|
42
42
|
(_a = this.braintreeManager) === null || _a === void 0 ? void 0 : _a.setReferrer(this.referrer);
|
|
43
|
+
this.logEventNoSampling('referrer', this.referrer);
|
|
43
44
|
}
|
|
44
45
|
if (changedProperties.has('loggedInUser') && this.loggedInUser) {
|
|
45
46
|
(_b = this.braintreeManager) === null || _b === void 0 ? void 0 : _b.setLoggedInUser(this.loggedInUser);
|
|
46
47
|
}
|
|
47
48
|
if (changedProperties.has('origin') && this.origin) {
|
|
48
49
|
(_c = this.braintreeManager) === null || _c === void 0 ? void 0 : _c.setOrigin(this.origin);
|
|
50
|
+
this.logEventNoSampling('origin', this.origin);
|
|
49
51
|
}
|
|
50
52
|
if (changedProperties.has('paymentClients') ||
|
|
51
53
|
changedProperties.has('braintreeAuthToken') ||
|
|
@@ -380,7 +382,8 @@ let DonationFormController = class DonationFormController extends LitElement {
|
|
|
380
382
|
*/
|
|
381
383
|
logEvent(action, label) {
|
|
382
384
|
var _a;
|
|
383
|
-
|
|
385
|
+
const analyticEvent = { action, label, category: this.analyticsCategory };
|
|
386
|
+
(_a = this.analyticsHandler) === null || _a === void 0 ? void 0 : _a.sendEvent(analyticEvent);
|
|
384
387
|
}
|
|
385
388
|
/**
|
|
386
389
|
* Log an event in no sample bucket
|
|
@@ -390,7 +393,8 @@ let DonationFormController = class DonationFormController extends LitElement {
|
|
|
390
393
|
*/
|
|
391
394
|
logEventNoSampling(action, label) {
|
|
392
395
|
var _a;
|
|
393
|
-
|
|
396
|
+
const analyticEvent = { action, label, category: this.analyticsCategory };
|
|
397
|
+
(_a = this.analyticsHandler) === null || _a === void 0 ? void 0 : _a.sendEventNoSampling(analyticEvent);
|
|
394
398
|
}
|
|
395
399
|
/**
|
|
396
400
|
* This is not the normal LitElement styles block.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"donation-form-controller.js","sourceRoot":"","sources":["../../src/donation-form-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, PropertyValues, TemplateResult } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\n\nimport currency from 'currency.js';\nimport {\n LazyLoaderService,\n LazyLoaderServiceInterface,\n} from '@internetarchive/lazy-loader-service';\nimport { ModalManagerInterface } from '@internetarchive/modal-manager';\n\nimport { DonationForm } from './donation-form';\nimport { PaymentClients, PaymentClientsInterface } from './braintree-manager/payment-clients';\nimport { BraintreeManager } from './braintree-manager/braintree-manager';\nimport {\n BraintreeEndpointManagerInterface,\n BraintreeManagerInterface,\n HostingEnvironment,\n} from './braintree-manager/braintree-interfaces';\nimport {\n PaymentFlowHandlers,\n PaymentFlowHandlersInterface,\n} from './payment-flow-handlers/payment-flow-handlers';\n\nimport { RecaptchaManager, RecaptchaManagerInterface } from './recaptcha-manager/recaptcha-manager';\nimport { HostedFieldConfiguration } from './braintree-manager/payment-providers/credit-card/hosted-field-configuration';\nimport {\n HostedFieldContainerInterface,\n HostedFieldContainer,\n} from './braintree-manager/payment-providers/credit-card/hosted-field-container';\n\nimport './form-elements/badged-input';\nimport { ContactForm } from './form-elements/contact-form/contact-form';\nimport './form-elements/contact-form/contact-form';\n\nimport creditCardImg from '@internetarchive/icon-credit-card';\nimport calendarImg from '@internetarchive/icon-calendar';\nimport lockImg from '@internetarchive/icon-lock';\nimport { AnalyticsHandlerInterface, DonationControllerEventLoggerInterface } from './@types/analytics-handler';\nimport {\n EditDonationAmountSelectionLayout,\n EditDonationFrequencySelectionMode,\n} from '@internetarchive/donation-form-edit-donation';\n\nimport {\n DonationPaymentInfo,\n PaymentProvider,\n DonationType,\n defaultDonationAmounts,\n defaultSelectedDonationInfo,\n} from '@internetarchive/donation-form-data-models';\nimport { UpsellModalCTAMode } from './modals/upsell-modal-content';\n\n/**\n * The DonationFormController orchestrates several of the interactions between\n * the various pieces of the donation form like modals, braintree, paypal, and recaptcha\n *\n * @export\n * @class RadioPlayerController\n * @extends {LitElement}\n */\n@customElement('donation-form-controller')\nexport class DonationFormController extends LitElement {\n @property({ type: String }) environment?: HostingEnvironment;\n\n @property({ type: String }) braintreeAuthToken?: string;\n\n @property({ type: String }) recaptchaSiteKey?: string;\n\n @property({ type: String }) venmoProfileId?: string;\n\n @property({ type: String }) googlePayMerchantId?: string;\n\n @property({ type: String }) analyticsCategory = 'DonationForm';\n\n @property({ type: Array }) amountOptions: number[] = defaultDonationAmounts;\n\n @property({ type: Object }) donationInfo: DonationPaymentInfo = defaultSelectedDonationInfo;\n\n @property({ type: String }) amountSelectionLayout: EditDonationAmountSelectionLayout =\n EditDonationAmountSelectionLayout.MultiLine;\n\n @property({ type: String }) frequencySelectionMode: EditDonationFrequencySelectionMode =\n EditDonationFrequencySelectionMode.Button;\n\n @property({ type: String }) referrer?: string;\n\n @property({ type: String }) loggedInUser?: string;\n\n @property({ type: String }) origin?: string;\n\n @property({ type: Object }) endpointManager?: BraintreeEndpointManagerInterface;\n\n @property({ type: Object }) analyticsHandler?: AnalyticsHandlerInterface;\n\n @property({ type: Object }) modalManager?: ModalManagerInterface;\n\n @property({ type: Object }) recaptchaElement?: HTMLElement;\n\n @property({ type: Object }) braintreeManager?: BraintreeManagerInterface;\n\n @property({ type: Object }) recaptchaManager?: RecaptchaManagerInterface;\n\n @property({ type: Object }) paymentFlowHandlers?: PaymentFlowHandlersInterface;\n\n @property({ type: Object }) paymentClients?: PaymentClientsInterface;\n\n @property({ type: Object })\n lazyLoaderService: LazyLoaderServiceInterface = new LazyLoaderService();\n\n @query('donation-form') private donationForm!: DonationForm;\n\n @query('#braintree-creditcard') private braintreeNumberInput!: HTMLDivElement;\n\n @query('#braintree-cvv') private braintreeCVVInput!: HTMLDivElement;\n\n @query('#braintree-expiration') private braintreeExpirationDateInput!: HTMLDivElement;\n\n @query('#braintree-error-message') private braintreeErrorMessage!: HTMLDivElement;\n\n @query('contact-form') private contactForm?: ContactForm;\n\n /** @inheritdoc */\n updated(changedProperties: PropertyValues): void {\n if (changedProperties.has('referrer') && this.referrer) {\n this.braintreeManager?.setReferrer(this.referrer);\n }\n\n if (changedProperties.has('loggedInUser') && this.loggedInUser) {\n this.braintreeManager?.setLoggedInUser(this.loggedInUser);\n }\n\n if (changedProperties.has('origin') && this.origin) {\n this.braintreeManager?.setOrigin(this.origin);\n }\n\n if (\n changedProperties.has('paymentClients') ||\n changedProperties.has('braintreeAuthToken') ||\n changedProperties.has('endpointManager') ||\n changedProperties.has('environment')\n ) {\n this.setupBraintreeManager();\n this.setupRecaptchaManager();\n }\n\n if (changedProperties.has('recaptchaSiteKey')) {\n this.setupRecaptchaManager();\n }\n\n if (\n changedProperties.has('braintreeManager') ||\n changedProperties.has('recaptchaManager') ||\n changedProperties.has('modalManager') ||\n changedProperties.has('recaptchaElement')\n ) {\n this.setupPaymentFlowHandlers();\n }\n\n if (\n (changedProperties.has('environment') || changedProperties.has('lazyLoaderService')) &&\n this.environment\n ) {\n this.paymentClients = new PaymentClients(this.lazyLoaderService, this.environment);\n }\n }\n\n async showConfirmationStepDev(options: {\n donationType: DonationType;\n amount: number;\n currencyType: string;\n cancelDonationCB: Function;\n confirmDonationCB: Function;\n }): Promise<void> {\n this.donationForm.showConfirmationModalDev(options);\n }\n\n async showUpsellModalDev(options: {\n oneTimeAmount: number;\n ctaMode?: UpsellModalCTAMode;\n yesSelected?: (amount: number) => void;\n noSelected?: () => void;\n amountChanged?: (amount: number) => void;\n userClosedModalCallback?: () => void;\n }): Promise<void> {\n this.donationForm.showUpsellModalDev(options);\n }\n\n private setupBraintreeManager(): void {\n if (\n this.braintreeManager === undefined &&\n this.braintreeAuthToken &&\n this.endpointManager &&\n this.paymentClients &&\n this.environment\n ) {\n this.braintreeManager = new BraintreeManager({\n paymentClients: this.paymentClients,\n endpointManager: this.endpointManager,\n authorizationToken: this.braintreeAuthToken,\n venmoProfileId: this.venmoProfileId,\n googlePayMerchantId: this.googlePayMerchantId,\n hostedFieldConfig: this.hostedFieldConfig,\n hostingEnvironment: this.environment,\n referrer: this.referrer,\n loggedInUser: this.loggedInUser,\n origin: this.origin,\n });\n\n this.braintreeManager.on('paymentProvidersHostedFieldsRetry', (retryNumber: number) => {\n const event = new CustomEvent('paymentProvidersHostedFieldsRetry', {\n detail: { retryNumber },\n });\n this.dispatchEvent(event);\n });\n\n this.braintreeManager.on('paymentProvidersHostedFieldsFailed', (error: unknown) => {\n const event = new CustomEvent('paymentProvidersHostedFieldsFailed', {\n detail: { error },\n });\n this.dispatchEvent(event);\n });\n }\n }\n\n private recaptchaManagerSetup = false;\n\n private async setupRecaptchaManager(): Promise<void> {\n if (!this.recaptchaSiteKey || !this.paymentClients || this.recaptchaManagerSetup) {\n return;\n }\n this.recaptchaManagerSetup = true;\n const grecaptchaLibrary = await this.paymentClients.recaptchaLibrary.get();\n this.recaptchaManager = new RecaptchaManager({\n grecaptchaLibrary: grecaptchaLibrary,\n siteKey: this.recaptchaSiteKey,\n });\n }\n\n /** @inheritdoc */\n firstUpdated(): void {\n this.configureFromQueryParams();\n this.trackViewedEvent();\n }\n\n private configureFromQueryParams(): void {\n const urlParams = new URLSearchParams(window.location.search);\n\n let amountOptions = this.amountOptions;\n const amountOptionsParam = urlParams.get('dollarAmounts');\n if (amountOptionsParam) {\n const stripBrackets = amountOptionsParam.slice(1, -1);\n const splitValues = stripBrackets.split(',');\n const numberArray = splitValues\n .map(value => parseFloat(value))\n .filter(value => !isNaN(value));\n amountOptions = numberArray;\n }\n\n let coverFees = this.donationInfo.coverFees;\n const coverFeesParam = urlParams.get('coverFees');\n if (coverFeesParam) {\n coverFees = coverFeesParam === 'true';\n }\n\n let frequency = this.donationInfo.donationType;\n const frequencyParam = urlParams.get('contrib_type');\n if (frequencyParam === 'monthly') {\n frequency = DonationType.Monthly;\n }\n\n let amount = this.donationInfo.amount;\n const amountParam = urlParams.get('amt');\n if (amountParam) {\n const parsedAmount = currency(amountParam).value;\n if (parsedAmount > 0) {\n amount = parsedAmount;\n }\n }\n\n const amountLayoutParam = urlParams.get('amountLayout');\n if (amountLayoutParam) {\n const amountLayout = amountLayoutParam as EditDonationAmountSelectionLayout;\n if (Object.values(EditDonationAmountSelectionLayout).includes(amountLayout)) {\n this.amountSelectionLayout = amountLayout;\n }\n }\n\n const frequencyModeParam = urlParams.get('frequencyMode');\n if (frequencyModeParam) {\n const frequencyMode = frequencyModeParam as EditDonationFrequencySelectionMode;\n if (Object.values(EditDonationFrequencySelectionMode).includes(frequencyMode)) {\n this.frequencySelectionMode = frequencyMode;\n }\n }\n\n const donationInfo = new DonationPaymentInfo({\n donationType: frequency,\n amount: amount,\n coverFees: coverFees,\n });\n\n this.amountOptions = amountOptions;\n this.donationInfo = donationInfo;\n }\n\n private setupPaymentFlowHandlers(): void {\n // only set up once\n if (this.paymentFlowHandlers) {\n return;\n }\n\n // verify we have all of the dependencies\n if (\n !this.braintreeManager ||\n !this.recaptchaManager ||\n !this.modalManager ||\n !this.recaptchaElement\n ) {\n return;\n }\n\n this.paymentFlowHandlers = new PaymentFlowHandlers({\n braintreeManager: this.braintreeManager,\n modalManager: this.modalManager,\n recaptchaManager: this.recaptchaManager,\n resources: {\n analytics: {\n logEvent: this.logEvent.bind(this),\n logEventNoSampling: this.logEventNoSampling.bind(this),\n } as DonationControllerEventLoggerInterface,\n }\n });\n\n this.donationForm.braintreeManager = this.braintreeManager;\n this.donationForm.paymentFlowHandlers = this.paymentFlowHandlers;\n\n this.braintreeManager.startup();\n this.paymentFlowHandlers?.startup();\n this.recaptchaManager.setup(this.recaptchaElement, 1, 'light', 'image');\n }\n\n private get hostedFieldConfig(): HostedFieldConfiguration {\n const hostedFieldStyle: Record<string, Record<string, string>> = {\n input: {\n 'font-size': '16px',\n 'font-family': '\"Helvetica Neue\", Helvetica, Arial, sans-serif',\n 'font-weight': '700',\n color: '#333',\n },\n ':focus': {\n color: '#333',\n },\n '.valid': {},\n '.invalid': {\n color: '#b00b00',\n },\n };\n\n const hostedFieldFieldOptions: braintree.HostedFieldFieldOptions = {\n number: {\n selector: '#braintree-creditcard',\n placeholder: 'Card number',\n },\n cvv: {\n selector: '#braintree-cvv',\n placeholder: 'CVC',\n },\n expirationDate: {\n selector: '#braintree-expiration',\n placeholder: 'MM / YY',\n },\n };\n\n const hostedFieldContainer: HostedFieldContainerInterface = new HostedFieldContainer({\n number: this.braintreeNumberInput,\n cvv: this.braintreeCVVInput,\n expirationDate: this.braintreeExpirationDateInput,\n errorContainer: this.braintreeErrorMessage,\n });\n\n const config: HostedFieldConfiguration = new HostedFieldConfiguration({\n hostedFieldStyle,\n hostedFieldFieldOptions,\n hostedFieldContainer,\n });\n\n return config;\n }\n\n /** @inheritdoc */\n render(): TemplateResult {\n return html`\n <div class=\"donation-form-controller-container\">\n <donation-form\n .environment=${this.environment}\n .braintreeManager=${this.braintreeManager}\n .contactForm=${this.contactForm}\n .amountOptions=${this.amountOptions}\n .donationInfo=${this.donationInfo}\n .amountSelectionLayout=${this.amountSelectionLayout}\n .frequencySelectionMode=${this.frequencySelectionMode}\n @donationInfoChanged=${this.donationInfoChanged}\n @paymentProviderSelected=${this.paymentProviderSelected}\n @paymentFlowStarted=${this.paymentFlowStarted}\n @paymentFlowConfirmed=${this.paymentFlowConfirmed}\n @paymentFlowCancelled=${this.paymentFlowCancelled}\n @paymentFlowError=${this.paymentFlowError}\n >\n <!--\n Why are these slots here?\n\n Due to the way Braintree, PayPal, and Recaptcha work, they cannot exist\n in the shadowDOM so must exist in the clearDOM and get passed\n in through a <slot>.\n\n Braintree / PayPal are working on a solution to this. See:\n - https://github.com/braintree/braintree-web-drop-in/issues/614#issuecomment-616796104\n - https://github.com/braintree/braintree-web-drop-in/issues/296#issuecomment-616749307\n - https://github.com/paypal/paypal-checkout-components/issues/353#issuecomment-595956216\n -->\n <div slot=\"braintree-hosted-fields\">\n <div id=\"braintree-error-message\"></div>\n <div class=\"braintree-row\">\n <badged-input .icon=${creditCardImg} ?required=${true} class=\"creditcard\">\n <div class=\"braintree-input\" id=\"braintree-creditcard\"></div>\n </badged-input>\n </div>\n <div class=\"braintree-row\">\n <badged-input .icon=${calendarImg} ?required=${true} class=\"expiration\">\n <div class=\"braintree-input\" id=\"braintree-expiration\"></div>\n </badged-input>\n <badged-input .icon=${lockImg} ?required=${true} class=\"cvv\">\n <div class=\"braintree-input\" id=\"braintree-cvv\"></div>\n </badged-input>\n </div>\n </div>\n\n <!--\n Form autocompletion does not work in the shadowDOM so\n we slot the contact form in from the lightDOM and pass\n in a reference to it in the <donation-form> tag above\n -->\n <div slot=\"contact-form\">\n <contact-form></contact-form>\n </div>\n\n <div slot=\"paypal-button\">\n <div id=\"paypal-button\"></div>\n </div>\n\n <slot name=\"recaptcha\" slot=\"recaptcha\"> </slot>\n </donation-form>\n </div>\n\n ${this.getStyles}\n `;\n }\n\n /** @inheritdoc */\n createRenderRoot(): this {\n // Render template without shadow DOM. Note that shadow DOM features like\n // encapsulated CSS and slots are unavailable.\n // We have to do this to accomodate the PayPal buttons and HostedFields,\n // which do not work in the shadow DOM\n return this;\n }\n\n private donationInfoChanged(): void {\n this.logEvent('DonationInfoChanged');\n }\n\n private trackViewedEvent(): void {\n this.logEvent('Viewed');\n }\n\n private paymentProviderSelected(e: CustomEvent): void {\n const paymentProvider = e.detail.paymentProvider as PaymentProvider;\n const previousPaymentProvider = e.detail.previousPaymentProvider;\n const providerNoSpaces = this.removeSpaces(paymentProvider);\n let eventName = `ProviderFirstSelected-${providerNoSpaces}`;\n let previousProviderInfo;\n if (previousPaymentProvider !== undefined) {\n eventName = `ProviderChangedTo-${providerNoSpaces}`;\n previousProviderInfo = `ProviderChangedFrom-${this.removeSpaces(previousPaymentProvider)}`;\n }\n this.logEvent(eventName, previousProviderInfo);\n }\n\n private paymentFlowConfirmed(e: CustomEvent): void {\n const selectedProvider = e.detail.paymentProvider as PaymentProvider;\n const providerNoSpaces = this.removeSpaces(selectedProvider);\n this.logEvent('PaymentFlowConfirmed', providerNoSpaces);\n }\n\n private paymentFlowStarted(e: CustomEvent): void {\n const selectedProvider = e.detail.paymentProvider as PaymentProvider;\n const providerNoSpaces = this.removeSpaces(selectedProvider);\n this.logEvent('PaymentFlowStarted', providerNoSpaces);\n }\n\n private paymentFlowCancelled(e: CustomEvent): void {\n const selectedProvider = e.detail.paymentProvider as PaymentProvider;\n const providerNoSpaces = this.removeSpaces(selectedProvider);\n this.logEvent('PaymentFlowCancelled', providerNoSpaces);\n }\n\n private paymentFlowError(e: CustomEvent): void {\n const selectedProvider = e.detail.paymentProvider as PaymentProvider;\n const providerNoSpaces = this.removeSpaces(selectedProvider);\n const error = e.detail.error;\n const detail = `${providerNoSpaces}-${error}`;\n this.logEvent('PaymentFlowError', detail);\n }\n\n private removeSpaces(original: string): string {\n return original.replace(/\\s+/g, '');\n }\n\n /**\n * Log an event\n *\n * @param {string} action Name of event\n * @param {string} label Event label, optional\n */\n private logEvent(action: string, label?: string): void {\n this.analyticsHandler?.send_event(this.analyticsCategory, action, label);\n }\n\n /**\n * Log an event in no sample bucket\n *\n * @param {string} action Name of event\n * @param {string} label Event label, optional\n */\n private logEventNoSampling(action: string, label?: string): void {\n this.analyticsHandler?.send_event_no_sampling(this.analyticsCategory, action, label);\n }\n\n /**\n * This is not the normal LitElement styles block.\n *\n * This element uses the clear DOM instead of the shadow DOM, it can't use\n * the shadowRoot's isolated styling. This is a bit of a workaround to keep all of\n * the styling local by writing out our own <style> tag and just be careful about\n * the selectors since they will leak outside of this component.\n *\n * @readonly\n * @private\n * @type {TemplateResult}\n * @memberof IADonationFormController\n */\n private get getStyles(): TemplateResult {\n return html`\n <style>\n .donation-form-controller-container {\n color: var(--donateFormTextColor, #333);\n background-color: var(--donateFormBgColor, transparent);\n\n --formSectionContentBackgroundColor: var(--donateFormBgColor, transparent);\n\n --editFormBadgeBgColor: var(--donateFormBadgeBgColor, #333);\n --formSectionBadgeBackgroundColor: var(--donateFormBadgeBgColor, #333);\n\n --editFormBadgeFontColor: var(--donateFormBadgeTextColor, #fff);\n --formSectionBadgeFontColor: var(--donateFormBadgeTextColor, #fff);\n\n --paymentButtonFontColor: var(--donateFormPaymentOptionTextColor);\n --paymentButtonColor: var(--donateFormPaymentOptionBgColor);\n\n --paymentButtonSelectedColor: var(--donateFormSelectedOptionBgColor);\n --paymentButtonSelectedFontColor: var(--donateFormSelectedOptionTextColor);\n }\n .donation-form-controller-container donation-form:focus {\n outline: none;\n }\n\n .donation-form-controller-container #paypal-button {\n opacity: 0.001;\n width: 5rem;\n height: 3rem;\n overflow: hidden;\n }\n\n .donation-form-controller-container .braintree-row {\n display: flex;\n margin-top: -1px;\n }\n\n .donation-form-controller-container badged-input {\n width: 100%;\n }\n\n .donation-form-controller-container badged-input.cvv {\n margin-left: -1px;\n }\n\n .donation-form-controller-container .braintree-input {\n width: 100%;\n height: 100%;\n }\n\n .donation-form-controller-container #braintree-error-message {\n color: red;\n font-size: 1.4rem;\n margin-bottom: 0.6rem;\n }\n\n .donation-form-controller-container div[slot=\"braintree-hosted-fields\"] {\n background-color: white;\n }\n </style>\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"donation-form-controller.js","sourceRoot":"","sources":["../../src/donation-form-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, PropertyValues, TemplateResult } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\n\nimport currency from 'currency.js';\nimport {\n LazyLoaderService,\n LazyLoaderServiceInterface,\n} from '@internetarchive/lazy-loader-service';\nimport { ModalManagerInterface } from '@internetarchive/modal-manager';\n\nimport { DonationForm } from './donation-form';\nimport { PaymentClients, PaymentClientsInterface } from './braintree-manager/payment-clients';\nimport { BraintreeManager } from './braintree-manager/braintree-manager';\nimport {\n BraintreeEndpointManagerInterface,\n BraintreeManagerInterface,\n HostingEnvironment,\n} from './braintree-manager/braintree-interfaces';\nimport {\n PaymentFlowHandlers,\n PaymentFlowHandlersInterface,\n} from './payment-flow-handlers/payment-flow-handlers';\n\nimport { RecaptchaManager, RecaptchaManagerInterface } from './recaptcha-manager/recaptcha-manager';\nimport { HostedFieldConfiguration } from './braintree-manager/payment-providers/credit-card/hosted-field-configuration';\nimport {\n HostedFieldContainerInterface,\n HostedFieldContainer,\n} from './braintree-manager/payment-providers/credit-card/hosted-field-container';\n\nimport './form-elements/badged-input';\nimport { ContactForm } from './form-elements/contact-form/contact-form';\nimport './form-elements/contact-form/contact-form';\n\nimport creditCardImg from '@internetarchive/icon-credit-card';\nimport calendarImg from '@internetarchive/icon-calendar';\nimport lockImg from '@internetarchive/icon-lock';\nimport { DonationControllerEventLoggerInterface } from './@types/analytics-handler';\nimport { AnalyticsManagerInterface, AnalyticsEvent } from '@internetarchive/analytics-manager';\nimport {\n EditDonationAmountSelectionLayout,\n EditDonationFrequencySelectionMode,\n} from '@internetarchive/donation-form-edit-donation';\n\nimport {\n DonationPaymentInfo,\n PaymentProvider,\n DonationType,\n defaultDonationAmounts,\n defaultSelectedDonationInfo,\n} from '@internetarchive/donation-form-data-models';\nimport { UpsellModalCTAMode } from './modals/upsell-modal-content';\n\n/**\n * The DonationFormController orchestrates several of the interactions between\n * the various pieces of the donation form like modals, braintree, paypal, and recaptcha\n *\n * @export\n * @class RadioPlayerController\n * @extends {LitElement}\n */\n@customElement('donation-form-controller')\nexport class DonationFormController extends LitElement {\n @property({ type: String }) environment?: HostingEnvironment;\n\n @property({ type: String }) braintreeAuthToken?: string;\n\n @property({ type: String }) recaptchaSiteKey?: string;\n\n @property({ type: String }) venmoProfileId?: string;\n\n @property({ type: String }) googlePayMerchantId?: string;\n\n @property({ type: String }) analyticsCategory = 'DonationForm';\n\n @property({ type: Array }) amountOptions: number[] = defaultDonationAmounts;\n\n @property({ type: Object }) donationInfo: DonationPaymentInfo = defaultSelectedDonationInfo;\n\n @property({ type: String }) amountSelectionLayout: EditDonationAmountSelectionLayout =\n EditDonationAmountSelectionLayout.MultiLine;\n\n @property({ type: String }) frequencySelectionMode: EditDonationFrequencySelectionMode =\n EditDonationFrequencySelectionMode.Button;\n\n @property({ type: String }) referrer?: string;\n\n @property({ type: String }) loggedInUser?: string;\n\n @property({ type: String }) origin?: string;\n\n @property({ type: Object }) endpointManager?: BraintreeEndpointManagerInterface;\n\n @property({ type: Object }) analyticsHandler?: AnalyticsManagerInterface;\n\n @property({ type: Object }) modalManager?: ModalManagerInterface;\n\n @property({ type: Object }) recaptchaElement?: HTMLElement;\n\n @property({ type: Object }) braintreeManager?: BraintreeManagerInterface;\n\n @property({ type: Object }) recaptchaManager?: RecaptchaManagerInterface;\n\n @property({ type: Object }) paymentFlowHandlers?: PaymentFlowHandlersInterface;\n\n @property({ type: Object }) paymentClients?: PaymentClientsInterface;\n\n @property({ type: Object })\n lazyLoaderService: LazyLoaderServiceInterface = new LazyLoaderService();\n\n @query('donation-form') private donationForm!: DonationForm;\n\n @query('#braintree-creditcard') private braintreeNumberInput!: HTMLDivElement;\n\n @query('#braintree-cvv') private braintreeCVVInput!: HTMLDivElement;\n\n @query('#braintree-expiration') private braintreeExpirationDateInput!: HTMLDivElement;\n\n @query('#braintree-error-message') private braintreeErrorMessage!: HTMLDivElement;\n\n @query('contact-form') private contactForm?: ContactForm;\n\n /** @inheritdoc */\n updated(changedProperties: PropertyValues): void {\n if (changedProperties.has('referrer') && this.referrer) {\n this.braintreeManager?.setReferrer(this.referrer);\n this.logEventNoSampling('referrer', this.referrer);\n }\n\n if (changedProperties.has('loggedInUser') && this.loggedInUser) {\n this.braintreeManager?.setLoggedInUser(this.loggedInUser);\n }\n\n if (changedProperties.has('origin') && this.origin) {\n this.braintreeManager?.setOrigin(this.origin);\n this.logEventNoSampling('origin', this.origin);\n }\n\n if (\n changedProperties.has('paymentClients') ||\n changedProperties.has('braintreeAuthToken') ||\n changedProperties.has('endpointManager') ||\n changedProperties.has('environment')\n ) {\n this.setupBraintreeManager();\n this.setupRecaptchaManager();\n }\n\n if (changedProperties.has('recaptchaSiteKey')) {\n this.setupRecaptchaManager();\n }\n\n if (\n changedProperties.has('braintreeManager') ||\n changedProperties.has('recaptchaManager') ||\n changedProperties.has('modalManager') ||\n changedProperties.has('recaptchaElement')\n ) {\n this.setupPaymentFlowHandlers();\n }\n\n if (\n (changedProperties.has('environment') || changedProperties.has('lazyLoaderService')) &&\n this.environment\n ) {\n this.paymentClients = new PaymentClients(this.lazyLoaderService, this.environment);\n }\n }\n\n async showConfirmationStepDev(options: {\n donationType: DonationType;\n amount: number;\n currencyType: string;\n cancelDonationCB: Function;\n confirmDonationCB: Function;\n }): Promise<void> {\n this.donationForm.showConfirmationModalDev(options);\n }\n\n async showUpsellModalDev(options: {\n oneTimeAmount: number;\n ctaMode?: UpsellModalCTAMode;\n yesSelected?: (amount: number) => void;\n noSelected?: () => void;\n amountChanged?: (amount: number) => void;\n userClosedModalCallback?: () => void;\n }): Promise<void> {\n this.donationForm.showUpsellModalDev(options);\n }\n\n private setupBraintreeManager(): void {\n if (\n this.braintreeManager === undefined &&\n this.braintreeAuthToken &&\n this.endpointManager &&\n this.paymentClients &&\n this.environment\n ) {\n this.braintreeManager = new BraintreeManager({\n paymentClients: this.paymentClients,\n endpointManager: this.endpointManager,\n authorizationToken: this.braintreeAuthToken,\n venmoProfileId: this.venmoProfileId,\n googlePayMerchantId: this.googlePayMerchantId,\n hostedFieldConfig: this.hostedFieldConfig,\n hostingEnvironment: this.environment,\n referrer: this.referrer,\n loggedInUser: this.loggedInUser,\n origin: this.origin,\n });\n\n this.braintreeManager.on('paymentProvidersHostedFieldsRetry', (retryNumber: number) => {\n const event = new CustomEvent('paymentProvidersHostedFieldsRetry', {\n detail: { retryNumber },\n });\n this.dispatchEvent(event);\n });\n\n this.braintreeManager.on('paymentProvidersHostedFieldsFailed', (error: unknown) => {\n const event = new CustomEvent('paymentProvidersHostedFieldsFailed', {\n detail: { error },\n });\n this.dispatchEvent(event);\n });\n }\n }\n\n private recaptchaManagerSetup = false;\n\n private async setupRecaptchaManager(): Promise<void> {\n if (!this.recaptchaSiteKey || !this.paymentClients || this.recaptchaManagerSetup) {\n return;\n }\n this.recaptchaManagerSetup = true;\n const grecaptchaLibrary = await this.paymentClients.recaptchaLibrary.get();\n this.recaptchaManager = new RecaptchaManager({\n grecaptchaLibrary: grecaptchaLibrary,\n siteKey: this.recaptchaSiteKey,\n });\n }\n\n /** @inheritdoc */\n firstUpdated(): void {\n this.configureFromQueryParams();\n this.trackViewedEvent();\n }\n\n private configureFromQueryParams(): void {\n const urlParams = new URLSearchParams(window.location.search);\n\n let amountOptions = this.amountOptions;\n const amountOptionsParam = urlParams.get('dollarAmounts');\n if (amountOptionsParam) {\n const stripBrackets = amountOptionsParam.slice(1, -1);\n const splitValues = stripBrackets.split(',');\n const numberArray = splitValues\n .map(value => parseFloat(value))\n .filter(value => !isNaN(value));\n amountOptions = numberArray;\n }\n\n let coverFees = this.donationInfo.coverFees;\n const coverFeesParam = urlParams.get('coverFees');\n if (coverFeesParam) {\n coverFees = coverFeesParam === 'true';\n }\n\n let frequency = this.donationInfo.donationType;\n const frequencyParam = urlParams.get('contrib_type');\n if (frequencyParam === 'monthly') {\n frequency = DonationType.Monthly;\n }\n\n let amount = this.donationInfo.amount;\n const amountParam = urlParams.get('amt');\n if (amountParam) {\n const parsedAmount = currency(amountParam).value;\n if (parsedAmount > 0) {\n amount = parsedAmount;\n }\n }\n\n const amountLayoutParam = urlParams.get('amountLayout');\n if (amountLayoutParam) {\n const amountLayout = amountLayoutParam as EditDonationAmountSelectionLayout;\n if (Object.values(EditDonationAmountSelectionLayout).includes(amountLayout)) {\n this.amountSelectionLayout = amountLayout;\n }\n }\n\n const frequencyModeParam = urlParams.get('frequencyMode');\n if (frequencyModeParam) {\n const frequencyMode = frequencyModeParam as EditDonationFrequencySelectionMode;\n if (Object.values(EditDonationFrequencySelectionMode).includes(frequencyMode)) {\n this.frequencySelectionMode = frequencyMode;\n }\n }\n\n const donationInfo = new DonationPaymentInfo({\n donationType: frequency,\n amount: amount,\n coverFees: coverFees,\n });\n\n this.amountOptions = amountOptions;\n this.donationInfo = donationInfo;\n }\n\n private setupPaymentFlowHandlers(): void {\n // only set up once\n if (this.paymentFlowHandlers) {\n return;\n }\n\n // verify we have all of the dependencies\n if (\n !this.braintreeManager ||\n !this.recaptchaManager ||\n !this.modalManager ||\n !this.recaptchaElement\n ) {\n return;\n }\n\n this.paymentFlowHandlers = new PaymentFlowHandlers({\n braintreeManager: this.braintreeManager,\n modalManager: this.modalManager,\n recaptchaManager: this.recaptchaManager,\n resources: {\n analytics: {\n logEvent: this.logEvent.bind(this),\n logEventNoSampling: this.logEventNoSampling.bind(this),\n } as DonationControllerEventLoggerInterface,\n }\n });\n\n this.donationForm.braintreeManager = this.braintreeManager;\n this.donationForm.paymentFlowHandlers = this.paymentFlowHandlers;\n\n this.braintreeManager.startup();\n this.paymentFlowHandlers?.startup();\n this.recaptchaManager.setup(this.recaptchaElement, 1, 'light', 'image');\n }\n\n private get hostedFieldConfig(): HostedFieldConfiguration {\n const hostedFieldStyle: Record<string, Record<string, string>> = {\n input: {\n 'font-size': '16px',\n 'font-family': '\"Helvetica Neue\", Helvetica, Arial, sans-serif',\n 'font-weight': '700',\n color: '#333',\n },\n ':focus': {\n color: '#333',\n },\n '.valid': {},\n '.invalid': {\n color: '#b00b00',\n },\n };\n\n const hostedFieldFieldOptions: braintree.HostedFieldFieldOptions = {\n number: {\n selector: '#braintree-creditcard',\n placeholder: 'Card number',\n },\n cvv: {\n selector: '#braintree-cvv',\n placeholder: 'CVC',\n },\n expirationDate: {\n selector: '#braintree-expiration',\n placeholder: 'MM / YY',\n },\n };\n\n const hostedFieldContainer: HostedFieldContainerInterface = new HostedFieldContainer({\n number: this.braintreeNumberInput,\n cvv: this.braintreeCVVInput,\n expirationDate: this.braintreeExpirationDateInput,\n errorContainer: this.braintreeErrorMessage,\n });\n\n const config: HostedFieldConfiguration = new HostedFieldConfiguration({\n hostedFieldStyle,\n hostedFieldFieldOptions,\n hostedFieldContainer,\n });\n\n return config;\n }\n\n /** @inheritdoc */\n render(): TemplateResult {\n return html`\n <div class=\"donation-form-controller-container\">\n <donation-form\n .environment=${this.environment}\n .braintreeManager=${this.braintreeManager}\n .contactForm=${this.contactForm}\n .amountOptions=${this.amountOptions}\n .donationInfo=${this.donationInfo}\n .amountSelectionLayout=${this.amountSelectionLayout}\n .frequencySelectionMode=${this.frequencySelectionMode}\n @donationInfoChanged=${this.donationInfoChanged}\n @paymentProviderSelected=${this.paymentProviderSelected}\n @paymentFlowStarted=${this.paymentFlowStarted}\n @paymentFlowConfirmed=${this.paymentFlowConfirmed}\n @paymentFlowCancelled=${this.paymentFlowCancelled}\n @paymentFlowError=${this.paymentFlowError}\n >\n <!--\n Why are these slots here?\n\n Due to the way Braintree, PayPal, and Recaptcha work, they cannot exist\n in the shadowDOM so must exist in the clearDOM and get passed\n in through a <slot>.\n\n Braintree / PayPal are working on a solution to this. See:\n - https://github.com/braintree/braintree-web-drop-in/issues/614#issuecomment-616796104\n - https://github.com/braintree/braintree-web-drop-in/issues/296#issuecomment-616749307\n - https://github.com/paypal/paypal-checkout-components/issues/353#issuecomment-595956216\n -->\n <div slot=\"braintree-hosted-fields\">\n <div id=\"braintree-error-message\"></div>\n <div class=\"braintree-row\">\n <badged-input .icon=${creditCardImg} ?required=${true} class=\"creditcard\">\n <div class=\"braintree-input\" id=\"braintree-creditcard\"></div>\n </badged-input>\n </div>\n <div class=\"braintree-row\">\n <badged-input .icon=${calendarImg} ?required=${true} class=\"expiration\">\n <div class=\"braintree-input\" id=\"braintree-expiration\"></div>\n </badged-input>\n <badged-input .icon=${lockImg} ?required=${true} class=\"cvv\">\n <div class=\"braintree-input\" id=\"braintree-cvv\"></div>\n </badged-input>\n </div>\n </div>\n\n <!--\n Form autocompletion does not work in the shadowDOM so\n we slot the contact form in from the lightDOM and pass\n in a reference to it in the <donation-form> tag above\n -->\n <div slot=\"contact-form\">\n <contact-form></contact-form>\n </div>\n\n <div slot=\"paypal-button\">\n <div id=\"paypal-button\"></div>\n </div>\n\n <slot name=\"recaptcha\" slot=\"recaptcha\"> </slot>\n </donation-form>\n </div>\n\n ${this.getStyles}\n `;\n }\n\n /** @inheritdoc */\n createRenderRoot(): this {\n // Render template without shadow DOM. Note that shadow DOM features like\n // encapsulated CSS and slots are unavailable.\n // We have to do this to accomodate the PayPal buttons and HostedFields,\n // which do not work in the shadow DOM\n return this;\n }\n\n private donationInfoChanged(): void {\n this.logEvent('DonationInfoChanged');\n }\n\n private trackViewedEvent(): void {\n this.logEvent('Viewed');\n }\n\n private paymentProviderSelected(e: CustomEvent): void {\n const paymentProvider = e.detail.paymentProvider as PaymentProvider;\n const previousPaymentProvider = e.detail.previousPaymentProvider;\n const providerNoSpaces = this.removeSpaces(paymentProvider);\n let eventName = `ProviderFirstSelected-${providerNoSpaces}`;\n let previousProviderInfo;\n if (previousPaymentProvider !== undefined) {\n eventName = `ProviderChangedTo-${providerNoSpaces}`;\n previousProviderInfo = `ProviderChangedFrom-${this.removeSpaces(previousPaymentProvider)}`;\n }\n this.logEvent(eventName, previousProviderInfo);\n }\n\n private paymentFlowConfirmed(e: CustomEvent): void {\n const selectedProvider = e.detail.paymentProvider as PaymentProvider;\n const providerNoSpaces = this.removeSpaces(selectedProvider);\n this.logEvent('PaymentFlowConfirmed', providerNoSpaces);\n }\n\n private paymentFlowStarted(e: CustomEvent): void {\n const selectedProvider = e.detail.paymentProvider as PaymentProvider;\n const providerNoSpaces = this.removeSpaces(selectedProvider);\n this.logEvent('PaymentFlowStarted', providerNoSpaces);\n }\n\n private paymentFlowCancelled(e: CustomEvent): void {\n const selectedProvider = e.detail.paymentProvider as PaymentProvider;\n const providerNoSpaces = this.removeSpaces(selectedProvider);\n this.logEvent('PaymentFlowCancelled', providerNoSpaces);\n }\n\n private paymentFlowError(e: CustomEvent): void {\n const selectedProvider = e.detail.paymentProvider as PaymentProvider;\n const providerNoSpaces = this.removeSpaces(selectedProvider);\n const error = e.detail.error;\n const detail = `${providerNoSpaces}-${error}`;\n this.logEvent('PaymentFlowError', detail);\n }\n\n private removeSpaces(original: string): string {\n return original.replace(/\\s+/g, '');\n }\n\n /**\n * Log an event\n *\n * @param {string} action Name of event\n * @param {string} label Event label, optional\n */\n private logEvent(action: string, label?: string): void {\n const analyticEvent = { action, label, category: this.analyticsCategory } as AnalyticsEvent;\n this.analyticsHandler?.sendEvent(analyticEvent);\n }\n\n /**\n * Log an event in no sample bucket\n *\n * @param {string} action Name of event\n * @param {string} label Event label, optional\n */\n private logEventNoSampling(action: string, label?: string): void {\n const analyticEvent = { action, label, category: this.analyticsCategory } as AnalyticsEvent;\n this.analyticsHandler?.sendEventNoSampling(analyticEvent);\n }\n\n /**\n * This is not the normal LitElement styles block.\n *\n * This element uses the clear DOM instead of the shadow DOM, it can't use\n * the shadowRoot's isolated styling. This is a bit of a workaround to keep all of\n * the styling local by writing out our own <style> tag and just be careful about\n * the selectors since they will leak outside of this component.\n *\n * @readonly\n * @private\n * @type {TemplateResult}\n * @memberof IADonationFormController\n */\n private get getStyles(): TemplateResult {\n return html`\n <style>\n .donation-form-controller-container {\n color: var(--donateFormTextColor, #333);\n background-color: var(--donateFormBgColor, transparent);\n\n --formSectionContentBackgroundColor: var(--donateFormBgColor, transparent);\n\n --editFormBadgeBgColor: var(--donateFormBadgeBgColor, #333);\n --formSectionBadgeBackgroundColor: var(--donateFormBadgeBgColor, #333);\n\n --editFormBadgeFontColor: var(--donateFormBadgeTextColor, #fff);\n --formSectionBadgeFontColor: var(--donateFormBadgeTextColor, #fff);\n\n --paymentButtonFontColor: var(--donateFormPaymentOptionTextColor);\n --paymentButtonColor: var(--donateFormPaymentOptionBgColor);\n\n --paymentButtonSelectedColor: var(--donateFormSelectedOptionBgColor);\n --paymentButtonSelectedFontColor: var(--donateFormSelectedOptionTextColor);\n }\n .donation-form-controller-container donation-form:focus {\n outline: none;\n }\n\n .donation-form-controller-container #paypal-button {\n opacity: 0.001;\n width: 5rem;\n height: 3rem;\n overflow: hidden;\n }\n\n .donation-form-controller-container .braintree-row {\n display: flex;\n margin-top: -1px;\n }\n\n .donation-form-controller-container badged-input {\n width: 100%;\n }\n\n .donation-form-controller-container badged-input.cvv {\n margin-left: -1px;\n }\n\n .donation-form-controller-container .braintree-input {\n width: 100%;\n height: 100%;\n }\n\n .donation-form-controller-container #braintree-error-message {\n color: red;\n font-size: 1.4rem;\n margin-bottom: 0.6rem;\n }\n\n .donation-form-controller-container div[slot=\"braintree-hosted-fields\"] {\n background-color: white;\n }\n </style>\n `;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"donation-flow-modal-manager.js","sourceRoot":"","sources":["../../../src/payment-flow-handlers/donation-flow-modal-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { html } from 'lit';\nimport { ModalConfig, ModalManagerInterface } from '@internetarchive/modal-manager';\nimport { UpsellModalCTAMode } from '../modals/upsell-modal-content';\nimport '../modals/confirm-donation-modal-content';\nimport { BraintreeManagerInterface } from '../braintree-manager/braintree-interfaces';\nimport {\n SuccessResponse,\n ErrorResponse,\n DonationPaymentInfo,\n DonationType,\n PaymentProvider,\n BillingInfo,\n CustomerInfo,\n DonationResponse,\n} from '@internetarchive/donation-form-data-models';\nimport '../modals/error-modal-content';\nimport { AnalyticsHandlerInterface, DonationControllerEventLoggerInterface } from '../@types/analytics-handler';\n\nenum ModalHeaderColor {\n Blue = '#497fbf',\n Green = '#55A183',\n Red = '#691916',\n}\n\n/**\n * The DonationFlowModalManager is responsible for most of the high-level modal flows.\n *\n * Each of the payment providers has slightly different interactions, ie the PayPal button,\n * ApplePay popup, Venmo launching the app, etc. The modal flow is the same for all of them\n * so this class gets called by the individual payment flow handlers to take the user\n * through the modal flow.\n *\n * @export\n * @interface DonationFlowModalManagerInterface\n */\nexport interface DonationFlowModalManagerInterface {\n showConfirmationStepModal(options: {\n amount: number;\n donationType: DonationType;\n currencyType: string;\n confirmDonationCB: Function;\n cancelDonationCB: Function;\n }): Promise<void>;\n /**\n * Close the modal\n *\n * @memberof DonationFlowModalManagerInterface\n */\n closeModal(): void;\n\n /**\n * Show the processing modal\n *\n * @memberof DonationFlowModalManagerInterface\n */\n showProcessingModal(): void;\n\n /**\n * Show the Thank You modal\n *\n * @memberof DonationFlowModalManagerInterface\n */\n showThankYouModal(options: {\n successResponse: SuccessResponse;\n upsellSuccessResponse?: SuccessResponse;\n }): void;\n\n /**\n * Show the Error modal\n *\n * @param {{\n * userClosedModalCallback?: () => void;\n * }} [options]\n * @memberof DonationFlowModalManagerInterface\n */\n showErrorModal(options: { message: string; userClosedModalCallback?: () => void }): void;\n\n /**\n * Show the upsell modal\n *\n * @param {{\n * ctaMode?: UpsellModalCTAMode;\n * yesSelected?: (amount: number) => void;\n * noSelected?: () => void;\n * amountChanged?: (amount: number) => void;\n * userClosedModalCallback?: () => void;\n * }} [options]\n * @returns {Promise<void>}\n * @memberof DonationFlowModalManagerInterface\n */\n showUpsellModal(options: {\n oneTimeAmount: number;\n ctaMode?: UpsellModalCTAMode;\n yesSelected?: (amount: number) => void;\n noSelected?: () => void;\n amountChanged?: (amount: number) => void;\n userClosedModalCallback?: () => void;\n }): Promise<void>;\n\n /**\n * Start the donation submission flow. This kicks off the \"main\" modal flow once the\n * user authorizes the donation through their payment provider, which provides\n * us the with the nonce used to complete the donation.\n *\n * @param {{\n * nonce: string;\n * paymentProvider: PaymentProvider;\n * donationInfo: DonationPaymentInfo;\n * billingInfo: BillingInfo;\n * customerInfo: CustomerInfo;\n * upsellOnetimeTransactionId?: string;\n * customerId?: string;\n * recaptchaToken?: string;\n * bin?: string; // first 6 digits of CC\n * binName?: string; // credit card bank name\n * }} options\n * @returns {(Promise<DonationResponse | undefined>)}\n * @memberof DonationFlowModalManagerInterface\n */\n startDonationSubmissionFlow(options: {\n nonce: string;\n paymentProvider: PaymentProvider;\n donationInfo: DonationPaymentInfo;\n billingInfo: BillingInfo;\n customerInfo: CustomerInfo;\n upsellOnetimeTransactionId?: string;\n customerId?: string;\n recaptchaToken?: string;\n bin?: string; // first 6 digits of CC\n binName?: string; // credit card bank name\n }): Promise<DonationResponse | undefined>;\n\n /**\n * Handle a successful donation response. This encapsulates the logic for the type of\n * donation that was made.\n * ie. If it was a one-time donation, show the upsell, if it was monthly do not.\n *\n * @param {DonationPaymentInfo} donationInfo\n * @param {SuccessResponse} response\n * @memberof DonationFlowModalManagerInterface\n */\n handleSuccessfulDonationResponse(\n donationInfo: DonationPaymentInfo,\n response: SuccessResponse,\n ): void;\n}\n\nexport class DonationFlowModalManager implements DonationFlowModalManagerInterface {\n private braintreeManager: BraintreeManagerInterface;\n\n private modalManager: ModalManagerInterface;\n\n private analytics: DonationControllerEventLoggerInterface;\n\n constructor(options: {\n braintreeManager: BraintreeManagerInterface;\n modalManager: ModalManagerInterface;\n analytics: DonationControllerEventLoggerInterface;\n }) {\n this.modalManager = options.modalManager;\n this.braintreeManager = options.braintreeManager;\n this.analytics = options.analytics;\n }\n\n /** @inheritdoc */\n closeModal(): void {\n this.modalManager.closeModal();\n }\n\n /** @inheritdoc */\n showProcessingModal(): void {\n const modalConfig = new ModalConfig({\n headerColor: ModalHeaderColor.Blue,\n showProcessingIndicator: true,\n closeOnBackdropClick: false,\n showCloseButton: false,\n processingImageMode: 'processing',\n title: html`\n Processing...\n `,\n });\n this.modalManager.showModal({ config: modalConfig });\n }\n\n /** @inheritdoc */\n showThankYouModal(options: {\n successResponse: SuccessResponse;\n upsellSuccessResponse?: SuccessResponse;\n }): void {\n const modalConfig = new ModalConfig({\n showProcessingIndicator: true,\n processingImageMode: 'complete',\n headerColor: ModalHeaderColor.Green,\n title: html`\n Thank You!\n `,\n });\n this.modalManager.showModal({\n config: modalConfig,\n });\n\n // post analytic\n const selectedPayment = options.successResponse.paymentProvider.replace(/\\s+/g, '');\n let action = `Donated-${selectedPayment}`;\n if (options.upsellSuccessResponse) {\n action += `-upsell`;\n }\n const label = options.successResponse.donationType;\n this.analytics.logEventNoSampling(action, label);\n\n // post donation\n this.braintreeManager.donationSuccessful(options);\n }\n\n /** @inheritdoc */\n showErrorModal(options: { message: string; userClosedModalCallback?: () => void }): void {\n const modalConfig = new ModalConfig({\n headerColor: ModalHeaderColor.Red,\n title: html`\n Processing error\n `,\n headline: html`\n There's been a problem completing your donation.\n `,\n message: html`\n ${options?.message}\n `,\n });\n\n this.modalManager.showModal({\n config: modalConfig,\n userClosedModalCallback: options?.userClosedModalCallback,\n customModalContent: html`\n <donation-form-error-modal-content></donation-form-error-modal-content>\n `,\n });\n }\n\n showConfirmationStepModal(options: {\n amount: number;\n donationType: DonationType;\n currencyType: string;\n confirmDonationCB: Function;\n cancelDonationCB: Function;\n }): Promise<void> {\n const confirmDonation = (): void => {\n options?.confirmDonationCB();\n };\n const cancelDonation = (): void => {\n options?.cancelDonationCB();\n };\n const modalTitle = options.donationType === DonationType.Upsell\n ? 'Confirm monthly donation'\n : 'Complete donation';\n\n const modalConfig = new ModalConfig({\n closeOnBackdropClick: false,\n headerColor: ModalHeaderColor.Green,\n title: html`${modalTitle}`,\n message: html`\n <confirm-donation-modal\n .amount=\"${options.amount}\"\n .currencyType=\"${options.currencyType}\"\n .donationType=\"${options.donationType}\"\n .confirmDonation=${confirmDonation}\n .cancelDonation=${cancelDonation}\n ></confirm-donation-modal>\n `,\n });\n return this.modalManager.showModal({\n config: modalConfig,\n userClosedModalCallback: cancelDonation\n });\n }\n\n /** @inheritdoc */\n showUpsellModal(options: {\n oneTimeAmount: number;\n yesSelected?: (amount: number) => void;\n noSelected?: () => void;\n amountChanged?: (amount: number) => void;\n userClosedModalCallback?: () => void;\n ctaMode?: UpsellModalCTAMode;\n }): Promise<void> {\n const modalConfig = new ModalConfig({\n headerColor: ModalHeaderColor.Green,\n title: html`\n Donation received\n `,\n processingImageMode: 'complete',\n showProcessingIndicator: true,\n });\n\n const upsellAmount = DonationFlowModalManager.getDefaultUpsellAmount(options.oneTimeAmount);\n if (options.amountChanged) {\n options.amountChanged(upsellAmount);\n }\n\n const modalContent = html`\n <upsell-modal-content\n .amount=${upsellAmount}\n .yesButtonMode=${options?.ctaMode ?? UpsellModalCTAMode.YesButton}\n @yesSelected=${(e: CustomEvent): void =>\n options?.yesSelected ? options.yesSelected(e.detail.amount) : undefined}\n @noThanksSelected=${options?.noSelected}\n @amountChanged=${(e: CustomEvent): void =>\n options?.amountChanged ? options.amountChanged(e.detail.amount) : undefined}\n >\n <slot name=\"paypal-upsell-button\"></slot>\n </upsell-modal-content>\n `;\n return this.modalManager.showModal({\n config: modalConfig,\n customModalContent: modalContent,\n userClosedModalCallback: options?.userClosedModalCallback,\n });\n }\n\n /** @inheritdoc */\n async startDonationSubmissionFlow(options: {\n nonce: string;\n paymentProvider: PaymentProvider;\n donationInfo: DonationPaymentInfo;\n billingInfo: BillingInfo;\n customerInfo: CustomerInfo;\n upsellOnetimeTransactionId?: string;\n customerId?: string;\n recaptchaToken?: string;\n bin?: string; // first 6 digits of CC\n binName?: string; // credit card bank name\n }): Promise<DonationResponse | undefined> {\n this.showProcessingModal();\n\n try {\n const response = await this.braintreeManager.submitDonation(options);\n\n if (response.success) {\n this.handleSuccessfulDonationResponse(\n options.donationInfo,\n response.value as SuccessResponse,\n );\n return response;\n } else {\n const error = response.value as ErrorResponse;\n this.showErrorModal({\n message: error.message,\n });\n return response;\n }\n } catch (error) {\n this.showErrorModal({\n message: `${error}`,\n });\n console.error('error getting a response', error);\n return undefined;\n }\n }\n\n private async upsellModalYesSelected(\n oneTimeDonationResponse: SuccessResponse,\n amount: number,\n ): Promise<DonationResponse | undefined> {\n this.showProcessingModal();\n\n try {\n const response = await this.braintreeManager.submitUpsellDonation({\n oneTimeDonationResponse: oneTimeDonationResponse,\n amount: amount,\n });\n\n if (response.success) {\n this.completeUpsell({\n successResponse: oneTimeDonationResponse,\n upsellSuccessResponse: response.value as SuccessResponse,\n });\n } else {\n const error = response.value as ErrorResponse;\n this.showErrorModal({\n message: error.message,\n });\n }\n\n return response;\n } catch (error) {\n this.showErrorModal({\n message: `${error}`,\n });\n console.error('error getting a response', error);\n return undefined;\n }\n }\n\n private completeUpsell(options: {\n successResponse: SuccessResponse;\n upsellSuccessResponse?: SuccessResponse;\n }): void {\n this.showThankYouModal(options);\n\n // post analytic\n const selectedPayment = options.successResponse.paymentProvider.replace(/\\s+/g, '');\n const action = `Donated-${selectedPayment}-upsell`;\n const label = options.successResponse.donationType;\n this.analytics.logEventNoSampling(action, label);\n\n this.braintreeManager.donationSuccessful(options);\n }\n\n static getDefaultUpsellAmount(oneTimeAmount: number): number {\n let amount = 5;\n\n if (oneTimeAmount <= 10) amount = 5;\n else if (oneTimeAmount > 10 && oneTimeAmount <= 25) amount = 10;\n else if (oneTimeAmount > 25 && oneTimeAmount <= 100) amount = 25;\n else if (oneTimeAmount > 100) amount = 50;\n\n return amount;\n }\n\n /** @inheritdoc */\n handleSuccessfulDonationResponse(\n donationInfo: DonationPaymentInfo,\n response: SuccessResponse,\n ): void {\n switch (donationInfo.donationType) {\n case DonationType.OneTime:\n this.showUpsellModal({\n oneTimeAmount: response.amount,\n yesSelected: (amount: number) => {\n this.upsellModalYesSelected(response, amount);\n },\n noSelected: () => {\n this.showThankYouModal({ successResponse: response });\n },\n userClosedModalCallback: () => {\n this.showThankYouModal({ successResponse: response });\n },\n });\n break;\n case DonationType.Monthly:\n this.showThankYouModal({ successResponse: response });\n break;\n // This case will never be reached, it is only here for completeness.\n // The upsell case gets handled in `modalYesSelected()` below\n case DonationType.Upsell:\n break;\n default:\n break;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"donation-flow-modal-manager.js","sourceRoot":"","sources":["../../../src/payment-flow-handlers/donation-flow-modal-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { html } from 'lit';\nimport { ModalConfig, ModalManagerInterface } from '@internetarchive/modal-manager';\nimport { UpsellModalCTAMode } from '../modals/upsell-modal-content';\nimport '../modals/confirm-donation-modal-content';\nimport { BraintreeManagerInterface } from '../braintree-manager/braintree-interfaces';\nimport {\n SuccessResponse,\n ErrorResponse,\n DonationPaymentInfo,\n DonationType,\n PaymentProvider,\n BillingInfo,\n CustomerInfo,\n DonationResponse,\n} from '@internetarchive/donation-form-data-models';\nimport '../modals/error-modal-content';\nimport { DonationControllerEventLoggerInterface } from '../@types/analytics-handler';\n\nenum ModalHeaderColor {\n Blue = '#497fbf',\n Green = '#55A183',\n Red = '#691916',\n}\n\n/**\n * The DonationFlowModalManager is responsible for most of the high-level modal flows.\n *\n * Each of the payment providers has slightly different interactions, ie the PayPal button,\n * ApplePay popup, Venmo launching the app, etc. The modal flow is the same for all of them\n * so this class gets called by the individual payment flow handlers to take the user\n * through the modal flow.\n *\n * @export\n * @interface DonationFlowModalManagerInterface\n */\nexport interface DonationFlowModalManagerInterface {\n showConfirmationStepModal(options: {\n amount: number;\n donationType: DonationType;\n currencyType: string;\n confirmDonationCB: Function;\n cancelDonationCB: Function;\n }): Promise<void>;\n /**\n * Close the modal\n *\n * @memberof DonationFlowModalManagerInterface\n */\n closeModal(): void;\n\n /**\n * Show the processing modal\n *\n * @memberof DonationFlowModalManagerInterface\n */\n showProcessingModal(): void;\n\n /**\n * Show the Thank You modal\n *\n * @memberof DonationFlowModalManagerInterface\n */\n showThankYouModal(options: {\n successResponse: SuccessResponse;\n upsellSuccessResponse?: SuccessResponse;\n }): void;\n\n /**\n * Show the Error modal\n *\n * @param {{\n * userClosedModalCallback?: () => void;\n * }} [options]\n * @memberof DonationFlowModalManagerInterface\n */\n showErrorModal(options: { message: string; userClosedModalCallback?: () => void }): void;\n\n /**\n * Show the upsell modal\n *\n * @param {{\n * ctaMode?: UpsellModalCTAMode;\n * yesSelected?: (amount: number) => void;\n * noSelected?: () => void;\n * amountChanged?: (amount: number) => void;\n * userClosedModalCallback?: () => void;\n * }} [options]\n * @returns {Promise<void>}\n * @memberof DonationFlowModalManagerInterface\n */\n showUpsellModal(options: {\n oneTimeAmount: number;\n ctaMode?: UpsellModalCTAMode;\n yesSelected?: (amount: number) => void;\n noSelected?: () => void;\n amountChanged?: (amount: number) => void;\n userClosedModalCallback?: () => void;\n }): Promise<void>;\n\n /**\n * Start the donation submission flow. This kicks off the \"main\" modal flow once the\n * user authorizes the donation through their payment provider, which provides\n * us the with the nonce used to complete the donation.\n *\n * @param {{\n * nonce: string;\n * paymentProvider: PaymentProvider;\n * donationInfo: DonationPaymentInfo;\n * billingInfo: BillingInfo;\n * customerInfo: CustomerInfo;\n * upsellOnetimeTransactionId?: string;\n * customerId?: string;\n * recaptchaToken?: string;\n * bin?: string; // first 6 digits of CC\n * binName?: string; // credit card bank name\n * }} options\n * @returns {(Promise<DonationResponse | undefined>)}\n * @memberof DonationFlowModalManagerInterface\n */\n startDonationSubmissionFlow(options: {\n nonce: string;\n paymentProvider: PaymentProvider;\n donationInfo: DonationPaymentInfo;\n billingInfo: BillingInfo;\n customerInfo: CustomerInfo;\n upsellOnetimeTransactionId?: string;\n customerId?: string;\n recaptchaToken?: string;\n bin?: string; // first 6 digits of CC\n binName?: string; // credit card bank name\n }): Promise<DonationResponse | undefined>;\n\n /**\n * Handle a successful donation response. This encapsulates the logic for the type of\n * donation that was made.\n * ie. If it was a one-time donation, show the upsell, if it was monthly do not.\n *\n * @param {DonationPaymentInfo} donationInfo\n * @param {SuccessResponse} response\n * @memberof DonationFlowModalManagerInterface\n */\n handleSuccessfulDonationResponse(\n donationInfo: DonationPaymentInfo,\n response: SuccessResponse,\n ): void;\n}\n\nexport class DonationFlowModalManager implements DonationFlowModalManagerInterface {\n private braintreeManager: BraintreeManagerInterface;\n\n private modalManager: ModalManagerInterface;\n\n private analytics: DonationControllerEventLoggerInterface;\n\n constructor(options: {\n braintreeManager: BraintreeManagerInterface;\n modalManager: ModalManagerInterface;\n analytics: DonationControllerEventLoggerInterface;\n }) {\n this.modalManager = options.modalManager;\n this.braintreeManager = options.braintreeManager;\n this.analytics = options.analytics;\n }\n\n /** @inheritdoc */\n closeModal(): void {\n this.modalManager.closeModal();\n }\n\n /** @inheritdoc */\n showProcessingModal(): void {\n const modalConfig = new ModalConfig({\n headerColor: ModalHeaderColor.Blue,\n showProcessingIndicator: true,\n closeOnBackdropClick: false,\n showCloseButton: false,\n processingImageMode: 'processing',\n title: html`\n Processing...\n `,\n });\n this.modalManager.showModal({ config: modalConfig });\n }\n\n /** @inheritdoc */\n showThankYouModal(options: {\n successResponse: SuccessResponse;\n upsellSuccessResponse?: SuccessResponse;\n }): void {\n const modalConfig = new ModalConfig({\n showProcessingIndicator: true,\n processingImageMode: 'complete',\n headerColor: ModalHeaderColor.Green,\n title: html`\n Thank You!\n `,\n });\n this.modalManager.showModal({\n config: modalConfig,\n });\n\n // post analytic\n const selectedPayment = options.successResponse.paymentProvider.replace(/\\s+/g, '');\n let action = `Donated-${selectedPayment}`;\n if (options.upsellSuccessResponse) {\n action += `-upsell`;\n }\n const label = options.successResponse.donationType;\n this.analytics.logEventNoSampling(action, label);\n\n // post donation\n this.braintreeManager.donationSuccessful(options);\n }\n\n /** @inheritdoc */\n showErrorModal(options: { message: string; userClosedModalCallback?: () => void }): void {\n const modalConfig = new ModalConfig({\n headerColor: ModalHeaderColor.Red,\n title: html`\n Processing error\n `,\n headline: html`\n There's been a problem completing your donation.\n `,\n message: html`\n ${options?.message}\n `,\n });\n\n this.modalManager.showModal({\n config: modalConfig,\n userClosedModalCallback: options?.userClosedModalCallback,\n customModalContent: html`\n <donation-form-error-modal-content></donation-form-error-modal-content>\n `,\n });\n }\n\n showConfirmationStepModal(options: {\n amount: number;\n donationType: DonationType;\n currencyType: string;\n confirmDonationCB: Function;\n cancelDonationCB: Function;\n }): Promise<void> {\n const confirmDonation = (): void => {\n options?.confirmDonationCB();\n };\n const cancelDonation = (): void => {\n options?.cancelDonationCB();\n };\n const modalTitle = options.donationType === DonationType.Upsell\n ? 'Confirm monthly donation'\n : 'Complete donation';\n\n const modalConfig = new ModalConfig({\n closeOnBackdropClick: false,\n headerColor: ModalHeaderColor.Green,\n title: html`${modalTitle}`,\n message: html`\n <confirm-donation-modal\n .amount=\"${options.amount}\"\n .currencyType=\"${options.currencyType}\"\n .donationType=\"${options.donationType}\"\n .confirmDonation=${confirmDonation}\n .cancelDonation=${cancelDonation}\n ></confirm-donation-modal>\n `,\n });\n return this.modalManager.showModal({\n config: modalConfig,\n userClosedModalCallback: cancelDonation\n });\n }\n\n /** @inheritdoc */\n showUpsellModal(options: {\n oneTimeAmount: number;\n yesSelected?: (amount: number) => void;\n noSelected?: () => void;\n amountChanged?: (amount: number) => void;\n userClosedModalCallback?: () => void;\n ctaMode?: UpsellModalCTAMode;\n }): Promise<void> {\n const modalConfig = new ModalConfig({\n headerColor: ModalHeaderColor.Green,\n title: html`\n Donation received\n `,\n processingImageMode: 'complete',\n showProcessingIndicator: true,\n });\n\n const upsellAmount = DonationFlowModalManager.getDefaultUpsellAmount(options.oneTimeAmount);\n if (options.amountChanged) {\n options.amountChanged(upsellAmount);\n }\n\n const modalContent = html`\n <upsell-modal-content\n .amount=${upsellAmount}\n .yesButtonMode=${options?.ctaMode ?? UpsellModalCTAMode.YesButton}\n @yesSelected=${(e: CustomEvent): void =>\n options?.yesSelected ? options.yesSelected(e.detail.amount) : undefined}\n @noThanksSelected=${options?.noSelected}\n @amountChanged=${(e: CustomEvent): void =>\n options?.amountChanged ? options.amountChanged(e.detail.amount) : undefined}\n >\n <slot name=\"paypal-upsell-button\"></slot>\n </upsell-modal-content>\n `;\n return this.modalManager.showModal({\n config: modalConfig,\n customModalContent: modalContent,\n userClosedModalCallback: options?.userClosedModalCallback,\n });\n }\n\n /** @inheritdoc */\n async startDonationSubmissionFlow(options: {\n nonce: string;\n paymentProvider: PaymentProvider;\n donationInfo: DonationPaymentInfo;\n billingInfo: BillingInfo;\n customerInfo: CustomerInfo;\n upsellOnetimeTransactionId?: string;\n customerId?: string;\n recaptchaToken?: string;\n bin?: string; // first 6 digits of CC\n binName?: string; // credit card bank name\n }): Promise<DonationResponse | undefined> {\n this.showProcessingModal();\n\n try {\n const response = await this.braintreeManager.submitDonation(options);\n\n if (response.success) {\n this.handleSuccessfulDonationResponse(\n options.donationInfo,\n response.value as SuccessResponse,\n );\n return response;\n } else {\n const error = response.value as ErrorResponse;\n this.showErrorModal({\n message: error.message,\n });\n return response;\n }\n } catch (error) {\n this.showErrorModal({\n message: `${error}`,\n });\n console.error('error getting a response', error);\n return undefined;\n }\n }\n\n private async upsellModalYesSelected(\n oneTimeDonationResponse: SuccessResponse,\n amount: number,\n ): Promise<DonationResponse | undefined> {\n this.showProcessingModal();\n\n try {\n const response = await this.braintreeManager.submitUpsellDonation({\n oneTimeDonationResponse: oneTimeDonationResponse,\n amount: amount,\n });\n\n if (response.success) {\n this.completeUpsell({\n successResponse: oneTimeDonationResponse,\n upsellSuccessResponse: response.value as SuccessResponse,\n });\n } else {\n const error = response.value as ErrorResponse;\n this.showErrorModal({\n message: error.message,\n });\n }\n\n return response;\n } catch (error) {\n this.showErrorModal({\n message: `${error}`,\n });\n console.error('error getting a response', error);\n return undefined;\n }\n }\n\n private completeUpsell(options: {\n successResponse: SuccessResponse;\n upsellSuccessResponse?: SuccessResponse;\n }): void {\n this.showThankYouModal(options);\n\n // post analytic\n const selectedPayment = options.successResponse.paymentProvider.replace(/\\s+/g, '');\n const action = `Donated-${selectedPayment}-upsell`;\n const label = options.successResponse.donationType;\n this.analytics.logEventNoSampling(action, label);\n\n this.braintreeManager.donationSuccessful(options);\n }\n\n static getDefaultUpsellAmount(oneTimeAmount: number): number {\n let amount = 5;\n\n if (oneTimeAmount <= 10) amount = 5;\n else if (oneTimeAmount > 10 && oneTimeAmount <= 25) amount = 10;\n else if (oneTimeAmount > 25 && oneTimeAmount <= 100) amount = 25;\n else if (oneTimeAmount > 100) amount = 50;\n\n return amount;\n }\n\n /** @inheritdoc */\n handleSuccessfulDonationResponse(\n donationInfo: DonationPaymentInfo,\n response: SuccessResponse,\n ): void {\n switch (donationInfo.donationType) {\n case DonationType.OneTime:\n this.showUpsellModal({\n oneTimeAmount: response.amount,\n yesSelected: (amount: number) => {\n this.upsellModalYesSelected(response, amount);\n },\n noSelected: () => {\n this.showThankYouModal({ successResponse: response });\n },\n userClosedModalCallback: () => {\n this.showThankYouModal({ successResponse: response });\n },\n });\n break;\n case DonationType.Monthly:\n this.showThankYouModal({ successResponse: response });\n break;\n // This case will never be reached, it is only here for completeness.\n // The upsell case gets handled in `modalYesSelected()` below\n case DonationType.Upsell:\n break;\n default:\n break;\n }\n }\n}\n"]}
|
|
@@ -9,8 +9,8 @@ import { MockPaymentClients } from '../mocks/mock-payment-clients';
|
|
|
9
9
|
import { fillInContactForm } from '../helpers/fillInContactForm';
|
|
10
10
|
import { promisedSleep } from '../../src/util/promisedSleep';
|
|
11
11
|
import { MockModalManager } from '../mocks/mock-modal-manager';
|
|
12
|
-
import { MockAnalyticHandler } from '../mocks/mock-analytics-handler';
|
|
13
12
|
import { MockPaymentFlowHandlers } from '../mocks/flow-handlers/mock-payment-flow-handlers';
|
|
13
|
+
import { MockAnalyticsManager } from '@internetarchive/analytics-manager/dist/test/mock-analytics-manager';
|
|
14
14
|
describe('Donation Form Controller', () => {
|
|
15
15
|
beforeEach(() => {
|
|
16
16
|
window['grecaptcha'] = new MockGrecaptcha(MockGrecaptchaMode.Success);
|
|
@@ -25,8 +25,8 @@ describe('Donation Form Controller', () => {
|
|
|
25
25
|
expect(el.shadowRoot).to.equal(null);
|
|
26
26
|
}));
|
|
27
27
|
it('can submit a donation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
-
var _a, _b, _c;
|
|
29
|
-
const mockAnalytics = new
|
|
28
|
+
var _a, _b, _c, _d;
|
|
29
|
+
const mockAnalytics = new MockAnalyticsManager();
|
|
30
30
|
const controller = (yield fixture(html `
|
|
31
31
|
<donation-form-controller .analyticsHandler=${mockAnalytics}> </donation-form-controller>
|
|
32
32
|
`));
|
|
@@ -72,12 +72,13 @@ describe('Donation Form Controller', () => {
|
|
|
72
72
|
const donateClickEvent = new MouseEvent('click');
|
|
73
73
|
donateButton === null || donateButton === void 0 ? void 0 : donateButton.dispatchEvent(donateClickEvent);
|
|
74
74
|
yield promisedSleep(100);
|
|
75
|
-
expect(mockAnalytics.
|
|
75
|
+
expect((_d = mockAnalytics.sendEventOptions) === null || _d === void 0 ? void 0 : _d.action).to.equal('PaymentFlowStarted');
|
|
76
76
|
// verify that a payload has been requested to be submitted to the backend
|
|
77
77
|
expect(endpointManager.requestSubmitted).to.not.equal(undefined);
|
|
78
78
|
}));
|
|
79
79
|
it('sends Viewed analytics when it first updates', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
80
|
-
|
|
80
|
+
var _e, _f;
|
|
81
|
+
const mockAnalytics = new MockAnalyticsManager();
|
|
81
82
|
const analyticsCategory = 'FooCategory';
|
|
82
83
|
(yield fixture(html `
|
|
83
84
|
<donation-form-controller
|
|
@@ -87,12 +88,12 @@ describe('Donation Form Controller', () => {
|
|
|
87
88
|
>
|
|
88
89
|
</donation-form-controller>
|
|
89
90
|
`));
|
|
90
|
-
expect(mockAnalytics.
|
|
91
|
-
expect(mockAnalytics.
|
|
91
|
+
expect((_e = mockAnalytics.sendEventOptions) === null || _e === void 0 ? void 0 : _e.category).to.equal(analyticsCategory);
|
|
92
|
+
expect((_f = mockAnalytics.sendEventOptions) === null || _f === void 0 ? void 0 : _f.action).to.equal('Viewed');
|
|
92
93
|
}));
|
|
93
94
|
it('sends DonationInfoChanged analytics when donation info changes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
94
|
-
var
|
|
95
|
-
const mockAnalytics = new
|
|
95
|
+
var _g, _h, _j, _k, _l;
|
|
96
|
+
const mockAnalytics = new MockAnalyticsManager();
|
|
96
97
|
const analyticsCategory = 'FooCategory';
|
|
97
98
|
const controller = (yield fixture(html `
|
|
98
99
|
<donation-form-controller
|
|
@@ -103,17 +104,17 @@ describe('Donation Form Controller', () => {
|
|
|
103
104
|
</donation-form-controller>
|
|
104
105
|
`));
|
|
105
106
|
const donationForm = controller.querySelector('donation-form');
|
|
106
|
-
const donationHeader = (
|
|
107
|
-
const editDonation = (
|
|
108
|
-
const monthlyOption = (
|
|
107
|
+
const donationHeader = (_g = donationForm.shadowRoot) === null || _g === void 0 ? void 0 : _g.querySelector('donation-form-header');
|
|
108
|
+
const editDonation = (_h = donationHeader === null || donationHeader === void 0 ? void 0 : donationHeader.shadowRoot) === null || _h === void 0 ? void 0 : _h.querySelector('donation-form-edit-donation');
|
|
109
|
+
const monthlyOption = (_j = editDonation === null || editDonation === void 0 ? void 0 : editDonation.shadowRoot) === null || _j === void 0 ? void 0 : _j.querySelector('#donationType-monthly-option');
|
|
109
110
|
const clickEvent = new MouseEvent('click');
|
|
110
111
|
monthlyOption === null || monthlyOption === void 0 ? void 0 : monthlyOption.dispatchEvent(clickEvent);
|
|
111
|
-
expect(mockAnalytics.
|
|
112
|
-
expect(mockAnalytics.
|
|
112
|
+
expect((_k = mockAnalytics.sendEventOptions) === null || _k === void 0 ? void 0 : _k.category).to.equal(analyticsCategory);
|
|
113
|
+
expect((_l = mockAnalytics.sendEventOptions) === null || _l === void 0 ? void 0 : _l.action).to.equal('DonationInfoChanged');
|
|
113
114
|
}));
|
|
114
115
|
it('sends ProviderSelected analytics', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
115
|
-
var
|
|
116
|
-
const mockAnalytics = new
|
|
116
|
+
var _m, _o, _p, _q, _r;
|
|
117
|
+
const mockAnalytics = new MockAnalyticsManager();
|
|
117
118
|
const analyticsCategory = 'FooCategory';
|
|
118
119
|
const controller = (yield fixture(html `
|
|
119
120
|
<donation-form-controller
|
|
@@ -124,26 +125,27 @@ describe('Donation Form Controller', () => {
|
|
|
124
125
|
</donation-form-controller>
|
|
125
126
|
`));
|
|
126
127
|
const donationForm = controller.querySelector('donation-form');
|
|
127
|
-
const paymentSelector = (
|
|
128
|
+
const paymentSelector = (_m = donationForm.shadowRoot) === null || _m === void 0 ? void 0 : _m.querySelector('payment-selector');
|
|
128
129
|
// on the first payment provider chosen, the previousPaymentProvider is undefined
|
|
129
|
-
const creditCardButton = (
|
|
130
|
+
const creditCardButton = (_o = paymentSelector.shadowRoot) === null || _o === void 0 ? void 0 : _o.querySelector('.credit-card-button');
|
|
130
131
|
setTimeout(() => {
|
|
131
132
|
const ccClickEvent = new MouseEvent('click');
|
|
132
133
|
creditCardButton.dispatchEvent(ccClickEvent);
|
|
133
134
|
});
|
|
134
135
|
yield oneEvent(donationForm, 'paymentProviderSelected');
|
|
135
|
-
expect(mockAnalytics.
|
|
136
|
+
expect((_p = mockAnalytics.sendEventOptions) === null || _p === void 0 ? void 0 : _p.action).to.equal('ProviderFirstSelected-CreditCard');
|
|
136
137
|
// on subsequent payment provider choices, the previousPaymentProvider is populated
|
|
137
|
-
const venmoButton = (
|
|
138
|
+
const venmoButton = (_q = paymentSelector.shadowRoot) === null || _q === void 0 ? void 0 : _q.querySelector('.venmo');
|
|
138
139
|
setTimeout(() => {
|
|
139
140
|
const venmoClickEvent = new MouseEvent('click');
|
|
140
141
|
venmoButton.dispatchEvent(venmoClickEvent);
|
|
141
142
|
});
|
|
142
143
|
yield oneEvent(donationForm, 'paymentProviderSelected');
|
|
143
|
-
expect(mockAnalytics.
|
|
144
|
+
expect((_r = mockAnalytics.sendEventOptions) === null || _r === void 0 ? void 0 : _r.action).to.equal('ProviderChangedTo-Venmo');
|
|
144
145
|
}));
|
|
145
146
|
it('sends PaymentFlowCancelled analytics', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
146
|
-
|
|
147
|
+
var _s, _t;
|
|
148
|
+
const mockAnalytics = new MockAnalyticsManager();
|
|
147
149
|
const analyticsCategory = 'FooCategory';
|
|
148
150
|
const controller = (yield fixture(html `
|
|
149
151
|
<donation-form-controller
|
|
@@ -159,11 +161,12 @@ describe('Donation Form Controller', () => {
|
|
|
159
161
|
yield elementUpdated(donationForm);
|
|
160
162
|
yield promisedSleep(250);
|
|
161
163
|
flowHandlers.paypalHandler.emitPaymentCancelledEvent();
|
|
162
|
-
expect(mockAnalytics.
|
|
163
|
-
expect(mockAnalytics.
|
|
164
|
+
expect((_s = mockAnalytics.sendEventOptions) === null || _s === void 0 ? void 0 : _s.action).to.equal('PaymentFlowCancelled');
|
|
165
|
+
expect((_t = mockAnalytics.sendEventOptions) === null || _t === void 0 ? void 0 : _t.label).to.equal('PayPal');
|
|
164
166
|
}));
|
|
165
167
|
it('sends PaymentFlowError analytics', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
166
|
-
|
|
168
|
+
var _u, _v;
|
|
169
|
+
const mockAnalytics = new MockAnalyticsManager();
|
|
167
170
|
const analyticsCategory = 'FooCategory';
|
|
168
171
|
const controller = (yield fixture(html `
|
|
169
172
|
<donation-form-controller
|
|
@@ -179,8 +182,8 @@ describe('Donation Form Controller', () => {
|
|
|
179
182
|
yield elementUpdated(donationForm);
|
|
180
183
|
yield promisedSleep(250);
|
|
181
184
|
flowHandlers.paypalHandler.emitPaymentErrorEvent();
|
|
182
|
-
expect(mockAnalytics.
|
|
183
|
-
expect(mockAnalytics.
|
|
185
|
+
expect((_u = mockAnalytics.sendEventOptions) === null || _u === void 0 ? void 0 : _u.action).to.equal('PaymentFlowError');
|
|
186
|
+
expect((_v = mockAnalytics.sendEventOptions) === null || _v === void 0 ? void 0 : _v.label).to.equal('PayPal-foo-error');
|
|
184
187
|
}));
|
|
185
188
|
});
|
|
186
189
|
//# sourceMappingURL=donation-form-controller.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"donation-form-controller.test.js","sourceRoot":"","sources":["../../../test/tests/donation-form-controller.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { html, fixture, expect, elementUpdated, oneEvent } from '@open-wc/testing';\n\nimport '../../src/donation-form-controller';\nimport { DonationFormController } from '../../src/donation-form-controller';\nimport { MockGrecaptcha, MockGrecaptchaMode } from '../mocks/payment-clients/mock-grecaptcha';\nimport { HostingEnvironment } from '../../src/braintree-manager/braintree-interfaces';\nimport { MockEndpointManager } from '../mocks/mock-endpoint-manager';\nimport { MockPaymentClients } from '../mocks/mock-payment-clients';\nimport { ContactForm } from '../../src/form-elements/contact-form/contact-form';\nimport { fillInContactForm } from '../helpers/fillInContactForm';\nimport { promisedSleep } from '../../src/util/promisedSleep';\nimport { MockModalManager } from '../mocks/mock-modal-manager';\nimport { MockHostedFieldsClient } from '../mocks/payment-clients/mock-hostedfields-client';\nimport { DonationForm } from '../../src/donation-form';\nimport { PaymentSelector } from '../../src/form-elements/payment-selector';\nimport { MockAnalyticHandler } from '../mocks/mock-analytics-handler';\nimport { DonationFormHeader } from '../../src/form-elements/header/donation-form-header';\nimport { DonationFormEditDonation } from '@internetarchive/donation-form-edit-donation';\nimport { MockPaymentFlowHandlers } from '../mocks/flow-handlers/mock-payment-flow-handlers';\n\ndescribe('Donation Form Controller', () => {\n beforeEach(() => {\n (window['grecaptcha' as any] as any) = new MockGrecaptcha(MockGrecaptchaMode.Success);\n });\n\n afterEach(() => {\n delete window['grecaptcha' as any];\n });\n\n it('has no shadowRoot', async () => {\n const el = (await fixture(html`\n <donation-form-controller></donation-form-controller>\n `)) as DonationFormController;\n\n expect(el.shadowRoot).to.equal(null);\n });\n\n it('can submit a donation', async () => {\n const mockAnalytics = new MockAnalyticHandler();\n const controller = (await fixture(html`\n <donation-form-controller .analyticsHandler=${mockAnalytics}> </donation-form-controller>\n `)) as DonationFormController;\n\n // configure the donation-form-controller\n const recaptchaElement = (await fixture(\n html`\n <div></div>\n `,\n )) as HTMLElement;\n const endpointManager = new MockEndpointManager();\n const paymentClients = new MockPaymentClients();\n const modalManager = new MockModalManager();\n controller.paymentClients = paymentClients;\n controller.modalManager = modalManager;\n controller.environment = HostingEnvironment.Development;\n controller.recaptchaElement = recaptchaElement;\n controller.endpointManager = endpointManager;\n controller.braintreeAuthToken = 'foo';\n controller.recaptchaSiteKey = 'bar';\n controller.venmoProfileId = 'baz';\n controller.referrer = 'test-referrer';\n controller.loggedInUser = 'test-user';\n\n // grab some internal elements to interact with\n const donationForm: DonationForm = controller.querySelector('donation-form') as DonationForm;\n const paymentSelector: PaymentSelector = donationForm?.shadowRoot?.querySelector(\n 'payment-selector',\n ) as PaymentSelector;\n const creditCardButton = paymentSelector?.shadowRoot?.querySelector('.credit-card-button');\n\n // click on the credit card button\n const ccClickEvent = new MouseEvent('click');\n creditCardButton?.dispatchEvent(ccClickEvent);\n\n // clicking on the credit card button will show the contact form so wait for it to be updated\n await elementUpdated(donationForm);\n await promisedSleep(100);\n const contactForm = document.querySelector('contact-form') as ContactForm;\n await fillInContactForm(contactForm);\n\n // verify the Donate button is still disabled\n const donateButton = donationForm?.shadowRoot?.querySelector(\n '#donate-button',\n ) as HTMLButtonElement;\n\n // simulates after the user has input all of the credit card fields\n const hostedFields = (await paymentClients.hostedFields.get()) as MockHostedFieldsClient;\n hostedFields.emitValidityChangedEvent(true);\n await promisedSleep(100);\n\n // verify that the donate button has become enabled and no request has been submitted\n expect(donateButton.disabled).to.equal(false);\n expect(endpointManager.requestSubmitted).to.equal(undefined);\n\n // click the donate button\n const donateClickEvent = new MouseEvent('click');\n donateButton?.dispatchEvent(donateClickEvent);\n await promisedSleep(100);\n\n expect(mockAnalytics.callAction).to.equal('PaymentFlowStarted');\n\n // verify that a payload has been requested to be submitted to the backend\n expect(endpointManager.requestSubmitted).to.not.equal(undefined);\n });\n\n it('sends Viewed analytics when it first updates', async () => {\n const mockAnalytics = new MockAnalyticHandler();\n const analyticsCategory = 'FooCategory';\n (await fixture(html`\n <donation-form-controller\n ?showCreditCardButtonText=${true}\n .analyticsCategory=${analyticsCategory}\n .analyticsHandler=${mockAnalytics}\n >\n </donation-form-controller>\n `)) as DonationFormController;\n\n expect(mockAnalytics.callCategory).to.equal(analyticsCategory);\n expect(mockAnalytics.callAction).to.equal('Viewed');\n });\n\n it('sends DonationInfoChanged analytics when donation info changes', async () => {\n const mockAnalytics = new MockAnalyticHandler();\n const analyticsCategory = 'FooCategory';\n const controller = (await fixture(html`\n <donation-form-controller\n ?showCreditCardButtonText=${true}\n .analyticsCategory=${analyticsCategory}\n .analyticsHandler=${mockAnalytics}\n >\n </donation-form-controller>\n `)) as DonationFormController;\n\n const donationForm: DonationForm = controller.querySelector('donation-form') as DonationForm;\n const donationHeader = donationForm.shadowRoot?.querySelector(\n 'donation-form-header',\n ) as DonationFormHeader;\n const editDonation = donationHeader?.shadowRoot?.querySelector(\n 'donation-form-edit-donation',\n ) as DonationFormEditDonation;\n const monthlyOption = editDonation?.shadowRoot?.querySelector('#donationType-monthly-option');\n const clickEvent = new MouseEvent('click');\n monthlyOption?.dispatchEvent(clickEvent);\n\n expect(mockAnalytics.callCategory).to.equal(analyticsCategory);\n expect(mockAnalytics.callAction).to.equal('DonationInfoChanged');\n });\n\n it('sends ProviderSelected analytics', async () => {\n const mockAnalytics = new MockAnalyticHandler();\n const analyticsCategory = 'FooCategory';\n const controller = (await fixture(html`\n <donation-form-controller\n ?showCreditCardButtonText=${true}\n .analyticsCategory=${analyticsCategory}\n .analyticsHandler=${mockAnalytics}\n >\n </donation-form-controller>\n `)) as DonationFormController;\n\n const donationForm: DonationForm = controller.querySelector('donation-form') as DonationForm;\n const paymentSelector = donationForm.shadowRoot?.querySelector(\n 'payment-selector',\n ) as PaymentSelector;\n\n // on the first payment provider chosen, the previousPaymentProvider is undefined\n const creditCardButton = paymentSelector.shadowRoot?.querySelector(\n '.credit-card-button',\n ) as HTMLButtonElement;\n setTimeout(() => {\n const ccClickEvent = new MouseEvent('click');\n creditCardButton.dispatchEvent(ccClickEvent);\n });\n await oneEvent(donationForm, 'paymentProviderSelected');\n expect(mockAnalytics.callAction).to.equal('ProviderFirstSelected-CreditCard');\n\n // on subsequent payment provider choices, the previousPaymentProvider is populated\n const venmoButton = paymentSelector.shadowRoot?.querySelector('.venmo') as HTMLButtonElement;\n setTimeout(() => {\n const venmoClickEvent = new MouseEvent('click');\n venmoButton.dispatchEvent(venmoClickEvent);\n });\n await oneEvent(donationForm, 'paymentProviderSelected');\n expect(mockAnalytics.callAction).to.equal('ProviderChangedTo-Venmo');\n });\n\n it('sends PaymentFlowCancelled analytics', async () => {\n const mockAnalytics = new MockAnalyticHandler();\n const analyticsCategory = 'FooCategory';\n const controller = (await fixture(html`\n <donation-form-controller\n ?showCreditCardButtonText=${true}\n .analyticsCategory=${analyticsCategory}\n .analyticsHandler=${mockAnalytics}\n >\n </donation-form-controller>\n `)) as DonationFormController;\n\n const donationForm: DonationForm = controller.querySelector('donation-form') as DonationForm;\n const flowHandlers = new MockPaymentFlowHandlers();\n donationForm.paymentFlowHandlers = flowHandlers;\n await elementUpdated(donationForm);\n await promisedSleep(250);\n flowHandlers.paypalHandler.emitPaymentCancelledEvent();\n expect(mockAnalytics.callAction).to.equal('PaymentFlowCancelled');\n expect(mockAnalytics.callLabel).to.equal('PayPal');\n });\n\n it('sends PaymentFlowError analytics', async () => {\n const mockAnalytics = new MockAnalyticHandler();\n const analyticsCategory = 'FooCategory';\n const controller = (await fixture(html`\n <donation-form-controller\n ?showCreditCardButtonText=${true}\n .analyticsCategory=${analyticsCategory}\n .analyticsHandler=${mockAnalytics}\n >\n </donation-form-controller>\n `)) as DonationFormController;\n\n const donationForm: DonationForm = controller.querySelector('donation-form') as DonationForm;\n const flowHandlers = new MockPaymentFlowHandlers();\n donationForm.paymentFlowHandlers = flowHandlers;\n await elementUpdated(donationForm);\n await promisedSleep(250);\n flowHandlers.paypalHandler.emitPaymentErrorEvent();\n expect(mockAnalytics.callAction).to.equal('PaymentFlowError');\n expect(mockAnalytics.callLabel).to.equal('PayPal-foo-error');\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"donation-form-controller.test.js","sourceRoot":"","sources":["../../../test/tests/donation-form-controller.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { html, fixture, expect, elementUpdated, oneEvent } from '@open-wc/testing';\n\nimport '../../src/donation-form-controller';\nimport { DonationFormController } from '../../src/donation-form-controller';\nimport { MockGrecaptcha, MockGrecaptchaMode } from '../mocks/payment-clients/mock-grecaptcha';\nimport { HostingEnvironment } from '../../src/braintree-manager/braintree-interfaces';\nimport { MockEndpointManager } from '../mocks/mock-endpoint-manager';\nimport { MockPaymentClients } from '../mocks/mock-payment-clients';\nimport { ContactForm } from '../../src/form-elements/contact-form/contact-form';\nimport { fillInContactForm } from '../helpers/fillInContactForm';\nimport { promisedSleep } from '../../src/util/promisedSleep';\nimport { MockModalManager } from '../mocks/mock-modal-manager';\nimport { MockHostedFieldsClient } from '../mocks/payment-clients/mock-hostedfields-client';\nimport { DonationForm } from '../../src/donation-form';\nimport { PaymentSelector } from '../../src/form-elements/payment-selector';\nimport { DonationFormHeader } from '../../src/form-elements/header/donation-form-header';\nimport { DonationFormEditDonation } from '@internetarchive/donation-form-edit-donation';\nimport { MockPaymentFlowHandlers } from '../mocks/flow-handlers/mock-payment-flow-handlers';\nimport { MockAnalyticsManager } from '@internetarchive/analytics-manager/dist/test/mock-analytics-manager';\n\ndescribe('Donation Form Controller', () => {\n beforeEach(() => {\n (window['grecaptcha' as any] as any) = new MockGrecaptcha(MockGrecaptchaMode.Success);\n });\n\n afterEach(() => {\n delete window['grecaptcha' as any];\n });\n\n it('has no shadowRoot', async () => {\n const el = (await fixture(html`\n <donation-form-controller></donation-form-controller>\n `)) as DonationFormController;\n\n expect(el.shadowRoot).to.equal(null);\n });\n\n it('can submit a donation', async () => {\n const mockAnalytics = new MockAnalyticsManager();\n const controller = (await fixture(html`\n <donation-form-controller .analyticsHandler=${mockAnalytics}> </donation-form-controller>\n `)) as DonationFormController;\n\n // configure the donation-form-controller\n const recaptchaElement = (await fixture(\n html`\n <div></div>\n `,\n )) as HTMLElement;\n const endpointManager = new MockEndpointManager();\n const paymentClients = new MockPaymentClients();\n const modalManager = new MockModalManager();\n controller.paymentClients = paymentClients;\n controller.modalManager = modalManager;\n controller.environment = HostingEnvironment.Development;\n controller.recaptchaElement = recaptchaElement;\n controller.endpointManager = endpointManager;\n controller.braintreeAuthToken = 'foo';\n controller.recaptchaSiteKey = 'bar';\n controller.venmoProfileId = 'baz';\n controller.referrer = 'test-referrer';\n controller.loggedInUser = 'test-user';\n\n // grab some internal elements to interact with\n const donationForm: DonationForm = controller.querySelector('donation-form') as DonationForm;\n const paymentSelector: PaymentSelector = donationForm?.shadowRoot?.querySelector(\n 'payment-selector',\n ) as PaymentSelector;\n const creditCardButton = paymentSelector?.shadowRoot?.querySelector('.credit-card-button');\n\n // click on the credit card button\n const ccClickEvent = new MouseEvent('click');\n creditCardButton?.dispatchEvent(ccClickEvent);\n\n // clicking on the credit card button will show the contact form so wait for it to be updated\n await elementUpdated(donationForm);\n await promisedSleep(100);\n const contactForm = document.querySelector('contact-form') as ContactForm;\n await fillInContactForm(contactForm);\n\n // verify the Donate button is still disabled\n const donateButton = donationForm?.shadowRoot?.querySelector(\n '#donate-button',\n ) as HTMLButtonElement;\n\n // simulates after the user has input all of the credit card fields\n const hostedFields = (await paymentClients.hostedFields.get()) as MockHostedFieldsClient;\n hostedFields.emitValidityChangedEvent(true);\n await promisedSleep(100);\n\n // verify that the donate button has become enabled and no request has been submitted\n expect(donateButton.disabled).to.equal(false);\n expect(endpointManager.requestSubmitted).to.equal(undefined);\n\n // click the donate button\n const donateClickEvent = new MouseEvent('click');\n donateButton?.dispatchEvent(donateClickEvent);\n await promisedSleep(100);\n\n expect(mockAnalytics.sendEventOptions?.action).to.equal('PaymentFlowStarted');\n\n // verify that a payload has been requested to be submitted to the backend\n expect(endpointManager.requestSubmitted).to.not.equal(undefined);\n });\n\n it('sends Viewed analytics when it first updates', async () => {\n const mockAnalytics = new MockAnalyticsManager();\n const analyticsCategory = 'FooCategory';\n (await fixture(html`\n <donation-form-controller\n ?showCreditCardButtonText=${true}\n .analyticsCategory=${analyticsCategory}\n .analyticsHandler=${mockAnalytics}\n >\n </donation-form-controller>\n `)) as DonationFormController;\n expect(mockAnalytics.sendEventOptions?.category).to.equal(analyticsCategory);\n expect(mockAnalytics.sendEventOptions?.action).to.equal('Viewed');\n });\n\n it('sends DonationInfoChanged analytics when donation info changes', async () => {\n const mockAnalytics = new MockAnalyticsManager();\n const analyticsCategory = 'FooCategory';\n const controller = (await fixture(html`\n <donation-form-controller\n ?showCreditCardButtonText=${true}\n .analyticsCategory=${analyticsCategory}\n .analyticsHandler=${mockAnalytics}\n >\n </donation-form-controller>\n `)) as DonationFormController;\n\n const donationForm: DonationForm = controller.querySelector('donation-form') as DonationForm;\n const donationHeader = donationForm.shadowRoot?.querySelector(\n 'donation-form-header',\n ) as DonationFormHeader;\n const editDonation = donationHeader?.shadowRoot?.querySelector(\n 'donation-form-edit-donation',\n ) as DonationFormEditDonation;\n const monthlyOption = editDonation?.shadowRoot?.querySelector('#donationType-monthly-option');\n const clickEvent = new MouseEvent('click');\n monthlyOption?.dispatchEvent(clickEvent);\n\n expect(mockAnalytics.sendEventOptions?.category).to.equal(analyticsCategory);\n expect(mockAnalytics.sendEventOptions?.action).to.equal('DonationInfoChanged');\n });\n\n it('sends ProviderSelected analytics', async () => {\n const mockAnalytics = new MockAnalyticsManager();\n const analyticsCategory = 'FooCategory';\n const controller = (await fixture(html`\n <donation-form-controller\n ?showCreditCardButtonText=${true}\n .analyticsCategory=${analyticsCategory}\n .analyticsHandler=${mockAnalytics}\n >\n </donation-form-controller>\n `)) as DonationFormController;\n\n const donationForm: DonationForm = controller.querySelector('donation-form') as DonationForm;\n const paymentSelector = donationForm.shadowRoot?.querySelector(\n 'payment-selector',\n ) as PaymentSelector;\n\n // on the first payment provider chosen, the previousPaymentProvider is undefined\n const creditCardButton = paymentSelector.shadowRoot?.querySelector(\n '.credit-card-button',\n ) as HTMLButtonElement;\n setTimeout(() => {\n const ccClickEvent = new MouseEvent('click');\n creditCardButton.dispatchEvent(ccClickEvent);\n });\n await oneEvent(donationForm, 'paymentProviderSelected');\n expect(mockAnalytics.sendEventOptions?.action).to.equal('ProviderFirstSelected-CreditCard');\n\n // on subsequent payment provider choices, the previousPaymentProvider is populated\n const venmoButton = paymentSelector.shadowRoot?.querySelector('.venmo') as HTMLButtonElement;\n setTimeout(() => {\n const venmoClickEvent = new MouseEvent('click');\n venmoButton.dispatchEvent(venmoClickEvent);\n });\n await oneEvent(donationForm, 'paymentProviderSelected');\n expect(mockAnalytics.sendEventOptions?.action).to.equal('ProviderChangedTo-Venmo');\n });\n\n it('sends PaymentFlowCancelled analytics', async () => {\n const mockAnalytics = new MockAnalyticsManager();\n const analyticsCategory = 'FooCategory';\n const controller = (await fixture(html`\n <donation-form-controller\n ?showCreditCardButtonText=${true}\n .analyticsCategory=${analyticsCategory}\n .analyticsHandler=${mockAnalytics}\n >\n </donation-form-controller>\n `)) as DonationFormController;\n\n const donationForm: DonationForm = controller.querySelector('donation-form') as DonationForm;\n const flowHandlers = new MockPaymentFlowHandlers();\n donationForm.paymentFlowHandlers = flowHandlers;\n await elementUpdated(donationForm);\n await promisedSleep(250);\n flowHandlers.paypalHandler.emitPaymentCancelledEvent();\n expect(mockAnalytics.sendEventOptions?.action).to.equal('PaymentFlowCancelled');\n expect(mockAnalytics.sendEventOptions?.label).to.equal('PayPal');\n });\n\n it('sends PaymentFlowError analytics', async () => {\n const mockAnalytics = new MockAnalyticsManager();\n const analyticsCategory = 'FooCategory';\n const controller = (await fixture(html`\n <donation-form-controller\n ?showCreditCardButtonText=${true}\n .analyticsCategory=${analyticsCategory}\n .analyticsHandler=${mockAnalytics}\n >\n </donation-form-controller>\n `)) as DonationFormController;\n\n const donationForm: DonationForm = controller.querySelector('donation-form') as DonationForm;\n const flowHandlers = new MockPaymentFlowHandlers();\n donationForm.paymentFlowHandlers = flowHandlers;\n await elementUpdated(donationForm);\n await promisedSleep(250);\n flowHandlers.paypalHandler.emitPaymentErrorEvent();\n expect(mockAnalytics.sendEventOptions?.action).to.equal('PaymentFlowError');\n expect(mockAnalytics.sendEventOptions?.label).to.equal('PayPal-foo-error');\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@internetarchive/donation-form",
|
|
3
|
-
"version": "0.5.15-
|
|
3
|
+
"version": "0.5.15-a3",
|
|
4
4
|
"description": "The Internet Archive Donation Form",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"test:watch": "concurrently --kill-others --names tsc,karma \"yarn run tsc:watch\" \"karma start --auto-watch=true --single-run=false\""
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
+
"@internetarchive/analytics-manager": "^0.1.2",
|
|
31
32
|
"@internetarchive/donation-form-currency-validator": "^0.3.0",
|
|
32
33
|
"@internetarchive/donation-form-data-models": "^0.3.2",
|
|
33
34
|
"@internetarchive/donation-form-edit-donation": "^0.3.13",
|
|
@@ -6,41 +6,3 @@ export interface DonationControllerEventLoggerInterface {
|
|
|
6
6
|
logEvent(action: string, label: string): void;
|
|
7
7
|
logEventNoSampling(action: string, label: string): void;
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* This is an interface for the analytics handler in petabox
|
|
12
|
-
* because we don't currently have a declarations file for it.
|
|
13
|
-
*/
|
|
14
|
-
export interface AnalyticsHandlerInterface {
|
|
15
|
-
/**
|
|
16
|
-
* Sends a tracking event.
|
|
17
|
-
*
|
|
18
|
-
* @param {string} category
|
|
19
|
-
* @param {string} action
|
|
20
|
-
* @param {string} label Defaults to `window.location.pathname`
|
|
21
|
-
* @param {Object} additionalEventParams These are internal params, not sent to GA
|
|
22
|
-
*/
|
|
23
|
-
// eslint-disable-next-line @typescript-eslint/camelcase
|
|
24
|
-
send_event(
|
|
25
|
-
category: string,
|
|
26
|
-
action: string,
|
|
27
|
-
label?: string,
|
|
28
|
-
additionalEventParams?: object,
|
|
29
|
-
): void;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Sends a tracking event to no sampling bucket.
|
|
33
|
-
*
|
|
34
|
-
* @param {string} category
|
|
35
|
-
* @param {string} action
|
|
36
|
-
* @param {string} label
|
|
37
|
-
* @param {Object} additionalEventParams These are internal params, not sent to GA
|
|
38
|
-
*/
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/camelcase
|
|
40
|
-
send_event_no_sampling(
|
|
41
|
-
category: string,
|
|
42
|
-
action: string,
|
|
43
|
-
label?: string,
|
|
44
|
-
additionalEventParams?: object,
|
|
45
|
-
): void;
|
|
46
|
-
}
|
|
@@ -35,7 +35,8 @@ import './form-elements/contact-form/contact-form';
|
|
|
35
35
|
import creditCardImg from '@internetarchive/icon-credit-card';
|
|
36
36
|
import calendarImg from '@internetarchive/icon-calendar';
|
|
37
37
|
import lockImg from '@internetarchive/icon-lock';
|
|
38
|
-
import {
|
|
38
|
+
import { DonationControllerEventLoggerInterface } from './@types/analytics-handler';
|
|
39
|
+
import { AnalyticsManagerInterface, AnalyticsEvent } from '@internetarchive/analytics-manager';
|
|
39
40
|
import {
|
|
40
41
|
EditDonationAmountSelectionLayout,
|
|
41
42
|
EditDonationFrequencySelectionMode,
|
|
@@ -90,7 +91,7 @@ export class DonationFormController extends LitElement {
|
|
|
90
91
|
|
|
91
92
|
@property({ type: Object }) endpointManager?: BraintreeEndpointManagerInterface;
|
|
92
93
|
|
|
93
|
-
@property({ type: Object }) analyticsHandler?:
|
|
94
|
+
@property({ type: Object }) analyticsHandler?: AnalyticsManagerInterface;
|
|
94
95
|
|
|
95
96
|
@property({ type: Object }) modalManager?: ModalManagerInterface;
|
|
96
97
|
|
|
@@ -123,6 +124,7 @@ export class DonationFormController extends LitElement {
|
|
|
123
124
|
updated(changedProperties: PropertyValues): void {
|
|
124
125
|
if (changedProperties.has('referrer') && this.referrer) {
|
|
125
126
|
this.braintreeManager?.setReferrer(this.referrer);
|
|
127
|
+
this.logEventNoSampling('referrer', this.referrer);
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
if (changedProperties.has('loggedInUser') && this.loggedInUser) {
|
|
@@ -131,6 +133,7 @@ export class DonationFormController extends LitElement {
|
|
|
131
133
|
|
|
132
134
|
if (changedProperties.has('origin') && this.origin) {
|
|
133
135
|
this.braintreeManager?.setOrigin(this.origin);
|
|
136
|
+
this.logEventNoSampling('origin', this.origin);
|
|
134
137
|
}
|
|
135
138
|
|
|
136
139
|
if (
|
|
@@ -523,7 +526,8 @@ export class DonationFormController extends LitElement {
|
|
|
523
526
|
* @param {string} label Event label, optional
|
|
524
527
|
*/
|
|
525
528
|
private logEvent(action: string, label?: string): void {
|
|
526
|
-
this.
|
|
529
|
+
const analyticEvent = { action, label, category: this.analyticsCategory } as AnalyticsEvent;
|
|
530
|
+
this.analyticsHandler?.sendEvent(analyticEvent);
|
|
527
531
|
}
|
|
528
532
|
|
|
529
533
|
/**
|
|
@@ -532,8 +536,9 @@ export class DonationFormController extends LitElement {
|
|
|
532
536
|
* @param {string} action Name of event
|
|
533
537
|
* @param {string} label Event label, optional
|
|
534
538
|
*/
|
|
535
|
-
|
|
536
|
-
this.
|
|
539
|
+
private logEventNoSampling(action: string, label?: string): void {
|
|
540
|
+
const analyticEvent = { action, label, category: this.analyticsCategory } as AnalyticsEvent;
|
|
541
|
+
this.analyticsHandler?.sendEventNoSampling(analyticEvent);
|
|
537
542
|
}
|
|
538
543
|
|
|
539
544
|
/**
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
DonationResponse,
|
|
15
15
|
} from '@internetarchive/donation-form-data-models';
|
|
16
16
|
import '../modals/error-modal-content';
|
|
17
|
-
import {
|
|
17
|
+
import { DonationControllerEventLoggerInterface } from '../@types/analytics-handler';
|
|
18
18
|
|
|
19
19
|
enum ModalHeaderColor {
|
|
20
20
|
Blue = '#497fbf',
|