@salesforcedevs/docs-components 0.0.10-edit → 0.0.11-edit

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/docs-components",
3
- "version": "0.0.10-edit",
3
+ "version": "0.0.11-edit",
4
4
  "description": "Docs Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -57,7 +57,7 @@ export default class Chat extends LightningElement {
57
57
  // API Configuration
58
58
  private static readonly API_URL =
59
59
  "https://276ca7264b79.ngrok-free.app/api/llm/search";
60
- private static readonly MAX_RESULTS = 5;
60
+ private static readonly MAX_RESULTS = 3;
61
61
 
62
62
  // Development mode flag - set to true if running in development
63
63
  private static readonly IS_DEVELOPMENT =
@@ -223,11 +223,77 @@
223
223
  font-weight: 500;
224
224
  }
225
225
 
226
+ /* Success State */
227
+ .edit-file-success {
228
+ display: flex;
229
+ align-items: flex-start;
230
+ gap: 16px;
231
+ padding: 20px;
232
+ background: #f0f9f4;
233
+ border: 1px solid #d1fae5;
234
+ border-radius: 12px;
235
+ margin-bottom: 24px;
236
+ }
237
+
238
+ .edit-file-success-icon {
239
+ width: 24px;
240
+ height: 24px;
241
+ color: #059669;
242
+ flex-shrink: 0;
243
+ margin-top: 2px;
244
+ }
245
+
246
+ .edit-file-success-content {
247
+ flex: 1;
248
+ display: flex;
249
+ flex-direction: column;
250
+ gap: 12px;
251
+ }
252
+
253
+ .edit-file-success-text {
254
+ font-size: 14px;
255
+ font-weight: 500;
256
+ color: #065f46;
257
+ line-height: 1.5;
258
+ }
259
+
260
+ .edit-file-pr-link {
261
+ display: inline-flex;
262
+ align-items: center;
263
+ gap: 6px;
264
+ color: #0176d3;
265
+ text-decoration: none;
266
+ font-size: 14px;
267
+ font-weight: 500;
268
+ transition: color 0.2s cubic-bezier(0.4, 0, 0.2, 1);
269
+ }
270
+
271
+ .edit-file-pr-link:hover {
272
+ color: #005fb2;
273
+ text-decoration: underline;
274
+ }
275
+
276
+ .edit-file-pr-link:focus {
277
+ outline: 2px solid #0176d3;
278
+ outline-offset: 2px;
279
+ border-radius: 4px;
280
+ }
281
+
282
+ .edit-file-success-footer {
283
+ display: flex;
284
+ justify-content: flex-end;
285
+ width: 100%;
286
+ }
287
+
226
288
  /* Editor */
227
289
  .edit-file-editor {
228
290
  width: 100%;
229
291
  }
230
292
 
293
+ .edit-file-editor_readonly {
294
+ opacity: 0.7;
295
+ }
296
+
231
297
  .edit-file-label {
232
298
  display: block;
233
299
  margin-bottom: 8px;
@@ -253,12 +319,25 @@
253
319
  box-sizing: border-box;
254
320
  }
255
321
 
322
+ .edit-file-textarea_readonly {
323
+ background: #f8f9fa;
324
+ border-color: #d1d5db;
325
+ color: #6b7280;
326
+ cursor: not-allowed;
327
+ }
328
+
256
329
  .edit-file-textarea:focus {
257
330
  border-color: #0176d3;
258
331
  background: white;
259
332
  box-shadow: 0 0 0 3px rgb(1 118 211 / 10%);
260
333
  }
261
334
 
335
+ .edit-file-textarea_readonly:focus {
336
+ border-color: #d1d5db;
337
+ background: #f8f9fa;
338
+ box-shadow: none;
339
+ }
340
+
262
341
  .edit-file-textarea::placeholder {
263
342
  color: #9ca3af;
264
343
  }
@@ -472,6 +551,28 @@
472
551
  min-height: 250px;
473
552
  padding: 12px;
474
553
  }
