Agent Tests for API, MAUI, and Slop Features

This commit is contained in:
2026-06-03 19:08:35 -04:00
parent 46150d3a69
commit 0feac0f0a0
142 changed files with 4156 additions and 1462 deletions
@@ -0,0 +1,98 @@
@layout PageLayout
@inject IGlossaryService glossaryService
@inject IGlossaryDialogService glossaryDialogService
@inject NavigationManager NavigationManager
@page "/glossary/{TermId}"
<LayoutMediumContentComponent>
@if (term != null)
{
<WebsiteTitleComponent>@term.Term</WebsiteTitleComponent>
<PaperComponent>
<div class="detailCategory">@term.Category</div>
<div class="detailDefinition">@((MarkupString)RenderMarkdown(term.LongDefinition))</div>
</PaperComponent>
@if (term.RelatedEntityIds.Count > 0)
{
<PaperComponent>
<div class="detailSectionTitle">Related Entities</div>
<div class="detailRelatedList">
@foreach (var entityId in term.RelatedEntityIds)
{
<EntityLabelComponent EntityId="@entityId"/>
}
</div>
</PaperComponent>
}
@if (term.RelatedTermIds.Count > 0)
{
<PaperComponent>
<div class="detailSectionTitle">Related Terms</div>
<div class="detailRelatedList">
@foreach (var relatedId in term.RelatedTermIds)
{
<GlossaryLabelComponent TermId="@relatedId"/>
}
</div>
</PaperComponent>
}
}
else
{
<WebsiteTitleComponent>Term not found</WebsiteTitleComponent>
<PaperComponent>
<p>The glossary term you're looking for doesn't exist.</p>
</PaperComponent>
}
</LayoutMediumContentComponent>
<style>
.detailCategory {
font-size: 0.85rem;
opacity: 0.7;
margin-bottom: 12px;
}
.detailDefinition {
line-height: 1.6;
font-size: 1rem;
}
.detailDefinition p {
margin-bottom: 12px;
}
.detailSectionTitle {
font-weight: 800;
font-size: 1.1rem;
margin-bottom: 12px;
}
.detailRelatedList {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
</style>
@code {
[Parameter] public string TermId { get; set; } = "";
private GlossaryTermModel? term;
protected override void OnParametersSet()
{
term = glossaryService.GetTerm(TermId);
}
string RenderMarkdown(string text)
{
return Markdown.ToHtml(text);
}
}
+178
View File
@@ -0,0 +1,178 @@
@layout PageLayout
@inherits BasePage
@inject IGlossaryService glossaryService
@inject IGlossaryDialogService glossaryDialogService
@page "/glossary"
<LayoutLargeContentComponent>
<WebsiteTitleComponent>Glossary</WebsiteTitleComponent>
<div class="glossaryControls">
<input class="glossarySearch" @bind="searchText" @bind:after="OnSearchChanged" placeholder="Search terms..."/>
<div class="glossaryCategories">
<button class="glossaryCategory @(selectedCategory == null ? "active" : "")"
@onclick="() => SelectCategory(null)">All
</button>
@foreach (var cat in categories)
{
<button class="glossaryCategory @(selectedCategory == cat ? "active" : "")"
@onclick="() => SelectCategory(cat)">@cat</button>
}
</div>
</div>
<div class="glossaryGrid">
@foreach (var term in filteredTerms)
{
<PaperComponent>
<div class="glossaryCard" @onclick="() => glossaryDialogService.AddDialog(term.Id)">
<div class="glossaryCardHeader">
<span class="glossaryCardTerm">@term.Term</span>
<span class="glossaryCardCategory">@term.Category</span>
</div>
<div class="glossaryCardBody">@term.ShortDefinition</div>
</div>
</PaperComponent>
}
</div>
</LayoutLargeContentComponent>
<style>
.glossaryControls {
display: flex;
flex-direction: column;
gap: 12px;
margin-bottom: 20px;
}
.glossarySearch {
padding: 10px 16px;
border-radius: 8px;
border: 2px solid var(--primary-border);
background-color: var(--primary);
color: white;
font-size: 1rem;
font-family: inherit;
width: 100%;
max-width: 500px;
}
.glossarySearch::placeholder {
color: rgba(255, 255, 255, 0.5);
}
.glossaryCategories {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.glossaryCategory {
padding: 6px 14px;
border-radius: 16px;
border: 2px solid var(--primary-border);
background-color: var(--primary);
color: white;
cursor: pointer;
font-family: inherit;
font-size: 0.85rem;
font-weight: 600;
}
.glossaryCategory.active {
background-color: var(--primary-hover);
border-color: var(--primary-border-hover);
}
.glossaryCategory:hover {
background-color: var(--primary-hover);
}
.glossaryGrid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 16px;
}
.glossaryCard {
cursor: pointer;
}
.glossaryCardHeader {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.glossaryCardTerm {
font-weight: 800;
font-size: 1.1rem;
}
.glossaryCardCategory {
font-size: 0.8rem;
opacity: 0.7;
}
.glossaryCardBody {
font-size: 0.9rem;
line-height: 1.4;
opacity: 0.9;
}
@@media only screen and (max-width: 1025px) {
.glossaryGrid {
grid-template-columns: 1fr;
}
}
</style>
@code {
private string searchText = "";
private string? selectedCategory;
private List<string> categories = new();
private List<GlossaryTermModel> allTerms = new();
private List<GlossaryTermModel> filteredTerms = new();
protected override void OnInitialized()
{
base.OnInitialized();
allTerms = glossaryService.GetAllTerms();
categories = glossaryService.GetCategories();
ApplyFilter();
}
void OnSearchChanged()
{
ApplyFilter();
}
void SelectCategory(string? category)
{
selectedCategory = category;
ApplyFilter();
}
void ApplyFilter()
{
var query = allTerms.AsEnumerable();
if (!string.IsNullOrWhiteSpace(searchText))
{
query = query.Where(t =>
t.Term.Contains(searchText, StringComparison.OrdinalIgnoreCase) ||
t.ShortDefinition.Contains(searchText, StringComparison.OrdinalIgnoreCase));
}
if (selectedCategory != null)
{
query = query.Where(t =>
t.Category.Equals(selectedCategory, StringComparison.OrdinalIgnoreCase));
}
filteredTerms = query.ToList();
}
}