@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.
@@ -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://www-jasonb.archive.org/services/donations/braintree-charge.php?debug=true', {
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://www-jasonb.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
+ {"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 { AnalyticsHandlerInterface } from '../src/@types/analytics-handler';
2
- export declare class DemoAnalyticsHandler implements AnalyticsHandlerInterface {
1
+ import { AnalyticsManagerInterface } from '@internetarchive/analytics-manager';
2
+ export declare class DemoAnalyticsHandler implements AnalyticsManagerInterface {
3
3
  nodeToUpdate: HTMLElement;
4
- send_event(category: string, action: string, label?: string, additionalEventParams?: object): void;
5
- send_event_no_sampling(category: string, action: string, label?: string, additionalEventParams?: object): void;
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
- // eslint-disable-next-line @typescript-eslint/camelcase
3
- send_event(category, action, label, additionalEventParams) {
4
- console.debug('DemoAnalyticsHandler', category, action, label, additionalEventParams);
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
- // eslint-disable-next-line @typescript-eslint/camelcase
7
- send_event_no_sampling(category, action, label, additionalEventParams) {
8
- console.debug('DemoAnalyticsHandler', category, action, label, additionalEventParams);
9
- const placeholder = document.querySelector('#latest-analytic');
10
- this.nodeToUpdate.innerHTML = `Action: ${action} - Label: ${label}`;
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":"AAEA,MAAM,OAAO,oBAAoB;IAE/B,wDAAwD;IACxD,UAAU,CACR,QAAgB,EAChB,MAAc,EACd,KAAc,EACd,qBAA8B;QAE9B,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;IACxF,CAAC;IACD,wDAAwD;IACxD,sBAAsB,CACpB,QAAgB,EAChB,MAAc,EACd,KAAc,EACd,qBAA8B;QAE9B,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;QACtF,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;QAC/D,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,WAAW,MAAM,aAAa,KAAK,EAAE,CAAC;IACtE,CAAC;CACF","sourcesContent":["import { AnalyticsHandlerInterface } from '../src/@types/analytics-handler';\n\nexport class DemoAnalyticsHandler implements AnalyticsHandlerInterface {\n nodeToUpdate!: HTMLElement;\n // eslint-disable-next-line @typescript-eslint/camelcase\n send_event(\n category: string,\n action: string,\n label?: string,\n additionalEventParams?: object,\n ): void {\n console.debug('DemoAnalyticsHandler', category, action, label, additionalEventParams);\n }\n // eslint-disable-next-line @typescript-eslint/camelcase\n send_event_no_sampling(\n category: string,\n action: string,\n label?: string,\n additionalEventParams?: object,\n ): void {\n console.debug('DemoAnalyticsHandler', category, action, label, additionalEventParams);\n const placeholder = document.querySelector('#latest-analytic');\n this.nodeToUpdate.innerHTML = `Action: ${action} - Label: ${label}`;\n }\n}\n"]}
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 { AnalyticsHandlerInterface } from './@types/analytics-handler';
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?: AnalyticsHandlerInterface;
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
- (_a = this.analyticsHandler) === null || _a === void 0 ? void 0 : _a.send_event(this.analyticsCategory, action, label);
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
- (_a = this.analyticsHandler) === null || _a === void 0 ? void 0 : _a.send_event_no_sampling(this.analyticsCategory, action, label);
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 MockAnalyticHandler();
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.callAction).to.equal('PaymentFlowStarted');
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
- const mockAnalytics = new MockAnalyticHandler();
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.callCategory).to.equal(analyticsCategory);
91
- expect(mockAnalytics.callAction).to.equal('Viewed');
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 _d, _e, _f;
95
- const mockAnalytics = new MockAnalyticHandler();
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 = (_d = donationForm.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector('donation-form-header');
107
- const editDonation = (_e = donationHeader === null || donationHeader === void 0 ? void 0 : donationHeader.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('donation-form-edit-donation');
108
- const monthlyOption = (_f = editDonation === null || editDonation === void 0 ? void 0 : editDonation.shadowRoot) === null || _f === void 0 ? void 0 : _f.querySelector('#donationType-monthly-option');
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.callCategory).to.equal(analyticsCategory);
112
- expect(mockAnalytics.callAction).to.equal('DonationInfoChanged');
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 _g, _h, _j;
116
- const mockAnalytics = new MockAnalyticHandler();
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 = (_g = donationForm.shadowRoot) === null || _g === void 0 ? void 0 : _g.querySelector('payment-selector');
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 = (_h = paymentSelector.shadowRoot) === null || _h === void 0 ? void 0 : _h.querySelector('.credit-card-button');
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.callAction).to.equal('ProviderFirstSelected-CreditCard');
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 = (_j = paymentSelector.shadowRoot) === null || _j === void 0 ? void 0 : _j.querySelector('.venmo');
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.callAction).to.equal('ProviderChangedTo-Venmo');
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
- const mockAnalytics = new MockAnalyticHandler();
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.callAction).to.equal('PaymentFlowCancelled');
163
- expect(mockAnalytics.callLabel).to.equal('PayPal');
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
- const mockAnalytics = new MockAnalyticHandler();
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.callAction).to.equal('PaymentFlowError');
183
- expect(mockAnalytics.callLabel).to.equal('PayPal-foo-error');
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-a1",
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 { AnalyticsHandlerInterface, DonationControllerEventLoggerInterface } from './@types/analytics-handler';
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?: AnalyticsHandlerInterface;
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.analyticsHandler?.send_event(this.analyticsCategory, action, label);
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
- private logEventNoSampling(action: string, label?: string): void {
536
- this.analyticsHandler?.send_event_no_sampling(this.analyticsCategory, action, label);
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 { AnalyticsHandlerInterface, DonationControllerEventLoggerInterface } from '../@types/analytics-handler';
17
+ import { DonationControllerEventLoggerInterface } from '../@types/analytics-handler';
18
18
 
19
19
  enum ModalHeaderColor {
20
20
  Blue = '#497fbf',