554
+
555
+ .edit-file-success {
556
+ padding: 12px;
557
+ gap: 8px;
558
+ }
559
+
560
+ .edit-file-success-icon {
561
+ width: 18px;
562
+ height: 18px;
563
+ }
564
+
565
+ .edit-file-success-content {
566
+ gap: 6px;
567
+ }
568
+
569
+ .edit-file-success-text {
570
+ font-size: 12px;
571
+ }
572
+
573
+ .edit-file-pr-link {
574
+ font-size: 12px;
575
+ }
475
576
  }
476
577
 
477
578
  /* Accessibility improvements */
@@ -100,61 +100,124 @@
100
100
  </div>
101
101
  </template>
102
102
 
103
- <!-- Content Editor -->
104
- <template lwc:if={fileContent}>
105
- <div class="edit-file-editor">
106
- <label class="edit-file-label" for="file-content">
107
- File Content
108
- </label>
109
- <textarea
110
- id="file-content"
111
- class="edit-file-textarea"
112
- oninput={handleContentChange}
113
- placeholder="Enter file content..."
114
- rows="20"
115
- spellcheck="false"
116
- ></textarea>
103
+ <!-- Success Message -->
104
+ <template lwc:if={isSuccessState}>
105
+ <div class="edit-file-success">
106
+ <svg
107
+ class="edit-file-success-icon"
108
+ viewBox="0 0 24 24"
109
+ fill="none"
110
+ stroke="currentColor"
111
+ >
112
+ <path
113
+ stroke-linecap="round"
114
+ stroke-linejoin="round"
115
+ stroke-width="2"
116
+ d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
117
+ />
118
+ </svg>
119
+ <div class="edit-file-success-content">
120
+ <span class="edit-file-success-text">
121
+ {successMessage}
122
+ </span>
123
+ <template lwc:if={prUrl}>
124
+ <a
125
+ href={prUrl}
126
+ target="_blank"
127
+ rel="noopener noreferrer"
128
+ class="edit-file-pr-link"
129
+ >
130
+ View Pull Request
131
+ </a>
132
+ </template>
133
+ </div>
117
134
  </div>
118
135
  </template>
119
- </div>
120
136
 
121
- <!-- Popover Footer -->
122
- <div class="edit-file-footer">
123
- <div class="edit-file-status">
124
- <template lwc:if={isSaving}>
125
- <div class="edit-file-saving">
126
- <div class="edit-file-mini-spinner"></div>
127
- <span>Saving...</span>
137
+ <!-- Content Editor -->
138
+ <template lwc:if={fileContent}>
139
+ <template lwc:if={isSuccessState}>
140
+ <div class="edit-file-editor edit-file-editor_readonly">
141
+ <label class="edit-file-label" for="file-content-readonly">
142
+ File Content (Saved)
143
+ </label>
144
+ <textarea
145
+ id="file-content-readonly"
146
+ class="edit-file-textarea edit-file-textarea_readonly"
147
+ readonly
148
+ placeholder="Enter file content..."
149
+ rows="20"
150
+ spellcheck="false"
151
+ ></textarea>
128
152
  </div>
129
153
  </template>
130
- <template lwc:elseif={isContentUnchanged}>
131
- <span class="edit-file-unchanged">No changes</span>
132
- </template>
133
154
  <template lwc:else>
134
- <span class="edit-file-modified">Modified</span>
155
+ <div class="edit-file-editor">
156
+ <label class="edit-file-label" for="file-content">
157
+ File Content
158
+ </label>
159
+ <textarea
160
+ id="file-content"
161
+ class="edit-file-textarea"
162
+ oninput={handleContentChange}
163
+ placeholder="Enter file content..."
164
+ rows="20"
165
+ spellcheck="false"
166
+ ></textarea>
167
+ </div>
135
168
  </template>
136
- </div>
169
+ </template>
170
+ </div>
137
171
 
