250 lines
10 KiB
Plaintext
250 lines
10 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">Suggest New by AI</button>
|
|
</div> *@
|
|
|
|
@if (isLoading)
|
|
{
|
|
<p>Loading suggestions...</p>
|
|
}
|
|
else if (extractedMenuItems.Any())
|
|
{
|
|
<h4>Menu Items Editor</h4>
|
|
<div class="row">
|
|
<div class="rz-p-sm-12">
|
|
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Right">
|
|
<RadzenButton Click="ToggleReorder">
|
|
@(allowReorder ? "Done Reordering" : "Reorder")
|
|
</RadzenButton>
|
|
</RadzenStack>
|
|
|
|
@if (allowReorder)
|
|
{
|
|
<RadzenDataGrid @ref="dataGrid" TItem="MenuItem" RowSelect=@OnRowSelect AllowFiltering="true" AllowColumnResize="true" AllowSorting="true" PageSize="20" AllowPaging="true"
|
|
Data="@menuItems" ColumnWidth="300px" SelectionMode="DataGridSelectionMode.Single" RowRender="@RowRender">
|
|
<Columns>
|
|
<RadzenDataGridColumn Property="@nameof(MenuItem.SortOrder)" Title="Sort Order" Width="40px" />
|
|
<RadzenDataGridColumn Property="@nameof(MenuItem.Name)" Title="Menu Name" Frozen="true" Width="200px" />
|
|
<RadzenDataGridColumn Property="@nameof(MenuItem.ShowInMainMenu)" Title="Visible" Width="40px" />
|
|
</Columns>
|
|
</RadzenDataGrid>
|
|
}
|
|
else
|
|
{
|
|
<RadzenAccordion class="admin-accordion" Multiple="false">
|
|
<Items>
|
|
@foreach (var item in extractedMenuItems)
|
|
{
|
|
<RadzenAccordionItem Text="@item.MenuItem.Name" Icon="menu">
|
|
<input @bind="item.MenuItem.Name" class="form-control mb-2" placeholder="Menu item name" />
|
|
|
|
<label>Parent Menu (optional):</label>
|
|
<select class="form-control mb-2" @bind="item.MenuItem.ParentId">
|
|
<option value="">-- No Parent --</option>
|
|
@foreach (var parent in extractedMenuItems)
|
|
{
|
|
if (parent != item)
|
|
{
|
|
<option value="@parent.MenuItem.Id">@parent.MenuItem.Name</option>
|
|
}
|
|
}
|
|
</select>
|
|
|
|
<label>Attach Content Item:</label>
|
|
<select class="form-control mb-2" @bind="item.MenuItem.ContentItemId">
|
|
<option value="">-- Select --</option>
|
|
@foreach (var contentItem in allContentItems)
|
|
{
|
|
<option value="@contentItem.Id">@contentItem.Title</option>
|
|
}
|
|
</select>
|
|
|
|
<textarea class="form-control mt-2" @bind="item.Content" placeholder="Optional inline content"></textarea>
|
|
|
|
<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-3" @onclick="() => AddMenuItem()">Add Menu Item</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 = new();
|
|
IList<MenuItem> selectedMenuItems;
|
|
private List<MenuItemModel> extractedMenuItems = new();
|
|
private List<ContentItem> allContentItems = 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()
|
|
{
|
|
var site = await ContentEditorService.GetSiteInfoByIdAsync(SiteId);
|
|
subject = site.SiteDescription ?? string.Empty;
|
|
menuItems = new ObservableCollection<MenuItem>((await ContentEditorService.GetMenuItemsBySiteIdAsync(SiteId)).OrderBy(x => x.SortOrder));
|
|
allContentItems = await ContentEditorService.GetAllContentItemsBySiteIdAsync(SiteId);
|
|
var collectionResult = await QDrantService.GetCollectionBySiteIdAsync(SiteId);
|
|
hasCollection = !string.IsNullOrEmpty(collectionResult);
|
|
|
|
if (menuItems.Count > 0)
|
|
{
|
|
foreach (var menuItem in menuItems)
|
|
{
|
|
var model = new MenuItemModel("") { MenuItem = menuItem };
|
|
if (menuItem.ContentItemId != null)
|
|
{
|
|
var contentItem = await ContentEditorService.GetContentItemByIdAsync(menuItem.ContentItemId.Value);
|
|
if (contentItem != null)
|
|
{
|
|
model.Content = contentItem.Content;
|
|
model.ContentDescription = contentItem.Description;
|
|
}
|
|
}
|
|
extractedMenuItems.Add(model);
|
|
}
|
|
MenuItemsSaved = true;
|
|
}
|
|
}
|
|
|
|
// private async Task GenerateMenuItems()
|
|
// {
|
|
// if (string.IsNullOrWhiteSpace(subject))
|
|
// {
|
|
// errorMessage = "Please enter a subject.";
|
|
// return;
|
|
// }
|
|
|
|
// isLoading = true;
|
|
// 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);
|
|
// extractedMenuItems = response.Select(name => new MenuItemModel(name)).ToList();
|
|
// }
|
|
// catch
|
|
// {
|
|
// errorMessage = "An error occurred while generating menu items.";
|
|
// }
|
|
// finally { isLoading = false; }
|
|
// }
|
|
|
|
private async Task AddMenuItem()
|
|
{
|
|
MenuItemModel newModel = new MenuItemModel("New Menu Item");
|
|
MenuItem newItem = new MenuItem();
|
|
newItem.SiteInfoId = SiteId;
|
|
newItem.Name = "New Menu Item";
|
|
newItem.SortOrder = extractedMenuItems.Count+1;
|
|
var result = await ContentEditorService.AddMenuItemAsync(newItem);
|
|
newModel.MenuItem = result;
|
|
extractedMenuItems.Add(newModel);
|
|
if(result == null)
|
|
{
|
|
extractedMenuItems.Remove(newModel);
|
|
}
|
|
|
|
}
|
|
|
|
private async Task RemoveMenuItem(MenuItemModel item){
|
|
await ContentEditorService.DeleteMenuItemAsync(item.MenuItem.Id);
|
|
extractedMenuItems.Remove(item);
|
|
}
|
|
|
|
private async Task SaveMenuItems(bool updateVectorDatabase)
|
|
{
|
|
//var result = await ContentEditorAIService.ProcessMenuItems(SiteId, hasCollection, extractedMenuItems, subject, MenuItemsSaved, updateVectorDatabase);
|
|
try
|
|
{
|
|
foreach (var menuItemToUpdate in extractedMenuItems)
|
|
{
|
|
var result2 = await ContentEditorService.UpdateMenuItemAsync(menuItemToUpdate.MenuItem);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errorMessage = "Some error occured: " + ex;
|
|
}
|
|
finally
|
|
{
|
|
MenuItemsSaved = true;
|
|
hasCollection = true;
|
|
errorMessage = "Menu saved";
|
|
}
|
|
}
|
|
|
|
void RowRender(RowRenderEventArgs<MenuItem> args)
|
|
{
|
|
if (!allowReorder) return;
|
|
|
|
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);
|
|
var droppedIndex = menuItems.IndexOf(args.Data);
|
|
var draggedModel = extractedMenuItems[draggedIndex];
|
|
|
|
menuItems.RemoveAt(draggedIndex);
|
|
extractedMenuItems.RemoveAt(draggedIndex);
|
|
|
|
menuItems.Insert(droppedIndex, draggedItem);
|
|
extractedMenuItems.Insert(droppedIndex, draggedModel);
|
|
|
|
for (int i = 0; i < menuItems.Count; i++)
|
|
{
|
|
menuItems[i].SortOrder = i;
|
|
extractedMenuItems[i].MenuItem.SortOrder = i;
|
|
}
|
|
|
|
JSRuntime.InvokeVoidAsync("eval", "document.querySelector('.my-class').classList.remove('my-class')");
|
|
}));
|
|
}
|
|
|
|
void ToggleReorder()
|
|
{
|
|
if (allowReorder) _ = SaveMenuItems(false);
|
|
allowReorder = !allowReorder;
|
|
}
|
|
|
|
void OnRowSelect(MenuItem item)
|
|
{
|
|
SelectedMenuItemModel = extractedMenuItems.FirstOrDefault(x => x.MenuItem.Id == item.Id) ?? new("");
|
|
}
|
|
}
|