|
231 | 231 | { |
232 | 232 | <div class="modal-overlay" @onclick="ToggleSavedModal"> |
233 | 233 | <div class="saved-modal" @onclick:stopPropagation="true"> |
234 | | - <h5>Saved Responses</h5> |
235 | | - @if (_savedItems is null) |
| 234 | + @if (_viewingItem is not null) |
236 | 235 | { |
237 | | - <p>Loading...</p> |
238 | | - } |
239 | | - else if (_savedItems.Count == 0) |
240 | | - { |
241 | | - <p class="text-muted">No saved responses yet.</p> |
| 236 | + <div class="saved-view-header"> |
| 237 | + <h5>@_viewingItem.Label</h5> |
| 238 | + <small class="saved-item-meta">@_viewingItem.AgentName — @TimeZoneInfo.ConvertTime(_viewingItem.SavedAt, _displayZone).ToString("MMM d, yyyy h:mm tt")</small> |
| 239 | + </div> |
| 240 | + <div class="saved-view-content"> |
| 241 | + @((MarkupString)Markdig.Markdown.ToHtml(_viewingItem.Content, MarkdownPipeline)) |
| 242 | + </div> |
| 243 | + <div class="d-flex gap-2 mt-2"> |
| 244 | + <button class="btn btn-sm btn-secondary" @onclick="BackToSavedList">Back</button> |
| 245 | + <button class="btn btn-sm btn-primary" @onclick="() => InsertViewedItem()">Insert into chat</button> |
| 246 | + </div> |
242 | 247 | } |
243 | 248 | else |
244 | 249 | { |
245 | | - @foreach (var item in _savedItems) |
| 250 | + <h5>Saved Responses</h5> |
| 251 | + @if (_savedItems is null) |
| 252 | + { |
| 253 | + <p>Loading...</p> |
| 254 | + } |
| 255 | + else if (_savedItems.Count == 0) |
| 256 | + { |
| 257 | + <p class="text-muted">No saved responses yet.</p> |
| 258 | + } |
| 259 | + else |
246 | 260 | { |
247 | | - <div class="saved-item d-flex justify-content-between align-items-center p-2 mb-1 rounded"> |
248 | | - <div class="saved-item-info" @onclick="() => LoadSavedItem(item.Id)" style="cursor:pointer;"> |
249 | | - <strong>@item.Label</strong> |
250 | | - <small class="saved-item-meta d-block">@item.AgentName — @TimeZoneInfo.ConvertTime(item.SavedAt, _displayZone).ToString("MMM d, yyyy h:mm tt")</small> |
| 261 | + @foreach (var item in _savedItems) |
| 262 | + { |
| 263 | + <div class="saved-item d-flex justify-content-between align-items-center p-2 mb-1 rounded"> |
| 264 | + <div class="saved-item-info" @onclick="() => LoadSavedItem(item.Id)" style="cursor:pointer;" title="Insert into chat"> |
| 265 | + <strong>@item.Label</strong> |
| 266 | + <small class="saved-item-meta d-block">@item.AgentName — @TimeZoneInfo.ConvertTime(item.SavedAt, _displayZone).ToString("MMM d, yyyy h:mm tt")</small> |
| 267 | + </div> |
| 268 | + <div class="d-flex gap-1"> |
| 269 | + <button class="btn btn-sm btn-outline-secondary" @onclick="() => ViewSavedItem(item.Id)" title="View">👁️</button> |
| 270 | + <button class="btn btn-sm btn-outline-danger" @onclick="() => DeleteSavedItem(item.Id)" title="Delete">🗑️</button> |
| 271 | + </div> |
251 | 272 | </div> |
252 | | - <button class="btn btn-sm btn-outline-danger" @onclick="() => DeleteSavedItem(item.Id)">🗑️</button> |
253 | | - </div> |
| 273 | + } |
254 | 274 | } |
| 275 | + <button class="btn btn-sm btn-secondary mt-2" @onclick="ToggleSavedModal">Close</button> |
255 | 276 | } |
256 | | - <button class="btn btn-sm btn-secondary mt-2" @onclick="ToggleSavedModal">Close</button> |
257 | 277 | </div> |
258 | 278 | </div> |
259 | 279 | } |
|
311 | 331 | private string _saveLabel = string.Empty; |
312 | 332 | private bool _showSavedModal; |
313 | 333 | private IReadOnlyList<SavedResponseSummary>? _savedItems; |
| 334 | + private GetSavedResponseResponse? _viewingItem; |
314 | 335 |
|
315 | 336 | private static readonly MarkdownPipeline MarkdownPipeline = new MarkdownPipelineBuilder() |
316 | 337 | .UseAdvancedExtensions() |
|
583 | 604 | private async Task ToggleSavedModal() |
584 | 605 | { |
585 | 606 | _showSavedModal = !_showSavedModal; |
| 607 | + _viewingItem = null; |
586 | 608 | if (_showSavedModal) |
587 | 609 | { |
588 | 610 | _savedItems = null; |
|
602 | 624 | private async Task LoadSavedItem(string id) |
603 | 625 | { |
604 | 626 | _showSavedModal = false; |
| 627 | + _viewingItem = null; |
605 | 628 | try |
606 | 629 | { |
607 | 630 | var response = await ProxyService.GetSavedResponseAsync(id); |
|
614 | 637 | } |
615 | 638 | } |
616 | 639 |
|
| 640 | + private async Task ViewSavedItem(string id) |
| 641 | + { |
| 642 | + try |
| 643 | + { |
| 644 | + var response = await ProxyService.GetSavedResponseAsync(id); |
| 645 | + if (response is not null && response.Found) |
| 646 | + _viewingItem = response; |
| 647 | + } |
| 648 | + catch (Exception ex) |
| 649 | + { |
| 650 | + ChatState.AddError($"Could not load saved response: {ex.Message}"); |
| 651 | + } |
| 652 | + } |
| 653 | + |
| 654 | + private void BackToSavedList() |
| 655 | + { |
| 656 | + _viewingItem = null; |
| 657 | + } |
| 658 | + |
| 659 | + private void InsertViewedItem() |
| 660 | + { |
| 661 | + if (_viewingItem is null) return; |
| 662 | + ChatState.AddSavedReference(_viewingItem.Id, _viewingItem.Label, _viewingItem.Content, _viewingItem.AgentName); |
| 663 | + _viewingItem = null; |
| 664 | + _showSavedModal = false; |
| 665 | + } |
| 666 | + |
617 | 667 | private async Task DeleteSavedItem(string id) |
618 | 668 | { |
619 | 669 | try |
|
0 commit comments