138
- <div class="edit-file-actions">
139
- <button
140
- class="edit-file-button edit-file-button_secondary"
141
- onclick={handleCancel}
142
- disabled={isSaving}
143
- >
144
- Cancel
145
- </button>
146
- <button
147
- class={saveButtonClass}
148
- onclick={handleSave}
149
- disabled={isSaving}
150
- >
172
+ <!-- Popover Footer -->
173
+ <div class="edit-file-footer">
174
+ <template lwc:if={isSuccessState}>
175
+ <div class="edit-file-success-footer">
176
+ <button
177
+ class="edit-file-button edit-file-button_primary"
178
+ onclick={handleCancel}
179
+ >
180
+ Close
181
+ </button>
182
+ </div>
183
+ </template>
184
+ <template lwc:else>
185
+ <div class="edit-file-status">
151
186
  <template lwc:if={isSaving}>
152
- <div class="edit-file-button-spinner"></div>
153
- Saving...
187
+ <div class="edit-file-saving">
188
+ <div class="edit-file-mini-spinner"></div>
189
+ <span>Saving...</span>
190
+ </div>
191
+ </template>
192
+ <template lwc:elseif={isContentUnchanged}>
193
+ <span class="edit-file-unchanged">No changes</span>
194
+ </template>
195
+ <template lwc:else>
196
+ <span class="edit-file-modified">Modified</span>
154
197
  </template>
155
- <template lwc:else>Save</template>
156
- </button>
157
- </div>
198
+ </div>
199
+
200
+ <div class="edit-file-actions">
201
+ <button
202
+ class="edit-file-button edit-file-button_secondary"
203
+ onclick={handleCancel}
204
+ disabled={isSaving}
205
+ >
206
+ Cancel
207
+ </button>
208
+ <button
209
+ class={saveButtonClass}
210
+ onclick={handleSave}
211
+ disabled={isSaving}
212
+ >
213
+ <template lwc:if={isSaving}>
214
+ <div class="edit-file-button-spinner"></div>
215
+ Saving...
216
+ </template>
217
+ <template lwc:else>Save</template>
218
+ </button>
219
+ </div>
220
+ </template>
158
221
  </div>
159
222
  </div>
160
223
  </div>
@@ -2,15 +2,30 @@ import { LightningElement, api, track } from "lwc";
2
2
  import cx from "classnames";
3
3
  import { normalizeBoolean } from "dxUtils/normalizers";
4
4
 
