@salesforcedevs/dw-components 1.3.148-canary.1 → 1.3.148-canary.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import { api, LightningElement } from "lwc";
|
|
2
2
|
import StepSequence from "dx/stepSequence";
|
|
3
3
|
import { getListWithUuids } from "dxUtils/list";
|
|
4
|
+
import { track } from "dxUtils/analytics";
|
|
4
5
|
import { toJson } from "dxUtils/normalizers";
|
|
5
|
-
import Button from "dx/button";
|
|
6
|
-
|
|
7
|
-
function isNoAnimationCookieSet() {
|
|
8
|
-
return document.cookie
|
|
9
|
-
.split(";")
|
|
10
|
-
.some((ck) => ck.trim() === "no_j2s_animation=true");
|
|
11
|
-
}
|
|
12
6
|
|
|
13
7
|
export type StepDatum = {
|
|
14
8
|
bodyHtml?: string;
|
|
@@ -42,14 +36,24 @@ export type StepDatum = {
|
|
|
42
36
|
stepTitle: string;
|
|
43
37
|
};
|
|
44
38
|
|
|
39
|
+
function isNoAnimationCookieSet() {
|
|
40
|
+
return document.cookie
|
|
41
|
+
.split(";")
|
|
42
|
+
.some((ck) => ck.trim() === "no_j2s_animation=true");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
45
|
export default class J2sCardSequence extends LightningElement {
|
|
46
46
|
_didRenderStaticInnerHtml = false;
|
|
47
47
|
_isDrmLoading = false;
|
|
48
|
+
_isFormSubmitting = false;
|
|
48
49
|
_isJ2sFormInvalid = false;
|
|
49
50
|
_isTbidLoading = false;
|
|
50
51
|
_stepsData: StepDatum[] = [];
|
|
51
52
|
@api animateTransitions = false;
|
|
52
53
|
@api drmDomain: string = "https://drm.my.salesforce-sites.com";
|
|
54
|
+
@api drmRecaptchaSiteKey: string = "";
|
|
55
|
+
@api formHandler: string =
|
|
56
|
+
"https://formhandlermule-1s9xrb.5sc6y6-4.usa-e2.cloudhub.io/form_handler";
|
|
53
57
|
@api tbidApiBaseUrl: string | undefined;
|
|
54
58
|
@api useHistory: boolean = false;
|
|
55
59
|
|
|
@@ -91,7 +95,9 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
91
95
|
private tbidUserInfo: any; // TODO typings?
|
|
92
96
|
|
|
93
97
|
private get isLoading() {
|
|
94
|
-
return
|
|
98
|
+
return (
|
|
99
|
+
this._isDrmLoading || this._isTbidLoading || this._isFormSubmitting
|
|
100
|
+
);
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
private get isLoggedIn() {
|
|
@@ -175,6 +181,15 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
175
181
|
}
|
|
176
182
|
}
|
|
177
183
|
|
|
184
|
+
handleFormValidityChange({ detail }: CustomEvent) {
|
|
185
|
+
this.isJ2sFormInvalid = !detail.isValid;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
handleStepSequenceChange({ detail }: CustomEvent) {
|
|
189
|
+
this.currentSequenceStep = detail.stepIndex;
|
|
190
|
+
this.resetCustomButtonColors();
|
|
191
|
+
}
|
|
192
|
+
|
|
178
193
|
handleGetStarted(evt: Event) {
|
|
179
194
|
// If the user is not yet logged in, we need to prevent moving immediately to the next
|
|
180
195
|
// step, but set storage up so that they are on the second step when they return to the
|
|
@@ -188,25 +203,55 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
188
203
|
}
|
|
189
204
|
}
|
|
190
205
|
|
|
191
|
-
|
|
192
|
-
this.
|
|
193
|
-
|
|
206
|
+
handleFormSubmit(evt: Event) {
|
|
207
|
+
if (!this.formHandler || this.isJ2sFormInvalid) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
194
210
|
|
|
195
|
-
|
|
196
|
-
this.
|
|
197
|
-
|
|
211
|
+
evt.preventDefault(); // don't proceed automatically to next step
|
|
212
|
+
this._isFormSubmitting = true;
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
const formData = (this.template.querySelector("dw-j2s-form") as any)
|
|
216
|
+
?.formDataForDrm;
|
|
217
|
+
// For some countries, explicit approvals will be present; for others, it is implicitly assumed
|
|
218
|
+
if (typeof formData.Opt_In__c !== "boolean") {
|
|
219
|
+
formData.Opt_In__c = true;
|
|
220
|
+
}
|
|
221
|
+
if (typeof formData.Privacy_Statement__c !== "boolean") {
|
|
222
|
+
formData.Privacy_Statement__c = true;
|
|
223
|
+
}
|
|
224
|
+
console.log("would submit", JSON.stringify(formData, null, 2));
|
|
225
|
+
this.jumpToStepIndex(2);
|
|
226
|
+
} catch (ex) {
|
|
227
|
+
console.log(ex); // TODO
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
this._isFormSubmitting = false;
|
|
198
231
|
}
|
|
199
232
|
|
|
200
233
|
primaryActionHandler(evt: Event) {
|
|
201
|
-
|
|
234
|
+
const target = evt.target as HTMLButtonElement;
|
|
235
|
+
|
|
236
|
+
if (!target || target.disabled) {
|
|
202
237
|
evt.preventDefault();
|
|
203
238
|
return;
|
|
204
239
|
}
|
|
205
240
|
|
|
241
|
+
track(target, "custEv_ctaButtonClick", {
|
|
242
|
+
click_text: target.textContent,
|
|
243
|
+
element_title: this.stepsData[this.currentSequenceStep].stepTitle,
|
|
244
|
+
click_url:
|
|
245
|
+
this.stepsData[this.currentSequenceStep].primaryAction.link ||
|
|
246
|
+
"",
|
|
247
|
+
element_type: "button",
|
|
248
|
+
content_category: "cta"
|
|
249
|
+
});
|
|
250
|
+
|
|
206
251
|
if (!this.currentSequenceStep) {
|
|
207
252
|
this.handleGetStarted(evt);
|
|
208
|
-
} else if (this.currentSequenceStep ===
|
|
209
|
-
|
|
253
|
+
} else if (this.currentSequenceStep === 1) {
|
|
254
|
+
this.handleFormSubmit(evt);
|
|
210
255
|
}
|
|
211
256
|
}
|
|
212
257
|
|
|
@@ -236,19 +281,18 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
236
281
|
);
|
|
237
282
|
}
|
|
238
283
|
|
|
239
|
-
private
|
|
240
|
-
this.initialStepIndex =
|
|
241
|
-
(
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
) as unknown as StepSequence
|
|
245
|
-
)?.jumpToStep(0);
|
|
284
|
+
private jumpToStepIndex(stepIndex: number) {
|
|
285
|
+
this.initialStepIndex = stepIndex; // update sessionStorage value
|
|
286
|
+
((this.template.querySelector(
|
|
287
|
+
"dx-step-sequence"
|
|
288
|
+
) as unknown) as StepSequence)?.jumpToStep(stepIndex);
|
|
246
289
|
}
|
|
247
290
|
|
|
248
291
|
// HTML is received via config from DSC and should be static after initial render.
|
|
249
292
|
private updateStaticInnerHtml() {
|
|
250
|
-
const bodyMarkupContainers =
|
|
251
|
-
|
|
293
|
+
const bodyMarkupContainers = this.template.querySelectorAll(
|
|
294
|
+
"span.body-markup"
|
|
295
|
+
);
|
|
252
296
|
const secondaryActionMarkupContainers = this.template.querySelectorAll(
|
|
253
297
|
"span.secondary-action-markup"
|
|
254
298
|
);
|
|
@@ -287,7 +331,7 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
287
331
|
if (this.initialStepIndex > 0) {
|
|
288
332
|
// Page loaded on a step higher than the first, but we can't get data for the form;
|
|
289
333
|
// send user back to the start for now.
|
|
290
|
-
this.
|
|
334
|
+
this.jumpToStepIndex(0);
|
|
291
335
|
}
|
|
292
336
|
}
|
|
293
337
|
|
|
@@ -309,7 +353,7 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
309
353
|
if (!this.tbidUserInfo && this.initialStepIndex > 0) {
|
|
310
354
|
// login failed and the user was previously beyond the start step; need to send them
|
|
311
355
|
// back to the start:
|
|
312
|
-
this.
|
|
356
|
+
this.jumpToStepIndex(0);
|
|
313
357
|
}
|
|
314
358
|
|
|
315
359
|
this._isTbidLoading = false;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
<!-- For the names of the form fields, see: https://salesforce.quip.com/daInAFETbPGm -->
|
|
2
3
|
<form class="j2s-form">
|
|
3
4
|
<div class="form-row">
|
|
4
5
|
<dx-input
|
|
5
6
|
class="first-name-field"
|
|
6
7
|
label="First Name"
|
|
7
8
|
missing-error-message="Enter your first name"
|
|
8
|
-
name="
|
|
9
|
+
name="FirstName"
|
|
9
10
|
placeholder="Your first name"
|
|
10
11
|
required
|
|
11
12
|
validity-on-blur
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
class="last-name-field"
|
|
17
18
|
label="Last Name"
|
|
18
19
|
missing-error-message="Enter your last name"
|
|
19
|
-
name="
|
|
20
|
+
name="LastName"
|
|
20
21
|
placeholder="Your last name"
|
|
21
22
|
required
|
|
22
23
|
validity-on-blur
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
class="company-name-field"
|
|
30
31
|
label="Company Name"
|
|
31
32
|
missing-error-message="Enter your company name"
|
|
32
|
-
name="
|
|
33
|
+
name="Company__c"
|
|
33
34
|
placeholder="Your company name"
|
|
34
35
|
required
|
|
35
36
|
validity-on-blur
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
class="job-role-field"
|
|
42
43
|
label="Job Role"
|
|
43
44
|
message-when-value-missing="Select your job role"
|
|
44
|
-
name="
|
|
45
|
+
name="DRM_Role__c"
|
|
45
46
|
options={jobRoles}
|
|
46
47
|
placeholder="Select Job Role"
|
|
47
48
|
value={state.jobRole}
|
|
@@ -51,7 +52,7 @@
|
|
|
51
52
|
class="job-role-field"
|
|
52
53
|
label="Job Role"
|
|
53
54
|
message-when-value-missing="Select your job role"
|
|
54
|
-
name="
|
|
55
|
+
name="DRM_Role__c"
|
|
55
56
|
options={jobRoles}
|
|
56
57
|
placeholder="Select Job Role"
|
|
57
58
|
required
|
|
@@ -61,7 +62,7 @@
|
|
|
61
62
|
</div>
|
|
62
63
|
<div class="form-row">
|
|
63
64
|
<dx-input
|
|
64
|
-
name="
|
|
65
|
+
name="Email"
|
|
65
66
|
type="email"
|
|
66
67
|
placeholder="Your email address"
|
|
67
68
|
label="Email"
|
|
@@ -74,7 +75,7 @@
|
|
|
74
75
|
<dx-select
|
|
75
76
|
label="Country/Region"
|
|
76
77
|
message-when-value-missing="Select your country/region"
|
|
77
|
-
name="
|
|
78
|
+
name="MailingCountry"
|
|
78
79
|
options={countries}
|
|
79
80
|
placeholder="Select Country/Region"
|
|
80
81
|
required
|
|
@@ -84,7 +85,7 @@
|
|
|
84
85
|
</div>
|
|
85
86
|
<div class="form-row" if:true={isCountryWithReferralInput}>
|
|
86
87
|
<dx-input
|
|
87
|
-
name="
|
|
88
|
+
name="Referral_Email__c"
|
|
88
89
|
class="referral-email-field full-width"
|
|
89
90
|
label="If anyone has referred you, please share their Email ID below, with their consent."
|
|
90
91
|
type="email"
|
|
@@ -102,7 +103,7 @@
|
|
|
102
103
|
<div class="form-row" if:true={state.showMarketingText}>
|
|
103
104
|
<dx-checkbox
|
|
104
105
|
value="marketing-terms"
|
|
105
|
-
name="
|
|
106
|
+
name="Opt_In__c"
|
|
106
107
|
required
|
|
107
108
|
class="terms"
|
|
108
109
|
onchange={handleRequiredFieldUpdate}
|
|
@@ -127,7 +128,7 @@
|
|
|
127
128
|
<dx-checkbox
|
|
128
129
|
if:true={state.showLegalCheckbox}
|
|
129
130
|
value="legal-terms"
|
|
130
|
-
name="
|
|
131
|
+
name="Privacy_Statement__c"
|
|
131
132
|
required
|
|
132
133
|
class="terms"
|
|
133
134
|
onchange={handleRequiredFieldUpdate}
|
|
@@ -153,6 +154,7 @@
|
|
|
153
154
|
class="legal-terms no-checkbox"
|
|
154
155
|
></span>
|
|
155
156
|
</div>
|
|
157
|
+
<div if:true={recaptcha} class="captcha" lwc:dom="manual"></div>
|
|
156
158
|
</div>
|
|
157
159
|
</form>
|
|
158
160
|
</template>
|
|
@@ -31,13 +31,17 @@ export type J2sFormState = {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
34
|
-
private _didSetFormId = false;
|
|
35
|
-
private _isInitialRender = true;
|
|
36
|
-
private _incomingUserInfo: any = {}; // TODO typings
|
|
37
|
-
private _formMetadata: any = {}; // TODO typings
|
|
38
34
|
private _countriesJson = "";
|
|
39
35
|
private _countriesLookup: any = {}; // TODO typings
|
|
36
|
+
private _didRenderRecaptcha = false;
|
|
37
|
+
private _didSetFormId = false;
|
|
38
|
+
private _formMetadata: any = {}; // TODO typings
|
|
39
|
+
private _incomingUserInfo: any = {}; // TODO typings
|
|
40
|
+
private _isInitialRender = true;
|
|
41
|
+
|
|
42
|
+
@api drmRecaptchaSiteKey = "";
|
|
40
43
|
@api id = "";
|
|
44
|
+
private recaptcha: any = null;
|
|
41
45
|
@api referralText = "";
|
|
42
46
|
|
|
43
47
|
@api
|
|
@@ -72,6 +76,22 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
72
76
|
this._formMetadata = toJson(value);
|
|
73
77
|
}
|
|
74
78
|
|
|
79
|
+
@api
|
|
80
|
+
get formDataForDrm() {
|
|
81
|
+
// We should be able to just get the formData from the form automatically using `new FormData(theForm)`,
|
|
82
|
+
// but our custom form elements don't seem to implement what it is required for that currently. See:
|
|
83
|
+
// https://web.dev/more-capable-form-controls/#defining-a-form-associated-custom-element
|
|
84
|
+
const formData: any = {};
|
|
85
|
+
this.template.querySelectorAll("[name]").forEach((namedElement) => {
|
|
86
|
+
const typedElement = namedElement as HTMLInputElement;
|
|
87
|
+
formData[typedElement.name] =
|
|
88
|
+
typeof typedElement.checked === "boolean"
|
|
89
|
+
? typedElement.checked
|
|
90
|
+
: typedElement.value;
|
|
91
|
+
});
|
|
92
|
+
return formData;
|
|
93
|
+
}
|
|
94
|
+
|
|
75
95
|
private participatingCountryCodes = ["US", "CA", "IN"];
|
|
76
96
|
private countriesWithReferralInput = ["IN"];
|
|
77
97
|
private countriesWithRequiredJobRole = ["CA"];
|
|
@@ -118,6 +138,12 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
118
138
|
}
|
|
119
139
|
|
|
120
140
|
this.state = initialState as J2sFormState;
|
|
141
|
+
|
|
142
|
+
if ((window as any).grecaptcha) {
|
|
143
|
+
this.setRecaptcha();
|
|
144
|
+
} else {
|
|
145
|
+
window.addEventListener("recaptchaloaded", this.setRecaptcha);
|
|
146
|
+
}
|
|
121
147
|
}
|
|
122
148
|
|
|
123
149
|
renderedCallback(): void {
|
|
@@ -171,19 +197,31 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
171
197
|
this._didSetFormId = true;
|
|
172
198
|
this.template.querySelector("form")?.setAttribute("id", this.id);
|
|
173
199
|
}
|
|
174
|
-
}
|
|
175
200
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
201
|
+
if (!this._didRenderRecaptcha && this.recaptcha) {
|
|
202
|
+
this._didRenderRecaptcha = true;
|
|
203
|
+
this.recaptcha.render(this.template.querySelector(".captcha"), {
|
|
204
|
+
sitekey: this.drmRecaptchaSiteKey,
|
|
205
|
+
callback: (recaptchaToken: string) => {
|
|
206
|
+
console.log("got captcha", recaptchaToken);
|
|
207
|
+
},
|
|
208
|
+
"expired-callback": () => {},
|
|
209
|
+
"error-callback": (...args: any[]) => {
|
|
210
|
+
console.log("RECAPTCHA ERROR");
|
|
211
|
+
console.log(...args);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
180
214
|
}
|
|
181
215
|
}
|
|
182
216
|
|
|
183
|
-
|
|
184
|
-
|
|
217
|
+
disconnectedCallback() {
|
|
218
|
+
window.removeEventListener("recaptchaloaded", this.setRecaptcha);
|
|
185
219
|
}
|
|
186
220
|
|
|
221
|
+
setRecaptcha = () => {
|
|
222
|
+
this.recaptcha = (window as any).grecaptcha;
|
|
223
|
+
};
|
|
224
|
+
|
|
187
225
|
handleRequiredFieldUpdate() {
|
|
188
226
|
const isFormNowValid = this.checkValidity();
|
|
189
227
|
if (this.state.isFormValid !== isFormNowValid) {
|
|
@@ -220,6 +258,17 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
220
258
|
?.classList.toggle("hidden");
|
|
221
259
|
}
|
|
222
260
|
|
|
261
|
+
private updateInnerHtml(selector: string, html: string): void {
|
|
262
|
+
const element = this.template.querySelector(selector);
|
|
263
|
+
if (element) {
|
|
264
|
+
element.innerHTML = html;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private isParticipatingCountry(country: string) {
|
|
269
|
+
return this.participatingCountryCodes.includes(country);
|
|
270
|
+
}
|
|
271
|
+
|
|
223
272
|
private checkValidity() {
|
|
224
273
|
return (
|
|
225
274
|
this.isParticipatingCountry(this.state.country) &&
|