From edead7077723389673285da167b9ad7621d5031a Mon Sep 17 00:00:00 2001 From: Bryan Jonker Date: Tue, 31 Mar 2026 13:03:56 -0500 Subject: [PATCH] Add order by, option for URL fragment, normalize draft and internal notes, change button --- .../DataHelpers/InstructionHelper.cs | 13 +- .../DataHelpers/SourceHelper.cs | 37 +- .../DataModels/Source.cs | 6 + .../20260331172431_AddFragment.Designer.cs | 559 ++++++++++++++++++ .../Migrations/20260331172431_AddFragment.cs | 113 ++++ .../ResourceContextModelSnapshot.cs | 30 +- .../PageList/PageGroup.cs | 2 +- .../Getters/BaseGetter.cs | 2 +- .../Getters/PublicationGetter.cs | 16 +- .../Components/Controls/InstructionList.razor | 16 +- .../Controls/InstructionList.razor.cs | 10 +- .../Components/Layout/NavMenu.razor | 2 +- .../Pages/Configuration/Deletion.razor | 6 +- .../Pages/Configuration/Email.razor | 2 +- .../Pages/Configuration/Filters.razor | 4 +- .../Pages/Configuration/Sources.razor | 2 +- .../Components/Pages/Event/Detail.razor | 2 +- .../Components/Pages/Event/Filters.razor | 2 +- .../Components/Pages/Event/General.razor | 12 +- .../Components/Pages/Event/General.razor.cs | 3 +- .../Components/Pages/Event/Image.razor | 2 +- .../Components/Pages/Event/RelatedLinks.razor | 2 +- .../Components/Pages/Event/Technical.razor | 36 +- .../Components/Pages/Event/Technical.razor.cs | 25 +- .../Components/Pages/Faq/Detail.razor | 2 +- .../Components/Pages/Faq/Filters.razor | 2 +- .../Components/Pages/Faq/General.razor | 11 +- .../Components/Pages/Faq/General.razor.cs | 3 +- .../Components/Pages/Faq/Image.razor | 2 +- .../Components/Pages/Faq/RelatedLinks.razor | 2 +- .../Components/Pages/Faq/Technical.razor | 36 +- .../Components/Pages/Faq/Technical.razor.cs | 25 +- .../Components/Pages/Note/Detail.razor | 2 +- .../Components/Pages/Note/Filters.razor | 2 +- .../Components/Pages/Note/General.razor | 12 +- .../Components/Pages/Note/General.razor.cs | 3 +- .../Components/Pages/Note/Image.razor | 2 +- .../Components/Pages/Note/RelatedLinks.razor | 2 +- .../Components/Pages/Note/Technical.razor | 36 +- .../Components/Pages/Note/Technical.razor.cs | 26 +- .../Components/Pages/Person/Filters.razor | 2 +- .../Components/Pages/Person/General.razor | 12 +- .../Components/Pages/Person/General.razor.cs | 3 +- .../Components/Pages/Person/Image.razor | 2 +- .../Pages/Person/RelatedLinks.razor | 2 +- .../Components/Pages/Person/Technical.razor | 21 +- .../Pages/Person/Technical.razor.cs | 1 - .../Components/Pages/Publication/Detail.razor | 2 +- .../Pages/Publication/Filters.razor | 2 +- .../Pages/Publication/General.razor | 12 +- .../Pages/Publication/General.razor.cs | 3 +- .../Components/Pages/Publication/Image.razor | 2 +- .../Pages/Publication/RelatedLinks.razor | 2 +- .../Pages/Publication/Technical.razor | 36 +- .../Pages/Publication/Technical.razor.cs | 27 +- .../Components/Pages/Resource/Filters.razor | 2 +- .../Components/Pages/Resource/General.razor | 11 +- .../Pages/Resource/General.razor.cs | 3 +- .../Components/Pages/Resource/Image.razor | 2 +- .../Pages/Resource/RelatedLinks.razor | 2 +- .../Components/Pages/Resource/Technical.razor | 29 +- .../Pages/Resource/Technical.razor.cs | 25 +- 62 files changed, 1156 insertions(+), 119 deletions(-) create mode 100644 ResourceInformationV2.Data/Migrations/20260331172431_AddFragment.Designer.cs create mode 100644 ResourceInformationV2.Data/Migrations/20260331172431_AddFragment.cs diff --git a/ResourceInformationV2.Data/DataHelpers/InstructionHelper.cs b/ResourceInformationV2.Data/DataHelpers/InstructionHelper.cs index 5a76ca0..0ac71b2 100644 --- a/ResourceInformationV2.Data/DataHelpers/InstructionHelper.cs +++ b/ResourceInformationV2.Data/DataHelpers/InstructionHelper.cs @@ -7,36 +7,43 @@ namespace ResourceInformationV2.Data.DataHelpers { public class InstructionHelper(ResourceRepository resourceRepository) { private readonly ResourceRepository _resourceRepository = resourceRepository; - public async Task<(List, bool)> GetInstructions(string code, CategoryType categoryType) { + public async Task<(List, bool, bool)> GetInstructions(string code, CategoryType categoryType) { var instructions = (await _resourceRepository.ReadAsync(c => c.Instructions.Include(i => i.Source).Where(i => i.CategoryType == categoryType && i.Source.Code == code))).ToList(); var source = instructions == null || instructions.Count == 0 ? await _resourceRepository.ReadAsync(c => c.Sources.FirstOrDefault(s => s.Code == code)) : instructions[0].Source; - bool isUsed = false; + var isUsed = false; + var useFragment = false; switch (categoryType) { case CategoryType.Event: isUsed = source?.UseEvents ?? false; + useFragment = source?.UseEventsFragment ?? false; break; case CategoryType.Faq: isUsed = source?.UseFaqs ?? false; + useFragment = source?.UseFaqsFragment ?? false; break; case CategoryType.Note: isUsed = source?.UseNotes ?? false; + useFragment = source?.UseNotesFragment ?? false; break; case CategoryType.Person: isUsed = source?.UsePeople ?? false; + useFragment = source?.UsePeopleFragment ?? false; break; case CategoryType.Publication: isUsed = source?.UsePublications ?? false; + useFragment = source?.UsePublicationsFragment ?? false; break; case CategoryType.Resource: isUsed = source?.UseResources ?? false; + useFragment = source?.UseResourcesFragment ?? false; break; } - return (instructions ?? [], isUsed); + return (instructions ?? [], isUsed, useFragment); } public async Task GetInstructionText(string sourceCode, CategoryType categoryType, FieldType fieldType) => await _resourceRepository diff --git a/ResourceInformationV2.Data/DataHelpers/SourceHelper.cs b/ResourceInformationV2.Data/DataHelpers/SourceHelper.cs index 3d14293..d40d3f6 100644 --- a/ResourceInformationV2.Data/DataHelpers/SourceHelper.cs +++ b/ResourceInformationV2.Data/DataHelpers/SourceHelper.cs @@ -68,6 +68,35 @@ public async Task DoesSourceUseItem(string sourceCode, CategoryType catego return false; } + public async Task DoesSourceUseFragment(string sourceCode, CategoryType categoryType) { + var source = await _resourceRepository.ReadAsync(c => c.Sources.FirstOrDefault(s => s.Code == sourceCode)); + if (source == null) { + return false; + } + switch (categoryType) { + case CategoryType.Event: + return source.UseEventsFragment; + + case CategoryType.Faq: + return source.UseFaqsFragment; + + case CategoryType.Note: + return source.UseNotesFragment; + + case CategoryType.Resource: + return source.UseResourcesFragment; + + case CategoryType.Person: + return source.UsePeopleFragment; + + case CategoryType.Publication: + return source.UsePublicationsFragment; + case CategoryType.None: + break; + } + return false; + } + public async Task<(bool eventItem, bool faqItem, bool noteItem, bool resourceItem, bool personItem, bool publicationItem)> DoesSourceUseItemCheckAll(string sourceCode) { var source = await _resourceRepository.ReadAsync(c => c.Sources.FirstOrDefault(s => s.Code == sourceCode)); return source == null ? (false, false, false, false, false, false) : @@ -175,7 +204,7 @@ public async Task SetSourceFilterOrder(string sourceCode, string order) { return source.Id; } - public async Task SetSourceItem(string sourceCode, CategoryType categoryType, bool isUsed) { + public async Task SetSourceItem(string sourceCode, CategoryType categoryType, bool isUsed, bool useFragment) { var source = await _resourceRepository.ReadAsync(c => c.Sources.FirstOrDefault(s => s.Code == sourceCode)); if (source == null) { return 0; @@ -183,26 +212,32 @@ public async Task SetSourceItem(string sourceCode, CategoryType categoryTyp switch (categoryType) { case CategoryType.Event: source.UseEvents = isUsed; + source.UseEventsFragment = useFragment; break; case CategoryType.Faq: source.UseFaqs = isUsed; + source.UseFaqsFragment = useFragment; break; case CategoryType.Note: source.UseNotes = isUsed; + source.UseNotesFragment = useFragment; break; case CategoryType.Resource: source.UseResources = isUsed; + source.UseResourcesFragment = useFragment; break; case CategoryType.Person: source.UsePeople = isUsed; + source.UsePeopleFragment = useFragment; break; case CategoryType.Publication: source.UsePublications = isUsed; + source.UsePublicationsFragment = useFragment; break; } _ = await _resourceRepository.UpdateAsync(source); diff --git a/ResourceInformationV2.Data/DataModels/Source.cs b/ResourceInformationV2.Data/DataModels/Source.cs index 49d1cb7..07e3469 100644 --- a/ResourceInformationV2.Data/DataModels/Source.cs +++ b/ResourceInformationV2.Data/DataModels/Source.cs @@ -32,10 +32,16 @@ public class Source : BaseDataItem { public string ReviewEmail { get; set; } = ""; public string Title { get; set; } = ""; public bool UseEvents { get; set; } + public bool UseEventsFragment { get; set; } public bool UseFaqs { get; set; } + public bool UseFaqsFragment { get; set; } public bool UseNotes { get; set; } + public bool UseNotesFragment { get; set; } public bool UsePeople { get; set; } + public bool UsePeopleFragment { get; set; } public bool UsePublications { get; set; } + public bool UsePublicationsFragment { get; set; } public bool UseResources { get; set; } + public bool UseResourcesFragment { get; set; } } } \ No newline at end of file diff --git a/ResourceInformationV2.Data/Migrations/20260331172431_AddFragment.Designer.cs b/ResourceInformationV2.Data/Migrations/20260331172431_AddFragment.Designer.cs new file mode 100644 index 0000000..5677029 --- /dev/null +++ b/ResourceInformationV2.Data/Migrations/20260331172431_AddFragment.Designer.cs @@ -0,0 +1,559 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ResourceInformationV2.Data.DataContext; + +#nullable disable + +namespace ResourceInformationV2.Data.Migrations +{ + [DbContext(typeof(ResourceContext))] + [Migration("20260331172431_AddFragment")] + partial class AddFragment + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.16") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.Instruction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CategoryType") + .HasColumnType("int"); + + b.Property("FieldType") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LastUpdated") + .HasColumnType("datetime2"); + + b.Property("SourceId") + .HasColumnType("int"); + + b.Property("Text") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("SourceId"); + + b.ToTable("Instructions"); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.LinkCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DateChecked") + .HasColumnType("datetime2"); + + b.Property("EditLink") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsSuccessful") + .HasColumnType("bit"); + + b.Property("ItemGuid") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastUpdated") + .HasColumnType("datetime2"); + + b.Property("ResponseMessage") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ResponseStatusCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SourceId") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("SourceId"); + + b.ToTable("LinkChecks"); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CategoryType") + .HasColumnType("int"); + + b.Property("ChangeType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ChangedByNetId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Data") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("EmailSent") + .HasColumnType("bit"); + + b.Property("FieldType") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LastUpdated") + .HasColumnType("datetime2"); + + b.Property("SourceId") + .HasColumnType("int"); + + b.Property("SubjectId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("SourceId"); + + b.ToTable("Logs"); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.SecurityEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DepartmentTag") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsFullAdmin") + .HasColumnType("bit"); + + b.Property("IsOwner") + .HasColumnType("bit"); + + b.Property("IsPublic") + .HasColumnType("bit"); + + b.Property("IsRequested") + .HasColumnType("bit"); + + b.Property("LastUpdated") + .HasColumnType("datetime2"); + + b.Property("SourceId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("SourceId"); + + b.ToTable("SecurityEntries"); + + b.HasData( + new + { + Id = -1, + DepartmentTag = "", + Email = "jonker@illinois.edu", + IsActive = true, + IsFullAdmin = false, + IsOwner = true, + IsPublic = false, + IsRequested = false, + LastUpdated = new DateTime(2026, 3, 31, 12, 24, 31, 93, DateTimeKind.Local).AddTicks(6632), + SourceId = -1 + }); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.Source", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApiSecretCurrent") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ApiSecretLastChanged") + .HasColumnType("datetime2"); + + b.Property("ApiSecretPrevious") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("BaseUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Code") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedByEmail") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DateLastUrlCheck") + .HasColumnType("datetime2"); + + b.Property("DeactivateOnReview") + .HasColumnType("bit"); + + b.Property("DeletedByEmail") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FilterAudienceTitle") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FilterDepartmentTitle") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FilterOrder") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FilterTag1Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FilterTag2Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FilterTag3Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FilterTag4Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FilterTopicTitle") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ForceApiToDraft") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsTest") + .HasColumnType("bit"); + + b.Property("LastUpdated") + .HasColumnType("datetime2"); + + b.Property("NumberOfDaysForReview") + .HasColumnType("int"); + + b.Property("ReviewEmail") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UseEvents") + .HasColumnType("bit"); + + b.Property("UseEventsFragment") + .HasColumnType("bit"); + + b.Property("UseFaqs") + .HasColumnType("bit"); + + b.Property("UseFaqsFragment") + .HasColumnType("bit"); + + b.Property("UseNotes") + .HasColumnType("bit"); + + b.Property("UseNotesFragment") + .HasColumnType("bit"); + + b.Property("UsePeople") + .HasColumnType("bit"); + + b.Property("UsePeopleFragment") + .HasColumnType("bit"); + + b.Property("UsePublications") + .HasColumnType("bit"); + + b.Property("UsePublicationsFragment") + .HasColumnType("bit"); + + b.Property("UseResources") + .HasColumnType("bit"); + + b.Property("UseResourcesFragment") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("Sources"); + + b.HasData( + new + { + Id = -1, + ApiSecretCurrent = "", + ApiSecretPrevious = "", + BaseUrl = "", + Code = "test", + CreatedByEmail = "jonker@illinois.edu", + DeactivateOnReview = false, + DeletedByEmail = "", + FilterAudienceTitle = "", + FilterDepartmentTitle = "", + FilterOrder = "", + FilterTag1Title = "", + FilterTag2Title = "", + FilterTag3Title = "", + FilterTag4Title = "", + FilterTopicTitle = "", + ForceApiToDraft = true, + IsActive = false, + IsTest = true, + LastUpdated = new DateTime(2026, 3, 31, 12, 24, 31, 93, DateTimeKind.Local).AddTicks(6514), + NumberOfDaysForReview = 0, + ReviewEmail = "", + Title = "Test Entry", + UseEvents = false, + UseEventsFragment = false, + UseFaqs = false, + UseFaqsFragment = false, + UseNotes = false, + UseNotesFragment = false, + UsePeople = false, + UsePeopleFragment = false, + UsePublications = false, + UsePublicationsFragment = false, + UseResources = false, + UseResourcesFragment = false + }); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.SourceEmail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Body") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("BodyText") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Cc") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("EmailType") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LastUpdated") + .HasColumnType("datetime2"); + + b.Property("ReplyTo") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SendToReviewEmail") + .HasColumnType("bit"); + + b.Property("SourceId") + .HasColumnType("int"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("To") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("SourceId"); + + b.ToTable("SourceEmails"); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LastUpdated") + .HasColumnType("datetime2"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("SourceId") + .HasColumnType("int"); + + b.Property("TagType") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("SourceId"); + + b.ToTable("Tags"); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.Instruction", b => + { + b.HasOne("ResourceInformationV2.Data.DataModels.Source", "Source") + .WithMany() + .HasForeignKey("SourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Source"); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.LinkCheck", b => + { + b.HasOne("ResourceInformationV2.Data.DataModels.Source", "Source") + .WithMany() + .HasForeignKey("SourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Source"); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.Log", b => + { + b.HasOne("ResourceInformationV2.Data.DataModels.Source", "Source") + .WithMany() + .HasForeignKey("SourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Source"); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.SecurityEntry", b => + { + b.HasOne("ResourceInformationV2.Data.DataModels.Source", "Source") + .WithMany() + .HasForeignKey("SourceId"); + + b.Navigation("Source"); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.SourceEmail", b => + { + b.HasOne("ResourceInformationV2.Data.DataModels.Source", "Source") + .WithMany() + .HasForeignKey("SourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Source"); + }); + + modelBuilder.Entity("ResourceInformationV2.Data.DataModels.Tag", b => + { + b.HasOne("ResourceInformationV2.Data.DataModels.Source", "Source") + .WithMany() + .HasForeignKey("SourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Source"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ResourceInformationV2.Data/Migrations/20260331172431_AddFragment.cs b/ResourceInformationV2.Data/Migrations/20260331172431_AddFragment.cs new file mode 100644 index 0000000..32153de --- /dev/null +++ b/ResourceInformationV2.Data/Migrations/20260331172431_AddFragment.cs @@ -0,0 +1,113 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ResourceInformationV2.Data.Migrations +{ + /// + public partial class AddFragment : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "UseEventsFragment", + table: "Sources", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "UseFaqsFragment", + table: "Sources", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "UseNotesFragment", + table: "Sources", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "UsePeopleFragment", + table: "Sources", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "UsePublicationsFragment", + table: "Sources", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "UseResourcesFragment", + table: "Sources", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.UpdateData( + table: "SecurityEntries", + keyColumn: "Id", + keyValue: -1, + column: "LastUpdated", + value: new DateTime(2026, 3, 31, 12, 24, 31, 93, DateTimeKind.Local).AddTicks(6632)); + + migrationBuilder.UpdateData( + table: "Sources", + keyColumn: "Id", + keyValue: -1, + columns: new[] { "LastUpdated", "UseEventsFragment", "UseFaqsFragment", "UseNotesFragment", "UsePeopleFragment", "UsePublicationsFragment", "UseResourcesFragment" }, + values: new object[] { new DateTime(2026, 3, 31, 12, 24, 31, 93, DateTimeKind.Local).AddTicks(6514), false, false, false, false, false, false }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "UseEventsFragment", + table: "Sources"); + + migrationBuilder.DropColumn( + name: "UseFaqsFragment", + table: "Sources"); + + migrationBuilder.DropColumn( + name: "UseNotesFragment", + table: "Sources"); + + migrationBuilder.DropColumn( + name: "UsePeopleFragment", + table: "Sources"); + + migrationBuilder.DropColumn( + name: "UsePublicationsFragment", + table: "Sources"); + + migrationBuilder.DropColumn( + name: "UseResourcesFragment", + table: "Sources"); + + migrationBuilder.UpdateData( + table: "SecurityEntries", + keyColumn: "Id", + keyValue: -1, + column: "LastUpdated", + value: new DateTime(2026, 2, 18, 8, 21, 35, 236, DateTimeKind.Local).AddTicks(6239)); + + migrationBuilder.UpdateData( + table: "Sources", + keyColumn: "Id", + keyValue: -1, + column: "LastUpdated", + value: new DateTime(2026, 2, 18, 8, 21, 35, 236, DateTimeKind.Local).AddTicks(6139)); + } + } +} diff --git a/ResourceInformationV2.Data/Migrations/ResourceContextModelSnapshot.cs b/ResourceInformationV2.Data/Migrations/ResourceContextModelSnapshot.cs index c9a8fcc..173a0e5 100644 --- a/ResourceInformationV2.Data/Migrations/ResourceContextModelSnapshot.cs +++ b/ResourceInformationV2.Data/Migrations/ResourceContextModelSnapshot.cs @@ -217,7 +217,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) IsOwner = true, IsPublic = false, IsRequested = false, - LastUpdated = new DateTime(2026, 2, 18, 8, 21, 35, 236, DateTimeKind.Local).AddTicks(6239), + LastUpdated = new DateTime(2026, 3, 31, 12, 24, 31, 93, DateTimeKind.Local).AddTicks(6632), SourceId = -1 }); }); @@ -321,21 +321,39 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("UseEvents") .HasColumnType("bit"); + b.Property("UseEventsFragment") + .HasColumnType("bit"); + b.Property("UseFaqs") .HasColumnType("bit"); + b.Property("UseFaqsFragment") + .HasColumnType("bit"); + b.Property("UseNotes") .HasColumnType("bit"); + b.Property("UseNotesFragment") + .HasColumnType("bit"); + b.Property("UsePeople") .HasColumnType("bit"); + b.Property("UsePeopleFragment") + .HasColumnType("bit"); + b.Property("UsePublications") .HasColumnType("bit"); + b.Property("UsePublicationsFragment") + .HasColumnType("bit"); + b.Property("UseResources") .HasColumnType("bit"); + b.Property("UseResourcesFragment") + .HasColumnType("bit"); + b.HasKey("Id"); b.ToTable("Sources"); @@ -362,16 +380,22 @@ protected override void BuildModel(ModelBuilder modelBuilder) ForceApiToDraft = true, IsActive = false, IsTest = true, - LastUpdated = new DateTime(2026, 2, 18, 8, 21, 35, 236, DateTimeKind.Local).AddTicks(6139), + LastUpdated = new DateTime(2026, 3, 31, 12, 24, 31, 93, DateTimeKind.Local).AddTicks(6514), NumberOfDaysForReview = 0, ReviewEmail = "", Title = "Test Entry", UseEvents = false, + UseEventsFragment = false, UseFaqs = false, + UseFaqsFragment = false, UseNotes = false, + UseNotesFragment = false, UsePeople = false, + UsePeopleFragment = false, UsePublications = false, - UseResources = false + UsePublicationsFragment = false, + UseResources = false, + UseResourcesFragment = false }); }); diff --git a/ResourceInformationV2.Data/PageList/PageGroup.cs b/ResourceInformationV2.Data/PageList/PageGroup.cs index b4bd600..bd2f11e 100644 --- a/ResourceInformationV2.Data/PageList/PageGroup.cs +++ b/ResourceInformationV2.Data/PageList/PageGroup.cs @@ -95,7 +95,7 @@ public static class PageGroup { new ("Email Options", "/configuration/email"), new ("Templates", "/configuration/templates"), new ("Review Options", "/configuration/review"), - new ("Request Deletion", "/configuration/requestdeletion"), + new ("Delete Source", "/configuration/deletion"), new ("Testing Access", "/configuration/testing") } }, { SidebarEnum.ConfigurationNoSource, new() { new ("Sources", "/configuration/sources"), new ("Testing Access", "/configuration/testing") } }, diff --git a/ResourceInformationV2.Search/Getters/BaseGetter.cs b/ResourceInformationV2.Search/Getters/BaseGetter.cs index 7ed63ae..9b72cf6 100644 --- a/ResourceInformationV2.Search/Getters/BaseGetter.cs +++ b/ResourceInformationV2.Search/Getters/BaseGetter.cs @@ -122,7 +122,7 @@ public async Task> Search(string source, string search, IEnumera f => audience.Any() ? f.Terms(m => m.Field(fld => fld.AudienceList).Terms(audience)) : f.MatchAll(), f => departments.Any() ? f.Terms(m => m.Field(fld => fld.DepartmentList).Terms(departments)) : f.MatchAll()) .Must(m => !string.IsNullOrWhiteSpace(search) ? m.MultiMatch(m => m.Fields(fld => fld.Field("title^10").Field("description^5").Field("notes")).Query(search)) : m.MatchAll()))) - .Sort(srt => sort == "date" ? srt.Descending(f => f.CreatedOn) : srt.Ascending(f => f.TitleSortKeyword)) + .Sort(srt => sort == "date" ? srt.Descending(f => f.CreatedOn) : srt.Ascending(f => f.Order).Ascending(f => f.TitleSortKeyword)) .Suggest(a => a.Phrase("didyoumean", p => p.Text(search).Field(fld => fld.Title)))); LogDebug(response); diff --git a/ResourceInformationV2.Search/Getters/PublicationGetter.cs b/ResourceInformationV2.Search/Getters/PublicationGetter.cs index 9bc4ac4..20587c1 100644 --- a/ResourceInformationV2.Search/Getters/PublicationGetter.cs +++ b/ResourceInformationV2.Search/Getters/PublicationGetter.cs @@ -2,16 +2,13 @@ using ResourceInformationV2.Search.JsonThinModels; using ResourceInformationV2.Search.Models; -namespace ResourceInformationV2.Search.Getters -{ +namespace ResourceInformationV2.Search.Getters { - public class PublicationGetter(OpenSearchClient? openSearchClient) : BaseGetter(openSearchClient) - { + public class PublicationGetter(OpenSearchClient? openSearchClient) : BaseGetter(openSearchClient) { internal override string IndexName { get => UrlTypes.Publications.ConvertToUrlString(); } - public async Task> SearchPublications(string source, string search, IEnumerable tags, IEnumerable tags2, IEnumerable tags3, IEnumerable tags4, IEnumerable topics, IEnumerable audience, IEnumerable departments, IEnumerable authors, string status, int take, int skip, string sort) - { - ISearchResponse response = await _openSearchClient.SearchAsync(s => s.Index(IndexName) + public async Task> SearchPublications(string source, string search, IEnumerable tags, IEnumerable tags2, IEnumerable tags3, IEnumerable tags4, IEnumerable topics, IEnumerable audience, IEnumerable departments, IEnumerable authors, string status, int take, int skip, string sort) { + var response = await _openSearchClient.SearchAsync(s => s.Index(IndexName) .Skip(skip) .Size(take) .Query(q => q @@ -28,13 +25,12 @@ public async Task> SearchPublications(string source, s f => authors.Any() ? f.Terms(m => m.Field(fld => fld.Authors).Terms(authors)) : f.MatchAll(), f => status != "" ? f.Term(m => m.Field(fld => fld.Status).Value(status)) : f.MatchAll()) .Must(m => !string.IsNullOrWhiteSpace(search) ? m.MultiMatch(m => m.Fields(fld => fld.Field("title^10").Field("description^5").Field("notes")).Query(search)) : m.MatchAll()))) - .Sort(srt => sort == "date" ? srt.Descending(f => f.PublishedDateNumeric) : srt.Ascending(f => f.TitleSortKeyword)) + .Sort(srt => sort == "date" ? srt.Descending(f => f.PublishedDateNumeric) : srt.Ascending(f => f.Order).Ascending(f => f.TitleSortKeyword)) .Suggest(a => a.Phrase("didyoumean", p => p.Text(search).Field(fld => fld.Title)))); LogDebug(response); List documents = response.IsValid ? [.. response.Documents] : []; - return new SearchObject() - { + return new SearchObject() { Error = !response.IsValid ? response.ServerError.Error.ToString() : "", DidYouMean = response.Suggest["didyoumean"].FirstOrDefault()?.Options?.FirstOrDefault()?.Text ?? "", Total = (int)response.Total, diff --git a/ResourceInformationV2/Components/Controls/InstructionList.razor b/ResourceInformationV2/Components/Controls/InstructionList.razor index fa8c1c5..5e0d43a 100644 --- a/ResourceInformationV2/Components/Controls/InstructionList.razor +++ b/ResourceInformationV2/Components/Controls/InstructionList.razor @@ -57,6 +57,20 @@