@salesforcedevs/docs-components 1.17.0-hack-alpha8 → 1.17.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/LICENSE +12 -0
- package/lwc.config.json +0 -1
- package/package.json +2 -2
- package/src/modules/doc/content/content.css +6 -17
- package/src/modules/doc/heading/heading.css +0 -56
- package/src/modules/doc/heading/heading.html +0 -40
- package/src/modules/doc/heading/heading.ts +0 -24
- package/src/modules/doc/xmlContent/xmlContent.html +9 -1
- package/src/modules/doc/xmlContent/xmlContent.ts +18 -8
- package/src/modules/docHelpers/contentLayoutStyle/contentLayoutStyle.css +0 -1
- package/src/modules/doc/commentPopup/README.md +0 -322
- package/src/modules/doc/commentPopup/commentDevHelper.ts +0 -380
- package/src/modules/doc/commentPopup/commentPopup.css +0 -440
- package/src/modules/doc/commentPopup/commentPopup.html +0 -138
- package/src/modules/doc/commentPopup/commentPopup.ts +0 -565
- package/src/modules/doc/commentPopup/commentUtils.ts +0 -382
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/lwc.config.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforcedevs/docs-components",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.2",
|
|
4
4
|
"description": "Docs Lightning web components for DSC",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "index.js",
|
|
@@ -25,5 +25,5 @@
|
|
|
25
25
|
"@types/lodash.orderby": "4.6.9",
|
|
26
26
|
"@types/lodash.uniqby": "4.7.9"
|
|
27
27
|
},
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "456b8ad8b3162df223f9809e66a454cb66b4add0"
|
|
29
29
|
}
|
|
@@ -67,53 +67,42 @@ h1 {
|
|
|
67
67
|
font-size: var(--dx-g-text-3xl);
|
|
68
68
|
letter-spacing: -0.8px;
|
|
69
69
|
line-height: var(--dx-g-spacing-3xl);
|
|
70
|
-
margin: var(--
|
|
71
|
-
var(--dx-g-spacing-md) 0;
|
|
70
|
+
margin: var(--dx-g-spacing-2xl) 0 var(--dx-g-spacing-md) 0;
|
|
72
71
|
}
|
|
73
72
|
|
|
74
73
|
h2 {
|
|
75
74
|
font-size: var(--dx-g-text-2xl);
|
|
76
75
|
letter-spacing: -0.4px;
|
|
77
76
|
line-height: var(--dx-g-spacing-2xl);
|
|
78
|
-
margin: var(--
|
|
79
|
-
var(--dx-g-spacing-md) 0;
|
|
77
|
+
margin: var(--dx-g-spacing-2xl) 0 var(--dx-g-spacing-md) 0;
|
|
80
78
|
}
|
|
81
79
|
|
|
82
80
|
h3 {
|
|
83
81
|
font-size: var(--dx-g-text-xl);
|
|
84
82
|
letter-spacing: -0.4px;
|
|
85
83
|
line-height: var(--dx-g-spacing-xl);
|
|
86
|
-
margin: var(--
|
|
87
|
-
var(--dx-g-spacing-md) 0;
|
|
84
|
+
margin: var(--dx-g-spacing-xl) 0 var(--dx-g-spacing-md) 0;
|
|
88
85
|
}
|
|
89
86
|
|
|
90
87
|
h4 {
|
|
91
88
|
font-size: var(--dx-g-text-base);
|
|
92
89
|
letter-spacing: -0.5px;
|
|
93
90
|
line-height: var(--dx-g-spacing-lg);
|
|
94
|
-
margin: var(--
|
|
95
|
-
var(--dx-g-spacing-sm) 0;
|
|
91
|
+
margin: var(--dx-g-spacing-lg) 0 var(--dx-g-spacing-sm) 0;
|
|
96
92
|
}
|
|
97
93
|
|
|
98
94
|
h5 {
|
|
99
95
|
font-size: var(--dx-g-text-sm);
|
|
100
96
|
letter-spacing: -0.3px;
|
|
101
97
|
line-height: var(--dx-g-spacing-mlg);
|
|
102
|
-
margin: var(--
|
|
103
|
-
var(--dx-g-spacing-sm) 0;
|
|
98
|
+
margin: var(--dx-g-spacing-md) 0 var(--dx-g-spacing-sm) 0;
|
|
104
99
|
}
|
|
105
100
|
|
|
106
101
|
h6 {
|
|
107
102
|
font-size: var(--dx-g-text-xs);
|
|
108
103
|
letter-spacing: -0.3px;
|
|
109
104
|
line-height: var(--dx-g-spacing-md);
|
|
110
|
-
margin: var(--
|
|
111
|
-
var(--dx-g-spacing-sm) 0;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/* Override top margin for doc-heading preceded by doc-comment-popup */
|
|
115
|
-
doc-comment-popup + doc-heading {
|
|
116
|
-
--heading-top-margin: 10px;
|
|
105
|
+
margin: var(--dx-g-spacing-sm) 0 var(--dx-g-spacing-sm) 0;
|
|
117
106
|
}
|
|
118
107
|
|
|
119
108
|
img {
|
|
@@ -31,59 +31,3 @@ h4 {
|
|
|
31
31
|
h4 doc-heading-content {
|
|
32
32
|
--doc-c-heading-anchor-button-bottom: -6px;
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
/* Heading alignment when comment popup is present */
|
|
36
|
-
h1:has(doc-comment-popup),
|
|
37
|
-
h2:has(doc-comment-popup),
|
|
38
|
-
h3:has(doc-comment-popup),
|
|
39
|
-
h4:has(doc-comment-popup) {
|
|
40
|
-
display: flex;
|
|
41
|
-
align-items: center;
|
|
42
|
-
gap: var(--dx-g-spacing-xs, 4px);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/* Ensure heading content takes up remaining space */
|
|
46
|
-
doc-heading-content {
|
|
47
|
-
flex: 1;
|
|
48
|
-
display: inline-block;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/* When no comment popup is present, reset flex to normal display */
|
|
52
|
-
h1:not(:has(doc-comment-popup)),
|
|
53
|
-
h2:not(:has(doc-comment-popup)),
|
|
54
|
-
h3:not(:has(doc-comment-popup)),
|
|
55
|
-
h4:not(:has(doc-comment-popup)) {
|
|
56
|
-
display: block;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/* Fallback for browsers that don't support :has() -
|
|
60
|
-
rely on JavaScript or assume all headings might have popups */
|
|
61
|
-
@supports not (selector(:has(*))) {
|
|
62
|
-
h1,
|
|
63
|
-
h2,
|
|
64
|
-
h3,
|
|
65
|
-
h4 {
|
|
66
|
-
display: flex;
|
|
67
|
-
align-items: center;
|
|
68
|
-
gap: var(--dx-g-spacing-xs, 4px);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/* Responsive Design */
|
|
73
|
-
@media (max-width: 768px) {
|
|
74
|
-
h1:has(doc-comment-popup),
|
|
75
|
-
h2:has(doc-comment-popup),
|
|
76
|
-
h3:has(doc-comment-popup),
|
|
77
|
-
h4:has(doc-comment-popup) {
|
|
78
|
-
gap: var(--dx-g-spacing-2xs, 2px);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
@supports not (selector(:has(*))) {
|
|
82
|
-
h1,
|
|
83
|
-
h2,
|
|
84
|
-
h3,
|
|
85
|
-
h4 {
|
|
86
|
-
gap: var(--dx-g-spacing-2xs, 2px);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
@@ -1,54 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<h1 class={className} if:true={isAriaLevelOne}>
|
|
3
|
-
<!-- Comment Popup -->
|
|
4
|
-
<template if:true={hasCommentPopup}>
|
|
5
|
-
<doc-comment-popup
|
|
6
|
-
heading-title={headingTitle}
|
|
7
|
-
file-path={filePath}
|
|
8
|
-
start-line={startLine}
|
|
9
|
-
end-line={endLine}
|
|
10
|
-
current-branch={currentBranch}
|
|
11
|
-
></doc-comment-popup>
|
|
12
|
-
</template>
|
|
13
3
|
<doc-heading-content header={header} hash={hash}></doc-heading-content>
|
|
14
4
|
</h1>
|
|
15
5
|
<h2 class={className} if:true={isAriaLevelTwo}>
|
|
16
|
-
<!-- Comment Popup -->
|
|
17
|
-
<template if:true={hasCommentPopup}>
|
|
18
|
-
<doc-comment-popup
|
|
19
|
-
heading-title={headingTitle}
|
|
20
|
-
file-path={filePath}
|
|
21
|
-
start-line={startLine}
|
|
22
|
-
end-line={endLine}
|
|
23
|
-
current-branch={currentBranch}
|
|
24
|
-
></doc-comment-popup>
|
|
25
|
-
</template>
|
|
26
6
|
<doc-heading-content header={header} hash={hash}></doc-heading-content>
|
|
27
7
|
</h2>
|
|
28
8
|
<h3 class={className} if:true={isAriaLevelThree}>
|
|
29
|
-
<!-- Comment Popup -->
|
|
30
|
-
<template if:true={hasCommentPopup}>
|
|
31
|
-
<doc-comment-popup
|
|
32
|
-
heading-title={headingTitle}
|
|
33
|
-
file-path={filePath}
|
|
34
|
-
start-line={startLine}
|
|
35
|
-
end-line={endLine}
|
|
36
|
-
current-branch={currentBranch}
|
|
37
|
-
></doc-comment-popup>
|
|
38
|
-
</template>
|
|
39
9
|
<doc-heading-content header={header} hash={hash}></doc-heading-content>
|
|
40
10
|
</h3>
|
|
41
11
|
<h4 class={className} if:true={isAriaLevelFour}>
|
|
42
|
-
<!-- Comment Popup -->
|
|
43
|
-
<template if:true={hasCommentPopup}>
|
|
44
|
-
<doc-comment-popup
|
|
45
|
-
heading-title={headingTitle}
|
|
46
|
-
file-path={filePath}
|
|
47
|
-
start-line={startLine}
|
|
48
|
-
end-line={endLine}
|
|
49
|
-
current-branch={currentBranch}
|
|
50
|
-
></doc-comment-popup>
|
|
51
|
-
</template>
|
|
52
12
|
<doc-heading-content header={header} hash={hash}></doc-heading-content>
|
|
53
13
|
</h4>
|
|
54
14
|
</template>
|
|
@@ -16,21 +16,6 @@ export default class Heading extends LightningElement {
|
|
|
16
16
|
@api header: string = "";
|
|
17
17
|
@api hash: string | null = null;
|
|
18
18
|
|
|
19
|
-
// Comment popup attributes
|
|
20
|
-
@api index?: string;
|
|
21
|
-
@api filePath?: string;
|
|
22
|
-
@api startLine?: string;
|
|
23
|
-
@api endLine?: string;
|
|
24
|
-
@api currentBranch?: string;
|
|
25
|
-
|
|
26
|
-
// Comment popup properties
|
|
27
|
-
@api iconSymbol = "chat";
|
|
28
|
-
@api iconSize = "medium";
|
|
29
|
-
@api popupTitle = "Leave a Comment";
|
|
30
|
-
@api submitButtonLabel = "Post Comment";
|
|
31
|
-
@api emailPlaceholder = "Enter your email";
|
|
32
|
-
@api commentPlaceholder = "Enter your comment";
|
|
33
|
-
|
|
34
19
|
@api
|
|
35
20
|
private get ariaLevel(): string {
|
|
36
21
|
// Really Dark Magic (TM)
|
|
@@ -79,13 +64,4 @@ export default class Heading extends LightningElement {
|
|
|
79
64
|
private get className(): string {
|
|
80
65
|
return `dx-text-display-${this.displayLevel}`;
|
|
81
66
|
}
|
|
82
|
-
|
|
83
|
-
// Comment popup computed properties
|
|
84
|
-
get hasCommentPopup() {
|
|
85
|
-
return this.currentBranch !== undefined;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
get headingTitle() {
|
|
89
|
-
return this.header;
|
|
90
|
-
}
|
|
91
67
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<doc-content-layout
|
|
3
|
-
lwc:if={
|
|
3
|
+
lwc:if={displayContent}
|
|
4
4
|
lwc:ref="docContentLayout"
|
|
5
5
|
coveo-organization-id={coveoOrganizationId}
|
|
6
6
|
coveo-public-access-token={coveoPublicAccessToken}
|
|
@@ -49,4 +49,12 @@
|
|
|
49
49
|
onnavclick={handleNavClick}
|
|
50
50
|
></doc-content>
|
|
51
51
|
</doc-content-layout>
|
|
52
|
+
<div lwc:if={display404}>
|
|
53
|
+
<dx-error
|
|
54
|
+
image="https://a.sfdcstatic.com/developer-website/images/404.svg"
|
|
55
|
+
code="404"
|
|
56
|
+
header="Beep boop. That did not compute."
|
|
57
|
+
subtitle="The document you're looking for doesn't seem to exist."
|
|
58
|
+
></dx-error>
|
|
59
|
+
</div>
|
|
52
60
|
</template>
|
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
SiderbarFooter,
|
|
12
12
|
HistoryState,
|
|
13
13
|
PageReference,
|
|
14
|
-
TocMap
|
|
14
|
+
TocMap,
|
|
15
|
+
ContentData
|
|
15
16
|
} from "./types";
|
|
16
17
|
import { SearchSyncer } from "docUtils/searchSyncer";
|
|
17
18
|
import { LightningElementWithState } from "dxBaseElements/lightningElementWithState";
|
|
@@ -72,7 +73,8 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
72
73
|
private contentProvider?: FetchContent;
|
|
73
74
|
private docContent = "";
|
|
74
75
|
private language?: DocLanguage | null = null;
|
|
75
|
-
private
|
|
76
|
+
private displayContent = false;
|
|
77
|
+
private display404 = false;
|
|
76
78
|
private _pageHeader?: Header;
|
|
77
79
|
private pdfUrl = "";
|
|
78
80
|
private tocMap: TocMap = {};
|
|
@@ -185,7 +187,13 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
185
187
|
this.apiDomain,
|
|
186
188
|
this.allLanguages
|
|
187
189
|
);
|
|
188
|
-
this.fetchDocument().then(() =>
|
|
190
|
+
this.fetchDocument().then((content: any) => {
|
|
191
|
+
if (content) {
|
|
192
|
+
this.displayContent = true;
|
|
193
|
+
} else {
|
|
194
|
+
this.display404 = true;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
189
197
|
window.addEventListener("popstate", this.handlePopState);
|
|
190
198
|
|
|
191
199
|
this.searchSyncer.init();
|
|
@@ -463,7 +471,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
463
471
|
);
|
|
464
472
|
}
|
|
465
473
|
|
|
466
|
-
async fetchDocument(): Promise<
|
|
474
|
+
async fetchDocument(): Promise<string> {
|
|
467
475
|
this.setState({
|
|
468
476
|
isFetchingDocument: true
|
|
469
477
|
});
|
|
@@ -477,7 +485,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
477
485
|
this.setState({
|
|
478
486
|
isFetchingDocument: false
|
|
479
487
|
});
|
|
480
|
-
return;
|
|
488
|
+
return "";
|
|
481
489
|
}
|
|
482
490
|
|
|
483
491
|
this.docTitle = data.docTitle;
|
|
@@ -509,11 +517,11 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
509
517
|
data.id
|
|
510
518
|
) {
|
|
511
519
|
try {
|
|
512
|
-
await this.fetchContent();
|
|
520
|
+
const moreData = await this.fetchContent();
|
|
513
521
|
this.setState({
|
|
514
522
|
isFetchingDocument: false
|
|
515
523
|
});
|
|
516
|
-
return;
|
|
524
|
+
return moreData.content;
|
|
517
525
|
} catch (error) {
|
|
518
526
|
this.pageReference.contentDocumentId = `${data.id}.htm`;
|
|
519
527
|
this.pageReference.hash = "";
|
|
@@ -527,9 +535,10 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
527
535
|
this.setState({
|
|
528
536
|
isFetchingDocument: false
|
|
529
537
|
});
|
|
538
|
+
return data.content;
|
|
530
539
|
}
|
|
531
540
|
|
|
532
|
-
async fetchContent(): Promise<
|
|
541
|
+
async fetchContent(): Promise<ContentData> {
|
|
533
542
|
this.setState({
|
|
534
543
|
isFetchingContent: true
|
|
535
544
|
});
|
|
@@ -553,6 +562,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
553
562
|
this.setState({
|
|
554
563
|
isFetchingContent: false
|
|
555
564
|
});
|
|
565
|
+
return data;
|
|
556
566
|
}
|
|
557
567
|
|
|
558
568
|
updateHeaderAndSidebarFooter(): void {
|
|
@@ -1,322 +0,0 @@
|
|
|
1
|
-
# Comment Popup Component
|
|
2
|
-
|
|
3
|
-
A Lightning Web Component that allows users to leave comments on documentation sections. The component supports both local storage (for development) and a new API format for production use.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- ✅ **API Integration**: Now actively tries to fetch from `/get-comments` endpoint
|
|
8
|
-
- ✅ **Fallback Support**: Falls back to localStorage if API is unavailable
|
|
9
|
-
- ✅ **New API Format**: Supports branch-based comment fetching
|
|
10
|
-
- ✅ **Pre-loaded Comments**: Comments are fetched when component is rendered, not when popup opens
|
|
11
|
-
- ✅ **Local Storage**: Comments persist across page refreshes during development
|
|
12
|
-
- ✅ **Form Validation**: Email format and required field validation
|
|
13
|
-
- ✅ **Real-time Display**: Comments appear immediately after posting
|
|
14
|
-
- ✅ **Timestamp Formatting**: Shows relative time (e.g., "2 hours ago")
|
|
15
|
-
- ✅ **Email Masking**: Protects user privacy in comment display
|
|
16
|
-
- ✅ **Comment Count Badge**: Shows total number of comments
|
|
17
|
-
- ✅ **Responsive Design**: Works on mobile and desktop
|
|
18
|
-
- ✅ **Keyboard Accessibility**: ESC key to close popup
|
|
19
|
-
- ✅ **Dark Mode Support**: Adapts to system preferences
|
|
20
|
-
- ✅ **Development Tools**: Helper utilities for testing
|
|
21
|
-
|
|
22
|
-
## API Format
|
|
23
|
-
|
|
24
|
-
The component now supports a new API format where comments are fetched by branch and then filtered by file path and heading title.
|
|
25
|
-
|
|
26
|
-
### API Endpoints
|
|
27
|
-
|
|
28
|
-
- **GET** `/get-comments?branch={branch}` - Fetch all comments for a branch
|
|
29
|
-
- **POST** `/post-comment` - Add a new comment
|
|
30
|
-
|
|
31
|
-
### API Response Format
|
|
32
|
-
|
|
33
|
-
```json
|
|
34
|
-
{
|
|
35
|
-
"request_branch": "feature/documentation-updates",
|
|
36
|
-
"paths": [
|
|
37
|
-
{
|
|
38
|
-
"path": "docs/installation.md",
|
|
39
|
-
"titles": [
|
|
40
|
-
{
|
|
41
|
-
"title": "Installation Guide",
|
|
42
|
-
"comments": [
|
|
43
|
-
{
|
|
44
|
-
"email": "john.doe@example.com",
|
|
45
|
-
"comment_text": "This installation guide is very helpful for new users.",
|
|
46
|
-
"timestamp": "2024-01-15T10:30:00Z"
|
|
47
|
-
}
|
|
48
|
-
]
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
}
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### API Request Format
|
|
57
|
-
|
|
58
|
-
```json
|
|
59
|
-
{
|
|
60
|
-
"branch": "feature/documentation-updates",
|
|
61
|
-
"file_path": "docs/installation.md",
|
|
62
|
-
"heading_title": "Installation Guide",
|
|
63
|
-
"start_line": "1",
|
|
64
|
-
"end_line": "50",
|
|
65
|
-
"comment": {
|
|
66
|
-
"comment_text": "This is a helpful comment.",
|
|
67
|
-
"email": "user@example.com",
|
|
68
|
-
"timestamp": "2024-01-15T10:30:00Z"
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Usage
|
|
74
|
-
|
|
75
|
-
### Basic Usage
|
|
76
|
-
|
|
77
|
-
```html
|
|
78
|
-
<sb-doc-comment-popup
|
|
79
|
-
heading-title="Installation Guide"
|
|
80
|
-
file-path="docs/installation.md"
|
|
81
|
-
current-branch="feature/documentation-updates"
|
|
82
|
-
start-line="1"
|
|
83
|
-
end-line="50"
|
|
84
|
-
open="false"
|
|
85
|
-
icon-symbol="chat"
|
|
86
|
-
icon-size="medium"
|
|
87
|
-
>
|
|
88
|
-
</sb-doc-comment-popup>
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Comment Loading Behavior
|
|
92
|
-
|
|
93
|
-
The component now fetches comments when it is rendered (connected to the DOM) rather than when the popup is opened. This ensures:
|
|
94
|
-
|
|
95
|
-
- **Faster Popup Opening**: Comments are already loaded when the user clicks the icon
|
|
96
|
-
- **Immediate Comment Count**: The comment count badge shows the correct number immediately
|
|
97
|
-
- **Better User Experience**: No loading delay when opening the popup
|
|
98
|
-
|
|
99
|
-
Comments are automatically refetched when any of these properties change:
|
|
100
|
-
|
|
101
|
-
- `heading-title`
|
|
102
|
-
- `file-path`
|
|
103
|
-
- `current-branch`
|
|
104
|
-
|
|
105
|
-
### Required Properties
|
|
106
|
-
|
|
107
|
-
- `heading-title`: The title of the section being commented on
|
|
108
|
-
- `file-path`: The file path where the comment is located
|
|
109
|
-
- `current-branch`: The current git branch
|
|
110
|
-
|
|
111
|
-
### Optional Properties
|
|
112
|
-
|
|
113
|
-
- `start-line`: Starting line number (for future line-specific comments)
|
|
114
|
-
- `end-line`: Ending line number (for future line-specific comments)
|
|
115
|
-
- `open`: Controls the popup visibility (default: false)
|
|
116
|
-
- `icon-symbol`: Icon symbol for the comment button (default: "chat")
|
|
117
|
-
- `icon-size`: Size of the comment icon (default: "medium")
|
|
118
|
-
|
|
119
|
-
### Available Icon Symbols
|
|
120
|
-
|
|
121
|
-
- `chat` - Chat bubble icon
|
|
122
|
-
- `comment` - Comment icon
|
|
123
|
-
- `message` - Message icon
|
|
124
|
-
- `feedback` - Feedback icon
|
|
125
|
-
|
|
126
|
-
### Available Icon Sizes
|
|
127
|
-
|
|
128
|
-
- `small` - Small icon
|
|
129
|
-
- `medium` - Medium icon (default)
|
|
130
|
-
- `large` - Large icon
|
|
131
|
-
|
|
132
|
-
## Local Storage Implementation
|
|
133
|
-
|
|
134
|
-
During development, the component uses localStorage to persist comments. Comments are stored with a unique key format:
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
{branch}_{file_path}_{heading_title}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Local Storage Structure
|
|
141
|
-
|
|
142
|
-
```json
|
|
143
|
-
{
|
|
144
|
-
"main_docs/installation.md_Installation Guide": [
|
|
145
|
-
{
|
|
146
|
-
"email": "user@example.com",
|
|
147
|
-
"comment_text": "This is a comment",
|
|
148
|
-
"timestamp": "2024-01-15T10:30:00Z"
|
|
149
|
-
}
|
|
150
|
-
]
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Development Tools
|
|
155
|
-
|
|
156
|
-
The component includes development tools for testing and managing comments during development.
|
|
157
|
-
|
|
158
|
-
### Console Commands
|
|
159
|
-
|
|
160
|
-
```javascript
|
|
161
|
-
// Export all comments to a JSON file
|
|
162
|
-
CommentDevHelper.exportCommentsToFile();
|
|
163
|
-
|
|
164
|
-
// Add sample comments matching the new API format
|
|
165
|
-
CommentDevHelper.addSampleCommentsForNewApi();
|
|
166
|
-
|
|
167
|
-
// Get statistics about stored comments
|
|
168
|
-
CommentDevHelper.getCommentsStats();
|
|
169
|
-
|
|
170
|
-
// Clear all comments from localStorage
|
|
171
|
-
CommentDevHelper.clearAllComments();
|
|
172
|
-
|
|
173
|
-
// Test the API response format
|
|
174
|
-
CommentDevHelper.testApiResponseFormat();
|
|
175
|
-
|
|
176
|
-
// Simulate API call for a specific branch
|
|
177
|
-
CommentDevHelper.simulateApiCall("main");
|
|
178
|
-
|
|
179
|
-
// Show all comments in console
|
|
180
|
-
CommentDevHelper.showAllComments();
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Development UI
|
|
184
|
-
|
|
185
|
-
The component automatically creates a development UI when running on localhost. This UI provides buttons for:
|
|
186
|
-
|
|
187
|
-
- Adding sample comments
|
|
188
|
-
- Testing API response format
|
|
189
|
-
- Exporting comments
|
|
190
|
-
- Clearing all comments
|
|
191
|
-
- Viewing statistics
|
|
192
|
-
|
|
193
|
-
## API Integration Status
|
|
194
|
-
|
|
195
|
-
The component now actively tries to use the backend API with localStorage as a fallback:
|
|
196
|
-
|
|
197
|
-
### Current Behavior
|
|
198
|
-
|
|
199
|
-
1. **Fetch Comments**: First tries `/get-comments?branch={branch}`, falls back to localStorage if API fails
|
|
200
|
-
2. **Post Comments**: First tries `/post-comment`, falls back to localStorage if API fails
|
|
201
|
-
3. **Error Handling**: Graceful degradation with console warnings for debugging
|
|
202
|
-
4. **Backward Compatibility**: localStorage continues to work for development and offline scenarios
|
|
203
|
-
|
|
204
|
-
### API Endpoints
|
|
205
|
-
|
|
206
|
-
- **GET** `/get-comments?branch={branch}` - Fetch all comments for a branch
|
|
207
|
-
- **POST** `/post-comment` - Add a new comment
|
|
208
|
-
|
|
209
|
-
### Fallback Strategy
|
|
210
|
-
|
|
211
|
-
```typescript
|
|
212
|
-
// Fetch comments with fallback
|
|
213
|
-
try {
|
|
214
|
-
const response = await fetch(`/get-comments?${params.toString()}`);
|
|
215
|
-
if (response.ok) {
|
|
216
|
-
// Use API response
|
|
217
|
-
const data = await response.json();
|
|
218
|
-
this.comments = this.extractCommentsFromApiResponse(data);
|
|
219
|
-
} else {
|
|
220
|
-
// Fallback to localStorage
|
|
221
|
-
this.comments = await this.getCommentsFromLocalStorage();
|
|
222
|
-
}
|
|
223
|
-
} catch (error) {
|
|
224
|
-
// Fallback to localStorage on network error
|
|
225
|
-
this.comments = await this.getCommentsFromLocalStorage();
|
|
226
|
-
}
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### Testing API Integration
|
|
230
|
-
|
|
231
|
-
Use the development tools to test API integration:
|
|
232
|
-
|
|
233
|
-
```javascript
|
|
234
|
-
// Test API response format
|
|
235
|
-
CommentDevHelper.testApiResponseFormat();
|
|
236
|
-
|
|
237
|
-
// Simulate API call for a specific branch
|
|
238
|
-
CommentDevHelper.simulateApiCall("main");
|
|
239
|
-
|
|
240
|
-
// Check if API is available
|
|
241
|
-
CommentDevHelper.checkApiAvailability();
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
## Testing
|
|
245
|
-
|
|
246
|
-
### Storybook Stories
|
|
247
|
-
|
|
248
|
-
The component includes comprehensive Storybook stories for testing:
|
|
249
|
-
|
|
250
|
-
1. **Base**: Basic component functionality
|
|
251
|
-
2. **WithNewApiFormatComments**: Testing with new API format
|
|
252
|
-
3. **MultipleBranchesAndFiles**: Testing multiple branches and files
|
|
253
|
-
4. **FormValidation**: Testing form validation features
|
|
254
|
-
|
|
255
|
-
### Jest Tests
|
|
256
|
-
|
|
257
|
-
Run the test suite:
|
|
258
|
-
|
|
259
|
-
```bash
|
|
260
|
-
npm test commentPopup.test.ts
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
The test suite covers:
|
|
264
|
-
|
|
265
|
-
- Component initialization
|
|
266
|
-
- Form validation
|
|
267
|
-
- Local storage operations
|
|
268
|
-
- API response format handling
|
|
269
|
-
- Comment operations
|
|
270
|
-
- UI interactions
|
|
271
|
-
- Error handling
|
|
272
|
-
- Lifecycle methods
|
|
273
|
-
|
|
274
|
-
## Troubleshooting
|
|
275
|
-
|
|
276
|
-
### Common Issues
|
|
277
|
-
|
|
278
|
-
1. **Comments not appearing**: Check that `heading-title`, `file-path`, and `current-branch` are set correctly
|
|
279
|
-
2. **Form validation errors**: Ensure email format is valid and all required fields are filled
|
|
280
|
-
3. **localStorage errors**: Check browser console for localStorage quota exceeded errors
|
|
281
|
-
4. **API integration issues**: Verify API endpoints and response format match expected structure
|
|
282
|
-
|
|
283
|
-
### Debug Commands
|
|
284
|
-
|
|
285
|
-
```javascript
|
|
286
|
-
// Check current comments
|
|
287
|
-
console.log(CommentDevHelper.getAllComments());
|
|
288
|
-
|
|
289
|
-
// Check component state
|
|
290
|
-
console.log(element.comments);
|
|
291
|
-
console.log(element.email);
|
|
292
|
-
console.log(element.comment);
|
|
293
|
-
|
|
294
|
-
// Test API response parsing
|
|
295
|
-
CommentDevHelper.testApiResponseFormat();
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
## Browser Support
|
|
299
|
-
|
|
300
|
-
- Chrome 60+
|
|
301
|
-
- Firefox 55+
|
|
302
|
-
- Safari 12+
|
|
303
|
-
- Edge 79+
|
|
304
|
-
|
|
305
|
-
## Dependencies
|
|
306
|
-
|
|
307
|
-
- Lightning Web Components (LWC)
|
|
308
|
-
- TypeScript
|
|
309
|
-
- Jest (for testing)
|
|
310
|
-
|
|
311
|
-
## Contributing
|
|
312
|
-
|
|
313
|
-
1. Fork the repository
|
|
314
|
-
2. Create a feature branch
|
|
315
|
-
3. Make your changes
|
|
316
|
-
4. Add tests for new functionality
|
|
317
|
-
5. Update documentation
|
|
318
|
-
6. Submit a pull request
|
|
319
|
-
|
|
320
|
-
## License
|
|
321
|
-
|
|
322
|
-
This component is part of the Salesforce Developer Documentation Components package.
|