338 lines
13 KiB
Plaintext
338 lines
13 KiB
Plaintext
@using BLAIzor.Models
|
|
@using Microsoft.AspNetCore.Components.Forms
|
|
@using BLAIzor.Services
|
|
@using Newtonsoft.Json
|
|
@using System.Collections.ObjectModel
|
|
@inject ContentEditorService ContentEditorService
|
|
@inject ContentEditorAIService ContentEditorAIService
|
|
@inject HtmlSnippetProcessor HtmlSnippetProcessor
|
|
@inject QDrantService QDrantService
|
|
@inject IJSRuntime JSRuntime
|
|
|
|
<h3>Upload Document to Generate Menu Items</h3>
|
|
|
|
<div>
|
|
<label for="fileInput">Upload a document:</label>
|
|
<InputFile id="fileInput" OnChange="HandleFileUpload" Accept=".docx" />
|
|
</div>
|
|
|
|
@if (IsLoading)
|
|
{
|
|
<p>Processing the document...</p>
|
|
}
|
|
else if (ExtractedMenuItems.Any())
|
|
{
|
|
<h4>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" WordFile=@document SessionId="SessionId" OnContentUpdated="UpdateMenuItem" />
|
|
}
|
|
<div class="card-footer">
|
|
|
|
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
|
</div>
|
|
}
|
|
</RadzenAccordionItem>
|
|
|
|
}
|
|
|
|
</Items>
|
|
</RadzenAccordion>
|
|
}
|
|
|
|
</div>
|
|
@* @foreach (var item in menuItems)
|
|
{
|
|
<div class="col-12">
|
|
<div class="card m-2">
|
|
<div class="card-header">
|
|
<input @bind="item.Name" class="form-control border-0" placeholder="Menu Item Name" />
|
|
</div>
|
|
<div class="card-body">
|
|
<h5>Content</h5>
|
|
@{
|
|
if (MenuItemsSaved)
|
|
{
|
|
|
|
<MenuItemContentEditor Subject=@subject MenuItem="item" OnContentUpdated="UpdateMenuItem" />
|
|
}
|
|
}
|
|
</div>
|
|
<div class="card-footer">
|
|
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
|
</div>
|
|
</div>
|
|
</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 IBrowserFile? UploadedFile;
|
|
private bool IsLoading = false;
|
|
private string? ErrorMessage;
|
|
private bool MenuItemsSaved = false;
|
|
|
|
ObservableCollection<MenuItem> menuItems;
|
|
IList<MenuItem> selectedMenuItems;
|
|
|
|
private string subject;
|
|
private string document;
|
|
private bool hasCollection;
|
|
private List<MenuItemModel> ExtractedMenuItems = new();
|
|
|
|
private bool allowReorder = false;
|
|
private RadzenDataGrid<MenuItem> dataGrid;
|
|
MenuItem draggedItem;
|
|
MenuItemModel SelectedMenuItemModel = new("");
|
|
|
|
void Change(string text)
|
|
{
|
|
Console.Write($"{text}");
|
|
}
|
|
|
|
protected override async Task OnParametersSetAsync()
|
|
{
|
|
//get menu items from DB
|
|
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); */ //FIXXXXXXX WONT WORKNOW
|
|
//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 HandleFileUpload(InputFileChangeEventArgs e)
|
|
{
|
|
UploadedFile = e.File;
|
|
if (UploadedFile == null)
|
|
{
|
|
ErrorMessage = "Please upload a valid .docx file.";
|
|
return;
|
|
}
|
|
|
|
IsLoading = true;
|
|
ErrorMessage = null;
|
|
|
|
try
|
|
{
|
|
// Read the uploaded .docx file
|
|
using var stream = UploadedFile.OpenReadStream(maxAllowedSize: 100 * 1024 * 1024); // 10MB limit
|
|
using var memoryStream = new MemoryStream();
|
|
await stream.CopyToAsync(memoryStream);
|
|
|
|
// Load the .docx file with DocX
|
|
document = WordFileReader.ExtractText(memoryStream);
|
|
|
|
//get website subject
|
|
var prompt1 = $"Analyze the following text and make an assumption about the characteristics of the text type (website, document, book, etc). Do not attach any explanation, make your answer like `A medical clinic of mammography` or `A webdesign and software development company` or `A book about XY` :\n\n{document}";
|
|
var response1 = await ContentEditorAIService.GetGeneratedContentAsync(SessionId, prompt1);
|
|
Console.Write(response1);
|
|
subject = response1;
|
|
|
|
if (!MenuItemsSaved)
|
|
{
|
|
var prompt2 = $"Analyze the following text and based on the sections suggest a list of menu items for a website. Do not attach any explanation. Text:\n\n`{document}`.";
|
|
var response2 = await ContentEditorAIService.GetMenuSuggestionsAsync(SessionId, prompt2);
|
|
var valami = response2.Split('\n', StringSplitOptions.RemoveEmptyEntries)
|
|
.Select(line => line.Trim('-').Trim())
|
|
.ToList() ?? new List<string>();
|
|
ExtractedMenuItems = valami.Select(name => new MenuItemModel(name)).ToList();
|
|
}
|
|
// Send the content to ChatGPT
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ErrorMessage = "An error occurred while processing the document.";
|
|
Console.Write(ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
IsLoading = false;
|
|
}
|
|
}
|
|
|
|
private void RemoveMenuItem(MenuItemModel item)
|
|
{
|
|
ExtractedMenuItems!.Remove(item);
|
|
}
|
|
|
|
private async Task AddMenuItem()
|
|
{
|
|
|
|
IsLoading = true;
|
|
ErrorMessage = null;
|
|
var newItem = new MenuItemModel("New menu item", "");
|
|
//TODO Fix
|
|
ExtractedMenuItems.Add(newItem);
|
|
IsLoading = false;
|
|
|
|
}
|
|
|
|
private void UpdateMenuItem(MenuItemModel updatedItem)
|
|
{
|
|
var item = ExtractedMenuItems!.FirstOrDefault(i => i.MenuItem.Id == updatedItem.MenuItem.Id);
|
|
if (item != null)
|
|
{
|
|
//item.MenuItem.
|
|
item.MenuItem.Name = updatedItem.MenuItem.Name;
|
|
item.Content = updatedItem.Content;
|
|
}
|
|
}
|
|
|
|
private async Task SaveMenuItems(bool updateVectorDatabase)
|
|
{
|
|
//bool valami = updateVectorDatabase;
|
|
var result = await ContentEditorAIService.ProcessMenuItems(SiteId, hasCollection, ExtractedMenuItems, subject, MenuItemsSaved, updateVectorDatabase);
|
|
if (result == "OK")
|
|
{
|
|
MenuItemsSaved = true;
|
|
hasCollection = true;
|
|
}
|
|
else
|
|
{
|
|
//Error
|
|
}
|
|
}
|
|
|
|
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);
|
|
Console.WriteLine($"{menuItemToReorder.Name}, {menuItemToReorder.SortOrder}");
|
|
}
|
|
foreach (var extractedMenuItemToReorder in ExtractedMenuItems)
|
|
{
|
|
extractedMenuItemToReorder.MenuItem.SortOrder = ExtractedMenuItems.IndexOf(extractedMenuItemToReorder);
|
|
Console.WriteLine($"{extractedMenuItemToReorder.MenuItem.Name}, {extractedMenuItemToReorder.MenuItem.SortOrder}");
|
|
}
|
|
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);
|
|
}
|
|
|
|
}
|