@salesforcedevs/docs-components 1.17.5-edit → 1.17.5-search-alpha1
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/lwc.config.json +0 -1
- package/package.json +1 -1
- package/src/modules/doc/amfReference/amfReference.html +0 -6
- package/src/modules/doc/amfReference/amfReference.ts +2 -37
- package/src/modules/doc/componentPlayground/componentPlayground.css +1 -1
- package/src/modules/doc/componentPlayground/componentPlayground.html +2 -2
- package/src/modules/doc/componentPlayground/componentPlayground.ts +13 -0
- package/src/modules/doc/contentLayout/contentLayout.html +15 -38
- package/src/modules/doc/contentLayout/contentLayout.ts +1 -9
- package/src/modules/doc/lwcContentLayout/lwcContentLayout.html +15 -38
- package/src/modules/doc/xmlContent/xmlContent.html +9 -7
- package/src/modules/doc/xmlContent/xmlContent.ts +23 -52
- package/src/modules/doc/markdownEditor/markdownEditor.css +0 -225
- package/src/modules/doc/markdownEditor/markdownEditor.html +0 -80
- package/src/modules/doc/markdownEditor/markdownEditor.ts +0 -148
package/lwc.config.json
CHANGED
package/package.json
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<doc-content-layout
|
|
3
3
|
lwc:if={isVersionFetched}
|
|
4
|
-
use-old-sidebar={useOldSidebar}
|
|
5
4
|
class="content-type content-type-reference"
|
|
6
|
-
coveo-organization-id={coveoOrganizationId}
|
|
7
|
-
coveo-public-access-token={coveoPublicAccessToken}
|
|
8
|
-
coveo-analytics-token={coveoAnalyticsToken}
|
|
9
|
-
coveo-search-hub={coveoSearchHub}
|
|
10
|
-
coveo-advanced-query-config={coveoAdvancedQueryConfig}
|
|
11
5
|
breadcrumbs={breadcrumbs}
|
|
12
6
|
sidebar-header={sidebarHeader}
|
|
13
7
|
sidebar-value={selectedSidebarValue}
|
|
@@ -3,7 +3,7 @@ import { noCase } from "no-case";
|
|
|
3
3
|
import { sentenceCase } from "sentence-case";
|
|
4
4
|
import qs from "query-string";
|
|
5
5
|
import { AmfModelParser } from "doc/amfModelParser";
|
|
6
|
-
import { normalizeBoolean
|
|
6
|
+
import { normalizeBoolean } from "dxUtils/normalizers";
|
|
7
7
|
import type { OptionWithLink } from "typings/custom";
|
|
8
8
|
import type {
|
|
9
9
|
AmfConfig,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
} from "./constants";
|
|
29
29
|
import { restoreScroll } from "dx/scrollManager";
|
|
30
30
|
import { DocPhaseInfo } from "typings/custom";
|
|
31
|
-
import {
|
|
31
|
+
import { oldVersionDocInfo } from "docUtils/utils";
|
|
32
32
|
|
|
33
33
|
type NavigationItem = {
|
|
34
34
|
label: string;
|
|
@@ -41,11 +41,6 @@ type NavigationItem = {
|
|
|
41
41
|
export default class AmfReference extends LightningElement {
|
|
42
42
|
@api breadcrumbs: string | null = null;
|
|
43
43
|
@api sidebarHeader!: string;
|
|
44
|
-
@api coveoOrganizationId!: string;
|
|
45
|
-
@api coveoPublicAccessToken!: string;
|
|
46
|
-
@api coveoAnalyticsToken!: string;
|
|
47
|
-
@api coveoSearchHub!: string;
|
|
48
|
-
@api useOldSidebar: boolean = false;
|
|
49
44
|
@api tocTitle?: string;
|
|
50
45
|
@api tocOptions?: string;
|
|
51
46
|
@api languages!: OptionWithLink[];
|
|
@@ -54,7 +49,6 @@ export default class AmfReference extends LightningElement {
|
|
|
54
49
|
@track navigation = [] as NavigationItem[];
|
|
55
50
|
@track versions: Array<ReferenceVersion> = [];
|
|
56
51
|
@track showVersionBanner = false;
|
|
57
|
-
@track _coveoAdvancedQueryConfig!: { [key: string]: any };
|
|
58
52
|
|
|
59
53
|
// Update this to update what component gets rendered in the content block
|
|
60
54
|
@track
|
|
@@ -160,31 +154,6 @@ export default class AmfReference extends LightningElement {
|
|
|
160
154
|
this._expandChildren = normalizeBoolean(value);
|
|
161
155
|
}
|
|
162
156
|
|
|
163
|
-
/*
|
|
164
|
-
* The get coveoAdvancedQueryConfig() method returns this._coveoAdvancedQueryConfig,
|
|
165
|
-
* but before returning it, it checks if there are multiple versions (this.versions.length > 1)
|
|
166
|
-
* and if a version is selected (this.selectedVersion). If both conditions are met,
|
|
167
|
-
* it updates the version property of this._coveoAdvancedQueryConfig with the selected version.
|
|
168
|
-
*/
|
|
169
|
-
@api
|
|
170
|
-
get coveoAdvancedQueryConfig(): { [key: string]: any } {
|
|
171
|
-
const coveoConfig = this._coveoAdvancedQueryConfig;
|
|
172
|
-
if (this.versions.length > 1 && this.selectedVersion) {
|
|
173
|
-
const currentGAVersionRef = this.versions[0];
|
|
174
|
-
if (this.selectedVersion.id !== currentGAVersionRef.id) {
|
|
175
|
-
// Currently Coveo only supports query without "v"
|
|
176
|
-
const version = this.selectedVersion.id.replace("v", "");
|
|
177
|
-
coveoConfig.version = version;
|
|
178
|
-
this._coveoAdvancedQueryConfig = coveoConfig;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return this._coveoAdvancedQueryConfig;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
set coveoAdvancedQueryConfig(config) {
|
|
185
|
-
this._coveoAdvancedQueryConfig = toJson(config);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
157
|
private get enableFooter(): boolean {
|
|
189
158
|
return !this.hideFooter;
|
|
190
159
|
}
|
|
@@ -1436,10 +1405,6 @@ export default class AmfReference extends LightningElement {
|
|
|
1436
1405
|
metaVal
|
|
1437
1406
|
);
|
|
1438
1407
|
|
|
1439
|
-
logCoveoPageView(
|
|
1440
|
-
this.coveoOrganizationId,
|
|
1441
|
-
this.coveoAnalyticsToken
|
|
1442
|
-
);
|
|
1443
1408
|
this.updateUrlWithSelected(parentReferencePath, metaVal);
|
|
1444
1409
|
this.updateTags(metadata.navTitle);
|
|
1445
1410
|
} else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="container" lwc:if={playgroundAvailable}>
|
|
2
|
+
<div class="playground-container" lwc:if={playgroundAvailable}>
|
|
3
3
|
<dx-spinner
|
|
4
4
|
size="large"
|
|
5
5
|
variant="brand"
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<iframe
|
|
9
9
|
src={playgroundSrc}
|
|
10
10
|
onload={handleIframeLoad}
|
|
11
|
-
title=
|
|
11
|
+
title={playgroundTitle}
|
|
12
12
|
allow="clipboard-write"
|
|
13
13
|
></iframe>
|
|
14
14
|
</div>
|
|
@@ -8,6 +8,19 @@ export default class ComponentPlayground extends LightningElement {
|
|
|
8
8
|
|
|
9
9
|
isLoading = true;
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Returns a formatted title for the component playground
|
|
13
|
+
* Maps 'aura' model to 'Aura' and 'lwc' model to 'Lightning'
|
|
14
|
+
* Capitalizes the first letter of the component name
|
|
15
|
+
* @returns {string} Formatted playground title
|
|
16
|
+
*/
|
|
17
|
+
get playgroundTitle() {
|
|
18
|
+
const modelName = this.model === "aura" ? "Aura" : "Lightning";
|
|
19
|
+
const componentName =
|
|
20
|
+
this.component.charAt(0).toUpperCase() + this.component.slice(1);
|
|
21
|
+
return `Example previews and code for ${modelName} ${componentName} component`;
|
|
22
|
+
}
|
|
23
|
+
|
|
11
24
|
get playgroundAvailable() {
|
|
12
25
|
return (
|
|
13
26
|
this.playgroundAppUrl &&
|
|
@@ -1,43 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="content">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
>
|
|
17
|
-
|
|
18
|
-
</dx-sidebar-old>
|
|
19
|
-
</template>
|
|
20
|
-
<template lwc:else>
|
|
21
|
-
<dx-sidebar
|
|
22
|
-
class="is-sticky left-nav-bar"
|
|
23
|
-
trees={sidebarContent}
|
|
24
|
-
value={sidebarValue}
|
|
25
|
-
header={sidebarHeader}
|
|
26
|
-
coveo-organization-id={coveoOrganizationId}
|
|
27
|
-
coveo-public-access-token={coveoPublicAccessToken}
|
|
28
|
-
coveo-search-hub={coveoSearchHub}
|
|
29
|
-
coveo-advanced-query-config={coveoAdvancedQueryConfig}
|
|
30
|
-
ontogglesidebar={onToggleSidebar}
|
|
31
|
-
languages={languages}
|
|
32
|
-
language={language}
|
|
33
|
-
bail-href={bailHref}
|
|
34
|
-
bail-label={bailLabel}
|
|
35
|
-
dev-center={devCenter}
|
|
36
|
-
brand={brand}
|
|
37
|
-
>
|
|
38
|
-
<slot name="sidebar-header" slot="version-picker"></slot>
|
|
39
|
-
</dx-sidebar>
|
|
40
|
-
</template>
|
|
3
|
+
<dx-sidebar-old
|
|
4
|
+
class="is-sticky left-nav-bar"
|
|
5
|
+
trees={sidebarContent}
|
|
6
|
+
value={sidebarValue}
|
|
7
|
+
header={sidebarHeader}
|
|
8
|
+
ontogglesidebar={onToggleSidebar}
|
|
9
|
+
languages={languages}
|
|
10
|
+
language={language}
|
|
11
|
+
bail-href={bailHref}
|
|
12
|
+
bail-label={bailLabel}
|
|
13
|
+
dev-center={devCenter}
|
|
14
|
+
brand={brand}
|
|
15
|
+
>
|
|
16
|
+
<slot name="sidebar-header" slot="version-picker"></slot>
|
|
17
|
+
</dx-sidebar-old>
|
|
41
18
|
<div class="content-body-doc-phase-container">
|
|
42
19
|
<slot name="doc-phase"></slot>
|
|
43
20
|
<slot name="version-banner"></slot>
|
|
@@ -32,11 +32,6 @@ export default class ContentLayout extends LightningElement {
|
|
|
32
32
|
@api sidebarHeader!: string;
|
|
33
33
|
@api tocTitle!: string;
|
|
34
34
|
@api enableSlotChange = false;
|
|
35
|
-
@api coveoOrganizationId!: string;
|
|
36
|
-
@api coveoPublicAccessToken!: string;
|
|
37
|
-
@api coveoAnalyticsToken!: string;
|
|
38
|
-
@api coveoSearchHub!: string;
|
|
39
|
-
@api coveoAdvancedQueryConfig!: string;
|
|
40
35
|
@api useOldSidebar?: boolean = false;
|
|
41
36
|
@api languages!: OptionWithLink[];
|
|
42
37
|
@api language!: string;
|
|
@@ -210,10 +205,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
210
205
|
We have to account for the global nav changing height due to animations.
|
|
211
206
|
*/
|
|
212
207
|
adjustNavPosition = () => {
|
|
213
|
-
const
|
|
214
|
-
? "dx-sidebar-old"
|
|
215
|
-
: "dx-sidebar";
|
|
216
|
-
const sidebarEl = this.template.querySelector(sidebarType);
|
|
208
|
+
const sidebarEl = this.template.querySelector("dx-sidebar-old");
|
|
217
209
|
const globalNavEl = document.querySelector(
|
|
218
210
|
"hgf-c360nav"
|
|
219
211
|
) as HTMLElement;
|
|
@@ -1,43 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="content">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
>
|
|
17
|
-
|
|
18
|
-
</dx-sidebar-old>
|
|
19
|
-
</template>
|
|
20
|
-
<template lwc:else>
|
|
21
|
-
<dx-sidebar
|
|
22
|
-
class="is-sticky left-nav-bar"
|
|
23
|
-
trees={sidebarContent}
|
|
24
|
-
value={sidebarValue}
|
|
25
|
-
header={sidebarHeader}
|
|
26
|
-
coveo-organization-id={coveoOrganizationId}
|
|
27
|
-
coveo-public-access-token={coveoPublicAccessToken}
|
|
28
|
-
coveo-search-hub={coveoSearchHub}
|
|
29
|
-
coveo-advanced-query-config={coveoAdvancedQueryConfig}
|
|
30
|
-
ontogglesidebar={onToggleSidebar}
|
|
31
|
-
languages={languages}
|
|
32
|
-
language={language}
|
|
33
|
-
bail-href={bailHref}
|
|
34
|
-
bail-label={bailLabel}
|
|
35
|
-
dev-center={devCenter}
|
|
36
|
-
brand={brand}
|
|
37
|
-
>
|
|
38
|
-
<slot name="sidebar-header" slot="version-picker"></slot>
|
|
39
|
-
</dx-sidebar>
|
|
40
|
-
</template>
|
|
3
|
+
<dx-sidebar-old
|
|
4
|
+
class="is-sticky left-nav-bar"
|
|
5
|
+
trees={sidebarContent}
|
|
6
|
+
value={sidebarValue}
|
|
7
|
+
header={sidebarHeader}
|
|
8
|
+
ontogglesidebar={onToggleSidebar}
|
|
9
|
+
languages={languages}
|
|
10
|
+
language={language}
|
|
11
|
+
bail-href={bailHref}
|
|
12
|
+
bail-label={bailLabel}
|
|
13
|
+
dev-center={devCenter}
|
|
14
|
+
brand={brand}
|
|
15
|
+
>
|
|
16
|
+
<slot name="sidebar-header" slot="version-picker"></slot>
|
|
17
|
+
</dx-sidebar-old>
|
|
41
18
|
<div class="content-body-doc-phase-container">
|
|
42
19
|
<slot name="doc-phase"></slot>
|
|
43
20
|
<slot name="version-banner"></slot>
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<doc-content-layout
|
|
3
|
-
lwc:if={
|
|
3
|
+
lwc:if={displayContent}
|
|
4
4
|
lwc:ref="docContentLayout"
|
|
5
|
-
coveo-organization-id={coveoOrganizationId}
|
|
6
|
-
coveo-public-access-token={coveoPublicAccessToken}
|
|
7
|
-
coveo-analytics-token={coveoAnalyticsToken}
|
|
8
|
-
coveo-search-hub={coveoSearchHub}
|
|
9
|
-
coveo-advanced-query-config={coveoAdvancedQueryConfig}
|
|
10
5
|
sidebar-header={docTitle}
|
|
11
6
|
sidebar-content={sidebarContent}
|
|
12
7
|
sidebar-value={sidebarValue}
|
|
13
8
|
onselect={handleSelect}
|
|
14
|
-
use-old-sidebar={useOldSidebar}
|
|
15
9
|
onlangchange={handleLanguageChange}
|
|
16
10
|
languages={sidebarFooterContent.languages}
|
|
17
11
|
language={sidebarFooterContent.language}
|
|
@@ -49,4 +43,12 @@
|
|
|
49
43
|
onnavclick={handleNavClick}
|
|
50
44
|
></doc-content>
|
|
51
45
|
</doc-content-layout>
|
|
46
|
+
<div lwc:if={display404}>
|
|
47
|
+
<dx-error
|
|
48
|
+
image="https://a.sfdcstatic.com/developer-website/images/404.svg"
|
|
49
|
+
code="404"
|
|
50
|
+
header="Beep boop. That did not compute."
|
|
51
|
+
subtitle="The document you're looking for doesn't seem to exist."
|
|
52
|
+
></dx-error>
|
|
53
|
+
</div>
|
|
52
54
|
</template>
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @lwc/lwc/no-document-query */
|
|
2
2
|
import { api, track } from "lwc";
|
|
3
|
-
import { normalizeBoolean } from "dxUtils/normalizers";
|
|
4
3
|
import { FetchContent } from "./utils";
|
|
5
4
|
import {
|
|
6
|
-
CoveoAdvancedQueryXMLConfig,
|
|
7
5
|
DocLanguage,
|
|
8
6
|
DocVersion,
|
|
9
7
|
TreeNode,
|
|
@@ -11,11 +9,12 @@ import {
|
|
|
11
9
|
SiderbarFooter,
|
|
12
10
|
HistoryState,
|
|
13
11
|
PageReference,
|
|
14
|
-
TocMap
|
|
12
|
+
TocMap,
|
|
13
|
+
ContentData
|
|
15
14
|
} from "./types";
|
|
16
15
|
import { SearchSyncer } from "docUtils/searchSyncer";
|
|
17
16
|
import { LightningElementWithState } from "dxBaseElements/lightningElementWithState";
|
|
18
|
-
import {
|
|
17
|
+
import { oldVersionDocInfo } from "docUtils/utils";
|
|
19
18
|
import { Breadcrumb, DocPhaseInfo, Language } from "typings/custom";
|
|
20
19
|
import { track as trackGTM } from "dxUtils/analytics";
|
|
21
20
|
import DOMPurify from "dompurify";
|
|
@@ -41,10 +40,6 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
41
40
|
internalLinkClicked: boolean;
|
|
42
41
|
}> {
|
|
43
42
|
@api apiDomain = "https://developer.salesforce.com";
|
|
44
|
-
@api coveoOrganizationId!: string;
|
|
45
|
-
@api coveoPublicAccessToken!: string;
|
|
46
|
-
@api coveoAnalyticsToken!: string;
|
|
47
|
-
@api coveoSearchHub!: string;
|
|
48
43
|
@api hideFooter = false;
|
|
49
44
|
|
|
50
45
|
@api
|
|
@@ -58,21 +53,13 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
58
53
|
}
|
|
59
54
|
}
|
|
60
55
|
|
|
61
|
-
@api
|
|
62
|
-
get enableCoveo() {
|
|
63
|
-
return this._enableCoveo;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
set enableCoveo(value) {
|
|
67
|
-
this._enableCoveo = normalizeBoolean(value);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
56
|
private availableLanguages: Array<DocLanguage> = [];
|
|
71
57
|
@track private availableVersions: Array<DocVersion> = [];
|
|
72
58
|
private contentProvider?: FetchContent;
|
|
73
59
|
private docContent = "";
|
|
74
60
|
private language?: DocLanguage | null = null;
|
|
75
|
-
private
|
|
61
|
+
private displayContent = false;
|
|
62
|
+
private display404 = false;
|
|
76
63
|
private _pageHeader?: Header;
|
|
77
64
|
private pdfUrl = "";
|
|
78
65
|
private tocMap: TocMap = {};
|
|
@@ -81,7 +68,6 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
81
68
|
private docTitle = "";
|
|
82
69
|
private _pathName = "";
|
|
83
70
|
private listenerAttached = false;
|
|
84
|
-
private _enableCoveo?: boolean = false;
|
|
85
71
|
private sidebarFooterContent: SiderbarFooter = { ...defaultSidebarFooter };
|
|
86
72
|
private latestVersion = false;
|
|
87
73
|
private previewVersion = false;
|
|
@@ -185,7 +171,13 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
185
171
|
this.apiDomain,
|
|
186
172
|
this.allLanguages
|
|
187
173
|
);
|
|
188
|
-
this.fetchDocument().then(() =>
|
|
174
|
+
this.fetchDocument().then((content: any) => {
|
|
175
|
+
if (content) {
|
|
176
|
+
this.displayContent = true;
|
|
177
|
+
} else {
|
|
178
|
+
this.display404 = true;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
189
181
|
window.addEventListener("popstate", this.handlePopState);
|
|
190
182
|
|
|
191
183
|
this.searchSyncer.init();
|
|
@@ -252,35 +244,13 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
252
244
|
// Coveo is enabled and the version is greater than 51 (within the latest 3 versions)
|
|
253
245
|
// TODO: we need a better fix for version number check
|
|
254
246
|
return !(
|
|
255
|
-
this.
|
|
256
|
-
this.
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
(this.version?.releaseVersion &&
|
|
260
|
-
parseInt(
|
|
261
|
-
this.version.releaseVersion.replace("v", ""),
|
|
262
|
-
10
|
|
263
|
-
) >= 53))
|
|
247
|
+
!this.version?.releaseVersion ||
|
|
248
|
+
(this.version?.releaseVersion &&
|
|
249
|
+
parseInt(this.version.releaseVersion.replace("v", ""), 10) >=
|
|
250
|
+
53)
|
|
264
251
|
);
|
|
265
252
|
}
|
|
266
253
|
|
|
267
|
-
private get coveoAdvancedQueryConfig(): CoveoAdvancedQueryXMLConfig {
|
|
268
|
-
const config: {
|
|
269
|
-
locale?: string;
|
|
270
|
-
topicid?: string;
|
|
271
|
-
version?: string;
|
|
272
|
-
} = {
|
|
273
|
-
locale: this.languageId,
|
|
274
|
-
topicid: this.deliverable
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
if (this.releaseVersionId && this.releaseVersionId !== "noversion") {
|
|
278
|
-
config.version = this.releaseVersionId;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return config;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
254
|
private get pageHeader(): Header {
|
|
285
255
|
if (!this._pageHeader) {
|
|
286
256
|
this._pageHeader = document.querySelector("doc-header")!;
|
|
@@ -463,7 +433,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
463
433
|
);
|
|
464
434
|
}
|
|
465
435
|
|
|
466
|
-
async fetchDocument(): Promise<
|
|
436
|
+
async fetchDocument(): Promise<string> {
|
|
467
437
|
this.setState({
|
|
468
438
|
isFetchingDocument: true
|
|
469
439
|
});
|
|
@@ -477,7 +447,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
477
447
|
this.setState({
|
|
478
448
|
isFetchingDocument: false
|
|
479
449
|
});
|
|
480
|
-
return;
|
|
450
|
+
return "";
|
|
481
451
|
}
|
|
482
452
|
|
|
483
453
|
this.docTitle = data.docTitle;
|
|
@@ -509,11 +479,11 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
509
479
|
data.id
|
|
510
480
|
) {
|
|
511
481
|
try {
|
|
512
|
-
await this.fetchContent();
|
|
482
|
+
const moreData = await this.fetchContent();
|
|
513
483
|
this.setState({
|
|
514
484
|
isFetchingDocument: false
|
|
515
485
|
});
|
|
516
|
-
return;
|
|
486
|
+
return moreData.content;
|
|
517
487
|
} catch (error) {
|
|
518
488
|
this.pageReference.contentDocumentId = `${data.id}.htm`;
|
|
519
489
|
this.pageReference.hash = "";
|
|
@@ -527,9 +497,10 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
527
497
|
this.setState({
|
|
528
498
|
isFetchingDocument: false
|
|
529
499
|
});
|
|
500
|
+
return data.content;
|
|
530
501
|
}
|
|
531
502
|
|
|
532
|
-
async fetchContent(): Promise<
|
|
503
|
+
async fetchContent(): Promise<ContentData> {
|
|
533
504
|
this.setState({
|
|
534
505
|
isFetchingContent: true
|
|
535
506
|
});
|
|
@@ -553,6 +524,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
553
524
|
this.setState({
|
|
554
525
|
isFetchingContent: false
|
|
555
526
|
});
|
|
527
|
+
return data;
|
|
556
528
|
}
|
|
557
529
|
|
|
558
530
|
updateHeaderAndSidebarFooter(): void {
|
|
@@ -579,7 +551,6 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
579
551
|
}
|
|
580
552
|
|
|
581
553
|
updateUrl(method = HistoryState.PUSH_STATE): void {
|
|
582
|
-
logCoveoPageView(this.coveoOrganizationId, this.coveoAnalyticsToken);
|
|
583
554
|
window.history[method](
|
|
584
555
|
{},
|
|
585
556
|
"docs",
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
.markdown-editor {
|
|
2
|
-
border: 1px solid #e1e5e9;
|
|
3
|
-
border-radius: 4px;
|
|
4
|
-
overflow: hidden;
|
|
5
|
-
background: #fff;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/* Editor Toolbar */
|
|
9
|
-
.editor-toolbar {
|
|
10
|
-
display: flex;
|
|
11
|
-
align-items: center;
|
|
12
|
-
justify-content: flex-end;
|
|
13
|
-
gap: 0.5rem;
|
|
14
|
-
padding: 0.75rem 1rem;
|
|
15
|
-
background: #f8f9fa;
|
|
16
|
-
border-bottom: 1px solid #e1e5e9;
|
|
17
|
-
flex-wrap: wrap;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.edit-button,
|
|
21
|
-
.cancel-button,
|
|
22
|
-
.save-button {
|
|
23
|
-
min-width: 80px;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.status-indicator {
|
|
27
|
-
margin-left: 0.5rem;
|
|
28
|
-
font-size: 0.875rem;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.status-saving {
|
|
32
|
-
color: #0176d3;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.status-success {
|
|
36
|
-
color: #04844b;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.status-error {
|
|
40
|
-
color: #ea001e;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/* Content Viewer */
|
|
44
|
-
.content-viewer {
|
|
45
|
-
padding: 1rem;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.content-display {
|
|
49
|
-
line-height: 1.6;
|
|
50
|
-
color: #3e3e3c;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.content-display h1,
|
|
54
|
-
.content-display h2,
|
|
55
|
-
.content-display h3,
|
|
56
|
-
.content-display h4,
|
|
57
|
-
.content-display h5,
|
|
58
|
-
.content-display h6 {
|
|
59
|
-
margin-top: 1.5rem;
|
|
60
|
-
margin-bottom: 0.5rem;
|
|
61
|
-
color: #181818;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.content-display p {
|
|
65
|
-
margin-bottom: 1rem;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.content-display ul,
|
|
69
|
-
.content-display ol {
|
|
70
|
-
margin-bottom: 1rem;
|
|
71
|
-
padding-left: 2rem;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
.content-display code {
|
|
75
|
-
background-color: #f3f2f2;
|
|
76
|
-
padding: 0.125rem 0.25rem;
|
|
77
|
-
border-radius: 0.25rem;
|
|
78
|
-
font-family: Monaco, Menlo, "Ubuntu Mono", monospace;
|
|
79
|
-
font-size: 0.875rem;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.content-display pre {
|
|
83
|
-
background-color: #f3f2f2;
|
|
84
|
-
padding: 1rem;
|
|
85
|
-
border-radius: 0.25rem;
|
|
86
|
-
overflow-x: auto;
|
|
87
|
-
margin-bottom: 1rem;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
.content-display pre code {
|
|
91
|
-
background-color: transparent;
|
|
92
|
-
padding: 0;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/* HTML Content Styling */
|
|
96
|
-
.html-content {
|
|
97
|
-
line-height: 1.6;
|
|
98
|
-
color: #3e3e3c;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.html-content h1,
|
|
102
|
-
.html-content h2,
|
|
103
|
-
.html-content h3,
|
|
104
|
-
.html-content h4,
|
|
105
|
-
.html-content h5,
|
|
106
|
-
.html-content h6 {
|
|
107
|
-
margin-top: 1.5rem;
|
|
108
|
-
margin-bottom: 0.5rem;
|
|
109
|
-
color: #181818;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
.html-content p {
|
|
113
|
-
margin-bottom: 1rem;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
.html-content ul,
|
|
117
|
-
.html-content ol {
|
|
118
|
-
margin-bottom: 1rem;
|
|
119
|
-
padding-left: 2rem;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
.html-content code {
|
|
123
|
-
background-color: #f3f2f2;
|
|
124
|
-
padding: 0.125rem 0.25rem;
|
|
125
|
-
border-radius: 0.25rem;
|
|
126
|
-
font-family: Monaco, Menlo, "Ubuntu Mono", monospace;
|
|
127
|
-
font-size: 0.875rem;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
.html-content pre {
|
|
131
|
-
background-color: #f3f2f2;
|
|
132
|
-
padding: 1rem;
|
|
133
|
-
border-radius: 0.25rem;
|
|
134
|
-
overflow-x: auto;
|
|
135
|
-
margin-bottom: 1rem;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.html-content pre code {
|
|
139
|
-
background-color: transparent;
|
|
140
|
-
padding: 0;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/* No Content Message */
|
|
144
|
-
.no-content {
|
|
145
|
-
color: #706e6b;
|
|
146
|
-
font-style: italic;
|
|
147
|
-
text-align: center;
|
|
148
|
-
padding: 2rem;
|
|
149
|
-
background-color: #f8f9fa;
|
|
150
|
-
border: 1px dashed #e1e5e9;
|
|
151
|
-
border-radius: 4px;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/* Editor Wrapper */
|
|
155
|
-
.editor-wrapper {
|
|
156
|
-
position: relative;
|
|
157
|
-
min-height: 300px;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
.simple-editor {
|
|
161
|
-
width: 100%;
|
|
162
|
-
min-height: 300px;
|
|
163
|
-
padding: 1rem;
|
|
164
|
-
border: none;
|
|
165
|
-
outline: none;
|
|
166
|
-
font-family: Monaco, Menlo, "Ubuntu Mono", monospace;
|
|
167
|
-
font-size: 0.875rem;
|
|
168
|
-
line-height: 1.5;
|
|
169
|
-
resize: vertical;
|
|
170
|
-
background: #fff;
|
|
171
|
-
color: #3e3e3c;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
.simple-editor:focus {
|
|
175
|
-
outline: none;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.simple-editor::placeholder {
|
|
179
|
-
color: #706e6b;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/* Loading Overlay */
|
|
183
|
-
.loading-overlay {
|
|
184
|
-
position: absolute;
|
|
185
|
-
top: 0;
|
|
186
|
-
left: 0;
|
|
187
|
-
right: 0;
|
|
188
|
-
bottom: 0;
|
|
189
|
-
background: rgb(255 255 255 / 80%);
|
|
190
|
-
display: flex;
|
|
191
|
-
align-items: center;
|
|
192
|
-
justify-content: center;
|
|
193
|
-
z-index: 1000;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/* Responsive Design */
|
|
197
|
-
@media (max-width: 768px) {
|
|
198
|
-
.editor-toolbar {
|
|
199
|
-
flex-wrap: wrap;
|
|
200
|
-
gap: 0.25rem;
|
|
201
|
-
justify-content: flex-end;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
.status-indicator {
|
|
205
|
-
margin-left: 0.25rem;
|
|
206
|
-
width: auto;
|
|
207
|
-
text-align: right;
|
|
208
|
-
margin-top: 0;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
.simple-editor {
|
|
212
|
-
min-height: 250px;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
.content-viewer {
|
|
216
|
-
padding: 0.75rem;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/* Empty state */
|
|
221
|
-
.content-display:empty::before {
|
|
222
|
-
content: "No content to display";
|
|
223
|
-
color: #706e6b;
|
|
224
|
-
font-style: italic;
|
|
225
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="markdown-editor">
|
|
3
|
-
<!-- Editor Toolbar -->
|
|
4
|
-
<div class="editor-toolbar">
|
|
5
|
-
<template if:true={showViewer}>
|
|
6
|
-
<dx-button
|
|
7
|
-
onclick={handleEdit}
|
|
8
|
-
variant="tertiary"
|
|
9
|
-
class="edit-button"
|
|
10
|
-
>
|
|
11
|
-
Edit Content
|
|
12
|
-
</dx-button>
|
|
13
|
-
</template>
|
|
14
|
-
|
|
15
|
-
<template if:true={showEditor}>
|
|
16
|
-
<dx-button
|
|
17
|
-
onclick={handleCancel}
|
|
18
|
-
variant="secondary"
|
|
19
|
-
class="cancel-button"
|
|
20
|
-
>
|
|
21
|
-
Cancel
|
|
22
|
-
</dx-button>
|
|
23
|
-
|
|
24
|
-
<dx-button
|
|
25
|
-
onclick={handleSave}
|
|
26
|
-
variant="primary"
|
|
27
|
-
disabled={saveButtonDisabled}
|
|
28
|
-
class="save-button"
|
|
29
|
-
>
|
|
30
|
-
Save
|
|
31
|
-
</dx-button>
|
|
32
|
-
|
|
33
|
-
<div class="status-indicator">
|
|
34
|
-
<span class={statusClass}>{statusMessage}</span>
|
|
35
|
-
</div>
|
|
36
|
-
</template>
|
|
37
|
-
</div>
|
|
38
|
-
|
|
39
|
-
<!-- Content Viewer (Read-only) -->
|
|
40
|
-
<template if:true={showViewer}>
|
|
41
|
-
<div class="content-viewer">
|
|
42
|
-
<div class="content-display">
|
|
43
|
-
<!-- Show HTML content if provided -->
|
|
44
|
-
<template if:true={hasHtmlContent}>
|
|
45
|
-
<div class="html-content" innerhtml={htmlContent}></div>
|
|
46
|
-
</template>
|
|
47
|
-
|
|
48
|
-
<!-- Show message if no HTML content -->
|
|
49
|
-
<template if:false={hasHtmlContent}>
|
|
50
|
-
<div class="no-content">
|
|
51
|
-
No content to display. Click 'Edit Content' to fetch from the backend.
|
|
52
|
-
</div>
|
|
53
|
-
</template>
|
|
54
|
-
</div>
|
|
55
|
-
</div>
|
|
56
|
-
</template>
|
|
57
|
-
|
|
58
|
-
<!-- Simple Editor -->
|
|
59
|
-
<template if:true={showEditor}>
|
|
60
|
-
<div class="editor-wrapper">
|
|
61
|
-
<textarea
|
|
62
|
-
class="simple-editor"
|
|
63
|
-
value={editorContent}
|
|
64
|
-
onchange={handleContentChange}
|
|
65
|
-
placeholder="Content will be loaded from the fetch URL..."
|
|
66
|
-
></textarea>
|
|
67
|
-
</div>
|
|
68
|
-
</template>
|
|
69
|
-
|
|
70
|
-
<!-- Loading Overlay -->
|
|
71
|
-
<template if:true={isLoading}>
|
|
72
|
-
<div class="loading-overlay">
|
|
73
|
-
<dx-spinner
|
|
74
|
-
size="medium"
|
|
75
|
-
alternative-text="Loading"
|
|
76
|
-
></dx-spinner>
|
|
77
|
-
</div>
|
|
78
|
-
</template>
|
|
79
|
-
</div>
|
|
80
|
-
</template>
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { LightningElement, api, track } from "lwc";
|
|
2
|
-
|
|
3
|
-
export default class MarkdownEditor extends LightningElement {
|
|
4
|
-
@api fetchUrl: string = "";
|
|
5
|
-
@api saveUrl: string = "";
|
|
6
|
-
@api filePath: string = "";
|
|
7
|
-
@api htmlContent: string = "";
|
|
8
|
-
|
|
9
|
-
@track isEditing: boolean = false;
|
|
10
|
-
@track editorContent: string = "";
|
|
11
|
-
@track isLoading: boolean = false;
|
|
12
|
-
@track saveStatus: "idle" | "saving" | "success" | "error" = "idle";
|
|
13
|
-
|
|
14
|
-
// Event Handlers
|
|
15
|
-
async handleEdit() {
|
|
16
|
-
if (!this.fetchUrl) {
|
|
17
|
-
console.error("Fetch URL not configured");
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
this.isLoading = true;
|
|
22
|
-
this.saveStatus = "idle";
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
const response = await fetch(this.fetchUrl, {
|
|
26
|
-
method: "GET",
|
|
27
|
-
headers: {
|
|
28
|
-
"Content-Type": "application/json"
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
if (response.ok) {
|
|
33
|
-
const data = await response.json();
|
|
34
|
-
this.editorContent = data.content || data.text || data.body || "";
|
|
35
|
-
this.isEditing = true;
|
|
36
|
-
} else {
|
|
37
|
-
throw new Error(`Failed to fetch content: ${response.status}`);
|
|
38
|
-
}
|
|
39
|
-
} catch (error) {
|
|
40
|
-
console.error("Failed to fetch content:", error);
|
|
41
|
-
this.saveStatus = "error";
|
|
42
|
-
} finally {
|
|
43
|
-
this.isLoading = false;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
handleCancel() {
|
|
48
|
-
this.isEditing = false;
|
|
49
|
-
this.saveStatus = "idle";
|
|
50
|
-
this.editorContent = "";
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
handleContentChange(event: Event) {
|
|
54
|
-
const target = event.target as HTMLTextAreaElement;
|
|
55
|
-
this.editorContent = target.value;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async handleSave() {
|
|
59
|
-
if (!this.saveUrl) {
|
|
60
|
-
console.error("Save URL not configured");
|
|
61
|
-
this.saveStatus = "error";
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
this.saveStatus = "saving";
|
|
66
|
-
this.isLoading = true;
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
const response = await fetch(this.saveUrl, {
|
|
70
|
-
method: "POST",
|
|
71
|
-
headers: {
|
|
72
|
-
"Content-Type": "application/json"
|
|
73
|
-
},
|
|
74
|
-
body: JSON.stringify({
|
|
75
|
-
content: this.editorContent,
|
|
76
|
-
filePath: this.filePath
|
|
77
|
-
})
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
if (response.ok) {
|
|
81
|
-
this.saveStatus = "success";
|
|
82
|
-
this.isEditing = false;
|
|
83
|
-
this.editorContent = "";
|
|
84
|
-
|
|
85
|
-
// Dispatch save success event
|
|
86
|
-
this.dispatchEvent(
|
|
87
|
-
new CustomEvent("saved", {
|
|
88
|
-
detail: {
|
|
89
|
-
success: true,
|
|
90
|
-
content: this.editorContent,
|
|
91
|
-
filePath: this.filePath
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
);
|
|
95
|
-
} else {
|
|
96
|
-
throw new Error(`Save failed: ${response.status}`);
|
|
97
|
-
}
|
|
98
|
-
} catch (error) {
|
|
99
|
-
console.error("Save failed:", error);
|
|
100
|
-
this.saveStatus = "error";
|
|
101
|
-
} finally {
|
|
102
|
-
this.isLoading = false;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Getters for UI state
|
|
107
|
-
get showEditor() {
|
|
108
|
-
return this.isEditing;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
get showViewer() {
|
|
112
|
-
return !this.isEditing;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
get saveButtonDisabled() {
|
|
116
|
-
return this.saveStatus === "saving" || this.isLoading || !this.editorContent.trim();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
get statusMessage() {
|
|
120
|
-
switch (this.saveStatus) {
|
|
121
|
-
case "saving":
|
|
122
|
-
return "Saving...";
|
|
123
|
-
case "success":
|
|
124
|
-
return "Saved successfully!";
|
|
125
|
-
case "error":
|
|
126
|
-
return "Save failed. Please try again.";
|
|
127
|
-
default:
|
|
128
|
-
return "";
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
get statusClass() {
|
|
133
|
-
switch (this.saveStatus) {
|
|
134
|
-
case "saving":
|
|
135
|
-
return "status-saving";
|
|
136
|
-
case "success":
|
|
137
|
-
return "status-success";
|
|
138
|
-
case "error":
|
|
139
|
-
return "status-error";
|
|
140
|
-
default:
|
|
141
|
-
return "";
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
get hasHtmlContent() {
|
|
146
|
-
return this.htmlContent && this.htmlContent.trim().length > 0;
|
|
147
|
-
}
|
|
148
|
-
}
|