5
- interface ApiResponse {
5
+ interface FetchApiResponse {
6
6
  success: boolean;
7
7
  data?: {
8
8
  content: string;
9
+ filename: string;
10
+ format: string;
9
11
  };
12
+ repositoryUrl?: string;
13
+ filePath?: string;
14
+ href?: string;
15
+ source?: string;
16
+ timestamp?: string;
10
17
  message?: string;
11
18
  error?: string;
12
19
  }
13
20
 
21
+ interface SaveApiResponse {
22
+ success: boolean;
23
+ message?: string;
24
+ branchName?: string;
25
+ prUrl?: string;
26
+ error?: string;
27
+ }
28
+
14
29
  export default class EditFile extends LightningElement {
15
30
  @api fileName: string = "";
16
31
  @api repoName: string = "";
@@ -33,13 +48,17 @@ export default class EditFile extends LightningElement {
33
48
  @track fileContent: string = "";
34
49
  @track originalContent: string = "";
35
50
  @track errorMessage: string = "";
51
+ @track repositoryUrl: string = "";
52
+ @track filePath: string = "";
53
+ @track successMessage: string = "";
54
+ @track prUrl: string = "";
36
55
 
37
56
  private _disabled: boolean = false;
38
57
 
39
58
  // API Configuration
40
59
  private static readonly FETCH_ENDPOINT =
41
60
  "https://1208ddd77328.ngrok-free.app/api/file-retrieval/retrieve";
42
- private static readonly SAVE_ENDPOINT = "/api/file/save";
61
+ private static readonly SAVE_ENDPOINT = "https://1208ddd77328.ngrok-free.app/api/github/create-branch-commit-pr";
43
62
 
44
63
  get popoverClass() {
45
64
  return cx(
@@ -68,6 +87,10 @@ export default class EditFile extends LightningElement {
68
87
  return this.fileContent === this.originalContent;
69
88
  }
70
89
 
90
+ get isSuccessState() {
91
+ return this.successMessage !== "";
92
+ }
93
+
71
94
  // Open the edit file popover
72
95
  async handleEditClick() {
73
96
  if (this.disabled) {
@@ -104,13 +127,15 @@ export default class EditFile extends LightningElement {
104
127
  throw new Error(`Failed to fetch file: ${response.status}`);
105
128
  }
106
129
 
107
- const data: ApiResponse = await response.json();
130
+ const data: FetchApiResponse = await response.json();
108
131
 
109
132
  if (data.success && data.data !== undefined) {
110
133
  this.fileContent = data.data.content;
111
134
  this.originalContent = data.data.content;
135
+ this.repositoryUrl = data.repositoryUrl || "";
136
+ this.filePath = data.filePath || "";
112
137
  this.errorMessage = "";
113
-
138
+
114
139
  // Set textarea value directly using ref
115
140
  this.updateTextareaValue();
116
141
  } else {
@@ -140,6 +165,10 @@ export default class EditFile extends LightningElement {
140
165
  this.fileContent = "";
141
166
  this.originalContent = "";
142
167
  this.errorMessage = "";
168
+ this.successMessage = "";
169
+ this.prUrl = "";
170
+ this.repositoryUrl = "";
171
+ this.filePath = "";
143
172
  this.isLoading = false;
144
173
  this.isSaving = false;
145
174
 
@@ -166,10 +195,10 @@ export default class EditFile extends LightningElement {
166
195
  headers: {
167
196
  "Content-Type": "application/json"
168
197
  },
169
- body: JSON.stringify({
170
- fileName: this.fileName,
171
- content: this.fileContent,
172
- action: "save"
198
+ body: JSON.stringify({
199
+ repositoryUrl: this.repositoryUrl,
200
+ filePath: this.filePath,
201
+ content: this.fileContent
173
202
  })
174
203
  });
175
204
 
@@ -177,19 +206,22 @@ export default class EditFile extends LightningElement {
177
206
  throw new Error(`Failed to save file: ${response.status}`);
178
207
  }
179
208
 
180
- const data: ApiResponse = await response.json();
209
+ const data: SaveApiResponse = await response.json();
181
210
 
182
211
  if (data.success) {
183
212
  this.originalContent = this.fileContent;
184
- this.isPopoverOpen = false;
185
-
213
+ this.successMessage = data.message || "File saved successfully";
214
+ this.prUrl = data.prUrl || "";
215
+
186
216
  // Dispatch success event
187
217
  this.dispatchEvent(
188
218
  new CustomEvent("editsuccess", {
189
- detail: {
219
+ detail: {
190
220
  fileName: this.fileName,
191
221
  content: this.fileContent,
192
- message: data.message || "File saved successfully"
222
+ message: this.successMessage,
223
+ prUrl: this.prUrl,
224
+ branchName: data.branchName
193
225
  }
194
226
  })
195
227
  );
@@ -226,11 +258,19 @@ export default class EditFile extends LightningElement {
226
258
  private updateTextareaValue() {
227
259
  // Use setTimeout to ensure DOM is updated
228
260
  setTimeout(() => {
229
- const textarea = this.template.querySelector(
261
+ const editableTextarea = this.template.querySelector(
230
262
  "#file-content"
231
263
  ) as HTMLTextAreaElement;
232
- if (textarea && this.fileContent !== undefined) {
233
- textarea.value = this.fileContent;
264
+ const readonlyTextarea = this.template.querySelector(
265
+ "#file-content-readonly"
266
+ ) as HTMLTextAreaElement;
267
+
268
+ if (editableTextarea && this.fileContent !== undefined) {
269
+ editableTextarea.value = this.fileContent;
270
+ }
271
+
272
+ if (readonlyTextarea && this.fileContent !== undefined) {
273
+ readonlyTextarea.value = this.fileContent;
234
274
  }
235
275
  }, 0);
236
276
  }