Compare commits
No commits in common. "00417c4cf8d5977ff3315efb892393b39dda2130" and "94d002657ae8ed0d0e5bd9aec8c49a905adf83e6" have entirely different histories.
00417c4cf8
...
94d002657a
|
|
@ -7,17 +7,6 @@
|
||||||
<AssemblyName>BLAIzor</AssemblyName>
|
<AssemblyName>BLAIzor</AssemblyName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Remove="SeemGen.Tests\**" />
|
|
||||||
<Content Remove="SeemGen.Tests\**" />
|
|
||||||
<EmbeddedResource Remove="SeemGen.Tests\**" />
|
|
||||||
<None Remove="SeemGen.Tests\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Remove="Components\Partials\OverlayEditor.razor" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Components\Pages\Home.razorOLD" />
|
<None Remove="Components\Pages\Home.razorOLD" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
@ -41,11 +30,9 @@
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="PdfPig" Version="0.1.10" />
|
<PackageReference Include="PdfPig" Version="0.1.10" />
|
||||||
<PackageReference Include="Qdrant.Client" Version="1.13.0" />
|
<PackageReference Include="Qdrant.Client" Version="1.13.0" />
|
||||||
<PackageReference Include="Radzen.Blazor" Version="7.1.1" />
|
<PackageReference Include="Radzen.Blazor" Version="6.4.0" />
|
||||||
<PackageReference Include="Sidio.Sitemap.Blazor" Version="1.1.2" />
|
<PackageReference Include="Sidio.Sitemap.Blazor" Version="1.1.2" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
|
|
||||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.3" />
|
<PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.3" />
|
||||||
<PackageReference Include="xunit.extensibility.core" Version="2.9.2" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -70,9 +57,6 @@
|
||||||
<Content Update="wwwroot\bootstrap\js\bootstrap.js">
|
<Content Update="wwwroot\bootstrap\js\bootstrap.js">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Update="wwwroot\admin.css">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Update="wwwroot\main.css">
|
<Content Update="wwwroot\main.css">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ VisualStudioVersion = 17.10.35004.147
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BLAIzor", "BLAIzor.csproj", "{A7A021E4-C303-4DF0-B55B-CE3233137085}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BLAIzor", "BLAIzor.csproj", "{A7A021E4-C303-4DF0-B55B-CE3233137085}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeemGen.Tests", "SeemGen.Tests\SeemGen.Tests.csproj", "{9B3FF465-BD0D-F50F-F19B-E2D1338E7FE6}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -17,10 +15,6 @@ Global
|
||||||
{A7A021E4-C303-4DF0-B55B-CE3233137085}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A7A021E4-C303-4DF0-B55B-CE3233137085}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A7A021E4-C303-4DF0-B55B-CE3233137085}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A7A021E4-C303-4DF0-B55B-CE3233137085}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A7A021E4-C303-4DF0-B55B-CE3233137085}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A7A021E4-C303-4DF0-B55B-CE3233137085}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{9B3FF465-BD0D-F50F-F19B-E2D1338E7FE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{9B3FF465-BD0D-F50F-F19B-E2D1338E7FE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{9B3FF465-BD0D-F50F-F19B-E2D1338E7FE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{9B3FF465-BD0D-F50F-F19B-E2D1338E7FE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
||||||
|
|
@ -6,22 +6,13 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<script>
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
function gtag(){dataLayer.push(arguments);}
|
|
||||||
gtag('js', new Date());
|
|
||||||
|
|
||||||
gtag('config', 'G-E9J9J414DF');
|
|
||||||
</script>
|
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<base href="/" />
|
<base href="/" />
|
||||||
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
|
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
|
||||||
<link rel="stylesheet" href="app.css" />
|
<link rel="stylesheet" href="app.css" />
|
||||||
<link rel="stylesheet" href="main.css" />
|
<link rel="stylesheet" href="main.css" />
|
||||||
<link rel="stylesheet" href="admin.css" />
|
<link rel="stylesheet" href="animate.css" />
|
||||||
@* <link rel="stylesheet" href="animate.css" /> *@
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
|
|
||||||
<link rel="stylesheet" href="loader.css" />
|
<link rel="stylesheet" href="loader.css" />
|
||||||
<link rel="stylesheet" href="BLAIzor.styles.css" />
|
<link rel="stylesheet" href="BLAIzor.styles.css" />
|
||||||
<link rel="icon" type="image/png" href="favicon.png" />
|
<link rel="icon" type="image/png" href="favicon.png" />
|
||||||
|
|
@ -31,12 +22,20 @@
|
||||||
<script src="https://kit.fontawesome.com/12c469cb8f.js" crossorigin="anonymous"></script>
|
<script src="https://kit.fontawesome.com/12c469cb8f.js" crossorigin="anonymous"></script>
|
||||||
<script src="https://assets.calendly.com/assets/external/widget.js" type="text/javascript"></script>
|
<script src="https://assets.calendly.com/assets/external/widget.js" type="text/javascript"></script>
|
||||||
<script type="text/javascript" src="scripts/background.js"> </script>
|
<script type="text/javascript" src="scripts/background.js"> </script>
|
||||||
|
<script type="text/javascript" src="scripts/SeemGenCss.js"> </script>
|
||||||
<script type="text/javascript" src="scripts/whisperRecorder.js"></script>
|
@* <script>
|
||||||
|
window.applyDynamicCss = (cssContent) => {
|
||||||
|
let styleTag = document.getElementById('seemgen-style');
|
||||||
<RadzenTheme Theme="material-dark" @rendermode="InteractiveServer" />
|
if (!styleTag) {
|
||||||
@* <RadzenTheme Theme="material" @rendermode="InteractiveServer" /> *@
|
styleTag = document.createElement('style');
|
||||||
|
styleTag.id = 'seemgen-style';
|
||||||
|
document.head.appendChild(styleTag);
|
||||||
|
}
|
||||||
|
styleTag.textContent = cssContent;
|
||||||
|
};
|
||||||
|
</script> *@
|
||||||
|
@* <RadzenTheme Theme="material-dark" @rendermode="InteractiveServer" /> *@
|
||||||
|
<RadzenTheme Theme="material" @rendermode="InteractiveServer" />
|
||||||
<HeadOutlet />
|
<HeadOutlet />
|
||||||
<SectionOutlet SectionName="HeadContentFromPage" />
|
<SectionOutlet SectionName="HeadContentFromPage" />
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -50,11 +49,6 @@
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
|
||||||
integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
|
integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
|
||||||
crossorigin="anonymous"></script>
|
crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" src="scripts/finisher-header.es5.min.js"> </script>
|
<script src="_content/Radzen.Blazor/Radzen.Blazor.js?v=@(typeof(Radzen.Colors).Assembly.GetName().Version)"></script>
|
||||||
<script src="_content/Radzen.Blazor/Radzen.Blazor.js?v=@(typeof(Radzen.Colors).Assembly.GetName().Version)"></script>
|
|
||||||
<script type="text/javascript" src="scripts/SeemGenCss.js"> </script>
|
|
||||||
<!-- Google tag (gtag.js) -->
|
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-E9J9J414DF"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="page admin-body" style="z-index: 1">
|
<div class="page" style="z-index: 1">
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
@* <div class="top-row px-4" style="z-index: 2">
|
@* <div class="top-row px-4" style="z-index: 2">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
@using BLAIzor.Services
|
@using BLAIzor.Services
|
||||||
@inherits LayoutComponentBase
|
@inherits LayoutComponentBase
|
||||||
<RadzenComponents @rendermode="InteractiveServer" />
|
|
||||||
@Body
|
@Body
|
||||||
|
|
||||||
<div id="blazor-error-ui">
|
<div id="blazor-error-ui">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<div class="top-row ps-3 navbar navbar-dark">
|
<div class="top-row ps-3 navbar navbar-dark">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
@* <div style="float: left"> *@
|
|
||||||
<a class="navbar-brand" href="">BLAIzor</a>
|
<a class="navbar-brand" href="">BLAIzor</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -35,29 +35,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const hostSelector = 'elevenlabs-convai'; // Replace with your real tag name
|
|
||||||
const targetClass = '_poweredBy_1f9vw_251'; // Replace with your class
|
|
||||||
|
|
||||||
const intervalId = setInterval(() => {
|
|
||||||
const host = document.querySelector(hostSelector);
|
|
||||||
|
|
||||||
if (host && host.shadowRoot) {
|
|
||||||
const target = host.shadowRoot.querySelector(`.${targetClass}`);
|
|
||||||
if (target) {
|
|
||||||
target.style.setProperty('display', 'none', 'important');
|
|
||||||
console.log('Element found inside shadow DOM and hidden!');
|
|
||||||
clearInterval(intervalId);
|
|
||||||
} else {
|
|
||||||
console.log('Waiting for target inside shadowRoot...');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('Waiting for host or shadowRoot...');
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
|
<script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
|
||||||
|
|
@ -70,20 +47,18 @@ const intervalId = setInterval(() => {
|
||||||
|
|
||||||
@if (ImageUrl is not null)
|
@if (ImageUrl is not null)
|
||||||
{
|
{
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
<img class="illustration" src="@ImageUrl"/>
|
<img class="illustration" src="@ImageUrl"/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (IsLoading)
|
@if (IsLoading)
|
||||||
{
|
{
|
||||||
<p>🎨 Kép készül... kis türelmet kérek!</p>
|
<p>🎨 Kép készül... kis türelmet kérek!</p>
|
||||||
}
|
}
|
||||||
</article>
|
</article>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string Menu = "Tanulás, Gyakorlás, Tesztelés, Vizsgázás";
|
private string Menu = "Tanulás, Gyakorlás, Tesztelés, Vizsgázás";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
@using BLAIzor.Components.Layout
|
@using BLAIzor.Components.Layout
|
||||||
@attribute [Authorize]
|
@attribute [Authorize]
|
||||||
@layout AdminLayout
|
@layout AdminLayout
|
||||||
@inject ContentEditorAIService ContentEditorAIService
|
@inject ContentEditorService ContentEditorService
|
||||||
|
|
||||||
<h3>Create a new from from pdf or word</h3>
|
<h3>Create a new from from pdf or word</h3>
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@
|
||||||
|
|
||||||
private async Task<List<FormFieldGroup>> CallAiForFieldExtraction(string plainText)
|
private async Task<List<FormFieldGroup>> CallAiForFieldExtraction(string plainText)
|
||||||
{
|
{
|
||||||
var jsonResult = await ContentEditorAIService.AnalyzeGroupedFormFieldsFromText(plainText);
|
var jsonResult = await ContentEditorService.AnalyzeGroupedFormFieldsFromText(plainText);
|
||||||
Console.WriteLine($"📄 PDF form AI response: {jsonResult}");
|
Console.WriteLine($"📄 PDF form AI response: {jsonResult}");
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -27,51 +27,43 @@ else
|
||||||
<DataAnnotationsValidator />
|
<DataAnnotationsValidator />
|
||||||
<ValidationSummary />
|
<ValidationSummary />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-md-6">
|
<div class="form-group col-md-4">
|
||||||
<div class="form-group">
|
<label>Template Name</label>
|
||||||
<label>Template Name</label>
|
<InputText class="form-control" @bind-Value="currentTemplate.TemplateName" />
|
||||||
<InputText class="form-control" @bind-Value="currentTemplate.TemplateName" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Template photo url</label>
|
|
||||||
<InputText class="form-control" @bind-Value="currentTemplate.TemplatePhotoUrl" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Tags (comma-separated)</label>
|
|
||||||
<InputText class="form-control" @bind-Value="currentTemplate.Tags" />
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Description</label>
|
|
||||||
<InputTextArea class="form-control" @bind-Value="currentTemplate.Description" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-md-6">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>CSS Content</label>
|
|
||||||
<RadzenHtmlEditor @bind-Value=@currentCssTemplate.CssContent
|
|
||||||
style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)"
|
|
||||||
Input=@OnInput
|
|
||||||
Change=@OnChange
|
|
||||||
Paste=@OnPaste
|
|
||||||
UploadComplete=@OnUploadComplete
|
|
||||||
Execute=@OnExecute
|
|
||||||
UploadUrl="upload/image"
|
|
||||||
Mode=@HtmlEditorMode.Source>
|
|
||||||
<RadzenHtmlEditorUndo />
|
|
||||||
<RadzenHtmlEditorRedo />
|
|
||||||
<RadzenHtmlEditorSource />
|
|
||||||
</RadzenHtmlEditor>
|
|
||||||
@* <InputTextArea class="form-control" @bind-Value="currentCssTemplate.CssContent" /> *@
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-md-4">
|
||||||
|
<label>Template photo url</label>
|
||||||
|
<InputText class="form-control" @bind-Value="currentTemplate.TemplatePhotoUrl" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-md-4">
|
||||||
|
<label>Tags (comma-separated)</label>
|
||||||
|
<InputText class="form-control" @bind-Value="currentTemplate.Tags" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Description</label>
|
||||||
|
<InputTextArea class="form-control" @bind-Value="currentTemplate.Description" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>CSS Content</label>
|
||||||
|
<RadzenHtmlEditor @bind-Value=@currentCssTemplate.CssContent
|
||||||
|
style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)"
|
||||||
|
Input=@OnInput
|
||||||
|
Change=@OnChange
|
||||||
|
Paste=@OnPaste
|
||||||
|
UploadComplete=@OnUploadComplete
|
||||||
|
Execute=@OnExecute
|
||||||
|
UploadUrl="upload/image">
|
||||||
|
<RadzenHtmlEditorUndo />
|
||||||
|
<RadzenHtmlEditorRedo />
|
||||||
|
<RadzenHtmlEditorSource />
|
||||||
|
</RadzenHtmlEditor>
|
||||||
|
@* <InputTextArea class="form-control" @bind-Value="currentCssTemplate.CssContent" /> *@
|
||||||
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-success" type="submit">Save Changes</button>
|
<button class="btn btn-success" type="submit">Save Changes</button>
|
||||||
</EditForm>
|
</EditForm>
|
||||||
|
|
|
||||||
|
|
@ -5,29 +5,25 @@
|
||||||
@using BLAIzor.Services
|
@using BLAIzor.Services
|
||||||
@layout AdminLayout
|
@layout AdminLayout
|
||||||
@inject ContentEditorService ContentEditorService
|
@inject ContentEditorService ContentEditorService
|
||||||
@inject ScopedContentService ScopedContentService
|
|
||||||
|
|
||||||
<h3>Generate Website Content</h3>
|
<h3>Generate Website Content</h3>
|
||||||
|
|
||||||
<div class="row">
|
<p>How would you start?</p>
|
||||||
<div class="rz-p-4 rz-text-align-center" style="width: fit-content; margin: 0 auto;">
|
|
||||||
<p>How would you start?</p>
|
|
||||||
<RadzenRadioButtonList @bind-Value=@FromDocument TValue="bool" AlignItems="AlignItems.Center" Style="margin: 0 auto;">
|
|
||||||
<Items>
|
|
||||||
<RadzenRadioButtonListItem Text="I have a document" Value="true" />
|
|
||||||
<RadzenRadioButtonListItem Text="Start from scratch" Value="false" />
|
|
||||||
</Items>
|
|
||||||
</RadzenRadioButtonList>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="rz-p-12 rz-text-align-center">
|
||||||
|
<RadzenRadioButtonList @bind-Value=@FromDocument TValue="bool">
|
||||||
|
<Items>
|
||||||
|
<RadzenRadioButtonListItem Text="I have a document" Value="true" />
|
||||||
|
<RadzenRadioButtonListItem Text="Start from scratch" Value="false" />
|
||||||
|
</Items>
|
||||||
|
</RadzenRadioButtonList>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>@errorMessage</p>
|
<p>@errorMessage</p>
|
||||||
@{
|
@{
|
||||||
if(!FromDocument)
|
if(!FromDocument)
|
||||||
{
|
{
|
||||||
// <GenerateFromScratch SiteId=@SiteId SessionId="sessionId"></GenerateFromScratch>
|
<GenerateFromScratch SiteId=@SiteId SessionId="sessionId"></GenerateFromScratch>
|
||||||
<GenerateSitePages SiteId=@SiteId SessionId="sessionId"></GenerateSitePages>
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -44,7 +40,6 @@
|
||||||
|
|
||||||
protected override Task OnParametersSetAsync()
|
protected override Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
sessionId = ScopedContentService.SessionId;
|
|
||||||
//TODO get sessionId
|
//TODO get sessionId
|
||||||
return base.OnParametersSetAsync();
|
return base.OnParametersSetAsync();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
@page "/"
|
@page "/"
|
||||||
@page "/menu/{topic?}"
|
|
||||||
@inherits MainPageBase
|
|
||||||
@using BLAIzor.Models
|
@using BLAIzor.Models
|
||||||
@using BLAIzor.Services
|
@using BLAIzor.Services
|
||||||
@using BLAIzor.Components.Partials
|
@using BLAIzor.Components.Partials
|
||||||
|
|
@ -10,163 +8,116 @@
|
||||||
@using System.Net
|
@using System.Net
|
||||||
@using System.Text.Json
|
@using System.Text.Json
|
||||||
@using Sidio.Sitemap.Blazor
|
@using Sidio.Sitemap.Blazor
|
||||||
|
@inject AIService ChatGptService
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
|
@inject IJSRuntime jsRuntime;
|
||||||
|
@inject IConfiguration configuration
|
||||||
|
@inject ContentService _contentService
|
||||||
|
@inject ContentEditorService _contentEditorService
|
||||||
|
@inject ScopedContentService _scopedContentService
|
||||||
|
@* @inject IEmailSender _emailService *@
|
||||||
@inject NavigationManager _navigationManager
|
@inject NavigationManager _navigationManager
|
||||||
@inject IHttpContextAccessor HttpContextAccessor
|
@inject IHttpContextAccessor HttpContextAccessor
|
||||||
@inject DesignTemplateService DesignTemplateService
|
@inject DesignTemplateService DesignTemplateService
|
||||||
@inject CssTemplateService CssTemplateService
|
@inject CssTemplateService CssTemplateService
|
||||||
@inject CssInjectorService CssService
|
@inject CssInjectorService CssService
|
||||||
|
@inject HttpClient Http
|
||||||
@attribute [Sitemap]
|
@attribute [Sitemap]
|
||||||
|
|
||||||
<ErrorBoundary>
|
<div class="page" style="z-index: 1">
|
||||||
<ChildContent>
|
<NavMenu MenuString="@Menu" OnMenuClicked=@MenuClick></NavMenu>
|
||||||
|
<main>
|
||||||
|
|
||||||
<div class="page" style="z-index: 1">
|
<article class="content container text-center" style="position: relative; z-index: 4;">
|
||||||
<NewNavMenu Menu="@MenuItems" BrandName="@SelectedBrandName" SiteId="SiteId" OnMenuClicked=@MenuClick></NewNavMenu>
|
<PageTitle>Home</PageTitle>
|
||||||
<main>
|
<VideoComponent SelectedBrandName="@selectedBrandName" />
|
||||||
|
@* <HeadContent>
|
||||||
<article class="content text-center" style="position: relative; z-index: 4;">
|
|
||||||
|
|
||||||
<PageTitle>Home</PageTitle>
|
|
||||||
@{
|
|
||||||
if (SiteInfo != null)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(SiteInfo.BackgroundVideo))
|
|
||||||
{
|
|
||||||
<VideoComponent site="SiteInfo" />
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@* <HeadContent>
|
|
||||||
|
|
||||||
<style id="seemgen-style">@dynamicallyLoadedCss</style>
|
<style id="seemgen-style">@dynamicallyLoadedCss</style>
|
||||||
|
|
||||||
</HeadContent> *@
|
</HeadContent> *@
|
||||||
|
|
||||||
<div id="maincontrol">
|
<div id="maincontrol" >
|
||||||
|
|
||||||
|
|
||||||
@* <div class="hoverslide"> *@
|
@* <div class="hoverslide"> *@
|
||||||
|
|
||||||
<div class="displaysearch">
|
<div class="displaysearch">
|
||||||
<div class="searchBox">
|
<div class="searchBox">
|
||||||
@if (VoiceEnabled)
|
|
||||||
{
|
<input @oninput="(e) => UserInput = e.Value.ToString()"
|
||||||
if (STTEnabled)
|
@onkeydown="@Enter" class="searchInput" type="text" name="" value="@UserInput" placeholder="Ask any question">
|
||||||
{
|
<button data-hint="ask anything" class="searchButton border-0" @onclick="SendUserQuery" href="#">
|
||||||
<button id="recButton" class="voicebutton bg-panel-gradient" onclick="startRecording()"><i class="fa-solid fa-microphone"></i></button>
|
<i class="fa-solid fa-hexagon-nodes-bolt" style="font-size:20px"></i>
|
||||||
<button id="stopButton" class="voicebutton bg-danger" onclick="stopRecording()" hidden><i class="fa-solid fa-microphone-slash"></i></button>
|
</button>
|
||||||
}
|
</div>
|
||||||
}
|
|
||||||
<input @oninput="(e) => UserInput = e.Value.ToString()"
|
@{
|
||||||
@onkeydown="@Enter" class="searchInput" type="text" name="" value="@UserInput" placeholder="Ask any question">
|
@if(VoiceEnabled)
|
||||||
<button data-hint="ask anything" class="searchButton border-0" @onclick="SendUserQuery" href="#">
|
{
|
||||||
<i class="fa-solid fa-hexagon-nodes-bolt" style="font-size:20px"></i>
|
if(STTEnabled)
|
||||||
</button>
|
{
|
||||||
|
<button id="recButton" class="btn btn-primary voicebutton" onclick="startRecording()"><i class="fa-solid fa-microphone"></i></button>
|
||||||
|
<button id="stopButton" class="btn btn-primary voicebutton" onclick="stopRecording()" hidden><i class="fa-solid fa-microphone-slash"></i></button>
|
||||||
|
}
|
||||||
|
|
||||||
|
if(TTSEnabled)
|
||||||
|
{
|
||||||
|
<button class="btn btn-primary voicebutton" @onclick="MuteAI"><i class="fa-solid fa-volume-high"></i></button>
|
||||||
|
<audio id="audioPlayer" hidden style="display: none;"></audio>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@* Type anything *@
|
||||||
|
|
||||||
|
@* </div> *@
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p id="recordingText"></p>
|
||||||
|
<div class="row" id="currentContent">
|
||||||
|
@{
|
||||||
|
if (!string.IsNullOrEmpty(HtmlContent.ToString()))
|
||||||
|
{
|
||||||
|
<div class="pt-5 @FirstColumnClass">
|
||||||
|
@((MarkupString)HtmlContent.ToString())
|
||||||
|
</div>
|
||||||
|
if (isEmailFormVisible)
|
||||||
|
{
|
||||||
|
<div class="pt-5 col-12 col-md-6">
|
||||||
|
<ContactFormComponent ContactFormModel="@ContactFormModel" DocumentEmailAddress="@DocumentEmailAddress" OnDataChanged="@ContentChangedInForm"></ContactFormComponent>
|
||||||
|
<button @onclick="CancelEmail" class="btn btn-primary">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@{
|
}
|
||||||
@if (VoiceEnabled)
|
}
|
||||||
{
|
else
|
||||||
// if (STTEnabled)
|
{
|
||||||
// {
|
<div class="text-center row" style="height: 70vh;">
|
||||||
// <button id="recButton" class="btn btn-primary voicebutton" onclick="startRecording()"><i class="fa-solid fa-microphone"></i></button>
|
<p>@StatusContent</p>
|
||||||
// <button id="stopButton" class="btn btn-primary voicebutton" onclick="stopRecording()" hidden><i class="fa-solid fa-microphone-slash"></i></button>
|
<div class="mydiv"></div>
|
||||||
// }
|
<div class="mydiv"></div>
|
||||||
|
<div class="mydiv"></div>
|
||||||
if (TTSEnabled)
|
<div class="mydiv"></div>
|
||||||
{
|
<div class="mydiv"></div>
|
||||||
if (!AiVoicePermitted)
|
|
||||||
{
|
|
||||||
<button data-hint="listen" class="btn btn-primary voicebutton" style="display: inline-block" @onclick="AllowAIVoice">
|
|
||||||
<i class="fa-solid fa-volume-xmark"></i>
|
|
||||||
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<button data-hint="listen" class="btn btn-primary voicebutton" style="display: inline-block" @onclick="MuteAI"><i class="fa-solid fa-volume-high"></i></button>
|
|
||||||
}
|
|
||||||
<audio id="audioPlayer" hidden style="display: none;"></audio>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
@* Type anything *@
|
|
||||||
|
|
||||||
@* </div> *@
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div id="currentContent">
|
}
|
||||||
<p id="recordingText"></p>
|
</div>
|
||||||
<AnimateOnRender CssClass="animate__animated animate__backInUp">
|
|
||||||
@{
|
|
||||||
if (!string.IsNullOrEmpty(HtmlContent.ToString()))
|
|
||||||
{
|
|
||||||
|
|
||||||
if (isEmailFormVisible)
|
<button class="btn btn-primary" @onclick="HomeClick"><i class="fa-solid fa-rotate"></i></button>
|
||||||
{
|
@* <FormWizardComponent SessionId="@sessionId"></FormWizardComponent> *@
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<div class="pt-5 @FirstColumnClass">
|
|
||||||
@((MarkupString)HtmlContent.ToString())
|
|
||||||
</div>
|
|
||||||
<div class="pt-5 col-12 col-md-6">
|
|
||||||
<ContactFormComponent ContactFormModel="@ContactFormModel" DocumentEmailAddress="@DocumentEmailAddress" OnDataChanged="@ContentChangedInForm"></ContactFormComponent>
|
|
||||||
<button @onclick="CancelEmail" class="btn btn-primary">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
}
|
</article>
|
||||||
else
|
</main>
|
||||||
{
|
</div>
|
||||||
<div class="pt-5 @FirstColumnClass">
|
|
||||||
@((MarkupString)HtmlContent.ToString())
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<div class="text-center row" style="height: 70vh;">
|
|
||||||
<p>@StatusContent</p>
|
|
||||||
<div class="mydiv"></div>
|
|
||||||
<div class="mydiv"></div>
|
|
||||||
<div class="mydiv"></div>
|
|
||||||
<div class="mydiv"></div>
|
|
||||||
<div class="mydiv"></div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
</AnimateOnRender>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button class="btn btn-primary" @onclick="HomeClick"><i class="fa-solid fa-rotate"></i></button>
|
|
||||||
@* <FormWizardComponent SessionId="@sessionId"></FormWizardComponent> *@
|
|
||||||
|
|
||||||
</article>
|
|
||||||
</main>
|
|
||||||
<FooterComponent MenuString="@Menu" OnMenuClicked=@MenuClick></FooterComponent>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</ChildContent>
|
|
||||||
<ErrorContent Context="ex">
|
|
||||||
<p role="alert">An error occurred: @ex.Message</p>
|
|
||||||
<p>Please try again later.</p>
|
|
||||||
@* You can log the exception here if you want *@
|
|
||||||
@{
|
|
||||||
Console.WriteLine($"Error caught by ErrorBoundary: {ex.Message}");
|
|
||||||
}
|
|
||||||
</ErrorContent>
|
|
||||||
</ErrorBoundary>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
|
@ -204,47 +155,119 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter]
|
public static Index myHome;
|
||||||
public string? topic { get; set; }
|
|
||||||
// public static Index myHome;
|
|
||||||
private string? Subdomain;
|
private string? Subdomain;
|
||||||
|
public int SiteId;
|
||||||
|
public SiteInfo SiteInfo;
|
||||||
|
private StringBuilder HtmlContent = new StringBuilder("");
|
||||||
|
private string TextContent = "";
|
||||||
|
private string StatusContent = "";
|
||||||
|
private string UserInput = string.Empty;
|
||||||
private string ChatGptResponse = string.Empty;
|
private string ChatGptResponse = string.Empty;
|
||||||
private bool isRecording = false;
|
private bool isRecording = false;
|
||||||
|
|
||||||
private void AllowAIVoice()
|
private string FirstColumnClass = "";
|
||||||
{
|
private bool isEmailFormVisible = false;
|
||||||
AiVoicePermitted = true;
|
|
||||||
}
|
private ContactFormModel ContactFormModel = new();
|
||||||
|
// private string? SuccessMessage;
|
||||||
|
// private string? ErrorMessage;
|
||||||
|
private string? DocumentEmailAddress = "";
|
||||||
|
private string selectedBrandName = "default";
|
||||||
|
private string dynamicallyLoadedCss = string.Empty;
|
||||||
|
private string collectionName = "html_snippets";
|
||||||
|
private string sessionId;
|
||||||
|
private static readonly Dictionary<string, Index> _instances = new();
|
||||||
|
private string Menu;
|
||||||
|
private bool VoiceEnabled;
|
||||||
|
private bool TTSEnabled;
|
||||||
|
private bool STTEnabled;
|
||||||
|
private bool _initVoicePending = false;
|
||||||
|
private bool welcomeStage = true;
|
||||||
|
|
||||||
|
|
||||||
|
private string GetApiKey() =>
|
||||||
|
configuration?.GetSection("ElevenLabsAPI")?.GetValue<string>("ApiKey") ?? string.Empty;
|
||||||
|
|
||||||
|
|
||||||
private void MuteAI()
|
private void MuteAI()
|
||||||
{
|
{
|
||||||
AiVoicePermitted = false;
|
TTSEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ConvertTextToSpeech()
|
||||||
|
{
|
||||||
|
// string plainText = WebUtility.HtmlDecode(HtmlContent.ToString());
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(TextContent) || VoiceEnabled == false || TTSEnabled == false || welcomeStage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Console.WriteLine("------------------------------OMGOMGOMG TTS call!!!!-------------");
|
||||||
|
|
||||||
|
var requestContent = new
|
||||||
|
{
|
||||||
|
text = TextContent,
|
||||||
|
// model_id = "eleven_multilingual_v2",
|
||||||
|
model_id = "eleven_flash_v2_5",
|
||||||
|
voice_settings = new
|
||||||
|
{
|
||||||
|
stability = 0.5,
|
||||||
|
similarity_boost = 0.75,
|
||||||
|
speed = 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var requestJson = JsonSerializer.Serialize(requestContent);
|
||||||
|
string voiceId = "rE22Kc7UGoQj4zdHNYvd";
|
||||||
|
// string voiceId = "yyPLNYHg3CvjlSdSOdLh";
|
||||||
|
|
||||||
|
var httpRequest = new HttpRequestMessage(HttpMethod.Post, $"https://api.elevenlabs.io/v1/text-to-speech/{voiceId}/stream")
|
||||||
|
{
|
||||||
|
Content = new StringContent(requestJson, Encoding.UTF8, "application/json")
|
||||||
|
};
|
||||||
|
|
||||||
|
httpRequest.Headers.Add("xi-api-key", GetApiKey());
|
||||||
|
|
||||||
|
var response = await Http.SendAsync(httpRequest);
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var audioBytes = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
var base64Audio = Convert.ToBase64String(audioBytes);
|
||||||
|
var audioDataUrl = $"data:audio/mpeg;base64,{base64Audio}";
|
||||||
|
|
||||||
|
await jsRuntime.InvokeVoidAsync("playAudio", audioDataUrl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle error response
|
||||||
|
var errorContent = await response.Content.ReadAsStringAsync();
|
||||||
|
Console.Error.WriteLine($"Error: {errorContent}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
await _logger.InfoAsync("Index component OnafterRender.", $"{SiteId}");
|
await jsRuntime.InvokeVoidAsync("setSessionId", sessionId);
|
||||||
await jsRuntime.InvokeVoidAsync("setSessionId", SessionId);
|
|
||||||
await jsRuntime.InvokeVoidAsync("initHints");
|
await jsRuntime.InvokeVoidAsync("initHints");
|
||||||
|
|
||||||
// sessionId = Guid.NewGuid().ToString();
|
// sessionId = Guid.NewGuid().ToString();
|
||||||
// _instances[sessionId] = this;
|
// _instances[sessionId] = this;
|
||||||
|
|
||||||
Console.Write($"\n\n SessionId: {SessionId}\n\n");
|
Console.Write($"\n\n SessionId: {sessionId}\n\n");
|
||||||
// _scopedContentService.OnBrandNameChanged += HandleBrandNameChanged;
|
// _scopedContentService.OnBrandNameChanged += HandleBrandNameChanged;
|
||||||
if (!string.IsNullOrEmpty(_scopedContentService.SelectedBrandName))
|
if (!string.IsNullOrEmpty(_scopedContentService.SelectedBrandName))
|
||||||
{
|
{
|
||||||
SelectedBrandName = _scopedContentService.SelectedBrandName;
|
selectedBrandName = _scopedContentService.SelectedBrandName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_scopedContentService.SelectedBrandName = "default";
|
_scopedContentService.SelectedBrandName = "default";
|
||||||
SelectedBrandName = "default";
|
selectedBrandName = "default";
|
||||||
}
|
}
|
||||||
Subdomain = HttpContextAccessor.HttpContext?.Items["Subdomain"]?.ToString();
|
Subdomain = HttpContextAccessor.HttpContext?.Items["Subdomain"]?.ToString();
|
||||||
SiteInfo = await _contentEditorService.GetSiteInfoByNameAsync(Subdomain);
|
SiteInfo = await _scopedContentService.GetSiteInfoByNameAsync(Subdomain);
|
||||||
if (SiteInfo != null && SiteInfo.IsPublished)
|
if (SiteInfo != null && SiteInfo.IsPublished)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -263,19 +286,17 @@
|
||||||
STTEnabled = false;
|
STTEnabled = false;
|
||||||
}
|
}
|
||||||
_scopedContentService.SelectedSiteId = SiteId;
|
_scopedContentService.SelectedSiteId = SiteId;
|
||||||
ContentCollectionName = SiteInfo.VectorCollectionName ?? "default_content_collection";
|
|
||||||
|
|
||||||
|
|
||||||
Console.Write("------------------------");
|
Console.Write("------------------------");
|
||||||
// Load the CSS template for the selected brand from the database
|
// Load the CSS template for the selected brand from the database
|
||||||
var designTemplate = await DesignTemplateService.GetByIdAsync((int)SiteInfo.TemplateId!);
|
var designTemplate = await DesignTemplateService.GetByIdAsync((int)SiteInfo.TemplateId!);
|
||||||
var cssTemplate = await CssTemplateService.GetByDesignTemplateIdAsync((int)SiteInfo.TemplateId);
|
var cssTemplate = await CssTemplateService.GetByDesignTemplateIdAsync((int)SiteInfo.TemplateId);
|
||||||
TemplateCollectionName = designTemplate.QDrandCollectionName;
|
collectionName = designTemplate.QDrandCollectionName;
|
||||||
|
|
||||||
if (cssTemplate != null)
|
if (cssTemplate != null)
|
||||||
{
|
{
|
||||||
dynamicallyLoadedCss = cssTemplate.CssContent; // Assuming Content holds the CSS string
|
dynamicallyLoadedCss = cssTemplate.CssContent; // Assuming Content holds the CSS string
|
||||||
var cssPath = await CssTemplateService.SaveTempCssFileAsync(dynamicallyLoadedCss, SessionId);
|
var cssPath = await CssTemplateService.SaveTempCssFileAsync(dynamicallyLoadedCss, sessionId);
|
||||||
await jsRuntime.InvokeVoidAsync("seemgen.injectCssFile", cssPath);
|
await jsRuntime.InvokeVoidAsync("seemgen.injectCssFile", cssPath);
|
||||||
|
|
||||||
//await CssService.ApplyCssAsync(dynamicallyLoadedCss);
|
//await CssService.ApplyCssAsync(dynamicallyLoadedCss);
|
||||||
|
|
@ -284,26 +305,13 @@
|
||||||
|
|
||||||
Console.Write($"------------------------ {SiteInfo.MenuItems}, {SiteId}, {SiteInfo.TemplateId}, {SiteInfo.SiteName}");
|
Console.Write($"------------------------ {SiteInfo.MenuItems}, {SiteId}, {SiteInfo.TemplateId}, {SiteInfo.SiteName}");
|
||||||
|
|
||||||
Menu = await GetMenuList(SiteId);
|
Menu = await GetMenuList();
|
||||||
MenuItems = await GetMenuItems(SiteId);
|
|
||||||
if (string.IsNullOrEmpty(HtmlContent.ToString()))
|
if (string.IsNullOrEmpty(HtmlContent.ToString()))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(topic))
|
|
||||||
{
|
|
||||||
UserInput = topic;
|
|
||||||
await ChatGptService.InitSite(SessionId, SiteInfo, TemplateCollectionName, Menu);
|
|
||||||
await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, Menu, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await ChatGptService.InitSite(SessionId, SiteInfo, TemplateCollectionName, Menu);
|
|
||||||
await ChatGptService.GetChatGptWelcomeMessage(SessionId, SiteId, TemplateCollectionName, Menu);
|
|
||||||
// SiteModel = await ChatGptService.InitSite(SessionId, SiteId, TemplateCollectionName, Menu);
|
|
||||||
//await ChatGptService.ProcessContentRequest(SessionId, MenuItems.FirstOrDefault(), SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, Menu, true);
|
|
||||||
}
|
|
||||||
// HtmlContent = await ChatGptService.GetChatGptWelcomeMessage();
|
// HtmlContent = await ChatGptService.GetChatGptWelcomeMessage();
|
||||||
|
await ChatGptService.GetChatGptWelcomeMessage(sessionId, SiteId, Menu);
|
||||||
// UserInput = "Sumerize for me, what is this website about, and what can I do on this website?";
|
// UserInput = "Sumerize for me, what is this website about, and what can I do on this website?";
|
||||||
// await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, Menu);
|
// await ChatGptService.ProcessUserIntent(sessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, collectionName, Menu);
|
||||||
}
|
}
|
||||||
UserInput = string.Empty;
|
UserInput = string.Empty;
|
||||||
// await InvokeAsync(StateHasChanged);
|
// await InvokeAsync(StateHasChanged);
|
||||||
|
|
@ -320,13 +328,13 @@
|
||||||
|
|
||||||
public async void MenuClick(string menuName)
|
public async void MenuClick(string menuName)
|
||||||
{
|
{
|
||||||
await CallCSharpMethod2(menuName, SessionId, true);
|
await CallCSharpMethod2(menuName, sessionId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HomeClick()
|
public void HomeClick()
|
||||||
{
|
{
|
||||||
//ChatGptService.OnContentReceived -= UpdateContent;
|
//ChatGptService.OnContentReceived -= UpdateContent;
|
||||||
ChatGptService.OnContentReceived -= UpdateContent;
|
AIService.OnContentReceived -= UpdateContent;
|
||||||
_navigationManager.Refresh(true);
|
_navigationManager.Refresh(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -342,24 +350,123 @@
|
||||||
myHome = this; // Set the static reference to the current instance
|
myHome = this; // Set the static reference to the current instance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JSInvokable("OpenEmailForm2")]
|
||||||
|
public static async void OpenEmailForm2(string emailAddress)
|
||||||
|
{
|
||||||
|
if (myHome != null)
|
||||||
|
{
|
||||||
|
await myHome.DisplayEmailForm(emailAddress);
|
||||||
|
}
|
||||||
|
Console.Write("openEmail with: " + emailAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DisplayEmailForm(string emailAddress)
|
||||||
|
{
|
||||||
|
FirstColumnClass = "col-12 col-md-6";
|
||||||
|
DocumentEmailAddress = emailAddress;
|
||||||
|
isEmailFormVisible = true;
|
||||||
|
StateHasChanged();
|
||||||
|
var result = await jsRuntime.InvokeAsync<object>("getDivContent", "currentContent");
|
||||||
|
_scopedContentService.CurrentDOM = JsonSerializer.Serialize(result);
|
||||||
|
// Console.Write($"{_scopedContentService.CurrentDOM}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[JSInvokable("CallCSharpMethod2")]
|
||||||
|
public static async Task CallCSharpMethod2(string input, string sessionId, bool forceUnModified = false)
|
||||||
|
{
|
||||||
|
// if (myHome != null)
|
||||||
|
// {
|
||||||
|
// await myHome.HandleJsCall(input, );
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (_instances.TryGetValue(sessionId, out var instance))
|
||||||
|
{
|
||||||
|
await instance.HandleJsCall(input, sessionId, forceUnModified);
|
||||||
|
}
|
||||||
|
Console.Write("Button clicked:" + input);
|
||||||
|
}
|
||||||
|
|
||||||
|
[JSInvokable("ProcessAudio2")]
|
||||||
|
public static async Task ProcessAudio2(string base64Audio, string sessionId)
|
||||||
|
{
|
||||||
|
|
||||||
|
Console.Write("audio incoming");
|
||||||
|
if (myHome != null)
|
||||||
|
{
|
||||||
|
if (myHome.STTEnabled == false) return;
|
||||||
|
Console.WriteLine("STT ENABLED -------------------------------------------------------------------------------");
|
||||||
|
var languageCode = "hu-HU";
|
||||||
|
if (myHome._scopedContentService.SelectedLanguage == "Hungarian")
|
||||||
|
{
|
||||||
|
languageCode = "hu-HU";
|
||||||
|
}
|
||||||
|
else if (myHome._scopedContentService.SelectedLanguage == "English")
|
||||||
|
{
|
||||||
|
languageCode = "en-US";
|
||||||
|
}
|
||||||
|
else if (myHome._scopedContentService.SelectedLanguage == "German")
|
||||||
|
{
|
||||||
|
languageCode = "de-DE";
|
||||||
|
}
|
||||||
|
var credentialsPath = myHome.configuration.GetSection("GoogleAPI").GetValue<string>("CredentialsPath");
|
||||||
|
Console.Write(credentialsPath);
|
||||||
|
var builder = new SpeechClientBuilder
|
||||||
|
{
|
||||||
|
CredentialsPath = credentialsPath
|
||||||
|
};
|
||||||
|
var speech = builder.Build();
|
||||||
|
|
||||||
|
byte[] audioBytes = Convert.FromBase64String(base64Audio);
|
||||||
|
myHome.HtmlContent.Clear();
|
||||||
|
var response = await speech.RecognizeAsync(new RecognitionConfig
|
||||||
|
{
|
||||||
|
Encoding = RecognitionConfig.Types.AudioEncoding.Mp3,
|
||||||
|
SampleRateHertz = 48000, // Match the actual sample rate
|
||||||
|
LanguageCode = languageCode
|
||||||
|
}, RecognitionAudio.FromBytes(audioBytes));
|
||||||
|
Console.Write("BILLED: " + response.TotalBilledTime);
|
||||||
|
foreach (var result in response.Results)
|
||||||
|
{
|
||||||
|
//Console.Write("RESULT: " + result.Alternatives.Count);
|
||||||
|
foreach (var alternative in result.Alternatives)
|
||||||
|
{
|
||||||
|
//Console.WriteLine($"Transcription: {alternative.Transcript}");
|
||||||
|
await myHome.HandleVoiceCommand(alternative.Transcript, sessionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SendMessage()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Button clicked!");
|
||||||
|
var menu = await GetMenuList();
|
||||||
|
HtmlContent.Clear();
|
||||||
|
await ChatGptService.ProcessUserIntent(sessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, collectionName, menu);
|
||||||
|
UserInput = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
await _logger.InfoAsync("Index component initialized.", $"{SiteId}");
|
|
||||||
_scopedContentService.OnBrandNameChanged += HandleBrandNameChanged;
|
_scopedContentService.OnBrandNameChanged += HandleBrandNameChanged;
|
||||||
// ChatGptService.OnContentReceived += UpdateContent;
|
// ChatGptService.OnContentReceived += UpdateContent;
|
||||||
ChatGptService.OnContentReceived += UpdateContent;
|
AIService.OnContentReceived += UpdateContent;
|
||||||
ChatGptService.OnContentReceiveFinished += UpdateFinished;
|
AIService.OnContentReceiveFinished += UpdateFinished;
|
||||||
// ChatGptService.OnStatusChangeReceived += UpdateStatus;
|
// ChatGptService.OnStatusChangeReceived += UpdateStatus;
|
||||||
ChatGptService.OnStatusChangeReceived += UpdateStatus;
|
AIService.OnStatusChangeReceived += UpdateStatus;
|
||||||
ChatGptService.OnTextContentAvailable += UpdateTextContentForVoice;
|
AIService.OnTextContentAvailable += UpdateTextContentForVoice;
|
||||||
SessionId = _scopedContentService.SessionId;
|
sessionId = Guid.NewGuid().ToString();
|
||||||
_instances[SessionId] = this;
|
_instances[sessionId] = this;
|
||||||
|
|
||||||
VoiceEnabled = configuration?.GetSection("AiSettings")?.GetValue<bool>("VoiceActivated") ?? false;
|
VoiceEnabled = configuration?.GetSection("AiSettings")?.GetValue<bool>("VoiceActivated") ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UpdateContent(string receivedSessionId, string content, MenuItem? menuItem)
|
private async void UpdateContent(string receivedSessionId, string content)
|
||||||
{
|
{
|
||||||
if (receivedSessionId == SessionId) // Only accept messages meant for this tab
|
if (receivedSessionId == sessionId) // Only accept messages meant for this tab
|
||||||
{
|
{
|
||||||
|
|
||||||
HtmlContent.Clear();
|
HtmlContent.Clear();
|
||||||
|
|
@ -373,21 +480,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private async void UpdateTextContentForVoice(string receivedSessionId, string content)
|
private async void UpdateTextContentForVoice(string receivedSessionId, string content)
|
||||||
// {
|
{
|
||||||
// Console.WriteLine("UPDATETEXTCONTENT called");
|
if (receivedSessionId == sessionId) // Only accept messages meant for this tab
|
||||||
// if (receivedSessionId == SessionId) // Only accept messages meant for this tab
|
{
|
||||||
// {
|
|
||||||
|
|
||||||
// TextContent = content;
|
TextContent = content;
|
||||||
// await ConvertTextToSpeech(content);
|
await ConvertTextToSpeech();
|
||||||
// //_scopedContentService.CurrentDOM = await jsRuntime.InvokeAsync<string>("getDivContent", "currentContent");
|
//_scopedContentService.CurrentDOM = await jsRuntime.InvokeAsync<string>("getDivContent", "currentContent");
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
private async void UpdateFinished(string receivedSessionId)
|
private async void UpdateFinished(string receivedSessionId)
|
||||||
{
|
{
|
||||||
if (receivedSessionId == SessionId) // Only accept messages meant for this tab
|
if (receivedSessionId == sessionId) // Only accept messages meant for this tab
|
||||||
{
|
{
|
||||||
Console.WriteLine("Content update finished");
|
Console.WriteLine("Content update finished");
|
||||||
var result = await jsRuntime.InvokeAsync<object>("getDivContent", "currentContent");
|
var result = await jsRuntime.InvokeAsync<object>("getDivContent", "currentContent");
|
||||||
|
|
@ -406,7 +512,7 @@
|
||||||
|
|
||||||
private async void UpdateStatus(string receivedSessionId, string content)
|
private async void UpdateStatus(string receivedSessionId, string content)
|
||||||
{
|
{
|
||||||
if (receivedSessionId == SessionId) // Only accept messages meant for this tab
|
if (receivedSessionId == sessionId) // Only accept messages meant for this tab
|
||||||
{
|
{
|
||||||
StatusContent = content;
|
StatusContent = content;
|
||||||
//InvokeAsync(StateHasChanged); // Ensures UI updates dynamically
|
//InvokeAsync(StateHasChanged); // Ensures UI updates dynamically
|
||||||
|
|
@ -421,33 +527,107 @@
|
||||||
{
|
{
|
||||||
if (e.Code == "Enter" || e.Code == "NumpadEnter")
|
if (e.Code == "Enter" || e.Code == "NumpadEnter")
|
||||||
{
|
{
|
||||||
var menu = await GetMenuList(SiteId);
|
var menu = await GetMenuList();
|
||||||
HtmlContent.Clear();
|
HtmlContent.Clear();
|
||||||
string input = "Please tell me more about: " + UserInput;
|
string input = "Please tell me more about: " + UserInput;
|
||||||
await ChatGptService.ProcessUserIntent(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu);
|
await ChatGptService.ProcessUserIntent(sessionId, input, SiteId, (int)SiteInfo.TemplateId!, collectionName, menu);
|
||||||
UserInput = string.Empty;
|
UserInput = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task HandleVoiceCommand(string input, string sessionId)
|
||||||
|
{
|
||||||
|
// HtmlContent = string.Empty;
|
||||||
|
UserInput = input;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
|
||||||
|
await SendUserQuery();
|
||||||
|
//UserInput = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task HandleJsCall(string input, string sessionId, bool forceUnmodified)
|
||||||
|
{
|
||||||
|
HtmlContent.Clear();
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
UserInput = input;
|
||||||
|
await DisplayMenuContent(input, forceUnmodified);
|
||||||
|
UserInput = string.Empty;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SendUserQuery()
|
||||||
|
{
|
||||||
|
welcomeStage = false;
|
||||||
|
if (!string.IsNullOrEmpty(UserInput))
|
||||||
|
{
|
||||||
|
HtmlContent.Clear();
|
||||||
|
var menu = await GetMenuList();
|
||||||
|
await ChatGptService.ProcessUserIntent(sessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, collectionName, menu);
|
||||||
|
UserInput = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DisplayMenuContent(string input, bool forceUnmodified)
|
||||||
|
{
|
||||||
|
welcomeStage = false;
|
||||||
|
if (!string.IsNullOrEmpty(UserInput))
|
||||||
|
{
|
||||||
|
HtmlContent.Clear();
|
||||||
|
var menu = await GetMenuList();
|
||||||
|
var menuItem = (await GetMenuItems()).Where(m => m.Name == input).FirstOrDefault();
|
||||||
|
if (menuItem == null)
|
||||||
|
{
|
||||||
|
await ChatGptService.ProcessContentRequest(sessionId, input, SiteId, (int)SiteInfo.TemplateId!, collectionName, menu, forceUnmodified);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await ChatGptService.ProcessContentRequest(sessionId, menuItem, SiteId, (int)SiteInfo.TemplateId!, collectionName, menu, forceUnmodified);
|
||||||
|
}
|
||||||
|
UserInput = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> GetMenuList()
|
||||||
|
{
|
||||||
|
List<MenuItem> menuItems = (await _contentEditorService.GetMenuItemsBySiteIdAsync(SiteId)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList();
|
||||||
|
string menuList = "";
|
||||||
|
foreach (MenuItem item in menuItems)
|
||||||
|
{
|
||||||
|
menuList += item.Name + ",";
|
||||||
|
}
|
||||||
|
return menuList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<List<MenuItem>> GetMenuItems()
|
||||||
|
{
|
||||||
|
List<MenuItem> menuItems = (await _contentEditorService.GetMenuItemsBySiteIdAsync(SiteId)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList();
|
||||||
|
return menuItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void HandleBrandNameChanged()
|
||||||
|
{
|
||||||
|
selectedBrandName = _scopedContentService.SelectedBrandName;
|
||||||
|
//StateHasChanged();
|
||||||
|
await InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
StateHasChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
dynamicallyLoadedCss = "";
|
dynamicallyLoadedCss = "";
|
||||||
HtmlContent.Clear();
|
HtmlContent.Clear();
|
||||||
_scopedContentService.OnBrandNameChanged -= HandleBrandNameChanged;
|
_scopedContentService.OnBrandNameChanged -= HandleBrandNameChanged;
|
||||||
ChatGptService.OnContentReceived -= UpdateContent;
|
AIService.OnContentReceived -= UpdateContent;
|
||||||
ChatGptService.OnContentReceiveFinished -= UpdateFinished;
|
AIService.OnContentReceiveFinished -= UpdateFinished;
|
||||||
ChatGptService.OnStatusChangeReceived -= UpdateStatus;
|
AIService.OnStatusChangeReceived -= UpdateStatus;
|
||||||
ChatGptService.OnTextContentAvailable -= UpdateTextContentForVoice;
|
AIService.OnTextContentAvailable -= UpdateTextContentForVoice;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask DisposeAsync()
|
public async ValueTask DisposeAsync()
|
||||||
{
|
{
|
||||||
await CssTemplateService.DeleteSessionCssFile(SessionId);
|
await CssTemplateService.DeleteSessionCssFile(sessionId);
|
||||||
_scopedContentService.OnBrandNameChanged -= HandleBrandNameChanged;
|
|
||||||
ChatGptService.OnContentReceived -= UpdateContent;
|
|
||||||
ChatGptService.OnContentReceiveFinished -= UpdateFinished;
|
|
||||||
ChatGptService.OnStatusChangeReceived -= UpdateStatus;
|
|
||||||
ChatGptService.OnTextContentAvailable -= UpdateTextContentForVoice;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
@page "/logs"
|
|
||||||
@using BLAIzor.Models
|
|
||||||
@inject ApplicationDbContext Db
|
|
||||||
@attribute [Authorize]
|
|
||||||
|
|
||||||
<h3 class="mb-3">📋 Application Logs</h3>
|
|
||||||
|
|
||||||
<RadzenCard>
|
|
||||||
<div class="row g-3">
|
|
||||||
<div class="col-md-2">
|
|
||||||
<RadzenDropDown @bind-Value="selectedSeverity"
|
|
||||||
Data="@severities"
|
|
||||||
Placeholder="All Severities"
|
|
||||||
AllowClear="true"
|
|
||||||
Style="width: 100%;" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<RadzenDatePicker @bind-Value="startDate" Placeholder="From date" Style="width: 100%;" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<RadzenDatePicker @bind-Value="endDate" Placeholder="To date" Style="width: 100%;" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<RadzenButton Text="Search" Click="LoadLogs" Icon="search" Style="width: 100%;" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</RadzenCard>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<RadzenDataGrid TItem="AppLog" Data="@logs" Count="@totalCount"
|
|
||||||
LoadData="@LoadData" AllowPaging="true" PageSize="10"
|
|
||||||
AllowSorting="true" AllowFiltering="false"
|
|
||||||
ColumnWidth="200px" ShowPagingSummary="true">
|
|
||||||
<Columns>
|
|
||||||
<RadzenDataGridColumn Width="100px" TItem="AppLog" Property="Timestamp" Title="Time" FormatString="{0:yyyy-MM-dd HH:mm:ss}" />
|
|
||||||
<RadzenDataGridColumn Width="100px" TItem="AppLog" Property="Severity" Title="Severity" />
|
|
||||||
<RadzenDataGridColumn TItem="AppLog" Property="Message" Title="Message" />
|
|
||||||
<RadzenDataGridColumn TItem="AppLog" Property="Details" Title="Details" />
|
|
||||||
</Columns>
|
|
||||||
</RadzenDataGrid>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<h4>📊 Log Summary</h4>
|
|
||||||
|
|
||||||
<RadzenStack Style="width: 100%;">
|
|
||||||
<RadzenChart SeriesClick=@OnSeriesClick>
|
|
||||||
<RadzenPieSeries Data="@logChartData" Title="Logs" CategoryProperty="Severity" ValueProperty="Count">
|
|
||||||
<RadzenSeriesDataLabels Visible="true" />
|
|
||||||
</RadzenPieSeries>
|
|
||||||
</RadzenChart>
|
|
||||||
</RadzenStack>
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private List<AppLog> logs = new();
|
|
||||||
private int totalCount = 0;
|
|
||||||
|
|
||||||
private string? selectedSeverity;
|
|
||||||
private DateTime? startDate;
|
|
||||||
private DateTime? endDate;
|
|
||||||
|
|
||||||
private List<string> severities = new() { "Info", "Warning", "Error" };
|
|
||||||
|
|
||||||
private List<LogChartItem> logChartData = new();
|
|
||||||
|
|
||||||
void OnSeriesClick(SeriesClickEventArgs args)
|
|
||||||
{
|
|
||||||
// console.Log(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task LoadData(LoadDataArgs args)
|
|
||||||
{
|
|
||||||
var query = Db.Logs.AsQueryable();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(selectedSeverity))
|
|
||||||
query = query.Where(l => l.Severity == selectedSeverity);
|
|
||||||
|
|
||||||
if (startDate.HasValue)
|
|
||||||
query = query.Where(l => l.Timestamp >= startDate.Value);
|
|
||||||
|
|
||||||
if (endDate.HasValue)
|
|
||||||
query = query.Where(l => l.Timestamp <= endDate.Value);
|
|
||||||
|
|
||||||
totalCount = query.Count();
|
|
||||||
|
|
||||||
logs = query
|
|
||||||
.OrderByDescending(l => l.Timestamp)
|
|
||||||
.Skip(args.Skip ?? 0)
|
|
||||||
.Take(args.Top ?? 10).ToList();
|
|
||||||
|
|
||||||
await LoadChartData();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task LoadLogs()
|
|
||||||
{
|
|
||||||
await LoadData(new LoadDataArgs { Skip = 0, Top = 10 });
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task LoadChartData()
|
|
||||||
{
|
|
||||||
var query = Db.Logs.AsQueryable();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(selectedSeverity))
|
|
||||||
query = query.Where(l => l.Severity == selectedSeverity);
|
|
||||||
|
|
||||||
if (startDate.HasValue)
|
|
||||||
query = query.Where(l => l.Timestamp >= startDate.Value);
|
|
||||||
|
|
||||||
if (endDate.HasValue)
|
|
||||||
query = query.Where(l => l.Timestamp <= endDate.Value);
|
|
||||||
|
|
||||||
logChartData = query
|
|
||||||
.GroupBy(l => l.Severity)
|
|
||||||
.Select(g => new LogChartItem
|
|
||||||
{
|
|
||||||
Severity = g.Key,
|
|
||||||
Count = g.Count()
|
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LogChartItem
|
|
||||||
{
|
|
||||||
public string Severity { get; set; } = "";
|
|
||||||
public int Count { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,378 +0,0 @@
|
||||||
@page "/create-logo"
|
|
||||||
@using BLAIzor.Components.Layout
|
|
||||||
@attribute [Authorize]
|
|
||||||
@layout AdminLayout
|
|
||||||
@using System.Net.Http.Headers
|
|
||||||
@using System.Text.Json
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@using Microsoft.AspNetCore.Components.Authorization
|
|
||||||
@using SixLabors.ImageSharp
|
|
||||||
@using SixLabors.ImageSharp.Processing
|
|
||||||
@inject IJSRuntime JS
|
|
||||||
@inject IHttpClientFactory HttpClientFactory
|
|
||||||
@inject WhisperTranscriptionService WhisperService
|
|
||||||
@inject ReplicateService ReplicateService
|
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
|
||||||
@inject CustomAuthenticationStateProvider CustomAuthProvider
|
|
||||||
|
|
||||||
<div class="card p-3 shadow-sm bg-panel-gradient text-white" style="max-width:100%; width: 700px; height: 70vh; margin: 0 auto; border-radius: 20px;">
|
|
||||||
<div class="card-header text-center text-white">
|
|
||||||
|
|
||||||
<h3 class="mb-3">Let's build your website step by step</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body" style="overflow: scroll">
|
|
||||||
|
|
||||||
<p class="text-white-50 small mb-3">
|
|
||||||
Step @CurrentStep of @Steps.Count (@(CurrentStep * 100 / Steps.Count)% complete)
|
|
||||||
</p>
|
|
||||||
|
|
||||||
@if (CurrentStep < Steps.Count)
|
|
||||||
{
|
|
||||||
<AnimateOnRender CssClass="animate__animated animate__backInUp" @key="CurrentStep">
|
|
||||||
<div class="my-3 text-center">
|
|
||||||
<label class="form-label">@Steps[CurrentStep].Question</label>
|
|
||||||
<p class="text-muted">@Steps[CurrentStep].Description</p>
|
|
||||||
|
|
||||||
<InputText class="form-control" @bind-Value="Steps[CurrentStep].Answer" />
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</AnimateOnRender>
|
|
||||||
<div class="d-flex justify-content-between mt-3">
|
|
||||||
<button class="btn btn-secondary" @onclick="PreviousStep" disabled="@IsFirstStep">Back</button>
|
|
||||||
<button class="btn btn-primary" @onclick="NextStep">Next</button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<h5 class="mt-4">Site Description Preview</h5>
|
|
||||||
<div class="p-3 bg-panel-gradient-highlight text-dark mb-3 rounded">
|
|
||||||
@((MarkupString)generatedDescription)
|
|
||||||
<button class="btn btn-success" @onclick="ProceedToLogoStep">Use this description</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (ShowLogoStep)
|
|
||||||
{
|
|
||||||
<div class="text-center my-4">
|
|
||||||
<h5>Would you like to upload a logo or generate one?</h5>
|
|
||||||
|
|
||||||
<div class="my-3">
|
|
||||||
@* <input type="file" @onchange="UploadLogo" class="form-control" /> *@
|
|
||||||
<InputFile class="btn btn-default" type="file" multiple OnChange=HandleFileUpload accept=".jpg,.png" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="my-3">
|
|
||||||
<button class="btn btn-outline-primary" @onclick="GenerateLogo" disabled="@IsGeneratingLogo">
|
|
||||||
@(logoGenerationCount == 0 ? "Generate Logo with AI" : "Regenerate Logo")
|
|
||||||
</button>
|
|
||||||
@if (logoGenerationCount > 0 && logoGenerationCount < MaxLogoGenerations)
|
|
||||||
{
|
|
||||||
<p class="text-muted small mt-2">
|
|
||||||
You can regenerate the logo @(MaxLogoGenerations - logoGenerationCount) more time(s).
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (!string.IsNullOrWhiteSpace(GeneratedLogoUrl))
|
|
||||||
{
|
|
||||||
<div class="my-3">
|
|
||||||
<img src="@GeneratedLogoUrl" class="img-fluid rounded shadow" style="max-height: 512px;" />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="p-3 bg-panel-gradient-highlight text-dark mb-3 rounded">
|
|
||||||
<button class="btn btn-success" @onclick="SaveDescription">Save</button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="card-footer my-4 d-flex justify-content-between align-items-center text-white small">
|
|
||||||
@for (int i = 0; i < Steps.Count; i++)
|
|
||||||
{
|
|
||||||
<div class="text-center flex-fill">
|
|
||||||
<div class="mb-1">
|
|
||||||
<div class="@GetStepCircleClass(i)">
|
|
||||||
@(i + 1)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@* <div style="min-height: 36px;">@Steps[i].Question.Split('?')[0]</div> *@
|
|
||||||
@* @if (i < Steps.Count - 1)
|
|
||||||
{ *@
|
|
||||||
<div class="progress-line mx-auto"></div>
|
|
||||||
@* } *@
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
public string UserId { get; set; } = string.Empty;
|
|
||||||
private string userName = string.Empty;
|
|
||||||
private AuthenticationState authState;
|
|
||||||
|
|
||||||
private int CurrentStep = 0;
|
|
||||||
private bool IsFirstStep => CurrentStep == 0;
|
|
||||||
private bool ShowLogoStep = false;
|
|
||||||
private string? GeneratedLogoUrl;
|
|
||||||
private string? logoUrl;
|
|
||||||
|
|
||||||
private int logoGenerationCount = 0;
|
|
||||||
private const int MaxLogoGenerations = 10;
|
|
||||||
private bool IsGeneratingLogo = false;
|
|
||||||
|
|
||||||
private List<QuestionStep> Steps = new()
|
|
||||||
{
|
|
||||||
new("What is the name of your site?", "The domain name or the brand name"),
|
|
||||||
new("Is it for a brand, a person, a cause, a blog, a service, a store, a beauty salon or something else?", "The entity that the site will introduce to the users. "),
|
|
||||||
new("What kind of feel or atmosphere should the site have? (e.g. friendly, professional, mysterious, playful)", "How should your website communicate?"),
|
|
||||||
new("What color(s) do you associate with your brand or prefer for the visuals?", "The colors you have in mind. This is needed for design suggestions and photo generation"),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private string generatedDescription = "";
|
|
||||||
private string siteName = "";
|
|
||||||
private string entity = "";
|
|
||||||
private string persona = "";
|
|
||||||
private string colors = "";
|
|
||||||
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
_instance = this;
|
|
||||||
authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
|
||||||
if (authState.User.Identity?.IsAuthenticated == true)
|
|
||||||
{
|
|
||||||
UserId = CustomAuthProvider.GetUserId();
|
|
||||||
userName = CustomAuthProvider.GetUserName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void NextStep()
|
|
||||||
{
|
|
||||||
if (CurrentStep < Steps.Count)
|
|
||||||
CurrentStep++;
|
|
||||||
if (CurrentStep == Steps.Count)
|
|
||||||
GenerateSiteDescription();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PreviousStep()
|
|
||||||
{
|
|
||||||
if (CurrentStep > 0)
|
|
||||||
CurrentStep--;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GenerateSiteDescription()
|
|
||||||
{
|
|
||||||
var name = Steps[0].Answer;
|
|
||||||
var siteEntity = Steps[1].Answer;
|
|
||||||
var feel = Steps[2].Answer;
|
|
||||||
colors = Steps[3].Answer;
|
|
||||||
|
|
||||||
|
|
||||||
siteName = name;
|
|
||||||
entity = siteEntity;
|
|
||||||
persona = feel;
|
|
||||||
|
|
||||||
generatedDescription = $@"
|
|
||||||
<p><strong>{name}</strong> is a {entity.ToLower()}.</p>
|
|
||||||
<p>The logo should offer {feel.ToLower()} experience for its viewers.</p>
|
|
||||||
<p>The design should reflect {colors.ToLower()} tones for visual consistency.</p>
|
|
||||||
";
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProceedToLogoStep()
|
|
||||||
{
|
|
||||||
ShowLogoStep = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task GenerateLogo()
|
|
||||||
{
|
|
||||||
if (logoGenerationCount >= MaxLogoGenerations)
|
|
||||||
return;
|
|
||||||
|
|
||||||
IsGeneratingLogo = true;
|
|
||||||
|
|
||||||
var logoPrompt = $"Logo for a {entity} named {siteName}, with a {persona} tone, using {colors} colors. DO NOT ADD taglines, or any text other than the brand name: {siteName}.";
|
|
||||||
GeneratedLogoUrl = await ReplicateService.GenerateLogoAsync(logoPrompt, true);
|
|
||||||
logoUrl = GeneratedLogoUrl;
|
|
||||||
|
|
||||||
logoGenerationCount++;
|
|
||||||
|
|
||||||
IsGeneratingLogo = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveDescription()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(GeneratedLogoUrl) && GeneratedLogoUrl.StartsWith("http"))
|
|
||||||
{
|
|
||||||
var savedPath = await DownloadAndSaveImage(GeneratedLogoUrl);
|
|
||||||
if (!string.IsNullOrEmpty(savedPath))
|
|
||||||
{
|
|
||||||
logoUrl = savedPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] siteInfo = new string[6];
|
|
||||||
siteInfo[0] = siteName;
|
|
||||||
siteInfo[1] = generatedDescription;
|
|
||||||
siteInfo[2] = entity;
|
|
||||||
siteInfo[3] = persona;
|
|
||||||
siteInfo[5] = logoUrl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private class QuestionStep
|
|
||||||
{
|
|
||||||
public string Question { get; }
|
|
||||||
public string Description { get; }
|
|
||||||
public string Answer { get; set; } = "";
|
|
||||||
|
|
||||||
public QuestionStep(string question, string description)
|
|
||||||
{
|
|
||||||
Question = question;
|
|
||||||
Description = description;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetStepCircleClass(int index)
|
|
||||||
{
|
|
||||||
if (index < CurrentStep)
|
|
||||||
return "step-circle completed";
|
|
||||||
else if (index == CurrentStep)
|
|
||||||
return "step-circle current";
|
|
||||||
else
|
|
||||||
return "step-circle";
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task HandleFileUpload(InputFileChangeEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.FileCount == 0) return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var uploadPath = Path.Combine("wwwroot", "uploads", UserId);
|
|
||||||
|
|
||||||
foreach (var file in e.GetMultipleFiles())
|
|
||||||
{
|
|
||||||
var folder = GetFolderForFile(file.ContentType);
|
|
||||||
var folderPath = Path.Combine(uploadPath, folder);
|
|
||||||
|
|
||||||
// Create target directory
|
|
||||||
Directory.CreateDirectory(folderPath);
|
|
||||||
|
|
||||||
var filePath = Path.Combine(folderPath, file.Name);
|
|
||||||
await using (var stream = new FileStream(filePath, FileMode.Create))
|
|
||||||
{
|
|
||||||
await file.OpenReadStream(50 * 1024 * 1024).CopyToAsync(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
var relativePath = $"/uploads/{UserId}/{folder}/{file.Name}";
|
|
||||||
AppendFilePathToContent(file.ContentType, relativePath);
|
|
||||||
|
|
||||||
// Generate thumbnail if it's an image
|
|
||||||
string? thumbnailRelativePath = null;
|
|
||||||
|
|
||||||
if (file.ContentType.StartsWith("image/"))
|
|
||||||
{
|
|
||||||
var thumbnailFolder = Path.Combine(folderPath, "thumbnails");
|
|
||||||
Directory.CreateDirectory(thumbnailFolder);
|
|
||||||
|
|
||||||
var thumbnailPath = Path.Combine(thumbnailFolder, file.Name);
|
|
||||||
using var image = await Image.LoadAsync(file.OpenReadStream());
|
|
||||||
image.Mutate(x => x.Resize(new ResizeOptions
|
|
||||||
{
|
|
||||||
Size = new Size(300, 0),
|
|
||||||
Mode = ResizeMode.Max
|
|
||||||
}));
|
|
||||||
await image.SaveAsync(thumbnailPath);
|
|
||||||
|
|
||||||
thumbnailRelativePath = $"/uploads/{UserId}/{folder}/thumbnails/{file.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
AppendFilePathToContent(file.ContentType, relativePath, thumbnailRelativePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error uploading files: {ex.Message}");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//IsLoading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetFolderForFile(string contentType)
|
|
||||||
{
|
|
||||||
return contentType switch
|
|
||||||
{
|
|
||||||
var type when type.StartsWith("image/") => "images",
|
|
||||||
var type when type.StartsWith("video/") => "videos",
|
|
||||||
var type when type.StartsWith("audio/") => "audio",
|
|
||||||
_ => "others"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AppendFilePathToContent(string contentType, string relativePath, string? thumbnailPath = null)
|
|
||||||
{
|
|
||||||
if (contentType.StartsWith("image/"))
|
|
||||||
{
|
|
||||||
logoUrl = relativePath;
|
|
||||||
GeneratedLogoUrl = relativePath;
|
|
||||||
var ThumbnailUrl = thumbnailPath ?? string.Empty;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<string?> DownloadAndSaveImage(string imageUrl)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var uploadPath = Path.Combine("wwwroot", "uploads", UserId, "images");
|
|
||||||
Directory.CreateDirectory(uploadPath);
|
|
||||||
|
|
||||||
var fileName = $"logo_{Guid.NewGuid().ToString().Substring(0, 8)}.jpg";
|
|
||||||
var filePath = Path.Combine(uploadPath, fileName);
|
|
||||||
|
|
||||||
var httpClient = HttpClientFactory.CreateClient();
|
|
||||||
var imageBytes = await httpClient.GetByteArrayAsync(imageUrl);
|
|
||||||
|
|
||||||
await File.WriteAllBytesAsync(filePath, imageBytes);
|
|
||||||
|
|
||||||
// Generate thumbnail
|
|
||||||
var thumbnailFolder = Path.Combine(uploadPath, "thumbnails");
|
|
||||||
Directory.CreateDirectory(thumbnailFolder);
|
|
||||||
|
|
||||||
var thumbnailPath = Path.Combine(thumbnailFolder, fileName);
|
|
||||||
using var image = Image.Load(imageBytes);
|
|
||||||
image.Mutate(x => x.Resize(new ResizeOptions
|
|
||||||
{
|
|
||||||
Size = new Size(300, 0),
|
|
||||||
Mode = ResizeMode.Max
|
|
||||||
}));
|
|
||||||
await image.SaveAsync(thumbnailPath);
|
|
||||||
|
|
||||||
return $"/uploads/{UserId}/images/{fileName}";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error saving logo: {ex.Message}");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// STT Hook
|
|
||||||
private static LogoGenerator? _instance;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,389 +0,0 @@
|
||||||
using BLAIzor.Models;
|
|
||||||
using BLAIzor.Services;
|
|
||||||
using Google.Cloud.Speech.V1;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.JSInterop;
|
|
||||||
using Radzen;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
|
|
||||||
namespace BLAIzor.Components.Pages
|
|
||||||
{
|
|
||||||
public class MainPageBase : ComponentBase
|
|
||||||
{
|
|
||||||
public string SelectedBrandName = "default";
|
|
||||||
[Inject] protected ScopedContentService _scopedContentService { get; set; }
|
|
||||||
[Inject] protected ContentEditorService _contentEditorService { get; set; }
|
|
||||||
[Inject] protected IConfiguration configuration { get; set; }
|
|
||||||
[Inject] protected HttpClient Http { get; set; }
|
|
||||||
[Inject] protected IJSRuntime jsRuntime { get; set; }
|
|
||||||
[Inject] protected ISimpleLogger _logger { get; set; }
|
|
||||||
[Inject] protected AIService ChatGptService { get; set; }
|
|
||||||
[Inject] protected NotificationService NotificationService { get; set; }
|
|
||||||
[Inject] protected CacheService CacheService { get; set; }
|
|
||||||
|
|
||||||
public static readonly Dictionary<string, MainPageBase> _instances = new();
|
|
||||||
|
|
||||||
public string SessionId;
|
|
||||||
public static MainPageBase myHome;
|
|
||||||
|
|
||||||
public int SiteId;
|
|
||||||
public SiteInfo SiteInfo;
|
|
||||||
public StringBuilder HtmlContent = new StringBuilder("");
|
|
||||||
public string TextContent = "";
|
|
||||||
public string StatusContent = "";
|
|
||||||
public string UserInput = string.Empty;
|
|
||||||
public string TemplateCollectionName = "html_snippets";
|
|
||||||
public string ContentCollectionName = "";
|
|
||||||
|
|
||||||
public bool VoiceEnabled;
|
|
||||||
public bool TTSEnabled;
|
|
||||||
public bool STTEnabled;
|
|
||||||
public bool _initVoicePending = false;
|
|
||||||
public bool welcomeStage = true;
|
|
||||||
public bool AiVoicePermitted = true;
|
|
||||||
|
|
||||||
public string FirstColumnClass = "";
|
|
||||||
public bool isEmailFormVisible = false;
|
|
||||||
public ContactFormModel ContactFormModel = new();
|
|
||||||
// private string? SuccessMessage;
|
|
||||||
// private string? ErrorMessage;
|
|
||||||
public string? DocumentEmailAddress = "";
|
|
||||||
|
|
||||||
public string Menu;
|
|
||||||
public List<MenuItem> MenuItems = new();
|
|
||||||
public string dynamicallyLoadedCss = string.Empty;
|
|
||||||
public MenuItem currentMenuItem = new();
|
|
||||||
public bool IsContentSaved = false;
|
|
||||||
|
|
||||||
|
|
||||||
public WebsiteContentModel SiteModel = new();
|
|
||||||
|
|
||||||
public void DoSharedWork()
|
|
||||||
{
|
|
||||||
// Logic here
|
|
||||||
}
|
|
||||||
public async void HandleBrandNameChanged()
|
|
||||||
{
|
|
||||||
SelectedBrandName = _scopedContentService.SelectedBrandName;
|
|
||||||
//await InvokeAsync(() =>
|
|
||||||
// {
|
|
||||||
// StateHasChanged();
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
StateHasChanged();
|
|
||||||
|
|
||||||
//await Task.Run(() =>
|
|
||||||
//{
|
|
||||||
// StateHasChanged();
|
|
||||||
//}).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string> GetMenuList(int siteId)
|
|
||||||
{
|
|
||||||
List<MenuItem> menuItems = (await _contentEditorService.GetMenuItemsBySiteIdAsync(siteId)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList();
|
|
||||||
string menuList = "";
|
|
||||||
foreach (MenuItem item in menuItems)
|
|
||||||
{
|
|
||||||
menuList += item.Name + ",";
|
|
||||||
}
|
|
||||||
return menuList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<MenuItem>> GetMenuItems(int siteId)
|
|
||||||
{
|
|
||||||
List<MenuItem> menuItems = (await _contentEditorService.GetMenuItemsBySiteIdWithChildrenAsync(siteId)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList();
|
|
||||||
return menuItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private string GetApiKey() =>
|
|
||||||
configuration?.GetSection("ElevenLabsAPI")?.GetValue<string>("ApiKey") ?? string.Empty;
|
|
||||||
|
|
||||||
public async Task ConvertTextToSpeech(string textContent)
|
|
||||||
{
|
|
||||||
// string plainText = WebUtility.HtmlDecode(HtmlContent.ToString());
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(textContent) || VoiceEnabled == false || TTSEnabled == false || welcomeStage || !AiVoicePermitted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Console.WriteLine("------------------------------OMGOMGOMG TTS call!!!!-------------");
|
|
||||||
|
|
||||||
var requestContent = new
|
|
||||||
{
|
|
||||||
text = textContent,
|
|
||||||
// model_id = "eleven_multilingual_v2",
|
|
||||||
model_id = "eleven_flash_v2_5",
|
|
||||||
voice_settings = new
|
|
||||||
{
|
|
||||||
stability = 0.5,
|
|
||||||
similarity_boost = 0.75,
|
|
||||||
speed = 1.1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var requestJson = JsonSerializer.Serialize(requestContent);
|
|
||||||
string voiceId;
|
|
||||||
if (SiteInfo.VoiceId != null)
|
|
||||||
{
|
|
||||||
voiceId = SiteInfo.VoiceId;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
voiceId = "rE22Kc7UGoQj4zdHNYvd";
|
|
||||||
}
|
|
||||||
// string voiceId = "yyPLNYHg3CvjlSdSOdLh";
|
|
||||||
|
|
||||||
var httpRequest = new HttpRequestMessage(HttpMethod.Post, $"https://api.elevenlabs.io/v1/text-to-speech/{voiceId}/stream")
|
|
||||||
{
|
|
||||||
Content = new StringContent(requestJson, Encoding.UTF8, "application/json")
|
|
||||||
};
|
|
||||||
|
|
||||||
httpRequest.Headers.Add("xi-api-key", GetApiKey());
|
|
||||||
|
|
||||||
var response = await Http.SendAsync(httpRequest);
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
var audioBytes = await response.Content.ReadAsByteArrayAsync();
|
|
||||||
var base64Audio = Convert.ToBase64String(audioBytes);
|
|
||||||
var audioDataUrl = $"data:audio/mpeg;base64,{base64Audio}";
|
|
||||||
|
|
||||||
await jsRuntime.InvokeVoidAsync("playAudio", audioDataUrl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Handle error response
|
|
||||||
var errorContent = await response.Content.ReadAsStringAsync();
|
|
||||||
Console.Error.WriteLine($"Error: {errorContent}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[JSInvokable("CallCSharpMethod2")]
|
|
||||||
public static async Task CallCSharpMethod2(string input, string sessionId, bool forceUnModified = false)
|
|
||||||
{
|
|
||||||
// if (myHome != null)
|
|
||||||
// {
|
|
||||||
// await myHome.HandleJsCall(input, );
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (_instances.TryGetValue(sessionId, out var instance))
|
|
||||||
{
|
|
||||||
await instance.HandleJsCall(input, sessionId, forceUnModified);
|
|
||||||
}
|
|
||||||
Console.Write("Button clicked:" + input);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task HandleJsCall(string input, string sessionId, bool forceUnmodified)
|
|
||||||
{
|
|
||||||
HtmlContent.Clear();
|
|
||||||
await InvokeAsync(StateHasChanged);
|
|
||||||
UserInput = input;
|
|
||||||
await DisplayMenuContent(input, forceUnmodified);
|
|
||||||
UserInput = string.Empty;
|
|
||||||
await InvokeAsync(StateHasChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task HandleVoiceCommand(string input, string sessionId)
|
|
||||||
{
|
|
||||||
// HtmlContent = string.Empty;
|
|
||||||
UserInput = input;
|
|
||||||
await InvokeAsync(StateHasChanged);
|
|
||||||
|
|
||||||
await SendUserQuery();
|
|
||||||
//UserInput = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SendUserQuery()
|
|
||||||
{
|
|
||||||
welcomeStage = false;
|
|
||||||
if (!string.IsNullOrEmpty(UserInput))
|
|
||||||
{
|
|
||||||
HtmlContent.Clear();
|
|
||||||
var menu = await GetMenuList(SiteId);
|
|
||||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu);
|
|
||||||
UserInput = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DisplayMenuContent(string input, bool forceUnmodified)
|
|
||||||
{
|
|
||||||
welcomeStage = false;
|
|
||||||
if (!string.IsNullOrEmpty(UserInput))
|
|
||||||
{
|
|
||||||
HtmlContent.Clear();
|
|
||||||
var menu = await GetMenuList(SiteId);
|
|
||||||
var menuList = await GetMenuItems(SiteId);
|
|
||||||
|
|
||||||
var menuItem = CompareMenuItemNames(input, menuList);
|
|
||||||
if (menuItem == null)
|
|
||||||
{
|
|
||||||
await ChatGptService.ProcessContentRequest(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, menu, forceUnmodified);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
currentMenuItem = menuItem;
|
|
||||||
if (!string.IsNullOrEmpty(menuItem.StoredHtml))
|
|
||||||
{
|
|
||||||
|
|
||||||
HtmlContent.Clear();
|
|
||||||
HtmlContent.Append(menuItem.StoredHtml);
|
|
||||||
if (currentMenuItem.ContentItemId != null) {
|
|
||||||
var content = await _contentEditorService.GetContentItemByIdAsync((int)currentMenuItem.ContentItemId);
|
|
||||||
if (content != null)
|
|
||||||
{
|
|
||||||
string removedNumbers = TextHelper.ReplaceNumbersAndSpecialCharacters(content.Content, _scopedContentService.SelectedLanguage);
|
|
||||||
Console.WriteLine(removedNumbers);
|
|
||||||
UpdateTextContentForVoice(SessionId, removedNumbers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IsContentSaved = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await ChatGptService.ProcessContentRequest(SessionId, menuItem, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, menu, forceUnmodified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UserInput = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async void UpdateTextContentForVoice(string receivedSessionId, string content)
|
|
||||||
{
|
|
||||||
Console.WriteLine("UPDATETEXTCONTENT called");
|
|
||||||
if (receivedSessionId == SessionId) // Only accept messages meant for this tab
|
|
||||||
{
|
|
||||||
|
|
||||||
TextContent = content;
|
|
||||||
await ConvertTextToSpeech(content);
|
|
||||||
//_scopedContentService.CurrentDOM = await jsRuntime.InvokeAsync<string>("getDivContent", "currentContent");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DisplayEmailForm(string emailAddress)
|
|
||||||
{
|
|
||||||
FirstColumnClass = "col-12 col-md-6";
|
|
||||||
DocumentEmailAddress = emailAddress;
|
|
||||||
isEmailFormVisible = true;
|
|
||||||
StateHasChanged();
|
|
||||||
var result = await jsRuntime.InvokeAsync<object>("getDivContent", "currentContent");
|
|
||||||
_scopedContentService.CurrentDOM = JsonSerializer.Serialize(result);
|
|
||||||
// Console.Write($"{_scopedContentService.CurrentDOM}");
|
|
||||||
}
|
|
||||||
|
|
||||||
[JSInvokable("ProcessAudio2")]
|
|
||||||
public static async Task ProcessAudio2(string base64Audio, string SessionId)
|
|
||||||
{
|
|
||||||
|
|
||||||
Console.Write("audio incoming");
|
|
||||||
if (myHome != null)
|
|
||||||
{
|
|
||||||
if (myHome.STTEnabled == false) return;
|
|
||||||
Console.WriteLine("STT ENABLED -------------------------------------------------------------------------------");
|
|
||||||
var languageCode = "hu-HU";
|
|
||||||
if (myHome._scopedContentService.SelectedLanguage == "Hungarian")
|
|
||||||
{
|
|
||||||
languageCode = "hu-HU";
|
|
||||||
}
|
|
||||||
else if (myHome._scopedContentService.SelectedLanguage == "English")
|
|
||||||
{
|
|
||||||
languageCode = "en-US";
|
|
||||||
}
|
|
||||||
else if (myHome._scopedContentService.SelectedLanguage == "German")
|
|
||||||
{
|
|
||||||
languageCode = "de-DE";
|
|
||||||
}
|
|
||||||
var credentialsPath = myHome.configuration.GetSection("GoogleAPI").GetValue<string>("CredentialsPath");
|
|
||||||
Console.Write(credentialsPath);
|
|
||||||
var builder = new SpeechClientBuilder
|
|
||||||
{
|
|
||||||
CredentialsPath = credentialsPath
|
|
||||||
};
|
|
||||||
var speech = builder.Build();
|
|
||||||
|
|
||||||
byte[] audioBytes = Convert.FromBase64String(base64Audio);
|
|
||||||
myHome.HtmlContent.Clear();
|
|
||||||
var response = await speech.RecognizeAsync(new RecognitionConfig
|
|
||||||
{
|
|
||||||
Encoding = RecognitionConfig.Types.AudioEncoding.Mp3,
|
|
||||||
SampleRateHertz = 48000, // Match the actual sample rate
|
|
||||||
LanguageCode = languageCode
|
|
||||||
}, RecognitionAudio.FromBytes(audioBytes));
|
|
||||||
Console.Write("BILLED: " + response.TotalBilledTime);
|
|
||||||
foreach (var result in response.Results)
|
|
||||||
{
|
|
||||||
//Console.Write("RESULT: " + result.Alternatives.Count);
|
|
||||||
foreach (var alternative in result.Alternatives)
|
|
||||||
{
|
|
||||||
//Console.WriteLine($"Transcription: {alternative.Transcript}");
|
|
||||||
await myHome.HandleVoiceCommand(alternative.Transcript, SessionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[JSInvokable("OpenEmailForm2")]
|
|
||||||
public static async void OpenEmailForm2(string emailAddress)
|
|
||||||
{
|
|
||||||
if (myHome != null)
|
|
||||||
{
|
|
||||||
await myHome.DisplayEmailForm(emailAddress);
|
|
||||||
}
|
|
||||||
Console.Write("openEmail with: " + emailAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SendMessage()
|
|
||||||
{
|
|
||||||
Console.WriteLine("Button clicked!");
|
|
||||||
var menu = await GetMenuList(SiteId);
|
|
||||||
HtmlContent.Clear();
|
|
||||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, menu);
|
|
||||||
UserInput = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MenuItem CompareMenuItemNames(string input, List<MenuItem> menuList)
|
|
||||||
{
|
|
||||||
var parent = menuList.FirstOrDefault(ml => ml.Name == input);
|
|
||||||
if (parent != null)
|
|
||||||
{
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var item in menuList)
|
|
||||||
{
|
|
||||||
var child = item.Children.FirstOrDefault(ch => ch.Name == input);
|
|
||||||
if (child != null)
|
|
||||||
{
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null; // or throw, or return a default
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowNotification(NotificationMessage message)
|
|
||||||
{
|
|
||||||
NotificationService.Notify(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask DisposeAsync()
|
|
||||||
{
|
|
||||||
//await CssTemplateService.DeleteSessionCssFile(SessionId);
|
|
||||||
_scopedContentService.OnBrandNameChanged -= HandleBrandNameChanged;
|
|
||||||
//AIService.OnContentReceived -= UpdateContent;
|
|
||||||
//AIService.OnContentReceiveFinished -= UpdateFinished;
|
|
||||||
//AIService.OnStatusChangeReceived -= UpdateStatus;
|
|
||||||
ChatGptService.OnTextContentAvailable -= UpdateTextContentForVoice;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
||||||
@page "/site/{SiteInfoId:int}/content-groups"
|
|
||||||
@using BLAIzor.Components.Layout
|
|
||||||
@using BLAIzor.Models
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@using Microsoft.AspNetCore.Components.Authorization
|
|
||||||
@layout AdminLayout
|
|
||||||
@inject ContentEditorService contentEditorService
|
|
||||||
@inject NavigationManager Navigation
|
|
||||||
@attribute [Authorize]
|
|
||||||
|
|
||||||
@if (isLoading)
|
|
||||||
{
|
|
||||||
<p>Loading content groups...</p>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
@foreach (var group in groups)
|
|
||||||
{
|
|
||||||
if (selectedGroupId == group.Id)
|
|
||||||
{
|
|
||||||
<EditForm Model="@group" OnValidSubmit="() => SaveGroup(group)">
|
|
||||||
<div class="border rounded p-3 mb-3">
|
|
||||||
<label>
|
|
||||||
Name
|
|
||||||
<InputText class="form-control my-1" @bind-Value="group.Name" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Type
|
|
||||||
<InputText class="form-control my-1" @bind-Value="group.Type" />
|
|
||||||
</label>
|
|
||||||
<div class="d-flex justify-content-between mt-2">
|
|
||||||
<button class="btn btn-success" type="submit">Save</button>
|
|
||||||
<button class="btn btn-danger" type="button" @onclick="() => DeleteGroup(group)">Delete</button>
|
|
||||||
<button class="btn btn-secondary" type="button" @onclick="() => DeselectGroup()">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</EditForm>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<div class="border rounded p-3 mb-3 d-flex justify-content-between align-items-center">
|
|
||||||
<div>
|
|
||||||
<strong>@group.Name</strong><br />
|
|
||||||
<small class="text-muted">@group.Type</small>
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-outline-primary" @onclick="() => SelectGroup(group.Id)">Edit</button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
<button class="btn btn-primary mt-3" @onclick="AddNewGroup">Add New Group</button>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter]
|
|
||||||
public int SiteInfoId { get; set; }
|
|
||||||
|
|
||||||
private List<ContentGroup> groups = new();
|
|
||||||
private bool isLoading = true;
|
|
||||||
|
|
||||||
private int? selectedGroupId = null;
|
|
||||||
|
|
||||||
private void SelectGroup(int groupId)
|
|
||||||
{
|
|
||||||
selectedGroupId = groupId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DeselectGroup()
|
|
||||||
{
|
|
||||||
selectedGroupId = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
isLoading = true;
|
|
||||||
groups = (await contentEditorService.GetContentGroupsBySiteInfoIdAsync(SiteInfoId))
|
|
||||||
.Where(g => g.SiteInfoId == SiteInfoId)
|
|
||||||
.OrderByDescending(g => g.LastUpdated)
|
|
||||||
.ToList();
|
|
||||||
isLoading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EditGroup(ContentGroup group)
|
|
||||||
{
|
|
||||||
Navigation.NavigateTo($"/content-group/{group.Id}/items");
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveGroup(ContentGroup group)
|
|
||||||
{
|
|
||||||
group.LastUpdated = DateTime.UtcNow;
|
|
||||||
group.Version = group.Version + 1;
|
|
||||||
var result = await contentEditorService.UpdateContentGroupByIdAsync(group);
|
|
||||||
if(result != null) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeleteGroup(ContentGroup group)
|
|
||||||
{
|
|
||||||
|
|
||||||
var result = await contentEditorService.DeleteContentGroupByIdAsync(group.Id); ;
|
|
||||||
groups.Remove(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task AddNewGroup()
|
|
||||||
{
|
|
||||||
var newGroup = new ContentGroup
|
|
||||||
{
|
|
||||||
SiteInfoId = SiteInfoId,
|
|
||||||
Name = "New Group",
|
|
||||||
Slug = $"group-{DateTime.UtcNow.Ticks}",
|
|
||||||
Type = "manual",
|
|
||||||
VectorSize = 384,
|
|
||||||
EmbeddingModel = "default",
|
|
||||||
CreatedAt = DateTime.UtcNow,
|
|
||||||
LastUpdated = DateTime.UtcNow,
|
|
||||||
Version = 1
|
|
||||||
};
|
|
||||||
var result = await contentEditorService.CreateContentGroupAsync(newGroup);
|
|
||||||
if(result!=null)
|
|
||||||
{
|
|
||||||
groups.Insert(0, newGroup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -5,35 +5,29 @@
|
||||||
@using BLAIzor.Services
|
@using BLAIzor.Services
|
||||||
@using Microsoft.AspNetCore.Components.Authorization
|
@using Microsoft.AspNetCore.Components.Authorization
|
||||||
@layout AdminLayout
|
@layout AdminLayout
|
||||||
@inject ContentEditorService _contentEditorService
|
@inject ScopedContentService SiteInfoService
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
@inject CustomAuthenticationStateProvider CustomAuthProvider
|
@inject CustomAuthenticationStateProvider CustomAuthProvider
|
||||||
|
|
||||||
|
<h3>Site Information</h3>
|
||||||
|
|
||||||
<EditForm Model="@siteInfo" OnValidSubmit="SaveSiteInfo">
|
<EditForm Model="@siteInfo" OnValidSubmit="SaveSiteInfo">
|
||||||
<label>
|
<label>
|
||||||
Brand name
|
Brand name:
|
||||||
<InputText class="form-control my-3" id="siteName" @bind-Value="siteInfo.SiteName" />
|
<InputText class="form-control my-3" id="siteName" @bind-Value="siteInfo.SiteName" />
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
Site description
|
Brand name:
|
||||||
<InputTextArea class="form-control my-3" style="height: 100px;" id="siteDescription" @bind-Value="siteInfo.SiteDescription" rows="3"/>
|
<InputText class="form-control my-3" id="siteDescription" @bind-Value="siteInfo.SiteDescription" />
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
Logo url
|
Logo url:
|
||||||
<InputText class="form-control my-3" id="brandLogoUrl" @bind-Value="siteInfo.BrandLogoUrl" />
|
<InputText class="form-control my-3" id="brandLogoUrl" @bind-Value="siteInfo.BrandLogoUrl" />
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
Default color (Do not bother with this)
|
Default color
|
||||||
<InputText class="form-control my-3" id="defaultColor" @bind-Value="siteInfo.DefaultColor" />
|
<InputText class="form-control my-3" id="defaultColor" @bind-Value="siteInfo.DefaultColor" />
|
||||||
</label>
|
</label>
|
||||||
<label>
|
|
||||||
The Entity behind this website (eg. "company", "professional sportsman", "worldwide brand", etc);
|
|
||||||
<InputText class="form-control my-3" id="defaultColor" @bind-Value="siteInfo.Entity" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Your agent Persona
|
|
||||||
<InputText class="form-control my-3" id="defaultColor" @bind-Value="siteInfo.Persona" />
|
|
||||||
</label>
|
|
||||||
<label>
|
<label>
|
||||||
Your domain url
|
Your domain url
|
||||||
<InputText class="form-control my-3" id="domainUrl" @bind-Value="siteInfo.DomainUrl" />
|
<InputText class="form-control my-3" id="domainUrl" @bind-Value="siteInfo.DomainUrl" />
|
||||||
|
|
@ -93,12 +87,12 @@ else
|
||||||
userId = CustomAuthProvider.GetUserId();
|
userId = CustomAuthProvider.GetUserId();
|
||||||
userName = CustomAuthProvider.GetUserName();
|
userName = CustomAuthProvider.GetUserName();
|
||||||
}
|
}
|
||||||
siteInfo = await _contentEditorService.GetSiteInfoWithFormsByIdAsync(SiteId) ?? new SiteInfo();
|
siteInfo = await SiteInfoService.GetSiteInfoWithFormsByIdAsync(SiteId) ?? new SiteInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveSiteInfo()
|
private async Task SaveSiteInfo()
|
||||||
{
|
{
|
||||||
await _contentEditorService.UpdateSiteInfoAsync(siteInfo);
|
await SiteInfoService.UpdateSiteInfoAsync(siteInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@
|
||||||
@using BLAIzor.Models.Editor
|
@using BLAIzor.Models.Editor
|
||||||
@using BLAIzor.Services
|
@using BLAIzor.Services
|
||||||
@using Microsoft.AspNetCore.Components.Authorization
|
@using Microsoft.AspNetCore.Components.Authorization
|
||||||
@using SixLabors.ImageSharp
|
|
||||||
@using SixLabors.ImageSharp.Processing
|
|
||||||
@layout AdminLayout
|
@layout AdminLayout
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IHttpContextAccessor HttpContextAccessor
|
@inject IHttpContextAccessor HttpContextAccessor
|
||||||
|
|
@ -28,25 +26,19 @@ else
|
||||||
{
|
{
|
||||||
<div>
|
<div>
|
||||||
<h4>Uploaded Images</h4>
|
<h4>Uploaded Images</h4>
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
<RadzenRow class="rz-text-align-center" Gap="1rem">
|
|
||||||
|
|
||||||
|
|
||||||
@foreach (var image in files.Images)
|
@foreach (var image in files.Images)
|
||||||
{
|
{
|
||||||
|
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-2">
|
||||||
<RadzenColumn Size="6" SizeXS="12" SizeSM="6" SizeMD="4" SizeLG="3" SizeXL="2" SizeXX="2" class="rz-color-on-info-lighter rz-p-5">
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="upload-image-container" @onclick="() => CopyToClipboard(image.OriginalUrl)">
|
<div class="upload-image-container" @onclick="() => CopyToClipboard(image)">
|
||||||
<img class="img-fluid square-thumbnail" src="@image.ThumbnailUrl" alt="Uploaded Image" loading="lazy" />
|
<img class="img-fluid square-thumbnail" src="@image" alt="Uploaded Image" />
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-danger" @onclick="@(() => DeleteFile(image.OriginalUrl, "Images"))">Delete</button>
|
<button class="btn btn-danger" @onclick="@(() => DeleteFile(image, "Images"))">Delete</button>
|
||||||
</div>
|
</div>
|
||||||
</RadzenColumn>
|
</div>
|
||||||
|
|
||||||
}
|
}
|
||||||
</RadzenRow>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4>Uploaded Videos</h4>
|
<h4>Uploaded Videos</h4>
|
||||||
|
|
@ -114,81 +106,25 @@ else
|
||||||
{
|
{
|
||||||
var basePath = Path.Combine("wwwroot", "uploads", userId);
|
var basePath = Path.Combine("wwwroot", "uploads", userId);
|
||||||
|
|
||||||
// Load IMAGES
|
files.Images = Directory.Exists(Path.Combine(basePath, "images"))
|
||||||
var imagesPath = Path.Combine(basePath, "images");
|
? Directory.GetFiles(Path.Combine(basePath, "images"))
|
||||||
var thumbnailsPath = Path.Combine(imagesPath, "thumbnails");
|
.Select(f => $"/uploads/{userId}/images/{Path.GetFileName(f)}")
|
||||||
|
.ToList()
|
||||||
|
: new List<string>();
|
||||||
|
|
||||||
if (!Directory.Exists(thumbnailsPath))
|
files.Videos = Directory.Exists(Path.Combine(basePath, "videos"))
|
||||||
{
|
? Directory.GetFiles(Path.Combine(basePath, "videos"))
|
||||||
Directory.CreateDirectory(thumbnailsPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Directory.Exists(imagesPath))
|
|
||||||
{
|
|
||||||
var imageFiles = Directory.GetFiles(imagesPath)
|
|
||||||
.Where(f => !Path.GetFileName(f).Equals("thumbnails", StringComparison.OrdinalIgnoreCase)) // skip folder
|
|
||||||
.Where(f => !Directory.Exists(f)) // skip directories
|
|
||||||
.Select(f =>
|
|
||||||
{
|
|
||||||
var fileName = Path.GetFileName(f);
|
|
||||||
var originalUrl = $"/uploads/{userId}/images/{fileName}";
|
|
||||||
var thumbnailPath = Path.Combine(thumbnailsPath, fileName);
|
|
||||||
var thumbnailUrl = $"/uploads/{userId}/images/thumbnails/{fileName}";
|
|
||||||
|
|
||||||
// Generate thumbnail if missing
|
|
||||||
if (!File.Exists(thumbnailPath))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using var image = Image.Load(f);
|
|
||||||
image.Mutate(x => x.Resize(new ResizeOptions
|
|
||||||
{
|
|
||||||
Mode = ResizeMode.Max,
|
|
||||||
Size = new Size(300, 300)
|
|
||||||
}));
|
|
||||||
image.Save(thumbnailPath); // Will auto-detect format
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"❌ Error generating thumbnail for {fileName}: {ex.Message}");
|
|
||||||
thumbnailUrl = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UploadedImage
|
|
||||||
{
|
|
||||||
OriginalUrl = originalUrl,
|
|
||||||
ThumbnailUrl = thumbnailUrl
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
files.Images = imageFiles;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
files.Images = new List<UploadedImage>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load VIDEOS
|
|
||||||
var videosPath = Path.Combine(basePath, "videos");
|
|
||||||
files.Videos = Directory.Exists(videosPath)
|
|
||||||
? Directory.GetFiles(videosPath)
|
|
||||||
.Select(f => $"/uploads/{userId}/videos/{Path.GetFileName(f)}")
|
.Select(f => $"/uploads/{userId}/videos/{Path.GetFileName(f)}")
|
||||||
.ToList()
|
.ToList()
|
||||||
: new List<string>();
|
: new List<string>();
|
||||||
|
|
||||||
// Load AUDIO
|
files.Audio = Directory.Exists(Path.Combine(basePath, "audio"))
|
||||||
var audioPath = Path.Combine(basePath, "audio");
|
? Directory.GetFiles(Path.Combine(basePath, "audio"))
|
||||||
files.Audio = Directory.Exists(audioPath)
|
|
||||||
? Directory.GetFiles(audioPath)
|
|
||||||
.Select(f => $"/uploads/{userId}/audio/{Path.GetFileName(f)}")
|
.Select(f => $"/uploads/{userId}/audio/{Path.GetFileName(f)}")
|
||||||
.ToList()
|
.ToList()
|
||||||
: new List<string>();
|
: new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private async Task DeleteFile(string filePath, string fileType)
|
private async Task DeleteFile(string filePath, string fileType)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -216,44 +152,27 @@ else
|
||||||
var folder = GetFolderForFile(file.ContentType);
|
var folder = GetFolderForFile(file.ContentType);
|
||||||
var folderPath = Path.Combine(uploadPath, folder);
|
var folderPath = Path.Combine(uploadPath, folder);
|
||||||
|
|
||||||
// Create target directory
|
// Create directories if they don't exist
|
||||||
Directory.CreateDirectory(folderPath);
|
if (!Directory.Exists(folderPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(folderPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save file
|
||||||
var filePath = Path.Combine(folderPath, file.Name);
|
var filePath = Path.Combine(folderPath, file.Name);
|
||||||
await using (var stream = new FileStream(filePath, FileMode.Create))
|
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||||
{
|
{
|
||||||
await file.OpenReadStream(50 * 1024 * 1024).CopyToAsync(stream);
|
await file.OpenReadStream(50 * 1024 * 1024).CopyToAsync(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add relative path to content
|
||||||
var relativePath = $"/uploads/{userId}/{folder}/{file.Name}";
|
var relativePath = $"/uploads/{userId}/{folder}/{file.Name}";
|
||||||
AppendFilePathToContent(file.ContentType, relativePath);
|
AppendFilePathToContent(file.ContentType, relativePath);
|
||||||
|
|
||||||
// Generate thumbnail if it's an image
|
|
||||||
string? thumbnailRelativePath = null;
|
|
||||||
|
|
||||||
if (file.ContentType.StartsWith("image/"))
|
|
||||||
{
|
|
||||||
var thumbnailFolder = Path.Combine(folderPath, "thumbnails");
|
|
||||||
Directory.CreateDirectory(thumbnailFolder);
|
|
||||||
|
|
||||||
var thumbnailPath = Path.Combine(thumbnailFolder, file.Name);
|
|
||||||
using var image = await Image.LoadAsync(file.OpenReadStream());
|
|
||||||
image.Mutate(x => x.Resize(new ResizeOptions
|
|
||||||
{
|
|
||||||
Size = new Size(300, 0),
|
|
||||||
Mode = ResizeMode.Max
|
|
||||||
}));
|
|
||||||
await image.SaveAsync(thumbnailPath);
|
|
||||||
|
|
||||||
thumbnailRelativePath = $"/uploads/{userId}/{folder}/thumbnails/{file.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
AppendFilePathToContent(file.ContentType, relativePath, thumbnailRelativePath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Error uploading files: {ex.Message}");
|
Console.Write($"Error uploading files: {ex.Message}");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
@ -272,15 +191,11 @@ else
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AppendFilePathToContent(string contentType, string relativePath, string? thumbnailPath = null)
|
private void AppendFilePathToContent(string contentType, string relativePath)
|
||||||
{
|
{
|
||||||
if (contentType.StartsWith("image/"))
|
if (contentType.StartsWith("image/"))
|
||||||
{
|
{
|
||||||
files.Images.Add(new UploadedImage
|
files.Images.Add(relativePath);
|
||||||
{
|
|
||||||
OriginalUrl = relativePath,
|
|
||||||
ThumbnailUrl = thumbnailPath ?? string.Empty
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else if (contentType.StartsWith("video/"))
|
else if (contentType.StartsWith("video/"))
|
||||||
{
|
{
|
||||||
|
|
@ -290,7 +205,6 @@ else
|
||||||
{
|
{
|
||||||
files.Audio.Add(relativePath);
|
files.Audio.Add(relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
@using Microsoft.AspNetCore.Components.Forms
|
@using Microsoft.AspNetCore.Components.Forms
|
||||||
@using System.Text
|
@using System.Text
|
||||||
@using UglyToad.PdfPig
|
@using UglyToad.PdfPig
|
||||||
@inject ContentEditorAIService ContentEditorAIService
|
@inject ContentEditorService ContentEditorService
|
||||||
|
|
||||||
<h3>PDF Form Extractor</h3>
|
<h3>PDF Form Extractor</h3>
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@
|
||||||
|
|
||||||
private async Task<List<FormFieldGroup>> CallAiForFieldExtraction(string plainText)
|
private async Task<List<FormFieldGroup>> CallAiForFieldExtraction(string plainText)
|
||||||
{
|
{
|
||||||
var jsonResult = await ContentEditorAIService.AnalyzeGroupedFormFieldsFromText(plainText);
|
var jsonResult = await ContentEditorService.AnalyzeGroupedFormFieldsFromText(plainText);
|
||||||
Console.WriteLine($"📄 PDF form AI response: {jsonResult}");
|
Console.WriteLine($"📄 PDF form AI response: {jsonResult}");
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -110,7 +110,7 @@ else
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
await base.OnParametersSetAsync();
|
await base.OnParametersSetAsync();
|
||||||
var siteInfo = await contentEditorService.GetSiteInfoByIdAsync(siteId);
|
var siteInfo = await scopedContentService.GetSiteInfoByIdAsync(siteId);
|
||||||
// var menuItems1 = await contentEditorService.GetMenuItemsBySiteIdAsync(1);
|
// var menuItems1 = await contentEditorService.GetMenuItemsBySiteIdAsync(1);
|
||||||
|
|
||||||
menuItems = new ObservableCollection<MenuItem>(await contentEditorService.GetMenuItemsBySiteIdAsync(siteId));
|
menuItems = new ObservableCollection<MenuItem>(await contentEditorService.GetMenuItemsBySiteIdAsync(siteId));
|
||||||
|
|
@ -129,17 +129,17 @@ else
|
||||||
foreach (var menuItem in menuItems)
|
foreach (var menuItem in menuItems)
|
||||||
{
|
{
|
||||||
|
|
||||||
List<WebPageContent> content;
|
string content;
|
||||||
MenuItemModel model = new MenuItemModel("");
|
MenuItemModel model = new MenuItemModel("");
|
||||||
//try to get content from qDrant
|
//try to get content from qDrant
|
||||||
if (menuItem.ContentGroupId != null && menuItem.ContentItemId != null)
|
if (menuItem.QdrantPointId != null)
|
||||||
{
|
{
|
||||||
var contentItem = await contentEditorService.GetContentItemByIdAsync((int)menuItem.ContentItemId);
|
content = await qDrantService.GetContentAsync(siteId, menuItem.SortOrder);
|
||||||
|
var selectedPoint = JsonConvert.DeserializeObject<QDrantGetContentPointResult>(content)!;
|
||||||
if (contentItem != null)
|
if (selectedPoint != null)
|
||||||
{
|
{
|
||||||
model.Content = contentItem.Content;
|
model.Content = selectedPoint.result.payload.content;
|
||||||
|
Console.Write($"Found point: {selectedPoint.result.payload.content}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,28 +6,23 @@
|
||||||
@using Microsoft.AspNetCore.Components.Authorization
|
@using Microsoft.AspNetCore.Components.Authorization
|
||||||
@layout AdminLayout
|
@layout AdminLayout
|
||||||
@inject ScopedContentService SiteInfoService
|
@inject ScopedContentService SiteInfoService
|
||||||
@inject ContentEditorService _contentEditorService
|
@inject ContentService ContentService
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
@inject CustomAuthenticationStateProvider CustomAuthProvider
|
@inject CustomAuthenticationStateProvider CustomAuthProvider
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
|
|
||||||
<h1>Your Sites</h1>
|
<h3>Your Sites</h3>
|
||||||
<div class="row g-0">
|
<div class="row g-0">
|
||||||
<AnimateOnRender CssClass="animate__animated animate__backInUp">
|
<RadzenPanel Collapsed="true" AllowCollapse="true" class="rz-my-10 rz-mx-auto" Style="width: 100%"
|
||||||
<RadzenPanel Collapsed="true" AllowCollapse="true" class="rz-my-5 rz-mx-auto" Style="width: 100%"
|
|
||||||
Expand=@(() => Change("Panel expanded")) Collapse=@(() => Change("Panel collapsed"))>
|
Expand=@(() => Change("Panel expanded")) Collapse=@(() => Change("Panel collapsed"))>
|
||||||
|
|
||||||
<HeaderTemplate>
|
<HeaderTemplate>
|
||||||
<RadzenText TextStyle="TextStyle.H6" class="rz-display-flex rz-align-items-center rz-m-0">
|
<RadzenText TextStyle="TextStyle.H6" class="rz-display-flex rz-align-items-center rz-m-0">
|
||||||
<RadzenIcon Icon="note_add" class="rz-me-1" /><b>New site</b>
|
<RadzenIcon Icon="account_box" class="rz-me-1" /><b>New site</b>
|
||||||
</RadzenText>
|
</RadzenText>
|
||||||
</HeaderTemplate>
|
</HeaderTemplate>
|
||||||
<ChildContent>
|
<ChildContent>
|
||||||
|
<RadzenCard class="rz-mt-4">
|
||||||
<CreateSiteWizard OnDescriptionFinalized="HandleDescriptionGenerated" UserId="@userId" />
|
|
||||||
|
|
||||||
@* <RadzenCard class="rz-mt-4">
|
|
||||||
<EditForm Model="newSite" OnValidSubmit="HandleValidSubmit">
|
<EditForm Model="newSite" OnValidSubmit="HandleValidSubmit">
|
||||||
<DataAnnotationsValidator />
|
<DataAnnotationsValidator />
|
||||||
<ValidationSummary />
|
<ValidationSummary />
|
||||||
|
|
@ -48,99 +43,74 @@
|
||||||
<label for="domainUrl">Domain URL</label>
|
<label for="domainUrl">Domain URL</label>
|
||||||
<InputText id="domainUrl" placeholder="Domain url" class="form-control" @bind-Value="newSite.DomainUrl" />
|
<InputText id="domainUrl" placeholder="Domain url" class="form-control" @bind-Value="newSite.DomainUrl" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-12 mb-3">
|
|
||||||
<label for="siteName" class="form-label">Site description</label>
|
|
||||||
<InputText id="siteDescription" placeholder="A description so AI will know what is this site about" class="form-control" @bind-Value="newSite.SiteDescription" />
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-md-12 mb-3">
|
|
||||||
<label for="siteName" class="form-label">Site language</label>
|
|
||||||
<InputText id="siteLanguage" placeholder="The default language of the website" class="form-control" @bind-Value="newSite.DefaultLanguage" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary">Create Site</button>
|
<button type="submit" class="btn btn-primary">Create Site</button>
|
||||||
</EditForm>
|
</EditForm>
|
||||||
|
|
||||||
</RadzenCard>*@
|
</RadzenCard>
|
||||||
|
|
||||||
|
|
||||||
</ChildContent>
|
</ChildContent>
|
||||||
|
|
||||||
</RadzenPanel>
|
</RadzenPanel>
|
||||||
|
|
||||||
@if (siteInfoList.Any())
|
@if (siteInfoList.Any())
|
||||||
{
|
{
|
||||||
|
|
||||||
<RadzenPanel AllowCollapse="true" class="rz-my-5 rz-mx-auto" Style="width: 100%"
|
<RadzenPanel AllowCollapse="true" class="rz-my-10 rz-mx-auto" Style="width: 100%"
|
||||||
Expand=@(() => Change("Panel expanded")) Collapse=@(() => Change("Panel collapsed"))>
|
Expand=@(() => Change("Panel expanded")) Collapse=@(() => Change("Panel collapsed"))>
|
||||||
<HeaderTemplate>
|
<HeaderTemplate>
|
||||||
<RadzenText TextStyle="TextStyle.H6" class="rz-display-flex rz-align-items-center rz-m-0">
|
<RadzenText TextStyle="TextStyle.H6" class="rz-display-flex rz-align-items-center rz-m-0">
|
||||||
<RadzenIcon Icon="account_box" class="rz-me-1" /><b>Sites created</b>
|
<RadzenIcon Icon="account_box" class="rz-me-1" /><b>Your sites</b>
|
||||||
</RadzenText>
|
</RadzenText>
|
||||||
</HeaderTemplate>
|
</HeaderTemplate>
|
||||||
<ChildContent>
|
<ChildContent>
|
||||||
@{
|
<RadzenCard class="rz-mt-4">
|
||||||
if(siteInfoList.Count() > 0)
|
<RadzenDataList PageSize="3" WrapItems="true" AllowPaging="true"
|
||||||
{
|
|
||||||
<AnimateOnRender CssClass="animate__animated animate__backInUp">
|
|
||||||
<RadzenCard class="rz-mt-4">
|
|
||||||
<RadzenDataList Density="Density.Compact" PageSize="4" WrapItems="true"
|
|
||||||
AllowPaging="false"
|
|
||||||
Data="@siteInfoList" TItem="SiteInfo">
|
Data="@siteInfoList" TItem="SiteInfo">
|
||||||
<Template Context="site">
|
<Template Context="site">
|
||||||
<RadzenCard class="admin-rz-card" Style="width: 250px;">
|
<RadzenCard Style="width: 250px; background-color: darkgrey">
|
||||||
<RadzenRow JustifyContent="@JustifyContent.SpaceBetween">
|
<RadzenRow JustifyContent="@JustifyContent.SpaceBetween">
|
||||||
<RadzenColumn Size="4" class="rz-text-truncate">
|
<RadzenColumn Size="4" class="rz-text-truncate">
|
||||||
<RadzenBadge BadgeStyle="BadgeStyle.Light" Text=@($"{site.Id}") class="rz-me-1" />
|
<RadzenBadge BadgeStyle="BadgeStyle.Light" Text=@($"{site.Id}") class="rz-me-1" />
|
||||||
<b>@(site.SiteName)</b>
|
<b>@(site.SiteName)</b>
|
||||||
</RadzenColumn>
|
</RadzenColumn>
|
||||||
<RadzenColumn Size="8" class="rz-text-align-end">
|
<RadzenColumn Size="8" class="rz-text-align-end">
|
||||||
<RadzenBadge BadgeStyle="BadgeStyle.Success" Text=@($"new") />
|
<RadzenBadge BadgeStyle="BadgeStyle.Success" Text=@($"new") />
|
||||||
</RadzenColumn>
|
</RadzenColumn>
|
||||||
</RadzenRow>
|
</RadzenRow>
|
||||||
<hr style="border: none; background-color: var(--rz-text-disabled-color); height: 1px; margin: 1rem 0;" />
|
<hr style="border: none; background-color: var(--rz-text-disabled-color); height: 1px; margin: 1rem 0;" />
|
||||||
<RadzenStack Orientation="Orientation.Vertical" AlignItems="AlignItems.Center" Gap="1rem">
|
<RadzenStack Orientation="Orientation.Vertical" AlignItems="AlignItems.Center" Gap="1rem">
|
||||||
<RadzenImage Path="@site.BrandLogoUrl" class="img-fluid" Style="max-height: 100px;" AlternateText="@(site.SiteName)" />
|
<RadzenImage Path="@site.BrandLogoUrl" class="img-fluid" Style="max-height: 100px;" AlternateText="@(site.SiteName)" />
|
||||||
<RadzenStack Gap="0">
|
<RadzenStack Gap="0">
|
||||||
<RadzenText TextStyle="TextStyle.H6" class="rz-mb-0">@(site.SiteName)</RadzenText>
|
<RadzenText TextStyle="TextStyle.H6" class="rz-mb-0">@(site.SiteName)</RadzenText>
|
||||||
<RadzenText TextStyle="TextStyle.Body1">@site.DefaultUrl</RadzenText>
|
<RadzenText TextStyle="TextStyle.Body1">@site.DefaultUrl</RadzenText>
|
||||||
<RadzenText TextStyle="TextStyle.Body2">Fefault color: @(site.DefaultColor)</RadzenText>
|
<RadzenText TextStyle="TextStyle.Body2">Fefault color: @(site.DefaultColor)</RadzenText>
|
||||||
<RadzenText TextStyle="TextStyle.Body2">Theme: @(site.TemplateId)</RadzenText>
|
<RadzenText TextStyle="TextStyle.Body2">Theme: @(site.TemplateId)</RadzenText>
|
||||||
</RadzenStack>
|
</RadzenStack>
|
||||||
</RadzenStack>
|
</RadzenStack>
|
||||||
<RadzenStack Orientation="@Orientation.Horizontal" Gap="10px" Reverse="false" JustifyContent="@JustifyContent.Center" AlignItems="@AlignItems.Center" Wrap="@FlexWrap.Wrap" Style="height: fit-content">
|
<RadzenStack Orientation="@Orientation.Horizontal" Gap="10px" Reverse="false" JustifyContent="@JustifyContent.Center" AlignItems="@AlignItems.Center" Wrap="@FlexWrap.Wrap" Style="height: fit-content">
|
||||||
<a href="/site-info/@site.Id" class="btn btn-secondary">Edit</a>
|
|
||||||
<InputText @bind-Value="collectionName" class="form-control" style="width: 100%;" placeholder="Site name" />
|
|
||||||
<a style="font-size: 14px;" @onclick="()=>Migrate(site.Id, collectionName)" class="btn btn-secondary">Migrate</a>
|
|
||||||
<a style="font-size: 14px;" href="/generate-content/@site.Id" class="btn btn-secondary">Manage content</a>
|
|
||||||
<a style="font-size: 14px;" @onclick="()=>Preview(site)" class="btn btn-secondary"> Preview</a>
|
|
||||||
|
|
||||||
</RadzenStack>
|
<a style="font-size: 14px;" href="/site-info/@site.Id" class="btn btn-secondary">Edit</a>
|
||||||
</RadzenCard>
|
<a style="font-size: 14px;" href="/generate-content/@site.Id" class="btn btn-secondary">Manage content</a>
|
||||||
</Template>
|
<a style="font-size: 14px;" @onclick="()=>Preview(site)" class="btn btn-secondary"> Preview</a>
|
||||||
</RadzenDataList>
|
|
||||||
</RadzenCard>
|
</RadzenStack>
|
||||||
</AnimateOnRender>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<RadzenCard class="rz-mt-4">
|
|
||||||
<p>Let1s create your first website!</p>
|
|
||||||
</RadzenCard>
|
</RadzenCard>
|
||||||
}
|
</Template>
|
||||||
|
</RadzenDataList>
|
||||||
}
|
</RadzenCard>
|
||||||
|
</ChildContent>
|
||||||
</ChildContent>
|
<SummaryTemplate>
|
||||||
<SummaryTemplate>
|
<RadzenCard class="rz-mt-4">
|
||||||
<RadzenCard class="rz-mt-4">
|
<b>@siteInfoList.Count() Sites</b>
|
||||||
<b>@siteInfoList.Count() Sites</b>
|
</RadzenCard>
|
||||||
</RadzenCard>
|
</SummaryTemplate>
|
||||||
</SummaryTemplate>
|
</RadzenPanel>
|
||||||
</RadzenPanel>
|
|
||||||
|
|
||||||
|
|
||||||
@* foreach (var item in siteInfoList)
|
@* foreach (var item in siteInfoList)
|
||||||
{
|
{
|
||||||
<div class="col-xs-12 col-md-4">
|
<div class="col-xs-12 col-md-4">
|
||||||
<div class="card m-2">
|
<div class="card m-2">
|
||||||
|
|
@ -166,12 +136,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
} *@
|
} *@
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<p>No sites created yet.</p>
|
<p>No sites created yet.</p>
|
||||||
}
|
}
|
||||||
</AnimateOnRender>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -184,27 +153,6 @@
|
||||||
private string? userName;
|
private string? userName;
|
||||||
private AuthenticationState? authState;
|
private AuthenticationState? authState;
|
||||||
int position = 1;
|
int position = 1;
|
||||||
public string SessionId;
|
|
||||||
//TEMPORARY
|
|
||||||
private string collectionName = "seemgen-collection";
|
|
||||||
|
|
||||||
private string FinalSiteDescription;
|
|
||||||
|
|
||||||
private async Task HandleDescriptionGenerated(string[] desc)
|
|
||||||
{
|
|
||||||
newSite.UserId = userId;
|
|
||||||
FinalSiteDescription = desc[1];
|
|
||||||
newSite.SiteDescription = desc[1];
|
|
||||||
newSite.SiteName = desc[0];
|
|
||||||
newSite.Entity = desc[2];
|
|
||||||
newSite.Persona = desc[3];
|
|
||||||
newSite.DefaultLanguage = desc[4];
|
|
||||||
newSite.BrandLogoUrl = desc[5];
|
|
||||||
newSite.FacebookUrl = desc[6];
|
|
||||||
await HandleValidSubmit();
|
|
||||||
// You can now store it in SiteInfo.SiteDescription
|
|
||||||
// or prefill the full form with the rest of the properties
|
|
||||||
}
|
|
||||||
|
|
||||||
void Change(string text)
|
void Change(string text)
|
||||||
{
|
{
|
||||||
|
|
@ -218,12 +166,6 @@
|
||||||
NavigationManager.NavigateTo(site.DefaultUrl, true);
|
NavigationManager.NavigateTo(site.DefaultUrl, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Migrate(int siteId, string collectionName)
|
|
||||||
{
|
|
||||||
var result = await _contentEditorService.MigrateQdrantToContentItemsAsync(siteId, collectionName);
|
|
||||||
Console.WriteLine($"Migration result: {result}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Preview(SiteInfo site)
|
private async Task Preview(SiteInfo site)
|
||||||
{
|
{
|
||||||
string myUrl = $"/preview/{site.Id}";
|
string myUrl = $"/preview/{site.Id}";
|
||||||
|
|
@ -246,25 +188,17 @@
|
||||||
userId = CustomAuthProvider.GetUserId();
|
userId = CustomAuthProvider.GetUserId();
|
||||||
userName = CustomAuthProvider.GetUserName();
|
userName = CustomAuthProvider.GetUserName();
|
||||||
}
|
}
|
||||||
siteInfoList = await _contentEditorService.GetUserSitesAsync(userId!);
|
siteInfoList = await SiteInfoService.GetUserSitesAsync(userId!);
|
||||||
SessionId = SiteInfoService.SessionId;
|
}
|
||||||
// SiteInfoService.SessionId = SessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task HandleValidSubmit()
|
private async Task HandleValidSubmit()
|
||||||
{
|
{
|
||||||
newSite.UserId = userId;
|
newSite.UserId = userId;
|
||||||
newSite.TemplateId = 1;
|
newSite.TemplateId = 1;
|
||||||
newSite.DefaultUrl = await GenerateSubdomainAsync(newSite.SiteName);
|
newSite.DefaultUrl = await GenerateSubdomainAsync(newSite.SiteName);
|
||||||
newSite.VectorCollectionName = _contentEditorService.GetGeneratedVectorCollectionName(newSite);
|
var result = await SiteInfoService.AddSiteInfoAsync(newSite);
|
||||||
var result = await _contentEditorService.AddSiteInfoAsync(newSite);
|
siteInfoList = await SiteInfoService.GetUserSitesAsync(userId!);
|
||||||
siteInfoList = await _contentEditorService.GetUserSitesAsync(userId!);
|
|
||||||
newSite = new(); // Reset the form
|
newSite = new(); // Reset the form
|
||||||
if(result != null)
|
|
||||||
{
|
|
||||||
|
|
||||||
NavigationManager.NavigateTo($"/generate-content/{result.Id}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public async Task<string> GenerateSubdomainAsync(string siteName)
|
public async Task<string> GenerateSubdomainAsync(string siteName)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
@inject IJSRuntime JS
|
|
||||||
|
|
||||||
<div @ref="ElementRef" class="@CssClass">
|
|
||||||
@ChildContent
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public string CssClass { get; set; } = "animate__animated animate__fadeIn";
|
|
||||||
[Parameter] public RenderFragment? ChildContent { get; set; }
|
|
||||||
|
|
||||||
private ElementReference ElementRef;
|
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
||||||
{
|
|
||||||
if (ElementRef.Context is not null)
|
|
||||||
{
|
|
||||||
await Task.Delay(50); // wait for DOM to settle
|
|
||||||
await JS.InvokeVoidAsync("seemgenAnimationHelper.restartAnimation", ElementRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,148 +0,0 @@
|
||||||
@using BLAIzor.Models
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@inject ContentEditorService contentEditorService
|
|
||||||
@inject DialogService dialogService
|
|
||||||
@inject NotificationService notificationService
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a style="width:100%" @onclick="ToggleVisibility">
|
|
||||||
<div class="mb-2 p-3 reference-button bg-panel">
|
|
||||||
<div class="text-content">
|
|
||||||
<strong>Content count: @contentItems.Count</strong><br />
|
|
||||||
<small class="text-muted">See all</small>
|
|
||||||
</div>
|
|
||||||
<div class="icon-buttons">
|
|
||||||
|
|
||||||
<div class="icon-circle"><i class="fa-solid fa-arrow-down text-white"></i></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
@if (isVisible)
|
|
||||||
{
|
|
||||||
|
|
||||||
<ul class="list-group content-item-list mb-3">
|
|
||||||
<li class="list-group-item">
|
|
||||||
<button class="pointer bg-transparent border-0" style="width:100%; text-align: left; " @onclick="CreateNewItem">
|
|
||||||
<div class="px-3 py-2 reference-button bg-panel-gradient-highlight pointer">
|
|
||||||
<div class="text-content">
|
|
||||||
<strong>Add new content</strong>
|
|
||||||
<br />
|
|
||||||
<small class="text-muted">Add a new content to this group</small>
|
|
||||||
</div>
|
|
||||||
<div class="icon-buttons">
|
|
||||||
|
|
||||||
<div class="icon-circle"><i class="fa-solid fa-plus text-white"></i></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
@* <li><button class="btn btn-sm btn-primary ms-2" @onclick="CreateNewItem">Add New Item</button></li> *@
|
|
||||||
@foreach (var item in contentItems)
|
|
||||||
{
|
|
||||||
<li class="list-group-item">
|
|
||||||
|
|
||||||
<div class="p-2 reference-button">
|
|
||||||
<div class="text-content text-start">
|
|
||||||
<strong>@item.Title</strong>
|
|
||||||
<br />
|
|
||||||
<small class="text-muted">@item.Language - @item.Tags</small>
|
|
||||||
</div>
|
|
||||||
<div class="icon-buttons text-end">
|
|
||||||
<button class="btn btn-sm btn-outline-primary" @onclick="() => EditItem(item.Id)">Edit</button>
|
|
||||||
<button class="btn btn-sm btn-outline-danger" @onclick="() => DeleteItem(item.Id)">Delete</button>
|
|
||||||
@* <div class="icon-circle">V</div> *@
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
}
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public int ContentGroupId { get; set; }
|
|
||||||
[Parameter] public Func<string, int, Task> OnManageContentItemClicked { get; set; }
|
|
||||||
|
|
||||||
private List<ContentItem> contentItems = new();
|
|
||||||
private bool isVisible = false;
|
|
||||||
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
contentItems = await contentEditorService.GetContentItemsByGroupIdAsync(ContentGroupId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ToggleVisibility()
|
|
||||||
{
|
|
||||||
isVisible = !isVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CreateNewItem()
|
|
||||||
{
|
|
||||||
var newItem = new ContentItem
|
|
||||||
{
|
|
||||||
ContentGroupId = ContentGroupId,
|
|
||||||
Title = "New Item",
|
|
||||||
Description = "",
|
|
||||||
Content = "",
|
|
||||||
Language = "en",
|
|
||||||
Tags = "",
|
|
||||||
IsPublished = false,
|
|
||||||
CreatedAt = DateTime.UtcNow,
|
|
||||||
LastUpdated = DateTime.UtcNow,
|
|
||||||
Version = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
var result = await contentEditorService.CreateContentItemAsync(newItem);
|
|
||||||
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
contentItems.Insert(0, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task EditItem(int itemId)
|
|
||||||
{
|
|
||||||
if (OnManageContentItemClicked != null)
|
|
||||||
await OnManageContentItemClicked.Invoke("EditContentItem", itemId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeleteItem(int itemId)
|
|
||||||
{
|
|
||||||
var confirmationResult = await dialogService.Confirm("Are you sure?", "Delete content", new ConfirmOptions() { OkButtonText = "Delete", CancelButtonText = "Oops, no" });
|
|
||||||
if (confirmationResult == true)
|
|
||||||
{
|
|
||||||
await ReallyDeleteItem(itemId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//do nothing?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task ReallyDeleteItem(int itemId)
|
|
||||||
{
|
|
||||||
var result = await contentEditorService.DeleteContentItemByIdAsync(itemId);
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
var toRemove = contentItems.FirstOrDefault(c => c.Id == itemId);
|
|
||||||
if (toRemove != null)
|
|
||||||
{
|
|
||||||
contentItems.Remove(toRemove);
|
|
||||||
}
|
|
||||||
var message = NotificationHelper.CreateNotificationMessage("Group deleted", 2, "Success", "ContentGroup deleted");
|
|
||||||
ShowNotification(message);
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowNotification(NotificationMessage message)
|
|
||||||
{
|
|
||||||
notificationService.Notify(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,501 +0,0 @@
|
||||||
@using System.Net.Http.Headers
|
|
||||||
@using System.Text.Json
|
|
||||||
@using BLAIzor.Interfaces
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@using SixLabors.ImageSharp
|
|
||||||
@using SixLabors.ImageSharp.Processing
|
|
||||||
@inject IJSRuntime JS
|
|
||||||
@inject IHttpClientFactory HttpClientFactory
|
|
||||||
@inject WhisperTranscriptionService WhisperService
|
|
||||||
@inject ReplicateService ReplicateService
|
|
||||||
|
|
||||||
|
|
||||||
<div class="card p-3 shadow-sm bg-panel-gradient text-white" style="max-width:100%; width: 600px; height: 70vh; margin: 0 auto; border-radius: 20px;">
|
|
||||||
<div class="card-header text-center text-white">
|
|
||||||
|
|
||||||
<h3 class="mb-3">Let's build your website step by step</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body" style="overflow-y: scroll">
|
|
||||||
|
|
||||||
<p class="text-white-50 small mb-3">
|
|
||||||
Step @CurrentStep of @Steps.Count (@(CurrentStep * 100 / Steps.Count)% complete)
|
|
||||||
</p>
|
|
||||||
|
|
||||||
@if (CurrentStep < Steps.Count)
|
|
||||||
{
|
|
||||||
<AnimateOnRender CssClass="animate__animated animate__backInUp" @key="CurrentStep">
|
|
||||||
<div class="my-3 text-center">
|
|
||||||
<label class="form-label">@Steps[CurrentStep].Question</label>
|
|
||||||
<p class="text-muted">@Steps[CurrentStep].Description</p>
|
|
||||||
|
|
||||||
@if (CurrentStep == 5)
|
|
||||||
{
|
|
||||||
<InputSelect class="form-select" @bind-Value="Steps[CurrentStep].Answer">
|
|
||||||
<option value="">-- Select Language --</option>
|
|
||||||
<option>English</option>
|
|
||||||
<option>German</option>
|
|
||||||
<option>Hungarian</option>
|
|
||||||
</InputSelect>
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (CurrentStep == 7)
|
|
||||||
{
|
|
||||||
|
|
||||||
<div class="row g-3">
|
|
||||||
<div class="col-md-4">
|
|
||||||
<label class="form-label">Gender</label>
|
|
||||||
<InputSelect class="form-select" @bind-Value="targetGender">
|
|
||||||
<option value="">Any</option>
|
|
||||||
<option>Male</option>
|
|
||||||
<option>Female</option>
|
|
||||||
<option>Non-binary</option>
|
|
||||||
</InputSelect>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<label class="form-label">Age Group</label>
|
|
||||||
<InputSelect class="form-select" @bind-Value="targetAge">
|
|
||||||
<option value="">All ages</option>
|
|
||||||
<option>Under 18</option>
|
|
||||||
<option>18–25</option>
|
|
||||||
<option>26–40</option>
|
|
||||||
<option>41–60</option>
|
|
||||||
<option>60+</option>
|
|
||||||
</InputSelect>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<label class="form-label">Location</label>
|
|
||||||
<InputText class="form-control" @bind-Value="targetLocation" />
|
|
||||||
</div>
|
|
||||||
<div class="col-12">
|
|
||||||
<label class="form-label">Interests</label>
|
|
||||||
<InputText class="form-control" @bind-Value="targetInterests" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (CurrentStep == 8) // Last step: Facebook
|
|
||||||
{
|
|
||||||
<InputText class="form-control" @bind-Value="facebookPageUrl" placeholder="https://www.facebook.com/yourpage" />
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
<InputText class="form-control" @bind-Value="Steps[CurrentStep].Answer" />
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
<div class="mt-2">
|
|
||||||
<button class="btn btn-sm btn-warning me-2" @onclick="StartRecording">🎙️ Speak</button>
|
|
||||||
<button class="btn btn-sm btn-danger" @onclick="StopRecording">⏹️ Stop</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</AnimateOnRender>
|
|
||||||
<div class="d-flex justify-content-between mt-3">
|
|
||||||
<button class="btn btn-secondary" @onclick="PreviousStep" disabled="@IsFirstStep">Back</button>
|
|
||||||
<button class="btn btn-primary" @onclick="NextStep">Next</button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<h5 class="mt-4">Site Description Preview</h5>
|
|
||||||
<div class="p-3 bg-panel-gradient-highlight text-dark mb-3 rounded">
|
|
||||||
@((MarkupString)generatedDescriptionToShow)
|
|
||||||
<button class="btn btn-success" @onclick="ProceedToLogoStep">Use this description</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (ShowLogoStep)
|
|
||||||
{
|
|
||||||
<div class="text-center my-4">
|
|
||||||
<h5>Would you like to upload a logo or generate one?</h5>
|
|
||||||
|
|
||||||
<div class="my-3">
|
|
||||||
@* <input type="file" @onchange="UploadLogo" class="form-control" /> *@
|
|
||||||
<InputFile class="btn btn-default" type="file" multiple OnChange=HandleFileUpload accept=".jpg,.png" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="my-3">
|
|
||||||
<button class="btn btn-outline-primary" @onclick="GenerateLogo" disabled="@IsGeneratingLogo">
|
|
||||||
@(logoGenerationCount == 0 ? "Generate Logo with AI" : "Regenerate Logo")
|
|
||||||
</button>
|
|
||||||
@if (logoGenerationCount > 0 && logoGenerationCount < MaxLogoGenerations)
|
|
||||||
{
|
|
||||||
<p class="text-muted small mt-2">
|
|
||||||
You can regenerate the logo @(MaxLogoGenerations - logoGenerationCount) more time(s).
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (!string.IsNullOrWhiteSpace(GeneratedLogoUrl))
|
|
||||||
{
|
|
||||||
<div class="my-3">
|
|
||||||
<img src="@GeneratedLogoUrl" class="img-fluid rounded shadow" style="max-height: 500px;" />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="p-3 bg-panel-gradient-highlight text-dark mb-3 rounded">
|
|
||||||
<button class="btn btn-success" @onclick="SaveDescription">Save</button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="card-footer my-4 d-flex justify-content-between align-items-center text-white small">
|
|
||||||
@for (int i = 0; i < Steps.Count; i++)
|
|
||||||
{
|
|
||||||
<div class="text-center flex-fill">
|
|
||||||
<div class="mb-1">
|
|
||||||
<div class="@GetStepCircleClass(i)">
|
|
||||||
@(i + 1)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@* <div style="min-height: 36px;">@Steps[i].Question.Split('?')[0]</div> *@
|
|
||||||
@* @if (i < Steps.Count - 1)
|
|
||||||
{ *@
|
|
||||||
<div class="progress-line mx-auto"></div>
|
|
||||||
@* } *@
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public EventCallback<string[]> OnDescriptionFinalized { get; set; }
|
|
||||||
[Parameter] public string UserId { get; set; }
|
|
||||||
|
|
||||||
private int CurrentStep = 0;
|
|
||||||
private bool IsFirstStep => CurrentStep == 0;
|
|
||||||
private bool ShowLogoStep = false;
|
|
||||||
private string? GeneratedLogoUrl;
|
|
||||||
private string? logoUrl;
|
|
||||||
|
|
||||||
private int logoGenerationCount = 0;
|
|
||||||
private const int MaxLogoGenerations = 5;
|
|
||||||
private bool IsGeneratingLogo = false;
|
|
||||||
|
|
||||||
private List<QuestionStep> Steps = new()
|
|
||||||
{
|
|
||||||
new("What is the name of your site?", "The domain name or the brand name"),
|
|
||||||
new("Is it for a brand, a person, a cause, a blog, a service, a store, a beauty salon or something else?", "The entity that the site will introduce to the users. "),
|
|
||||||
new("What is the main purpose of the site?", "What is your goal with the website. Promote the brand, or acquire new customers? This is needed for SEO, and content generation."),
|
|
||||||
new("What kind of feel or atmosphere should the site have? (e.g. friendly, professional, mysterious, playful)", "How should your website communicate?"),
|
|
||||||
new("Where is it located (country or city)?", "This is for content generation and SEO purposes."),
|
|
||||||
new("What is your preferred language?", "The default language of your website. As it is AI driven, AI can answer in almost any language to questions"),
|
|
||||||
new("What color(s) do you associate with your brand or prefer for the visuals?", "The colors you have in mind. This is needed for design suggestions and photo generation"),
|
|
||||||
new("Who is your target audience?", "This is needed to generate have a better overall understanding during content generation."),
|
|
||||||
new("Do you already have a Facebook page for your business?", "Provide the URL of your Facebook page if you have one. We'll use it to generate content more accurately.")
|
|
||||||
};
|
|
||||||
|
|
||||||
private string targetGender = "";
|
|
||||||
private string targetAge = "";
|
|
||||||
private string targetLocation = "";
|
|
||||||
private string targetInterests = "";
|
|
||||||
|
|
||||||
private string generatedDescription = "";
|
|
||||||
private string generatedDescriptionToShow = "";
|
|
||||||
private string siteName = "";
|
|
||||||
private string entity = "";
|
|
||||||
private string persona = "";
|
|
||||||
private string defaultLanguage = "";
|
|
||||||
private string facebookPageUrl = "";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 3. Trigger Brightdata scraping after generating site description
|
|
||||||
private async Task GenerateSiteDescription()
|
|
||||||
{
|
|
||||||
var name = Steps[0].Answer;
|
|
||||||
var siteEntity = Steps[1].Answer;
|
|
||||||
var purpose = Steps[2].Answer;
|
|
||||||
var feel = Steps[3].Answer;
|
|
||||||
var location = Steps[4].Answer;
|
|
||||||
var language = Steps[5].Answer;
|
|
||||||
var color = Steps[6].Answer;
|
|
||||||
var facebook = Steps[8].Answer;
|
|
||||||
|
|
||||||
var audience = $"people who are {(string.IsNullOrEmpty(targetGender) ? "all genders" : targetGender.ToLower())} aged {(string.IsNullOrEmpty(targetAge) ? "any age" : targetAge)}, located in {targetLocation}, interested in {targetInterests.ToLower()}";
|
|
||||||
|
|
||||||
siteName = name;
|
|
||||||
entity = siteEntity;
|
|
||||||
persona = feel;
|
|
||||||
defaultLanguage = language;
|
|
||||||
|
|
||||||
generatedDescription = $@"
|
|
||||||
{name} is a {entity.ToLower()} based in {location}, created to {purpose.ToLower()}.
|
|
||||||
The site aims to offer a {feel.ToLower()} experience for its visitors, primarily targeting {audience}.
|
|
||||||
The preferred language is {language}, and the design should reflect {color.ToLower()} tones for visual consistency.
|
|
||||||
";
|
|
||||||
|
|
||||||
generatedDescriptionToShow = $@"
|
|
||||||
<p><strong>{name}</strong> is a {entity.ToLower()} based in {location}, created to {purpose.ToLower()}.</p>
|
|
||||||
<p>The site aims to offer a {feel.ToLower()} experience for its visitors, primarily targeting {audience}.</p>
|
|
||||||
<p>The preferred language is {language}, and the design should reflect {color.ToLower()} tones for visual consistency.</p>
|
|
||||||
";
|
|
||||||
|
|
||||||
// --- New: Scrape Facebook posts if provided ---
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
|
||||||
{
|
|
||||||
_instance = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void NextStep()
|
|
||||||
{
|
|
||||||
if (CurrentStep < Steps.Count)
|
|
||||||
CurrentStep++;
|
|
||||||
if (CurrentStep == Steps.Count)
|
|
||||||
GenerateSiteDescription();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PreviousStep()
|
|
||||||
{
|
|
||||||
if (CurrentStep > 0)
|
|
||||||
CurrentStep--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// private void GenerateSiteDescription()
|
|
||||||
// {
|
|
||||||
// var name = Steps[0].Answer;
|
|
||||||
// var siteEntity = Steps[1].Answer;
|
|
||||||
// var purpose = Steps[2].Answer;
|
|
||||||
// var feel = Steps[3].Answer;
|
|
||||||
// var location = Steps[4].Answer;
|
|
||||||
// var language = Steps[5].Answer;
|
|
||||||
// var color = Steps[6].Answer;
|
|
||||||
|
|
||||||
// var audience = $"people who are {(string.IsNullOrEmpty(targetGender) ? "all genders" : targetGender.ToLower())} aged {(string.IsNullOrEmpty(targetAge) ? "any age" : targetAge)}, located in {targetLocation}, interested in {targetInterests.ToLower()}";
|
|
||||||
|
|
||||||
// siteName = name;
|
|
||||||
// entity = siteEntity;
|
|
||||||
// persona = feel;
|
|
||||||
// defaultLanguage = language;
|
|
||||||
|
|
||||||
// generatedDescription = $@"
|
|
||||||
// {name} is a {entity.ToLower()} based in {location}, created to {purpose.ToLower()}.
|
|
||||||
// The site aims to offer a {feel.ToLower()} experience for its visitors, primarily targeting {audience}.
|
|
||||||
// The preferred language is {language}, and the design should reflect {color.ToLower()} tones for visual consistency.
|
|
||||||
// ";
|
|
||||||
|
|
||||||
// generatedDescriptionToShow = $@"
|
|
||||||
// <p><strong>{name}</strong> is a {entity.ToLower()} based in {location}, created to {purpose.ToLower()}.</p>
|
|
||||||
// <p>The site aims to offer a {feel.ToLower()} experience for its visitors, primarily targeting {audience}.</p>
|
|
||||||
// <p>The preferred language is {language}, and the design should reflect {color.ToLower()} tones for visual consistency.</p>
|
|
||||||
// ";
|
|
||||||
// }
|
|
||||||
|
|
||||||
private void ProceedToLogoStep()
|
|
||||||
{
|
|
||||||
ShowLogoStep = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// private async Task GenerateLogo()
|
|
||||||
// {
|
|
||||||
// var logoPrompt = $"Logo for a {entity} named {siteName}, with a {persona} tone, using {Steps[6].Answer} colors.";
|
|
||||||
// GeneratedLogoUrl = await ReplicateService.GenerateImageAsync(logoPrompt);
|
|
||||||
// logoUrl = GeneratedLogoUrl;
|
|
||||||
// }
|
|
||||||
|
|
||||||
private async Task GenerateLogo()
|
|
||||||
{
|
|
||||||
if (logoGenerationCount >= MaxLogoGenerations)
|
|
||||||
return;
|
|
||||||
|
|
||||||
IsGeneratingLogo = true;
|
|
||||||
|
|
||||||
var logoPrompt = $"Logo for a {entity} named {siteName}, with a {persona} tone, using {Steps[6].Answer} colors. DO NOT ADD taglines, or any text other than the brand name: {siteName}.";
|
|
||||||
GeneratedLogoUrl = await ReplicateService.GenerateLogoAsync(logoPrompt, true);
|
|
||||||
logoUrl = GeneratedLogoUrl;
|
|
||||||
|
|
||||||
logoGenerationCount++;
|
|
||||||
|
|
||||||
IsGeneratingLogo = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveDescription()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(GeneratedLogoUrl) && GeneratedLogoUrl.StartsWith("http"))
|
|
||||||
{
|
|
||||||
var savedPath = await DownloadAndSaveImage(GeneratedLogoUrl);
|
|
||||||
if (!string.IsNullOrEmpty(savedPath))
|
|
||||||
{
|
|
||||||
logoUrl = savedPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] siteInfo = new string[7];
|
|
||||||
siteInfo[0] = siteName;
|
|
||||||
siteInfo[1] = generatedDescription;
|
|
||||||
siteInfo[2] = entity;
|
|
||||||
siteInfo[3] = persona;
|
|
||||||
siteInfo[4] = defaultLanguage;
|
|
||||||
siteInfo[5] = logoUrl;
|
|
||||||
siteInfo[6] = facebookPageUrl;
|
|
||||||
await OnDescriptionFinalized.InvokeAsync(siteInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task StartRecording() => await JS.InvokeVoidAsync("startRecording");
|
|
||||||
private async Task StopRecording() => await JS.InvokeVoidAsync("stopRecording");
|
|
||||||
|
|
||||||
private class QuestionStep
|
|
||||||
{
|
|
||||||
public string Question { get; }
|
|
||||||
public string Description { get; }
|
|
||||||
public string Answer { get; set; } = "";
|
|
||||||
|
|
||||||
public QuestionStep(string question, string description)
|
|
||||||
{
|
|
||||||
Question = question;
|
|
||||||
Description = description;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetStepCircleClass(int index)
|
|
||||||
{
|
|
||||||
if (index < CurrentStep)
|
|
||||||
return "step-circle completed";
|
|
||||||
else if (index == CurrentStep)
|
|
||||||
return "step-circle current";
|
|
||||||
else
|
|
||||||
return "step-circle";
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task HandleFileUpload(InputFileChangeEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.FileCount == 0) return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var uploadPath = Path.Combine("wwwroot", "uploads", UserId);
|
|
||||||
|
|
||||||
foreach (var file in e.GetMultipleFiles())
|
|
||||||
{
|
|
||||||
var folder = GetFolderForFile(file.ContentType);
|
|
||||||
var folderPath = Path.Combine(uploadPath, folder);
|
|
||||||
|
|
||||||
// Create target directory
|
|
||||||
Directory.CreateDirectory(folderPath);
|
|
||||||
|
|
||||||
var filePath = Path.Combine(folderPath, file.Name);
|
|
||||||
await using (var stream = new FileStream(filePath, FileMode.Create))
|
|
||||||
{
|
|
||||||
await file.OpenReadStream(50 * 1024 * 1024).CopyToAsync(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
var relativePath = $"/uploads/{UserId}/{folder}/{file.Name}";
|
|
||||||
AppendFilePathToContent(file.ContentType, relativePath);
|
|
||||||
|
|
||||||
// Generate thumbnail if it's an image
|
|
||||||
string? thumbnailRelativePath = null;
|
|
||||||
|
|
||||||
if (file.ContentType.StartsWith("image/"))
|
|
||||||
{
|
|
||||||
var thumbnailFolder = Path.Combine(folderPath, "thumbnails");
|
|
||||||
Directory.CreateDirectory(thumbnailFolder);
|
|
||||||
|
|
||||||
var thumbnailPath = Path.Combine(thumbnailFolder, file.Name);
|
|
||||||
using var image = await Image.LoadAsync(file.OpenReadStream());
|
|
||||||
image.Mutate(x => x.Resize(new ResizeOptions
|
|
||||||
{
|
|
||||||
Size = new Size(300, 0),
|
|
||||||
Mode = ResizeMode.Max
|
|
||||||
}));
|
|
||||||
await image.SaveAsync(thumbnailPath);
|
|
||||||
|
|
||||||
thumbnailRelativePath = $"/uploads/{UserId}/{folder}/thumbnails/{file.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
AppendFilePathToContent(file.ContentType, relativePath, thumbnailRelativePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error uploading files: {ex.Message}");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//IsLoading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetFolderForFile(string contentType)
|
|
||||||
{
|
|
||||||
return contentType switch
|
|
||||||
{
|
|
||||||
var type when type.StartsWith("image/") => "images",
|
|
||||||
var type when type.StartsWith("video/") => "videos",
|
|
||||||
var type when type.StartsWith("audio/") => "audio",
|
|
||||||
_ => "others"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AppendFilePathToContent(string contentType, string relativePath, string? thumbnailPath = null)
|
|
||||||
{
|
|
||||||
if (contentType.StartsWith("image/"))
|
|
||||||
{
|
|
||||||
logoUrl = relativePath;
|
|
||||||
GeneratedLogoUrl = relativePath;
|
|
||||||
var ThumbnailUrl = thumbnailPath ?? string.Empty;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<string?> DownloadAndSaveImage(string imageUrl)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var uploadPath = Path.Combine("wwwroot", "uploads", UserId, "images");
|
|
||||||
Directory.CreateDirectory(uploadPath);
|
|
||||||
|
|
||||||
var fileName = $"logo_{Guid.NewGuid().ToString().Substring(0, 8)}.jpg";
|
|
||||||
var filePath = Path.Combine(uploadPath, fileName);
|
|
||||||
|
|
||||||
var httpClient = HttpClientFactory.CreateClient();
|
|
||||||
var imageBytes = await httpClient.GetByteArrayAsync(imageUrl);
|
|
||||||
|
|
||||||
await File.WriteAllBytesAsync(filePath, imageBytes);
|
|
||||||
|
|
||||||
// Generate thumbnail
|
|
||||||
var thumbnailFolder = Path.Combine(uploadPath, "thumbnails");
|
|
||||||
Directory.CreateDirectory(thumbnailFolder);
|
|
||||||
|
|
||||||
var thumbnailPath = Path.Combine(thumbnailFolder, fileName);
|
|
||||||
using var image = Image.Load(imageBytes);
|
|
||||||
image.Mutate(x => x.Resize(new ResizeOptions
|
|
||||||
{
|
|
||||||
Size = new Size(300, 0),
|
|
||||||
Mode = ResizeMode.Max
|
|
||||||
}));
|
|
||||||
await image.SaveAsync(thumbnailPath);
|
|
||||||
|
|
||||||
return $"/uploads/{UserId}/images/{fileName}";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error saving logo: {ex.Message}");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// STT Hook
|
|
||||||
private static CreateSiteWizard? _instance;
|
|
||||||
|
|
||||||
[JSInvokable]
|
|
||||||
public static async Task SendAudioToServer(List<byte> audioData)
|
|
||||||
{
|
|
||||||
if (_instance is null) return;
|
|
||||||
|
|
||||||
var result = await _instance.WhisperService.TranscribeAsync(audioData.ToArray());
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(result))
|
|
||||||
{
|
|
||||||
_instance.Steps[_instance.CurrentStep].Answer = result;
|
|
||||||
_instance.StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
@page "/dialogcard/{OrderID}"
|
|
||||||
|
|
||||||
@using Microsoft.EntityFrameworkCore
|
|
||||||
|
|
||||||
@inject Radzen.DialogService dialogService
|
|
||||||
|
|
||||||
<RadzenStack Gap="1rem" Orientation="Orientation.Vertical" JustifyContent="JustifyContent.SpaceBetween" Style="height: 100%;">
|
|
||||||
<RadzenStack>
|
|
||||||
|
|
||||||
</RadzenStack>
|
|
||||||
</RadzenStack>
|
|
||||||
@code {
|
|
||||||
[Parameter] public int OrderID { get; set; }
|
|
||||||
[Parameter] public bool ShowClose { get; set; } = true;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
|
||||||
{
|
|
||||||
await base.OnParametersSetAsync();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
@using BLAIzor.Models
|
|
||||||
|
|
||||||
|
|
||||||
@if (!editCurrentGroup)
|
|
||||||
{
|
|
||||||
@* <div class="reference-button">
|
|
||||||
<div class="text-content">
|
|
||||||
<h4>Reference</h4>
|
|
||||||
<p>Create songs inspired by a<br>reference track</p>
|
|
||||||
</div>
|
|
||||||
<div class="icon-buttons">
|
|
||||||
<div class="icon-circle">+</div>
|
|
||||||
<div class="icon-circle">★</div>
|
|
||||||
</div>
|
|
||||||
</div> *@
|
|
||||||
|
|
||||||
<div class="bg-panel rounded p-3 mb-3">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-8">
|
|
||||||
<div @key="Group.Id">
|
|
||||||
<strong>
|
|
||||||
@Group.Name
|
|
||||||
</strong>
|
|
||||||
<small class="text-muted">
|
|
||||||
Group type: @Group.Type
|
|
||||||
</small>
|
|
||||||
<small class="text-muted">
|
|
||||||
Group slug: @Group.Slug
|
|
||||||
</small>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-4">
|
|
||||||
<div class="d-flex flex-row-reverse">
|
|
||||||
@* <RadzenButton Text="Edit" Click="() => ToggleGroupEdit()"></RadzenButton>
|
|
||||||
<RadzenButton ButtonStyle=@ButtonStyle.Warning Text="Edit" Click="() => OnForceReChunkClicked(Group)"></RadzenButton> *@
|
|
||||||
<button class="btn" type="button" @onclick="() => ToggleGroupEdit()">Edit</button>
|
|
||||||
@* <button class="btn btn-warning" type="button" @onclick="() => OnForceReChunkClicked(Group)">ReChunk</button> *@
|
|
||||||
<button class="btn btn-danger" type="button" @onclick="() => DeleteGroup(Group)">Delete</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<ContentItemList ContentGroupId="@Group.Id" OnManageContentItemClicked="ContentItemManagedCallback"></ContentItemList>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<EditForm Model="@Group" OnValidSubmit="() => SaveGroup(Group)">
|
|
||||||
<div class="rounded bg-panel p-3 mb-3">
|
|
||||||
<label>
|
|
||||||
Name
|
|
||||||
<InputText class="form-control my-1" @bind-Value="Group.Name" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Type
|
|
||||||
<InputText class="form-control my-1" @bind-Value="Group.Type" />
|
|
||||||
</label>
|
|
||||||
<div class="d-flex flex-row-reverse">
|
|
||||||
<button class="btn btn-success" type="submit">Save</button>
|
|
||||||
|
|
||||||
<button class="btn btn-secondary" type="button" @onclick="() => ToggleGroupEdit()">Cancel</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</EditForm>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public ContentGroup Group { get; set; }
|
|
||||||
// [Parameter] public Action<ContentGroup> OnContentGroupUpdated { get; set; }
|
|
||||||
[Parameter] public Func<ContentGroup, Task> OnContentGroupSaveClicked { get; set; }
|
|
||||||
[Parameter] public Func<ContentGroup, Task> OnContentGroupDeleteClicked { get; set; }
|
|
||||||
[Parameter] public Func<ContentGroup, Task> OnForceReChunkClicked { get; set; }
|
|
||||||
// [Parameter] public Func<Task> OnContentGroupDeselectClicked { get; set; }
|
|
||||||
[Parameter] public Func<string, int, Task> OnManageContentItemClicked { get; set; }
|
|
||||||
|
|
||||||
private bool editCurrentGroup = false;
|
|
||||||
|
|
||||||
private async Task ForceReChunk(int contenGroupId)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ToggleGroupEdit()
|
|
||||||
{
|
|
||||||
Console.WriteLine($"dklsajdlaéjdksléajdéal djkéa sdjklaésj dkléajdklaéjdkléa");
|
|
||||||
editCurrentGroup = !editCurrentGroup;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveGroup(ContentGroup group)
|
|
||||||
{
|
|
||||||
if (OnContentGroupSaveClicked != null)
|
|
||||||
await OnContentGroupSaveClicked.Invoke(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeleteGroup(ContentGroup group)
|
|
||||||
{
|
|
||||||
if (OnContentGroupDeleteClicked != null)
|
|
||||||
await OnContentGroupDeleteClicked.Invoke(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ContentItemManagedCallback(string method, int itemId)
|
|
||||||
{
|
|
||||||
if (OnManageContentItemClicked != null)
|
|
||||||
await OnManageContentItemClicked.Invoke(method, itemId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ForceContentReChunkCallback(ContentGroup group)
|
|
||||||
{
|
|
||||||
if (OnForceReChunkClicked != null)
|
|
||||||
await OnForceReChunkClicked.Invoke(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
@using BLAIzor.Models
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@inject ContentEditorService contentEditorService
|
|
||||||
@inject CacheService cache
|
|
||||||
|
|
||||||
@if (isLoading)
|
|
||||||
{
|
|
||||||
<p>Loading content item...</p>
|
|
||||||
}
|
|
||||||
else if (contentItem == null)
|
|
||||||
{
|
|
||||||
<p class="text-danger">Content item not found.</p>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<EditForm Model="@contentItem" OnValidSubmit="HandleSave">
|
|
||||||
<div class="rounded p-3 bg-panel">
|
|
||||||
<label>
|
|
||||||
Title
|
|
||||||
<InputText class="form-control my-2" @bind-Value="contentItem.Title" />
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
Description
|
|
||||||
<InputTextArea class="form-control my-2" style="height: 60px;" @bind-Value="contentItem.Description" Rows="3" />
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
Content
|
|
||||||
<InputTextArea class="form-control my-2" style="height: 200px;" @bind-Value="contentItem.Content" Rows="10" />
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
Language
|
|
||||||
<InputText class="form-control my-2" @bind-Value="contentItem.Language" />
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
Tags (comma-separated)
|
|
||||||
<InputText class="form-control my-2" @bind-Value="contentItem.Tags" />
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="form-check my-2">
|
|
||||||
<InputCheckbox class="form-check-input" id="isPublished" @bind-Value="contentItem.IsPublished" />
|
|
||||||
<label class="form-check-label" for="isPublished">Published</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-flex flex-row-reverse">
|
|
||||||
<button class="btn btn-primary" type="submit">Save</button>
|
|
||||||
<button class="btn btn-secondary" type="button" @onclick="CancelEdit">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</EditForm>
|
|
||||||
}
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public int ContentItemId { get; set; }
|
|
||||||
[Parameter] public Func<ContentItem, Task> OnContentUpdated { get; set; }
|
|
||||||
[Parameter] public Func<ContentItem, Task> OnSaved { get; set; }
|
|
||||||
[Parameter] public Func<Task> OnCancelled { get; set; }
|
|
||||||
|
|
||||||
private ContentItem? contentItem;
|
|
||||||
private bool isLoading = true;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
isLoading = true;
|
|
||||||
contentItem = await contentEditorService.GetContentItemByIdAsync(ContentItemId);
|
|
||||||
isLoading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task HandleSave()
|
|
||||||
{
|
|
||||||
contentItem!.LastUpdated = DateTime.UtcNow;
|
|
||||||
|
|
||||||
await contentEditorService.SaveAndSyncContentItemAsync(contentItem, contentItem.ContentGroup.SiteInfo.VectorCollectionName, false);
|
|
||||||
|
|
||||||
if (OnSaved != null)
|
|
||||||
await OnSaved.Invoke(contentItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CancelEdit()
|
|
||||||
{
|
|
||||||
if (OnCancelled != null)
|
|
||||||
await OnCancelled.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task OnUpdated()
|
|
||||||
{
|
|
||||||
if (OnContentUpdated != null)
|
|
||||||
await OnContentUpdated.Invoke(contentItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
using BLAIzor.Models;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
namespace BLAIzor.Components.Partials
|
|
||||||
{
|
|
||||||
public class EditorUIComponentBase<T> : ComponentBase
|
|
||||||
{
|
|
||||||
[Parameter] public Func<T, Task> OnContentUpdated { get; set; }
|
|
||||||
[Parameter] public Func<T, Task> OnContentEditStarted { get; set; }
|
|
||||||
|
|
||||||
protected async Task NotifyContentUpdatedAsync(T updatedObject)
|
|
||||||
{
|
|
||||||
if (OnContentUpdated != null)
|
|
||||||
{
|
|
||||||
await OnContentUpdated.Invoke(updatedObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async Task NotifyContentEditStartedAsync(T updatedObject)
|
|
||||||
{
|
|
||||||
if (OnContentEditStarted != null)
|
|
||||||
{
|
|
||||||
await OnContentEditStarted.Invoke(updatedObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
@using BLAIzor.Models
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@inject ScopedContentService _scopedContentService;
|
|
||||||
@inject NavigationManager _navigationManager;
|
|
||||||
@inject ContentEditorService _contentEditorService
|
|
||||||
@inject IHttpContextAccessor HttpContextAccessor
|
|
||||||
@inject IJSRuntime JS
|
|
||||||
|
|
||||||
|
|
||||||
<div class="container-fluid footer" style="position: relative; z-index: 10000; margin-top: 100px;">
|
|
||||||
<div class="container">
|
|
||||||
<footer class="footer-inner pt-5">
|
|
||||||
<div class="row">
|
|
||||||
@{
|
|
||||||
|
|
||||||
|
|
||||||
var brandFileName = _scopedContentService.SelectedDocument;
|
|
||||||
var brandName = _scopedContentService.SelectedBrandName;
|
|
||||||
|
|
||||||
if (MenuList != null)
|
|
||||||
{
|
|
||||||
int columnCount = 3;
|
|
||||||
int itemsPerColumn = (int)Math.Ceiling(MenuList.Length / (double)columnCount);
|
|
||||||
var columns = new List<List<string>>();
|
|
||||||
|
|
||||||
for (int i = 0; i < columnCount; i++)
|
|
||||||
{
|
|
||||||
columns.Add(MenuList.Skip(i * itemsPerColumn).Take(itemsPerColumn).ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@foreach (var column in columns)
|
|
||||||
{
|
|
||||||
<div class="col-6 col-md-2 mb-3">
|
|
||||||
<h5>@brandName</h5>
|
|
||||||
<ul class="nav flex-column">
|
|
||||||
@foreach (var item in column)
|
|
||||||
{
|
|
||||||
<li class="nav-item mb-2" style="text-align: start;"><a class="nav-link p-0 text-body-secondary" @onclick="()=>MenuClickedAsync(item)">@item</a></li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
<div class="col-md-5 offset-md-1 mb-3">
|
|
||||||
<form>
|
|
||||||
<h5>Subscribe to our newsletter</h5> <p>Monthly digest of what's new and exciting from us.</p>
|
|
||||||
<div class="d-flex flex-column flex-sm-row w-100 gap-2">
|
|
||||||
<label for="newsletter1" class="visually-hidden">Email address</label>
|
|
||||||
<input id="newsletter1" type="email" class="form-control" placeholder="Email address">
|
|
||||||
<button class="btn btn-primary" type="button">Subscribe</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex flex-column flex-sm-row justify-content-between pt-4 mt-4 border-top">
|
|
||||||
|
|
||||||
<p>© 2025 <NavLink @onclick="HomeClick">@brandName</NavLink>, Inc. All rights reserved.</p>
|
|
||||||
<ul class="list-unstyled d-flex">
|
|
||||||
<li class="ms-3"><a href="#" aria-label="Instagram"><i class="fa-brands fa-square-instagram"></i></a></li>
|
|
||||||
<li class="ms-3"><a href="#" aria-label="Facebook"><i class="fa-brands fa-square-facebook"></i></a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
|
||||||
public int SiteId;
|
|
||||||
[Parameter]
|
|
||||||
public string? MenuString { get; set; }
|
|
||||||
public string[] MenuList;
|
|
||||||
public string videoUrl = "";
|
|
||||||
public string SelectedLanguage;
|
|
||||||
private int RenderCounter = 0;
|
|
||||||
|
|
||||||
[Parameter] public Action<string>? OnMenuClicked { get; set; }
|
|
||||||
|
|
||||||
public async Task MenuClickedAsync(string menuName)
|
|
||||||
{
|
|
||||||
OnMenuClicked?.Invoke(menuName);
|
|
||||||
await JS.InvokeVoidAsync("collapseNavbar");
|
|
||||||
}
|
|
||||||
public void HomeClick()
|
|
||||||
{
|
|
||||||
_navigationManager.Refresh(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
var lang = await JS.InvokeAsync<string>("getUserLanguage");
|
|
||||||
|
|
||||||
// Normalize and match to one of your supported languages
|
|
||||||
if (lang.StartsWith("hu", StringComparison.OrdinalIgnoreCase))
|
|
||||||
SelectedLanguage = "Hungarian";
|
|
||||||
else if (lang.StartsWith("de", StringComparison.OrdinalIgnoreCase))
|
|
||||||
SelectedLanguage = "German";
|
|
||||||
else
|
|
||||||
SelectedLanguage = "English";
|
|
||||||
|
|
||||||
_scopedContentService.SelectedLanguage = SelectedLanguage;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(MenuString))
|
|
||||||
{
|
|
||||||
MenuList = MenuString.Split(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
await base.OnParametersSetAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnLanguageSelected(ChangeEventArgs e)
|
|
||||||
{
|
|
||||||
SelectedLanguage = e.Value?.ToString();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(SelectedLanguage))
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Language selected: {SelectedLanguage}");
|
|
||||||
_scopedContentService.SelectedLanguage = SelectedLanguage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
@using Newtonsoft.Json
|
@using Newtonsoft.Json
|
||||||
@using System.Collections.ObjectModel
|
@using System.Collections.ObjectModel
|
||||||
@inject ContentEditorService ContentEditorService
|
@inject ContentEditorService ContentEditorService
|
||||||
@inject ContentEditorAIService ContentEditorAIService
|
|
||||||
@inject HtmlSnippetProcessor HtmlSnippetProcessor
|
@inject HtmlSnippetProcessor HtmlSnippetProcessor
|
||||||
@inject QDrantService QDrantService
|
@inject QDrantService QDrantService
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
|
|
@ -61,7 +60,7 @@ else if (ExtractedMenuItems.Any())
|
||||||
<MenuItemContentEditor Subject=@subject MenuItem="item" WordFile=@document SessionId="SessionId" OnContentUpdated="UpdateMenuItem" />
|
<MenuItemContentEditor Subject=@subject MenuItem="item" WordFile=@document SessionId="SessionId" OnContentUpdated="UpdateMenuItem" />
|
||||||
}
|
}
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
|
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
|
||||||
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +101,7 @@ else if (ExtractedMenuItems.Any())
|
||||||
|
|
||||||
</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>
|
<button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrEmpty(ErrorMessage))
|
else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
|
|
@ -154,23 +153,17 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
foreach (var menuItem in menuItems)
|
foreach (var menuItem in menuItems)
|
||||||
{
|
{
|
||||||
|
|
||||||
List<WebPageContent> content;
|
string content;
|
||||||
MenuItemModel model = new MenuItemModel("");
|
MenuItemModel model = new MenuItemModel("");
|
||||||
//try to get content from qDrant
|
//try to get content from qDrant
|
||||||
if (menuItem.ContentGroupId != null && menuItem.ContentItemId != null) ////FIXXXXXXX
|
if (menuItem.QdrantPointId != null)
|
||||||
{
|
{
|
||||||
ContentItem contentItem = await ContentEditorService.GetContentItemByIdAsync((int)menuItem.ContentItemId);
|
content = await QDrantService.GetContentAsync(SiteId, menuItem.PointId);
|
||||||
|
var selectedPoint = JsonConvert.DeserializeObject<QDrantGetContentPointResult>(content)!;
|
||||||
/* content = await QDrantService.GetPointFromQdrantAsyncByPointId(SiteId, contentItem.Chunks); */ //FIXXXXXXX WONT WORKNOW
|
if (selectedPoint != null)
|
||||||
//var selectedPoint = JsonConvert.DeserializeObject<QDrantGetContentPointResult>(content)!;
|
|
||||||
if (contentItem != null)
|
|
||||||
{
|
{
|
||||||
foreach (var vector in contentItem.Chunks)
|
model.Content = selectedPoint.result.payload.content;
|
||||||
{
|
Console.Write($"Found point: {selectedPoint.result.payload.content}");
|
||||||
//get vectors to compare
|
|
||||||
}
|
|
||||||
model.Content = contentItem.Content;
|
|
||||||
model.ContentDescription = contentItem.Description;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -207,18 +200,15 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
|
|
||||||
//get website subject
|
//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 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);
|
var response1 = await ContentEditorService.GetGeneratedContentAsync(SessionId, prompt1);
|
||||||
Console.Write(response1);
|
Console.Write(response1);
|
||||||
subject = response1;
|
subject = response1;
|
||||||
|
|
||||||
if (!MenuItemsSaved)
|
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 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 response2 = await ContentEditorService.GetMenuSuggestionsAsync(SessionId, prompt2);
|
||||||
var valami = response2.Split('\n', StringSplitOptions.RemoveEmptyEntries)
|
ExtractedMenuItems = response2.Select(name => new MenuItemModel(name)).ToList();
|
||||||
.Select(line => line.Trim('-').Trim())
|
|
||||||
.ToList() ?? new List<string>();
|
|
||||||
ExtractedMenuItems = valami.Select(name => new MenuItemModel(name)).ToList();
|
|
||||||
}
|
}
|
||||||
// Send the content to ChatGPT
|
// Send the content to ChatGPT
|
||||||
}
|
}
|
||||||
|
|
@ -256,7 +246,6 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
//item.MenuItem.
|
//item.MenuItem.
|
||||||
item.MenuItem.Name = updatedItem.MenuItem.Name;
|
|
||||||
item.Content = updatedItem.Content;
|
item.Content = updatedItem.Content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -264,7 +253,7 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
private async Task SaveMenuItems(bool updateVectorDatabase)
|
private async Task SaveMenuItems(bool updateVectorDatabase)
|
||||||
{
|
{
|
||||||
//bool valami = updateVectorDatabase;
|
//bool valami = updateVectorDatabase;
|
||||||
var result = await ContentEditorAIService.ProcessMenuItems(SiteId, hasCollection, ExtractedMenuItems, subject, MenuItemsSaved, updateVectorDatabase);
|
var result = await ContentEditorService.ProcessMenuItems(SiteId, hasCollection, ExtractedMenuItems, subject, MenuItemsSaved, updateVectorDatabase);
|
||||||
if (result == "OK")
|
if (result == "OK")
|
||||||
{
|
{
|
||||||
MenuItemsSaved = true;
|
MenuItemsSaved = true;
|
||||||
|
|
@ -298,12 +287,10 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
foreach (var menuItemToReorder in menuItems)
|
foreach (var menuItemToReorder in menuItems)
|
||||||
{
|
{
|
||||||
menuItemToReorder.SortOrder = menuItems.IndexOf(menuItemToReorder);
|
menuItemToReorder.SortOrder = menuItems.IndexOf(menuItemToReorder);
|
||||||
Console.WriteLine($"{menuItemToReorder.Name}, {menuItemToReorder.SortOrder}");
|
|
||||||
}
|
}
|
||||||
foreach (var extractedMenuItemToReorder in ExtractedMenuItems)
|
foreach (var extractedMenuItemToReorder in ExtractedMenuItems)
|
||||||
{
|
{
|
||||||
extractedMenuItemToReorder.MenuItem.SortOrder = ExtractedMenuItems.IndexOf(extractedMenuItemToReorder);
|
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')");
|
JSRuntime.InvokeVoidAsync("eval", $"document.querySelector('.my-class').classList.remove('my-class')");
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
@using BLAIzor.Components.Partials
|
@using BLAIzor.Components.Partials
|
||||||
@using System.Collections.ObjectModel
|
@using System.Collections.ObjectModel
|
||||||
@inject ContentEditorService ContentEditorService
|
@inject ContentEditorService ContentEditorService
|
||||||
@inject ContentEditorAIService ContentEditorAIService
|
|
||||||
@inject HtmlSnippetProcessor HtmlSnippetProcessor
|
@inject HtmlSnippetProcessor HtmlSnippetProcessor
|
||||||
@inject QDrantService QDrantService
|
@inject QDrantService QDrantService
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
|
|
@ -63,7 +62,7 @@ else if (extractedMenuItems.Any())
|
||||||
<MenuItemContentEditor Subject=@subject MenuItem="item" OnContentUpdated="UpdateMenuItem" SessionId="SessionId" />
|
<MenuItemContentEditor Subject=@subject MenuItem="item" OnContentUpdated="UpdateMenuItem" SessionId="SessionId" />
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
||||||
|
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +77,7 @@ else if (extractedMenuItems.Any())
|
||||||
</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>
|
<button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
|
||||||
}
|
}
|
||||||
|
|
@ -123,27 +122,23 @@ else if (!string.IsNullOrEmpty(errorMessage))
|
||||||
foreach (var menuItem in menuItems)
|
foreach (var menuItem in menuItems)
|
||||||
{
|
{
|
||||||
|
|
||||||
List<WebPageContent> content;
|
string content;
|
||||||
MenuItemModel model = new MenuItemModel("");
|
MenuItemModel model = new MenuItemModel("");
|
||||||
//try to get content from qDrant
|
//try to get content from qDrant
|
||||||
if (menuItem.ContentGroupId != null && menuItem.ContentItemId != null) ////FIXXXXXXX
|
if (menuItem.QdrantPointId != null)
|
||||||
{
|
{
|
||||||
ContentItem contentItem = await ContentEditorService.GetContentItemByIdAsync((int)menuItem.ContentItemId);
|
content = await QDrantService.GetContentAsync(SiteId, menuItem.PointId);
|
||||||
|
// content = await QDrantService.GetContentAsync(SiteId, menuItem.QdrantPointId); TODO
|
||||||
/* content = await QDrantService.GetPointFromQdrantAsyncByPointId(SiteId, contentItem.Chunks); */
|
var selectedPoint = JsonConvert.DeserializeObject<QDrantGetContentPointResult>(content)!;
|
||||||
//var selectedPoint = JsonConvert.DeserializeObject<QDrantGetContentPointResult>(content)!;
|
if (selectedPoint != null)
|
||||||
if (contentItem != null)
|
|
||||||
{
|
{
|
||||||
foreach (var vector in contentItem.Chunks)
|
model.Content = selectedPoint.result.payload.content;
|
||||||
{
|
Console.Write($"Found point: {selectedPoint.result.payload.content}");
|
||||||
//get vectors to compare
|
|
||||||
}
|
|
||||||
model.Content = contentItem.Content;
|
|
||||||
model.ContentDescription = contentItem.Description;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
model.MenuItem = menuItem;
|
model.MenuItem = menuItem;
|
||||||
|
|
||||||
extractedMenuItems.Add(model);
|
extractedMenuItems.Add(model);
|
||||||
// UpdateMenuItem(model);
|
// UpdateMenuItem(model);
|
||||||
}
|
}
|
||||||
|
|
@ -166,11 +161,8 @@ else if (!string.IsNullOrEmpty(errorMessage))
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var prompt = $"Suggest a list of menu items for a website about: {subject}. Please do not attach any explanation.";
|
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 response = await ContentEditorService.GetMenuSuggestionsAsync(SessionId, prompt);
|
||||||
var valami = response.Split('\n', StringSplitOptions.RemoveEmptyEntries)
|
extractedMenuItems = response.Select(name => new MenuItemModel(name)).ToList();
|
||||||
.Select(line => line.Trim('-').Trim())
|
|
||||||
.ToList() ?? new List<string>();
|
|
||||||
extractedMenuItems = valami.Select(name => new MenuItemModel(name)).ToList();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -190,7 +182,6 @@ else if (!string.IsNullOrEmpty(errorMessage))
|
||||||
var newItem = new MenuItemModel("New menu item", "");
|
var newItem = new MenuItemModel("New menu item", "");
|
||||||
//TODO Fix
|
//TODO Fix
|
||||||
extractedMenuItems.Add(newItem);
|
extractedMenuItems.Add(newItem);
|
||||||
isLoading = false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,7 +206,7 @@ else if (!string.IsNullOrEmpty(errorMessage))
|
||||||
|
|
||||||
private async Task SaveMenuItems(bool updateVectorDatabase)
|
private async Task SaveMenuItems(bool updateVectorDatabase)
|
||||||
{
|
{
|
||||||
var result = await ContentEditorAIService.ProcessMenuItems(SiteId, hasCollection, extractedMenuItems, subject, MenuItemsSaved, updateVectorDatabase);
|
var result = await ContentEditorService.ProcessMenuItems(SiteId, hasCollection, extractedMenuItems, subject, MenuItemsSaved, updateVectorDatabase);
|
||||||
if (result == "OK")
|
if (result == "OK")
|
||||||
{
|
{
|
||||||
MenuItemsSaved = true;
|
MenuItemsSaved = true;
|
||||||
|
|
|
||||||
|
|
@ -1,195 +0,0 @@
|
||||||
@* @page "/site/{SiteId:int}/generate" *@
|
|
||||||
@using BLAIzor.Models
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@inject HttpClient Http
|
|
||||||
@inject ContentEditorAIService contentEditorAIService
|
|
||||||
@inject ContentEditorService contentEditorService
|
|
||||||
@inject NavigationManager Navigation
|
|
||||||
|
|
||||||
<div class="container-fluid">
|
|
||||||
|
|
||||||
@if (!string.IsNullOrEmpty(errorMessage))
|
|
||||||
{
|
|
||||||
<p class="text-red-600">Error: @errorMessage</p>
|
|
||||||
}
|
|
||||||
else if (isLoading || GeneratedItems.Any())
|
|
||||||
{
|
|
||||||
|
|
||||||
<RadzenLayout Style="grid-template-areas: 'rz-sidebar rz-header' 'rz-sidebar rz-body'">
|
|
||||||
<RadzenHeader>
|
|
||||||
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0">
|
|
||||||
<RadzenSidebarToggle Click="@(() => sidebarExpanded = !sidebarExpanded)" />
|
|
||||||
<RadzenLabel Text=@(totalItemsToGenerate.ToString() + " page(s)") />
|
|
||||||
</RadzenStack>
|
|
||||||
</RadzenHeader>
|
|
||||||
<RadzenSidebar @bind-Expanded="@sidebarExpanded">
|
|
||||||
<RadzenPanelMenu>
|
|
||||||
@foreach (var item in GeneratedItems)
|
|
||||||
{
|
|
||||||
<RadzenPanelMenuItem Text="@item.Title" Icon="account_box" Click="@(() => SelectContent(item.Title))" />
|
|
||||||
}
|
|
||||||
|
|
||||||
</RadzenPanelMenu>
|
|
||||||
<button class="btn btn-primary mt-4" @onclick="SaveContent">Save All</button>
|
|
||||||
</RadzenSidebar>
|
|
||||||
<RadzenBody Style="padding: 0px !important">
|
|
||||||
@if (isLoading)
|
|
||||||
{
|
|
||||||
<p class="text-muted">Generating... please wait.</p>
|
|
||||||
//progress bar
|
|
||||||
<RadzenProgressBar Value="@generationProgress" ShowValue="true" Style="width: 100%;" />
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (SelectedItem != null)
|
|
||||||
{
|
|
||||||
<textarea class="w-100 p-2 rounded text-white bg-panel-gradient" style="min-height:500px" @bind="SelectedItem.Content"></textarea>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</RadzenBody>
|
|
||||||
</RadzenLayout>
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<button class="btn btn-success" @onclick="GeneratePageList">Start Generation</button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter]
|
|
||||||
public int SiteId { get; set; }
|
|
||||||
[Parameter] public string SessionId { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
private SiteInfo site;
|
|
||||||
private bool isLoading = false;
|
|
||||||
private string errorMessage = string.Empty;
|
|
||||||
private List<ContentItem> GeneratedItems = new();
|
|
||||||
private ContentGroup defaultGroup;
|
|
||||||
private ContentItem SelectedItem;
|
|
||||||
|
|
||||||
private double generationProgress = 0.0;
|
|
||||||
private int totalItemsToGenerate = 0;
|
|
||||||
|
|
||||||
|
|
||||||
bool sidebarExpanded = true;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
site = await contentEditorService.GetSiteInfoByIdAsync(SiteId);
|
|
||||||
var existingGroup = await contentEditorService.GetContentGroupsBySiteInfoIdAsync(SiteId);
|
|
||||||
if (!existingGroup.Any(x => x.Name == "Pages"))
|
|
||||||
{
|
|
||||||
defaultGroup = new ContentGroup
|
|
||||||
{
|
|
||||||
SiteInfoId = SiteId,
|
|
||||||
Name = "Pages",
|
|
||||||
Slug = "pages",
|
|
||||||
Type = "Page",
|
|
||||||
VectorSize = 1536,
|
|
||||||
EmbeddingModel = "openai",
|
|
||||||
Version = 0
|
|
||||||
};
|
|
||||||
// Save ContentGroup to DB (if not already exists)
|
|
||||||
var response = await contentEditorService.CreateContentGroupAsync(defaultGroup);
|
|
||||||
defaultGroup = response;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
defaultGroup = existingGroup.FirstOrDefault(x => x.Name == "Pages");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SelectContent(string title)
|
|
||||||
{
|
|
||||||
SelectedItem = GeneratedItems.Where(x => x.Title == title).FirstOrDefault();
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task GeneratePageList()
|
|
||||||
{
|
|
||||||
isLoading = true;
|
|
||||||
errorMessage = string.Empty;
|
|
||||||
GeneratedItems.Clear();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var pageListPrompt = $"Based on the following site description, list the main website pages in {site.DefaultLanguage} as a comma-separated list. " +
|
|
||||||
"Only return the page titles." +
|
|
||||||
$"Site Description: {site.SiteDescription}";
|
|
||||||
|
|
||||||
var pageListText = await contentEditorAIService.GetMenuSuggestionsAsync(SessionId, pageListPrompt);
|
|
||||||
|
|
||||||
var pageTitles = pageListText
|
|
||||||
.Split(',', StringSplitOptions.RemoveEmptyEntries)
|
|
||||||
.Select(t => t.Trim())
|
|
||||||
.Where(t => !string.IsNullOrWhiteSpace(t))
|
|
||||||
.Distinct()
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
totalItemsToGenerate = pageTitles.Count;
|
|
||||||
|
|
||||||
foreach (var title in pageTitles)
|
|
||||||
{
|
|
||||||
var itemPrompt = $"Write a full, well-structured website page text content in {site.DefaultLanguage} for a page titled {title}. " +
|
|
||||||
$"The tone should be {site.Persona}, and match the following site description: '{site.SiteDescription}' " +
|
|
||||||
"Include headers, clear sections, and persuasive copy.";
|
|
||||||
|
|
||||||
var content = await contentEditorAIService.GetGeneratedContentAsync(SessionId, itemPrompt);
|
|
||||||
|
|
||||||
GeneratedItems.Add(new ContentItem
|
|
||||||
{
|
|
||||||
Title = title,
|
|
||||||
Description = $"A {defaultGroup.Type} called {title} of a website called {site.SiteName}.",
|
|
||||||
Language = site.DefaultLanguage,
|
|
||||||
Content = content,
|
|
||||||
ContentGroupId = defaultGroup.Id,
|
|
||||||
Tags = title,
|
|
||||||
IsPublished = false,
|
|
||||||
Version = 0
|
|
||||||
});
|
|
||||||
generationProgress += 100.0 / totalItemsToGenerate;
|
|
||||||
// Refresh UI after each item is generated
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
errorMessage = ex.Message;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
SelectedItem = GeneratedItems.FirstOrDefault();
|
|
||||||
isLoading = false;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task SaveContent()
|
|
||||||
{
|
|
||||||
isLoading = true;
|
|
||||||
errorMessage = string.Empty;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (var item in GeneratedItems)
|
|
||||||
{
|
|
||||||
//await Http.PostAsJsonAsync("/api/contentitem", item);
|
|
||||||
await contentEditorService.CreateContentItemAsync(item, site.VectorCollectionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
Navigation.NavigateTo($"/site/{SiteId}/overview");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
errorMessage = ex.Message;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
isLoading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,511 +0,0 @@
|
||||||
@page "/site/{SiteId:int}/generate"
|
|
||||||
@using BLAIzor.Interfaces
|
|
||||||
@using BLAIzor.Models
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@using System.Text.RegularExpressions
|
|
||||||
@using SixLabors.ImageSharp
|
|
||||||
@using SixLabors.ImageSharp.Processing
|
|
||||||
@inject HttpClient Http
|
|
||||||
@inject ContentEditorAIService contentEditorAIService
|
|
||||||
@inject ContentEditorService contentEditorService
|
|
||||||
@inject NavigationManager Navigation
|
|
||||||
@inject ReplicateService ReplicateService
|
|
||||||
@inject IHttpClientFactory HttpClientFactory
|
|
||||||
@inject IBrightDataService BrightDataService
|
|
||||||
|
|
||||||
|
|
||||||
<div class="container-fluid flex">
|
|
||||||
<!-- Sidebar -->
|
|
||||||
@if (GeneratedItems.Any())
|
|
||||||
{
|
|
||||||
<aside class="w-64 border-r p-4 flex flex-col">
|
|
||||||
<div class="text-lg font-semibold mb-4">Pages (@totalItemsToGenerate)</div>
|
|
||||||
|
|
||||||
<nav class="flex-1 overflow-auto space-y-2">
|
|
||||||
@foreach (var item in GeneratedItems)
|
|
||||||
{
|
|
||||||
<button class="btn @(item == SelectedItem ? "btn-primary font-semibold" : "bg-panel-gradient")"
|
|
||||||
@onclick="@(() => SelectContent(item.Title))">
|
|
||||||
@item.Title
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</nav>
|
|
||||||
@if (isLoading || isGeneratingImages)
|
|
||||||
{
|
|
||||||
<button disabled class="btn py-2 px-4 rounded"
|
|
||||||
@onclick="SaveContent">
|
|
||||||
💾 Please wait...
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<button class="btn py-2 px-4 rounded"
|
|
||||||
@onclick="SaveContent">
|
|
||||||
💾 Save All
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</aside>
|
|
||||||
}
|
|
||||||
|
|
||||||
<!-- Main Content -->
|
|
||||||
<div class="row">
|
|
||||||
@if (!string.IsNullOrEmpty(errorMessage))
|
|
||||||
{
|
|
||||||
<div class="text-red-600 font-medium mb-4">⚠️ @errorMessage</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (isLoading)
|
|
||||||
{
|
|
||||||
<div class="text-gray-700 mb-4" style="width:fit-content !important; margin: 0 auto !important">
|
|
||||||
@if (!string.IsNullOrEmpty(message))
|
|
||||||
{
|
|
||||||
<p>@message</p>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (GeneratedItems.Any())
|
|
||||||
{
|
|
||||||
<RadzenProgressBarCircular Style="margin: 0 auto !important" ProgressBarStyle="ProgressBarStyle.Primary" Value="@(Math.Round(generationProgress, 0))" ShowValue="true" Size="ProgressBarCircularSize.Large" />
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<RadzenProgressBarCircular Style="margin: 0 auto !important" ProgressBarStyle="ProgressBarStyle.Light" Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate" Size="ProgressBarCircularSize.Large" />
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
@* <RadzenProgressBar Value="@generationProgress" ShowValue="true" Style="width: 100%;" /> *@
|
|
||||||
}
|
|
||||||
else if (SelectedItem != null)
|
|
||||||
{
|
|
||||||
|
|
||||||
@if (isGeneratingImages)
|
|
||||||
{
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="text-gray-700 mb-4" style="width:fit-content !important; margin: 0 auto !important">
|
|
||||||
<p>Generating pages... please wait.</p>
|
|
||||||
|
|
||||||
@* <RadzenProgressBarCircular Style="margin: 0 auto !important" ProgressBarStyle="ProgressBarStyle.Success" Value="@(Math.Round(generationProgress, 0))" ShowValue="true" Size="ProgressBarCircularSize.Large" /> *@
|
|
||||||
<RadzenProgressBar Value="@(Math.Round(generationProgress, 0))" ShowValue="true" Style="width: 100%;" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<div class="col-12">
|
|
||||||
<p>
|
|
||||||
Please review the generated content and the images. You are free to modify the text, but please don't remove photo tags, they are handled automatically.
|
|
||||||
Please approve the images you like. You can also regenerate, and select photos from your device.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Content editor -->
|
|
||||||
<div class="col-sm-12 col-md-7">
|
|
||||||
<h2 class="text-xl font-bold mb-2">@SelectedItem.Title</h2>
|
|
||||||
|
|
||||||
<textarea class="p-4 rounded text-white bg-panel-gradient" style="height:500px; width: 100%; border: 0px;"
|
|
||||||
@bind="SelectedItem.Content"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Photo slots -->
|
|
||||||
<div class="col-sm-12 col-md-5">
|
|
||||||
<h2 class="text-xl font-bold mb-2">Suggested Photos</h2>
|
|
||||||
|
|
||||||
<div class="row" style="height: 500px; overflow: scroll">
|
|
||||||
|
|
||||||
|
|
||||||
@if (SelectedItem.PhotoSlots.Any())
|
|
||||||
{
|
|
||||||
@foreach (var slot in SelectedItem.PhotoSlots)
|
|
||||||
{
|
|
||||||
<div class="col-6 rounded p-1">
|
|
||||||
<div class="bg-panel-gradient text-white m-1">
|
|
||||||
@* <p class="text-sm mb-2">@slot.Description</p> *@
|
|
||||||
@if (!string.IsNullOrEmpty(slot.ImageUrl))
|
|
||||||
{
|
|
||||||
<div style="width: 100%; position: relative;">
|
|
||||||
<p>Photo_slot_@(SelectedItem.PhotoSlots.IndexOf(slot) + 1)</p>
|
|
||||||
<div style="position: absolute; height: 100px; top: 0px; right: 0px;">
|
|
||||||
<button class="btn btn-sm btn-primary flex-1"
|
|
||||||
@onclick="() => ReplaceUrls(slot)">
|
|
||||||
✓ Approve
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<img src="@slot.ImageUrl" alt="@slot.Description" class="img-fluid" />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<div style="width: 100%; height: 270px;">
|
|
||||||
<RadzenProgressBarCircular Style="width:100%; margin: 0 auto;" ProgressBarStyle="ProgressBarStyle.Light" ShowValue="true" Mode="ProgressBarMode.Indeterminate" Size="ProgressBarCircularSize.Large">
|
|
||||||
<Template>Wait</Template>
|
|
||||||
</RadzenProgressBarCircular>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<div class="flex gap-2">
|
|
||||||
|
|
||||||
<button class="btn btn-primary flex-1"
|
|
||||||
@onclick="() => RegeneratePhoto(slot, false)">
|
|
||||||
🎨 Regenerate
|
|
||||||
</button>
|
|
||||||
<button class="btn flex-1"
|
|
||||||
@onclick="() => SelectPhoto(slot)">
|
|
||||||
📂 Select
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<p class="text-gray-400 text-sm">No photo suggestions yet.</p>
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (!GeneratedItems.Any())
|
|
||||||
{
|
|
||||||
<div class="flex flex-col items-center justify-center h-full text-center text-gray-500">
|
|
||||||
<p class="mb-4">Click the button below to generate your site's pages based on its description.</p>
|
|
||||||
<button class="btn text-white py-2 px-6 rounded"
|
|
||||||
@onclick="GeneratePageList">
|
|
||||||
🚀 Start Generation
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public int SiteId { get; set; }
|
|
||||||
[Parameter] public string SessionId { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
private SiteInfo site;
|
|
||||||
private bool isLoading = false;
|
|
||||||
private string errorMessage = string.Empty;
|
|
||||||
private string message = "Generating pages... please wait.";
|
|
||||||
private List<GeneratedContentItem> GeneratedItems = new();
|
|
||||||
private ContentGroup defaultGroup;
|
|
||||||
private GeneratedContentItem SelectedItem;
|
|
||||||
|
|
||||||
private double generationProgress = 0.0;
|
|
||||||
private int totalItemsToGenerate = 0;
|
|
||||||
private bool isGeneratingImages = false;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
site = await contentEditorService.GetSiteInfoByIdAsync(SiteId);
|
|
||||||
var existingGroup = await contentEditorService.GetContentGroupsBySiteInfoIdAsync(SiteId);
|
|
||||||
|
|
||||||
if (!existingGroup.Any(x => x.Name == "Pages"))
|
|
||||||
{
|
|
||||||
defaultGroup = new ContentGroup
|
|
||||||
{
|
|
||||||
SiteInfoId = SiteId,
|
|
||||||
Name = "Pages",
|
|
||||||
Slug = "pages",
|
|
||||||
Type = "Page",
|
|
||||||
VectorSize = 1536,
|
|
||||||
EmbeddingModel = "openai",
|
|
||||||
Version = 0
|
|
||||||
};
|
|
||||||
defaultGroup = await contentEditorService.CreateContentGroupAsync(defaultGroup);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
defaultGroup = existingGroup.First(x => x.Name == "Pages");
|
|
||||||
var content = await contentEditorService.GetContentItemsByGroupIdAsync(defaultGroup.Id);
|
|
||||||
GeneratedItems = content.Select(c => new GeneratedContentItem
|
|
||||||
{
|
|
||||||
Id = c.Id,
|
|
||||||
Title = c.Title,
|
|
||||||
Description = c.Description,
|
|
||||||
Language = c.Language,
|
|
||||||
Content = c.Content,
|
|
||||||
ContentGroupId = c.ContentGroupId,
|
|
||||||
Tags = c.Tags,
|
|
||||||
IsPublished = c.IsPublished,
|
|
||||||
Version = c.Version
|
|
||||||
}).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SelectContent(string title)
|
|
||||||
{
|
|
||||||
SelectedItem = GeneratedItems.FirstOrDefault(x => x.Title == title);
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task GeneratePageList()
|
|
||||||
{
|
|
||||||
isLoading = true;
|
|
||||||
errorMessage = string.Empty;
|
|
||||||
GeneratedItems.Clear();
|
|
||||||
string facebookContent = string.Empty;
|
|
||||||
if (!string.IsNullOrWhiteSpace(site.FacebookUrl))
|
|
||||||
{
|
|
||||||
message = "Reading Facebook posts... please wait.";
|
|
||||||
var valami = await BrightDataService.ScrapeFacebookPostsAsync(site.FacebookUrl, 20);
|
|
||||||
if (valami == null || !valami.Any())
|
|
||||||
{
|
|
||||||
errorMessage = "No Facebook posts found. Please check the URL.";
|
|
||||||
isLoading = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var grabFacebookPrompt = $"Based on the following Facebook posts, extract the main topics and themes that could be used to generate website pages. " +
|
|
||||||
$"Focus on the content relevant to the site description: {site.SiteDescription}. " +
|
|
||||||
$"Content found on Facebook in JSON format: {valami}";
|
|
||||||
|
|
||||||
facebookContent = await contentEditorAIService.GetFacebookContentAsync(SessionId, grabFacebookPrompt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
message = "Generating pages... please wait.";
|
|
||||||
// 1️⃣ Ask AI for the page titles first
|
|
||||||
var pageListPrompt = $"Based on the following site description, list the main website pages in {site.DefaultLanguage} as a comma-separated list. " +
|
|
||||||
"Only return the page titles." +
|
|
||||||
$"Site Description: {site.SiteDescription}." +
|
|
||||||
$"Content found on facebook: {facebookContent}";
|
|
||||||
|
|
||||||
var pageListText = await contentEditorAIService.GetMenuSuggestionsAsync(SessionId, pageListPrompt);
|
|
||||||
|
|
||||||
var pageTitles = pageListText
|
|
||||||
.Split(',', StringSplitOptions.RemoveEmptyEntries)
|
|
||||||
.Select(t => t.Trim())
|
|
||||||
.Where(t => !string.IsNullOrWhiteSpace(t))
|
|
||||||
.Distinct()
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
totalItemsToGenerate = pageTitles.Count;
|
|
||||||
|
|
||||||
foreach (var title in pageTitles)
|
|
||||||
{
|
|
||||||
message = $"Generating content for page: {title}... please wait.";
|
|
||||||
// 2️⃣ Generate content WITH inline photo placeholders
|
|
||||||
var itemPrompt =
|
|
||||||
$"Write a full, well-structured website page text content in {site.DefaultLanguage} for a page titled '{title}'. " +
|
|
||||||
$"The tone should be {site.Persona}, and match the following site description: '{site.SiteDescription}'. " +
|
|
||||||
"Include headers, clear sections, and persuasive copy. " +
|
|
||||||
"Insert image placeholders in the text like [PHOTO_SLOT_1: short image description] at natural points where an illustration would be helpful. " +
|
|
||||||
"Number them sequentially starting from 1.";
|
|
||||||
|
|
||||||
var content = await contentEditorAIService.GetGeneratedContentAsync(SessionId, itemPrompt);
|
|
||||||
|
|
||||||
// 3️⃣ Extract PhotoSlots from placeholders
|
|
||||||
var matches = Regex.Matches(content, @"\[PHOTO_SLOT_(\d+):\s*(.+?)\]");
|
|
||||||
var photoSlots = matches
|
|
||||||
.Select(m => new PhotoSlot { Description = m.Groups[2].Value.Trim() })
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
// 4️⃣ Build GeneratedContentItem
|
|
||||||
var generatedItem = new GeneratedContentItem
|
|
||||||
{
|
|
||||||
Title = title,
|
|
||||||
Description = $"A {defaultGroup.Type} called {title} of a website called {site.SiteName}.",
|
|
||||||
Language = site.DefaultLanguage,
|
|
||||||
Content = content,
|
|
||||||
ContentGroupId = defaultGroup.Id,
|
|
||||||
Tags = title,
|
|
||||||
IsPublished = false,
|
|
||||||
Version = 0,
|
|
||||||
PhotoSlots = photoSlots
|
|
||||||
};
|
|
||||||
|
|
||||||
GeneratedItems.Add(generatedItem);
|
|
||||||
|
|
||||||
generationProgress += 100.0 / totalItemsToGenerate;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
errorMessage = ex.Message;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
message = "Generating images... please wait.";
|
|
||||||
SelectedItem = GeneratedItems.FirstOrDefault();
|
|
||||||
isLoading = false;
|
|
||||||
generationProgress = 0;
|
|
||||||
isGeneratingImages = true;
|
|
||||||
StateHasChanged();
|
|
||||||
foreach (var page in GeneratedItems)
|
|
||||||
{
|
|
||||||
totalItemsToGenerate += page.PhotoSlots.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var page in GeneratedItems)
|
|
||||||
{
|
|
||||||
|
|
||||||
foreach (var image in page.PhotoSlots)
|
|
||||||
{
|
|
||||||
await GeneratePhoto(image, false);
|
|
||||||
generationProgress += 100.0 / totalItemsToGenerate;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isGeneratingImages = false;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveContent()
|
|
||||||
{
|
|
||||||
isLoading = true;
|
|
||||||
errorMessage = string.Empty;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
foreach (var item in GeneratedItems)
|
|
||||||
{
|
|
||||||
|
|
||||||
//get all photo urls from content and replace them with uploaded version
|
|
||||||
|
|
||||||
// if (!string.IsNullOrWhiteSpace(GeneratedLogoUrl) && GeneratedLogoUrl.StartsWith("http"))
|
|
||||||
// {
|
|
||||||
// var savedPath = await DownloadAndSaveImage(GeneratedLogoUrl);
|
|
||||||
// if (!string.IsNullOrEmpty(savedPath))
|
|
||||||
// {
|
|
||||||
// logoUrl = savedPath;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
item.Content = Regex.Replace(SelectedItem.Content, @"\[PHOTO_SLOT_\d+:[^\]]*\]", "");
|
|
||||||
var contentItem = await contentEditorService.CreateContentItemAsync(item, site.VectorCollectionName);
|
|
||||||
var newMenuItem = new MenuItem
|
|
||||||
{
|
|
||||||
SiteInfoId = SiteId,
|
|
||||||
ContentItemId = contentItem.Id,
|
|
||||||
ContentGroupId = defaultGroup.Id,
|
|
||||||
ShowInMainMenu = true,
|
|
||||||
Slug = contentItem.Title.ToLower(),
|
|
||||||
SortOrder = i,
|
|
||||||
Name = contentItem.Title
|
|
||||||
};
|
|
||||||
await contentEditorService.AddMenuItemAsync(newMenuItem);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Navigation.NavigateTo($"/preview/{SiteId}");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
errorMessage = ex.Message;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
isLoading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private async Task RegeneratePhoto(PhotoSlot slot, bool removeBackground)
|
|
||||||
{
|
|
||||||
slot.ImageUrl = "";
|
|
||||||
StateHasChanged();
|
|
||||||
await GeneratePhoto(slot, removeBackground);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task GeneratePhoto(PhotoSlot slot, bool removeBackground)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (SelectedItem == null)
|
|
||||||
{
|
|
||||||
errorMessage = "No content item selected.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var userPrompt =
|
|
||||||
$"Generate an image prompt for me for AN ILLUSTRATION. Use the colors: {site.DefaultColor}. " +
|
|
||||||
$"The photo should have a {site.Persona} feel, and must be in {site.DesignStyle} style " +
|
|
||||||
$"My general photo idea: {slot.Description}. " +
|
|
||||||
"DO NOT generate a UI design or UX design prompt, the image will be part of the website content.";
|
|
||||||
|
|
||||||
var imagePrompt = await contentEditorAIService.GetPhotoPromptAsync(SessionId, userPrompt);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var imageUrl = await ReplicateService.GenerateImageAsync(imagePrompt, removeBackground);
|
|
||||||
slot.ImageUrl = imageUrl;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
errorMessage = $"Image generation failed: {ex.Message}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ReplaceUrls(PhotoSlot slot)
|
|
||||||
{
|
|
||||||
// Find the index of this slot in the SelectedItem's PhotoSlots list
|
|
||||||
var slotIndex = SelectedItem.PhotoSlots.IndexOf(slot);
|
|
||||||
if (slotIndex >= 0)
|
|
||||||
{
|
|
||||||
var imageUrl = await DownloadAndSaveImage(slot.ImageUrl);
|
|
||||||
|
|
||||||
// Replace placeholder with actual image URL
|
|
||||||
SelectedItem.Content = Regex.Replace(
|
|
||||||
SelectedItem.Content,
|
|
||||||
$@"\[PHOTO_SLOT_{slotIndex + 1}:[^\]]*\]",
|
|
||||||
$"[Photo URL: {imageUrl}]"
|
|
||||||
);
|
|
||||||
slot.ImageUrl = imageUrl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task<string?> DownloadAndSaveImage(string imageUrl)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var uploadPath = Path.Combine("wwwroot", "uploads", site.UserId, "images");
|
|
||||||
Directory.CreateDirectory(uploadPath);
|
|
||||||
|
|
||||||
var fileName = $"logo_{Guid.NewGuid().ToString().Substring(0, 8)}.jpg";
|
|
||||||
var filePath = Path.Combine(uploadPath, fileName);
|
|
||||||
|
|
||||||
var httpClient = HttpClientFactory.CreateClient();
|
|
||||||
var imageBytes = await httpClient.GetByteArrayAsync(imageUrl);
|
|
||||||
|
|
||||||
await File.WriteAllBytesAsync(filePath, imageBytes);
|
|
||||||
|
|
||||||
// Generate thumbnail
|
|
||||||
var thumbnailFolder = Path.Combine(uploadPath, "thumbnails");
|
|
||||||
Directory.CreateDirectory(thumbnailFolder);
|
|
||||||
|
|
||||||
var thumbnailPath = Path.Combine(thumbnailFolder, fileName);
|
|
||||||
using var image = Image.Load(imageBytes);
|
|
||||||
image.Mutate(x => x.Resize(new ResizeOptions
|
|
||||||
{
|
|
||||||
Size = new Size(300, 0),
|
|
||||||
Mode = ResizeMode.Max
|
|
||||||
}));
|
|
||||||
await image.SaveAsync(thumbnailPath);
|
|
||||||
|
|
||||||
return $"/uploads/{site.UserId}/images/{fileName}";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error saving logo: {ex.Message}");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SelectPhoto(PhotoSlot slot)
|
|
||||||
{
|
|
||||||
// TODO: implement image picker dialog
|
|
||||||
// For now, just simulate selecting an existing image
|
|
||||||
slot.ImageUrl = "/images/placeholder.png";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
@using Microsoft.AspNetCore.Components.Forms
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@* <InputTextArea @bind-Value="RawHtml" class="form-control" rows="10" /> *@
|
|
||||||
<RadzenHtmlEditor @bind-Value=@RawHtml style="height: 70vh; color:#000; background-color: transparent !important;" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
|
||||||
<RadzenHtmlEditorUndo />
|
|
||||||
<RadzenHtmlEditorRedo />
|
|
||||||
<RadzenHtmlEditorSource />
|
|
||||||
</RadzenHtmlEditor>
|
|
||||||
|
|
||||||
<div class="mt-3 d-flex justify-content-end gap-2">
|
|
||||||
<button class="btn btn-primary" @onclick="OnSaveClicked">Save</button>
|
|
||||||
<button class="btn btn-secondary" @onclick="OnCancelClicked">Cancel</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (ShowPreview)
|
|
||||||
{
|
|
||||||
<div class="mt-4">
|
|
||||||
<h6>Live Preview:</h6>
|
|
||||||
<div class="border p-3 bg-light" style="min-height: 100px;" @key="RawHtml">
|
|
||||||
@((MarkupString)RawHtml)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter]
|
|
||||||
public string Html { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public Func<string, Task> HtmlChanged { get; set; }
|
|
||||||
|
|
||||||
private string RawHtml = string.Empty;
|
|
||||||
private bool ShowPreview = false;
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
|
||||||
{
|
|
||||||
RawHtml = Html;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task OnSaveClicked()
|
|
||||||
{
|
|
||||||
// await HtmlChanged.InvokeAsync(RawHtml);
|
|
||||||
if (HtmlChanged != null)
|
|
||||||
await HtmlChanged.Invoke(RawHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnCancelClicked()
|
|
||||||
{
|
|
||||||
RawHtml = Html;
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task OnPaste(HtmlEditorPasteEventArgs args)
|
|
||||||
{
|
|
||||||
// console.Log($"Paste: {args.Html}");
|
|
||||||
// MenuItem.Content = args.Html;
|
|
||||||
// await OnContentUpdated.InvokeAsync(MenuItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task OnChange(string html)
|
|
||||||
{
|
|
||||||
// console.Log($"Change: {html}");
|
|
||||||
// MenuItem.Content = html;
|
|
||||||
// await OnContentUpdated.InvokeAsync(MenuItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task OnInput(string html)
|
|
||||||
{
|
|
||||||
// console.Log($"Input: {html}");
|
|
||||||
// MenuItem.Content = html;
|
|
||||||
// await OnContentUpdated.InvokeAsync(MenuItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnExecute(HtmlEditorExecuteEventArgs args)
|
|
||||||
{
|
|
||||||
//console.Log($"Execute: {args.CommandName}");
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnUploadComplete(UploadCompleteEventArgs args)
|
|
||||||
{
|
|
||||||
//console.Log($"Upload complete: {args.RawResponse}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,208 +0,0 @@
|
||||||
@using BLAIzor.Models
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@using Microsoft.AspNetCore.Components.Authorization
|
|
||||||
@inherits EditorUIComponentBase<ContentGroup>
|
|
||||||
@inject ContentEditorService contentEditorService
|
|
||||||
@inject NavigationManager navigation
|
|
||||||
@inject NotificationService notificationService
|
|
||||||
@inject DialogService dialogService
|
|
||||||
@attribute [Authorize]
|
|
||||||
|
|
||||||
@if (isLoading)
|
|
||||||
{
|
|
||||||
<p>Loading content groups...</p>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
@foreach (var group in groups)
|
|
||||||
{
|
|
||||||
if (selectedGroupId == group.Id)
|
|
||||||
{
|
|
||||||
|
|
||||||
<EditContentGroup Group="group" OnContentGroupSaveClicked="SaveGroup" OnContentGroupDeleteClicked="DeleteGroup" OnManageContentItemClicked="ContentItemManagedCallback" OnForceReChunkClicked="Rechunk"></EditContentGroup>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<div class="rounded bg-panel p-3 mb-3 d-flex justify-content-between align-items-center">
|
|
||||||
<a style="width:100%" @onclick="() => SelectGroup(group.Id)">
|
|
||||||
<div style="width:100%; cursor:pointer;">
|
|
||||||
<strong>@group.Name</strong><br />
|
|
||||||
<small class="text-muted">@group.Type</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
<button class="pointer bg-transparent border-0 p-0" style="width:100%; text-align: left;" @onclick="AddNewGroup">
|
|
||||||
<div class="mb-2 p-3 reference-button bg-panel-gradient-highlight pointer">
|
|
||||||
<div class="text-content">
|
|
||||||
<strong>Add new group</strong>
|
|
||||||
<br />
|
|
||||||
<small class="text-muted">Add a new content group like "Blog", News, "Manuals" etc...</small>
|
|
||||||
</div>
|
|
||||||
<div class="icon-buttons">
|
|
||||||
|
|
||||||
<div class="icon-circle"><i class="fa-solid fa-plus text-white"></i></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter]
|
|
||||||
public int SiteInfoId { get; set; }
|
|
||||||
[Parameter] public Func<string, int, Task> OnManageContentItemClicked { get; set; }
|
|
||||||
|
|
||||||
private List<ContentGroup> groups = new();
|
|
||||||
private bool isLoading = true;
|
|
||||||
|
|
||||||
private int? selectedGroupId = null;
|
|
||||||
|
|
||||||
private async Task SelectGroup(int groupId)
|
|
||||||
{
|
|
||||||
selectedGroupId = groupId;
|
|
||||||
var group = groups.FirstOrDefault(g => g.Id == groupId);
|
|
||||||
if (group != null)
|
|
||||||
{
|
|
||||||
await NotifyContentEditStartedAsync(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeselectGroup()
|
|
||||||
{
|
|
||||||
selectedGroupId = null;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
|
|
||||||
isLoading = true;
|
|
||||||
groups = (await contentEditorService.GetContentGroupsBySiteInfoIdAsync(SiteInfoId))
|
|
||||||
.Where(g => g.SiteInfoId == SiteInfoId)
|
|
||||||
.OrderByDescending(g => g.LastUpdated)
|
|
||||||
.ToList();
|
|
||||||
isLoading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EditGroup(ContentGroup group)
|
|
||||||
{
|
|
||||||
navigation.NavigateTo($"/content-group/{group.Id}/items");
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Rechunk(ContentGroup group)
|
|
||||||
{
|
|
||||||
var confirmationResult = await dialogService.Confirm("Are you sure?", "Rechunk group", new ConfirmOptions() { OkButtonText = "Rechunk", CancelButtonText = "Oops, no" });
|
|
||||||
if (confirmationResult == true)
|
|
||||||
{
|
|
||||||
await ReallyRechunk(group);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//do nothing?
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
private async Task ReallyRechunk(ContentGroup group)
|
|
||||||
{
|
|
||||||
group.LastUpdated = DateTime.UtcNow;
|
|
||||||
var siteInfo = await contentEditorService.GetSiteInfoByIdAsync(group.SiteInfoId);
|
|
||||||
|
|
||||||
var result = await contentEditorService.ForceRechunkContentGroupAsync(group.Id, siteInfo.VectorCollectionName);
|
|
||||||
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
await NotifyContentUpdatedAsync(group); // This triggers the base class logic
|
|
||||||
await DeselectGroup();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveGroup(ContentGroup group)
|
|
||||||
{
|
|
||||||
group.LastUpdated = DateTime.UtcNow;
|
|
||||||
group.Version = group.Version + 1;
|
|
||||||
var result = await contentEditorService.UpdateContentGroupByIdAsync(group);
|
|
||||||
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
await NotifyContentUpdatedAsync(group); // This triggers the base class logic
|
|
||||||
await DeselectGroup();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeleteGroup(ContentGroup group)
|
|
||||||
{
|
|
||||||
var confirmationResult = await dialogService.Confirm("Are you sure?", "Delete group", new ConfirmOptions() { OkButtonText = "Delete", CancelButtonText = "Oops, no" });
|
|
||||||
if (confirmationResult == true)
|
|
||||||
{
|
|
||||||
await ReallyDeleteGroup(group);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//do nothing?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ReallyDeleteGroup(ContentGroup group)
|
|
||||||
{
|
|
||||||
|
|
||||||
var result = await contentEditorService.DeleteContentGroupByIdAsync(group.Id); ;
|
|
||||||
groups.Remove(group);
|
|
||||||
var message = NotificationHelper.CreateNotificationMessage("Group deleted", 2, "Success", "ContentGroup deleted");
|
|
||||||
ShowNotification(message);
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task AddNewGroup()
|
|
||||||
{
|
|
||||||
var newGroup = new ContentGroup
|
|
||||||
{
|
|
||||||
SiteInfoId = SiteInfoId,
|
|
||||||
Name = "New Group",
|
|
||||||
Slug = $"group-{DateTime.UtcNow.Ticks}",
|
|
||||||
Type = "manual",
|
|
||||||
VectorSize = 384,
|
|
||||||
EmbeddingModel = "default",
|
|
||||||
CreatedAt = DateTime.UtcNow,
|
|
||||||
LastUpdated = DateTime.UtcNow,
|
|
||||||
Version = 1
|
|
||||||
};
|
|
||||||
var result = await contentEditorService.CreateContentGroupAsync(newGroup);
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
var message = NotificationHelper.CreateNotificationMessage("Group created", 2, "Success", "ContentGroup created");
|
|
||||||
ShowNotification(message);
|
|
||||||
groups.Insert(0, newGroup);
|
|
||||||
selectedGroupId = newGroup.Id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ContentItemManagedCallback(string method, int itemId)
|
|
||||||
{
|
|
||||||
if (OnManageContentItemClicked != null)
|
|
||||||
await OnManageContentItemClicked.Invoke(method, itemId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowNotification(NotificationMessage message)
|
|
||||||
{
|
|
||||||
notificationService.Notify(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderFragment GetMessage()
|
|
||||||
{
|
|
||||||
return __builder =>
|
|
||||||
{
|
|
||||||
<text>
|
|
||||||
Are <b>you</b> sure?
|
|
||||||
</text>
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,154 +0,0 @@
|
||||||
|
|
||||||
@attribute [Authorize]
|
|
||||||
@using BLAIzor.Components.Layout
|
|
||||||
@using BLAIzor.Models
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@using Microsoft.AspNetCore.Components.Authorization
|
|
||||||
@layout AdminLayout
|
|
||||||
@inject ContentEditorService _contentEditorService
|
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
|
||||||
@inject CustomAuthenticationStateProvider CustomAuthProvider
|
|
||||||
@inject NotificationService notificationService
|
|
||||||
@inject DialogService dialogService
|
|
||||||
|
|
||||||
|
|
||||||
<EditForm OnValidSubmit="SaveSiteInfo" EditContext="@EditContext">
|
|
||||||
<label>
|
|
||||||
Brand name
|
|
||||||
<InputText class="form-control my-3" id="siteName" @bind-Value="siteInfo.SiteName" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Site description
|
|
||||||
<InputTextArea class="form-control my-3" style="height: 100px;" id="siteDescription" @bind-Value="siteInfo.SiteDescription" rows="3"/>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Logo url
|
|
||||||
<InputText class="form-control my-3" id="brandLogoUrl" @bind-Value="siteInfo.BrandLogoUrl" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Default color (Do not bother with this)
|
|
||||||
<InputText class="form-control my-3" id="defaultColor" @bind-Value="siteInfo.DefaultColor" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
The Entity behind this website (eg. "company", "professional sportsman", "worldwide brand", etc);
|
|
||||||
<InputText class="form-control my-3" id="defaultColor" @bind-Value="siteInfo.Entity" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Your agent Persona
|
|
||||||
<InputText class="form-control my-3" id="defaultColor" @bind-Value="siteInfo.Persona" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Your domain url
|
|
||||||
<InputText class="form-control my-3" id="domainUrl" @bind-Value="siteInfo.DomainUrl" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Chosen template
|
|
||||||
<InputNumber class="form-control my-3" id="templateId" @bind-Value="siteInfo.TemplateId" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Published
|
|
||||||
<InputCheckbox class="my-3" id="ispublished" @bind-Value="siteInfo.IsPublished" />
|
|
||||||
</label>
|
|
||||||
<button class="btn btn-primary" type="submit">Save</button>
|
|
||||||
</EditForm>
|
|
||||||
<button class="btn btn-warning" type="button" @onclick="() => Rechunk(siteInfo)">ReChunk Site</button>
|
|
||||||
<hr />
|
|
||||||
<h4 class="mt-4">Forms linked to this site</h4>
|
|
||||||
|
|
||||||
@if (siteInfo.FormDefinitions?.Count > 0)
|
|
||||||
{
|
|
||||||
<ul class="list-group mb-3">
|
|
||||||
@foreach (var form in siteInfo.FormDefinitions)
|
|
||||||
{
|
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
||||||
<span>
|
|
||||||
<strong>@form.Title</strong><br />
|
|
||||||
<small class="text-muted">@form.CreatedAt.ToString("yyyy-MM-dd HH:mm")</small>
|
|
||||||
</span>
|
|
||||||
<a class="btn btn-sm btn-outline-secondary" href="/form-editor/@form.Id">Edit</a>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<p class="text-muted">No forms added yet.</p>
|
|
||||||
}
|
|
||||||
|
|
||||||
<a class="btn btn-success" href="/createform/@SiteId">
|
|
||||||
<i class="fas fa-plus-circle"></i> Add New Form
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter]
|
|
||||||
public int SiteId { get; set; }
|
|
||||||
|
|
||||||
[Parameter] public Func<SiteInfo, Task> OnSiteInfoSaveClicked { get; set; }
|
|
||||||
[Parameter] public Func<string, Task> OnSiteNameChanged { get; set; }
|
|
||||||
[Parameter] public Func<string, int, Task> OnCancelItemClicked { get; set; }
|
|
||||||
|
|
||||||
private EditContext EditContext;
|
|
||||||
private SiteInfo siteInfo = new();
|
|
||||||
private string? userId;
|
|
||||||
private string? userName;
|
|
||||||
private AuthenticationState? authState;
|
|
||||||
|
|
||||||
|
|
||||||
protected override Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
EditContext = new EditContext(siteInfo);
|
|
||||||
EditContext.OnFieldChanged += EditContext_OnFieldChanged;
|
|
||||||
return base.OnInitializedAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
|
||||||
{
|
|
||||||
authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
|
||||||
if (authState.User.Identity?.IsAuthenticated == true)
|
|
||||||
{
|
|
||||||
userId = CustomAuthProvider.GetUserId();
|
|
||||||
userName = CustomAuthProvider.GetUserName();
|
|
||||||
}
|
|
||||||
siteInfo = await _contentEditorService.GetSiteInfoWithFormsByIdAsync(SiteId) ?? new SiteInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveSiteInfo()
|
|
||||||
{
|
|
||||||
await _contentEditorService.UpdateSiteInfoAsync(siteInfo);
|
|
||||||
if (OnSiteInfoSaveClicked != null)
|
|
||||||
await OnSiteInfoSaveClicked.Invoke(siteInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.FieldIdentifier.FieldName == "SiteName")
|
|
||||||
{
|
|
||||||
//invoke SiteNameChanged
|
|
||||||
if (OnSiteNameChanged != null)
|
|
||||||
await OnSiteNameChanged.Invoke(siteInfo.SiteName);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Rechunk(SiteInfo site)
|
|
||||||
{
|
|
||||||
var confirmationResult = await dialogService.Confirm("Are you sure?", "Rechunk site", new ConfirmOptions() { OkButtonText = "Rechunk", CancelButtonText = "Oops, no" });
|
|
||||||
if (confirmationResult == true)
|
|
||||||
{
|
|
||||||
await ReallyRechunk(site);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//do nothing?
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
private async Task ReallyRechunk(SiteInfo site)
|
|
||||||
{
|
|
||||||
await _contentEditorService.ForceRecreateQdrantCollectionAsync(site.Id);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -2,12 +2,11 @@
|
||||||
@using BLAIzor.Services
|
@using BLAIzor.Services
|
||||||
@using Microsoft.AspNetCore.Components.Authorization
|
@using Microsoft.AspNetCore.Components.Authorization
|
||||||
@inject ContentEditorService ContentEditorService
|
@inject ContentEditorService ContentEditorService
|
||||||
@inject ContentEditorAIService ContentEditorAIService
|
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
@inject CustomAuthenticationStateProvider CustomAuthProvider
|
@inject CustomAuthenticationStateProvider CustomAuthProvider
|
||||||
|
|
||||||
<div class="menu-item-editor">
|
<div class="menu-item-editor">
|
||||||
|
|
||||||
@{
|
@{
|
||||||
if (!string.IsNullOrEmpty(WordFile))
|
if (!string.IsNullOrEmpty(WordFile))
|
||||||
{
|
{
|
||||||
|
|
@ -18,20 +17,14 @@
|
||||||
}
|
}
|
||||||
<button class="btn btn-primary mb-2" @onclick="GenerateContent" disabled="@IsLoading">Generate by AI</button>
|
<button class="btn btn-primary mb-2" @onclick="GenerateContent" disabled="@IsLoading">Generate by AI</button>
|
||||||
@* <textarea class="form-control border-0 text-white" @bind="GeneratedContent" rows="5"></textarea> *@
|
@* <textarea class="form-control border-0 text-white" @bind="GeneratedContent" rows="5"></textarea> *@
|
||||||
<div class="row">
|
<RadzenHtmlEditor @bind-Value=@GeneratedContent style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
||||||
|
<RadzenHtmlEditorUndo />
|
||||||
|
<RadzenHtmlEditorRedo />
|
||||||
|
<RadzenHtmlEditorSource />
|
||||||
|
</RadzenHtmlEditor>
|
||||||
|
<InputFile class="btn btn-default" type="file" multiple OnChange=HandleFileUpload accept=".mp3,.mp4,.jpg,.png" />
|
||||||
|
|
||||||
<RadzenTextArea @bind-Value=@MenuItem.ContentDescription></RadzenTextArea>
|
<EventConsole @ref=@console />
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<RadzenHtmlEditor @bind-Value=@GeneratedContent style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
|
||||||
<RadzenHtmlEditorUndo />
|
|
||||||
<RadzenHtmlEditorRedo />
|
|
||||||
<RadzenHtmlEditorSource />
|
|
||||||
</RadzenHtmlEditor>
|
|
||||||
</div>
|
|
||||||
<InputFile class="btn btn-default" type="file" multiple OnChange=HandleFileUpload accept=".mp3,.mp4,.jpg,.png" />
|
|
||||||
|
|
||||||
@* <EventConsole @ref=@console /> *@
|
|
||||||
@if (IsLoading)
|
@if (IsLoading)
|
||||||
{
|
{
|
||||||
<p>Loading content...</p>
|
<p>Loading content...</p>
|
||||||
|
|
@ -47,17 +40,15 @@
|
||||||
|
|
||||||
private bool IsLoading = false;
|
private bool IsLoading = false;
|
||||||
private string GeneratedContent = string.Empty;
|
private string GeneratedContent = string.Empty;
|
||||||
// private string Description = string.Empty;
|
|
||||||
private string? userId;
|
private string? userId;
|
||||||
private string? userName;
|
private string? userName;
|
||||||
private AuthenticationState? authState;
|
private AuthenticationState? authState;
|
||||||
|
|
||||||
//EventConsole console;
|
EventConsole console;
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
GeneratedContent = MenuItem.Content;
|
GeneratedContent = MenuItem.Content;
|
||||||
// Description = MenuItem.ContentDescription;
|
|
||||||
authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||||
if (authState.User.Identity?.IsAuthenticated == true)
|
if (authState.User.Identity?.IsAuthenticated == true)
|
||||||
{
|
{
|
||||||
|
|
@ -73,7 +64,7 @@
|
||||||
{
|
{
|
||||||
Console.Write($"Subject: {Subject}");
|
Console.Write($"Subject: {Subject}");
|
||||||
var prompt = $"Generate website content for a page titled '{MenuItem.MenuItem.Name}' of a '{Subject}' website. Please do not attach any explanation.";
|
var prompt = $"Generate website content for a page titled '{MenuItem.MenuItem.Name}' of a '{Subject}' website. Please do not attach any explanation.";
|
||||||
GeneratedContent = await ContentEditorAIService.GetGeneratedContentAsync(SessionId, prompt);
|
GeneratedContent = await ContentEditorService.GetGeneratedContentAsync(SessionId, prompt);
|
||||||
MenuItem.Content = GeneratedContent;
|
MenuItem.Content = GeneratedContent;
|
||||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +85,7 @@
|
||||||
{
|
{
|
||||||
Console.Write($"Subject: {Subject}");
|
Console.Write($"Subject: {Subject}");
|
||||||
var prompt = $"This is the provided text: {WordFile}. Look for the relevant content for a page titled '{MenuItem.MenuItem.Name}' of a '{Subject}' website. Please do not attach any explanation.";
|
var prompt = $"This is the provided text: {WordFile}. Look for the relevant content for a page titled '{MenuItem.MenuItem.Name}' of a '{Subject}' website. Please do not attach any explanation.";
|
||||||
GeneratedContent = await ContentEditorAIService.GetGeneratedContentAsync(SessionId, prompt);
|
GeneratedContent = await ContentEditorService.GetGeneratedContentAsync(SessionId, prompt);
|
||||||
MenuItem.Content = GeneratedContent;
|
MenuItem.Content = GeneratedContent;
|
||||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||||
}
|
}
|
||||||
|
|
@ -112,33 +103,33 @@
|
||||||
|
|
||||||
async Task OnPaste(HtmlEditorPasteEventArgs args)
|
async Task OnPaste(HtmlEditorPasteEventArgs args)
|
||||||
{
|
{
|
||||||
// console.Log($"Paste: {args.Html}");
|
console.Log($"Paste: {args.Html}");
|
||||||
MenuItem.Content = args.Html;
|
MenuItem.Content = args.Html;
|
||||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task OnChange(string html)
|
async Task OnChange(string html)
|
||||||
{
|
{
|
||||||
// console.Log($"Change: {html}");
|
console.Log($"Change: {html}");
|
||||||
MenuItem.Content = html;
|
MenuItem.Content = html;
|
||||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task OnInput(string html)
|
async Task OnInput(string html)
|
||||||
{
|
{
|
||||||
// console.Log($"Input: {html}");
|
console.Log($"Input: {html}");
|
||||||
MenuItem.Content = html;
|
MenuItem.Content = html;
|
||||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnExecute(HtmlEditorExecuteEventArgs args)
|
void OnExecute(HtmlEditorExecuteEventArgs args)
|
||||||
{
|
{
|
||||||
//console.Log($"Execute: {args.CommandName}");
|
console.Log($"Execute: {args.CommandName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnUploadComplete(UploadCompleteEventArgs args)
|
void OnUploadComplete(UploadCompleteEventArgs args)
|
||||||
{
|
{
|
||||||
//console.Log($"Upload complete: {args.RawResponse}");
|
console.Log($"Upload complete: {args.RawResponse}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleFileUpload(InputFileChangeEventArgs e)
|
private async Task HandleFileUpload(InputFileChangeEventArgs e)
|
||||||
|
|
@ -176,7 +167,7 @@
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// console.Log($"Error uploading files: {ex.Message}");
|
console.Log($"Error uploading files: {ex.Message}");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,249 +0,0 @@
|
||||||
@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("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,9 +9,8 @@
|
||||||
|
|
||||||
|
|
||||||
@* <nav class="navbar navbar-expand-lg bg-body-tertiary" style="z-index: 5"> *@
|
@* <nav class="navbar navbar-expand-lg bg-body-tertiary" style="z-index: 5"> *@
|
||||||
<nav class="navbar fixed-top" style="z-index: 10005">
|
<nav class="navbar fixed-top" style="z-index: 5">
|
||||||
@* <div class="container-fluid"> *@
|
<div class="container-fluid">
|
||||||
<div style="--bs-gutter-x: 1.5rem; --bs-gutter-y: 0; width: 100%; padding-right: calc(var(--bs-gutter-x) * .5); padding-left: calc(var(--bs-gutter-x) * .5); margin-right: auto; margin-left: auto;">
|
|
||||||
@{
|
@{
|
||||||
var brandFileName = _scopedContentService.SelectedDocument;
|
var brandFileName = _scopedContentService.SelectedDocument;
|
||||||
var brandName = _scopedContentService.SelectedBrandName;
|
var brandName = _scopedContentService.SelectedBrandName;
|
||||||
|
|
@ -24,14 +23,14 @@
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
@{
|
@{
|
||||||
if (MenuList != null)
|
if(MenuList != null)
|
||||||
{
|
{
|
||||||
foreach (var menu in MenuList)
|
foreach(var menu in MenuList)
|
||||||
{
|
{
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link active" aria-current="page" @onclick="()=>MenuClickedAsync(menu)">@menu</a>
|
<a class="nav-link active" aria-current="page" @onclick="()=>MenuClickedAsync(menu)">@menu</a>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +44,7 @@
|
||||||
<option value="">Lang</option>
|
<option value="">Lang</option>
|
||||||
@foreach (var Language in Languages)
|
@foreach (var Language in Languages)
|
||||||
{
|
{
|
||||||
<option value="@Language">@Language</option>
|
<option value="@Language">@Language</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -99,12 +98,12 @@
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(MenuString))
|
if(!string.IsNullOrEmpty(MenuString))
|
||||||
{
|
{
|
||||||
MenuList = MenuString.Split(",");
|
MenuList = MenuString.Split(",");
|
||||||
}
|
}
|
||||||
await base.OnParametersSetAsync();
|
await base.OnParametersSetAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLanguageSelected(ChangeEventArgs e)
|
public void OnLanguageSelected(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,167 +0,0 @@
|
||||||
@using BLAIzor.Models
|
|
||||||
@using BLAIzor.Services
|
|
||||||
@inject ScopedContentService _scopedContentService;
|
|
||||||
@inject NavigationManager _navigationManager;
|
|
||||||
@inject ContentEditorService _contentEditorService
|
|
||||||
@inject IHttpContextAccessor HttpContextAccessor
|
|
||||||
@inject IJSRuntime JS
|
|
||||||
@inject ISimpleLogger _logger
|
|
||||||
|
|
||||||
<nav class="navbar fixed-top navbar-expand-lg" style="z-index: 10005">
|
|
||||||
<div class="container-fluid">
|
|
||||||
|
|
||||||
<NavLink class="navbar-brand" @onclick="HomeClick">@BrandName</NavLink>
|
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
|
||||||
<i class="fa-solid fa-bars"></i>
|
|
||||||
</button>
|
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
||||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
|
||||||
@{
|
|
||||||
if (Menu != null)
|
|
||||||
{
|
|
||||||
// foreach (var menuItem in Menu)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// <li class="nav-item">
|
|
||||||
// <a class="nav-link" aria-current="page" @onclick="()=>MenuClickedAsync(menuItem.Name)">@menuItem.Name</a>
|
|
||||||
// </li>
|
|
||||||
// }
|
|
||||||
|
|
||||||
foreach (var menuItem in Menu.Where(m => m.ParentId == null).OrderBy(m => m.SortOrder))
|
|
||||||
{
|
|
||||||
if (menuItem.Children != null && menuItem.Children.Any())
|
|
||||||
{
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a class="nav-link dropdown-toggle" role="button"
|
|
||||||
data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
@menuItem.Name
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
@foreach (var child in menuItem.Children.OrderBy(c => c.SortOrder))
|
|
||||||
{
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" @onclick="() => MenuClickedAsync(child.Name)">
|
|
||||||
@child.Name
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" @onclick="() => MenuClickedAsync(menuItem.Name)">
|
|
||||||
@menuItem.Name
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@* <li class="nav-item dropdown">
|
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
Dropdown
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
|
|
||||||
<li><a class="dropdown-item" href="#">Action</a></li>
|
|
||||||
<li><a class="dropdown-item" href="#">Another action</a></li>
|
|
||||||
<li><hr class="dropdown-divider"></li>
|
|
||||||
<li><a class="dropdown-item" href="#">Something else here</a></li>
|
|
||||||
</ul>
|
|
||||||
</li> *@
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
<select @onchange="OnLanguageSelected" class="form-select" style="width:100px">
|
|
||||||
<option value="@SelectedLanguage">@SelectedLanguage</option>
|
|
||||||
@foreach (var Language in Languages)
|
|
||||||
{
|
|
||||||
<option value="@Language">@Language</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter]
|
|
||||||
public int SiteId { get; set; }
|
|
||||||
[Parameter]
|
|
||||||
public List<MenuItem> Menu { get; set; }
|
|
||||||
[Parameter] public string? BrandName { get; set; } = "BLAIzor";
|
|
||||||
//public string[] MenuList;
|
|
||||||
public string videoUrl = "";
|
|
||||||
public string SelectedLanguage;
|
|
||||||
private int RenderCounter = 0;
|
|
||||||
|
|
||||||
//public static event Action<string>? OnMenuClicked;
|
|
||||||
[Parameter] public Action<string>? OnMenuClicked { get; set; }
|
|
||||||
|
|
||||||
public List<string> Languages = new List<string>
|
|
||||||
{
|
|
||||||
"Hungarian", "English", "German"
|
|
||||||
};
|
|
||||||
|
|
||||||
public async Task MenuClickedAsync(string menuName)
|
|
||||||
{
|
|
||||||
OnMenuClicked?.Invoke(menuName);
|
|
||||||
await JS.InvokeVoidAsync("collapseNavbar");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HomeClick()
|
|
||||||
{
|
|
||||||
_navigationManager.Refresh(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
|
||||||
{
|
|
||||||
if (Menu != null)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
var lang = await JS.InvokeAsync<string>("getUserLanguage");
|
|
||||||
|
|
||||||
SiteInfo site = await _contentEditorService.GetSiteInfoByIdAsync(SiteId);
|
|
||||||
if (site.DefaultLanguage != null)
|
|
||||||
{
|
|
||||||
await _logger.InfoAsync($"NavMenu component: Setting default language to {site.DefaultLanguage} for site {site.Id}");
|
|
||||||
_scopedContentService.WebsiteDefaultLanguage = site.DefaultLanguage;
|
|
||||||
_scopedContentService.SelectedLanguage = site.DefaultLanguage;
|
|
||||||
SelectedLanguage = site.DefaultLanguage;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Normalize and match to one of your supported languages
|
|
||||||
if (lang.StartsWith("hu", StringComparison.OrdinalIgnoreCase))
|
|
||||||
SelectedLanguage = "Hungarian";
|
|
||||||
else if (lang.StartsWith("de", StringComparison.OrdinalIgnoreCase))
|
|
||||||
SelectedLanguage = "German";
|
|
||||||
else
|
|
||||||
SelectedLanguage = "English";
|
|
||||||
await _logger.InfoAsync($"Setting default language to {SelectedLanguage} based on user language {lang}");
|
|
||||||
_scopedContentService.SelectedLanguage = SelectedLanguage;
|
|
||||||
}
|
|
||||||
await base.OnParametersSetAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnLanguageSelected(ChangeEventArgs e)
|
|
||||||
{
|
|
||||||
SelectedLanguage = e.Value?.ToString();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(SelectedLanguage))
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Language selected: {SelectedLanguage}");
|
|
||||||
_scopedContentService.SelectedLanguage = SelectedLanguage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -57,14 +57,14 @@
|
||||||
<p>Your sample html template for a specific block, like article, card, hero or such. Here you can use sample data in the snippet, to see if your css is working well</p>
|
<p>Your sample html template for a specific block, like article, card, hero or such. Here you can use sample data in the snippet, to see if your css is working well</p>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Sample</label><RadzenButton Click="@(() => ShowSnippetPreview(Snippet))">Preview snippet</RadzenButton>
|
<label>Sample</label><RadzenButton Click="@(() => ShowSnippetPreview(Snippet))">Preview snippet</RadzenButton>
|
||||||
@* <RadzenHtmlEditor @bind-Value=@Snippet.SampleHtml style="height: 450px; color:#000; background-color: rgba(255,255,255,0) !important" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
<RadzenHtmlEditor @bind-Value=@Snippet.SampleHtml style="height: 450px; color:#000; background-color: rgba(255,255,255,0) !important" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
||||||
<RadzenHtmlEditorUndo />
|
<RadzenHtmlEditorUndo />
|
||||||
<RadzenHtmlEditorRedo />
|
<RadzenHtmlEditorRedo />
|
||||||
<RadzenHtmlEditorSource />
|
<RadzenHtmlEditorSource />
|
||||||
</RadzenHtmlEditor> *@
|
</RadzenHtmlEditor>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@* <EventConsole @ref=@console /> *@
|
<EventConsole @ref=@console />
|
||||||
@if (IsLoading)
|
@if (IsLoading)
|
||||||
{
|
{
|
||||||
<p>Loading content...</p>
|
<p>Loading content...</p>
|
||||||
|
|
@ -83,7 +83,7 @@
|
||||||
private string? userName;
|
private string? userName;
|
||||||
private AuthenticationState? authState;
|
private AuthenticationState? authState;
|
||||||
|
|
||||||
// EventConsole console;
|
EventConsole console;
|
||||||
|
|
||||||
public async void ShowSnippetPreview(HtmlSnippet snippet)
|
public async void ShowSnippetPreview(HtmlSnippet snippet)
|
||||||
{
|
{
|
||||||
|
|
@ -117,30 +117,30 @@
|
||||||
|
|
||||||
async Task OnPaste(HtmlEditorPasteEventArgs args)
|
async Task OnPaste(HtmlEditorPasteEventArgs args)
|
||||||
{
|
{
|
||||||
// console.Log($"Paste: {args.Html}");
|
console.Log($"Paste: {args.Html}");
|
||||||
// await OnContentUpdated.InvokeAsync(MenuItem);
|
// await OnContentUpdated.InvokeAsync(MenuItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task OnChange(string html)
|
async Task OnChange(string html)
|
||||||
{
|
{
|
||||||
// console.Log($"Change: {html}");
|
console.Log($"Change: {html}");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task OnInput(string html)
|
async Task OnInput(string html)
|
||||||
{
|
{
|
||||||
// console.Log($"Input: {html}");
|
console.Log($"Input: {html}");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnExecute(HtmlEditorExecuteEventArgs args)
|
void OnExecute(HtmlEditorExecuteEventArgs args)
|
||||||
{
|
{
|
||||||
// console.Log($"Execute: {args.CommandName}");
|
console.Log($"Execute: {args.CommandName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnUploadComplete(UploadCompleteEventArgs args)
|
void OnUploadComplete(UploadCompleteEventArgs args)
|
||||||
{
|
{
|
||||||
// console.Log($"Upload complete: {args.RawResponse}");
|
console.Log($"Upload complete: {args.RawResponse}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
@using BLAIzor.Models
|
<style>
|
||||||
<style>
|
|
||||||
.parent-element-to-video {
|
.parent-element-to-video {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 120vw;
|
width: 120vw;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#myVideo {
|
video {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
@ -17,8 +16,8 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="parent-element-to-video">
|
<div class="parent-element-to-video">
|
||||||
<video style="opacity:0.3; z-index: -1" autoplay muted loop id="myVideo" @key="site.BackgroundVideo">
|
<video style="opacity:0.3; z-index: -1" autoplay muted loop id="myVideo" @key="SelectedBrandName">
|
||||||
<source src="@(site.BackgroundVideo)" type="video/mp4">
|
<source src="@("/video/" + SelectedBrandName + ".mp4")" type="video/mp4">
|
||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -35,5 +34,5 @@
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public SiteInfo site { get; set; } = new SiteInfo();
|
public string SelectedBrandName { get; set; } = "default";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,10 @@ namespace BLAIzor.Data
|
||||||
public DbSet<SiteInfo> SiteInfos { get; set; }
|
public DbSet<SiteInfo> SiteInfos { get; set; }
|
||||||
public DbSet<MenuItem> MenuItems { get; set; } // Add MenuItem DbSet
|
public DbSet<MenuItem> MenuItems { get; set; } // Add MenuItem DbSet
|
||||||
public DbSet<DesignTemplate> DesignTemplates { get; set; }
|
public DbSet<DesignTemplate> DesignTemplates { get; set; }
|
||||||
|
|
||||||
public DbSet<CssTemplate> CssTemplates { get; set; }
|
public DbSet<CssTemplate> CssTemplates { get; set; }
|
||||||
public DbSet<ContentGroup> ContentGroups { get; set; }
|
|
||||||
public DbSet<ContentItem> ContentItems { get; set; }
|
|
||||||
public DbSet<ContentChunk> ContentChunks { get; set; }
|
|
||||||
public DbSet<FormDefinition> FormDefinitions { get; set; }
|
public DbSet<FormDefinition> FormDefinitions { get; set; }
|
||||||
public DbSet<AppLog> Logs { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
|
@ -94,36 +90,6 @@ namespace BLAIzor.Data
|
||||||
.HasForeignKey(m => m.SiteInfoId)
|
.HasForeignKey(m => m.SiteInfoId)
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
modelBuilder.Entity<MenuItem>()
|
|
||||||
.HasOne(m => m.ContentGroup)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(m => m.ContentGroupId)
|
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
|
||||||
|
|
||||||
modelBuilder.Entity<MenuItem>()
|
|
||||||
.HasOne(m => m.ContentItem)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(m => m.ContentItemId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<MenuItem>()
|
|
||||||
.HasOne(m => m.Parent)
|
|
||||||
.WithMany(p => p.Children)
|
|
||||||
.HasForeignKey(m => m.ParentId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<ContentItem>()
|
|
||||||
.HasOne(ci => ci.ContentGroup)
|
|
||||||
.WithMany(cg => cg.Items)
|
|
||||||
.HasForeignKey(ci => ci.ContentGroupId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade); // When a ContentGroup is deleted, delete its ContentItems
|
|
||||||
|
|
||||||
modelBuilder.Entity<ContentChunk>()
|
|
||||||
.HasOne(cc => cc.ContentItem)
|
|
||||||
.WithMany(ci => ci.Chunks)
|
|
||||||
.HasForeignKey(cc => cc.ContentItemId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade); // When a ContentItem is deleted, delete its Chunks
|
|
||||||
|
|
||||||
modelBuilder.Entity<DesignTemplate>()
|
modelBuilder.Entity<DesignTemplate>()
|
||||||
.HasOne(s => s.User)
|
.HasOne(s => s.User)
|
||||||
.WithMany()
|
.WithMany()
|
||||||
|
|
@ -137,10 +103,10 @@ namespace BLAIzor.Data
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
modelBuilder.Entity<FormDefinition>()
|
modelBuilder.Entity<FormDefinition>()
|
||||||
.HasOne(fd => fd.SiteInfo)
|
.HasOne(fd => fd.SiteInfo)
|
||||||
.WithMany(s => s.FormDefinitions)
|
.WithMany(s => s.FormDefinitions)
|
||||||
.HasForeignKey(fd => fd.SiteInfoId)
|
.HasForeignKey(fd => fd.SiteInfoId)
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
modelBuilder.Entity<FormDefinition>()
|
modelBuilder.Entity<FormDefinition>()
|
||||||
.HasIndex(fd => new { fd.SiteInfoId, fd.Slug })
|
.HasIndex(fd => new { fd.SiteInfoId, fd.Slug })
|
||||||
|
|
|
||||||
|
|
@ -1,130 +0,0 @@
|
||||||
using BLAIzor.Models;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace BLAIzor.Helpers
|
|
||||||
{
|
|
||||||
public static class ChunkingHelper
|
|
||||||
{
|
|
||||||
private static readonly string[] SectionDelimiters =
|
|
||||||
{
|
|
||||||
"\n##", "\n###", "\nSection:", "\nTopic:", "\nTitle:", "\n---", "[[CHUNK_BREAK]]", "### Logical Break ###"
|
|
||||||
};
|
|
||||||
|
|
||||||
public static List<string> SplitStructuredText(string content, int maxChunkCharLength = 3000)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(content))
|
|
||||||
return new List<string>();
|
|
||||||
|
|
||||||
// Normalize newlines
|
|
||||||
content = content.Replace("\r\n", "\n").Trim();
|
|
||||||
|
|
||||||
// Step 1: Split by known logical boundaries
|
|
||||||
var logicalParts = SplitByDelimiters(content, SectionDelimiters);
|
|
||||||
|
|
||||||
// Step 2: Recombine smaller logical parts into full-size chunks
|
|
||||||
var chunks = new List<string>();
|
|
||||||
var currentChunk = new StringBuilder();
|
|
||||||
|
|
||||||
foreach (var part in logicalParts)
|
|
||||||
{
|
|
||||||
if (currentChunk.Length + part.Length + 2 <= maxChunkCharLength)
|
|
||||||
{
|
|
||||||
currentChunk.AppendLine(part);
|
|
||||||
currentChunk.AppendLine();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (currentChunk.Length > 0)
|
|
||||||
{
|
|
||||||
chunks.Add(currentChunk.ToString().Trim());
|
|
||||||
currentChunk.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (part.Length > maxChunkCharLength)
|
|
||||||
{
|
|
||||||
chunks.AddRange(SplitLongParagraph(part, maxChunkCharLength));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
currentChunk.AppendLine(part);
|
|
||||||
currentChunk.AppendLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentChunk.Length > 0)
|
|
||||||
chunks.Add(currentChunk.ToString().Trim());
|
|
||||||
|
|
||||||
return chunks;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<string> SplitByDelimiters(string content, string[] delimiters)
|
|
||||||
{
|
|
||||||
var parts = new List<string>();
|
|
||||||
var remaining = content;
|
|
||||||
|
|
||||||
foreach (var delimiter in delimiters)
|
|
||||||
{
|
|
||||||
remaining = remaining.Replace(delimiter, "\n[[SECTION_BREAK]]");
|
|
||||||
}
|
|
||||||
|
|
||||||
return remaining.Split(new[] { "[[SECTION_BREAK]]" }, StringSplitOptions.RemoveEmptyEntries)
|
|
||||||
.Select(s => s.Trim())
|
|
||||||
.Where(s => !string.IsNullOrWhiteSpace(s))
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<string> SplitLongParagraph(string text, int maxLength)
|
|
||||||
{
|
|
||||||
var chunks = new List<string>();
|
|
||||||
int index = 0;
|
|
||||||
while (index < text.Length)
|
|
||||||
{
|
|
||||||
int len = Math.Min(maxLength, text.Length - index);
|
|
||||||
chunks.Add(text.Substring(index, len));
|
|
||||||
index += len;
|
|
||||||
}
|
|
||||||
return chunks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks whether the Qdrant-based chunks match the original ContentItem text.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The ContentItem to check.</param>
|
|
||||||
/// <param name="chunks">The SQL chunks that reference Qdrant IDs.</param>
|
|
||||||
/// <param name="vectorData">All related WebPageContent objects pulled from Qdrant.</param>
|
|
||||||
public static bool IsChunkingConsistent(
|
|
||||||
ContentItem item,
|
|
||||||
List<ContentChunk> chunks,
|
|
||||||
List<WebPageContent> vectorData)
|
|
||||||
{
|
|
||||||
if (item == null || string.IsNullOrWhiteSpace(item.Content) || chunks == null || vectorData == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var orderedChunks = chunks.OrderBy(c => c.ChunkIndex).ToList();
|
|
||||||
|
|
||||||
var combinedText = string.Join("",
|
|
||||||
orderedChunks.Select(chunk =>
|
|
||||||
vectorData.FirstOrDefault(v => v.UId == chunk.QdrantPointId)?.Content?.Trim() ?? ""
|
|
||||||
));
|
|
||||||
|
|
||||||
var original = NormalizeText(item.Content);
|
|
||||||
var reassembled = NormalizeText(combinedText);
|
|
||||||
|
|
||||||
return original == reassembled;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string NormalizeText(string text)
|
|
||||||
{
|
|
||||||
return text.Replace("\r", "")
|
|
||||||
.Replace("\n", "")
|
|
||||||
.Replace(" ", "")
|
|
||||||
.Trim()
|
|
||||||
.ToLowerInvariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Text;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Radzen;
|
|
||||||
|
|
||||||
public static class NotificationHelper
|
|
||||||
{
|
|
||||||
// Special character replacement map
|
|
||||||
public static NotificationMessage CreateNotificationMessage(string messageText, int severity, string summary, string detail, int duration = 4000, bool showProgress = true, Action<Radzen.NotificationMessage> callBack = null)
|
|
||||||
{
|
|
||||||
NotificationSeverity messageSeverity;
|
|
||||||
switch (severity)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
messageSeverity = NotificationSeverity.Error;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
messageSeverity = NotificationSeverity.Info;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
messageSeverity = NotificationSeverity.Success;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
messageSeverity = NotificationSeverity.Warning;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
messageSeverity = NotificationSeverity.Info;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var message = new NotificationMessage
|
|
||||||
{
|
|
||||||
//error 0, info 1, success 2, warning 3
|
|
||||||
|
|
||||||
Severity = messageSeverity,
|
|
||||||
Summary = summary,
|
|
||||||
Detail = detail,
|
|
||||||
Duration = duration,
|
|
||||||
ShowProgress = showProgress,
|
|
||||||
Click = callBack,
|
|
||||||
CloseOnClick = true,
|
|
||||||
Payload = DateTime.Now
|
|
||||||
};
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,269 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Text;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
public static class TextHelper
|
|
||||||
{
|
|
||||||
// Special character replacement map
|
|
||||||
private static readonly Dictionary<string, string> HungarianSpecialCharacterMap = new()
|
|
||||||
{
|
|
||||||
{ "/", " per " },
|
|
||||||
{ "@", " kukac " },
|
|
||||||
{ "#", " kettőskereszt " },
|
|
||||||
{ "&", " és " },
|
|
||||||
//{ ",", " vessző " },
|
|
||||||
{ " = ", " egyenlő " }, // Example, you can add more
|
|
||||||
//{ " - ", " mínusz " } // Example, you can add more
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly Dictionary<string, string> EnglishSpecialCharacterMap = new()
|
|
||||||
{
|
|
||||||
{ "/", " slash " },
|
|
||||||
{ "@", " at " },
|
|
||||||
{ "#", " hashtag " },
|
|
||||||
{ "&", " and " },
|
|
||||||
//{ ",", " vessző " },
|
|
||||||
{ " = ", " equals " }, // Example, you can add more
|
|
||||||
//{ " - ", " mínusz " } // Example, you can add more
|
|
||||||
};
|
|
||||||
|
|
||||||
public static string ReplaceNumbersAndSpecialCharacters(string text, string language)
|
|
||||||
{
|
|
||||||
// Save parts that should be skipped (emails, URLs, dates)
|
|
||||||
var protectedParts = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
// Protect dates like 2024.05.06
|
|
||||||
text = Regex.Replace(text, @"\b\d{4}\.\d{2}\.\d{2}\b", match =>
|
|
||||||
{
|
|
||||||
string key = $"__DATE__{protectedParts.Count}__";
|
|
||||||
protectedParts[key] = match.Value;
|
|
||||||
return key;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove anything between [] including the brackets themselves
|
|
||||||
text = Regex.Replace(text, @"\[[^\]]*\]", "");
|
|
||||||
|
|
||||||
// First replace floats (keep this BEFORE integers)
|
|
||||||
text = Regex.Replace(text, @"\b\d+\.\d+\b", match =>
|
|
||||||
{
|
|
||||||
var parts = match.Value.Split('.');
|
|
||||||
var integerPart = int.Parse(parts[0]);
|
|
||||||
var decimalPart = int.Parse(parts[1]);
|
|
||||||
if(language == "Hungarian")
|
|
||||||
{
|
|
||||||
return $"{NumberToHungarian(integerPart)} egész {NumberToHungarian(decimalPart)} {(parts[1].Length == 1 ? "tized" : parts[1].Length == 2 ? "század" : "ezred")}";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $"{NumberToEnglish(integerPart)} point {NumberToEnglish(decimalPart)}";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Then replace integers
|
|
||||||
text = Regex.Replace(text, @"\b\d+\b", match =>
|
|
||||||
{
|
|
||||||
int number = int.Parse(match.Value);
|
|
||||||
if(language == "Hungarian")
|
|
||||||
{
|
|
||||||
return NumberToHungarian(number);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NumberToEnglish(number);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Replace special characters from dictionary
|
|
||||||
if(language == "Hungarian")
|
|
||||||
{
|
|
||||||
foreach (var kvp in HungarianSpecialCharacterMap)
|
|
||||||
{
|
|
||||||
text = text.Replace(kvp.Key, kvp.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var kvp in EnglishSpecialCharacterMap)
|
|
||||||
{
|
|
||||||
text = text.Replace(kvp.Key, kvp.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace dots surrounded by spaces (optional)
|
|
||||||
//text = Regex.Replace(text, @" (?=\.)|(?<=\.) ", " pont ");
|
|
||||||
|
|
||||||
// Restore protected parts
|
|
||||||
foreach (var kvp in protectedParts)
|
|
||||||
{
|
|
||||||
text = text.Replace(kvp.Key, kvp.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static string NumberToHungarian(int number)
|
|
||||||
{
|
|
||||||
if (number == 0) return "nulla";
|
|
||||||
|
|
||||||
string[] units = { "", "egy", "két", "három", "négy", "öt", "hat", "hét", "nyolc", "kilenc" };
|
|
||||||
string[] tens = { "", "tíz", "húsz", "harminc", "negyven", "ötven", "hatvan", "hetven", "nyolcvan", "kilencven" };
|
|
||||||
string[] tensAlternate = { "", "tizen", "huszon", "harminc", "negyven", "ötven", "hatvan", "hetven", "nyolcvan", "kilencven" };
|
|
||||||
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
|
|
||||||
if (number >= 1000)
|
|
||||||
{
|
|
||||||
int thousands = number / 1000;
|
|
||||||
if (thousands == 1)
|
|
||||||
result.Append("ezer");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.Append(NumberToHungarian(thousands));
|
|
||||||
result.Append("ezer");
|
|
||||||
}
|
|
||||||
number %= 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (number >= 100)
|
|
||||||
{
|
|
||||||
int hundreds = number / 100;
|
|
||||||
if (hundreds == 1)
|
|
||||||
result.Append("száz");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.Append(NumberToHungarian(hundreds));
|
|
||||||
result.Append("száz");
|
|
||||||
}
|
|
||||||
number %= 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (number >= 10)
|
|
||||||
{
|
|
||||||
int tensPart = number / 10;
|
|
||||||
result.Append(tensAlternate[tensPart]);
|
|
||||||
number %= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (number > 0)
|
|
||||||
{
|
|
||||||
// "két" instead of "kettő" in compound numbers
|
|
||||||
if (number == 2 && result.Length > 0)
|
|
||||||
result.Append("két");
|
|
||||||
else
|
|
||||||
result.Append(units[number]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string NumberToEnglish(int number)
|
|
||||||
{
|
|
||||||
if (number == 0) return "zero";
|
|
||||||
|
|
||||||
string[] units = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
|
|
||||||
string[] tens = { "", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninty" };
|
|
||||||
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
|
|
||||||
if (number >= 1000)
|
|
||||||
{
|
|
||||||
int thousands = number / 1000;
|
|
||||||
if (thousands == 1)
|
|
||||||
result.Append("thousand");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.Append(NumberToHungarian(thousands));
|
|
||||||
result.Append("thousand");
|
|
||||||
}
|
|
||||||
number %= 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (number >= 100)
|
|
||||||
{
|
|
||||||
int hundreds = number / 100;
|
|
||||||
if (hundreds == 1)
|
|
||||||
result.Append("hundred");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.Append(NumberToHungarian(hundreds));
|
|
||||||
result.Append("hundred");
|
|
||||||
}
|
|
||||||
number %= 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (number >= 10)
|
|
||||||
{
|
|
||||||
//int tensPart = number / 10;
|
|
||||||
//result.Append(tens[tensPart]);
|
|
||||||
//number %= 10;
|
|
||||||
switch (number)
|
|
||||||
{
|
|
||||||
case 10:
|
|
||||||
result.Append("ten");
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
result.Append("eleven");
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
result.Append("twelve");
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
result.Append("thirteen");
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
result.Append("fourteen");
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
result.Append("fifteen");
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
result.Append("sixteen");
|
|
||||||
break;
|
|
||||||
case 17:
|
|
||||||
result.Append("seventeen");
|
|
||||||
break;
|
|
||||||
case 18:
|
|
||||||
result.Append("eighteen");
|
|
||||||
break;
|
|
||||||
case 19:
|
|
||||||
result.Append("nineteen");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string FixJsonWithoutAI(string aiResponse)
|
|
||||||
{
|
|
||||||
if (aiResponse.StartsWith("```"))
|
|
||||||
{
|
|
||||||
|
|
||||||
//Console.WriteLine("FIXING ``` in AI Response.");
|
|
||||||
aiResponse = aiResponse.Substring(3);
|
|
||||||
if (aiResponse.StartsWith("json"))
|
|
||||||
{
|
|
||||||
aiResponse = aiResponse.Substring(4);
|
|
||||||
}
|
|
||||||
if (aiResponse.StartsWith("html"))
|
|
||||||
{
|
|
||||||
aiResponse = aiResponse.Substring(4);
|
|
||||||
}
|
|
||||||
aiResponse = aiResponse.Substring(0, aiResponse.Length - 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return aiResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string RemoveTabs(string text)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(text)) return text;
|
|
||||||
return text.Replace("\t", ""); // Simple replace — remove all tab characters
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace BLAIzor.Helpers
|
|
||||||
{
|
|
||||||
|
|
||||||
public static class VectorHashHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Computes a SHA-256 hash for a float vector and returns it as a Base64 string.
|
|
||||||
/// </summary>
|
|
||||||
public static string ComputeVectorHash(float[] vector)
|
|
||||||
{
|
|
||||||
if (vector == null || vector.Length == 0)
|
|
||||||
throw new ArgumentException("Vector cannot be null or empty.");
|
|
||||||
|
|
||||||
// Convert float array to byte array
|
|
||||||
byte[] byteArray = new byte[vector.Length * sizeof(float)];
|
|
||||||
Buffer.BlockCopy(vector, 0, byteArray, 0, byteArray.Length);
|
|
||||||
|
|
||||||
using (var sha = SHA256.Create())
|
|
||||||
{
|
|
||||||
byte[] hashBytes = sha.ComputeHash(byteArray);
|
|
||||||
return Convert.ToBase64String(hashBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compares two float vectors by computing and comparing their SHA-256 hashes.
|
|
||||||
/// </summary>
|
|
||||||
public static bool AreVectorsEqual(float[] vector1, float[] vector2)
|
|
||||||
{
|
|
||||||
if (vector1 == null || vector2 == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (vector1.Length != vector2.Length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
string hash1 = ComputeVectorHash(vector1);
|
|
||||||
string hash2 = ComputeVectorHash(vector2);
|
|
||||||
|
|
||||||
return hash1 == hash2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
namespace BLAIzor.Interfaces
|
|
||||||
{
|
|
||||||
public interface IBrightDataService
|
|
||||||
{
|
|
||||||
Task<string?> ScrapeFacebookPostsAsync(string pageUrl, int numPosts = 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,637 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20250602055410_addVoiceInformation")]
|
|
||||||
partial class addVoiceInformation
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.3")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("CssContent")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("DesignTemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DesignTemplateId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("CssTemplates");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsDeprecated")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPrivate")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("QDrandCollectionName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Status")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplateName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplatePhotoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("UpdatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("DesignTemplates");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Description = "The default template",
|
|
||||||
IsDeprecated = false,
|
|
||||||
IsPrivate = false,
|
|
||||||
IsPublished = false,
|
|
||||||
QDrandCollectionName = "html_snippets",
|
|
||||||
Status = "Draft",
|
|
||||||
Tags = "system",
|
|
||||||
TemplateName = "Default Site",
|
|
||||||
TemplatePhotoUrl = "/images/default-logo.png",
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
Version = 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("JsonDefinition")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId", "Slug")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("FormDefinitions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("PointId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<Guid?>("QdrantPointId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SiteDescription")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("SiteName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TTSActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int?>("TemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("voiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("SiteInfos");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
BrandLogoUrl = "/images/default-logo.png",
|
|
||||||
DefaultColor = "#FFFFFF",
|
|
||||||
DefaultUrl = "https://ai.poppixel.cloud",
|
|
||||||
DomainUrl = "poppixel.cloud",
|
|
||||||
IsPublished = false,
|
|
||||||
STTActive = false,
|
|
||||||
SiteName = "Default Site",
|
|
||||||
TTSActive = false,
|
|
||||||
TemplateId = 1,
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
AccessFailedCount = 0,
|
|
||||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
|
||||||
Email = "adam.g@aycode.com",
|
|
||||||
EmailConfirmed = true,
|
|
||||||
LockoutEnabled = false,
|
|
||||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
|
||||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
|
||||||
PhoneNumberConfirmed = false,
|
|
||||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
|
||||||
TwoFactorEnabled = false,
|
|
||||||
UserName = "adam.g@aycode.com"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
|
||||||
.WithOne("CssTemplate")
|
|
||||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("DesignTemplate");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("FormDefinitions")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("MenuItems")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
|
||||||
.WithMany("Sites")
|
|
||||||
.HasForeignKey("TemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Template");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("CssTemplate")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Sites");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("FormDefinitions");
|
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class addVoiceInformation : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "Entity",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "Persona",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "voiceId",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.UpdateData(
|
|
||||||
table: "SiteInfos",
|
|
||||||
keyColumn: "Id",
|
|
||||||
keyValue: 1,
|
|
||||||
columns: new[] { "Entity", "Persona", "voiceId" },
|
|
||||||
values: new object[] { null, null, null });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "Entity",
|
|
||||||
table: "SiteInfos");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "Persona",
|
|
||||||
table: "SiteInfos");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "voiceId",
|
|
||||||
table: "SiteInfos");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,645 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20250615203806_EmbeddingServiceAndDefaultLanguage")]
|
|
||||||
partial class EmbeddingServiceAndDefaultLanguage
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.3")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("CssContent")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("DesignTemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DesignTemplateId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("CssTemplates");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsDeprecated")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPrivate")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("QDrandCollectionName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Status")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplateName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplatePhotoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("UpdatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("DesignTemplates");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Description = "The default template",
|
|
||||||
IsDeprecated = false,
|
|
||||||
IsPrivate = false,
|
|
||||||
IsPublished = false,
|
|
||||||
QDrandCollectionName = "html_snippets",
|
|
||||||
Status = "Draft",
|
|
||||||
Tags = "system",
|
|
||||||
TemplateName = "Default Site",
|
|
||||||
TemplatePhotoUrl = "/images/default-logo.png",
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
Version = 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("JsonDefinition")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId", "Slug")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("FormDefinitions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("PointId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<Guid?>("QdrantPointId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("BackgroundVideo")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultLanguage")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingService")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SiteDescription")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("SiteName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TTSActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int?>("TemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("VoiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("SiteInfos");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
BrandLogoUrl = "/images/default-logo.png",
|
|
||||||
DefaultColor = "#FFFFFF",
|
|
||||||
DefaultUrl = "https://ai.poppixel.cloud",
|
|
||||||
DomainUrl = "poppixel.cloud",
|
|
||||||
IsPublished = false,
|
|
||||||
STTActive = false,
|
|
||||||
SiteName = "Default Site",
|
|
||||||
TTSActive = false,
|
|
||||||
TemplateId = 1,
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
AccessFailedCount = 0,
|
|
||||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
|
||||||
Email = "adam.g@aycode.com",
|
|
||||||
EmailConfirmed = true,
|
|
||||||
LockoutEnabled = false,
|
|
||||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
|
||||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
|
||||||
PhoneNumberConfirmed = false,
|
|
||||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
|
||||||
TwoFactorEnabled = false,
|
|
||||||
UserName = "adam.g@aycode.com"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
|
||||||
.WithOne("CssTemplate")
|
|
||||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("DesignTemplate");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("FormDefinitions")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("MenuItems")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
|
||||||
.WithMany("Sites")
|
|
||||||
.HasForeignKey("TemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Template");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("CssTemplate")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Sites");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("FormDefinitions");
|
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class EmbeddingServiceAndDefaultLanguage : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.RenameColumn(
|
|
||||||
name: "voiceId",
|
|
||||||
table: "SiteInfos",
|
|
||||||
newName: "VoiceId");
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "BackgroundVideo",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "DefaultLanguage",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "EmbeddingService",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<string>(
|
|
||||||
name: "StoredHtml",
|
|
||||||
table: "MenuItems",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(string),
|
|
||||||
oldType: "nvarchar(max)");
|
|
||||||
|
|
||||||
migrationBuilder.UpdateData(
|
|
||||||
table: "SiteInfos",
|
|
||||||
keyColumn: "Id",
|
|
||||||
keyValue: 1,
|
|
||||||
columns: new[] { "BackgroundVideo", "DefaultLanguage", "EmbeddingService" },
|
|
||||||
values: new object[] { null, null, null });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "BackgroundVideo",
|
|
||||||
table: "SiteInfos");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "DefaultLanguage",
|
|
||||||
table: "SiteInfos");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "EmbeddingService",
|
|
||||||
table: "SiteInfos");
|
|
||||||
|
|
||||||
migrationBuilder.RenameColumn(
|
|
||||||
name: "VoiceId",
|
|
||||||
table: "SiteInfos",
|
|
||||||
newName: "voiceId");
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<string>(
|
|
||||||
name: "StoredHtml",
|
|
||||||
table: "MenuItems",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: "",
|
|
||||||
oldClrType: typeof(string),
|
|
||||||
oldType: "nvarchar(max)",
|
|
||||||
oldNullable: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,841 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20250617221435_CollectionAdministrationUpdate")]
|
|
||||||
partial class CollectionAdministrationUpdate
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.3")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("ChunkIndex")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("QdrantPointId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.ToTable("ContentChunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingModel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("VectorSize")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("ContentGroups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Language")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.ToTable("ContentItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("CssContent")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("DesignTemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DesignTemplateId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("CssTemplates");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsDeprecated")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPrivate")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("QDrandCollectionName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Status")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplateName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplatePhotoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("UpdatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("DesignTemplates");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Description = "The default template",
|
|
||||||
IsDeprecated = false,
|
|
||||||
IsPrivate = false,
|
|
||||||
IsPublished = false,
|
|
||||||
QDrandCollectionName = "html_snippets",
|
|
||||||
Status = "Draft",
|
|
||||||
Tags = "system",
|
|
||||||
TemplateName = "Default Site",
|
|
||||||
TemplatePhotoUrl = "/images/default-logo.png",
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
Version = 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("JsonDefinition")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId", "Slug")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("FormDefinitions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int?>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("ParentId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("BackgroundVideo")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultLanguage")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingService")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SiteDescription")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("SiteName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TTSActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int?>("TemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("VoiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("SiteInfos");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
BrandLogoUrl = "/images/default-logo.png",
|
|
||||||
DefaultColor = "#FFFFFF",
|
|
||||||
DefaultUrl = "https://ai.poppixel.cloud",
|
|
||||||
DomainUrl = "poppixel.cloud",
|
|
||||||
IsPublished = false,
|
|
||||||
STTActive = false,
|
|
||||||
SiteName = "Default Site",
|
|
||||||
TTSActive = false,
|
|
||||||
TemplateId = 1,
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
AccessFailedCount = 0,
|
|
||||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
|
||||||
Email = "adam.g@aycode.com",
|
|
||||||
EmailConfirmed = true,
|
|
||||||
LockoutEnabled = false,
|
|
||||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
|
||||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
|
||||||
PhoneNumberConfirmed = false,
|
|
||||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
|
||||||
TwoFactorEnabled = false,
|
|
||||||
UserName = "adam.g@aycode.com"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany("Chunks")
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany("Items")
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
|
||||||
.WithOne("CssTemplate")
|
|
||||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("DesignTemplate");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("FormDefinitions")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.MenuItem", "Parent")
|
|
||||||
.WithMany("Children")
|
|
||||||
.HasForeignKey("ParentId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("MenuItems")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
|
|
||||||
b.Navigation("Parent");
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
|
||||||
.WithMany("Sites")
|
|
||||||
.HasForeignKey("TemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Template");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Items");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Chunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("CssTemplate")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Sites");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Children");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("FormDefinitions");
|
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,214 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class CollectionAdministrationUpdate : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "PointId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "QdrantPointId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "ContentGroupId",
|
|
||||||
table: "MenuItems",
|
|
||||||
type: "int",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "ParentId",
|
|
||||||
table: "MenuItems",
|
|
||||||
type: "int",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "Slug",
|
|
||||||
table: "MenuItems",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "ContentGroups",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
SiteInfoId = table.Column<int>(type: "int", nullable: false),
|
|
||||||
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
Slug = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
Type = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
VectorSize = table.Column<int>(type: "int", nullable: false),
|
|
||||||
EmbeddingModel = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
Version = table.Column<int>(type: "int", nullable: false),
|
|
||||||
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false),
|
|
||||||
LastUpdated = table.Column<DateTime>(type: "datetime2", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_ContentGroups", x => x.Id);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_ContentGroups_SiteInfos_SiteInfoId",
|
|
||||||
column: x => x.SiteInfoId,
|
|
||||||
principalTable: "SiteInfos",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "ContentItems",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
ContentGroupId = table.Column<int>(type: "int", nullable: false),
|
|
||||||
Title = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
Description = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
Content = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
Language = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
Tags = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
IsPublished = table.Column<bool>(type: "bit", nullable: false),
|
|
||||||
Version = table.Column<int>(type: "int", nullable: false),
|
|
||||||
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false),
|
|
||||||
LastUpdated = table.Column<DateTime>(type: "datetime2", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_ContentItems", x => x.Id);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_ContentItems_ContentGroups_ContentGroupId",
|
|
||||||
column: x => x.ContentGroupId,
|
|
||||||
principalTable: "ContentGroups",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "ContentChunks",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
ContentItemId = table.Column<int>(type: "int", nullable: false),
|
|
||||||
QdrantPointId = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
ChunkIndex = table.Column<int>(type: "int", nullable: false),
|
|
||||||
VectorHash = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
|
||||||
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_ContentChunks", x => x.Id);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_ContentChunks_ContentItems_ContentItemId",
|
|
||||||
column: x => x.ContentItemId,
|
|
||||||
principalTable: "ContentItems",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_MenuItems_ContentGroupId",
|
|
||||||
table: "MenuItems",
|
|
||||||
column: "ContentGroupId");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_MenuItems_ParentId",
|
|
||||||
table: "MenuItems",
|
|
||||||
column: "ParentId");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_ContentChunks_ContentItemId",
|
|
||||||
table: "ContentChunks",
|
|
||||||
column: "ContentItemId");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_ContentGroups_SiteInfoId",
|
|
||||||
table: "ContentGroups",
|
|
||||||
column: "SiteInfoId");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_ContentItems_ContentGroupId",
|
|
||||||
table: "ContentItems",
|
|
||||||
column: "ContentGroupId");
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_MenuItems_ContentGroups_ContentGroupId",
|
|
||||||
table: "MenuItems",
|
|
||||||
column: "ContentGroupId",
|
|
||||||
principalTable: "ContentGroups",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.NoAction);
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_MenuItems_MenuItems_ParentId",
|
|
||||||
table: "MenuItems",
|
|
||||||
column: "ParentId",
|
|
||||||
principalTable: "MenuItems",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Restrict);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_MenuItems_ContentGroups_ContentGroupId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_MenuItems_MenuItems_ParentId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "ContentChunks");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "ContentItems");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "ContentGroups");
|
|
||||||
|
|
||||||
migrationBuilder.DropIndex(
|
|
||||||
name: "IX_MenuItems_ContentGroupId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.DropIndex(
|
|
||||||
name: "IX_MenuItems_ParentId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "ContentGroupId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "ParentId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "Slug",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "PointId",
|
|
||||||
table: "MenuItems",
|
|
||||||
type: "int",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<Guid>(
|
|
||||||
name: "QdrantPointId",
|
|
||||||
table: "MenuItems",
|
|
||||||
type: "uniqueidentifier",
|
|
||||||
nullable: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,841 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20250617224307_CollectionAdministrationUpdateFIX")]
|
|
||||||
partial class CollectionAdministrationUpdateFIX
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.3")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("ChunkIndex")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("QdrantPointId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.ToTable("ContentChunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingModel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("VectorSize")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("ContentGroups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Language")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.ToTable("ContentItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("CssContent")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("DesignTemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DesignTemplateId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("CssTemplates");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsDeprecated")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPrivate")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("QDrandCollectionName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Status")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplateName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplatePhotoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("UpdatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("DesignTemplates");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Description = "The default template",
|
|
||||||
IsDeprecated = false,
|
|
||||||
IsPrivate = false,
|
|
||||||
IsPublished = false,
|
|
||||||
QDrandCollectionName = "html_snippets",
|
|
||||||
Status = "Draft",
|
|
||||||
Tags = "system",
|
|
||||||
TemplateName = "Default Site",
|
|
||||||
TemplatePhotoUrl = "/images/default-logo.png",
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
Version = 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("JsonDefinition")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId", "Slug")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("FormDefinitions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int?>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("ParentId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("BackgroundVideo")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultLanguage")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingService")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SiteDescription")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("SiteName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TTSActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int?>("TemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("VoiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("SiteInfos");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
BrandLogoUrl = "/images/default-logo.png",
|
|
||||||
DefaultColor = "#FFFFFF",
|
|
||||||
DefaultUrl = "https://ai.poppixel.cloud",
|
|
||||||
DomainUrl = "poppixel.cloud",
|
|
||||||
IsPublished = false,
|
|
||||||
STTActive = false,
|
|
||||||
SiteName = "Default Site",
|
|
||||||
TTSActive = false,
|
|
||||||
TemplateId = 1,
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
AccessFailedCount = 0,
|
|
||||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
|
||||||
Email = "adam.g@aycode.com",
|
|
||||||
EmailConfirmed = true,
|
|
||||||
LockoutEnabled = false,
|
|
||||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
|
||||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
|
||||||
PhoneNumberConfirmed = false,
|
|
||||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
|
||||||
TwoFactorEnabled = false,
|
|
||||||
UserName = "adam.g@aycode.com"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany("Chunks")
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany("Items")
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
|
||||||
.WithOne("CssTemplate")
|
|
||||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("DesignTemplate");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("FormDefinitions")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.MenuItem", "Parent")
|
|
||||||
.WithMany("Children")
|
|
||||||
.HasForeignKey("ParentId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("MenuItems")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
|
|
||||||
b.Navigation("Parent");
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
|
||||||
.WithMany("Sites")
|
|
||||||
.HasForeignKey("TemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Template");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Items");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Chunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("CssTemplate")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Sites");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Children");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("FormDefinitions");
|
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class CollectionAdministrationUpdateFIX : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_MenuItems_ContentGroups_ContentGroupId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_MenuItems_ContentGroups_ContentGroupId",
|
|
||||||
table: "MenuItems",
|
|
||||||
column: "ContentGroupId",
|
|
||||||
principalTable: "ContentGroups",
|
|
||||||
principalColumn: "Id");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_MenuItems_ContentGroups_ContentGroupId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_MenuItems_ContentGroups_ContentGroupId",
|
|
||||||
table: "MenuItems",
|
|
||||||
column: "ContentGroupId",
|
|
||||||
principalTable: "ContentGroups",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.NoAction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,855 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20250618105221_CollectionAdministrationUpdate2")]
|
|
||||||
partial class CollectionAdministrationUpdate2
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.3")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("ChunkIndex")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("QdrantPointId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.ToTable("ContentChunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingModel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("VectorSize")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("ContentGroups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Language")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.ToTable("ContentItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("CssContent")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("DesignTemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DesignTemplateId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("CssTemplates");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsDeprecated")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPrivate")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("QDrandCollectionName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Status")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplateName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplatePhotoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("UpdatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("DesignTemplates");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Description = "The default template",
|
|
||||||
IsDeprecated = false,
|
|
||||||
IsPrivate = false,
|
|
||||||
IsPublished = false,
|
|
||||||
QDrandCollectionName = "html_snippets",
|
|
||||||
Status = "Draft",
|
|
||||||
Tags = "system",
|
|
||||||
TemplateName = "Default Site",
|
|
||||||
TemplatePhotoUrl = "/images/default-logo.png",
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
Version = 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("JsonDefinition")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId", "Slug")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("FormDefinitions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int?>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("ParentId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("BackgroundVideo")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultLanguage")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingService")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SiteDescription")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("SiteName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TTSActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int?>("TemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("VoiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("SiteInfos");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
BrandLogoUrl = "/images/default-logo.png",
|
|
||||||
DefaultColor = "#FFFFFF",
|
|
||||||
DefaultUrl = "https://ai.poppixel.cloud",
|
|
||||||
DomainUrl = "poppixel.cloud",
|
|
||||||
IsPublished = false,
|
|
||||||
STTActive = false,
|
|
||||||
SiteName = "Default Site",
|
|
||||||
TTSActive = false,
|
|
||||||
TemplateId = 1,
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
AccessFailedCount = 0,
|
|
||||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
|
||||||
Email = "adam.g@aycode.com",
|
|
||||||
EmailConfirmed = true,
|
|
||||||
LockoutEnabled = false,
|
|
||||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
|
||||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
|
||||||
PhoneNumberConfirmed = false,
|
|
||||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
|
||||||
TwoFactorEnabled = false,
|
|
||||||
UserName = "adam.g@aycode.com"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany("Chunks")
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("ContentGroups")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany("Items")
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
|
||||||
.WithOne("CssTemplate")
|
|
||||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("DesignTemplate");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("FormDefinitions")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.MenuItem", "Parent")
|
|
||||||
.WithMany("Children")
|
|
||||||
.HasForeignKey("ParentId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("MenuItems")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
|
|
||||||
b.Navigation("Parent");
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
|
||||||
.WithMany("Sites")
|
|
||||||
.HasForeignKey("TemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Template");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Items");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Chunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("CssTemplate")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Sites");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Children");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("ContentGroups");
|
|
||||||
|
|
||||||
b.Navigation("FormDefinitions");
|
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class CollectionAdministrationUpdate2 : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "ContentItemId",
|
|
||||||
table: "MenuItems",
|
|
||||||
type: "int",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_MenuItems_ContentItemId",
|
|
||||||
table: "MenuItems",
|
|
||||||
column: "ContentItemId");
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_MenuItems_ContentItems_ContentItemId",
|
|
||||||
table: "MenuItems",
|
|
||||||
column: "ContentItemId",
|
|
||||||
principalTable: "ContentItems",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Restrict);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_MenuItems_ContentItems_ContentItemId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.DropIndex(
|
|
||||||
name: "IX_MenuItems_ContentItemId",
|
|
||||||
table: "MenuItems");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "ContentItemId",
|
|
||||||
table: "MenuItems");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,858 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20250625185236_StoredCollectionName")]
|
|
||||||
partial class StoredCollectionName
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.3")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("ChunkIndex")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("QdrantPointId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.ToTable("ContentChunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingModel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("VectorSize")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("ContentGroups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Language")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.ToTable("ContentItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("CssContent")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("DesignTemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DesignTemplateId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("CssTemplates");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsDeprecated")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPrivate")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("QDrandCollectionName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Status")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplateName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplatePhotoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("UpdatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("DesignTemplates");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Description = "The default template",
|
|
||||||
IsDeprecated = false,
|
|
||||||
IsPrivate = false,
|
|
||||||
IsPublished = false,
|
|
||||||
QDrandCollectionName = "html_snippets",
|
|
||||||
Status = "Draft",
|
|
||||||
Tags = "system",
|
|
||||||
TemplateName = "Default Site",
|
|
||||||
TemplatePhotoUrl = "/images/default-logo.png",
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
Version = 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("JsonDefinition")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId", "Slug")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("FormDefinitions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int?>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("ParentId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("BackgroundVideo")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultLanguage")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingService")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SiteDescription")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("SiteName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TTSActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int?>("TemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorCollectionName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VoiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("SiteInfos");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
BrandLogoUrl = "/images/default-logo.png",
|
|
||||||
DefaultColor = "#FFFFFF",
|
|
||||||
DefaultUrl = "https://ai.poppixel.cloud",
|
|
||||||
DomainUrl = "poppixel.cloud",
|
|
||||||
IsPublished = false,
|
|
||||||
STTActive = false,
|
|
||||||
SiteName = "Default Site",
|
|
||||||
TTSActive = false,
|
|
||||||
TemplateId = 1,
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
AccessFailedCount = 0,
|
|
||||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
|
||||||
Email = "adam.g@aycode.com",
|
|
||||||
EmailConfirmed = true,
|
|
||||||
LockoutEnabled = false,
|
|
||||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
|
||||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
|
||||||
PhoneNumberConfirmed = false,
|
|
||||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
|
||||||
TwoFactorEnabled = false,
|
|
||||||
UserName = "adam.g@aycode.com"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany("Chunks")
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("ContentGroups")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany("Items")
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
|
||||||
.WithOne("CssTemplate")
|
|
||||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("DesignTemplate");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("FormDefinitions")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.MenuItem", "Parent")
|
|
||||||
.WithMany("Children")
|
|
||||||
.HasForeignKey("ParentId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("MenuItems")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
|
|
||||||
b.Navigation("Parent");
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
|
||||||
.WithMany("Sites")
|
|
||||||
.HasForeignKey("TemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Template");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Items");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Chunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("CssTemplate")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Sites");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Children");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("ContentGroups");
|
|
||||||
|
|
||||||
b.Navigation("FormDefinitions");
|
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class StoredCollectionName : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "VectorCollectionName",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.UpdateData(
|
|
||||||
table: "SiteInfos",
|
|
||||||
keyColumn: "Id",
|
|
||||||
keyValue: 1,
|
|
||||||
column: "VectorCollectionName",
|
|
||||||
value: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "VectorCollectionName",
|
|
||||||
table: "SiteInfos");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,885 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20250628191216_logger")]
|
|
||||||
partial class logger
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.3")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.AppLog", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Details")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Message")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Severity")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Timestamp")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Logs");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("ChunkIndex")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("QdrantPointId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.ToTable("ContentChunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingModel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("VectorSize")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("ContentGroups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Language")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.ToTable("ContentItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("CssContent")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("DesignTemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DesignTemplateId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("CssTemplates");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsDeprecated")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPrivate")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("QDrandCollectionName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Status")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplateName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplatePhotoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("UpdatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("DesignTemplates");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Description = "The default template",
|
|
||||||
IsDeprecated = false,
|
|
||||||
IsPrivate = false,
|
|
||||||
IsPublished = false,
|
|
||||||
QDrandCollectionName = "html_snippets",
|
|
||||||
Status = "Draft",
|
|
||||||
Tags = "system",
|
|
||||||
TemplateName = "Default Site",
|
|
||||||
TemplatePhotoUrl = "/images/default-logo.png",
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
Version = 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("JsonDefinition")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId", "Slug")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("FormDefinitions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int?>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("ParentId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("BackgroundVideo")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultLanguage")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingService")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SiteDescription")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("SiteName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TTSActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int?>("TemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorCollectionName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VoiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("SiteInfos");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
BrandLogoUrl = "/images/default-logo.png",
|
|
||||||
DefaultColor = "#FFFFFF",
|
|
||||||
DefaultUrl = "https://ai.poppixel.cloud",
|
|
||||||
DomainUrl = "poppixel.cloud",
|
|
||||||
IsPublished = false,
|
|
||||||
STTActive = false,
|
|
||||||
SiteName = "Default Site",
|
|
||||||
TTSActive = false,
|
|
||||||
TemplateId = 1,
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
AccessFailedCount = 0,
|
|
||||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
|
||||||
Email = "adam.g@aycode.com",
|
|
||||||
EmailConfirmed = true,
|
|
||||||
LockoutEnabled = false,
|
|
||||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
|
||||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
|
||||||
PhoneNumberConfirmed = false,
|
|
||||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
|
||||||
TwoFactorEnabled = false,
|
|
||||||
UserName = "adam.g@aycode.com"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany("Chunks")
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("ContentGroups")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany("Items")
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
|
||||||
.WithOne("CssTemplate")
|
|
||||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("DesignTemplate");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("FormDefinitions")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.MenuItem", "Parent")
|
|
||||||
.WithMany("Children")
|
|
||||||
.HasForeignKey("ParentId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("MenuItems")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
|
|
||||||
b.Navigation("Parent");
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
|
||||||
.WithMany("Sites")
|
|
||||||
.HasForeignKey("TemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Template");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Items");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Chunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("CssTemplate")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Sites");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Children");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("ContentGroups");
|
|
||||||
|
|
||||||
b.Navigation("FormDefinitions");
|
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class logger : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "Logs",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
Timestamp = table.Column<DateTime>(type: "datetime2", nullable: false),
|
|
||||||
Severity = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
Message = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
Details = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_Logs", x => x.Id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "Logs");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,884 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20250717145336_domainurl_nullable")]
|
|
||||||
partial class domainurl_nullable
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.3")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.AppLog", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Details")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Message")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Severity")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Timestamp")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Logs");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("ChunkIndex")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("QdrantPointId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.ToTable("ContentChunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingModel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("VectorSize")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("ContentGroups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Language")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.ToTable("ContentItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("CssContent")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("DesignTemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DesignTemplateId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("CssTemplates");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsDeprecated")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPrivate")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("QDrandCollectionName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Status")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplateName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplatePhotoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("UpdatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("DesignTemplates");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Description = "The default template",
|
|
||||||
IsDeprecated = false,
|
|
||||||
IsPrivate = false,
|
|
||||||
IsPublished = false,
|
|
||||||
QDrandCollectionName = "html_snippets",
|
|
||||||
Status = "Draft",
|
|
||||||
Tags = "system",
|
|
||||||
TemplateName = "Default Site",
|
|
||||||
TemplatePhotoUrl = "/images/default-logo.png",
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
Version = 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("JsonDefinition")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId", "Slug")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("FormDefinitions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int?>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("ParentId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("BackgroundVideo")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultLanguage")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingService")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SiteDescription")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("SiteName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TTSActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int?>("TemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorCollectionName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VoiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("SiteInfos");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
BrandLogoUrl = "/images/default-logo.png",
|
|
||||||
DefaultColor = "#FFFFFF",
|
|
||||||
DefaultUrl = "https://ai.poppixel.cloud",
|
|
||||||
DomainUrl = "poppixel.cloud",
|
|
||||||
IsPublished = false,
|
|
||||||
STTActive = false,
|
|
||||||
SiteName = "Default Site",
|
|
||||||
TTSActive = false,
|
|
||||||
TemplateId = 1,
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
AccessFailedCount = 0,
|
|
||||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
|
||||||
Email = "adam.g@aycode.com",
|
|
||||||
EmailConfirmed = true,
|
|
||||||
LockoutEnabled = false,
|
|
||||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
|
||||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
|
||||||
PhoneNumberConfirmed = false,
|
|
||||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
|
||||||
TwoFactorEnabled = false,
|
|
||||||
UserName = "adam.g@aycode.com"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany("Chunks")
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("ContentGroups")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany("Items")
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
|
||||||
.WithOne("CssTemplate")
|
|
||||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("DesignTemplate");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("FormDefinitions")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.MenuItem", "Parent")
|
|
||||||
.WithMany("Children")
|
|
||||||
.HasForeignKey("ParentId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("MenuItems")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
|
|
||||||
b.Navigation("Parent");
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
|
||||||
.WithMany("Sites")
|
|
||||||
.HasForeignKey("TemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Template");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Items");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Chunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("CssTemplate")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Sites");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Children");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("ContentGroups");
|
|
||||||
|
|
||||||
b.Navigation("FormDefinitions");
|
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class domainurl_nullable : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AlterColumn<string>(
|
|
||||||
name: "DomainUrl",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(string),
|
|
||||||
oldType: "nvarchar(max)");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AlterColumn<string>(
|
|
||||||
name: "DomainUrl",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: "",
|
|
||||||
oldClrType: typeof(string),
|
|
||||||
oldType: "nvarchar(max)",
|
|
||||||
oldNullable: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,893 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20250814214748_social_links")]
|
|
||||||
partial class social_links
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.3")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.AppLog", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Details")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Message")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Severity")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Timestamp")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Logs");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("ChunkIndex")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("QdrantPointId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.ToTable("ContentChunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingModel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("VectorSize")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("ContentGroups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Language")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.ToTable("ContentItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("CssContent")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("DesignTemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DesignTemplateId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("CssTemplates");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsDeprecated")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPrivate")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("QDrandCollectionName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Status")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplateName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplatePhotoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("UpdatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("DesignTemplates");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Description = "The default template",
|
|
||||||
IsDeprecated = false,
|
|
||||||
IsPrivate = false,
|
|
||||||
IsPublished = false,
|
|
||||||
QDrandCollectionName = "html_snippets",
|
|
||||||
Status = "Draft",
|
|
||||||
Tags = "system",
|
|
||||||
TemplateName = "Default Site",
|
|
||||||
TemplatePhotoUrl = "/images/default-logo.png",
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
Version = 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("JsonDefinition")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId", "Slug")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("FormDefinitions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int?>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("ParentId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("BackgroundVideo")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultLanguage")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingService")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("FacebookUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("InstagramUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SiteDescription")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("SiteName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TTSActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int?>("TemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("TwitterUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorCollectionName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VoiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("SiteInfos");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
BrandLogoUrl = "/images/default-logo.png",
|
|
||||||
DefaultColor = "#FFFFFF",
|
|
||||||
DefaultUrl = "https://ai.poppixel.cloud",
|
|
||||||
DomainUrl = "poppixel.cloud",
|
|
||||||
IsPublished = false,
|
|
||||||
STTActive = false,
|
|
||||||
SiteName = "Default Site",
|
|
||||||
TTSActive = false,
|
|
||||||
TemplateId = 1,
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
AccessFailedCount = 0,
|
|
||||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
|
||||||
Email = "adam.g@aycode.com",
|
|
||||||
EmailConfirmed = true,
|
|
||||||
LockoutEnabled = false,
|
|
||||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
|
||||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
|
||||||
PhoneNumberConfirmed = false,
|
|
||||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
|
||||||
TwoFactorEnabled = false,
|
|
||||||
UserName = "adam.g@aycode.com"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany("Chunks")
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("ContentGroups")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany("Items")
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
|
||||||
.WithOne("CssTemplate")
|
|
||||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("DesignTemplate");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("FormDefinitions")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.MenuItem", "Parent")
|
|
||||||
.WithMany("Children")
|
|
||||||
.HasForeignKey("ParentId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("MenuItems")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
|
|
||||||
b.Navigation("Parent");
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
|
||||||
.WithMany("Sites")
|
|
||||||
.HasForeignKey("TemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Template");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Items");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Chunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("CssTemplate")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Sites");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Children");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("ContentGroups");
|
|
||||||
|
|
||||||
b.Navigation("FormDefinitions");
|
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class social_links : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "FacebookUrl",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "InstagramUrl",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "TwitterUrl",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.UpdateData(
|
|
||||||
table: "SiteInfos",
|
|
||||||
keyColumn: "Id",
|
|
||||||
keyValue: 1,
|
|
||||||
columns: new[] { "FacebookUrl", "InstagramUrl", "TwitterUrl" },
|
|
||||||
values: new object[] { null, null, null });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "FacebookUrl",
|
|
||||||
table: "SiteInfos");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "InstagramUrl",
|
|
||||||
table: "SiteInfos");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "TwitterUrl",
|
|
||||||
table: "SiteInfos");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,896 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20250816221528_siteinfo_designstyle")]
|
|
||||||
partial class siteinfo_designstyle
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.3")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.AppLog", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Details")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Message")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Severity")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Timestamp")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Logs");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("ChunkIndex")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("QdrantPointId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.ToTable("ContentChunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingModel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("VectorSize")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("ContentGroups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Language")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.ToTable("ContentItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("CssContent")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("DesignTemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DesignTemplateId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("CssTemplates");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsDeprecated")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPrivate")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("QDrandCollectionName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Status")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplateName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("TemplatePhotoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("UpdatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("DesignTemplates");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Description = "The default template",
|
|
||||||
IsDeprecated = false,
|
|
||||||
IsPrivate = false,
|
|
||||||
IsPublished = false,
|
|
||||||
QDrandCollectionName = "html_snippets",
|
|
||||||
Status = "Draft",
|
|
||||||
Tags = "system",
|
|
||||||
TemplateName = "Default Site",
|
|
||||||
TemplatePhotoUrl = "/images/default-logo.png",
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
Version = 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("JsonDefinition")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(100)
|
|
||||||
.HasColumnType("nvarchar(100)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId", "Slug")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("FormDefinitions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int?>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("ParentId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("BackgroundVideo")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultLanguage")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DesignStyle")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingService")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("FacebookUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("InstagramUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SiteDescription")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("SiteName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TTSActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int?>("TemplateId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("TwitterUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorCollectionName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VoiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("SiteInfos");
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = 1,
|
|
||||||
BrandLogoUrl = "/images/default-logo.png",
|
|
||||||
DefaultColor = "#FFFFFF",
|
|
||||||
DefaultUrl = "https://ai.poppixel.cloud",
|
|
||||||
DomainUrl = "poppixel.cloud",
|
|
||||||
IsPublished = false,
|
|
||||||
STTActive = false,
|
|
||||||
SiteName = "Default Site",
|
|
||||||
TTSActive = false,
|
|
||||||
TemplateId = 1,
|
|
||||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
|
||||||
|
|
||||||
b.HasData(
|
|
||||||
new
|
|
||||||
{
|
|
||||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
|
||||||
AccessFailedCount = 0,
|
|
||||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
|
||||||
Email = "adam.g@aycode.com",
|
|
||||||
EmailConfirmed = true,
|
|
||||||
LockoutEnabled = false,
|
|
||||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
|
||||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
|
||||||
PhoneNumberConfirmed = false,
|
|
||||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
|
||||||
TwoFactorEnabled = false,
|
|
||||||
UserName = "adam.g@aycode.com"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("RoleId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("UserId")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany("Chunks")
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("ContentGroups")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany("Items")
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
|
||||||
.WithOne("CssTemplate")
|
|
||||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("DesignTemplate");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("FormDefinitions")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.MenuItem", "Parent")
|
|
||||||
.WithMany("Children")
|
|
||||||
.HasForeignKey("ParentId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("MenuItems")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
|
|
||||||
b.Navigation("Parent");
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
|
||||||
.WithMany("Sites")
|
|
||||||
.HasForeignKey("TemplateId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Template");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Items");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Chunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("CssTemplate")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Sites");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Children");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("ContentGroups");
|
|
||||||
|
|
||||||
b.Navigation("FormDefinitions");
|
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace BLAIzor.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class siteinfo_designstyle : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "DesignStyle",
|
|
||||||
table: "SiteInfos",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.UpdateData(
|
|
||||||
table: "SiteInfos",
|
|
||||||
keyColumn: "Id",
|
|
||||||
keyValue: 1,
|
|
||||||
column: "DesignStyle",
|
|
||||||
value: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "DesignStyle",
|
|
||||||
table: "SiteInfos");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -22,160 +22,6 @@ namespace BLAIzor.Migrations
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.AppLog", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Details")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Message")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Severity")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Timestamp")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Logs");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("ChunkIndex")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("QdrantPointId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VectorHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.ToTable("ContentChunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("EmbeddingModel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("VectorSize")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
|
||||||
|
|
||||||
b.ToTable("ContentGroups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Language")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("LastUpdated")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<string>("Tags")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Version")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.ToTable("ContentItems");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
|
|
@ -327,42 +173,31 @@ namespace BLAIzor.Migrations
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<int?>("ContentGroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("ContentItemId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<int?>("ParentId")
|
b.Property<int>("PointId")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<Guid?>("QdrantPointId")
|
||||||
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<bool>("ShowInMainMenu")
|
b.Property<bool>("ShowInMainMenu")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("bit");
|
||||||
|
|
||||||
b.Property<int>("SiteInfoId")
|
b.Property<int>("SiteInfoId")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("Slug")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("SortOrder")
|
b.Property<int>("SortOrder")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
b.Property<string>("StoredHtml")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("ContentGroupId");
|
|
||||||
|
|
||||||
b.HasIndex("ContentItemId");
|
|
||||||
|
|
||||||
b.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b.HasIndex("SiteInfoId");
|
b.HasIndex("SiteInfoId");
|
||||||
|
|
||||||
b.ToTable("MenuItems");
|
b.ToTable("MenuItems");
|
||||||
|
|
@ -376,46 +211,23 @@ namespace BLAIzor.Migrations
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<string>("BackgroundVideo")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
b.Property<string>("BrandLogoUrl")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
b.Property<string>("DefaultColor")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("DefaultLanguage")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
b.Property<string>("DefaultUrl")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("DesignStyle")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("DomainUrl")
|
b.Property<string>("DomainUrl")
|
||||||
.HasColumnType("nvarchar(max)");
|
.IsRequired()
|
||||||
|
|
||||||
b.Property<string>("EmbeddingService")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("FacebookUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("InstagramUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<bool>("IsPublished")
|
b.Property<bool>("IsPublished")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("bit");
|
||||||
|
|
||||||
b.Property<string>("Persona")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("STTActive")
|
b.Property<bool>("STTActive")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
|
@ -431,19 +243,10 @@ namespace BLAIzor.Migrations
|
||||||
b.Property<int?>("TemplateId")
|
b.Property<int?>("TemplateId")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("TwitterUrl")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("UserId")
|
b.Property<string>("UserId")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(450)");
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
b.Property<string>("VectorCollectionName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("VoiceId")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("TemplateId");
|
b.HasIndex("TemplateId");
|
||||||
|
|
@ -689,39 +492,6 @@ namespace BLAIzor.Migrations
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
b.ToTable("AspNetUserTokens", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentChunk", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany("Chunks")
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
|
||||||
.WithMany("ContentGroups")
|
|
||||||
.HasForeignKey("SiteInfoId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany("Items")
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
||||||
|
|
@ -757,33 +527,12 @@ namespace BLAIzor.Migrations
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("BLAIzor.Models.ContentGroup", "ContentGroup")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentGroupId")
|
|
||||||
.OnDelete(DeleteBehavior.NoAction);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.ContentItem", "ContentItem")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentItemId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.MenuItem", "Parent")
|
|
||||||
.WithMany("Children")
|
|
||||||
.HasForeignKey("ParentId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
||||||
.WithMany("MenuItems")
|
.WithMany("MenuItems")
|
||||||
.HasForeignKey("SiteInfoId")
|
.HasForeignKey("SiteInfoId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("ContentGroup");
|
|
||||||
|
|
||||||
b.Navigation("ContentItem");
|
|
||||||
|
|
||||||
b.Navigation("Parent");
|
|
||||||
|
|
||||||
b.Navigation("SiteInfo");
|
b.Navigation("SiteInfo");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -856,16 +605,6 @@ namespace BLAIzor.Migrations
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentGroup", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Items");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.ContentItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Chunks");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("CssTemplate")
|
b.Navigation("CssTemplate")
|
||||||
|
|
@ -874,15 +613,8 @@ namespace BLAIzor.Migrations
|
||||||
b.Navigation("Sites");
|
b.Navigation("Sites");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Children");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("ContentGroups");
|
|
||||||
|
|
||||||
b.Navigation("FormDefinitions");
|
b.Navigation("FormDefinitions");
|
||||||
|
|
||||||
b.Navigation("MenuItems");
|
b.Navigation("MenuItems");
|
||||||
|
|
|
||||||
|
|
@ -1,358 +0,0 @@
|
||||||
using BLAIzor.Services;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public static class AiPrompts
|
|
||||||
{
|
|
||||||
public static class WelcomeContent
|
|
||||||
{
|
|
||||||
public static string GetSystemMessageForWelcomeMessage(string mood, string siteEntity, string extractedText, string selectedBrandName, string language, string menuList)
|
|
||||||
{
|
|
||||||
string systemMessage = "You are a helpful, " + mood + " assistant that welcomes the user speaking in the name of the " + siteEntity + " described by the content, on a website of " + selectedBrandName + " in " + language + ". Use the following content: `" +
|
|
||||||
extractedText + "` " +
|
|
||||||
//"and generate a short" +Mood+ "but kind marketing-oriented welcome message and introduction of the brand for the user, constructed as simple Bootstrap HTML codeblock with a <h1> tagged title and a paragraph." +
|
|
||||||
"and generate a" + mood + " marketing-oriented welcome message and a summary of the content and introduction " +
|
|
||||||
"of the brand for the user in the name of " + siteEntity + " , aiming to explain clearly, what does the company/person offer, constructed " +
|
|
||||||
"as simple Bootstrap HTML <div clss=\"container\"> codeblock with a <h1> tagged title and a paragraph." +
|
|
||||||
"If there is any logo, or not logo but main brand image in the document use that url, " +
|
|
||||||
"and add that in a new container, as a bootstrap responsive ('img-fluid py-3') image, with the maximum height of 30vh." +
|
|
||||||
"If there is anything marked important in the text, make sure to add that in your answer." +
|
|
||||||
"If there are links to be displayed, make sure to display them as clickable links." +
|
|
||||||
"After the welcome message, always add in a new div with container class: 'This website has a live, " +
|
|
||||||
"AI interface: if you have any questions, you can simply ask either by typing in the message " +
|
|
||||||
"box, or by clicking the microphone icon on the top of the page. '" +
|
|
||||||
"Here is a list of topics " + menuList +
|
|
||||||
", make a new bootstrap clearfix and after that make a clickable bootstrap " +
|
|
||||||
"styled (btn btn-primary) button from each of the determined topics, " +
|
|
||||||
"that calls the javascript function 'callAI({the name of the topic})' on click. " +
|
|
||||||
"Do not include anything else than the html title and text elements, no css, no scripts, no head or other tags." +
|
|
||||||
"Do not mark your answer with ```html or any other mark.";
|
|
||||||
return systemMessage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class UserIntention
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ContentProcessing
|
|
||||||
{
|
|
||||||
|
|
||||||
public static string GetSystemMessageForJsonResultDecision(string language, string extractedText, string currentDom)
|
|
||||||
{
|
|
||||||
string systemMessage = $"You are a helpful assistant built in a website, trying to figure out what the User wants to do or know about.\r\n" +
|
|
||||||
"Your job is to classify the user's request into one of the following categories:\r\n" +
|
|
||||||
"1. **Ask about or search infromation in the website’s content** (Return a 'Text result')\r\n" +
|
|
||||||
"2. **Analyze the currently displayed HTML content** (Return an 'Examination result')\r\n" +
|
|
||||||
"3. **Initiate an action** (Return a 'Method result')\r\n" +
|
|
||||||
"If none of the above applies, return an 'Error result'.\r\n\r\n" +
|
|
||||||
|
|
||||||
"**Response format:**\r\n" +
|
|
||||||
"Strictly respond in " + language + " as a JSON object, using one of the following formats:\r\n" +
|
|
||||||
|
|
||||||
"1. **chatGPTMethodResult** (for initiating actions):\r\n" +
|
|
||||||
" - `type`: \"methodresult\"\r\n" +
|
|
||||||
" - `text`: A short explanation of what the user wants to do.\r\n" +
|
|
||||||
" - `methodToCall`: One of: [openContactForm, openCalendar, openApplicationForm]\r\n" +
|
|
||||||
" - `parameter`: [email address for openContactForm, calendlyUserName for openCalendar, empty string for openApplicationForm]\r\n\r\n" +
|
|
||||||
|
|
||||||
"2. **chatGPTTextResult** (for general website content searches):\r\n" +
|
|
||||||
" - `type`: \"textresult\"\r\n" +
|
|
||||||
" - `text`: The user’s unmodified query.\r\n\r\n" +
|
|
||||||
|
|
||||||
"3. **chatGPTExaminationResult** (for analyzing the currently displayed page only):\r\n" +
|
|
||||||
" - `type`: \"examinationresult\"\r\n" +
|
|
||||||
" - `text`: The user’s unmodified query.\r\n\r\n" +
|
|
||||||
|
|
||||||
"4. **chatGPTErrorResult** (for errors):\r\n" +
|
|
||||||
" - `type`: \"errorresult\"\r\n" +
|
|
||||||
" - `text`: A description of the issue encountered.\r\n\r\n" +
|
|
||||||
|
|
||||||
"**Decision Rules:**\r\n" +
|
|
||||||
"- If the user is **searching for website content** beyond what is currently displayed (e.g., 'Find information about our services'), return a `textresult`.\r\n" +
|
|
||||||
"- If the user is **asking about the currently visible content** (e.g., 'What is shown on the page?'), return an `examinationresult`.\r\n" +
|
|
||||||
"- If the user wants to **perform an action**, return a `methodresult`.\r\n" +
|
|
||||||
"- If the required parameter is missing, return an `errorresult`.\r\n\r\n" +
|
|
||||||
|
|
||||||
"**Examples:**\r\n" +
|
|
||||||
"- User asks: 'Show me information about pricing' → `textresult`\r\n" +
|
|
||||||
"- User asks: 'What is displayed right now?' → `examinationresult`\r\n" +
|
|
||||||
"- User asks: 'Open the contact form' → `methodresult`\r\n" +
|
|
||||||
"- User asks: 'Contact support' but no email is found → `errorresult`\r\n\r\n" +
|
|
||||||
|
|
||||||
"**Context:**\r\n" +
|
|
||||||
"- Base responses on this initial document: {" + extractedText + "}\r\n" +
|
|
||||||
"- Current displayed HTML: {" + currentDom + "}\r\n" +
|
|
||||||
|
|
||||||
"**IMPORTANT:**\r\n" +
|
|
||||||
"- If the request is about general content, **DO NOT use 'examinationresult'**.\r\n" +
|
|
||||||
"- If the request is about the currently displayed page, **DO NOT use 'textresult'**.\r\n" +
|
|
||||||
"- Do NOT format the response with markdown, code blocks, or `json` tags, do not add any title, or explanation besides the plain json object";
|
|
||||||
|
|
||||||
return systemMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HtmlGeneration
|
|
||||||
{
|
|
||||||
public const string BootstrapCard = "Generate a Bootstrap 5 card layout using the following content:";
|
|
||||||
public const string SectionLayout = "Create a responsive HTML5 layout section for this text:";
|
|
||||||
}
|
|
||||||
public static class LayoutPlanning
|
|
||||||
{
|
|
||||||
public static string GetLayoutPlanningSystemPrompt(List<HtmlSnippet> htmlToUse, Dictionary<string, string>? photos, string[]? topics)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
// 📌 STRICT FORMAT INSTRUCTION
|
|
||||||
sb.AppendLine("You are a helpful assistant whose ONLY task is to break down THE PROVIDED CONTENT into a structured JSON object for Bootstrap 5 pages, using \n" +
|
|
||||||
"**layoutplan**:\r\n" +
|
|
||||||
"- `title`: \"The title of the page\"\r\n" +
|
|
||||||
"- `blocks`: \"an array of layoutblocks\"\r\n" +
|
|
||||||
".");
|
|
||||||
|
|
||||||
if ((htmlToUse != null))
|
|
||||||
{
|
|
||||||
sb.AppendLine("\n### You have these html snippets provided:");
|
|
||||||
foreach (var snippet in htmlToUse)
|
|
||||||
{
|
|
||||||
//no need to paste the html code
|
|
||||||
//sb.AppendLine($"Snippet id: {snippet.Id}, Snippet name: {snippet.Name}, Snippet description: {snippet.Description}, Snippet type: {snippet.Type}, Snippet template code: {snippet.Html}");
|
|
||||||
sb.AppendLine($"Snippet id: {snippet.Id}, Snippet name: {snippet.Name}, Snippet description: {snippet.Description}, Snippet type: {snippet.Type}");
|
|
||||||
}
|
|
||||||
sb.AppendLine("- Use them ONLY if relevant.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (photos != null && photos.Any())
|
|
||||||
{
|
|
||||||
sb.AppendLine("\n### Photos to be used in the blocks:");
|
|
||||||
sb.AppendLine(string.Join(", ", photos.Select(kv => $"{kv.Key}: {kv.Value}")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (topics != null && topics.Any())
|
|
||||||
{
|
|
||||||
sb.AppendLine("\n### Topics:");
|
|
||||||
sb.AppendLine(string.Join(", ", topics));
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine("### ⛔️ ABSOLUTELY DO NOT:");
|
|
||||||
sb.AppendLine("- ❌ Return HTML structure trees like `<section><div>`...");
|
|
||||||
sb.AppendLine("- ❌ Include keys like `src`, `alt`, `url`, `items`, or nested object lists.");
|
|
||||||
sb.AppendLine("- ❌ Invent block types not on the list.");
|
|
||||||
sb.AppendLine("- ❌ Return any explanation, markdown, prose, comments, or fallback formats.");
|
|
||||||
sb.AppendLine("- ❌ Use any of these block types: `image`, `quote`, `list`, `layout`, `header`, `footer`, `sidebar`, etc.");
|
|
||||||
sb.AppendLine("- ❌ Remove messages for AI marked with []");
|
|
||||||
|
|
||||||
sb.AppendLine("\n### ✅ REQUIRED OUTPUT FORMAT:");
|
|
||||||
sb.AppendLine("{");
|
|
||||||
sb.AppendLine(" \"title\": \"string\",");
|
|
||||||
sb.AppendLine(" \"blocks\": [");
|
|
||||||
sb.AppendLine(" { \"type\": \"string\", \"rawcontent\": \"string (text)\", \"preferredsnippetid\" : an integer id of matching html snippet if one found., \"order\": an incremented integer to set the blocks in order }");
|
|
||||||
sb.AppendLine(" ]");
|
|
||||||
sb.AppendLine("}");
|
|
||||||
|
|
||||||
sb.AppendLine("\n### ✅ Allowed `type` values (only use these):");
|
|
||||||
sb.AppendLine("- hero");
|
|
||||||
sb.AppendLine("- text");
|
|
||||||
sb.AppendLine("- text-image");
|
|
||||||
sb.AppendLine("- features");
|
|
||||||
sb.AppendLine("- cta");
|
|
||||||
sb.AppendLine("- video");
|
|
||||||
sb.AppendLine("- icon-list");
|
|
||||||
sb.AppendLine("- event-list");
|
|
||||||
sb.AppendLine("- audio-player");
|
|
||||||
sb.AppendLine("- topic-buttons");
|
|
||||||
|
|
||||||
sb.AppendLine("\n### ❗ GOOD EXAMPLE:");
|
|
||||||
sb.AppendLine("{");
|
|
||||||
sb.AppendLine(" \"title\": \"Welcome to Our Product\",");
|
|
||||||
sb.AppendLine(" \"blocks\": [");
|
|
||||||
sb.AppendLine(" { \"type\": \"hero\", \"rawcontent\": \"Example text\", \"preferredsnippetid\": 1, \"order\": 0 },");
|
|
||||||
sb.AppendLine(" { \"type\": \"features\", \"rawcontent\": \"Example features\", \"order\": 1 },");
|
|
||||||
sb.AppendLine(" { \"type\": \"cta\", \"rawcontent\": \"call to action content\", \"order\": 2 }");
|
|
||||||
sb.AppendLine(" ]");
|
|
||||||
sb.AppendLine("}");
|
|
||||||
|
|
||||||
sb.AppendLine("\n### ⛔ BAD EXAMPLES (DO NOT DO THIS):");
|
|
||||||
sb.AppendLine("- { \"type\": \"image\", \"src\": \"...\", \"alt\": \"...\" }");
|
|
||||||
sb.AppendLine("- { \"type\": \"list\", \"items\": [\"...\", \"...\"] }");
|
|
||||||
sb.AppendLine("- { \"layout\": { \"header\": ..., \"footer\": ... } }");
|
|
||||||
|
|
||||||
sb.AppendLine("\n### FINAL TASK:");
|
|
||||||
sb.AppendLine("Based on the following content, generate a JSON object following the exact format above. Output only the JSON. No markdown. No other marks. No explanation. ONLY the pure JSON.");
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetLayoutPlanningUserPrompt(string interMediateResult, string pageTitle, Dictionary<string, string>? photos)
|
|
||||||
{
|
|
||||||
var userMessage = "Based on the following content:\n\n*** " + interMediateResult + " ***\n\n" +
|
|
||||||
"and the available photos:";
|
|
||||||
|
|
||||||
if (photos != null && photos.Any())
|
|
||||||
{
|
|
||||||
userMessage += "\n### Photo urls to be used WITHOUT ANY MODIFICATION in the blocks:";
|
|
||||||
userMessage += string.Join(", ", photos.Select(kv => $"{kv.Key}: {kv.Value}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
userMessage += ", return ONLY a JSON object representing a structured content layout for a webpage with the title '" + pageTitle + "', with this exact shape:\n" +
|
|
||||||
"{ \"title\": string, \"blocks\": [ { \"type\": \"string\", \"rawcontent\": \"string (text)\", \"preferredsnippetid\" : an integer id of matching html snippet if one found., \"order\": an incremented integer to set the blocks in order } ] }\n\n" +
|
|
||||||
"⚠️ DO NOT use layout structures like 'header', 'sidebar', 'mainContent', or 'footer'.\n" +
|
|
||||||
"⚠️ DO NOT explain anything. Just return the pure JSON. No markdown, no ``` markers.\n\n" +
|
|
||||||
"🎯 OBJECTIVE:\n" +
|
|
||||||
"1. Determine 1 to 5 major content blocks from the input, grouping full paragraphs or sections together.\n" +
|
|
||||||
"Prefer **1 to 5 blocks max**, unless the content is extremely long. Each block should represent a semantically complete section.\r\n" +
|
|
||||||
"Group related ideas into one block, even if they are multiple paragraphs. Do NOT break up content just because it is a new sentence. \r\n" +
|
|
||||||
"2. Use meaningful, semantically grouped layout block types like: 'hero', 'features list', 'text with image', 'text', 'product list', 'call to action', 'videoplayer', 'audioplayer', etc.\n" +
|
|
||||||
"3. Each block should contain **rich content** and related photo ['photo url': 'the url of the photo'], not just one or two sentences. Group related ideas into a single `rawcontent` field.\n\n" +
|
|
||||||
"DO NOT REMOVE ANY URLS (photo, wen link, etc) from the section or paragraph that it follows. \n\n" +
|
|
||||||
"📌 Examples of good block grouping:\n" +
|
|
||||||
"- All introductory marketing text together in one 'hero' or 'text' block\n" +
|
|
||||||
"- A group of benefits or features into a single 'features' block\n" +
|
|
||||||
"- A pitch paragraph into a 'call to action' block\n\n" +
|
|
||||||
"🎨 Naming:\n" +
|
|
||||||
"- Try to find related type values in the available snippets list. If you find a relevant snippet for that block, use the name of that snippet for type, and add the id if the snippet as preferredsnippetid." +
|
|
||||||
"- If there is no relevant snippet, use such layout `type` values: hero, text, features, text with image, call to action, product list, team members, testimonial, event list, blogpost, article, video player, audio player, etc\n" +
|
|
||||||
"X Restrictions:" +
|
|
||||||
"- DO **NOT** modify the photo urls in any way." +
|
|
||||||
"- DO **NOT use the same text multiple times**" +
|
|
||||||
"- Do **NOT** generate or assume new photo URLs.\n" +
|
|
||||||
"- Do **NOT** modify photo URLs in any way.\n" +
|
|
||||||
"- Do **NOT** skip or deny ANY part of the provided text. All of the provided text should be put in blocks \n" +
|
|
||||||
"- Do **NOT** assume ANY content, like missing prices, missing links, etc. \n" +
|
|
||||||
"✅ Final output: JSON only, well grouped, no extra explanation or formatting, no markdown, no ``` markers.\n";
|
|
||||||
|
|
||||||
return userMessage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HtmlRendering
|
|
||||||
{
|
|
||||||
public static string GetHtmlRenderingSystemPromptForTextAndErrorResult(string language, string pageTitle, List<HtmlSnippet> htmlToUse, Dictionary<string, string>? photos, string[]? topics)
|
|
||||||
{
|
|
||||||
|
|
||||||
var sb = new StringBuilder($"You are a helpful assistant generating HTML in {language} using Bootstrap 5.\n\n" +
|
|
||||||
"### General Instructions:\n" +
|
|
||||||
"- Output only the **HTML content** between the menu and footer.\n" +
|
|
||||||
"- DO NOT include `<head>`, `<body>`, or markdown formatting.\n" +
|
|
||||||
"- Use `<h1 class='p-3'>` for the title: " + pageTitle + ".\n" +
|
|
||||||
"- Structure sections inside separate `<section>` or `<div class='row'>` blocks.\n" +
|
|
||||||
"- Use Bootstrap spacing and layout classes:\n" +
|
|
||||||
" - Use `row justify-content-center` for rows.\n" +
|
|
||||||
" - Use `col-xx-x` only for multiple-column layouts.\n" +
|
|
||||||
" - Always use `img-fluid` for images.\n" +
|
|
||||||
"- Avoid: unnecessary paragraph classes, nesting `<img>` inside `<p>`, or using `col` for single-column content.\n\n");
|
|
||||||
|
|
||||||
if (htmlToUse != null && htmlToUse.Any())
|
|
||||||
{
|
|
||||||
sb.AppendLine("### Snippet Handling:\n" +
|
|
||||||
"- You are provided with multiple HTML snippets:\n");
|
|
||||||
|
|
||||||
foreach (var snippet in htmlToUse)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{snippet.Id}: {snippet.Name}: {snippet.Html}\n");
|
|
||||||
sb.AppendLine($"Type: {snippet.Type}, Tags: {snippet.Tags}, Variant: {snippet.Variant}\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine(
|
|
||||||
"- Use each snippet as a separate `<section>`.\n" +
|
|
||||||
"- DO NOT merge snippets into one block.\n" +
|
|
||||||
"- Use snippets only if they match the content block.\n" +
|
|
||||||
"- Prefer variants with images if image content is present.\n" +
|
|
||||||
"- Always use a short title in `<h>` and place body text in a `<p>`.\n" +
|
|
||||||
"- If snippet includes a button, wrap it in `<div class='text-center'>`.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (photos != null && photos.Any())
|
|
||||||
{
|
|
||||||
sb.AppendLine("### Photo Usage:\n" +
|
|
||||||
"- Use ONLY the following image URLs as-is (no changes):\n" +
|
|
||||||
string.Join(", ", photos.Select(kv => $"{kv.Key}: {kv.Value}")) + "\n" +
|
|
||||||
"- Example:\n" +
|
|
||||||
$" <img src='{photos.First().Value}' class='img-fluid' alt='{photos.First().Key}' />\n" +
|
|
||||||
"- DO NOT generate or modify photo URLs.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (topics != null && topics.Any())
|
|
||||||
{
|
|
||||||
sb.AppendLine("### Topic Buttons:\n" +
|
|
||||||
"- Place this section last, titled `Related`.\n" +
|
|
||||||
"- Generate a `btn btn-primary` for each topic, calling `callAI('{original_non_translated_topicName}')`.\n" +
|
|
||||||
"- Translate topic names to " + language + " if needed.\n" +
|
|
||||||
"- Example:\n" +
|
|
||||||
$" <button class='btn btn-primary' onclick='callAI(\"{topics.FirstOrDefault()}\")'>{topics.FirstOrDefault()}</button>\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.AppendLine("- No topics provided → DO NOT generate topic buttons.");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine("\n### DO NOT:\n" +
|
|
||||||
"- DO **NOT** merge different content blocks.\n" +
|
|
||||||
"- DO **NOT** remove javascript or <script> tags" +
|
|
||||||
"- DO **NOT** wrap the full output in a single `div`.\n" +
|
|
||||||
"- DO **NOT** skip any provided content.\n" +
|
|
||||||
"- DO **NOT** add assumed text (e.g. prices, links).\n" +
|
|
||||||
"- DO **NOT** add `<img>` if no image URL exists.\n" +
|
|
||||||
"- DO **NOT** modify image URLs. not even adding 'https://example.com or such before the relaitve path'\n" +
|
|
||||||
"- DO **NOT** include explanation, markdown, or ` ```html` markers.\n");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string HtmlRenderingUserPromptForTextAndErrorResult = "Create a perfect, production ready, structured, responsive Bootstrap 5 webpage " +
|
|
||||||
"content from the provided layout and available html snippets. \r \n" +
|
|
||||||
"Read the layout plan, analyze the blocks, and identify if there is any matching html snippets for each block folowing these rules: \r \n" +
|
|
||||||
"- If there is no matching html snippet, generate the bootstrap 5 based layout for the given block. Else parse the block content into the available code snippet." +
|
|
||||||
"- For each block, add am opening and closing comment with the name of the block like: <!-- Hero start --> \r \n" +
|
|
||||||
"- Do not remove script tags from the provided snippets. \r \n" +
|
|
||||||
"If the block's rawcontent contains photo url, display that photo within that section, not elsewhere. ";
|
|
||||||
|
|
||||||
public static string GetHtmlRenderingAssistantMessageForTextAndErrorResult(LayoutPlan layoutPlan)
|
|
||||||
{
|
|
||||||
string assistantMessage = "`Provided layout plan, that contains the text to be displayed as HTML`:";
|
|
||||||
|
|
||||||
foreach (var block in layoutPlan.Blocks)
|
|
||||||
{
|
|
||||||
assistantMessage += $"Block type: {block.Type}, block content: {block.RawContent}";
|
|
||||||
}
|
|
||||||
return assistantMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetHtmlRenderingSystemPromptForMethodResult(string language, string methodToCall, string methodParameter)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder("You are a helpful assistant generating HTML content in " + language + " using Bootstrap. \n\n" +
|
|
||||||
"### Rules to Follow: \n" +
|
|
||||||
"- Please generate clean and structured HTML that goes inside a Bootstrap container.\n" +
|
|
||||||
"- DO NOT include `<head>`, `<body>` tags — only content inside the Bootstrap container.\n" +
|
|
||||||
"- Use `<h1 class='p-3'>` for a short title followed by the content, based on the user's query.\n" +
|
|
||||||
"- Structure content using **separate `row` elements** for different sections.\n" +
|
|
||||||
"- Use Bootstrap classes to ensure proper spacing and alignment.\n" +
|
|
||||||
" - Use 'row justify-content-center' for layout, 'col-xx-x' classes for columns (ONLY IF multiple columns are needed), and always use 'img-fluid' class for images.\r\n" +
|
|
||||||
" - Do NOT use 'col' class if there is only one column to display in the row. \n" +
|
|
||||||
"- Do NOT use additional class for paragraphs! \n" +
|
|
||||||
"- Do NOT nest images inside paragraphs! \n" +
|
|
||||||
"- Ensure clear **separation of content into multiple sections if multiple snippets are provided**.\n");
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(methodToCall))
|
|
||||||
{
|
|
||||||
sb.AppendLine("- At the END of the content, include a **single** Bootstrap button (`btn btn-primary`) that calls `" + methodToCall + "` with `" + methodParameter + "` on click.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine("- DO **NOT** merge different content sections.\n" +
|
|
||||||
"- DO **NOT** wrap the entire content in a single `div`— use separate `row` divs.\n" +
|
|
||||||
"- Do **NOT** skip or deny ANY part of the provided text. All of the provided text should be displayed as html\n" +
|
|
||||||
"- Do **NOT** assume ANY content, like missing prices, missing links. \n" +
|
|
||||||
"- If the snippet contains an image, but there is no photo url available, SKIP adding the image tag." +
|
|
||||||
"- **Never** add explanations or start with ```html syntax markers.\n");
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class AppLog
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
|
|
||||||
public string Severity { get; set; } = "Info"; // "Info", "Warning", "Error"
|
|
||||||
public string Message { get; set; }
|
|
||||||
public string? Details { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -14,10 +14,6 @@ namespace BLAIzor.Models
|
||||||
public Message[] Messages { get; set; } = Array.Empty<Message>();
|
public Message[] Messages { get; set; } = Array.Empty<Message>();
|
||||||
[JsonProperty("stream")]
|
[JsonProperty("stream")]
|
||||||
public bool Stream { get; set; } = true;
|
public bool Stream { get; set; } = true;
|
||||||
//[JsonProperty("reasoning_effort")]
|
|
||||||
//public string ReasoningEffort { get; set; } = "minimal";
|
|
||||||
//[JsonProperty("verbosity")]
|
|
||||||
//public string Verbosity { get; set; } = "high";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class ContentChunk
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public int ContentItemId { get; set; } // FK to ContentItem
|
|
||||||
public string QdrantPointId { get; set; }
|
|
||||||
public int ChunkIndex { get; set; }
|
|
||||||
public string? VectorHash { get; set; }
|
|
||||||
public DateTime CreatedAt { get; set; }
|
|
||||||
|
|
||||||
public ContentItem ContentItem { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
using NuGet.ContentModel;
|
|
||||||
|
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class ContentGroup
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public int SiteInfoId { get; set; } // FK to SiteInfo
|
|
||||||
public string Name { get; set; } // e.g. "Blog", "Manuals"
|
|
||||||
public string Slug { get; set; } // e.g. "blog", "manuals"
|
|
||||||
public string Type { get; set; } // "blogpost", "manual", etc.
|
|
||||||
public int VectorSize { get; set; }
|
|
||||||
public string EmbeddingModel { get; set; }
|
|
||||||
public int Version { get; set; }
|
|
||||||
public DateTime CreatedAt { get; set; }
|
|
||||||
public DateTime LastUpdated { get; set; }
|
|
||||||
|
|
||||||
public SiteInfo SiteInfo { get; set; }
|
|
||||||
public ICollection<ContentItem> Items { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class ContentGroupModel
|
|
||||||
{
|
|
||||||
public int SiteInfoId { get; set; }
|
|
||||||
public ContentGroup ContentGroup { get; set; }
|
|
||||||
public List<ContentItemModel> ContentItems { get; set; } = new();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class ContentItem
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public int ContentGroupId { get; set; } // FK to ContentGroup
|
|
||||||
public string Title { get; set; }
|
|
||||||
public string Description { get; set; }
|
|
||||||
public string Content { get; set; }
|
|
||||||
public string Language { get; set; }
|
|
||||||
public string Tags { get; set; } // comma-separated tags
|
|
||||||
public bool IsPublished { get; set; }
|
|
||||||
public int Version { get; set; }
|
|
||||||
public DateTime CreatedAt { get; set; }
|
|
||||||
public DateTime LastUpdated { get; set; }
|
|
||||||
|
|
||||||
public ContentGroup ContentGroup { get; set; }
|
|
||||||
public ICollection<ContentChunk> Chunks { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class ContentItemModel
|
|
||||||
{
|
|
||||||
public ContentItem ContentItem { get; set; }
|
|
||||||
public List<ContentChunk> Chunks { get; set; } = new();
|
|
||||||
|
|
||||||
// Optional: enriched vector data pulled from Qdrant
|
|
||||||
public List<WebPageContent> VectorPoints { get; set; } = new();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,14 +2,8 @@
|
||||||
{
|
{
|
||||||
public class UploadedFilesModel
|
public class UploadedFilesModel
|
||||||
{
|
{
|
||||||
public List<UploadedImage> Images { get; set; } = new();
|
public List<string> Images { get; set; } = new();
|
||||||
public List<string> Videos { get; set; } = new();
|
public List<string> Videos { get; set; } = new();
|
||||||
public List<string> Audio { get; set; } = new();
|
public List<string> Audio { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UploadedImage
|
|
||||||
{
|
|
||||||
public string OriginalUrl { get; set; } = string.Empty;
|
|
||||||
public string ThumbnailUrl { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class GeneratedContentItem : ContentItem
|
|
||||||
{
|
|
||||||
public List<PhotoSlot> PhotoSlots { get; set; } = new();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -18,10 +18,7 @@
|
||||||
public string Tags { get; set; }
|
public string Tags { get; set; }
|
||||||
public string Type { get; set; } // e.g. "article", "form", "gallery"
|
public string Type { get; set; } // e.g. "article", "form", "gallery"
|
||||||
public string? Variant { get; set; } // 👈 NEW: e.g. "image-left", "image-right", "no-image"
|
public string? Variant { get; set; } // 👈 NEW: e.g. "image-left", "image-right", "no-image"
|
||||||
public string SampleHtml { get; set; } //for design purposes
|
public string SampleHtml { get; set; }
|
||||||
public List<string> Slots { get; set; } // e.g. ["title", "subtitle", "image", "cta"]
|
|
||||||
public float[] Vectors { get; set; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class LayoutBlock
|
|
||||||
{
|
|
||||||
public string Type { get; set; } // e.g. "hero", "article", "gallery", "testimonial"
|
|
||||||
public string? Variant { get; set; } // e.g. "image-left", "image-right", "no-image"
|
|
||||||
|
|
||||||
public List<string> RequiredSlots { get; set; } // e.g. ["title", "text", "image", "cta"]
|
|
||||||
|
|
||||||
public Dictionary<string, string> ContentMap { get; set; }
|
|
||||||
// Maps slot names to content IDs or keys, e.g. { "title": "main_heading", "image": "img_1" }
|
|
||||||
|
|
||||||
public int? PreferredSnippetId { get; set; }
|
|
||||||
// Optional: used if a perfect match snippet is found or AI prefers one
|
|
||||||
|
|
||||||
//public string? BootstrapStructure { get; set; }
|
|
||||||
// Optional: e.g. "row-cols-2", "container-fluid py-5"
|
|
||||||
|
|
||||||
public string RawContent { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public int Order { get; set; }
|
|
||||||
// The position of the block in the layout
|
|
||||||
|
|
||||||
public string? Notes { get; set; }
|
|
||||||
// Optional field for AI hints, comments, or debug info
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class LayoutPlan
|
|
||||||
{
|
|
||||||
public string Title { get; set; }
|
|
||||||
public List<LayoutBlock> Blocks { get; set; } = new();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -12,32 +12,18 @@ namespace BLAIzor.Models
|
||||||
[Required]
|
[Required]
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string? Slug { get; set; }
|
public int PointId { get; set; }
|
||||||
|
|
||||||
//public int PointId { get; set; }
|
|
||||||
public int SortOrder { get; set; }
|
public int SortOrder { get; set; }
|
||||||
|
|
||||||
public bool ShowInMainMenu { get; set; } = false;
|
public bool ShowInMainMenu { get; set; } = false;
|
||||||
|
|
||||||
public string? StoredHtml { get; set; }
|
public string StoredHtml { get; set; }
|
||||||
|
|
||||||
//public Guid? QdrantPointId { get; set; }
|
public Guid? QdrantPointId { get; set; }
|
||||||
|
|
||||||
[ForeignKey("ContentGroup")]
|
|
||||||
public int? ContentGroupId { get; set; } // optional link to a ContentGroup
|
|
||||||
public ContentGroup? ContentGroup { get; set; }
|
|
||||||
|
|
||||||
public int? ContentItemId { get; set; } // optional link to a specific ContentItem
|
|
||||||
public ContentItem? ContentItem { get; set; }
|
|
||||||
|
|
||||||
[ForeignKey("SiteInfo")]
|
[ForeignKey("SiteInfo")]
|
||||||
public int SiteInfoId { get; set; }
|
public int SiteInfoId { get; set; }
|
||||||
public SiteInfo SiteInfo { get; set; } = null!;
|
public SiteInfo SiteInfo { get; set; } = null!;
|
||||||
|
|
||||||
[ForeignKey("MenuItem")]
|
|
||||||
public int? ParentId { get; set; }
|
|
||||||
public MenuItem? Parent { get; set; }
|
|
||||||
public ICollection<MenuItem> Children { get; set; } = new List<MenuItem>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ namespace BLAIzor.Models
|
||||||
{
|
{
|
||||||
public MenuItem MenuItem { get; set; }
|
public MenuItem MenuItem { get; set; }
|
||||||
public string Content { get; set; } = string.Empty;
|
public string Content { get; set; } = string.Empty;
|
||||||
public string ContentDescription { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public MenuItemModel(string name)
|
public MenuItemModel(string name)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class PhotoSlot
|
|
||||||
{
|
|
||||||
public string Description { get; set; } // AI-generated suggestion
|
|
||||||
public string ImageUrl { get; set; } // AI-generated or user-selected image
|
|
||||||
public int SortOrder { get; set; } // order in which it appears in the UI
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -19,27 +19,14 @@ namespace BLAIzor.Models
|
||||||
public string UserId { get; set; }
|
public string UserId { get; set; }
|
||||||
|
|
||||||
[Url(ErrorMessage = "The DomainUrl field must be a valid URL.")]
|
[Url(ErrorMessage = "The DomainUrl field must be a valid URL.")]
|
||||||
public string? DomainUrl { get; set; } // For custom domains
|
public string DomainUrl { get; set; } // For custom domains
|
||||||
|
|
||||||
[Url(ErrorMessage = "The DefaultUrl field must be a valid URL.")]
|
[Url(ErrorMessage = "The DefaultUrl field must be a valid URL.")]
|
||||||
public string DefaultUrl { get; set; } // For generated subdomains
|
public string DefaultUrl { get; set; } // For generated subdomains
|
||||||
public bool IsPublished { get; set; }
|
public bool IsPublished { get; set; } // For generated subdomains
|
||||||
public int? TemplateId { get; set; }
|
public int? TemplateId { get; set; }
|
||||||
public bool TTSActive { get; set; } = false;
|
public bool TTSActive { get; set; } = false;
|
||||||
public bool STTActive { get; set; } = false;
|
public bool STTActive { get; set; } = false;
|
||||||
public string? VoiceId { get; set; }
|
|
||||||
public string? Persona { get; set; }
|
|
||||||
public string? Entity { get; set; }
|
|
||||||
public string? DesignStyle { get; set; } // e.g. "Modern", "Classic", "Photorealistic"
|
|
||||||
public string? DefaultLanguage { get; set; }
|
|
||||||
public string? BackgroundVideo { get; set; }
|
|
||||||
public string? VectorCollectionName { get; set; }
|
|
||||||
public string? EmbeddingService { get; set; }
|
|
||||||
public string? FacebookUrl { get; set; }
|
|
||||||
public string? TwitterUrl { get; set; }
|
|
||||||
public string? InstagramUrl { get; set; }
|
|
||||||
|
|
||||||
public List<ContentGroup> ContentGroups { get; set; } = new();
|
|
||||||
|
|
||||||
// Navigation property for IdentityUser
|
// Navigation property for IdentityUser
|
||||||
public IdentityUser User { get; set; }
|
public IdentityUser User { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,17 @@
|
||||||
using Qdrant.Client.Grpc;
|
using DateTime = System.DateTime;
|
||||||
using DateTime = System.DateTime;
|
|
||||||
|
|
||||||
namespace BLAIzor.Models
|
namespace BLAIzor.Models
|
||||||
{
|
{
|
||||||
public class WebPageContent
|
public class WebPageContent
|
||||||
{
|
{
|
||||||
public PointId Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string UId { get; set; }
|
public string UId { get; set; }
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
public int SiteId { get; set; }
|
public int SiteId { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public string Content { get; set; }
|
public string Content { get; set; }
|
||||||
public float[] Vectors { get; set; }
|
|
||||||
public DateTime LastUpdated { get; set; }
|
public DateTime LastUpdated { get; set; }
|
||||||
|
|
||||||
public WebPageContent()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebPageContent(PointId id, string uId, string type, int siteId, string name, string description, string content, float[] vectors, DateTime lastUpdated)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
UId = uId;
|
|
||||||
Type = type;
|
|
||||||
SiteId = siteId;
|
|
||||||
Name = name;
|
|
||||||
Description = description;
|
|
||||||
Content = content;
|
|
||||||
Vectors = vectors;
|
|
||||||
LastUpdated = lastUpdated;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
namespace BLAIzor.Models
|
|
||||||
{
|
|
||||||
public class WebsiteContentModel
|
|
||||||
{
|
|
||||||
public int SiteInfoId { get; set; }
|
|
||||||
public List<ContentGroup> ContentGroups { get; set; }
|
|
||||||
public List<ContentItemModel> ContentItems { get; set; } = new();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
42
Program.cs
42
Program.cs
|
|
@ -1,8 +1,6 @@
|
||||||
using BLAIzor.Components;
|
using BLAIzor.Components;
|
||||||
using BLAIzor.Components.Partials;
|
|
||||||
using BLAIzor.Data;
|
using BLAIzor.Data;
|
||||||
using BLAIzor.Helpers;
|
using BLAIzor.Helpers;
|
||||||
using BLAIzor.Interfaces;
|
|
||||||
using BLAIzor.Services;
|
using BLAIzor.Services;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
|
|
@ -14,8 +12,6 @@ using Radzen;
|
||||||
using Sidio.Sitemap.AspNetCore;
|
using Sidio.Sitemap.AspNetCore;
|
||||||
using Sidio.Sitemap.Blazor;
|
using Sidio.Sitemap.Blazor;
|
||||||
using Sidio.Sitemap.Core.Services;
|
using Sidio.Sitemap.Core.Services;
|
||||||
using System;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
var configuration = builder.Configuration;
|
var configuration = builder.Configuration;
|
||||||
|
|
@ -39,12 +35,6 @@ builder.Services.Configure<KestrelServerOptions>(options =>
|
||||||
options.Limits.MaxRequestBodySize = 50 * 1024 * 1024;
|
options.Limits.MaxRequestBodySize = 50 * 1024 * 1024;
|
||||||
});
|
});
|
||||||
|
|
||||||
var env = builder.Environment; // This is IWebHostEnvironment
|
|
||||||
|
|
||||||
if (env.IsProduction())
|
|
||||||
{
|
|
||||||
// do production-specific setup
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddRazorComponents()
|
builder.Services.AddRazorComponents()
|
||||||
|
|
@ -52,24 +42,12 @@ builder.Services.AddRazorComponents()
|
||||||
|
|
||||||
builder.Services.AddRadzenComponents();
|
builder.Services.AddRadzenComponents();
|
||||||
|
|
||||||
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
|
|
||||||
|
|
||||||
// Required for scoped injection (used in pages/services)
|
|
||||||
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
|
||||||
options.UseSqlServer(connectionString));
|
|
||||||
|
|
||||||
// Required for factory-based logging or background usage
|
|
||||||
builder.Services.AddDbContextFactory<ApplicationDbContext>(options =>
|
|
||||||
options.UseSqlServer(connectionString), ServiceLifetime.Scoped);
|
|
||||||
|
|
||||||
builder.Services.AddHttpClient();
|
builder.Services.AddHttpClient();
|
||||||
builder.Services.AddScoped<ISimpleLogger, SimpleLogger>();
|
|
||||||
builder.Services.AddScoped<AIService>();
|
builder.Services.AddScoped<AIService>();
|
||||||
//builder.Services.AddSingleton<ContentService>();
|
builder.Services.AddSingleton<ContentService>();
|
||||||
builder.Services.AddScoped<ScopedContentService>();
|
builder.Services.AddScoped<ScopedContentService>();
|
||||||
builder.Services.AddScoped<QDrantService>();
|
builder.Services.AddScoped<QDrantService>();
|
||||||
builder.Services.AddScoped<OpenAIEmbeddingService>();
|
builder.Services.AddScoped<OpenAIEmbeddingService>();
|
||||||
builder.Services.AddScoped<LocalEmbeddingService>();
|
|
||||||
builder.Services.AddScoped<HtmlSnippetProcessor>();
|
builder.Services.AddScoped<HtmlSnippetProcessor>();
|
||||||
builder.Services
|
builder.Services
|
||||||
.AddHttpContextAccessor()
|
.AddHttpContextAccessor()
|
||||||
|
|
@ -79,32 +57,14 @@ builder.Services.AddScoped<CustomAuthenticationStateProvider>();
|
||||||
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("Smtp"));
|
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("Smtp"));
|
||||||
builder.Services.AddTransient<IEmailSender, EmailService>();
|
builder.Services.AddTransient<IEmailSender, EmailService>();
|
||||||
builder.Services.AddScoped<ContentEditorService>();
|
builder.Services.AddScoped<ContentEditorService>();
|
||||||
builder.Services.AddScoped<ContentEditorAIService>();
|
|
||||||
builder.Services.AddScoped<CssTemplateService>();
|
builder.Services.AddScoped<CssTemplateService>();
|
||||||
builder.Services.AddScoped<DesignTemplateService>();
|
builder.Services.AddScoped<DesignTemplateService>();
|
||||||
builder.Services.AddScoped<OpenAIApiService>();
|
builder.Services.AddScoped<OpenAIApiService>();
|
||||||
builder.Services.AddScoped<DeepSeekApiService>();
|
builder.Services.AddScoped<DeepSeekApiService>();
|
||||||
builder.Services.AddScoped<OpenAiRealtimeService>();
|
builder.Services.AddScoped<OpenAiRealtimeService>();
|
||||||
builder.Services.AddScoped<CerebrasAPIService>();
|
builder.Services.AddScoped<CerebrasAPIService>();
|
||||||
builder.Services.AddScoped<KimiApiService>();
|
|
||||||
builder.Services.AddScoped<CssInjectorService>();
|
builder.Services.AddScoped<CssInjectorService>();
|
||||||
builder.Services.AddScoped<LocalVectorSearchService>();
|
|
||||||
builder.Services.AddScoped<WebsiteContentLoaderService>();
|
|
||||||
builder.Services.AddScoped<CacheService>();
|
|
||||||
builder.Services.AddSingleton<CreateSiteWizard>();
|
|
||||||
builder.Services.AddScoped<WhisperTranscriptionService>();
|
|
||||||
builder.Services.AddScoped<IBrightDataService, BrightDataService>();
|
|
||||||
|
|
||||||
builder.Services.AddHttpClient<ReplicateService>(client =>
|
|
||||||
{
|
|
||||||
client.DefaultRequestHeaders.Authorization =
|
|
||||||
new AuthenticationHeaderValue("Bearer", "r8_MUApXYIE5mRjxqy20tsGLehWBJkCzNj0Cwvrh");
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.Services.AddHostedService<TempFileCleanupService>();
|
builder.Services.AddHostedService<TempFileCleanupService>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
builder.Services.AddServerSideBlazor().AddCircuitOptions(options => options.DetailedErrors = true).AddHubOptions(options =>
|
builder.Services.AddServerSideBlazor().AddCircuitOptions(options => options.DetailedErrors = true).AddHubOptions(options =>
|
||||||
{
|
{
|
||||||
options.MaximumReceiveMessageSize = 1024000; // e.g. 100 KB
|
options.MaximumReceiveMessageSize = 1024000; // e.g. 100 KB
|
||||||
|
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using BLAIzor.Data;
|
|
||||||
using BLAIzor.Models;
|
|
||||||
using BLAIzor.Services;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Moq;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace SeemGen.Tests;
|
|
||||||
public class ContentEditorServiceTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public async Task SaveAndSyncContentItemAsync_UpdatesFieldsAndRechunks_WhenContentChanged()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var contentItemId = 1;
|
|
||||||
var oldContent = "Old content";
|
|
||||||
var newContent = "New content for chunking";
|
|
||||||
var collectionName = "test_collection";
|
|
||||||
|
|
||||||
var contentGroup = new ContentGroup { Id = 1, Name = "Group", SiteInfoId = 1, Items = new List<ContentItem>() };
|
|
||||||
var existingChunks = new List<ContentChunk>
|
|
||||||
{
|
|
||||||
new ContentChunk { Id = 1, ContentItemId = contentItemId, QdrantPointId = Guid.NewGuid().ToString(), ChunkIndex = 0, CreatedAt = DateTime.UtcNow }
|
|
||||||
};
|
|
||||||
var existingItem = new ContentItem
|
|
||||||
{
|
|
||||||
Id = contentItemId,
|
|
||||||
Title = "Old Title",
|
|
||||||
Description = "Old Desc",
|
|
||||||
Content = oldContent,
|
|
||||||
Language = "en",
|
|
||||||
Tags = "tag1",
|
|
||||||
IsPublished = true,
|
|
||||||
LastUpdated = DateTime.UtcNow,
|
|
||||||
ContentGroup = contentGroup,
|
|
||||||
Chunks = existingChunks
|
|
||||||
};
|
|
||||||
contentGroup.Items.Add(existingItem);
|
|
||||||
|
|
||||||
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
|
|
||||||
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
|
|
||||||
.Options;
|
|
||||||
var dbContext = new ApplicationDbContext(options);
|
|
||||||
dbContext.ContentItems.Add(existingItem);
|
|
||||||
dbContext.ContentChunks.AddRange(existingChunks);
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
|
|
||||||
var serviceScopeFactoryMock = new Mock<IServiceScopeFactory>();
|
|
||||||
var scopeMock = new Mock<IServiceScope>();
|
|
||||||
var providerMock = new Mock<IServiceProvider>();
|
|
||||||
providerMock.Setup(x => x.GetService(typeof(ApplicationDbContext))).Returns(dbContext);
|
|
||||||
scopeMock.Setup(x => x.ServiceProvider).Returns(providerMock.Object);
|
|
||||||
serviceScopeFactoryMock.Setup(x => x.CreateScope()).Returns(scopeMock.Object);
|
|
||||||
|
|
||||||
var qdrantServiceMock = new Mock<QDrantService>(null);
|
|
||||||
qdrantServiceMock.Setup(x => x.DeletePointsAsync(It.IsAny<Guid[]>(), collectionName)).Returns(Task.CompletedTask);
|
|
||||||
qdrantServiceMock.Setup(x => x.QDrantInsertManyAsync(It.IsAny<List<WebPageContent>>(), collectionName)).Returns(Task.CompletedTask);
|
|
||||||
|
|
||||||
var openAIEmbeddingServiceMock = new Mock<OpenAIEmbeddingService>();
|
|
||||||
openAIEmbeddingServiceMock.Setup(x => x.GenerateEmbeddingAsync(It.IsAny<string>())).ReturnsAsync(new float[] { 0.1f, 0.2f });
|
|
||||||
|
|
||||||
var localEmbeddingServiceMock = new Mock<LocalEmbeddingService>();
|
|
||||||
localEmbeddingServiceMock.Setup(x => x.GenerateEmbeddingAsync(It.IsAny<string>())).ReturnsAsync(new float[] { 0.1f, 0.2f });
|
|
||||||
|
|
||||||
var openAIApiServiceMock = new Mock<OpenAIApiService>(MockBehavior.Loose, null, null);
|
|
||||||
var htmlSnippetProcessorMock = new Mock<HtmlSnippetProcessor>(qdrantServiceMock.Object, openAIEmbeddingServiceMock.Object, localEmbeddingServiceMock.Object, null);
|
|
||||||
var scopedContentServiceMock = new Mock<ScopedContentService>(dbContext, serviceScopeFactoryMock.Object);
|
|
||||||
|
|
||||||
var configMock = new Mock<IConfiguration>();
|
|
||||||
configMock.Setup(x => x.GetSection("AiSettings").GetValue<string>("EmbeddingService")).Returns("openai");
|
|
||||||
|
|
||||||
var service = new ContentEditorService(
|
|
||||||
openAIApiServiceMock.Object,
|
|
||||||
qdrantServiceMock.Object,
|
|
||||||
openAIEmbeddingServiceMock.Object,
|
|
||||||
localEmbeddingServiceMock.Object,
|
|
||||||
htmlSnippetProcessorMock.Object,
|
|
||||||
serviceScopeFactoryMock.Object,
|
|
||||||
scopedContentServiceMock.Object,
|
|
||||||
configMock.Object
|
|
||||||
);
|
|
||||||
|
|
||||||
var dto = new ContentItem
|
|
||||||
{
|
|
||||||
Id = contentItemId,
|
|
||||||
Title = "New Title",
|
|
||||||
Description = "New Desc",
|
|
||||||
Content = newContent,
|
|
||||||
Language = "fr",
|
|
||||||
Tags = "tag2",
|
|
||||||
IsPublished = false,
|
|
||||||
LastUpdated = DateTime.UtcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = await service.SaveAndSyncContentItemAsync(dto, collectionName, false);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(dto.Title, result.Title);
|
|
||||||
Assert.Equal(dto.Description, result.Description);
|
|
||||||
Assert.Equal(dto.Content, result.Content);
|
|
||||||
Assert.Equal(dto.Language, result.Language);
|
|
||||||
Assert.Equal(dto.Tags, result.Tags);
|
|
||||||
Assert.Equal(dto.IsPublished, result.IsPublished);
|
|
||||||
Assert.True(result.Version > 0);
|
|
||||||
Assert.NotEmpty(dbContext.ContentChunks.Where(c => c.ContentItemId == contentItemId));
|
|
||||||
qdrantServiceMock.Verify(x => x.DeletePointsAsync(It.IsAny<Guid[]>(), collectionName), Times.Once);
|
|
||||||
qdrantServiceMock.Verify(x => x.QDrantInsertManyAsync(It.IsAny<List<WebPageContent>>(), collectionName), Times.Once);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.2" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.6" />
|
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
|
||||||
<PackageReference Include="Moq" Version="4.20.72" />
|
|
||||||
<PackageReference Include="xunit" Version="2.9.2" />
|
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\BLAIzor.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Using Include="Xunit" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
namespace SeemGen.Tests;
|
|
||||||
|
|
||||||
public class UnitTest1
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void Test1()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,127 +0,0 @@
|
||||||
using BLAIzor.Interfaces;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace BLAIzor.Services
|
|
||||||
{
|
|
||||||
public class BrightDataService : IBrightDataService
|
|
||||||
{
|
|
||||||
|
|
||||||
private readonly ISimpleLogger _logger;
|
|
||||||
private readonly IHttpClientFactory _httpClientFactory;
|
|
||||||
private string _apiToken;
|
|
||||||
public static IConfiguration? _configuration;
|
|
||||||
public BrightDataService(ISimpleLogger logger, IHttpClientFactory httpClientFactory, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_httpClientFactory = httpClientFactory;
|
|
||||||
_configuration = configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetScraperSettings() =>
|
|
||||||
_configuration?.GetSection("ScraperSettings")?.GetValue<string>("Provider") ?? string.Empty;
|
|
||||||
|
|
||||||
public string GetApiKey()
|
|
||||||
{
|
|
||||||
if (_configuration == null)
|
|
||||||
{
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
if (_configuration.GetSection("ScraperSettings") == null)
|
|
||||||
{
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _configuration.GetSection("ScraperSettings").GetValue<string>("ApiKey")!;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string?> ScrapeFacebookPostsAsync(string pageUrl, int numPosts = 10)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(pageUrl))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
_apiToken = GetApiKey();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = _httpClientFactory.CreateClient();
|
|
||||||
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiToken}");
|
|
||||||
|
|
||||||
var url = "https://api.brightdata.com/datasets/v3/trigger?dataset_id=gd_lkaxegm826bjpoo9m5&include_errors=true&limit_multiple_results=20";
|
|
||||||
|
|
||||||
var payload = new[]
|
|
||||||
{
|
|
||||||
new
|
|
||||||
{
|
|
||||||
url = pageUrl,
|
|
||||||
num_of_posts = numPosts,
|
|
||||||
posts_to_not_include = Array.Empty<string>(),
|
|
||||||
start_date = "",
|
|
||||||
end_date = ""
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var json = JsonSerializer.Serialize(payload);
|
|
||||||
var response = await client.PostAsync(url, new StringContent(json, Encoding.UTF8, "application/json"));
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
|
|
||||||
var scrapeId = await response.Content.ReadAsStringAsync();
|
|
||||||
//"snapshot_id
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(scrapeId))
|
|
||||||
{
|
|
||||||
await _logger.ErrorAsync("Failed to initiate scraping for Facebook posts.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//have to keep checking:
|
|
||||||
//result: "{\"snapshot_id\":\"s_mec12qv422avgbv9jl\"}"
|
|
||||||
//let's extract the scrapeId from the response
|
|
||||||
scrapeId = scrapeId.Trim('"').Split(':')[1].Trim('"');
|
|
||||||
//remove all other characters
|
|
||||||
scrapeId = scrapeId.Replace("{", "").Replace("}", "").Replace("\"", "");
|
|
||||||
|
|
||||||
var checkUrl = $"https://api.brightdata.com/datasets/v3/progress/{scrapeId}";
|
|
||||||
var statusResponse = await client.GetAsync(checkUrl);
|
|
||||||
var responseString = await statusResponse.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
int attempt = 0;
|
|
||||||
//make a cycle
|
|
||||||
|
|
||||||
while (responseString.Contains("status") && !responseString.Contains("ready"))
|
|
||||||
{
|
|
||||||
if (attempt >= 60)
|
|
||||||
{
|
|
||||||
await _logger.ErrorAsync($"Failed to get scraping status for Facebook page: {pageUrl} after multiple attempts.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Wait for a while before retrying
|
|
||||||
await Task.Delay(5000); // Wait for 5 seconds
|
|
||||||
statusResponse = await client.GetAsync(checkUrl);
|
|
||||||
responseString = await statusResponse.Content.ReadAsStringAsync();
|
|
||||||
attempt++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now fetch the snapshot
|
|
||||||
|
|
||||||
var snapshotUrl = $"https://api.brightdata.com/datasets/v3/snapshot/{scrapeId}?format=json";
|
|
||||||
|
|
||||||
var snapshotResponse = await client.GetAsync(snapshotUrl);
|
|
||||||
var snapshotString = await snapshotResponse.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
return snapshotString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error scraping Facebook: {ex.Message}");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
using BLAIzor.Models;
|
|
||||||
|
|
||||||
namespace BLAIzor.Services
|
|
||||||
{
|
|
||||||
public class CacheService
|
|
||||||
{
|
|
||||||
private readonly WebsiteContentLoaderService _websiteContentLoaderService;
|
|
||||||
private readonly ISimpleLogger _logger;
|
|
||||||
private readonly ScopedContentService _scopedContentService;
|
|
||||||
private readonly ContentEditorService _contentEditorService;
|
|
||||||
private readonly QDrantService _qDrantService;
|
|
||||||
|
|
||||||
public CacheService(
|
|
||||||
WebsiteContentLoaderService websiteContentLoaderService,
|
|
||||||
ISimpleLogger logger,
|
|
||||||
ScopedContentService scopedContentService,
|
|
||||||
ContentEditorService contentEditorService,
|
|
||||||
QDrantService qDrantService
|
|
||||||
)
|
|
||||||
{
|
|
||||||
_websiteContentLoaderService = websiteContentLoaderService;
|
|
||||||
_logger = logger;
|
|
||||||
_scopedContentService = scopedContentService;
|
|
||||||
_contentEditorService = contentEditorService;
|
|
||||||
_qDrantService = qDrantService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<WebsiteContentModel> UpdateContentCache(string sessionId, int siteId)
|
|
||||||
{
|
|
||||||
await _logger.InfoAsync($"UpdateCache: method called", $"sessionId: {sessionId}, siteId: {siteId}");
|
|
||||||
SiteInfo site = await _contentEditorService.GetSiteInfoByIdAsync(siteId);
|
|
||||||
WebsiteContentModel siteModel = null;
|
|
||||||
siteModel = await _websiteContentLoaderService.LoadAllAsync(
|
|
||||||
site,
|
|
||||||
_qDrantService.GetPointsFromQdrantAsyncByPointIds
|
|
||||||
);
|
|
||||||
_scopedContentService.WebsiteContentModel = siteModel;
|
|
||||||
return siteModel;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -82,10 +82,6 @@ namespace BLAIzor.Services
|
||||||
|
|
||||||
using var responseStream = await response.Content.ReadAsStreamAsync();
|
using var responseStream = await response.Content.ReadAsStreamAsync();
|
||||||
using var document = await JsonDocument.ParseAsync(responseStream);
|
using var document = await JsonDocument.ParseAsync(responseStream);
|
||||||
var inputTokens = document.RootElement.GetProperty("usage").GetProperty("prompt_tokens").GetInt32();
|
|
||||||
var outputTokens = document.RootElement.GetProperty("usage").GetProperty("completion_tokens").GetInt32();
|
|
||||||
var sum = inputTokens + outputTokens;
|
|
||||||
Console.WriteLine($"USAGE STATS - Tokens: {inputTokens.ToString()} + {outputTokens.ToString()} = {sum.ToString()}");
|
|
||||||
|
|
||||||
return document.RootElement
|
return document.RootElement
|
||||||
.GetProperty("choices")[0]
|
.GetProperty("choices")[0]
|
||||||
|
|
|
||||||
|
|
@ -1,308 +0,0 @@
|
||||||
using BLAIzor.Data;
|
|
||||||
using BLAIzor.Models;
|
|
||||||
using Microsoft.DotNet.Scaffolding.Shared;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Identity.Client;
|
|
||||||
|
|
||||||
namespace BLAIzor.Services
|
|
||||||
{
|
|
||||||
public class ContentEditorAIService
|
|
||||||
{
|
|
||||||
//private readonly AIService _aiService;
|
|
||||||
private readonly OpenAIApiService _openAIApiService;
|
|
||||||
private readonly OpenAiRealtimeService _openAIRealtimeService;
|
|
||||||
private readonly DeepSeekApiService _deepSeekApiService;
|
|
||||||
private readonly CerebrasAPIService _cerebrasAPIService;
|
|
||||||
private readonly KimiApiService _kimiApiService;
|
|
||||||
//private readonly ApplicationDbContext _context;
|
|
||||||
private readonly QDrantService _qDrantService;
|
|
||||||
private readonly HtmlSnippetProcessor _htmlSnippetProcessor;
|
|
||||||
private readonly IServiceScopeFactory _serviceScopeFactory;
|
|
||||||
private readonly ScopedContentService _scopedContentService;
|
|
||||||
private readonly ContentEditorService _contentEditorService;
|
|
||||||
private readonly ISimpleLogger _logger;
|
|
||||||
|
|
||||||
public static IConfiguration? _configuration;
|
|
||||||
|
|
||||||
public bool UseWebsocket = false;
|
|
||||||
private string AiProvider = "";
|
|
||||||
|
|
||||||
public ContentEditorAIService(
|
|
||||||
OpenAIApiService openAIApiService,
|
|
||||||
DeepSeekApiService deepSeekApiService,
|
|
||||||
OpenAiRealtimeService openAIRealtimeService,
|
|
||||||
CerebrasAPIService cerebrasAPIService,
|
|
||||||
KimiApiService kimiApiService,
|
|
||||||
/*ApplicationDbContext context,*/
|
|
||||||
QDrantService qDrantService,
|
|
||||||
HtmlSnippetProcessor htmlSnippetProcessor,
|
|
||||||
IServiceScopeFactory serviceScopeFactory,
|
|
||||||
ScopedContentService scopedContentService,
|
|
||||||
ISimpleLogger logger,
|
|
||||||
IConfiguration? configuration,
|
|
||||||
ContentEditorService contentEditorService)
|
|
||||||
{
|
|
||||||
//_aiService = aiService;
|
|
||||||
_openAIApiService = openAIApiService;
|
|
||||||
_deepSeekApiService = deepSeekApiService;
|
|
||||||
_openAIRealtimeService = openAIRealtimeService;
|
|
||||||
_cerebrasAPIService = cerebrasAPIService;
|
|
||||||
_kimiApiService = kimiApiService;
|
|
||||||
//_context = context;
|
|
||||||
_qDrantService = qDrantService;
|
|
||||||
_htmlSnippetProcessor = htmlSnippetProcessor;
|
|
||||||
_serviceScopeFactory = serviceScopeFactory;
|
|
||||||
_scopedContentService = scopedContentService;
|
|
||||||
_logger = logger;
|
|
||||||
_configuration = configuration;
|
|
||||||
_contentEditorService = contentEditorService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetAiEmbeddingSettings() =>
|
|
||||||
_configuration?.GetSection("AiSettings")?.GetValue<string>("EmbeddingService") ?? string.Empty;
|
|
||||||
|
|
||||||
private string GetAiSettings() =>
|
|
||||||
_configuration?.GetSection("AiSettings")?.GetValue<string>("Provider") ?? string.Empty;
|
|
||||||
|
|
||||||
// Existing methods
|
|
||||||
public async Task<string> GetMenuSuggestionsAsync(string sessionId, string prompt)
|
|
||||||
{
|
|
||||||
string systemMessage = "You are a helpful assistant that helps the user in creating a website.";
|
|
||||||
var result = await _openAIApiService.GetSimpleChatGPTResponse(sessionId, systemMessage, prompt);
|
|
||||||
|
|
||||||
//return result.Split('\n', StringSplitOptions.RemoveEmptyEntries)
|
|
||||||
// .Select(line => line.Trim('-').Trim())
|
|
||||||
// .ToList() ?? new List<string>();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string> GetFacebookContentAsync(string sessionId, string prompt)
|
|
||||||
{
|
|
||||||
string systemMessage = "You are a helpful assistant that helps the user in creating a website content from facebook posts.";
|
|
||||||
var result = await _openAIApiService.GetSimpleChatGPTResponse(sessionId, systemMessage, prompt);
|
|
||||||
await _logger.InfoAsync("Facebook content: " + result);
|
|
||||||
//return result.Split('\n', StringSplitOptions.RemoveEmptyEntries)
|
|
||||||
// .Select(line => line.Trim('-').Trim())
|
|
||||||
// .ToList() ?? new List<string>();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string> GetGeneratedContentAsync(string sessionId, string prompt)
|
|
||||||
{
|
|
||||||
string systemMessage = "You are a helpful assistant that helps the user plan the content of a website. Do not generate html, just plain text.";
|
|
||||||
//var result = await _openAIApiService.GetSimpleChatGPTResponse(sessionId, systemMessage, prompt);
|
|
||||||
string result = "";
|
|
||||||
|
|
||||||
AiProvider = GetAiSettings();
|
|
||||||
if (AiProvider == "cerebras")
|
|
||||||
{
|
|
||||||
result = await _cerebrasAPIService.GetSimpleCerebrasResponse(sessionId, systemMessage, prompt);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (AiProvider == "chatgpt")
|
|
||||||
{
|
|
||||||
result = await _openAIApiService.GetSimpleChatGPTResponse(sessionId, systemMessage, prompt);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (AiProvider == "deepseek")
|
|
||||||
{
|
|
||||||
//await _deepSeekApiService.GetChatGPTStreamedResponse(systemMessage, userMessage);
|
|
||||||
result = await _deepSeekApiService.GetSimpleChatGPTResponse(sessionId, systemMessage, prompt);
|
|
||||||
}
|
|
||||||
if (AiProvider == "kimi")
|
|
||||||
{
|
|
||||||
result = await _kimiApiService.GetSimpleChatGPTResponse(sessionId, systemMessage, prompt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string> GetPhotoPromptAsync(string sessionId, string prompt)
|
|
||||||
{
|
|
||||||
string systemMessage = "You are a helpful assistant that writes image prompts. Respond only with the image prompt, no explanation, or information added.";
|
|
||||||
//var result = await _openAIApiService.GetSimpleChatGPTResponse(sessionId, systemMessage, prompt);
|
|
||||||
string result = "";
|
|
||||||
|
|
||||||
AiProvider = GetAiSettings();
|
|
||||||
if (AiProvider == "cerebras")
|
|
||||||
{
|
|
||||||
result = await _cerebrasAPIService.GetSimpleCerebrasResponse(sessionId, systemMessage, prompt);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (AiProvider == "chatgpt")
|
|
||||||
{
|
|
||||||
result = await _openAIApiService.GetSimpleChatGPTResponse(sessionId, systemMessage, prompt);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (AiProvider == "deepseek")
|
|
||||||
{
|
|
||||||
//await _deepSeekApiService.GetChatGPTStreamedResponse(systemMessage, userMessage);
|
|
||||||
result = await _deepSeekApiService.GetSimpleChatGPTResponse(sessionId, systemMessage, prompt);
|
|
||||||
}
|
|
||||||
if (AiProvider == "kimi")
|
|
||||||
{
|
|
||||||
result = await _kimiApiService.GetSimpleChatGPTResponse(sessionId, systemMessage, prompt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<string> ProcessMenuItems(int SiteId, bool hasCollection, List<MenuItemModel> ExtractedMenuItems, string subject, bool menuItemsSaved, bool updateVectorDatabase)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
if (!hasCollection)
|
|
||||||
{
|
|
||||||
//create colection
|
|
||||||
await _qDrantService.CreateQdrantCollectionAsync("Site" + SiteId.ToString());
|
|
||||||
hasCollection = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//check if Collection is really created already
|
|
||||||
var collection = await _qDrantService.GetCollectionCount("Site" + SiteId.ToString());
|
|
||||||
if (collection != null)
|
|
||||||
{
|
|
||||||
var siteInfo = await _contentEditorService.GetSiteInfoByIdAsync(SiteId);
|
|
||||||
if (siteInfo.EmbeddingService != null)
|
|
||||||
{
|
|
||||||
var currentEmbeddingServiceName = GetAiEmbeddingSettings();
|
|
||||||
if (siteInfo.EmbeddingService == currentEmbeddingServiceName)
|
|
||||||
{
|
|
||||||
//drop existing collection
|
|
||||||
await _qDrantService.DeleteCollectionAsync("Site" + SiteId.ToString());
|
|
||||||
//create will automatically handle the new vector size
|
|
||||||
await _qDrantService.CreateQdrantCollectionAsync("Site" + SiteId.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var updateQdrantList = ExtractedMenuItems.OrderBy(mi => mi.MenuItem.ContentGroup.Items.FirstOrDefault().Id).ToList(); //FIXXXXXXX
|
|
||||||
|
|
||||||
for (int i = 0; i < updateQdrantList.Count(); i++)
|
|
||||||
{
|
|
||||||
MenuItem menuItem = new MenuItem();
|
|
||||||
menuItem.Name = ExtractedMenuItems[i].MenuItem.Name;
|
|
||||||
menuItem.SortOrder = i;
|
|
||||||
menuItem.SiteInfoId = SiteId;
|
|
||||||
menuItem.ShowInMainMenu = true;
|
|
||||||
if (!string.IsNullOrEmpty(ExtractedMenuItems[i].Content)) //if we have content in the menuItem, let's update the vector DB
|
|
||||||
{
|
|
||||||
if (updateVectorDatabase)
|
|
||||||
{
|
|
||||||
Guid guid = Guid.NewGuid();
|
|
||||||
WebPageContent content = new WebPageContent();
|
|
||||||
content.Id = guid;
|
|
||||||
content.UId = guid.ToString();
|
|
||||||
content.Type = "page";
|
|
||||||
content.SiteId = SiteId;
|
|
||||||
content.Name = ExtractedMenuItems[i].MenuItem.Name;
|
|
||||||
if (ExtractedMenuItems[i].ContentDescription == null)
|
|
||||||
{
|
|
||||||
content.Description = $"A section called {ExtractedMenuItems[i].MenuItem.Name} of a website of {subject}";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
content.Description = ExtractedMenuItems[i].ContentDescription;
|
|
||||||
}
|
|
||||||
content.Content = ExtractedMenuItems[i].Content;
|
|
||||||
content.LastUpdated = DateTime.UtcNow;
|
|
||||||
//menuItem.QdrantPointId = guid; //FIXXXXXXX
|
|
||||||
//menuItem.PointId = i; //FIXXXXXXX
|
|
||||||
await _htmlSnippetProcessor.ProcessAndStoreWebContentAsync(guid, content, SiteId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//menuItem.PointId = i; //FIXXXXXXX
|
|
||||||
//menuItem.QdrantPointId = ExtractedMenuItems[i].MenuItem.QdrantPointId; //FIXXXXXXX
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!menuItemsSaved) //menuItems just extracted, no content yet because that can be generated only after menuItems have been saved first
|
|
||||||
{
|
|
||||||
//menuItem.Name = ExtractedMenuItems[i].MenuItem.Name;
|
|
||||||
//menuItem.SortOrder = i;
|
|
||||||
//menuItem.SiteInfoId = SiteId;
|
|
||||||
//menuItem.ShowInMainMenu = true;
|
|
||||||
await _contentEditorService.AddMenuItemAsync(menuItem);
|
|
||||||
}
|
|
||||||
else //menuItems available already
|
|
||||||
{
|
|
||||||
var menuItems = await _contentEditorService.GetMenuItemsBySiteIdAsync(SiteId);
|
|
||||||
var thisItem = menuItems.FirstOrDefault(x => x.SiteInfoId == SiteId && x.Id == ExtractedMenuItems[i].MenuItem.Id);
|
|
||||||
if (thisItem == null)
|
|
||||||
{
|
|
||||||
//new menu item?
|
|
||||||
await _contentEditorService.AddMenuItemAsync(menuItem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//thisItem.PointId = menuItem.PointId; //FIXXXXXXX
|
|
||||||
//thisItem.QdrantPointId = menuItem.QdrantPointId; //FIXXXXXXX
|
|
||||||
thisItem.SortOrder = ExtractedMenuItems[i].MenuItem.SortOrder;
|
|
||||||
thisItem.ShowInMainMenu = ExtractedMenuItems[i].MenuItem.ShowInMainMenu;
|
|
||||||
await _contentEditorService.UpdateMenuItemAsync(thisItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//await ContentEditorService.SaveMenuItemsAsync(menuItems);
|
|
||||||
//menuItemsSaved = true;
|
|
||||||
return "OK";
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return "Error";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//public async Task<string> AnalyzeFormFieldsFromText(string text)
|
|
||||||
//{
|
|
||||||
// string systemMessage = "You are a helpful assistant that extracts structured form field data from plain text.";
|
|
||||||
|
|
||||||
// string userMessage =
|
|
||||||
// "This is the plain text extracted from a form document. " +
|
|
||||||
// "Please extract all input fields a user is expected to fill in and return a JSON array of objects.\n\n" +
|
|
||||||
// "Each object should have the following structure:\n" +
|
|
||||||
// "- `label`: The label or prompt for the input\n" +
|
|
||||||
// "- `type`: One of `text`, `number`, `date`, `checkbox`, `radio`, or `textarea`\n" +
|
|
||||||
// "- `options`: If type is `radio` or `checkbox`, include the possible options as a list of strings; otherwise, return an empty list\n" +
|
|
||||||
// "- `section`: The section title this field belongs to (if any)\n" +
|
|
||||||
// "- `repeatable`: true if this field (or set of fields) is expected to be repeated for multiple entries (like multiple employers or qualifications), otherwise false\n\n" +
|
|
||||||
// "Return only the JSON array, without any explanation or formatting like ```json.\n\n" +
|
|
||||||
// "Here is the form text:\n\n" +
|
|
||||||
// $"---\n{text}\n---";
|
|
||||||
|
|
||||||
// return await _openAIApiService.GetSimpleChatGPTResponseNoSession(systemMessage, userMessage).ConfigureAwait(false);
|
|
||||||
//}
|
|
||||||
|
|
||||||
public async Task<string> AnalyzeGroupedFormFieldsFromText(string text)
|
|
||||||
{
|
|
||||||
string systemMessage = "You are a helpful assistant that analyzes plain form text and extracts structured, grouped form field definitions.";
|
|
||||||
|
|
||||||
string userMessage =
|
|
||||||
"This is a plain text version of a printed form. Your task is to extract the **input fields** that a user must fill in. " +
|
|
||||||
"Group related fields under sections where applicable, and return them in a JSON structure.\n\n" +
|
|
||||||
"Each group should follow this structure:\n" +
|
|
||||||
"- `groupName`: Name of the logical section or group (e.g. 'Work Experience')\n" +
|
|
||||||
"- `repeatable`: true if this section can appear multiple times (e.g. multiple employers, qualifications)\n" +
|
|
||||||
"- `fields`: an array of fields within the group\n\n" +
|
|
||||||
"Each field must have:\n" +
|
|
||||||
"- `label`: The field label/question\n" +
|
|
||||||
"- `type`: one of `text`, `number`, `date`, `textarea`, `checkbox`, or `radio`\n" +
|
|
||||||
"- `options`: list of string values if type is `radio` or `checkbox`, or an empty list otherwise\n" +
|
|
||||||
"- `section`: optional section name (can match group name or be more specific)\n\n" +
|
|
||||||
"Return only the JSON array. Do not include any explanation or formatting like ```json.\n\n" +
|
|
||||||
$"Here is the form text:\n\n---\n{text}\n---";
|
|
||||||
|
|
||||||
return await _openAIApiService.GetSimpleChatGPTResponseNoSession(systemMessage, userMessage).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Numerics;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BLAIzor.Models;
|
using BLAIzor.Models;
|
||||||
using DocumentFormat.OpenXml.Office2010.Excel;
|
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||||
|
|
@ -17,18 +16,16 @@ namespace BLAIzor.Services
|
||||||
|
|
||||||
public class HtmlSnippetProcessor
|
public class HtmlSnippetProcessor
|
||||||
{
|
{
|
||||||
private readonly OpenAIEmbeddingService _openAIEmbeddingService;
|
private readonly OpenAIEmbeddingService _embeddingService;
|
||||||
private readonly LocalEmbeddingService _localEmbeddingService;
|
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly QDrantService _drantService;
|
private readonly QDrantService _drantService;
|
||||||
public static IConfiguration? _configuration;
|
public static IConfiguration? _configuration;
|
||||||
private string _qdrantApiKey;
|
private string _qdrantApiKey;
|
||||||
|
|
||||||
public HtmlSnippetProcessor(QDrantService drantService, OpenAIEmbeddingService openAIEmbeddingService, LocalEmbeddingService localEmbeddingService, IConfiguration? configuration)
|
public HtmlSnippetProcessor(QDrantService drantService, IConfiguration? configuration)
|
||||||
{
|
{
|
||||||
_drantService = drantService;
|
_drantService = drantService;
|
||||||
_openAIEmbeddingService = openAIEmbeddingService;
|
_embeddingService = new OpenAIEmbeddingService();
|
||||||
_localEmbeddingService = localEmbeddingService;
|
|
||||||
_httpClient = new HttpClient();
|
_httpClient = new HttpClient();
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
@ -38,9 +35,6 @@ namespace BLAIzor.Services
|
||||||
return _configuration?.GetSection("QDrant")?.GetValue<string>("ApiKey") ?? string.Empty;
|
return _configuration?.GetSection("QDrant")?.GetValue<string>("ApiKey") ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetAiEmbeddingSettings() =>
|
|
||||||
_configuration?.GetSection("AiSettings")?.GetValue<string>("EmbeddingService") ?? string.Empty;
|
|
||||||
|
|
||||||
//public async Task ProcessAndStoreSnippetsAsync()
|
//public async Task ProcessAndStoreSnippetsAsync()
|
||||||
//{
|
//{
|
||||||
// _qdrantApiKey = GetApiKey();
|
// _qdrantApiKey = GetApiKey();
|
||||||
|
|
@ -100,27 +94,14 @@ namespace BLAIzor.Services
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
// Combine details to generate the embedding
|
// Combine details to generate the embedding
|
||||||
var combinedText = $"{snippet.Name}: {snippet.Description}. " +
|
var combinedText = $"{snippet.Name}: {snippet.Description}. " +
|
||||||
$"Type: {snippet.Type}. " +
|
$"Type: {snippet.Type}. " +
|
||||||
$"Variant: {snippet.Variant ?? "default"}. " +
|
$"Variant: {snippet.Variant ?? "default"}. " +
|
||||||
$"Tags: {snippet.Tags}. " +
|
$"Tags: {snippet.Tags}. " +
|
||||||
$"HTML: {snippet.Html}";
|
$"HTML: {snippet.Html}";
|
||||||
|
var embedding = await _embeddingService.GenerateEmbeddingAsync(combinedText);
|
||||||
float[] embedding = [];
|
|
||||||
|
|
||||||
var embeddingServiceProvider = GetAiEmbeddingSettings();
|
|
||||||
//if (embeddingServiceProvider == "local")
|
|
||||||
//{
|
|
||||||
// embedding = await _localEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
|
||||||
//}
|
|
||||||
embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
|
||||||
|
|
||||||
|
|
||||||
// Add data for batch insertion
|
// Add data for batch insertion
|
||||||
ids.Add(snippet.Id);
|
ids.Add(snippet.Id);
|
||||||
|
|
@ -129,7 +110,7 @@ namespace BLAIzor.Services
|
||||||
{
|
{
|
||||||
["type"] = snippet.Type,
|
["type"] = snippet.Type,
|
||||||
["name"] = snippet.Name,
|
["name"] = snippet.Name,
|
||||||
["variant"] = string.IsNullOrWhiteSpace(snippet.Variant) ? "" : snippet.Variant,
|
["variant"] = string.IsNullOrWhiteSpace(snippet.Variant)? "" : snippet.Variant,
|
||||||
["tags"] = snippet.Tags,
|
["tags"] = snippet.Tags,
|
||||||
["description"] = snippet.Description,
|
["description"] = snippet.Description,
|
||||||
["html"] = snippet.Html,
|
["html"] = snippet.Html,
|
||||||
|
|
@ -152,114 +133,95 @@ namespace BLAIzor.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//public async Task ProcessAndStoreWebContentsAsync(List<WebPageContent> pageContentList, int siteId)
|
public async Task ProcessAndStoreWebContentsAsync(List<WebPageContent> pageContentList, int siteId)
|
||||||
//{
|
|
||||||
// _qdrantApiKey = GetApiKey();
|
|
||||||
|
|
||||||
// var ids = new List<int>();
|
|
||||||
// var vectors = new List<float[]>();
|
|
||||||
// var payloads = new List<MapField<string, Value>>();
|
|
||||||
|
|
||||||
// foreach (var content in pageContentList)
|
|
||||||
// {
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// // Combine details to generate the embedding
|
|
||||||
// var combinedText = $"{content.Name}: Description: {content.Description}, complete text: {content.Content}";
|
|
||||||
|
|
||||||
// float[] embedding = [];
|
|
||||||
|
|
||||||
// var embeddingServiceProvider = GetAiEmbeddingSettings();
|
|
||||||
// if (embeddingServiceProvider == "local")
|
|
||||||
// {
|
|
||||||
// embedding = await _localEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Add data for batch insertion
|
|
||||||
// ids.Add(content.Id);
|
|
||||||
// vectors.Add(embedding);
|
|
||||||
|
|
||||||
|
|
||||||
// payloads.Add(new MapField<string, Value>
|
|
||||||
// {
|
|
||||||
// ["uid"] = content.UId,
|
|
||||||
// ["type"] = content.Type,
|
|
||||||
// ["siteId"] = content.SiteId,
|
|
||||||
// //["menuItemId"] = content.MenuItemId,
|
|
||||||
// ["name"] = content.Name,
|
|
||||||
// ["description"] = content.Description,
|
|
||||||
// ["content"] = content.Content,
|
|
||||||
// ["lastUpdated"] = content.LastUpdated.ToString()
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// catch (Exception ex)
|
|
||||||
// {
|
|
||||||
// Console.WriteLine($"Error processing content {content.Name}: {ex.Message}");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (ids.Count > 0)
|
|
||||||
// {
|
|
||||||
// await _drantService.QDrantInsertManyAsync(ids, vectors, payloads, "Site" + siteId);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// Console.WriteLine("No points were processed successfully.");
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
public async Task ProcessAndStoreWebContentAsync(PointId id, WebPageContent pageContent, int siteId)
|
|
||||||
{
|
{
|
||||||
_qdrantApiKey = GetApiKey();
|
_qdrantApiKey = GetApiKey();
|
||||||
|
|
||||||
|
var ids = new List<int>();
|
||||||
|
var vectors = new List<float[]>();
|
||||||
|
var payloads = new List<MapField<string, Value>>();
|
||||||
|
|
||||||
|
foreach (var content in pageContentList)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Combine details to generate the embedding
|
||||||
|
var combinedText = $"{content.Name}: Description: {content.Description}, complete text: {content.Content}";
|
||||||
|
var embedding = await _embeddingService.GenerateEmbeddingAsync(combinedText);
|
||||||
|
|
||||||
|
// Add data for batch insertion
|
||||||
|
ids.Add(content.Id);
|
||||||
|
vectors.Add(embedding);
|
||||||
|
|
||||||
|
|
||||||
|
payloads.Add(new MapField<string, Value>
|
||||||
|
{
|
||||||
|
["uid"] = content.UId,
|
||||||
|
["type"] = content.Type,
|
||||||
|
["siteId"] = content.SiteId,
|
||||||
|
//["menuItemId"] = content.MenuItemId,
|
||||||
|
["name"] = content.Name,
|
||||||
|
["description"] = content.Description,
|
||||||
|
["content"] = content.Content,
|
||||||
|
["lastUpdated"] = content.LastUpdated.ToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error processing content {content.Name}: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ids.Count > 0)
|
||||||
|
{
|
||||||
|
await _drantService.QDrantInsertManyAsync(ids, vectors, payloads, "Site"+siteId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("No points were processed successfully.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ProcessAndStoreWebContentAsync(int id, WebPageContent pageContent, int siteId)
|
||||||
|
{
|
||||||
|
_qdrantApiKey = GetApiKey();
|
||||||
|
|
||||||
|
|
||||||
float[] vectors = [];
|
float[] vectors = [];
|
||||||
var payload = new MapField<string, Value>();
|
var payload = new MapField<string, Value>();
|
||||||
|
|
||||||
try
|
|
||||||
{
|
try
|
||||||
// Combine details to generate the embedding
|
|
||||||
var combinedText = $"{pageContent.Name}: {pageContent.Description} - {pageContent.Content}";
|
|
||||||
float[] embedding = [];
|
|
||||||
|
|
||||||
var embeddingServiceProvider = GetAiEmbeddingSettings();
|
|
||||||
if (embeddingServiceProvider == "local")
|
|
||||||
{
|
{
|
||||||
embedding = await _localEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
// Combine details to generate the embedding
|
||||||
|
var combinedText = $"{pageContent.Name}: {pageContent.Description} - {pageContent.Content}";
|
||||||
|
var embedding = await _embeddingService.GenerateEmbeddingAsync(combinedText);
|
||||||
|
|
||||||
|
// Add data for batch insertion
|
||||||
|
|
||||||
|
vectors = embedding;
|
||||||
|
|
||||||
|
|
||||||
|
payload = new MapField<string, Value>
|
||||||
|
{
|
||||||
|
["uid"] = pageContent.UId,
|
||||||
|
["type"] = pageContent.Type,
|
||||||
|
["siteId"] = pageContent.SiteId,
|
||||||
|
//["menuItemId"] = pageContent.MenuItemId,
|
||||||
|
["name"] = pageContent.Name,
|
||||||
|
["description"] = pageContent.Description,
|
||||||
|
["content"] = pageContent.Content,
|
||||||
|
["lastUpdated"] = pageContent.LastUpdated.ToString()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
Console.WriteLine($"Error processing content {pageContent.Name}: {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add data for batch insertion
|
|
||||||
|
await _drantService.QDrantInsertPointAsync(id, vectors, payload, "Site"+siteId);
|
||||||
vectors = embedding;
|
|
||||||
|
|
||||||
|
|
||||||
payload = new MapField<string, Value>
|
|
||||||
{
|
|
||||||
["uid"] = pageContent.UId,
|
|
||||||
["type"] = pageContent.Type,
|
|
||||||
["siteId"] = pageContent.SiteId,
|
|
||||||
//["menuItemId"] = pageContent.MenuItemId,
|
|
||||||
["name"] = pageContent.Name,
|
|
||||||
["description"] = pageContent.Description,
|
|
||||||
["content"] = pageContent.Content,
|
|
||||||
["lastUpdated"] = pageContent.LastUpdated.ToString()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error processing content {pageContent.Name}: {ex.Message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
await _drantService.QDrantInsertPointAsync(id, vectors, payload, "Site" + siteId);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<HtmlSnippet> GetHtmlSnippets()
|
private List<HtmlSnippet> GetHtmlSnippets()
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue