SeemGen/Components/Partials/GenerateFromScratch.razor

288 lines
11 KiB
Plaintext

@using BLAIzor.Models
@using BLAIzor.Services
@using Newtonsoft.Json
@using BLAIzor.Components.Partials
@using System.Collections.ObjectModel
@inject ContentEditorService ContentEditorService
@inject ContentEditorAIService ContentEditorAIService
@inject HtmlSnippetProcessor HtmlSnippetProcessor
@inject QDrantService QDrantService
@inject IJSRuntime JSRuntime
<div>
<label for="subject">Enter the subject of your website:</label>
<input id="subject" @bind="subject" class="form-control" placeholder="e.g., Web Design Company" />
<button class="btn btn-primary mt-2" @onclick="GenerateMenuItems">Generate Menu Items</button>
</div>
@if (isLoading)
{
<p>Loading suggestions...</p>
}
else if (extractedMenuItems.Any())
{
<h4>Suggested Menu Items</h4>
<div class="row">
<div class="rz-p-sm-12">
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Right">
@{
<RadzenButton Click="ToggleReorder">
@(allowReorder ? "Done" : "Reorder")
</RadzenButton>
}
</RadzenStack>
@if (allowReorder)
{
<RadzenDataGrid @ref="dataGrid" TItem="MenuItem" RowSelect=@OnRowSelect AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.Advanced" AllowSorting="true" PageSize="20" AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true"
Data="@menuItems" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single"
@bind-Value=@selectedMenuItems RowRender="@RowRender">
<Columns>
<RadzenDataGridColumn Property="@nameof(MenuItem.SortOrder)" Title="Sort order" Width="30px" />
@* <RadzenDataGridColumn Property="@nameof(MenuItem.Id)" Filterable="false" Title="ID" Frozen="true" Width="55px" TextAlign="TextAlign.Center" /> *@
<RadzenDataGridColumn Property="@nameof(MenuItem.Name)" Title="Name" Frozen="true" Width="130px" />
@* <RadzenDataGridColumn Property="@nameof(MenuItem.PointId)" Title="Point Id" Width="200px" /> *@
<RadzenDataGridColumn Property="@nameof(MenuItem.ShowInMainMenu)" Title="Show in menu" Width="30px" />
</Columns>
</RadzenDataGrid>
}
else
{
<RadzenAccordion Multiple="true">
<Items>
@foreach (var item in extractedMenuItems)
{
<RadzenAccordionItem Text="@item.MenuItem.Name" Icon="account_balance_wallet">
@{
if (MenuItemsSaved)
{
<input @bind="item.MenuItem.Name" class="form-control border-0" placeholder="Menu item name" />
<MenuItemContentEditor Subject=@subject MenuItem="item" OnContentUpdated="UpdateMenuItem" SessionId="SessionId" />
<div class="card-footer">
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
</div>
}
}
</RadzenAccordionItem>
}
</Items>
</RadzenAccordion>
}
</div>
</div>
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
<button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
}
else if (!string.IsNullOrEmpty(errorMessage))
{
<p class="text-danger">@errorMessage</p>
}
@code {
[Parameter]
public int SiteId { get; set; }
[Parameter]
public string SessionId { get; set; }
private string subject = string.Empty;
ObservableCollection<MenuItem> menuItems;
IList<MenuItem> selectedMenuItems;
private List<MenuItemModel> extractedMenuItems = new();
private bool MenuItemsSaved = false;
private bool isLoading = false;
private string? errorMessage;
private bool hasCollection = false;
private bool allowReorder = false;
private RadzenDataGrid<MenuItem> dataGrid;
MenuItem draggedItem;
MenuItemModel SelectedMenuItemModel = new("");
protected override async Task OnParametersSetAsync()
{
menuItems = new ObservableCollection<MenuItem>((await ContentEditorService.GetMenuItemsBySiteIdAsync(SiteId)).OrderBy(x => x.SortOrder));
var collectionResult = await QDrantService.GetCollectionBySiteIdAsync(SiteId);
if (!string.IsNullOrEmpty(collectionResult))
{
//create colection
hasCollection = true;
Console.Write("Has collection already");
}
if (menuItems.Count() > 0)
{
foreach (var menuItem in menuItems)
{
List<WebPageContent> content;
MenuItemModel model = new MenuItemModel("");
//try to get content from qDrant
if (menuItem.ContentGroupId != null && menuItem.ContentItemId != null) ////FIXXXXXXX
{
ContentItem contentItem = await ContentEditorService.GetContentItemByIdAsync((int)menuItem.ContentItemId);
/* content = await QDrantService.GetPointFromQdrantAsyncByPointId(SiteId, contentItem.Chunks); */
//var selectedPoint = JsonConvert.DeserializeObject<QDrantGetContentPointResult>(content)!;
if (contentItem != null)
{
foreach (var vector in contentItem.Chunks)
{
//get vectors to compare
}
model.Content = contentItem.Content;
model.ContentDescription = contentItem.Description;
}
}
model.MenuItem = menuItem;
extractedMenuItems.Add(model);
// UpdateMenuItem(model);
}
MenuItemsSaved = true;
}
//get menu content from QDrant for each menu item
}
private async Task GenerateMenuItems()
{
if (string.IsNullOrWhiteSpace(subject))
{
errorMessage = "Please enter a subject.";
return;
}
isLoading = true;
errorMessage = null;
try
{
var prompt = $"Suggest a list of menu items for a website about: {subject}. Please do not attach any explanation.";
var response = await ContentEditorAIService.GetMenuSuggestionsAsync(SessionId, prompt);
var valami = response.Split('\n', StringSplitOptions.RemoveEmptyEntries)
.Select(line => line.Trim('-').Trim())
.ToList() ?? new List<string>();
extractedMenuItems = valami.Select(name => new MenuItemModel(name)).ToList();
}
catch (Exception ex)
{
errorMessage = "An error occurred while generating menu items.";
}
finally
{
isLoading = false;
}
}
private async Task AddMenuItem()
{
isLoading = true;
errorMessage = null;
var newItem = new MenuItemModel("New menu item", "");
//TODO Fix
extractedMenuItems.Add(newItem);
isLoading = false;
}
private void RemoveMenuItem(MenuItemModel item)
{
extractedMenuItems.Remove(item);
}
private void UpdateMenuItem(MenuItemModel updatedItem)
{
Console.Write("Updating menu item");
var item = extractedMenuItems.FirstOrDefault(i => i.MenuItem.Name == updatedItem.MenuItem.Name);
if (item != null)
{
item.Content = updatedItem.Content;
}
else
{
Console.Write("Not found");
}
}
private async Task SaveMenuItems(bool updateVectorDatabase)
{
var result = await ContentEditorAIService.ProcessMenuItems(SiteId, hasCollection, extractedMenuItems, subject, MenuItemsSaved, updateVectorDatabase);
if (result == "OK")
{
MenuItemsSaved = true;
hasCollection = true;
errorMessage = "Menu saved";
}
else
{
errorMessage = result;
}
}
void RowRender(RowRenderEventArgs<MenuItem> args)
{
if (allowReorder)
{
args.Attributes.Add("title", "Drag row to reorder");
args.Attributes.Add("style", "cursor:grab");
args.Attributes.Add("draggable", "true");
args.Attributes.Add("ondragover", "event.preventDefault();event.target.closest('.rz-data-row').classList.add('my-class')");
args.Attributes.Add("ondragleave", "event.target.closest('.rz-data-row').classList.remove('my-class')");
args.Attributes.Add("ondragstart", EventCallback.Factory.Create<DragEventArgs>(this, () => draggedItem = args.Data));
args.Attributes.Add("ondrop", EventCallback.Factory.Create<DragEventArgs>(this, () =>
{
var draggedIndex = menuItems.IndexOf(draggedItem);
MenuItemModel draggedExtractedMenuItem = extractedMenuItems[draggedIndex];
var droppedIndex = menuItems.IndexOf(args.Data);
menuItems.Remove(draggedItem);
menuItems.Insert(draggedIndex <= droppedIndex ? droppedIndex++ : droppedIndex, draggedItem);
extractedMenuItems.Remove(draggedExtractedMenuItem);
extractedMenuItems.Insert(draggedIndex <= droppedIndex ? droppedIndex++ : droppedIndex, draggedExtractedMenuItem);
foreach (var menuItemToReorder in menuItems)
{
menuItemToReorder.SortOrder = menuItems.IndexOf(menuItemToReorder);
}
foreach (var extractedMenuItemToReorder in extractedMenuItems)
{
extractedMenuItemToReorder.MenuItem.SortOrder = extractedMenuItems.IndexOf(extractedMenuItemToReorder);
}
JSRuntime.InvokeVoidAsync("eval", $"document.querySelector('.my-class').classList.remove('my-class')");
}));
}
}
void Select(MenuItem menuItem)
{
SelectedMenuItemModel.MenuItem.Name = menuItem.Name;
SelectedMenuItemModel.Content = extractedMenuItems.Where(x => x.MenuItem.Name == menuItem.Name).FirstOrDefault().Content;
SelectedMenuItemModel.MenuItem.SortOrder = menuItem.SortOrder;
SelectedMenuItemModel.MenuItem.ShowInMainMenu = menuItem.ShowInMainMenu;
}
void OnRowSelect(MenuItem menuItem)
{
Select(menuItem);
}
async void ToggleReorder()
{
if (allowReorder)
{
await SaveMenuItems(false);
}
allowReorder = !allowReorder;
await InvokeAsync(StateHasChanged);
}
}