@salesforcedevs/dw-components 1.3.157-canary.5 → 1.3.162

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.
@@ -1,348 +0,0 @@
1
- import { toJson } from "dxUtils/normalizers";
2
- import { stateMap } from "dwUtils/forms";
3
- import { api } from "lwc";
4
- import debounce from "debounce";
5
- import { LightningElementWithState } from "dxBaseElements/lightningElementWithState";
6
- import { DrmFormData } from "dw/j2sCardSequence";
7
-
8
- // Hard-coding for now because we can't get information about an endpoint for this
9
- const tbidValidRoles = [
10
- "Developer",
11
- "Administrator",
12
- "Architect",
13
- "Sales Representative / Manager",
14
- "Marketer",
15
- "Service Agent / Supervisor",
16
- "Data Analyst",
17
- "Consultant",
18
- "Business Operations Manager",
19
- "Designer",
20
- "Educator",
21
- "Student",
22
- "Executive",
23
- "Product Manager"
24
- ];
25
-
26
- export type J2sFormState = DrmFormData & {
27
- legalText: string;
28
- marketingText: string;
29
- learnMore: string;
30
- showLegalCheckbox: boolean;
31
- showMarketingText: boolean;
32
- isFormValid: boolean;
33
- };
34
-
35
- const debounceCallback = (callback: Function) =>
36
- debounce(callback, 1000 / 15 /* 15fps roughly */);
37
-
38
- export default class J2sForm extends LightningElementWithState<J2sFormState> {
39
- private _countriesJson = "";
40
- private _countriesLookup: any = {}; // TODO typings
41
- private _didSetFormId = false;
42
- private _isInitialRender = true;
43
- private _recaptchaToken = "";
44
-
45
- @api formMetadata: any = {};
46
- @api id = "";
47
- @api incomingUserInfo = {} as DrmFormData;
48
- @api referralText = "";
49
-
50
- @api
51
- get countries() {
52
- return this._countriesJson || "[]";
53
- }
54
- set countries(value: string) {
55
- this._countriesJson = value;
56
-
57
- // Store a lookup table of country data by value so that we don't have to loop all the time
58
- const countries = toJson(value);
59
- const countriesLookup: any = {};
60
- countries.forEach((country: any) => {
61
- countriesLookup[country.value] = country;
62
- });
63
- this._countriesLookup = countriesLookup;
64
- }
65
-
66
- @api
67
- get formDataForDrm(): Partial<DrmFormData> {
68
- // We should be able to just get the formData from the form automatically using `new FormData(theForm)`,
69
- // but our custom form elements don't seem to implement what it is required for that currently. See:
70
- // https://web.dev/more-capable-form-controls/#defining-a-form-associated-custom-element
71
- const formData: any = {};
72
- this.template
73
- .querySelectorAll("form [name]")
74
- .forEach((namedElement) => {
75
- const typedElement = namedElement as HTMLInputElement;
76
- formData[typedElement.name] =
77
- typeof typedElement.checked === "boolean"
78
- ? typedElement.checked
79
- : typedElement.value;
80
- });
81
- return formData;
82
- }
83
-
84
- @api
85
- get recaptchaToken() {
86
- return this._recaptchaToken;
87
- }
88
- set recaptchaToken(value: string) {
89
- this._recaptchaToken = value;
90
- if (!this._isInitialRender) {
91
- // Treat recaptcha checkbox as a required form field even though not technically marked as such:
92
- this.setState({
93
- isFormValid: this.checkValidity()
94
- });
95
- }
96
- }
97
-
98
- private participatingCountryCodes = ["US", "CA", "IN"];
99
- private countriesWithReferralInput = ["IN"];
100
- private requiredFormFields: HTMLElement[] = [];
101
- private showSubmitFailureAlert = false;
102
-
103
- get isNotParticipatingCountry() {
104
- return !this.isParticipatingCountry(this.state.MailingCountry);
105
- }
106
-
107
- get isCountryWithReferralInput() {
108
- return this.countriesWithReferralInput.includes(
109
- this.state.MailingCountry
110
- );
111
- }
112
-
113
- get isSalesforceEmployee() {
114
- return this.state.RelationshipToSalesforce === "Salesforce Employee";
115
- }
116
-
117
- get notAvailableAlertInfo() {
118
- return this.formMetadata.notAvailableAlertInfo;
119
- }
120
-
121
- get salesforceEmployeeAlertInfo() {
122
- return this.formMetadata.salesforceEmployeeAlertInfo;
123
- }
124
-
125
- get formSubmitFailureAlertInfo() {
126
- return this.formMetadata.formSubmitFailureAlertInfo;
127
- }
128
-
129
- get jobRoles() {
130
- return tbidValidRoles.map((role) => ({
131
- label: role,
132
- value: role
133
- }));
134
- }
135
-
136
- get showStateProvince(): boolean {
137
- return this.state.MailingCountry in stateMap;
138
- }
139
-
140
- get states(): { id: string; label: string; value: string }[] {
141
- return (
142
- stateMap[this.state.MailingCountry as keyof typeof stateMap] || []
143
- );
144
- }
145
-
146
- connectedCallback() {
147
- const initialState: Partial<J2sFormState> = {
148
- ...this.incomingUserInfo,
149
- isFormValid: false,
150
- showMarketingText: true
151
- };
152
- const initialCountry = initialState.MailingCountry;
153
- const initialCountryData =
154
- initialCountry && this._countriesLookup[initialCountry];
155
- if (initialCountryData) {
156
- initialState.showLegalCheckbox =
157
- initialCountryData.showLegalCheckbox;
158
- initialState.showMarketingText =
159
- initialCountryData.showMarketingText;
160
- initialState.legalText = initialCountryData.legalText;
161
- initialState.marketingText = initialCountryData.marketingText;
162
- initialState.learnMore = initialCountryData.learnMore;
163
- }
164
-
165
- this.state = initialState as J2sFormState;
166
- }
167
-
168
- renderedCallback(): void {
169
- if (this._isInitialRender) {
170
- this.updateInnerHtml("span.j2s-terms", this.formMetadata.j2sTerms);
171
- this._isInitialRender = false;
172
- }
173
-
174
- if (
175
- this.state.MailingCountry &&
176
- this.state.MailingCountry !== this.prevState.MailingCountry
177
- ) {
178
- // Re-render new country's terms
179
- this.updateInnerHtml(
180
- "span.marketing-terms",
181
- this.state.marketingText
182
- );
183
- this.updateInnerHtml("span.legal-terms", this.state.legalText);
184
- if (this.state.learnMore) {
185
- this.updateInnerHtml(
186
- "span.legal-terms-learn-more",
187
- this.state.learnMore
188
- );
189
- } else {
190
- this.updateInnerHtml("span.legal-terms-learn-more", "");
191
- this.template
192
- .querySelector(".legal-terms-learn-more")
193
- ?.classList.add("hidden");
194
- }
195
- }
196
-
197
- if (this.state.isFormValid !== this.prevState.isFormValid) {
198
- this.dispatchEvent(
199
- new CustomEvent("formvaliditychange", {
200
- detail: {
201
- isValid: this.state.isFormValid
202
- },
203
- bubbles: true,
204
- composed: true
205
- })
206
- );
207
- }
208
-
209
- this.requiredFormFields = Array.from(
210
- this.template.querySelectorAll("[required]")
211
- );
212
-
213
- if (this.id && !this._didSetFormId) {
214
- this._didSetFormId = true;
215
- this.template.querySelector("form")?.setAttribute("id", this.id);
216
- }
217
- }
218
-
219
- handleLearnMore() {
220
- this.template
221
- .querySelector(".legal-terms-learn-more")
222
- ?.classList.toggle("hidden");
223
- }
224
-
225
- debouncedFormFieldChangeHandler = debounceCallback(
226
- (targetName: string, value: any, isRequiredField = false) => {
227
- if (targetName === "MailingCountry") {
228
- this.handleCountryChange(value);
229
- } else {
230
- const nextState: Partial<J2sFormState> = {};
231
- if (targetName) {
232
- nextState[targetName as keyof J2sFormState] = value;
233
- }
234
- if (isRequiredField) {
235
- nextState.isFormValid = this.checkValidity();
236
- }
237
- this.setState(nextState);
238
- }
239
-
240
- this.unsetSubmitFailure();
241
- }
242
- );
243
-
244
- handleFormFieldChange = (evt: CustomEvent) => {
245
- // Event target information must be read prior to debouncing; the target is gone after the debounce.
246
- const { target = {}, detail } = evt;
247
- const { name: targetName, required: isRequiredField } =
248
- target as HTMLInputElement;
249
- const value =
250
- typeof detail === "string"
251
- ? detail
252
- : typeof detail.checked === "boolean"
253
- ? detail.checked
254
- : detail.value;
255
-
256
- // Perform the real work after a debounce, in order to prevent unnecessary work on rapid form value changes:
257
- this.debouncedFormFieldChangeHandler(
258
- targetName,
259
- value,
260
- isRequiredField
261
- );
262
- };
263
-
264
- @api
265
- notifySubmitFailure(formSubmissionFailureState: Partial<DrmFormData>) {
266
- this.showSubmitFailureAlert = true;
267
- // After form submission failure, restore at most the following values to the form:
268
- const {
269
- FirstName,
270
- LastName,
271
- Email,
272
- MailingCountry,
273
- MailingState,
274
- Company__c,
275
- DRM_Role__c,
276
- Referral_Email__c
277
- } = formSubmissionFailureState;
278
- this.setState({
279
- FirstName,
280
- LastName,
281
- Email,
282
- MailingCountry,
283
- MailingState,
284
- Company__c,
285
- DRM_Role__c,
286
- Referral_Email__c
287
- });
288
- }
289
-
290
- private unsetSubmitFailure() {
291
- if (this.showSubmitFailureAlert) {
292
- this.showSubmitFailureAlert = false;
293
- }
294
- }
295
-
296
- private handleCountryChange(countryCode: string) {
297
- const countryData = this._countriesLookup[countryCode];
298
-
299
- this.setState({
300
- MailingCountry: countryCode,
301
- learnMore: countryData.learnMore,
302
- legalText: countryData.legalText,
303
- marketingText: countryData.marketingText,
304
- showLegalCheckbox: countryData.showLegalCheckbox,
305
- showMarketingText: countryData.showMarketingText
306
- });
307
-
308
- this.dispatchEvent(
309
- new CustomEvent("countrychange", {
310
- bubbles: true,
311
- composed: true,
312
- detail: countryCode
313
- })
314
- );
315
-
316
- // Because updating the country can update the required fields, we need to re-set form
317
- // validity _after_ render
318
- requestAnimationFrame(() =>
319
- this.setState({
320
- isFormValid: this.checkValidity()
321
- })
322
- );
323
- }
324
-
325
- private updateInnerHtml(selector: string, html: string): void {
326
- const element = this.template.querySelector(selector);
327
- if (element) {
328
- element.innerHTML = html;
329
- }
330
- }
331
-
332
- private isParticipatingCountry(country: string) {
333
- return this.participatingCountryCodes.includes(country);
334
- }
335
-
336
- private checkValidity() {
337
- return (
338
- Boolean(this.recaptchaToken) &&
339
- !this.isSalesforceEmployee &&
340
- this.isParticipatingCountry(this.state.MailingCountry) &&
341
- this.requiredFormFields.every(
342
- (requiredFormField) =>
343
- // @ts-ignore
344
- requiredFormField.checkValidity?.() === true
345
- )
346
- );
347
- }
348
- }