From 0778874667513128d715535d8173303317697ec8 Mon Sep 17 00:00:00 2001 From: Mark Youngman Date: Fri, 13 Dec 2024 11:13:35 +0000 Subject: [PATCH 1/7] EES-5738 Create new DataSetFileGeographicLevels table --- ...taSetFileGeographicLevelsTable.Designer.cs | 2272 +++++++++++++++++ ..._CreateDataSetFileGeographicLevelsTable.cs | 43 + .../ContentDbContextModelSnapshot.cs | 29 + .../DataSetFileGeographicLevels.cs | 17 + .../Database/ContentDbContext.cs | 18 +- .../File.cs | 3 + 6 files changed, 2380 insertions(+), 2 deletions(-) create mode 100644 src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs create mode 100644 src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.cs create mode 100644 src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs new file mode 100644 index 00000000000..dcc66a1e236 --- /dev/null +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs @@ -0,0 +1,2272 @@ +// +using System; +using GovUk.Education.ExploreEducationStatistics.Content.Model.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace GovUk.Education.ExploreEducationStatistics.Admin.Migrations.ContentMigrations +{ + [DbContext(typeof(ContentDbContext))] + [Migration("20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable")] + partial class EES5738_CreateDataSetFileGeographicLevelsTable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Common.Model.Contact", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContactName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ContactTelNo") + .HasColumnType("nvarchar(max)"); + + b.Property("TeamEmail") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TeamName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Contacts"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Common.Model.FreeTextRank", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Rank") + .HasColumnType("int"); + + b.ToTable((string)null); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ContentBlockId") + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("LegacyCreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Resolved") + .HasColumnType("datetime2"); + + b.Property("ResolvedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("ContentBlockId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ResolvedById"); + + b.ToTable("Comment"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentBlock", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Locked") + .HasColumnType("datetime2"); + + b.Property("LockedById") + .IsConcurrencyToken() + .HasColumnType("uniqueidentifier"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(25) + .HasColumnType("nvarchar(25)"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("ContentSectionId"); + + b.HasIndex("LockedById"); + + b.HasIndex("ReleaseVersionId"); + + b.HasIndex("Type"); + + b.ToTable("ContentBlock", (string)null); + + b.HasDiscriminator("Type").HasValue("ContentBlock"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentSection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Caption") + .HasColumnType("nvarchar(max)"); + + b.Property("Heading") + .HasColumnType("nvarchar(max)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(25) + .HasColumnType("nvarchar(25)"); + + b.HasKey("Id"); + + b.HasIndex("ReleaseVersionId"); + + b.HasIndex("Type"); + + b.ToTable("ContentSections"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockParent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("LatestDraftVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("LatestPublishedVersionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("LatestDraftVersionId") + .IsUnique() + .HasFilter("[LatestDraftVersionId] IS NOT NULL"); + + b.HasIndex("LatestPublishedVersionId") + .IsUnique() + .HasFilter("[LatestPublishedVersionId] IS NOT NULL"); + + b.ToTable("DataBlocks", (string)null); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentBlockId") + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("DataBlockParentId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DataBlockId"); + + b.Property("Published") + .HasColumnType("datetime2"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.Property("Version") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ContentBlockId"); + + b.HasIndex("DataBlockParentId"); + + b.HasIndex("ReleaseVersionId"); + + b.ToTable("DataBlockVersions", (string)null); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataImport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("ExpectedImportedRows") + .HasColumnType("int"); + + b.Property("FileId") + .HasColumnType("uniqueidentifier"); + + b.Property("GeographicLevels") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ImportedRows") + .HasColumnType("int"); + + b.Property("LastProcessedRowIndex") + .HasColumnType("int"); + + b.Property("MetaFileId") + .HasColumnType("uniqueidentifier"); + + b.Property("StagePercentageComplete") + .HasColumnType("int"); + + b.Property("Status") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("TotalRows") + .HasColumnType("int"); + + b.Property("ZipFileId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("FileId") + .IsUnique(); + + SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("FileId"), new[] { "Status" }); + + b.HasIndex("MetaFileId") + .IsUnique(); + + b.HasIndex("ZipFileId"); + + b.ToTable("DataImports"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataImportError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("DataImportId") + .HasColumnType("uniqueidentifier"); + + b.Property("Message") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("DataImportId"); + + b.ToTable("DataImportErrors"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileGeographicLevel", b => + { + b.Property("DataSetFileVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("GeographicLevel") + .HasColumnType("int"); + + b.HasKey("DataSetFileVersionId", "GeographicLevel"); + + b.ToTable("DataSetFileGeographicLevels"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.EmbedBlock", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.Property("Url") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("EmbedBlocks"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.FeaturedTable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("DataBlockId") + .HasColumnType("uniqueidentifier"); + + b.Property("DataBlockParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.Property("UpdatedById") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DataBlockId") + .IsUnique(); + + b.HasIndex("DataBlockParentId"); + + b.HasIndex("ReleaseVersionId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("FeaturedTables"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContentLength") + .HasColumnType("bigint"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("DataSetFileId") + .HasColumnType("uniqueidentifier"); + + b.Property("DataSetFileMeta") + .HasColumnType("nvarchar(max)"); + + b.Property("DataSetFileVersion") + .HasColumnType("int"); + + b.Property("Filename") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReplacedById") + .HasColumnType("uniqueidentifier"); + + b.Property("ReplacingId") + .HasColumnType("uniqueidentifier"); + + b.Property("RootPath") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("SubjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(25) + .HasColumnType("nvarchar(25)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ReplacedById") + .IsUnique() + .HasFilter("[ReplacedById] IS NOT NULL"); + + b.HasIndex("ReplacingId") + .IsUnique() + .HasFilter("[ReplacingId] IS NOT NULL"); + + b.HasIndex("SourceId"); + + b.HasIndex("Type"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.GlossaryEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Body") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.ToTable("GlossaryEntries"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatistic", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("GuidanceText") + .HasColumnType("nvarchar(max)"); + + b.Property("GuidanceTitle") + .HasColumnType("nvarchar(max)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Trend") + .HasColumnType("nvarchar(max)"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.Property("UpdatedById") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ReleaseVersionId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("KeyStatistics"); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Methodology", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("LatestPublishedVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("OwningPublicationSlug") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OwningPublicationTitle") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("LatestPublishedVersionId") + .IsUnique() + .HasFilter("[LatestPublishedVersionId] IS NOT NULL"); + + b.ToTable("Methodologies"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyFile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("FileId") + .HasColumnType("uniqueidentifier"); + + b.Property("MethodologyVersionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.HasIndex("MethodologyVersionId"); + + b.ToTable("MethodologyFiles"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayDate") + .HasColumnType("datetime2"); + + b.Property("MethodologyVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.Property("UpdatedById") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("MethodologyVersionId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("MethodologyNotes"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyRedirect", b => + { + b.Property("MethodologyVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Slug") + .HasColumnType("nvarchar(450)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.HasKey("MethodologyVersionId", "Slug"); + + b.ToTable("MethodologyRedirects"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApprovalStatus") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("InternalReleaseNote") + .HasColumnType("nvarchar(max)"); + + b.Property("MethodologyVersionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("MethodologyVersionId"); + + b.ToTable("MethodologyStatus"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AlternativeSlug") + .HasColumnType("nvarchar(max)"); + + b.Property("AlternativeTitle") + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("MethodologyId") + .HasColumnType("uniqueidentifier"); + + b.Property("PreviousVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Published") + .HasColumnType("datetime2"); + + b.Property("PublishingStrategy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ScheduledWithReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.Property("Version") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("MethodologyId"); + + b.HasIndex("PreviousVersionId"); + + b.HasIndex("ScheduledWithReleaseVersionId"); + + b.ToTable("MethodologyVersions"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersionContent", b => + { + b.Property("MethodologyVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Annexes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("MethodologyVersionId"); + + b.ToTable("MethodologyVersions", (string)null); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Permalink", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("DataSetTitle") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MigratedFromLegacy") + .HasColumnType("bit"); + + b.Property("PublicationTitle") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("SubjectId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ReleaseVersionId"); + + b.HasIndex("SubjectId"); + + b.ToTable("Permalinks"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ContactId") + .HasColumnType("uniqueidentifier"); + + b.Property("LatestPublishedReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("ReleaseSeries") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Summary") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("nvarchar(160)"); + + b.Property("SupersededById") + .HasColumnType("uniqueidentifier"); + + b.Property("ThemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("ContactId"); + + b.HasIndex("LatestPublishedReleaseVersionId") + .IsUnique() + .HasFilter("[LatestPublishedReleaseVersionId] IS NOT NULL"); + + b.HasIndex("SupersededById"); + + b.HasIndex("ThemeId"); + + b.ToTable("Publications"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.PublicationMethodology", b => + { + b.Property("PublicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("MethodologyId") + .HasColumnType("uniqueidentifier"); + + b.Property("Owner") + .HasColumnType("bit"); + + b.HasKey("PublicationId", "MethodologyId"); + + b.HasIndex("MethodologyId"); + + b.ToTable("PublicationMethodologies"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.PublicationRedirect", b => + { + b.Property("PublicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("Slug") + .HasColumnType("nvarchar(450)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.HasKey("PublicationId", "Slug"); + + b.ToTable("PublicationRedirects"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Release", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Label") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("PublicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(81) + .HasColumnType("nvarchar(81)"); + + b.Property("TimePeriodCoverage") + .IsRequired() + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PublicationId", "Year", "TimePeriodCoverage", "Label") + .IsUnique(); + + b.ToTable("Releases"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseFile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("FileId") + .HasColumnType("uniqueidentifier"); + + b.Property("FilterSequence") + .HasColumnType("nvarchar(max)"); + + b.Property("IndicatorSequence") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("PublicApiDataSetId") + .HasColumnType("uniqueidentifier"); + + b.Property("PublicApiDataSetVersion") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Published") + .HasColumnType("datetime2"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Summary") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.HasIndex("ReleaseVersionId", "FileId") + .IsUnique(); + + b.HasIndex("ReleaseVersionId", "PublicApiDataSetId", "PublicApiDataSetVersion") + .IsUnique() + .HasFilter("[PublicApiDataSetId] IS NOT NULL AND [PublicApiDataSetVersion] IS NOT NULL"); + + b.ToTable("ReleaseFiles"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseRedirect", b => + { + b.Property("ReleaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Slug") + .HasColumnType("nvarchar(450)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.HasKey("ReleaseId", "Slug"); + + b.ToTable("ReleaseRedirects"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApprovalStatus") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("InternalReleaseNote") + .HasColumnType("nvarchar(max)"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ReleaseVersionId"); + + b.ToTable("ReleaseStatus"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApprovalStatus") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("DataGuidance") + .HasColumnType("nvarchar(max)"); + + b.Property("NextReleaseDate") + .HasColumnType("nvarchar(max)"); + + b.Property("NotifiedOn") + .HasColumnType("datetime2"); + + b.Property("NotifySubscribers") + .HasColumnType("bit"); + + b.Property("PreReleaseAccessList") + .HasColumnType("nvarchar(max)"); + + b.Property("PreviousVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("PublicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("PublishScheduled") + .HasColumnType("datetime2"); + + b.Property("Published") + .HasColumnType("datetime2"); + + b.Property("RelatedInformation") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReleaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("ReleaseName") + .HasColumnType("nvarchar(max)"); + + b.Property("Slug") + .HasColumnType("nvarchar(max)"); + + b.Property("SoftDeleted") + .HasColumnType("bit"); + + b.Property("TimePeriodCoverage") + .IsRequired() + .HasMaxLength(6) + .HasColumnType("nvarchar(6)"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("UpdatePublishedDate") + .HasColumnType("bit"); + + b.Property("Version") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("PublicationId"); + + b.HasIndex("ReleaseId"); + + b.HasIndex("Type"); + + b.HasIndex("PreviousVersionId", "Version"); + + b.ToTable("ReleaseVersions"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Theme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Slug") + .HasColumnType("nvarchar(max)"); + + b.Property("Summary") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Themes"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Update", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("On") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ReleaseVersionId"); + + b.ToTable("Update"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DeletedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .HasColumnType("nvarchar(max)"); + + b.Property("SoftDeleted") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("DeletedById"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.UserPublicationInvite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PublicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("Role") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("PublicationId"); + + b.ToTable("UserPublicationInvites"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.UserPublicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Deleted") + .HasColumnType("datetime2"); + + b.Property("DeletedById") + .HasColumnType("uniqueidentifier"); + + b.Property("PublicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("Role") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("PublicationId"); + + b.HasIndex("UserId"); + + b.ToTable("UserPublicationRoles"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.UserReleaseInvite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("EmailSent") + .HasColumnType("bit"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Role") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SoftDeleted") + .HasColumnType("bit"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ReleaseVersionId"); + + b.ToTable("UserReleaseInvites"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.UserReleaseRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Deleted") + .HasColumnType("datetime2"); + + b.Property("DeletedById") + .HasColumnType("uniqueidentifier"); + + b.Property("ReleaseVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Role") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SoftDeleted") + .HasColumnType("bit"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DeletedById"); + + b.HasIndex("ReleaseVersionId"); + + b.HasIndex("UserId"); + + b.ToTable("UserReleaseRoles"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlock", b => + { + b.HasBaseType("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentBlock"); + + b.Property("Charts") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("DataBlock_Charts"); + + b.Property("Heading") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("DataBlock_Heading"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Query") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("DataBlock_Query"); + + b.Property("Source") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Table") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("DataBlock_Table"); + + b.HasDiscriminator().HasValue("DataBlock"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.EmbedBlockLink", b => + { + b.HasBaseType("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentBlock"); + + b.Property("EmbedBlockId") + .HasColumnType("uniqueidentifier") + .HasColumnName("EmbedBlockId"); + + b.HasIndex("EmbedBlockId") + .IsUnique() + .HasFilter("[EmbedBlockId] IS NOT NULL"); + + b.HasDiscriminator().HasValue("EmbedBlockLink"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.HtmlBlock", b => + { + b.HasBaseType("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentBlock"); + + b.Property("Body") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("nvarchar(max)") + .HasColumnName("Body"); + + b.HasDiscriminator().HasValue("HtmlBlock"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MarkDownBlock", b => + { + b.HasBaseType("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentBlock"); + + b.Property("Body") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("nvarchar(max)") + .HasColumnName("Body"); + + b.HasDiscriminator().HasValue("MarkDownBlock"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatisticDataBlock", b => + { + b.HasBaseType("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatistic"); + + b.Property("DataBlockId") + .HasColumnType("uniqueidentifier"); + + b.Property("DataBlockParentId") + .HasColumnType("uniqueidentifier"); + + b.HasIndex("DataBlockId"); + + b.HasIndex("DataBlockParentId"); + + b.ToTable("KeyStatisticsDataBlock", (string)null); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatisticText", b => + { + b.HasBaseType("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatistic"); + + b.Property("Statistic") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.ToTable("KeyStatisticsText", (string)null); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Comment", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentBlock", "ContentBlock") + .WithMany("Comments") + .HasForeignKey("ContentBlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "ResolvedBy") + .WithMany() + .HasForeignKey("ResolvedById"); + + b.Navigation("ContentBlock"); + + b.Navigation("CreatedBy"); + + b.Navigation("ResolvedBy"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentBlock", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentSection", "ContentSection") + .WithMany("Content") + .HasForeignKey("ContentSectionId"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "LockedBy") + .WithMany() + .HasForeignKey("LockedById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ReleaseVersion") + .WithMany() + .HasForeignKey("ReleaseVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentSection"); + + b.Navigation("LockedBy"); + + b.Navigation("ReleaseVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentSection", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ReleaseVersion") + .WithMany("Content") + .HasForeignKey("ReleaseVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ReleaseVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockParent", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockVersion", "LatestDraftVersion") + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockParent", "LatestDraftVersionId"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockVersion", "LatestPublishedVersion") + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockParent", "LatestPublishedVersionId"); + + b.Navigation("LatestDraftVersion"); + + b.Navigation("LatestPublishedVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockVersion", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlock", "ContentBlock") + .WithMany() + .HasForeignKey("ContentBlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockParent", "DataBlockParent") + .WithMany() + .HasForeignKey("DataBlockParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ReleaseVersion") + .WithMany("DataBlockVersions") + .HasForeignKey("ReleaseVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ContentBlock"); + + b.Navigation("DataBlockParent"); + + b.Navigation("ReleaseVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataImport", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "File") + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.DataImport", "FileId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "MetaFile") + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.DataImport", "MetaFileId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "ZipFile") + .WithMany() + .HasForeignKey("ZipFileId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("File"); + + b.Navigation("MetaFile"); + + b.Navigation("ZipFile"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataImportError", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.DataImport", "DataImport") + .WithMany("Errors") + .HasForeignKey("DataImportId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DataImport"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileGeographicLevel", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "DataSetFileVersion") + .WithMany("DataSetFileGeographicLevels") + .HasForeignKey("DataSetFileVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DataSetFileVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.FeaturedTable", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlock", "DataBlock") + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.FeaturedTable", "DataBlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockParent", "DataBlockParent") + .WithMany() + .HasForeignKey("DataBlockParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ReleaseVersion") + .WithMany("FeaturedTables") + .HasForeignKey("ReleaseVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("DataBlock"); + + b.Navigation("DataBlockParent"); + + b.Navigation("ReleaseVersion"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.File", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "ReplacedBy") + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "ReplacedById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "Replacing") + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "ReplacingId"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "Source") + .WithMany() + .HasForeignKey("SourceId"); + + b.Navigation("CreatedBy"); + + b.Navigation("ReplacedBy"); + + b.Navigation("Replacing"); + + b.Navigation("Source"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.GlossaryEntry", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("CreatedBy"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatistic", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ReleaseVersion") + .WithMany("KeyStatistics") + .HasForeignKey("ReleaseVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("ReleaseVersion"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Methodology", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersion", "LatestPublishedVersion") + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.Methodology", "LatestPublishedVersionId"); + + b.Navigation("LatestPublishedVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyFile", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "File") + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersion", "MethodologyVersion") + .WithMany() + .HasForeignKey("MethodologyVersionId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("File"); + + b.Navigation("MethodologyVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyNote", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersion", "MethodologyVersion") + .WithMany("Notes") + .HasForeignKey("MethodologyVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("CreatedBy"); + + b.Navigation("MethodologyVersion"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyRedirect", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersion", "MethodologyVersion") + .WithMany("MethodologyRedirects") + .HasForeignKey("MethodologyVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MethodologyVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyStatus", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersion", "MethodologyVersion") + .WithMany() + .HasForeignKey("MethodologyVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("MethodologyVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersion", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Methodology", "Methodology") + .WithMany("Versions") + .HasForeignKey("MethodologyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersion", "PreviousVersion") + .WithMany() + .HasForeignKey("PreviousVersionId"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ScheduledWithReleaseVersion") + .WithMany() + .HasForeignKey("ScheduledWithReleaseVersionId"); + + b.Navigation("CreatedBy"); + + b.Navigation("Methodology"); + + b.Navigation("PreviousVersion"); + + b.Navigation("ScheduledWithReleaseVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersionContent", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersion", null) + .WithOne("MethodologyContent") + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersionContent", "MethodologyVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Common.Model.Contact", "Contact") + .WithMany() + .HasForeignKey("ContactId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "LatestPublishedReleaseVersion") + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", "LatestPublishedReleaseVersionId"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", "SupersededBy") + .WithMany() + .HasForeignKey("SupersededById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Theme", "Theme") + .WithMany("Publications") + .HasForeignKey("ThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ExternalMethodology", "ExternalMethodology", b1 => + { + b1.Property("PublicationId") + .HasColumnType("uniqueidentifier"); + + b1.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("Url") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.HasKey("PublicationId"); + + b1.ToTable("ExternalMethodology", (string)null); + + b1.WithOwner() + .HasForeignKey("PublicationId"); + }); + + b.Navigation("Contact"); + + b.Navigation("ExternalMethodology"); + + b.Navigation("LatestPublishedReleaseVersion"); + + b.Navigation("SupersededBy"); + + b.Navigation("Theme"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.PublicationMethodology", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Methodology", "Methodology") + .WithMany("Publications") + .HasForeignKey("MethodologyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", "Publication") + .WithMany("Methodologies") + .HasForeignKey("PublicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Methodology"); + + b.Navigation("Publication"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.PublicationRedirect", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", "Publication") + .WithMany("PublicationRedirects") + .HasForeignKey("PublicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Publication"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Release", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", "Publication") + .WithMany("Releases") + .HasForeignKey("PublicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Publication"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseFile", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "File") + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ReleaseVersion") + .WithMany() + .HasForeignKey("ReleaseVersionId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("File"); + + b.Navigation("ReleaseVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseRedirect", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Release", "Release") + .WithMany("ReleaseRedirects") + .HasForeignKey("ReleaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Release"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseStatus", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ReleaseVersion") + .WithMany("ReleaseStatuses") + .HasForeignKey("ReleaseVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("ReleaseVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "PreviousVersion") + .WithMany() + .HasForeignKey("PreviousVersionId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", "Publication") + .WithMany("ReleaseVersions") + .HasForeignKey("PublicationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Release", "Release") + .WithMany("Versions") + .HasForeignKey("ReleaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("PreviousVersion"); + + b.Navigation("Publication"); + + b.Navigation("Release"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Update", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ReleaseVersion") + .WithMany("Updates") + .HasForeignKey("ReleaseVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("ReleaseVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.User", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "DeletedBy") + .WithMany() + .HasForeignKey("DeletedById"); + + b.Navigation("DeletedBy"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.UserPublicationInvite", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", "Publication") + .WithMany() + .HasForeignKey("PublicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("Publication"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.UserPublicationRole", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "DeletedBy") + .WithMany() + .HasForeignKey("DeletedById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", "Publication") + .WithMany() + .HasForeignKey("PublicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("Publication"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.UserReleaseInvite", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ReleaseVersion") + .WithMany() + .HasForeignKey("ReleaseVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("ReleaseVersion"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.UserReleaseRole", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "DeletedBy") + .WithMany() + .HasForeignKey("DeletedById"); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", "ReleaseVersion") + .WithMany() + .HasForeignKey("ReleaseVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("DeletedBy"); + + b.Navigation("ReleaseVersion"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.EmbedBlockLink", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.EmbedBlock", "EmbedBlock") + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.EmbedBlockLink", "EmbedBlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EmbedBlock"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatisticDataBlock", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlock", "DataBlock") + .WithMany() + .HasForeignKey("DataBlockId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.DataBlockParent", "DataBlockParent") + .WithMany() + .HasForeignKey("DataBlockParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatistic", null) + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatisticDataBlock", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DataBlock"); + + b.Navigation("DataBlockParent"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatisticText", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatistic", null) + .WithOne() + .HasForeignKey("GovUk.Education.ExploreEducationStatistics.Content.Model.KeyStatisticText", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentBlock", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ContentSection", b => + { + b.Navigation("Content"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataImport", b => + { + b.Navigation("Errors"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.File", b => + { + b.Navigation("DataSetFileGeographicLevels"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Methodology", b => + { + b.Navigation("Publications"); + + b.Navigation("Versions"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.MethodologyVersion", b => + { + b.Navigation("MethodologyContent") + .IsRequired(); + + b.Navigation("MethodologyRedirects"); + + b.Navigation("Notes"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Publication", b => + { + b.Navigation("Methodologies"); + + b.Navigation("PublicationRedirects"); + + b.Navigation("ReleaseVersions"); + + b.Navigation("Releases"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Release", b => + { + b.Navigation("ReleaseRedirects"); + + b.Navigation("Versions"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion", b => + { + b.Navigation("Content"); + + b.Navigation("DataBlockVersions"); + + b.Navigation("FeaturedTables"); + + b.Navigation("KeyStatistics"); + + b.Navigation("ReleaseStatuses"); + + b.Navigation("Updates"); + }); + + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Theme", b => + { + b.Navigation("Publications"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.cs new file mode 100644 index 00000000000..b4a23fa687c --- /dev/null +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.cs @@ -0,0 +1,43 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace GovUk.Education.ExploreEducationStatistics.Admin.Migrations.ContentMigrations +{ + /// + public partial class EES5738_CreateDataSetFileGeographicLevelsTable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "DataSetFileGeographicLevels", + columns: table => new + { + DataSetFileVersionId = table.Column(type: "uniqueidentifier", nullable: false), + GeographicLevel = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DataSetFileGeographicLevels", x => new { x.DataSetFileVersionId, x.GeographicLevel }); + table.ForeignKey( + name: "FK_DataSetFileGeographicLevels_Files_DataSetFileVersionId", + column: x => x.DataSetFileVersionId, + principalTable: "Files", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.Sql("GRANT SELECT ON dbo.DataSetFileGeographicLevels TO [content];"); + migrationBuilder.Sql("GRANT INSERT ON dbo.DataSetFileGeographicLevels TO [importer];"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql("REVOKE SELECT ON dbo.DataSetFileGeographicLevels TO [content];"); + migrationBuilder.Sql("REVOKE INSERT ON dbo.DataSetFileGeographicLevels TO [importer];"); + migrationBuilder.DropTable( + name: "DataSetFileGeographicLevels"); + } + } +} diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs index 2877ed7a1a1..75b3a97870b 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs @@ -328,6 +328,19 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("DataImportErrors"); }); + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileGeographicLevel", b => + { + b.Property("DataSetFileVersionId") + .HasColumnType("uniqueidentifier"); + + b.Property("GeographicLevel") + .HasColumnType("int"); + + b.HasKey("DataSetFileVersionId", "GeographicLevel"); + + b.ToTable("DataSetFileGeographicLevels"); + }); + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.EmbedBlock", b => { b.Property("Id") @@ -1594,6 +1607,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("DataImport"); }); + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileGeographicLevel", b => + { + b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "DataSetFileVersion") + .WithMany("DataSetFileGeographicLevels") + .HasForeignKey("DataSetFileVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DataSetFileVersion"); + }); + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.FeaturedTable", b => { b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.User", "CreatedBy") @@ -2180,6 +2204,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Errors"); }); + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.File", b => + { + b.Navigation("DataSetFileGeographicLevels"); + }); + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Methodology", b => { b.Navigation("Publications"); diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs new file mode 100644 index 00000000000..ae83fb59cbc --- /dev/null +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs @@ -0,0 +1,17 @@ +#nullable enable +using System; +using GovUk.Education.ExploreEducationStatistics.Common.Converters; +using GovUk.Education.ExploreEducationStatistics.Common.Model.Data; +using Newtonsoft.Json; + +namespace GovUk.Education.ExploreEducationStatistics.Content.Model; + +public class DataSetFileGeographicLevel +{ + public Guid DataSetFileVersionId { get; set; } // Currently Files.Id, but will become DataSetFileVersion.Id in EES-5105 + + public File DataSetFileVersion { get; set; } = null!; + + [JsonConverter(typeof(EnumToEnumValueJsonConverter))] + public GeographicLevel GeographicLevel { get; set; } +} diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs index a86f10300d4..61c71e4f880 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs @@ -55,6 +55,7 @@ private void Configure(bool updateTimestamps = true) public virtual DbSet ReleaseStatus { get; set; } public virtual DbSet ReleaseFiles { get; set; } public virtual DbSet Files { get; set; } + public virtual DbSet DataSetFileGeographicLevels { get; set; } public virtual DbSet ContentSections { get; set; } public virtual DbSet ContentBlocks { get; set; } public virtual DbSet KeyStatistics { get; set; } @@ -110,6 +111,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) ConfigureReleaseStatus(modelBuilder); ConfigureReleaseFile(modelBuilder); ConfigureFile(modelBuilder); + ConfigureDataSetFileGeographicLevel(modelBuilder); ConfigureContentBlock(modelBuilder); ConfigureContentSection(modelBuilder); ConfigureReleaseVersion(modelBuilder); @@ -452,13 +454,25 @@ private static void ConfigureFile(ModelBuilder modelBuilder) v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Utc) : null); - entity.Property(p => p.DataSetFileMeta) - .HasConversion( // You might want to use EF8 JSON support instead of this + entity.Property(p => p.DataSetFileMeta) // EES-5666 + .HasConversion( v => JsonConvert.SerializeObject(v), v => JsonConvert.DeserializeObject(v)); }); } + private static void ConfigureDataSetFileGeographicLevel(ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.HasKey(gl => new + { + gl.DataSetFileVersionId, + gl.GeographicLevel + }); + }); + } + private static void ConfigureContentBlock(ModelBuilder modelBuilder) { modelBuilder.Entity(entity => diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs index f9a9ac9fd22..8fc1696a46a 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.Collections.Generic; using GovUk.Education.ExploreEducationStatistics.Common.Model; namespace GovUk.Education.ExploreEducationStatistics.Content.Model @@ -22,6 +23,8 @@ public class File : ICreatedTimestamp public int? DataSetFileVersion { get; set; } + public List? DataSetFileGeographicLevels { get; set; } + public DataSetFileMeta? DataSetFileMeta { get; set; } public Guid? ReplacedById { get; set; } From 6e32d38808bdb82be843d0b2634f074632316fb3 Mon Sep 17 00:00:00 2001 From: Mark Youngman Date: Fri, 13 Dec 2024 11:40:51 +0000 Subject: [PATCH 2/7] EES-5738 Migration to move DataSetFileMeta geog lvls to new table --- ...FileGeographicLevelsMigrationController.cs | 83 +++++++++++++++++++ ...aSetFileGeographicLevelsTable.Designer.cs} | 6 +- ...CreateDataSetFileGeographicLevelsTable.cs} | 2 +- .../ContentDbContextModelSnapshot.cs | 4 +- .../DataSetFileGeographicLevels.cs | 3 - .../Database/ContentDbContext.cs | 3 + 6 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 src/GovUk.Education.ExploreEducationStatistics.Admin/Controllers/Api/DataSetFileGeographicLevelsMigrationController.cs rename src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/{20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs => 20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs} (99%) rename src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/{20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.cs => 20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.cs} (94%) diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Controllers/Api/DataSetFileGeographicLevelsMigrationController.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Controllers/Api/DataSetFileGeographicLevelsMigrationController.cs new file mode 100644 index 00000000000..f1adf49fd34 --- /dev/null +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Controllers/Api/DataSetFileGeographicLevelsMigrationController.cs @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using GovUk.Education.ExploreEducationStatistics.Admin.Models; +using GovUk.Education.ExploreEducationStatistics.Common.Extensions; +using GovUk.Education.ExploreEducationStatistics.Content.Model; +using GovUk.Education.ExploreEducationStatistics.Content.Model.Database; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace GovUk.Education.ExploreEducationStatistics.Admin.Controllers.Api; + +[Route("api")] +[ApiController] +[Authorize(Roles = GlobalRoles.RoleNames.BauUser)] +public class DataSetFileMetaMigrationController(ContentDbContext contentDbContext) : ControllerBase +{ + public class MigrationResult + { + public bool IsDryRun; + public int Processed; + public string Errors; + } + + [HttpPut("bau/migrate-datasetfile-geographiclevels")] + public async Task DataSetFileGeographicLevelsMigration( + [FromQuery] bool isDryRun = true, + [FromQuery] int? num = null, + CancellationToken cancellationToken = default) + { + var queryable = contentDbContext.Files + .Where(f => f.DataSetFileMeta != null + && f.DataSetFileGeographicLevels.Count == 0); + + if (num != null) + { + queryable = queryable.Take(num.Value); + } + + var files = queryable.ToList(); + + var numProcessed = 0; + List errors = []; + + foreach (var file in files) + { + var meta = file.DataSetFileMeta; + + if (meta == null) + { + errors.Add($"No DataSetFileMeta found for File {file.Id}"); + continue; + } + + var dataSetFileGeographicLevels = meta!.GeographicLevels + .Distinct() + .Select(gl => new DataSetFileGeographicLevel + { + DataSetFileVersionId = file.Id, + GeographicLevel = gl, + }) + .ToList(); + + contentDbContext.DataSetFileGeographicLevels.AddRange(dataSetFileGeographicLevels); + + numProcessed++; + } + + if (!isDryRun) + { + await contentDbContext.SaveChangesAsync(cancellationToken); + } + + return new MigrationResult + { + IsDryRun = isDryRun, + Processed = numProcessed, + Errors = errors.IsNullOrEmpty() ? "No errors" : errors.JoinToString("\n"), + }; + } + +} diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs similarity index 99% rename from src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs rename to src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs index dcc66a1e236..9c4bfa60215 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs @@ -12,7 +12,7 @@ namespace GovUk.Education.ExploreEducationStatistics.Admin.Migrations.ContentMigrations { [DbContext(typeof(ContentDbContext))] - [Migration("20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable")] + [Migration("20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable")] partial class EES5738_CreateDataSetFileGeographicLevelsTable { /// @@ -336,8 +336,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("DataSetFileVersionId") .HasColumnType("uniqueidentifier"); - b.Property("GeographicLevel") - .HasColumnType("int"); + b.Property("GeographicLevel") + .HasColumnType("nvarchar(450)"); b.HasKey("DataSetFileVersionId", "GeographicLevel"); diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.cs similarity index 94% rename from src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.cs rename to src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.cs index b4a23fa687c..1434036a2a3 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213112036_EES5738_CreateDataSetFileGeographicLevelsTable.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.cs @@ -14,7 +14,7 @@ protected override void Up(MigrationBuilder migrationBuilder) columns: table => new { DataSetFileVersionId = table.Column(type: "uniqueidentifier", nullable: false), - GeographicLevel = table.Column(type: "int", nullable: false) + GeographicLevel = table.Column(type: "nvarchar(450)", nullable: false) }, constraints: table => { diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs index 75b3a97870b..bc677140783 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs @@ -333,8 +333,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("DataSetFileVersionId") .HasColumnType("uniqueidentifier"); - b.Property("GeographicLevel") - .HasColumnType("int"); + b.Property("GeographicLevel") + .HasColumnType("nvarchar(450)"); b.HasKey("DataSetFileVersionId", "GeographicLevel"); diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs index ae83fb59cbc..2b23db07a4a 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs @@ -1,8 +1,6 @@ #nullable enable using System; -using GovUk.Education.ExploreEducationStatistics.Common.Converters; using GovUk.Education.ExploreEducationStatistics.Common.Model.Data; -using Newtonsoft.Json; namespace GovUk.Education.ExploreEducationStatistics.Content.Model; @@ -12,6 +10,5 @@ public class DataSetFileGeographicLevel public File DataSetFileVersion { get; set; } = null!; - [JsonConverter(typeof(EnumToEnumValueJsonConverter))] public GeographicLevel GeographicLevel { get; set; } } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs index 61c71e4f880..2cec48a76d7 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs @@ -470,6 +470,9 @@ private static void ConfigureDataSetFileGeographicLevel(ModelBuilder modelBuilde gl.DataSetFileVersionId, gl.GeographicLevel }); + + entity.Property(gl => gl.GeographicLevel) + .HasConversion(new EnumToEnumValueConverter()); }); } From 47a3c8e99ae957cfe938442c1bffa27cd0d2f322 Mon Sep 17 00:00:00 2001 From: Mark Youngman Date: Fri, 13 Dec 2024 12:54:04 +0000 Subject: [PATCH 3/7] EES-5738 Create DataSetFileGL entries in WriteDataSetFileMeta --- .../Services/DataImportServiceTests.cs | 2 +- .../Services/FileImportServiceTests.cs | 5 ++++- .../Services/DataImportService.cs | 11 ++++++++++- .../Services/FileImportService.cs | 4 ++-- .../Services/Interfaces/IDataImportService.cs | 2 +- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs index f0aabc50536..5aa9ee86309 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs @@ -284,7 +284,7 @@ public async Task WriteDataSetMetaFile_Success() contentDbContextId, statisticsDbContextId); - await service.WriteDataSetFileMeta(subject.Id); + await service.WriteDataSetFileMeta(file.Id, subject.Id); await using (var contentDbContext = InMemoryContentDbContext(contentDbContextId)) { diff --git a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/FileImportServiceTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/FileImportServiceTests.cs index c33c514b8a8..eaaa1f0c9f7 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/FileImportServiceTests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/FileImportServiceTests.cs @@ -60,6 +60,7 @@ public async Task CompleteImport() dataImportService .Setup(s => s.WriteDataSetFileMeta( + import.FileId, import.SubjectId)) .Returns(Task.CompletedTask); @@ -228,7 +229,9 @@ await FinishedStatuses var dataImportService = new Mock(Strict); if (finishedStatus == COMPLETE) { - dataImportService.Setup(mock => mock.WriteDataSetFileMeta(import.SubjectId)) + dataImportService.Setup(mock => mock.WriteDataSetFileMeta( + import.FileId, + import.SubjectId)) .Returns(Task.CompletedTask); } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs index 301d89cd76a..acb15120605 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs @@ -151,7 +151,7 @@ public async Task UpdateStatus(Guid id, DataImportStatus newStatus, double perce await context.SaveChangesAsync(); } - public async Task WriteDataSetFileMeta(Guid subjectId) + public async Task WriteDataSetFileMeta(Guid fileId, Guid subjectId) { await using var contentDbContext = _dbContextSupplier.CreateDbContext(); await using var statisticsDbContext = _dbContextSupplier.CreateDbContext(); @@ -220,6 +220,15 @@ public async Task WriteDataSetFileMeta(Guid subjectId) .Single(f => f.Type == FileType.Data && f.SubjectId == subjectId); file.DataSetFileMeta = dataSetFileMeta; + + var dataSetFileGeographicLevels = geographicLevels + .Select(gl => new DataSetFileGeographicLevel + { + DataSetFileVersionId = fileId, + GeographicLevel = gl, + }).ToList(); + await contentDbContext.DataSetFileGeographicLevels.AddRangeAsync(dataSetFileGeographicLevels); + await contentDbContext.SaveChangesAsync(); } } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/FileImportService.cs b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/FileImportService.cs index 44daca0a939..c2c9550cdd0 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/FileImportService.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/FileImportService.cs @@ -105,7 +105,7 @@ public async Task CompleteImport(DataImport import, StatisticsDbContext context) if (import.Status == COMPLETE) { - await _dataImportService.WriteDataSetFileMeta(import.SubjectId); + await _dataImportService.WriteDataSetFileMeta(import.FileId, import.SubjectId); } return; @@ -139,7 +139,7 @@ await _dataImportService.FailImport(import.Id, if (import.Errors.Count == 0) { await _dataImportService.UpdateStatus(import.Id, COMPLETE, 100); - await _dataImportService.WriteDataSetFileMeta(import.SubjectId); + await _dataImportService.WriteDataSetFileMeta(import.FileId, import.SubjectId); } else { diff --git a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/Interfaces/IDataImportService.cs b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/Interfaces/IDataImportService.cs index e6ea8ba07ba..1ece36d23a5 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/Interfaces/IDataImportService.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/Interfaces/IDataImportService.cs @@ -19,7 +19,7 @@ public interface IDataImportService Task UpdateStatus(Guid id, DataImportStatus newStatus, double percentageComplete); - Task WriteDataSetFileMeta(Guid subjectId); + Task WriteDataSetFileMeta(Guid fileId, Guid subjectId); Task Update( Guid id, From c614926726b51b09f43646ab980ac92eb68de86b Mon Sep 17 00:00:00 2001 From: Mark Youngman Date: Fri, 13 Dec 2024 14:29:24 +0000 Subject: [PATCH 4/7] EES-5738 Data Catalogue page Geog lvl filtering --- .../FunctionsIntegrationTest.cs | 1 - .../DataSetFilesControllerCachingTests.cs | 2 + .../Controllers/DataSetFilesController.cs | 2 + .../DataSetFileListRequest.cs | 12 ++++ .../DataSetFileService.cs | 62 ++++++++++--------- .../Interfaces/IDataSetFileService.cs | 2 + .../data-catalogue/DataCataloguePage.tsx | 5 ++ .../data-catalogue/components/Filters.tsx | 36 +++++++++++ .../utils/createDataSetFileListRequest.ts | 3 + .../utils/dataSetFileFilters.ts | 1 + .../src/services/dataSetFileService.ts | 2 + 11 files changed, 97 insertions(+), 31 deletions(-) diff --git a/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/FunctionsIntegrationTest.cs b/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/FunctionsIntegrationTest.cs index 0a7cda58edf..9516e767bbc 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/FunctionsIntegrationTest.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/FunctionsIntegrationTest.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; using System.Threading.Tasks; using Azure.Data.Tables; using GovUk.Education.ExploreEducationStatistics.Common.Extensions; diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerCachingTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerCachingTests.cs index 651ba30ac9d..efa82dcb7ee 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerCachingTests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerCachingTests.cs @@ -31,6 +31,7 @@ public class ListDataSetsTests : DataSetFilesControllerCachingTests ThemeId: Guid.NewGuid(), PublicationId: Guid.NewGuid(), ReleaseId: Guid.NewGuid(), + GeographicLevel: GeographicLevel.Country.GetEnumValue(), LatestOnly: true, DataSetType: DataSetType.Api, SearchTerm: "term", @@ -116,6 +117,7 @@ public async Task NoCachedEntryExists_CreatesCache() _query.ThemeId, _query.PublicationId, _query.ReleaseId, + _query.GeographicLevelEnum, _query.LatestOnly, _query.DataSetType, _query.SearchTerm, diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/DataSetFilesController.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/DataSetFilesController.cs index 015a79b28da..db48b8fc809 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/DataSetFilesController.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/DataSetFilesController.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using GovUk.Education.ExploreEducationStatistics.Common.Cache; using GovUk.Education.ExploreEducationStatistics.Common.Extensions; +using GovUk.Education.ExploreEducationStatistics.Common.Model.Data; using GovUk.Education.ExploreEducationStatistics.Common.ViewModels; using GovUk.Education.ExploreEducationStatistics.Content.Api.Cache; using GovUk.Education.ExploreEducationStatistics.Content.Requests; @@ -39,6 +40,7 @@ public async Task + GeographicLevel == null + ? null + : EnumUtil.GetFromEnumValue(GeographicLevel); + public class Validator : AbstractValidator { public Validator() @@ -23,6 +32,9 @@ public Validator() .MinimumLength(3); RuleFor(request => request.ReleaseId).NotEmpty() .When(request => request.Sort == DataSetsListRequestSortBy.Natural); + RuleFor(request => request.GeographicLevel) + .AllowedValue(EnumUtil.GetEnumValues()) + .When(request => request.GeographicLevel != null); RuleFor(request => request.SearchTerm).NotEmpty() .When(request => request.Sort == DataSetsListRequestSortBy.Relevance); RuleFor(request => request.Page) diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs index ab71aad330e..4a0775ccddd 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs @@ -26,35 +26,25 @@ using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using GovUk.Education.ExploreEducationStatistics.Common.Model.Data; using static GovUk.Education.ExploreEducationStatistics.Common.Model.SortDirection; using static GovUk.Education.ExploreEducationStatistics.Content.Requests.DataSetsListRequestSortBy; using ReleaseVersion = GovUk.Education.ExploreEducationStatistics.Content.Model.ReleaseVersion; namespace GovUk.Education.ExploreEducationStatistics.Content.Services; -public class DataSetFileService : IDataSetFileService +public class DataSetFileService( + ContentDbContext contentDbContext, + IReleaseVersionRepository releaseVersionRepository, + IPublicBlobStorageService publicBlobStorageService, + IFootnoteRepository footnoteRepository) + : IDataSetFileService { - private readonly ContentDbContext _contentDbContext; - private readonly IReleaseVersionRepository _releaseVersionRepository; - private readonly IPublicBlobStorageService _publicBlobStorageService; - private readonly IFootnoteRepository _footnoteRepository; - - public DataSetFileService( - ContentDbContext contentDbContext, - IReleaseVersionRepository releaseVersionRepository, - IPublicBlobStorageService publicBlobStorageService, - IFootnoteRepository footnoteRepository) - { - _contentDbContext = contentDbContext; - _releaseVersionRepository = releaseVersionRepository; - _publicBlobStorageService = publicBlobStorageService; - _footnoteRepository = footnoteRepository; - } - public async Task>> ListDataSetFiles( Guid? themeId, Guid? publicationId, Guid? releaseVersionId, + GeographicLevel? geographicLevel, bool? latestOnly, DataSetType? dataSetType, string? searchTerm, @@ -73,18 +63,19 @@ public async Task rf.Id, searchTerm); + .JoinFreeText(contentDbContext.ReleaseFilesFreeTextTable, rf => rf.Id, searchTerm); var results = await query .OrderBy(sort.Value, sortDirection.Value) @@ -144,10 +135,10 @@ private static Expression, DataSetFileSumm public async Task>> ListSitemapItems( CancellationToken cancellationToken = default) { - var latestReleaseVersions = _contentDbContext.ReleaseVersions + var latestReleaseVersions = contentDbContext.ReleaseVersions .LatestReleaseVersions(publishedOnly: true); - var latestReleaseFiles = _contentDbContext.ReleaseFiles + var latestReleaseFiles = contentDbContext.ReleaseFiles .AsNoTracking() .OfFileType(FileType.Data) .HavingNoDataReplacementInProgress() @@ -176,7 +167,7 @@ private static async Task> ChangeSummaryHtmlTo public async Task> GetDataSetFile(Guid dataSetFileId) { - var releaseFile = await _contentDbContext.ReleaseFiles + var releaseFile = await contentDbContext.ReleaseFiles .Include(rf => rf.ReleaseVersion.Publication.Theme) .Include(rf => rf.ReleaseVersion.Publication.SupersededBy) .Include(rf => rf.File) @@ -188,7 +179,7 @@ public async Task> GetDataSetFile(Gui .FirstOrDefaultAsync(); if (releaseFile == null - || !await _releaseVersionRepository.IsLatestPublishedReleaseVersion( + || !await releaseVersionRepository.IsLatestPublishedReleaseVersion( releaseFile.ReleaseVersionId)) { return new NotFoundResult(); @@ -198,7 +189,7 @@ public async Task> GetDataSetFile(Gui var variables = GetVariables(releaseFile.File.DataSetFileMeta!); - var footnotes = await _footnoteRepository.GetFootnotes( + var footnotes = await footnoteRepository.GetFootnotes( releaseFile.ReleaseVersionId, releaseFile.File.SubjectId); @@ -249,7 +240,7 @@ public async Task> GetDataSetFile(Gui public async Task DownloadDataSetFile( Guid dataSetFileId) { - var releaseFile = await _contentDbContext.ReleaseFiles + var releaseFile = await contentDbContext.ReleaseFiles .Include(rf => rf.File) .Where(rf => rf.File.DataSetFileId == dataSetFileId @@ -259,13 +250,13 @@ public async Task DownloadDataSetFile( .FirstOrDefaultAsync(); if (releaseFile == null - || !await _releaseVersionRepository.IsLatestPublishedReleaseVersion( + || !await releaseVersionRepository.IsLatestPublishedReleaseVersion( releaseFile.ReleaseVersionId)) { return new NotFoundResult(); } - var stream = await _publicBlobStorageService.StreamBlob( + var stream = await publicBlobStorageService.StreamBlob( containerName: BlobContainers.PublicReleaseFiles, path: releaseFile.PublicPath()); @@ -306,7 +297,7 @@ private static DataSetFileMetaViewModel BuildDataSetFileMetaViewModel( private async Task GetDataCsvPreview(ReleaseFile releaseFile) { - var datafileStreamProvider = () => _publicBlobStorageService.StreamBlob( + var datafileStreamProvider = () => publicBlobStorageService.StreamBlob( containerName: BlobContainers.PublicReleaseFiles, path: releaseFile.PublicPath()); @@ -491,6 +482,17 @@ internal static IQueryable HavingReleaseVersionId( return releaseVersionId.HasValue ? query.Where(rf => rf.ReleaseVersionId == releaseVersionId.Value) : query; } + internal static IQueryable HavingGeographicLevel( // @MarkFix write tests + this IQueryable query, + GeographicLevel? geographicLevel) + { + return geographicLevel.HasValue + ? query.Where(rf => rf.File.DataSetFileGeographicLevels!.Any( // @MarkFix null allowing + gl => gl.GeographicLevel == geographicLevel + && rf.FileId == gl.DataSetFileVersionId)) + : query; + } + internal static IQueryable OfDataSetType( this IQueryable query, DataSetType dataSetType) diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Services/Interfaces/IDataSetFileService.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Services/Interfaces/IDataSetFileService.cs index 1b5cb2a3372..0a16d4cb669 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Services/Interfaces/IDataSetFileService.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Services/Interfaces/IDataSetFileService.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using GovUk.Education.ExploreEducationStatistics.Common.Model; +using GovUk.Education.ExploreEducationStatistics.Common.Model.Data; using GovUk.Education.ExploreEducationStatistics.Common.ViewModels; using GovUk.Education.ExploreEducationStatistics.Content.Requests; using GovUk.Education.ExploreEducationStatistics.Content.ViewModels; @@ -17,6 +18,7 @@ Task>> Guid? themeId, Guid? publicationId, Guid? releaseVersionId, + GeographicLevel? geographicLevel, bool? latestOnly, DataSetType? dataSetType, string? searchTerm, diff --git a/src/explore-education-statistics-frontend/src/modules/data-catalogue/DataCataloguePage.tsx b/src/explore-education-statistics-frontend/src/modules/data-catalogue/DataCataloguePage.tsx index e551420f4d2..c14872aa2e0 100644 --- a/src/explore-education-statistics-frontend/src/modules/data-catalogue/DataCataloguePage.tsx +++ b/src/explore-education-statistics-frontend/src/modules/data-catalogue/DataCataloguePage.tsx @@ -52,6 +52,7 @@ import omit from 'lodash/omit'; import Head from 'next/head'; import { useRouter } from 'next/router'; import { ParsedUrlQuery } from 'querystring'; +import { GeographicLevelCode } from '@common/utils/locationLevelsMap'; const defaultPageTitle = 'Data catalogue'; @@ -61,6 +62,7 @@ export interface DataCataloguePageQuery { page?: number; publicationId?: string; releaseId?: string; + geographicLevel?: GeographicLevelCode; searchTerm?: string; sortBy?: DataSetFileSortOption; sortDirection?: SortDirection; @@ -85,6 +87,7 @@ const DataCataloguePage: NextPage = ({ showTypeFilter }) => { sortBy, publicationId, releaseId, + geographicLevel, searchTerm, themeId, } = getParamsFromQuery(router.query); @@ -131,6 +134,7 @@ const DataCataloguePage: NextPage = ({ showTypeFilter }) => { searchTerm, selectedTheme?.title, selectedPublication?.title, + geographicLevel, ]).join(', '); const updateQueryParams = async (nextQuery: DataCataloguePageQuery) => { @@ -327,6 +331,7 @@ const DataCataloguePage: NextPage = ({ showTypeFilter }) => { publicationId={publicationId} publications={publications} releaseId={releaseId} + geographicLevel={geographicLevel} releases={releases} showResetFiltersButton={!isMobileMedia && isFiltered} showTypeFilter={showTypeFilter} diff --git a/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/Filters.tsx b/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/Filters.tsx index 1dc33f5d1ed..c564cbc8fd5 100644 --- a/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/Filters.tsx +++ b/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/Filters.tsx @@ -13,6 +13,10 @@ import styles from '@frontend/modules/data-catalogue/components/Filters.module.s import { DataSetFileFilter } from '@frontend/modules/data-catalogue/utils/dataSetFileFilters'; import React from 'react'; import classNames from 'classnames'; +import locationLevelsMap, { + GeographicLevelCode, +} from '@common/utils/locationLevelsMap'; +import typedKeys from '@common/utils/object/typedKeys'; const formId = 'filters-form'; @@ -23,6 +27,7 @@ interface Props { publications?: PublicationTreeSummary[]; releaseId?: string; releases?: ReleaseSummary[]; + geographicLevel?: GeographicLevelCode; showResetFiltersButton?: boolean; showTypeFilter?: boolean; themeId?: string; @@ -44,6 +49,7 @@ export default function Filters({ publicationId, releaseId, releases = [], + geographicLevel, showResetFiltersButton, showTypeFilter, themeId, @@ -140,6 +146,36 @@ export default function Filters({ /> + + + Filter by Geographic level + + } + name="geographicLevel" + options={[ + { label: 'All', value: 'all' }, + ...typedKeys(locationLevelsMap).map(key => { + return { + label: locationLevelsMap[key].label, + value: locationLevelsMap[key].code, + }; + }), + ]} + value={geographicLevel} + order={[]} + onChange={e => { + onChange({ + filterType: 'geographicLevel', + nextValue: e.target.value, + }); + }} + /> + + {showResetFiltersButton && ( Date: Fri, 13 Dec 2024 16:35:11 +0000 Subject: [PATCH 5/7] EES-5738 Add tests --- .../DataSetFilesControllerTests.cs | 47 +++++++++++++++++ .../Fixtures/DataImportGeneratorExtensions.cs | 34 ++++++++++++- ...tFileGeographicLevelGeneratorExtensions.cs | 50 +++++++++++++++++++ .../Fixtures/FileGeneratorExtensions.cs | 23 ++++++++- .../File.cs | 2 +- .../DataSetFileService.cs | 4 +- .../Functions/ProcessorStage3Tests.cs | 21 ++++---- .../Services/DataImportServiceTests.cs | 1 + .../Services/DataImportService.cs | 1 + .../data-catalogue/__data__/testDataSets.ts | 2 +- .../__tests__/DataCataloguePage.test.tsx | 26 ++++++++++ .../__tests__/DataSetSummary.test.tsx | 4 +- 12 files changed, 195 insertions(+), 20 deletions(-) create mode 100644 src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileGeographicLevelGeneratorExtensions.cs diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerTests.cs index 91a6b434769..b69ddb03ce6 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerTests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerTests.cs @@ -95,6 +95,51 @@ await TestApp.AddTestData(context => AssertResultsForExpectedReleaseFiles(publication1Release1Version1Files, pagedResult.Results); } + [Fact] + public async Task FilterByGeographicLevel_Success() + { + var (publication1, publication2) = _fixture + .DefaultPublication() + // Publications each have a published release version + .WithReleases(_fixture.DefaultRelease(publishedVersions: 1) + .Generate(1)) + .WithTheme(_fixture.DefaultTheme()) + .GenerateTuple2(); + + var publication1Release1Version1Files = _fixture.DefaultReleaseFile() + .WithReleaseVersion(publication1.ReleaseVersions[0]) + .WithFiles(_fixture.DefaultFile(FileType.Data) + .WithDataSetFileMeta(_fixture.DefaultDataSetFileMeta() + .WithGeographicLevels( + [GeographicLevel.Country, GeographicLevel.LocalAuthority, GeographicLevel.Institution])) + .WithDataSetFileGeographicLevels( + [GeographicLevel.Country, GeographicLevel.LocalAuthority, GeographicLevel.Institution]) + .GenerateList(1)) + .GenerateList(); + + var publication2Release1Version1Files = GenerateDataSetFilesForReleaseVersion(publication2.ReleaseVersions[0]); + + await TestApp.AddTestData(context => + { + context.ReleaseFiles.AddRange(publication1Release1Version1Files); + context.ReleaseFiles.AddRange(publication2Release1Version1Files); + }); + + MemoryCacheService + .SetupNotFoundForAnyKey>(); + + var query = new DataSetFileListRequest(GeographicLevel: GeographicLevel.Institution.GetEnumValue()); + var response = await ListDataSetFiles(query); + + MockUtils.VerifyAllMocks(MemoryCacheService); + + var pagedResult = response.AssertOk>(); + + pagedResult.AssertHasExpectedPagingAndResultCount( + expectedTotalResults: 1); + AssertResultsForExpectedReleaseFiles(publication1Release1Version1Files, pagedResult.Results); + } + [Fact] public async Task FilterByPublicationId_Success() { @@ -1675,6 +1720,7 @@ private async Task ListDataSetFiles( { "themeId", request.ThemeId?.ToString() }, { "publicationId", request.PublicationId?.ToString() }, { "releaseId", request.ReleaseId?.ToString() }, + { "geographicLevel", request.GeographicLevel }, { "latestOnly", request.LatestOnly?.ToString() }, { "searchTerm", request.SearchTerm }, { "sort", request.Sort?.ToString() }, @@ -1737,6 +1783,7 @@ private List GenerateDataSetFilesForReleaseVersion( .WithReleaseVersion(releaseVersion) .WithFiles(_fixture.DefaultFile(FileType.Data) .WithDataSetFileMeta(_fixture.DefaultDataSetFileMeta()) + .WithDataSetFileGeographicLevels([GeographicLevel.Country]) .GenerateList(numberOfDataSets)) .GenerateList(); } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataImportGeneratorExtensions.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataImportGeneratorExtensions.cs index 7a02d7410cf..0eab870e422 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataImportGeneratorExtensions.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataImportGeneratorExtensions.cs @@ -19,8 +19,15 @@ public static Generator WithSubjectId( public static Generator WithDefaultFiles( this Generator generator, - string dataFileName) - => generator.ForInstance(s => s.SetDefaultFiles(dataFileName)); + string dataFileName, + bool metaSet = true) + { + if (metaSet) + { + return generator.ForInstance(s => s.SetDefaultFiles(dataFileName)); + } + return generator.ForInstance(s => s.SetDefaultFilesWithoutMeta(dataFileName)); + } public static Generator WithFile( this Generator generator, @@ -98,6 +105,29 @@ public static InstanceSetters SetDefaultFiles( ) .Set(d => d.MetaFileId, (_, d) => d.MetaFile.Id); + public static InstanceSetters SetDefaultFilesWithoutMeta( + this InstanceSetters setters, + string dataFileName) + => setters + .Set( + d => d.File, + (_, d, context) => context.Fixture + .DefaultFile(FileType.Data) + .WithDataSetFileMeta(null) + .WithDataSetFileGeographicLevels([]) + .WithFilename($"{dataFileName}.csv") + .WithSubjectId(d.SubjectId) + ) + .Set(d => d.FileId, (_, d) => d.File.Id) + .Set( + d => d.MetaFile, + (_, d, context) => context.Fixture + .DefaultFile(FileType.Metadata) + .WithFilename($"{dataFileName}.meta.csv") + .WithSubjectId(d.SubjectId) + ) + .Set(d => d.MetaFileId, (_, d) => d.MetaFile.Id); + public static InstanceSetters SetFile( this InstanceSetters setters, File file) diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileGeographicLevelGeneratorExtensions.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileGeographicLevelGeneratorExtensions.cs new file mode 100644 index 00000000000..b9c7d83a357 --- /dev/null +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileGeographicLevelGeneratorExtensions.cs @@ -0,0 +1,50 @@ +using System; +using GovUk.Education.ExploreEducationStatistics.Common.Model.Data; +using GovUk.Education.ExploreEducationStatistics.Common.Tests.Fixtures; + +namespace GovUk.Education.ExploreEducationStatistics.Content.Model.Tests.Fixtures; + +public static class DataSetFileGeographicLevelGeneratorExtensions +{ + public static Generator DefaultDataSetFileGeographicLevel(this DataFixture fixture) + => fixture.Generator().WithDefaults(); + + public static Generator WithDefaults(this Generator generator) + => generator.ForInstance(d => d.SetDefaults()); + + public static InstanceSetters SetDefaults( + this InstanceSetters setters) + => setters + .SetDataSetFileVersionId(Guid.NewGuid()) + .SetGeographicLevel(GeographicLevel.Country); + + public static Generator WithDataSetFileVersion( + this Generator generator, + File dataSetFileVersion) + => generator.ForInstance(s => s.SetDataSetFileVersion(dataSetFileVersion)); + + public static Generator WithDataSetFileVersionId( + this Generator generator, + Guid dataSetFileVersionId) + => generator.ForInstance(s => s.SetDataSetFileVersionId(dataSetFileVersionId)); + + public static Generator WithGeographicLevel( + this Generator generator, + GeographicLevel geographicLevel) + => generator.ForInstance(s => s.SetGeographicLevel(geographicLevel)); + + public static InstanceSetters SetDataSetFileVersion( + this InstanceSetters setters, + File dataSetFileVersion) + => setters.Set(f => f.DataSetFileVersion, dataSetFileVersion); + + public static InstanceSetters SetDataSetFileVersionId( + this InstanceSetters setters, + Guid dataSetFileVersionId) + => setters.Set(f => f.DataSetFileVersionId, dataSetFileVersionId); + + public static InstanceSetters SetGeographicLevel( + this InstanceSetters setters, + GeographicLevel geographicLevel) + => setters.Set(f => f.GeographicLevel, geographicLevel); +} diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/FileGeneratorExtensions.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/FileGeneratorExtensions.cs index f45b0e99adc..b60fb4e6798 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/FileGeneratorExtensions.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/FileGeneratorExtensions.cs @@ -1,8 +1,9 @@ using System; +using System.Collections.Generic; +using System.Linq; using GovUk.Education.ExploreEducationStatistics.Common.Model; using GovUk.Education.ExploreEducationStatistics.Common.Model.Data; using GovUk.Education.ExploreEducationStatistics.Common.Tests.Fixtures; -using Semver; namespace GovUk.Education.ExploreEducationStatistics.Content.Model.Tests.Fixtures; @@ -84,6 +85,11 @@ public static Generator WithDataSetFileMeta( DataSetFileMeta? dataSetFileMeta) => generator.ForInstance(s => s.SetDataSetFileMeta(dataSetFileMeta)); + public static Generator WithDataSetFileGeographicLevels( + this Generator generator, + List geographicLevels) + => generator.ForInstance(s => s.SetDataSetFileGeographicLevels(geographicLevels)); + public static InstanceSetters SetDefaults(this InstanceSetters setters, FileType? fileType) => fileType switch { @@ -110,7 +116,8 @@ public static InstanceSetters SetDataFileDefaults(this InstanceSetters f.SubjectId) .SetContentType("text/csv") .SetDefault(f => f.DataSetFileId) - .Set(f => f.DataSetFileMeta, (_, _, context) => context.Fixture.DefaultDataSetFileMeta()); + .Set(f => f.DataSetFileMeta, (_, _, context) => context.Fixture.DefaultDataSetFileMeta()) + .SetDataSetFileGeographicLevels([GeographicLevel.Country, GeographicLevel.LocalAuthority, GeographicLevel.LocalAuthorityDistrict]); public static InstanceSetters SetMetaFileDefaults(this InstanceSetters setters) => setters @@ -200,4 +207,16 @@ public static InstanceSetters SetDataSetFileMeta( this InstanceSetters setters, DataSetFileMeta? dataSetFileMeta) => setters.Set(f => f.DataSetFileMeta, dataSetFileMeta); + + public static InstanceSetters SetDataSetFileGeographicLevels( + this InstanceSetters setters, + List geographicLevels) + => setters.Set( + file => file.DataSetFileGeographicLevels, + (_, file) => geographicLevels.Select( + gl => new DataSetFileGeographicLevel + { + DataSetFileVersionId = file.Id, + GeographicLevel = gl, + }).ToList()); } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs index 8fc1696a46a..42c6f75b9dd 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs @@ -23,7 +23,7 @@ public class File : ICreatedTimestamp public int? DataSetFileVersion { get; set; } - public List? DataSetFileGeographicLevels { get; set; } + public List DataSetFileGeographicLevels { get; set; } = []; public DataSetFileMeta? DataSetFileMeta { get; set; } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs index 4a0775ccddd..b743fd1198e 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs @@ -482,12 +482,12 @@ internal static IQueryable HavingReleaseVersionId( return releaseVersionId.HasValue ? query.Where(rf => rf.ReleaseVersionId == releaseVersionId.Value) : query; } - internal static IQueryable HavingGeographicLevel( // @MarkFix write tests + internal static IQueryable HavingGeographicLevel( this IQueryable query, GeographicLevel? geographicLevel) { return geographicLevel.HasValue - ? query.Where(rf => rf.File.DataSetFileGeographicLevels!.Any( // @MarkFix null allowing + ? query.Where(rf => rf.File.DataSetFileGeographicLevels.Any( gl => gl.GeographicLevel == geographicLevel && rf.FileId == gl.DataSetFileVersionId)) : query; diff --git a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Functions/ProcessorStage3Tests.cs b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Functions/ProcessorStage3Tests.cs index 36f3fdc9e87..965c0c781e1 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Functions/ProcessorStage3Tests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Functions/ProcessorStage3Tests.cs @@ -23,6 +23,7 @@ using GovUk.Education.ExploreEducationStatistics.Data.Processor.Services; using GovUk.Education.ExploreEducationStatistics.Data.Processor.Services.Interfaces; using GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests.Services; +using GovUk.Education.ExploreEducationStatistics.Public.Data.Model.Migrations; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -106,7 +107,7 @@ public async Task ProcessStage3() var import = _fixture .DefaultDataImport() .WithSubjectId(_subject.Id) - .WithDefaultFiles("small-csv") + .WithDefaultFiles("small-csv", metaSet: false) .WithStatus(STAGE_3) .WithTotalRows(16) .WithExpectedImportedRows(16) @@ -325,7 +326,7 @@ public async Task ProcessStage3_FailsImportIfRowCountsDontMatch() var import = _fixture .DefaultDataImport() .WithSubjectId(_subject.Id) - .WithDefaultFiles("small-csv") + .WithDefaultFiles("small-csv", metaSet: false) .WithStatus(STAGE_3) .WithTotalRows(16) .WithExpectedImportedRows(16) @@ -454,7 +455,7 @@ public async Task ProcessStage3_PartiallyImportedAlready() var import = _fixture .DefaultDataImport() .WithSubjectId(_subject.Id) - .WithDefaultFiles("small-csv") + .WithDefaultFiles("small-csv", metaSet: false) .WithStatus(STAGE_3) .WithTotalRows(16) .WithExpectedImportedRows(16) @@ -604,7 +605,7 @@ public async Task ProcessStage3_PartiallyImportedAlready_BatchSizeChanged() var import = _fixture .DefaultDataImport() .WithSubjectId(_subject.Id) - .WithDefaultFiles("small-csv") + .WithDefaultFiles("small-csv", metaSet: false) .WithStatus(STAGE_3) .WithTotalRows(16) .WithExpectedImportedRows(16) @@ -749,7 +750,7 @@ public async Task ProcessStage3_IgnoredRows() var import = _fixture .DefaultDataImport() .WithSubjectId(_subject.Id) - .WithDefaultFiles("ignored-school-rows") + .WithDefaultFiles("ignored-school-rows", metaSet: false) .WithStatus(STAGE_3) .WithTotalRows(16) .WithExpectedImportedRows(8) @@ -894,7 +895,7 @@ public async Task ProcessStage3_IgnoredRows_PartiallyImported() var import = _fixture .DefaultDataImport() .WithSubjectId(_subject.Id) - .WithDefaultFiles("ignored-school-rows") + .WithDefaultFiles("ignored-school-rows", metaSet: false) .WithStatus(STAGE_3) .WithTotalRows(16) .WithExpectedImportedRows(8) @@ -1052,7 +1053,7 @@ public async Task ProcessStage3_Cancelling() var import = _fixture .DefaultDataImport() .WithSubjectId(_subject.Id) - .WithDefaultFiles("small-csv") + .WithDefaultFiles("small-csv", metaSet: false) .WithStatus(STAGE_3) .WithTotalRows(16) .WithExpectedImportedRows(16) @@ -1190,7 +1191,7 @@ public async Task ProcessStage3_CancelledAlready() var import = _fixture .DefaultDataImport() .WithSubjectId(_subject.Id) - .WithDefaultFiles("small-csv") + .WithDefaultFiles("small-csv", metaSet: false) .WithStatus(CANCELLED) .WithTotalRows(16) .WithExpectedImportedRows(16) @@ -1324,7 +1325,7 @@ public async Task ProcessStage3_AdditionalFiltersAndIndicators() var import = _fixture .DefaultDataImport() .WithSubjectId(_subject.Id) - .WithDefaultFiles("additional-filters-and-indicators") + .WithDefaultFiles("additional-filters-and-indicators", metaSet: false) .WithStatus(STAGE_3) .WithTotalRows(16) .WithExpectedImportedRows(16) @@ -1493,7 +1494,7 @@ public async Task ProcessStage3_SpecialFilterItemAndIndicatorValues() var import = _fixture .DefaultDataImport() .WithSubjectId(subject.Id) - .WithDefaultFiles("small-csv-with-special-data") + .WithDefaultFiles("small-csv-with-special-data", metaSet: false) .WithStatus(STAGE_3) .WithTotalRows(5) .WithExpectedImportedRows(5) diff --git a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs index 5aa9ee86309..8463051e0f5 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs @@ -220,6 +220,7 @@ public async Task WriteDataSetMetaFile_Success() var file = _fixture.DefaultFile(FileType.Data) .WithDataSetFileMeta(null) + .WithDataSetFileGeographicLevels([]) .WithSubjectId(subject.Id) .Generate(); diff --git a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs index acb15120605..162c826776d 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs @@ -222,6 +222,7 @@ public async Task WriteDataSetFileMeta(Guid fileId, Guid subjectId) file.DataSetFileMeta = dataSetFileMeta; var dataSetFileGeographicLevels = geographicLevels + .Distinct() .Select(gl => new DataSetFileGeographicLevel { DataSetFileVersionId = fileId, diff --git a/src/explore-education-statistics-frontend/src/modules/data-catalogue/__data__/testDataSets.ts b/src/explore-education-statistics-frontend/src/modules/data-catalogue/__data__/testDataSets.ts index c73c983240c..c6a2e4a13ca 100644 --- a/src/explore-education-statistics-frontend/src/modules/data-catalogue/__data__/testDataSets.ts +++ b/src/explore-education-statistics-frontend/src/modules/data-catalogue/__data__/testDataSets.ts @@ -77,7 +77,7 @@ export const testDataSetFileSummaries: DataSetFileSummary[] = [ to: '2020', }, filters: ['Filter 1', 'Filter 2'], - geographicLevels: ['National', 'Regional'], + geographicLevels: ['National', 'Regional', 'Local authority'], indicators: ['Indicator 1', 'Indicator 2'], }, latestData: true, diff --git a/src/explore-education-statistics-frontend/src/modules/data-catalogue/__tests__/DataCataloguePage.test.tsx b/src/explore-education-statistics-frontend/src/modules/data-catalogue/__tests__/DataCataloguePage.test.tsx index 4026e9df8c6..e6b684958f7 100644 --- a/src/explore-education-statistics-frontend/src/modules/data-catalogue/__tests__/DataCataloguePage.test.tsx +++ b/src/explore-education-statistics-frontend/src/modules/data-catalogue/__tests__/DataCataloguePage.test.tsx @@ -1195,6 +1195,32 @@ describe('DataCataloguePage', () => { ).toBeInTheDocument(); }); + test('filters by geographic level', async () => { + mockRouter.setCurrentUrl('/data-catalogue?geographicLevel=LA'); + + dataSetService.listDataSetFiles.mockResolvedValueOnce({ + results: [testDataSetFileSummaries[1], testDataSetFileSummaries[2]], + paging: { ...testPaging, totalPages: 1, totalResults: 1 }, + }); + publicationService.getPublicationTree.mockResolvedValue(testThemes); + publicationService.listReleases.mockResolvedValue(testReleases); + + render(); + + await waitFor(() => { + expect(screen.getByText('1 data set')).toBeInTheDocument(); + }); + + expect(mockRouter).toMatchObject({ + pathname: '/data-catalogue', + query: { geographicLevel: 'LA' }, + }); + + expect(screen.getByLabelText('Filter by Geographic level')).toHaveValue( + 'LA', + ); + }); + test('filters by search term', async () => { mockRouter.setCurrentUrl('/data-catalogue?searchTerm=find+me'); diff --git a/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/__tests__/DataSetSummary.test.tsx b/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/__tests__/DataSetSummary.test.tsx index ddf431535b5..fd464e53a87 100644 --- a/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/__tests__/DataSetSummary.test.tsx +++ b/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/__tests__/DataSetSummary.test.tsx @@ -50,7 +50,7 @@ describe('DataSetFileSummary', () => { expect( within(screen.getByTestId('Geographic levels')).getByText( - 'National, Regional', + 'Local authority, National, Regional', ), ).toBeInTheDocument(); expect( @@ -83,7 +83,7 @@ describe('DataSetFileSummary', () => { expect( within(screen.getByTestId('Geographic levels')).getByText( - 'National, Regional', + 'Local authority, National, Regional', ), ).toBeInTheDocument(); expect( From 1d65b4b418c6ff75ea282e1fb3ba8c0799af53d4 Mon Sep 17 00:00:00 2001 From: Mark Youngman Date: Tue, 17 Dec 2024 12:23:51 +0000 Subject: [PATCH 6/7] EES-5738 Changes in response to PR comments --- ...FileGeographicLevelsMigrationController.cs | 14 ++--- ...aSetFileGeographicLevelsTable.Designer.cs} | 15 +++--- ...CreateDataSetFileGeographicLevelsTable.cs} | 22 +++++--- .../ContentDbContextModelSnapshot.cs | 13 ++--- .../DataSetFilesControllerTests.cs | 22 +++----- .../Fixtures/DataImportGeneratorExtensions.cs | 2 +- ...tFileGeographicLevelGeneratorExtensions.cs | 50 ------------------ ...rsionGeographicLevelGeneratorExtensions.cs | 51 +++++++++++++++++++ .../Fixtures/FileGeneratorExtensions.cs | 13 ++--- ...s => DataSetFileVersionGeographicLevel.cs} | 2 +- .../Database/ContentDbContext.cs | 11 ++-- .../File.cs | 2 +- .../DataSetFileService.cs | 5 +- .../Services/DataImportServiceTests.cs | 2 +- .../Services/DataImportService.cs | 8 +-- .../src/utils/locationLevelsMap.ts | 19 +++++++ .../data-catalogue/DataCataloguePage.tsx | 22 +++++++- .../data-catalogue/components/Filters.tsx | 4 +- .../admin_and_public/bau/data_catalogue.robot | 16 ++++++ 19 files changed, 177 insertions(+), 116 deletions(-) rename src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/{20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs => 20241219093820_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs} (99%) rename src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/{20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.cs => 20241219093820_EES5738_CreateDataSetFileGeographicLevelsTable.cs} (62%) delete mode 100644 src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileGeographicLevelGeneratorExtensions.cs create mode 100644 src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileVersionGeographicLevelGeneratorExtensions.cs rename src/GovUk.Education.ExploreEducationStatistics.Content.Model/{DataSetFileGeographicLevels.cs => DataSetFileVersionGeographicLevel.cs} (89%) diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Controllers/Api/DataSetFileGeographicLevelsMigrationController.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Controllers/Api/DataSetFileGeographicLevelsMigrationController.cs index f1adf49fd34..b4ceec2eb98 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Admin/Controllers/Api/DataSetFileGeographicLevelsMigrationController.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Controllers/Api/DataSetFileGeographicLevelsMigrationController.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using GovUk.Education.ExploreEducationStatistics.Admin.Models; using GovUk.Education.ExploreEducationStatistics.Common.Extensions; +using GovUk.Education.ExploreEducationStatistics.Common.Model; using GovUk.Education.ExploreEducationStatistics.Content.Model; using GovUk.Education.ExploreEducationStatistics.Content.Model.Database; using Microsoft.AspNetCore.Authorization; @@ -24,14 +25,14 @@ public class MigrationResult } [HttpPut("bau/migrate-datasetfile-geographiclevels")] - public async Task DataSetFileGeographicLevelsMigration( + public async Task DataSetFileVersionGeographicLevelsMigration( [FromQuery] bool isDryRun = true, [FromQuery] int? num = null, CancellationToken cancellationToken = default) { var queryable = contentDbContext.Files - .Where(f => f.DataSetFileMeta != null - && f.DataSetFileGeographicLevels.Count == 0); + .Where(f => f.Type == FileType.Data + && f.DataSetFileVersionGeographicLevels.Count == 0); if (num != null) { @@ -53,16 +54,17 @@ public async Task DataSetFileGeographicLevelsMigration( continue; } - var dataSetFileGeographicLevels = meta!.GeographicLevels + var dataSetFileVersionGeographicLevels = meta!.GeographicLevels .Distinct() - .Select(gl => new DataSetFileGeographicLevel + .Select(gl => new DataSetFileVersionGeographicLevel { DataSetFileVersionId = file.Id, GeographicLevel = gl, }) .ToList(); - contentDbContext.DataSetFileGeographicLevels.AddRange(dataSetFileGeographicLevels); + contentDbContext.DataSetFileVersionGeographicLevels.AddRange( + dataSetFileVersionGeographicLevels); numProcessed++; } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241219093820_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs similarity index 99% rename from src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs rename to src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241219093820_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs index 9c4bfa60215..739bb0e01e7 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241219093820_EES5738_CreateDataSetFileGeographicLevelsTable.Designer.cs @@ -12,7 +12,7 @@ namespace GovUk.Education.ExploreEducationStatistics.Admin.Migrations.ContentMigrations { [DbContext(typeof(ContentDbContext))] - [Migration("20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable")] + [Migration("20241219093820_EES5738_CreateDataSetFileGeographicLevelsTable")] partial class EES5738_CreateDataSetFileGeographicLevelsTable { /// @@ -331,17 +331,18 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.ToTable("DataImportErrors"); }); - modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileGeographicLevel", b => + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileVersionGeographicLevel", b => { b.Property("DataSetFileVersionId") .HasColumnType("uniqueidentifier"); b.Property("GeographicLevel") - .HasColumnType("nvarchar(450)"); + .HasMaxLength(6) + .HasColumnType("nvarchar(6)"); b.HasKey("DataSetFileVersionId", "GeographicLevel"); - b.ToTable("DataSetFileGeographicLevels"); + b.ToTable("DataSetFileVersionGeographicLevels"); }); modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.EmbedBlock", b => @@ -1610,10 +1611,10 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("DataImport"); }); - modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileGeographicLevel", b => + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileVersionGeographicLevel", b => { b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "DataSetFileVersion") - .WithMany("DataSetFileGeographicLevels") + .WithMany("DataSetFileVersionGeographicLevels") .HasForeignKey("DataSetFileVersionId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -2209,7 +2210,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.File", b => { - b.Navigation("DataSetFileGeographicLevels"); + b.Navigation("DataSetFileVersionGeographicLevels"); }); modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Methodology", b => diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241219093820_EES5738_CreateDataSetFileGeographicLevelsTable.cs similarity index 62% rename from src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.cs rename to src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241219093820_EES5738_CreateDataSetFileGeographicLevelsTable.cs index 1434036a2a3..7a652fbef83 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241213123442_EES5738_CreateDataSetFileGeographicLevelsTable.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/20241219093820_EES5738_CreateDataSetFileGeographicLevelsTable.cs @@ -1,6 +1,8 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; +#nullable disable + namespace GovUk.Education.ExploreEducationStatistics.Admin.Migrations.ContentMigrations { /// @@ -10,25 +12,27 @@ public partial class EES5738_CreateDataSetFileGeographicLevelsTable : Migration protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( - name: "DataSetFileGeographicLevels", + name: "DataSetFileVersionGeographicLevels", columns: table => new { DataSetFileVersionId = table.Column(type: "uniqueidentifier", nullable: false), - GeographicLevel = table.Column(type: "nvarchar(450)", nullable: false) + GeographicLevel = table.Column(type: "nvarchar(6)", maxLength: 6, nullable: false) }, constraints: table => { - table.PrimaryKey("PK_DataSetFileGeographicLevels", x => new { x.DataSetFileVersionId, x.GeographicLevel }); + table.PrimaryKey("PK_DataSetFileVersionGeographicLevels", x => new { x.DataSetFileVersionId, x.GeographicLevel }); table.ForeignKey( - name: "FK_DataSetFileGeographicLevels_Files_DataSetFileVersionId", + name: "FK_DataSetFileVersionGeographicLevels_Files_DataSetFileVersionId", column: x => x.DataSetFileVersionId, principalTable: "Files", principalColumn: "Id", onDelete: ReferentialAction.Cascade); }); + migrationBuilder.Sql("GRANT SELECT ON dbo.DataSetFileVersionGeographicLevels TO [content];"); + migrationBuilder.Sql("GRANT INSERT ON dbo.DataSetFileVersionGeographicLevels TO [importer];"); - migrationBuilder.Sql("GRANT SELECT ON dbo.DataSetFileGeographicLevels TO [content];"); - migrationBuilder.Sql("GRANT INSERT ON dbo.DataSetFileGeographicLevels TO [importer];"); + migrationBuilder.Sql("GRANT SELECT ON dbo.DataSetFileVersionGeographicLevels TO [data];"); + migrationBuilder.Sql("GRANT SELECT ON dbo.DataSetFileVersionGeographicLevels TO [publisher];"); } /// @@ -36,8 +40,12 @@ protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.Sql("REVOKE SELECT ON dbo.DataSetFileGeographicLevels TO [content];"); migrationBuilder.Sql("REVOKE INSERT ON dbo.DataSetFileGeographicLevels TO [importer];"); + + migrationBuilder.Sql("REVOKE SELECT ON dbo.DataSetFileGeographicLevels TO [data];"); + migrationBuilder.Sql("REVOKE SELECT ON dbo.DataSetFileGeographicLevels TO [publisher];"); + migrationBuilder.DropTable( - name: "DataSetFileGeographicLevels"); + name: "DataSetFileVersionGeographicLevels"); } } } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs index bc677140783..292daec9d7f 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Admin/Migrations/ContentMigrations/ContentDbContextModelSnapshot.cs @@ -328,17 +328,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("DataImportErrors"); }); - modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileGeographicLevel", b => + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileVersionGeographicLevel", b => { b.Property("DataSetFileVersionId") .HasColumnType("uniqueidentifier"); b.Property("GeographicLevel") - .HasColumnType("nvarchar(450)"); + .HasMaxLength(6) + .HasColumnType("nvarchar(6)"); b.HasKey("DataSetFileVersionId", "GeographicLevel"); - b.ToTable("DataSetFileGeographicLevels"); + b.ToTable("DataSetFileVersionGeographicLevels"); }); modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.EmbedBlock", b => @@ -1607,10 +1608,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("DataImport"); }); - modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileGeographicLevel", b => + modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.DataSetFileVersionGeographicLevel", b => { b.HasOne("GovUk.Education.ExploreEducationStatistics.Content.Model.File", "DataSetFileVersion") - .WithMany("DataSetFileGeographicLevels") + .WithMany("DataSetFileVersionGeographicLevels") .HasForeignKey("DataSetFileVersionId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -2206,7 +2207,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.File", b => { - b.Navigation("DataSetFileGeographicLevels"); + b.Navigation("DataSetFileVersionGeographicLevels"); }); modelBuilder.Entity("GovUk.Education.ExploreEducationStatistics.Content.Model.Methodology", b => diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerTests.cs index b69ddb03ce6..b32dde93656 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerTests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/DataSetFilesControllerTests.cs @@ -101,27 +101,21 @@ public async Task FilterByGeographicLevel_Success() var (publication1, publication2) = _fixture .DefaultPublication() // Publications each have a published release version - .WithReleases(_fixture.DefaultRelease(publishedVersions: 1) - .Generate(1)) + .WithReleases([_fixture.DefaultRelease(publishedVersions: 1)]) .WithTheme(_fixture.DefaultTheme()) .GenerateTuple2(); - var publication1Release1Version1Files = _fixture.DefaultReleaseFile() + ReleaseFile publication1Release1Version1File = _fixture.DefaultReleaseFile() .WithReleaseVersion(publication1.ReleaseVersions[0]) - .WithFiles(_fixture.DefaultFile(FileType.Data) - .WithDataSetFileMeta(_fixture.DefaultDataSetFileMeta() - .WithGeographicLevels( - [GeographicLevel.Country, GeographicLevel.LocalAuthority, GeographicLevel.Institution])) - .WithDataSetFileGeographicLevels( - [GeographicLevel.Country, GeographicLevel.LocalAuthority, GeographicLevel.Institution]) - .GenerateList(1)) - .GenerateList(); + .WithFile(_fixture.DefaultFile(FileType.Data) + .WithDataSetFileVersionGeographicLevels( + [GeographicLevel.Country, GeographicLevel.LocalAuthority, GeographicLevel.Institution])); var publication2Release1Version1Files = GenerateDataSetFilesForReleaseVersion(publication2.ReleaseVersions[0]); await TestApp.AddTestData(context => { - context.ReleaseFiles.AddRange(publication1Release1Version1Files); + context.ReleaseFiles.Add(publication1Release1Version1File); context.ReleaseFiles.AddRange(publication2Release1Version1Files); }); @@ -137,7 +131,7 @@ await TestApp.AddTestData(context => pagedResult.AssertHasExpectedPagingAndResultCount( expectedTotalResults: 1); - AssertResultsForExpectedReleaseFiles(publication1Release1Version1Files, pagedResult.Results); + AssertResultsForExpectedReleaseFiles([publication1Release1Version1File], pagedResult.Results); } [Fact] @@ -1783,7 +1777,7 @@ private List GenerateDataSetFilesForReleaseVersion( .WithReleaseVersion(releaseVersion) .WithFiles(_fixture.DefaultFile(FileType.Data) .WithDataSetFileMeta(_fixture.DefaultDataSetFileMeta()) - .WithDataSetFileGeographicLevels([GeographicLevel.Country]) + .WithDataSetFileVersionGeographicLevels([GeographicLevel.Country]) .GenerateList(numberOfDataSets)) .GenerateList(); } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataImportGeneratorExtensions.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataImportGeneratorExtensions.cs index 0eab870e422..5d13f4f4164 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataImportGeneratorExtensions.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataImportGeneratorExtensions.cs @@ -114,7 +114,7 @@ public static InstanceSetters SetDefaultFilesWithoutMeta( (_, d, context) => context.Fixture .DefaultFile(FileType.Data) .WithDataSetFileMeta(null) - .WithDataSetFileGeographicLevels([]) + .WithDataSetFileVersionGeographicLevels([]) .WithFilename($"{dataFileName}.csv") .WithSubjectId(d.SubjectId) ) diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileGeographicLevelGeneratorExtensions.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileGeographicLevelGeneratorExtensions.cs deleted file mode 100644 index b9c7d83a357..00000000000 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileGeographicLevelGeneratorExtensions.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using GovUk.Education.ExploreEducationStatistics.Common.Model.Data; -using GovUk.Education.ExploreEducationStatistics.Common.Tests.Fixtures; - -namespace GovUk.Education.ExploreEducationStatistics.Content.Model.Tests.Fixtures; - -public static class DataSetFileGeographicLevelGeneratorExtensions -{ - public static Generator DefaultDataSetFileGeographicLevel(this DataFixture fixture) - => fixture.Generator().WithDefaults(); - - public static Generator WithDefaults(this Generator generator) - => generator.ForInstance(d => d.SetDefaults()); - - public static InstanceSetters SetDefaults( - this InstanceSetters setters) - => setters - .SetDataSetFileVersionId(Guid.NewGuid()) - .SetGeographicLevel(GeographicLevel.Country); - - public static Generator WithDataSetFileVersion( - this Generator generator, - File dataSetFileVersion) - => generator.ForInstance(s => s.SetDataSetFileVersion(dataSetFileVersion)); - - public static Generator WithDataSetFileVersionId( - this Generator generator, - Guid dataSetFileVersionId) - => generator.ForInstance(s => s.SetDataSetFileVersionId(dataSetFileVersionId)); - - public static Generator WithGeographicLevel( - this Generator generator, - GeographicLevel geographicLevel) - => generator.ForInstance(s => s.SetGeographicLevel(geographicLevel)); - - public static InstanceSetters SetDataSetFileVersion( - this InstanceSetters setters, - File dataSetFileVersion) - => setters.Set(f => f.DataSetFileVersion, dataSetFileVersion); - - public static InstanceSetters SetDataSetFileVersionId( - this InstanceSetters setters, - Guid dataSetFileVersionId) - => setters.Set(f => f.DataSetFileVersionId, dataSetFileVersionId); - - public static InstanceSetters SetGeographicLevel( - this InstanceSetters setters, - GeographicLevel geographicLevel) - => setters.Set(f => f.GeographicLevel, geographicLevel); -} diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileVersionGeographicLevelGeneratorExtensions.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileVersionGeographicLevelGeneratorExtensions.cs new file mode 100644 index 00000000000..eb49d2897ec --- /dev/null +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/DataSetFileVersionGeographicLevelGeneratorExtensions.cs @@ -0,0 +1,51 @@ +using System; +using GovUk.Education.ExploreEducationStatistics.Common.Model.Data; +using GovUk.Education.ExploreEducationStatistics.Common.Tests.Fixtures; + +namespace GovUk.Education.ExploreEducationStatistics.Content.Model.Tests.Fixtures; + +public static class DataSetFileVersionGeographicLevelGeneratorExtensions +{ + public static Generator DefaultDataSetFileVersionGeographicLevel(this DataFixture fixture) + => fixture.Generator().WithDefaults(); + + public static Generator WithDefaults(this Generator generator) + => generator.ForInstance(d => d.SetDefaults()); + + public static InstanceSetters SetDefaults( + this InstanceSetters setters) + => setters + .SetDefault(p => p.DataSetFileVersionId); + + public static Generator WithDataSetFileVersion( + this Generator generator, + File dataSetFileVersion) + => generator.ForInstance(s => s.SetDataSetFileVersion(dataSetFileVersion)); + + public static Generator WithDataSetFileVersionId( + this Generator generator, + Guid dataSetFileVersionId) + => generator.ForInstance(s => s.SetDataSetFileVersionId(dataSetFileVersionId)); + + public static Generator WithGeographicLevel( + this Generator generator, + GeographicLevel geographicLevel) + => generator.ForInstance(s => s.SetGeographicLevel(geographicLevel)); + + public static InstanceSetters SetDataSetFileVersion( + this InstanceSetters setters, + File dataSetFileVersion) + => setters + .Set(f => f.DataSetFileVersion, dataSetFileVersion) + .Set(f => f.DataSetFileVersionId, dataSetFileVersion.Id); + + public static InstanceSetters SetDataSetFileVersionId( + this InstanceSetters setters, + Guid dataSetFileVersionId) + => setters.Set(f => f.DataSetFileVersionId, dataSetFileVersionId); + + public static InstanceSetters SetGeographicLevel( + this InstanceSetters setters, + GeographicLevel geographicLevel) + => setters.Set(f => f.GeographicLevel, geographicLevel); +} diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/FileGeneratorExtensions.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/FileGeneratorExtensions.cs index b60fb4e6798..320c2950442 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/FileGeneratorExtensions.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model.Tests/Fixtures/FileGeneratorExtensions.cs @@ -85,10 +85,10 @@ public static Generator WithDataSetFileMeta( DataSetFileMeta? dataSetFileMeta) => generator.ForInstance(s => s.SetDataSetFileMeta(dataSetFileMeta)); - public static Generator WithDataSetFileGeographicLevels( + public static Generator WithDataSetFileVersionGeographicLevels( this Generator generator, List geographicLevels) - => generator.ForInstance(s => s.SetDataSetFileGeographicLevels(geographicLevels)); + => generator.ForInstance(s => s.SetDataSetFileVersionGeographicLevels(geographicLevels)); public static InstanceSetters SetDefaults(this InstanceSetters setters, FileType? fileType) => fileType switch @@ -117,7 +117,7 @@ public static InstanceSetters SetDataFileDefaults(this InstanceSetters f.DataSetFileId) .Set(f => f.DataSetFileMeta, (_, _, context) => context.Fixture.DefaultDataSetFileMeta()) - .SetDataSetFileGeographicLevels([GeographicLevel.Country, GeographicLevel.LocalAuthority, GeographicLevel.LocalAuthorityDistrict]); + .SetDataSetFileVersionGeographicLevels([GeographicLevel.Country, GeographicLevel.LocalAuthority, GeographicLevel.LocalAuthorityDistrict]); public static InstanceSetters SetMetaFileDefaults(this InstanceSetters setters) => setters @@ -208,15 +208,16 @@ public static InstanceSetters SetDataSetFileMeta( DataSetFileMeta? dataSetFileMeta) => setters.Set(f => f.DataSetFileMeta, dataSetFileMeta); - public static InstanceSetters SetDataSetFileGeographicLevels( + public static InstanceSetters SetDataSetFileVersionGeographicLevels( this InstanceSetters setters, List geographicLevels) => setters.Set( - file => file.DataSetFileGeographicLevels, + file => file.DataSetFileVersionGeographicLevels, (_, file) => geographicLevels.Select( - gl => new DataSetFileGeographicLevel + gl => new DataSetFileVersionGeographicLevel { DataSetFileVersionId = file.Id, + DataSetFileVersion = file, GeographicLevel = gl, }).ToList()); } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileVersionGeographicLevel.cs similarity index 89% rename from src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs rename to src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileVersionGeographicLevel.cs index 2b23db07a4a..d677283dbe6 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileGeographicLevels.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/DataSetFileVersionGeographicLevel.cs @@ -4,7 +4,7 @@ namespace GovUk.Education.ExploreEducationStatistics.Content.Model; -public class DataSetFileGeographicLevel +public class DataSetFileVersionGeographicLevel { public Guid DataSetFileVersionId { get; set; } // Currently Files.Id, but will become DataSetFileVersion.Id in EES-5105 diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs index 2cec48a76d7..8521a3ede07 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/Database/ContentDbContext.cs @@ -55,7 +55,7 @@ private void Configure(bool updateTimestamps = true) public virtual DbSet ReleaseStatus { get; set; } public virtual DbSet ReleaseFiles { get; set; } public virtual DbSet Files { get; set; } - public virtual DbSet DataSetFileGeographicLevels { get; set; } + public virtual DbSet DataSetFileVersionGeographicLevels { get; set; } public virtual DbSet ContentSections { get; set; } public virtual DbSet ContentBlocks { get; set; } public virtual DbSet KeyStatistics { get; set; } @@ -111,7 +111,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) ConfigureReleaseStatus(modelBuilder); ConfigureReleaseFile(modelBuilder); ConfigureFile(modelBuilder); - ConfigureDataSetFileGeographicLevel(modelBuilder); + ConfigureDataSetFileVersionGeographicLevel(modelBuilder); ConfigureContentBlock(modelBuilder); ConfigureContentSection(modelBuilder); ConfigureReleaseVersion(modelBuilder); @@ -454,16 +454,16 @@ private static void ConfigureFile(ModelBuilder modelBuilder) v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Utc) : null); - entity.Property(p => p.DataSetFileMeta) // EES-5666 + entity.Property(p => p.DataSetFileMeta) .HasConversion( v => JsonConvert.SerializeObject(v), v => JsonConvert.DeserializeObject(v)); }); } - private static void ConfigureDataSetFileGeographicLevel(ModelBuilder modelBuilder) + private static void ConfigureDataSetFileVersionGeographicLevel(ModelBuilder modelBuilder) { - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasKey(gl => new { @@ -472,6 +472,7 @@ private static void ConfigureDataSetFileGeographicLevel(ModelBuilder modelBuilde }); entity.Property(gl => gl.GeographicLevel) + .HasMaxLength(6) .HasConversion(new EnumToEnumValueConverter()); }); } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs index 42c6f75b9dd..7ada31a8934 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Model/File.cs @@ -23,7 +23,7 @@ public class File : ICreatedTimestamp public int? DataSetFileVersion { get; set; } - public List DataSetFileGeographicLevels { get; set; } = []; + public List DataSetFileVersionGeographicLevels { get; set; } = []; public DataSetFileMeta? DataSetFileMeta { get; set; } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs index b743fd1198e..e6d0e9d85d9 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Services/DataSetFileService.cs @@ -487,9 +487,8 @@ internal static IQueryable HavingGeographicLevel( GeographicLevel? geographicLevel) { return geographicLevel.HasValue - ? query.Where(rf => rf.File.DataSetFileGeographicLevels.Any( - gl => gl.GeographicLevel == geographicLevel - && rf.FileId == gl.DataSetFileVersionId)) + ? query.Where(rf => rf.File.DataSetFileVersionGeographicLevels.Any( + gl => gl.GeographicLevel == geographicLevel)) : query; } diff --git a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs index 8463051e0f5..de19c60ad62 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor.Tests/Services/DataImportServiceTests.cs @@ -220,7 +220,7 @@ public async Task WriteDataSetMetaFile_Success() var file = _fixture.DefaultFile(FileType.Data) .WithDataSetFileMeta(null) - .WithDataSetFileGeographicLevels([]) + .WithDataSetFileVersionGeographicLevels([]) .WithSubjectId(subject.Id) .Generate(); diff --git a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs index 162c826776d..5b29fd83184 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Data.Processor/Services/DataImportService.cs @@ -221,14 +221,14 @@ public async Task WriteDataSetFileMeta(Guid fileId, Guid subjectId) && f.SubjectId == subjectId); file.DataSetFileMeta = dataSetFileMeta; - var dataSetFileGeographicLevels = geographicLevels - .Distinct() - .Select(gl => new DataSetFileGeographicLevel + var dataSetFileVersionGeographicLevels = geographicLevels + .Select(gl => new DataSetFileVersionGeographicLevel { DataSetFileVersionId = fileId, GeographicLevel = gl, }).ToList(); - await contentDbContext.DataSetFileGeographicLevels.AddRangeAsync(dataSetFileGeographicLevels); + contentDbContext.DataSetFileVersionGeographicLevels.AddRange( + dataSetFileVersionGeographicLevels); await contentDbContext.SaveChangesAsync(); } diff --git a/src/explore-education-statistics-common/src/utils/locationLevelsMap.ts b/src/explore-education-statistics-common/src/utils/locationLevelsMap.ts index 6f54b04f835..947dd7b3049 100644 --- a/src/explore-education-statistics-common/src/utils/locationLevelsMap.ts +++ b/src/explore-education-statistics-common/src/utils/locationLevelsMap.ts @@ -22,6 +22,7 @@ export type GeographicLevelCode = | 'WARD'; export interface LocationLevelDetails { + filterLabel: string; // used in the dropdown that filters data sets by geographic level label: string; plural: string; prefix: string; @@ -30,108 +31,126 @@ export interface LocationLevelDetails { const locationLevelsMap = { country: { + filterLabel: 'National', label: 'Country', plural: 'Countries', prefix: 'a', code: 'NAT', }, englishDevolvedArea: { + filterLabel: 'English Devolved Area', label: 'English Devolved Area', plural: 'English Devolved Areas', prefix: 'an', code: 'EDA', }, institution: { + filterLabel: 'Institution', label: 'Institution', plural: 'Institutions', prefix: 'an', code: 'INST', }, localAuthority: { + filterLabel: 'Local Authority', label: 'Local Authority', plural: 'Local Authorities', prefix: 'a', code: 'LA', }, localAuthorityDistrict: { + filterLabel: 'Local Authority District', label: 'Local Authority District', plural: 'Local Authority Districts', prefix: 'a', code: 'LAD', }, localEnterprisePartnership: { + filterLabel: 'Local Enterprise Partnership', label: 'Local Enterprise Partnership', plural: 'Local Enterprise Partnerships', prefix: 'a', code: 'LEP', }, localSkillsImprovementPlanArea: { + filterLabel: 'Local Skills Improvement Plan Area', label: 'Local Skills Improvement Plan Area', plural: 'Local Skills Improvement Plan Areas', prefix: 'a', code: 'LSIP', }, mayoralCombinedAuthority: { + filterLabel: 'Mayoral Combined Authority', label: 'Mayoral Combined Authority', plural: 'Mayoral Combined Authorities', prefix: 'a', code: 'MCA', }, multiAcademyTrust: { + filterLabel: 'Multi Academy Trust', label: 'Multi Academy Trust', plural: 'Multi Academy Trusts', prefix: 'a', code: 'MAT', }, opportunityArea: { + filterLabel: 'Opportunity Area', label: 'Opportunity Area', plural: 'Opportunity Areas', prefix: 'an', code: 'OA', }, parliamentaryConstituency: { + filterLabel: 'Parliamentary Constituency', label: 'Parliamentary Constituency', plural: 'Parliamentary Constituencies', prefix: 'a', code: 'PCON', }, planningArea: { + filterLabel: 'Planning Area', label: 'Planning Area', plural: 'Planning Areas', prefix: 'a', code: 'PA', }, provider: { + filterLabel: 'Provider', label: 'Provider', plural: 'Providers', prefix: 'a', code: 'PROV', }, region: { + filterLabel: 'Region', label: 'Region', plural: 'Regions', prefix: 'a', code: 'REG', }, rscRegion: { + filterLabel: 'RSC Region', label: 'RSC Region', plural: 'RSC Regions', prefix: 'an', code: 'RSC', }, school: { + filterLabel: 'School', label: 'School', plural: 'Schools', prefix: 'a', code: 'SCH', }, sponsor: { + filterLabel: 'Sponsor', label: 'Sponsor', plural: 'Sponsors', prefix: 'a', code: 'SPON', }, ward: { + filterLabel: 'Ward', label: 'Ward', plural: 'Wards', prefix: 'a', diff --git a/src/explore-education-statistics-frontend/src/modules/data-catalogue/DataCataloguePage.tsx b/src/explore-education-statistics-frontend/src/modules/data-catalogue/DataCataloguePage.tsx index c14872aa2e0..039b1dd1c12 100644 --- a/src/explore-education-statistics-frontend/src/modules/data-catalogue/DataCataloguePage.tsx +++ b/src/explore-education-statistics-frontend/src/modules/data-catalogue/DataCataloguePage.tsx @@ -52,7 +52,11 @@ import omit from 'lodash/omit'; import Head from 'next/head'; import { useRouter } from 'next/router'; import { ParsedUrlQuery } from 'querystring'; -import { GeographicLevelCode } from '@common/utils/locationLevelsMap'; +import locationLevelsMap, { + GeographicLevelCode, + geographicLevelCodesMap, + LocationLevelKey, +} from '@common/utils/locationLevelsMap'; const defaultPageTitle = 'Data catalogue'; @@ -124,11 +128,16 @@ const DataCataloguePage: NextPage = ({ showTypeFilter }) => { const selectedRelease = releases.find(release => release.id === releaseId); + const selectedGeographicLevel = geographicLevel + ? geographicLevelCodesMap[geographicLevel] + : undefined; + const { paging, results: dataSets = [] } = dataSetsData ?? {}; const { page, totalPages, totalResults = 0 } = paging ?? {}; const [showAllDetails, toggleAllDetails] = useToggle(false); - const isFiltered = !!publicationId || !!searchTerm || !!themeId; + const isFiltered = + !!publicationId || !!searchTerm || !!themeId || !!geographicLevel; const filteredByString = compact([ searchTerm, @@ -420,6 +429,15 @@ const DataCataloguePage: NextPage = ({ showTypeFilter }) => { } /> )} + {selectedGeographicLevel && ( + + handleResetFilter({ filterType: 'geographicLevel' }) + } + /> + )} )} diff --git a/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/Filters.tsx b/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/Filters.tsx index c564cbc8fd5..a5e34d16eb0 100644 --- a/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/Filters.tsx +++ b/src/explore-education-statistics-frontend/src/modules/data-catalogue/components/Filters.tsx @@ -160,12 +160,12 @@ export default function Filters({ { label: 'All', value: 'all' }, ...typedKeys(locationLevelsMap).map(key => { return { - label: locationLevelsMap[key].label, + label: locationLevelsMap[key].filterLabel, value: locationLevelsMap[key].code, }; }), ]} - value={geographicLevel} + value={geographicLevel ?? 'all'} order={[]} onChange={e => { onChange({ diff --git a/tests/robot-tests/tests/admin_and_public/bau/data_catalogue.robot b/tests/robot-tests/tests/admin_and_public/bau/data_catalogue.robot index d1781d21f42..ceff983c154 100644 --- a/tests/robot-tests/tests/admin_and_public/bau/data_catalogue.robot +++ b/tests/robot-tests/tests/admin_and_public/bau/data_catalogue.robot @@ -212,6 +212,22 @@ Remove release filter user checks page does not contain button ${PUPIL_ABSENCE_RELEASE_NAME} user checks selected option label id:filters-form-release All releases +Filter by geographic level + user wait for option to be available and select it css:select[id="filters-form-geographic-level"] + ... Local Authority District + + user checks page contains button Local Authority District + user checks testid element contains total-results 1 data set + +Remove geographic level filter + user clicks button Local Authority District + + user checks page does not contain button Local Authority District + user checks selected option label id:filters-form-geographic-level All + + user checks page contains button ${PUPILS_AND_SCHOOLS_THEME_TITLE} + user checks page contains button ${PUPIL_ABSENCE_PUBLICATION_TITLE} + Reset all filters user clicks element id:searchForm-search user presses keys pupil From 3968fb43a929712109bbf93ac464552f9b51e1c3 Mon Sep 17 00:00:00 2001 From: Mark Youngman Date: Fri, 20 Dec 2024 16:20:19 +0000 Subject: [PATCH 7/7] EES-5738 More changes in response to PR comments --- .../tests/admin_and_public/bau/data_catalogue.robot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/robot-tests/tests/admin_and_public/bau/data_catalogue.robot b/tests/robot-tests/tests/admin_and_public/bau/data_catalogue.robot index ceff983c154..659af1efdbc 100644 --- a/tests/robot-tests/tests/admin_and_public/bau/data_catalogue.robot +++ b/tests/robot-tests/tests/admin_and_public/bau/data_catalogue.robot @@ -219,6 +219,9 @@ Filter by geographic level user checks page contains button Local Authority District user checks testid element contains total-results 1 data set + user clicks button Show more details + user checks testid element contains Geographic levels-value Local authority district + Remove geographic level filter user clicks button Local Authority District