@salesforcedevs/dx-components 1.3.54 → 1.3.56

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/LICENSE ADDED
@@ -0,0 +1,12 @@
1
+ Copyright (c) 2020, Salesforce.com, Inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+
8
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
+
10
+ * Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/dx-components",
3
- "version": "1.3.54",
3
+ "version": "1.3.56",
4
4
  "description": "DX Lightning web components",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -39,5 +39,6 @@
39
39
  "@types/vimeo__player": "^2.16.2",
40
40
  "eventsourcemock": "^2.0.0",
41
41
  "luxon": "^3.1.0"
42
- }
42
+ },
43
+ "gitHead": "8270531b83c9d652a58a7e5cd8088c0ec554b649"
43
44
  }
@@ -10,6 +10,7 @@
10
10
  label={label}
11
11
  target={target}
12
12
  title={title}
13
+ content-type="blogs"
13
14
  >
14
15
  <dx-formatted-date-time
15
16
  if:true={_datetime}
@@ -19,11 +19,15 @@ export default class CardContent extends LightningElement {
19
19
  @api target?: string | null = null;
20
20
  @api title!: string;
21
21
  @api hrefClick: any = null;
22
+ @api contentType: string | null = null;
22
23
  @api
23
24
  get authors() {
24
25
  if (this._authors && this._authors.length) {
25
26
  return this._authors!.map((author, index) => ({
26
- ...author,
27
+ ...{
28
+ ...author,
29
+ href: author.href || this.getAuthorLink(author.name)
30
+ },
27
31
  imgSrc: author.image_src,
28
32
  key: index
29
33
  }));
@@ -87,4 +91,10 @@ export default class CardContent extends LightningElement {
87
91
  this.hrefClick(e);
88
92
  }
89
93
  }
94
+
95
+ private getAuthorLink(name: any): string {
96
+ return `/content-archive?authors=${name.split(" ").join("-").trim()}${
97
+ this.contentType ? `&content-type=${this.contentType}` : ``
98
+ }`;
99
+ }
90
100
  }
@@ -41,6 +41,11 @@ const enum PlatformEventsType {
41
41
  UserMerge = "UserMerge"
42
42
  }
43
43
 
44
+ // TODO: We probably should rewrite the logic of this component once the new identity stuff is released,
45
+ // especially because SSO should work in all browsers at that point, and we won't need to do any weird
46
+ // checking for the presence of SFIDWidget (and all the associated pain from trying to "time" the triggering of login
47
+ // events due to logins coming via two distinct routes in Chrome).
48
+
44
49
  // This component handles the core Salesforce OAuth 2.0 flow used by TBID for login, rendering a
45
50
  // simple Login button or avatar icon depending on login status. It should be reusable in any case
46
51
  // where TBID login is needed.
@@ -56,6 +61,7 @@ export default class TbidAvatarButton extends LightningElement {
56
61
  private eventSource?: EventSource;
57
62
  private _isRequestingUserInfo = false;
58
63
  private _didReceiveUserInfo = false;
64
+ private _didDispatchLoginSuccess = false;
59
65
 
60
66
  // _didReceiveUserInfo is a proxy for "isLoggedIn" because we only want to show the UI corresponding
61
67
  // to logged-in state when user info has been received (avoids flashes of weird content)
@@ -155,8 +161,12 @@ export default class TbidAvatarButton extends LightningElement {
155
161
  // then this method waits a maximum of 1 second for the widget to finish logging in. If it does
156
162
  // *not* respond quickly, the method resolves early so that we can stop waiting pointlessly.
157
163
  private waitForSFIDWidget = async () => {
164
+ const millisecondsFor30fps = 33;
158
165
  const widgetNotAlivePromise = new Promise<boolean>((resolve) => {
159
- const timeoutId = setTimeout(() => resolve(false), 100);
166
+ const timeoutId = setTimeout(
167
+ () => resolve(false),
168
+ 5 * millisecondsFor30fps // give SFIDWidget roughly 5 chances to load
169
+ );
160
170
  window.SFIDWidget?.isAlive({
161
171
  // If the widget responds as expected, this promise will fail to resolve and thus
162
172
  // we will continue to wait on the other promise, below.
@@ -165,7 +175,7 @@ export default class TbidAvatarButton extends LightningElement {
165
175
  });
166
176
  const widgetLoggedInPromise = pollUntil(
167
177
  () => Boolean(window.SFIDWidget?.openid_response),
168
- 100,
178
+ millisecondsFor30fps,
169
179
  1000
170
180
  );
171
181
  const success = await Promise.race([
@@ -279,12 +289,13 @@ export default class TbidAvatarButton extends LightningElement {
279
289
  // on SSO login. For some reason, the user info on SSO login lacks the user's photo URLs, so we
280
290
  // have to re-request it. Maybe something to bring up with the TBID team.
281
291
  await this.requestUserInfo();
282
- this.dispatchLoginSuccess();
292
+ this.dispatchLoginSuccess(true);
283
293
  } else if (
284
294
  tokenResponse.status === 409 &&
285
- !this._didReceiveUserInfo
295
+ !this._didReceiveUserInfo &&
296
+ !this._isRequestingUserInfo // don't duplicate requests when we already have this token and a request is on-going
286
297
  ) {
287
- // Valid token received, but we still need to grab userInfo. This could happen in certain edge cases
298
+ // Valid but duplicate token received, but we still need to grab userInfo. This could happen in certain edge cases
288
299
  // involving "seamless SSO" (e.g., you might be sitting on our page in more than one tab, then log in
289
300
  // on one of them; in that case, our back-end will receive the token from one tab, end up _rejecting_ it
290
301
  // as a duplicate on other tabs where the login event occurs, and yet still need to request user info
@@ -384,11 +395,6 @@ export default class TbidAvatarButton extends LightningElement {
384
395
  };
385
396
 
386
397
  private requestUserInfo = async () => {
387
- if (this._isRequestingUserInfo) {
388
- // prevent duplicate requests
389
- return;
390
- }
391
-
392
398
  this._isRequestingUserInfo = true;
393
399
 
394
400
  try {
@@ -422,12 +428,16 @@ export default class TbidAvatarButton extends LightningElement {
422
428
  );
423
429
  };
424
430
 
425
- private dispatchLoginSuccess = () => {
426
- this.dispatchEvent(
427
- new CustomEvent("tbidloginsuccess", {
428
- bubbles: true
429
- })
430
- );
431
+ private dispatchLoginSuccess = (receivedNewToken = false) => {
432
+ // Receiving a new token should be treated as a new (SSO) login.
433
+ if (!this._didDispatchLoginSuccess || receivedNewToken) {
434
+ this._didDispatchLoginSuccess = true;
435
+ this.dispatchEvent(
436
+ new CustomEvent("tbidloginsuccess", {
437
+ bubbles: true
438
+ })
439
+ );
440
+ }
431
441
  };
432
442
 
433
443
  private dispatchLogoutSuccess = () => {