@salesforcedevs/docs-components 1.28.5-redoc-alpha → 1.28.5-redoc-alpha2
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 +1 -1
- package/src/modules/doc/amfReference/amfReference.ts +60 -26
- package/src/modules/doc/amfReference/types.ts +2 -5
- package/src/modules/doc/redocReference/redocReference.css +0 -24
- package/src/modules/doc/redocReference/redocReference.html +0 -16
- package/src/modules/doc/redocReference/redocReference.ts +99 -6
package/package.json
CHANGED
|
@@ -38,6 +38,7 @@ type NavigationItem = {
|
|
|
38
38
|
isExpanded: boolean;
|
|
39
39
|
children: ParsedMarkdownTopic[];
|
|
40
40
|
isChildrenLoading: boolean;
|
|
41
|
+
renderWith?: string;
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
export default class AmfReference extends LightningElement {
|
|
@@ -147,6 +148,19 @@ export default class AmfReference extends LightningElement {
|
|
|
147
148
|
|
|
148
149
|
this._amfConfigList = this._referenceSetConfig.refList || [];
|
|
149
150
|
|
|
151
|
+
// If the framework didn't tag the reference, infer redoc rendering
|
|
152
|
+
// from the config shape: spec-based references with no AMF URL are
|
|
153
|
+
// shipped as raw spec sources for Redoc to render directly.
|
|
154
|
+
this._amfConfigList.forEach((amfConfig) => {
|
|
155
|
+
if (
|
|
156
|
+
!amfConfig.renderWith &&
|
|
157
|
+
amfConfig.referenceType !== REFERENCE_TYPES.markdown &&
|
|
158
|
+
!amfConfig.amf
|
|
159
|
+
) {
|
|
160
|
+
amfConfig.renderWith = RENDER_WITH.redoc;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
150
164
|
this._amfConfigList.forEach((amfConfig) => {
|
|
151
165
|
this._amfConfigMap.set(amfConfig.id, amfConfig);
|
|
152
166
|
});
|
|
@@ -252,6 +266,7 @@ export default class AmfReference extends LightningElement {
|
|
|
252
266
|
|
|
253
267
|
_boundOnApiNavigationChanged;
|
|
254
268
|
_boundUpdateSelectedItemFromUrlQuery;
|
|
269
|
+
_boundOnPageShow;
|
|
255
270
|
|
|
256
271
|
constructor() {
|
|
257
272
|
super();
|
|
@@ -260,6 +275,7 @@ export default class AmfReference extends LightningElement {
|
|
|
260
275
|
this.onApiNavigationChanged.bind(this);
|
|
261
276
|
this._boundUpdateSelectedItemFromUrlQuery =
|
|
262
277
|
this.updateSelectedItemFromUrlQuery.bind(this);
|
|
278
|
+
this._boundOnPageShow = this.onPageShow.bind(this);
|
|
263
279
|
}
|
|
264
280
|
|
|
265
281
|
connectedCallback(): void {
|
|
@@ -271,6 +287,7 @@ export default class AmfReference extends LightningElement {
|
|
|
271
287
|
"popstate",
|
|
272
288
|
this._boundUpdateSelectedItemFromUrlQuery
|
|
273
289
|
);
|
|
290
|
+
window.addEventListener("pageshow", this._boundOnPageShow);
|
|
274
291
|
}
|
|
275
292
|
|
|
276
293
|
disconnectedCallback(): void {
|
|
@@ -282,6 +299,22 @@ export default class AmfReference extends LightningElement {
|
|
|
282
299
|
"popstate",
|
|
283
300
|
this._boundUpdateSelectedItemFromUrlQuery
|
|
284
301
|
);
|
|
302
|
+
window.removeEventListener("pageshow", this._boundOnPageShow);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* On bfcache restore, reset the sidebar selection so the tree re-syncs
|
|
307
|
+
* its highlighted tile with the current URL.
|
|
308
|
+
*/
|
|
309
|
+
protected onPageShow(event: PageTransitionEvent): void {
|
|
310
|
+
if (!event.persisted) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const currentPath = window.location.pathname;
|
|
314
|
+
this.selectedSidebarValue = "";
|
|
315
|
+
Promise.resolve().then(() => {
|
|
316
|
+
this.selectedSidebarValue = currentPath;
|
|
317
|
+
});
|
|
285
318
|
}
|
|
286
319
|
|
|
287
320
|
renderedCallback(): void {
|
|
@@ -500,32 +533,32 @@ export default class AmfReference extends LightningElement {
|
|
|
500
533
|
for (const [index, amfConfig] of this._amfConfigList.entries()) {
|
|
501
534
|
let navItemChildren = [] as ParsedMarkdownTopic[];
|
|
502
535
|
let isChildrenLoading = false;
|
|
503
|
-
if (amfConfig.renderWith
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
536
|
+
if (amfConfig.renderWith !== RENDER_WITH.redoc) {
|
|
537
|
+
if (amfConfig.referenceType !== REFERENCE_TYPES.markdown) {
|
|
538
|
+
if (amfConfig.isSelected) {
|
|
539
|
+
const amfPromise = this.fetchAmf(amfConfig).then(
|
|
540
|
+
(amfJson) => {
|
|
541
|
+
this.updateModel(amfConfig.id, amfJson);
|
|
542
|
+
this.assignNavigationItemsFromAmf(
|
|
543
|
+
amfConfig,
|
|
544
|
+
index
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
);
|
|
548
|
+
this.amfFetchPromiseMap[amfConfig.id] = amfPromise;
|
|
549
|
+
}
|
|
550
|
+
isChildrenLoading = true;
|
|
551
|
+
} else {
|
|
552
|
+
const isExpandChildrenEnabled =
|
|
553
|
+
this.isExpandChildrenEnabled(amfConfig.id);
|
|
554
|
+
// check whether we should expand all the child nodes, this is required for Coveo to crawl.
|
|
555
|
+
if (isExpandChildrenEnabled) {
|
|
556
|
+
this.expandChildrenForMarkdownReferences(
|
|
557
|
+
amfConfig.topic!.children
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
navItemChildren = amfConfig.topic!.children;
|
|
527
561
|
}
|
|
528
|
-
navItemChildren = amfConfig.topic!.children;
|
|
529
562
|
}
|
|
530
563
|
// store nav items for each spec in order
|
|
531
564
|
navAmfOrder[index] = {
|
|
@@ -535,7 +568,8 @@ export default class AmfReference extends LightningElement {
|
|
|
535
568
|
amfConfig.isSelected ||
|
|
536
569
|
this.isExpandChildrenEnabled(amfConfig.id),
|
|
537
570
|
children: navItemChildren,
|
|
538
|
-
isChildrenLoading
|
|
571
|
+
isChildrenLoading,
|
|
572
|
+
renderWith: amfConfig.renderWith
|
|
539
573
|
};
|
|
540
574
|
this.parentReferenceUrls.push(amfConfig.href);
|
|
541
575
|
}
|
|
@@ -80,15 +80,12 @@ export interface AmfConfig {
|
|
|
80
80
|
topic?: ParsedMarkdownTopic;
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
84
|
-
* When "redoc", spec-based references are rendered with Redoc instead of
|
|
85
|
-
* the AMF-based topic view. Other values fall back to the default pipeline.
|
|
83
|
+
* Required for rendering the arrow on LNB
|
|
86
84
|
*/
|
|
87
85
|
renderWith?: string;
|
|
88
86
|
|
|
89
87
|
/**
|
|
90
|
-
* Spec URL consumed by alternate renderers (e.g. Redoc).
|
|
91
|
-
* references this is the OpenAPI document URL.
|
|
88
|
+
* Spec URL consumed by alternate renderers (e.g. Redoc, Mulesoft).
|
|
92
89
|
*/
|
|
93
90
|
source?: string;
|
|
94
91
|
}
|
|
@@ -5,27 +5,3 @@
|
|
|
5
5
|
var(--dx-g-spacing-xl)
|
|
6
6
|
);
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
.redoc-project-header {
|
|
10
|
-
display: flex;
|
|
11
|
-
flex-direction: column;
|
|
12
|
-
gap: var(--dx-g-spacing-2xs);
|
|
13
|
-
padding: var(--dx-g-spacing-s) var(--dx-g-spacing-m);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.redoc-project-back {
|
|
17
|
-
display: inline-flex;
|
|
18
|
-
align-items: center;
|
|
19
|
-
gap: var(--dx-g-spacing-xs);
|
|
20
|
-
color: var(--dx-g-blue-vibrant-50);
|
|
21
|
-
text-decoration: none;
|
|
22
|
-
width: fit-content;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.redoc-project-back:hover .redoc-project-title {
|
|
26
|
-
text-decoration: underline;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.redoc-spec-title {
|
|
30
|
-
margin: 0;
|
|
31
|
-
}
|
|
@@ -8,22 +8,6 @@
|
|
|
8
8
|
></dx-error>
|
|
9
9
|
</template>
|
|
10
10
|
<template lwc:else>
|
|
11
|
-
<div lwc:if={showRedocHeader} class="redoc-project-header">
|
|
12
|
-
<a
|
|
13
|
-
lwc:if={projectTitle}
|
|
14
|
-
class="redoc-project-back"
|
|
15
|
-
href="#"
|
|
16
|
-
onclick={onBackClick}
|
|
17
|
-
>
|
|
18
|
-
<dx-icon sprite="utility" symbol="back" size="small"></dx-icon>
|
|
19
|
-
<span class="redoc-project-title dx-text-body-4">
|
|
20
|
-
{projectTitle}
|
|
21
|
-
</span>
|
|
22
|
-
</a>
|
|
23
|
-
<h2 lwc:if={specTitle} class="redoc-spec-title dx-text-display-6">
|
|
24
|
-
{specTitle}
|
|
25
|
-
</h2>
|
|
26
|
-
</div>
|
|
27
11
|
<slot></slot>
|
|
28
12
|
</template>
|
|
29
13
|
</template>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { createElement, LightningElement, api } from "lwc";
|
|
3
3
|
import DocPhase from "doc/phase";
|
|
4
4
|
import DxFooter from "dx/footer";
|
|
5
|
+
import DxIcon from "dx/icon";
|
|
5
6
|
import SprigSurvey from "doc/sprigSurvey";
|
|
6
7
|
import { throttle } from "throttle-debounce";
|
|
7
8
|
import { pollUntil } from "dxUtils/async";
|
|
@@ -14,11 +15,19 @@ declare global {
|
|
|
14
15
|
|
|
15
16
|
declare const Sprig: (eventType: string, eventName: string) => void;
|
|
16
17
|
|
|
18
|
+
type ReferenceTopic = {
|
|
19
|
+
link?: { href?: string };
|
|
20
|
+
children?: ReferenceTopic[];
|
|
21
|
+
};
|
|
22
|
+
|
|
17
23
|
type ReferenceItem = {
|
|
18
24
|
source: string;
|
|
19
25
|
href: string;
|
|
26
|
+
title?: string;
|
|
20
27
|
isSelected?: boolean;
|
|
21
28
|
docPhase?: string | null;
|
|
29
|
+
referenceType?: string;
|
|
30
|
+
topic?: ReferenceTopic;
|
|
22
31
|
};
|
|
23
32
|
|
|
24
33
|
type ReferenceConfig = {
|
|
@@ -77,21 +86,34 @@ export default class RedocReference extends LightningElement {
|
|
|
77
86
|
*/
|
|
78
87
|
@api projectTitle: string | null = null;
|
|
79
88
|
|
|
89
|
+
private _specTitle: string | null = null;
|
|
90
|
+
|
|
80
91
|
/** Title of the currently selected spec, shown beneath the project title. */
|
|
81
|
-
@api
|
|
92
|
+
@api
|
|
93
|
+
get specTitle(): string | null {
|
|
94
|
+
return this._specTitle;
|
|
95
|
+
}
|
|
82
96
|
|
|
97
|
+
set specTitle(value: string | null) {
|
|
98
|
+
this._specTitle = value || this.getSelectedReference()?.title || null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Whether to show the project header (only for multi-spec reference sets).
|
|
103
|
+
*/
|
|
83
104
|
get showRedocHeader(): boolean {
|
|
84
|
-
|
|
105
|
+
const refCount = this._referenceConfig?.refList?.length ?? 0;
|
|
106
|
+
const isMultiSpecSet = refCount > 1;
|
|
107
|
+
return isMultiSpecSet && !!(this.projectTitle || this.specTitle);
|
|
85
108
|
}
|
|
86
109
|
|
|
87
110
|
/**
|
|
88
|
-
* Navigates back to
|
|
89
|
-
* project-title back link rendered above the Redoc UI.
|
|
111
|
+
* Navigates back to reference doc.
|
|
90
112
|
*/
|
|
91
|
-
private onBackClick(event: Event): void {
|
|
113
|
+
private onBackClick = (event: Event): void => {
|
|
92
114
|
event.preventDefault();
|
|
93
115
|
window.history.back();
|
|
94
|
-
}
|
|
116
|
+
};
|
|
95
117
|
|
|
96
118
|
/** When origin is provided, pass it to the footer; otherwise use dx-footer's default. */
|
|
97
119
|
get effectiveFooterOrigin(): string {
|
|
@@ -332,6 +354,9 @@ export default class RedocReference extends LightningElement {
|
|
|
332
354
|
|
|
333
355
|
this.appendFooterItems(apiContentDiv);
|
|
334
356
|
|
|
357
|
+
// Inject the multi-spec project header into Redoc's left menu only.
|
|
358
|
+
this.insertProjectHeaderInMenu(redocContainer);
|
|
359
|
+
|
|
335
360
|
// Wait for footer to be rendered before updating styles
|
|
336
361
|
requestAnimationFrame(() => {
|
|
337
362
|
this.updateRedocThirdColumnStyle(redocContainer);
|
|
@@ -344,6 +369,74 @@ export default class RedocReference extends LightningElement {
|
|
|
344
369
|
}
|
|
345
370
|
}
|
|
346
371
|
|
|
372
|
+
/**
|
|
373
|
+
* Inserts the project header into Redoc for multi-spec reference sets.
|
|
374
|
+
*/
|
|
375
|
+
private insertProjectHeaderInMenu(redocContainer: HTMLElement): void {
|
|
376
|
+
if (!this.showRedocHeader) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
for (const selector of [".menu-content", ".api-content"]) {
|
|
381
|
+
const target = redocContainer.querySelector<HTMLElement>(selector);
|
|
382
|
+
if (
|
|
383
|
+
!target ||
|
|
384
|
+
target.querySelector(":scope > .redoc-project-header")
|
|
385
|
+
) {
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
target.insertBefore(
|
|
389
|
+
this.buildProjectHeaderDom(),
|
|
390
|
+
target.firstChild
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Builds a fresh project-title/spec-title header DOM node.
|
|
397
|
+
*/
|
|
398
|
+
private buildProjectHeaderDom(): HTMLElement {
|
|
399
|
+
const wrapper = document.createElement("div");
|
|
400
|
+
wrapper.className = "redoc-project-header";
|
|
401
|
+
|
|
402
|
+
/* TODO:
|
|
403
|
+
* Uncomment when doc-header is dropped with Vision state UX.
|
|
404
|
+
* if(this.projectTitle) {
|
|
405
|
+
*/
|
|
406
|
+
if (this.specTitle) {
|
|
407
|
+
const backLink = document.createElement("a");
|
|
408
|
+
backLink.className = "redoc-project-back";
|
|
409
|
+
backLink.href = "#";
|
|
410
|
+
backLink.addEventListener("click", this.onBackClick);
|
|
411
|
+
|
|
412
|
+
const icon = createElement("dx-icon", { is: DxIcon });
|
|
413
|
+
Object.assign(icon, {
|
|
414
|
+
sprite: "utility",
|
|
415
|
+
symbol: "back",
|
|
416
|
+
size: "medium"
|
|
417
|
+
});
|
|
418
|
+
icon.classList.add("redoc-project-back-arrow");
|
|
419
|
+
|
|
420
|
+
const label = document.createElement("span");
|
|
421
|
+
label.className = "redoc-project-title";
|
|
422
|
+
label.textContent = this.specTitle;
|
|
423
|
+
|
|
424
|
+
backLink.appendChild(icon);
|
|
425
|
+
backLink.appendChild(label);
|
|
426
|
+
wrapper.appendChild(backLink);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// TODO: Uncomment when we we have vision state UX with no doc-header
|
|
430
|
+
// if (this.specTitle) {
|
|
431
|
+
// const specEl = document.createElement("h2");
|
|
432
|
+
// specEl.className = "redoc-spec-title";
|
|
433
|
+
// specEl.textContent = this.specTitle;
|
|
434
|
+
// wrapper.appendChild(specEl);
|
|
435
|
+
// }
|
|
436
|
+
|
|
437
|
+
return wrapper;
|
|
438
|
+
}
|
|
439
|
+
|
|
347
440
|
// Waits for Redoc's API content element to be rendered
|
|
348
441
|
private async waitForApiContent(
|
|
349
442
|
container: HTMLElement
|