diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ad71cc6d..ba0dd985f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,15 +2,28 @@ ## [Unreleased] +### Added + +- Tooltips to main side navigation. +- Location hash for tabs in borehole detail view. +- Language dropdown in the header. + ### Changed - Renamed technical attributes `kind_id_cli` to `borehole_type_id`, `top_bedrock` to `top_bedrock_fresh` and `qt_top_bedrock` to `top_bedrock_weathered`. - Moved groundwater radio buttons in borehole form to the bottom. +- Made `startTime` and `reliability` optional for hydrogeology. +- Removed title from prompt dialog. +- Use standard prompt dialog for deleting boreholes. ### Fixed - Attribute `top_bedrock_weathered` could not be imported. - Badge with number of active filters on sidebar did not include polygon filter. +- Fixed label for water ingress menu item. +- Location precision filter caused an internal error. +- Base maps were loaded beyond their maximum zoom level. +- `layer_depth_to` was displayed in filter even though it was not selected in the filter settings. - Users can now only import or add new boreholes to workgroups where they have an editor role. ## v2.1.772 - 2024-06-27 diff --git a/src/api-legacy/v1/action.py b/src/api-legacy/v1/action.py index f225de367..393b44838 100644 --- a/src/api-legacy/v1/action.py +++ b/src/api-legacy/v1/action.py @@ -536,7 +536,7 @@ def filterBorehole(self, filter={}): 'location_precision'] not in ['', None]: params.append(int(filter['location_precision'])) where.append(""" - location_precision_id_cli = %s + qt_location_id_cli = %s """ % self.getIdx()) if 'reference_elevation_from' in keys and filter['reference_elevation_from'] not in ['', None]: diff --git a/src/api/Migrations/20240723071757_MakeReliabilityIdNullable.Designer.cs b/src/api/Migrations/20240723071757_MakeReliabilityIdNullable.Designer.cs new file mode 100644 index 000000000..be95206d2 --- /dev/null +++ b/src/api/Migrations/20240723071757_MakeReliabilityIdNullable.Designer.cs @@ -0,0 +1,3274 @@ +// +using System; +using BDMS; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NetTopologySuite.Geometries; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace BDMS.Migrations +{ + [DbContext(typeof(BdmsContext))] + [Migration("20240723071757_MakeReliabilityIdNullable")] + partial class MakeReliabilityIdNullable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("bdms") + .HasAnnotation("ProductVersion", "8.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "ltree"); + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("BDMS.Models.Backfill", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CasingId") + .HasColumnType("integer") + .HasColumnName("casing_id"); + + b.Property("CompletionId") + .HasColumnType("integer") + .HasColumnName("completion_id"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("FromDepth") + .HasColumnType("double precision") + .HasColumnName("from_depth"); + + b.Property("IsOpenBorehole") + .HasColumnType("boolean") + .HasColumnName("is_open_borehole"); + + b.Property("KindId") + .HasColumnType("integer") + .HasColumnName("kind_id"); + + b.Property("MaterialId") + .HasColumnType("integer") + .HasColumnName("material_id"); + + b.Property("Notes") + .HasColumnType("text") + .HasColumnName("notes"); + + b.Property("ToDepth") + .HasColumnType("double precision") + .HasColumnName("to_depth"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("CasingId"); + + b.HasIndex("CompletionId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("KindId"); + + b.HasIndex("MaterialId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("backfill", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Borehole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_bho"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AlternateName") + .HasColumnType("text") + .HasColumnName("alternate_name_bho"); + + b.Property("Canton") + .HasColumnType("text") + .HasColumnName("canton_bho"); + + b.Property("ChronostratigraphyId") + .HasColumnType("integer") + .HasColumnName("chronostrat_id_cli"); + + b.Property("Country") + .HasColumnType("text") + .HasColumnName("country_bho"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_bho"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("created_by_bho"); + + b.Property("ElevationPrecisionId") + .HasColumnType("integer") + .HasColumnName("qt_elevation_id_cli"); + + b.Property("ElevationZ") + .HasColumnType("double precision") + .HasColumnName("elevation_z_bho"); + + b.Property("Geometry") + .HasColumnType("geometry") + .HasColumnName("geom_bho"); + + b.Property("HasGroundwater") + .HasColumnType("boolean") + .HasColumnName("groundwater_bho"); + + b.Property("HrsId") + .HasColumnType("integer") + .HasColumnName("hrs_id_cli"); + + b.Property("IsPublic") + .HasColumnType("boolean") + .HasColumnName("public_bho"); + + b.Property("LithologyTopBedrockId") + .HasColumnType("integer") + .HasColumnName("lithology_top_bedrock_id_cli"); + + b.Property("LithostratigraphyId") + .HasColumnType("integer") + .HasColumnName("lithostrat_id_cli"); + + b.Property("LocationPrecisionId") + .HasColumnType("integer") + .HasColumnName("qt_location_id_cli"); + + b.Property("LocationX") + .HasColumnType("double precision") + .HasColumnName("location_x_bho"); + + b.Property("LocationXLV03") + .HasColumnType("double precision") + .HasColumnName("location_x_lv03_bho"); + + b.Property("LocationY") + .HasColumnType("double precision") + .HasColumnName("location_y_bho"); + + b.Property("LocationYLV03") + .HasColumnType("double precision") + .HasColumnName("location_y_lv03_bho"); + + b.Property("Locked") + .HasColumnType("timestamp with time zone") + .HasColumnName("locked_bho"); + + b.Property("LockedById") + .HasColumnType("integer") + .HasColumnName("locked_by_bho"); + + b.Property("Municipality") + .HasColumnType("text") + .HasColumnName("municipality_bho"); + + b.Property("NationalInterest") + .HasColumnType("boolean") + .HasColumnName("national_interest"); + + b.Property("OriginalName") + .HasColumnType("text") + .HasColumnName("original_name_bho"); + + b.Property("OriginalReferenceSystem") + .HasColumnType("integer") + .HasColumnName("srs_id_cli"); + + b.Property("PrecisionLocationX") + .HasColumnType("integer") + .HasColumnName("precision_location_x"); + + b.Property("PrecisionLocationXLV03") + .HasColumnType("integer") + .HasColumnName("precision_location_x_lv03"); + + b.Property("PrecisionLocationY") + .HasColumnType("integer") + .HasColumnName("precision_location_y"); + + b.Property("PrecisionLocationYLV03") + .HasColumnType("integer") + .HasColumnName("precision_location_y_lv03"); + + b.Property("ProjectName") + .HasColumnType("text") + .HasColumnName("project_name_bho"); + + b.Property("PurposeId") + .HasColumnType("integer") + .HasColumnName("purpose_id_cli"); + + b.Property("QtDepthId") + .HasColumnType("integer") + .HasColumnName("qt_depth_id_cli"); + + b.Property("QtReferenceElevationId") + .HasColumnType("integer") + .HasColumnName("qt_reference_elevation_id_cli"); + + b.Property("ReferenceElevation") + .HasColumnType("double precision") + .HasColumnName("reference_elevation_bho"); + + b.Property("ReferenceElevationTypeId") + .HasColumnType("integer") + .HasColumnName("reference_elevation_type_id_cli"); + + b.Property("Remarks") + .HasColumnType("text") + .HasColumnName("remarks_bho"); + + b.Property("RestrictionId") + .HasColumnType("integer") + .HasColumnName("restriction_id_cli"); + + b.Property("RestrictionUntil") + .HasColumnType("timestamp with time zone") + .HasColumnName("restriction_until_bho"); + + b.Property("StatusId") + .HasColumnType("integer") + .HasColumnName("status_id_cli"); + + b.Property("TopBedrockFreshMd") + .HasColumnType("double precision") + .HasColumnName("top_bedrock_fresh_md"); + + b.Property("TopBedrockWeatheredMd") + .HasColumnType("double precision") + .HasColumnName("top_bedrock_weathered_md"); + + b.Property("TotalDepth") + .HasColumnType("double precision") + .HasColumnName("total_depth_bho"); + + b.Property("TypeId") + .HasColumnType("integer") + .HasColumnName("borehole_type_id"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_bho"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updated_by_bho"); + + b.Property("WorkgroupId") + .HasColumnType("integer") + .HasColumnName("id_wgp_fk"); + + b.HasKey("Id"); + + b.HasIndex("ChronostratigraphyId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ElevationPrecisionId"); + + b.HasIndex("HrsId"); + + b.HasIndex("LithologyTopBedrockId"); + + b.HasIndex("LithostratigraphyId"); + + b.HasIndex("LocationPrecisionId"); + + b.HasIndex("LockedById"); + + b.HasIndex("PurposeId"); + + b.HasIndex("QtDepthId"); + + b.HasIndex("QtReferenceElevationId"); + + b.HasIndex("ReferenceElevationTypeId"); + + b.HasIndex("RestrictionId"); + + b.HasIndex("StatusId"); + + b.HasIndex("TypeId"); + + b.HasIndex("UpdatedById"); + + b.HasIndex("WorkgroupId"); + + b.ToTable("borehole", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.BoreholeCodelist", b => + { + b.Property("BoreholeId") + .HasColumnType("integer") + .HasColumnName("borehole_id"); + + b.Property("CodelistId") + .HasColumnType("integer") + .HasColumnName("identifier_id"); + + b.Property("Value") + .IsRequired() + .HasColumnType("text") + .HasColumnName("identifier_value"); + + b.HasKey("BoreholeId", "CodelistId"); + + b.HasIndex("CodelistId"); + + b.ToTable("borehole_identifiers_codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.BoreholeFile", b => + { + b.Property("BoreholeId") + .HasColumnType("integer") + .HasColumnName("id_bho_fk"); + + b.Property("FileId") + .HasColumnType("integer") + .HasColumnName("id_fil_fk"); + + b.Property("Attached") + .HasColumnType("timestamp with time zone") + .HasColumnName("attached_bfi"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_bfi"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("created_by_bfi"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description_bfi"); + + b.Property("Public") + .HasColumnType("boolean") + .HasColumnName("public_bfi"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update_bfi"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater_bfi"); + + b.Property("UserId") + .HasColumnType("integer") + .HasColumnName("id_usr_fk"); + + b.HasKey("BoreholeId", "FileId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("FileId"); + + b.HasIndex("UpdatedById"); + + b.HasIndex("UserId"); + + b.ToTable("borehole_files", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.BoreholeGeometryElement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BoreholeId") + .HasColumnType("integer") + .HasColumnName("borehole_id"); + + b.Property("DEVI") + .HasColumnType("double precision"); + + b.Property("HAZI") + .HasColumnType("double precision"); + + b.Property("MD") + .HasColumnType("double precision"); + + b.Property("X") + .HasColumnType("double precision"); + + b.Property("Y") + .HasColumnType("double precision"); + + b.Property("Z") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.HasIndex("BoreholeId"); + + b.ToTable("borehole_geometry", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Casing", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CompletionId") + .HasColumnType("integer") + .HasColumnName("completion_id"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("DateFinish") + .HasColumnType("date") + .HasColumnName("date_finish"); + + b.Property("DateStart") + .HasColumnType("date") + .HasColumnName("date_start"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Notes") + .HasColumnType("text") + .HasColumnName("notes"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("CompletionId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("UpdatedById"); + + b.ToTable("casing", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.CasingElement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CasingId") + .HasColumnType("integer") + .HasColumnName("casing_id"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("FromDepth") + .HasColumnType("double precision") + .HasColumnName("from_depth"); + + b.Property("InnerDiameter") + .HasColumnType("double precision") + .HasColumnName("inner_diameter"); + + b.Property("KindId") + .HasColumnType("integer") + .HasColumnName("kind_id"); + + b.Property("MaterialId") + .HasColumnType("integer") + .HasColumnName("material_id"); + + b.Property("OuterDiameter") + .HasColumnType("double precision") + .HasColumnName("outer_diameter"); + + b.Property("ToDepth") + .HasColumnType("double precision") + .HasColumnName("to_depth"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("CasingId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("KindId"); + + b.HasIndex("MaterialId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("casing_element", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.ChronostratigraphyLayer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_chr"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChronostratigraphyId") + .HasColumnType("integer") + .HasColumnName("chronostratigraphy_id"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("FromDepth") + .HasColumnType("double precision") + .HasColumnName("depth_from"); + + b.Property("StratigraphyId") + .HasColumnType("integer") + .HasColumnName("id_sty_fk"); + + b.Property("ToDepth") + .HasColumnType("double precision") + .HasColumnName("depth_to"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("ChronostratigraphyId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("StratigraphyId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("chronostratigraphy", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Codelist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_cli"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Code") + .IsRequired() + .HasColumnType("text") + .HasColumnName("code_cli"); + + b.Property("Conf") + .HasColumnType("text") + .HasColumnName("conf_cli"); + + b.Property("De") + .HasColumnType("text") + .HasColumnName("text_cli_de"); + + b.Property("En") + .IsRequired() + .HasColumnType("text") + .HasColumnName("text_cli_en"); + + b.Property("Fr") + .HasColumnType("text") + .HasColumnName("text_cli_fr"); + + b.Property("Geolcode") + .HasColumnType("integer") + .HasColumnName("geolcode"); + + b.Property("IsDefault") + .HasColumnType("boolean") + .HasColumnName("default_cli"); + + b.Property("It") + .HasColumnType("text") + .HasColumnName("text_cli_it"); + + b.Property("Order") + .HasColumnType("integer") + .HasColumnName("order_cli"); + + b.Property("Path") + .HasColumnType("ltree") + .HasColumnName("path_cli"); + + b.Property("Ro") + .HasColumnType("text") + .HasColumnName("text_cli_ro"); + + b.Property("Schema") + .HasColumnType("text") + .HasColumnName("schema_cli"); + + b.HasKey("Id"); + + b.ToTable("codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Completion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AbandonDate") + .HasColumnType("date") + .HasColumnName("abandon_date"); + + b.Property("BoreholeId") + .HasColumnType("integer") + .HasColumnName("borehole_id"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("IsPrimary") + .HasColumnType("boolean") + .HasColumnName("is_primary"); + + b.Property("KindId") + .HasColumnType("integer") + .HasColumnName("kind_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Notes") + .HasColumnType("text") + .HasColumnName("notes"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("BoreholeId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("KindId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("completion", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Config", b => + { + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name_cfg"); + + b.Property("Value") + .HasColumnType("text") + .HasColumnName("value_cfg"); + + b.HasKey("Name"); + + b.ToTable("config", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.FaciesDescription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_fac"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("DescriptionQualityId") + .HasColumnType("integer") + .HasColumnName("qt_description_id"); + + b.Property("FromDepth") + .HasColumnType("double precision") + .HasColumnName("depth_from"); + + b.Property("StratigraphyId") + .HasColumnType("integer") + .HasColumnName("id_sty_fk"); + + b.Property("ToDepth") + .HasColumnType("double precision") + .HasColumnName("depth_to"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DescriptionQualityId"); + + b.HasIndex("StratigraphyId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("facies_description", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.FieldMeasurementResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("FieldMeasurementId") + .HasColumnType("integer") + .HasColumnName("fieldmeasurement_id"); + + b.Property("ParameterId") + .HasColumnType("integer") + .HasColumnName("parameter"); + + b.Property("SampleTypeId") + .HasColumnType("integer") + .HasColumnName("sample_type"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.Property("Value") + .HasColumnType("double precision") + .HasColumnName("value"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("FieldMeasurementId"); + + b.HasIndex("ParameterId"); + + b.HasIndex("SampleTypeId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("fieldmeasurement_result", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_fil"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("uploaded_fil"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("id_usr_fk"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text") + .HasColumnName("hash_fil"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name_fil"); + + b.Property("NameUuid") + .HasColumnType("text") + .HasColumnName("name_uuid_fil"); + + b.Property("Type") + .IsRequired() + .HasColumnType("text") + .HasColumnName("type_fil"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_fil"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updated_by_fil"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("UpdatedById"); + + b.ToTable("files", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.HydrotestEvaluationMethodCode", b => + { + b.Property("HydrotestId") + .HasColumnType("integer") + .HasColumnName("hydrotest_id"); + + b.Property("CodelistId") + .HasColumnType("integer") + .HasColumnName("codelist_id"); + + b.HasKey("HydrotestId", "CodelistId"); + + b.HasIndex("CodelistId"); + + b.ToTable("hydrotest_evaluationmethod_codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.HydrotestFlowDirectionCode", b => + { + b.Property("HydrotestId") + .HasColumnType("integer") + .HasColumnName("hydrotest_id"); + + b.Property("CodelistId") + .HasColumnType("integer") + .HasColumnName("codelist_id"); + + b.HasKey("HydrotestId", "CodelistId"); + + b.HasIndex("CodelistId"); + + b.ToTable("hydrotest_flowdirection_codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.HydrotestKindCode", b => + { + b.Property("HydrotestId") + .HasColumnType("integer") + .HasColumnName("hydrotest_id"); + + b.Property("CodelistId") + .HasColumnType("integer") + .HasColumnName("codelist_id"); + + b.HasKey("HydrotestId", "CodelistId"); + + b.HasIndex("CodelistId"); + + b.ToTable("hydrotest_kind_codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.HydrotestResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("HydrotestId") + .HasColumnType("integer") + .HasColumnName("hydrotest_id"); + + b.Property("MaxValue") + .HasColumnType("double precision") + .HasColumnName("max_value"); + + b.Property("MinValue") + .HasColumnType("double precision") + .HasColumnName("min_value"); + + b.Property("ParameterId") + .HasColumnType("integer") + .HasColumnName("parameter"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.Property("Value") + .HasColumnType("double precision") + .HasColumnName("value"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("HydrotestId"); + + b.HasIndex("ParameterId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("hydrotest_result", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Instrumentation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CasingId") + .HasColumnType("integer") + .HasColumnName("casing_id"); + + b.Property("CompletionId") + .HasColumnType("integer") + .HasColumnName("completion_id"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("FromDepth") + .HasColumnType("double precision") + .HasColumnName("from_depth"); + + b.Property("IsOpenBorehole") + .HasColumnType("boolean") + .HasColumnName("is_open_borehole"); + + b.Property("KindId") + .HasColumnType("integer") + .HasColumnName("kind_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Notes") + .HasColumnType("text") + .HasColumnName("notes"); + + b.Property("StatusId") + .HasColumnType("integer") + .HasColumnName("status_id"); + + b.Property("ToDepth") + .HasColumnType("double precision") + .HasColumnName("to_depth"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("CasingId"); + + b.HasIndex("CompletionId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("KindId"); + + b.HasIndex("StatusId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("instrumentation", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Layer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_lay"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AlterationId") + .HasColumnType("integer") + .HasColumnName("alteration_id_cli"); + + b.Property("CohesionId") + .HasColumnType("integer") + .HasColumnName("cohesion_id_cli"); + + b.Property("CompactnessId") + .HasColumnType("integer") + .HasColumnName("compactness_id_cli"); + + b.Property("ConsistanceId") + .HasColumnType("integer") + .HasColumnName("consistance_id_cli"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation_lay"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator_lay"); + + b.Property("DescriptionQualityId") + .HasColumnType("integer") + .HasColumnName("qt_description_id_cli"); + + b.Property("FromDepth") + .HasColumnType("double precision") + .HasColumnName("depth_from_lay"); + + b.Property("GradationId") + .HasColumnType("integer") + .HasColumnName("gradation_id_cli"); + + b.Property("GrainSize1Id") + .HasColumnType("integer") + .HasColumnName("grain_size_1_id_cli"); + + b.Property("GrainSize2Id") + .HasColumnType("integer") + .HasColumnName("grain_size_2_id_cli"); + + b.Property("HumidityId") + .HasColumnType("integer") + .HasColumnName("humidity_id_cli"); + + b.Property("IsLast") + .HasColumnType("boolean") + .HasColumnName("last_lay"); + + b.Property("IsStriae") + .HasColumnType("boolean") + .HasColumnName("striae_lay"); + + b.Property("IsUndefined") + .HasColumnType("boolean") + .HasColumnName("undefined_lay"); + + b.Property("LithologyId") + .HasColumnType("integer") + .HasColumnName("lithology_id_cli"); + + b.Property("LithologyTopBedrockId") + .HasColumnType("integer") + .HasColumnName("lithology_top_bedrock_id_cli"); + + b.Property("LithostratigraphyId") + .HasColumnType("integer") + .HasColumnName("lithostratigraphy_id_cli"); + + b.Property("Notes") + .HasColumnType("text") + .HasColumnName("notes_lay"); + + b.Property("OriginalLithology") + .HasColumnType("text") + .HasColumnName("original_lithology"); + + b.Property("OriginalUscs") + .HasColumnType("text") + .HasColumnName("uscs_original_lay"); + + b.Property("PlasticityId") + .HasColumnType("integer") + .HasColumnName("plasticity_id_cli"); + + b.Property("StratigraphyId") + .HasColumnType("integer") + .HasColumnName("id_sty_fk"); + + b.Property("ToDepth") + .HasColumnType("double precision") + .HasColumnName("depth_to_lay"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update_lay"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater_lay"); + + b.Property("Uscs1Id") + .HasColumnType("integer") + .HasColumnName("uscs_1_id_cli"); + + b.Property("Uscs2Id") + .HasColumnType("integer") + .HasColumnName("uscs_2_id_cli"); + + b.Property("UscsDeterminationId") + .HasColumnType("integer") + .HasColumnName("uscs_determination_id_cli"); + + b.HasKey("Id"); + + b.HasIndex("AlterationId"); + + b.HasIndex("CohesionId"); + + b.HasIndex("CompactnessId"); + + b.HasIndex("ConsistanceId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DescriptionQualityId"); + + b.HasIndex("GradationId"); + + b.HasIndex("GrainSize1Id"); + + b.HasIndex("GrainSize2Id"); + + b.HasIndex("HumidityId"); + + b.HasIndex("LithologyId"); + + b.HasIndex("LithologyTopBedrockId"); + + b.HasIndex("LithostratigraphyId"); + + b.HasIndex("PlasticityId"); + + b.HasIndex("StratigraphyId"); + + b.HasIndex("UpdatedById"); + + b.HasIndex("Uscs1Id"); + + b.HasIndex("Uscs2Id"); + + b.HasIndex("UscsDeterminationId"); + + b.ToTable("layer", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.LayerColorCode", b => + { + b.Property("LayerId") + .HasColumnType("integer") + .HasColumnName("layer_id"); + + b.Property("CodelistId") + .HasColumnType("integer") + .HasColumnName("color_id"); + + b.HasKey("LayerId", "CodelistId"); + + b.HasIndex("CodelistId"); + + b.ToTable("layer_color_codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.LayerDebrisCode", b => + { + b.Property("LayerId") + .HasColumnType("integer") + .HasColumnName("layer_id"); + + b.Property("CodelistId") + .HasColumnType("integer") + .HasColumnName("debris_id"); + + b.HasKey("LayerId", "CodelistId"); + + b.HasIndex("CodelistId"); + + b.ToTable("layer_debris_codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.LayerGrainAngularityCode", b => + { + b.Property("LayerId") + .HasColumnType("integer") + .HasColumnName("layer_id"); + + b.Property("CodelistId") + .HasColumnType("integer") + .HasColumnName("grain_angularity_id"); + + b.HasKey("LayerId", "CodelistId"); + + b.HasIndex("CodelistId"); + + b.ToTable("layer_grain_angularity_codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.LayerGrainShapeCode", b => + { + b.Property("LayerId") + .HasColumnType("integer") + .HasColumnName("layer_id"); + + b.Property("CodelistId") + .HasColumnType("integer") + .HasColumnName("grain_shape_id"); + + b.HasKey("LayerId", "CodelistId"); + + b.HasIndex("CodelistId"); + + b.ToTable("layer_grain_shape_codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.LayerOrganicComponentCode", b => + { + b.Property("LayerId") + .HasColumnType("integer") + .HasColumnName("layer_id"); + + b.Property("CodelistId") + .HasColumnType("integer") + .HasColumnName("organic_components_id"); + + b.HasKey("LayerId", "CodelistId"); + + b.HasIndex("CodelistId"); + + b.ToTable("layer_organic_component_codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.LayerUscs3Code", b => + { + b.Property("LayerId") + .HasColumnType("integer") + .HasColumnName("layer_id"); + + b.Property("CodelistId") + .HasColumnType("integer") + .HasColumnName("uscs3_id"); + + b.HasKey("LayerId", "CodelistId"); + + b.HasIndex("CodelistId"); + + b.ToTable("layer_uscs3_codelist", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.LithologicalDescription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_ldp"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("DescriptionQualityId") + .HasColumnType("integer") + .HasColumnName("qt_description_id"); + + b.Property("FromDepth") + .HasColumnType("double precision") + .HasColumnName("depth_from"); + + b.Property("StratigraphyId") + .HasColumnType("integer") + .HasColumnName("id_sty_fk"); + + b.Property("ToDepth") + .HasColumnType("double precision") + .HasColumnName("depth_to"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("DescriptionQualityId"); + + b.HasIndex("StratigraphyId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("lithological_description", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.LithostratigraphyLayer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("FromDepth") + .HasColumnType("double precision") + .HasColumnName("depth_from"); + + b.Property("LithostratigraphyId") + .HasColumnType("integer") + .HasColumnName("lithostratigraphy_id"); + + b.Property("StratigraphyId") + .HasColumnType("integer") + .HasColumnName("stratigraphy_id"); + + b.Property("ToDepth") + .HasColumnType("double precision") + .HasColumnName("depth_to"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("LithostratigraphyId"); + + b.HasIndex("StratigraphyId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("lithostratigraphy", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Observation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BoreholeId") + .HasColumnType("integer") + .HasColumnName("borehole_id"); + + b.Property("CasingId") + .HasColumnType("integer") + .HasColumnName("casing_id"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("Duration") + .HasColumnType("double precision") + .HasColumnName("duration"); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("end_time"); + + b.Property("FromDepthM") + .HasColumnType("double precision") + .HasColumnName("from_depth_m"); + + b.Property("FromDepthMasl") + .HasColumnType("double precision") + .HasColumnName("from_depth_masl"); + + b.Property("IsOpenBorehole") + .HasColumnType("boolean") + .HasColumnName("is_open_borehole"); + + b.Property("ReliabilityId") + .HasColumnType("integer") + .HasColumnName("reliability"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("start_time"); + + b.Property("ToDepthM") + .HasColumnType("double precision") + .HasColumnName("to_depth_m"); + + b.Property("ToDepthMasl") + .HasColumnType("double precision") + .HasColumnName("to_depth_masl"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("observation_type"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("BoreholeId"); + + b.HasIndex("CasingId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ReliabilityId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("observation", "bdms"); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("BDMS.Models.Section", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BoreholeId") + .HasColumnType("integer") + .HasColumnName("borehole_id"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("BoreholeId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("UpdatedById"); + + b.ToTable("section", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.SectionElement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("creator"); + + b.Property("CuttingsId") + .HasColumnType("integer") + .HasColumnName("cuttings_id"); + + b.Property("DrillingCoreDiameter") + .HasColumnType("double precision") + .HasColumnName("drilling_core_diameter"); + + b.Property("DrillingDiameter") + .HasColumnType("double precision") + .HasColumnName("drilling_diameter"); + + b.Property("DrillingEndDate") + .HasColumnType("date") + .HasColumnName("drilling_end_date"); + + b.Property("DrillingMethodId") + .HasColumnType("integer") + .HasColumnName("drilling_method_id"); + + b.Property("DrillingMudSubtypeId") + .HasColumnType("integer") + .HasColumnName("mud_subtype_id"); + + b.Property("DrillingMudTypeId") + .HasColumnType("integer") + .HasColumnName("mud_type_id"); + + b.Property("DrillingStartDate") + .HasColumnType("date") + .HasColumnName("drilling_start_date"); + + b.Property("FromDepth") + .HasColumnType("double precision") + .HasColumnName("from_depth"); + + b.Property("Order") + .HasColumnType("integer") + .HasColumnName("order"); + + b.Property("SectionId") + .HasColumnType("integer") + .HasColumnName("section_id"); + + b.Property("ToDepth") + .HasColumnType("double precision") + .HasColumnName("to_depth"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("CuttingsId"); + + b.HasIndex("DrillingMethodId"); + + b.HasIndex("DrillingMudSubtypeId"); + + b.HasIndex("DrillingMudTypeId"); + + b.HasIndex("SectionId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("section_element", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Stratigraphy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_sty"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BoreholeId") + .HasColumnType("integer") + .HasColumnName("id_bho_fk"); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation_sty"); + + b.Property("CreatedById") + .HasColumnType("integer") + .HasColumnName("author_sty"); + + b.Property("Date") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_sty"); + + b.Property("IsPrimary") + .HasColumnType("boolean") + .HasColumnName("primary_sty"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name_sty"); + + b.Property("Notes") + .HasColumnType("text") + .HasColumnName("notes_sty"); + + b.Property("QualityId") + .HasColumnType("integer") + .HasColumnName("quality_id"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone") + .HasColumnName("update_sty"); + + b.Property("UpdatedById") + .HasColumnType("integer") + .HasColumnName("updater_sty"); + + b.HasKey("Id"); + + b.HasIndex("BoreholeId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("QualityId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("stratigraphy", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Term", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_tes"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Creation") + .HasColumnType("timestamp with time zone") + .HasColumnName("creation_tes"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone") + .HasColumnName("expired_tes"); + + b.Property("IsDraft") + .HasColumnType("boolean") + .HasColumnName("draft_tes"); + + b.Property("TextDe") + .HasColumnType("text") + .HasColumnName("text_tes_de"); + + b.Property("TextEn") + .IsRequired() + .HasColumnType("text") + .HasColumnName("text_tes_en"); + + b.Property("TextFr") + .HasColumnType("text") + .HasColumnName("text_tes_fr"); + + b.Property("TextIt") + .HasColumnType("text") + .HasColumnName("text_tes_it"); + + b.Property("TextRo") + .HasColumnType("text") + .HasColumnName("text_tes_ro"); + + b.HasKey("Id"); + + b.ToTable("terms", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_usr"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DisabledAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("disabled_usr"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("firstname"); + + b.Property("IsAdmin") + .HasColumnType("boolean") + .HasColumnName("admin_usr"); + + b.Property("IsViewer") + .HasColumnType("boolean") + .HasColumnName("viewer_usr"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("lastname"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("username"); + + b.Property("SubjectId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("subject_id"); + + b.HasKey("Id"); + + b.ToTable("users", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.UserEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_evs"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_evs"); + + b.Property("Payload") + .HasColumnType("jsonb") + .HasColumnName("payload_evs"); + + b.Property("Topic") + .IsRequired() + .HasColumnType("text") + .HasColumnName("topic_evs"); + + b.Property("UserId") + .HasColumnType("integer") + .HasColumnName("id_usr_fk"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("events", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.UserWorkgroupRole", b => + { + b.Property("UserId") + .HasColumnType("integer") + .HasColumnName("id_usr_fk"); + + b.Property("WorkgroupId") + .HasColumnType("integer") + .HasColumnName("id_wgp_fk"); + + b.Property("Role") + .HasColumnType("int") + .HasColumnName("id_rol_fk"); + + b.HasKey("UserId", "WorkgroupId", "Role"); + + b.ToTable("users_roles", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Workflow", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_wkf"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BoreholeId") + .HasColumnType("integer") + .HasColumnName("id_bho_fk"); + + b.Property("Finished") + .HasColumnType("timestamp with time zone") + .HasColumnName("finished_wkf"); + + b.Property("Notes") + .HasColumnType("text") + .HasColumnName("notes_wkf"); + + b.Property("Role") + .HasColumnType("integer") + .HasColumnName("id_rol_fk"); + + b.Property("Started") + .HasColumnType("timestamp with time zone") + .HasColumnName("started_wkf"); + + b.Property("UserId") + .HasColumnType("integer") + .HasColumnName("id_usr_fk"); + + b.HasKey("Id"); + + b.HasIndex("BoreholeId"); + + b.HasIndex("UserId"); + + b.ToTable("workflow", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Workgroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_wgp"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_wgp"); + + b.Property("Disabled") + .HasColumnType("timestamp with time zone") + .HasColumnName("disabled_wgp"); + + b.Property("IsSupplier") + .HasColumnType("boolean") + .HasColumnName("supplier_wgp"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name_wgp"); + + b.Property("Settings") + .HasColumnType("json") + .HasColumnName("settings_wgp"); + + b.HasKey("Id"); + + b.ToTable("workgroups", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.FieldMeasurement", b => + { + b.HasBaseType("BDMS.Models.Observation"); + + b.ToTable("field_measurement", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.GroundwaterLevelMeasurement", b => + { + b.HasBaseType("BDMS.Models.Observation"); + + b.Property("KindId") + .HasColumnType("integer") + .HasColumnName("kind"); + + b.Property("LevelM") + .HasColumnType("double precision") + .HasColumnName("level_m"); + + b.Property("LevelMasl") + .HasColumnType("double precision") + .HasColumnName("level_masl"); + + b.HasIndex("KindId"); + + b.ToTable("groundwater_level_measurement", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Hydrotest", b => + { + b.HasBaseType("BDMS.Models.Observation"); + + b.ToTable("hydrotest", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.WaterIngress", b => + { + b.HasBaseType("BDMS.Models.Observation"); + + b.Property("ConditionsId") + .HasColumnType("integer") + .HasColumnName("conditions"); + + b.Property("QuantityId") + .HasColumnType("integer") + .HasColumnName("quantity"); + + b.HasIndex("ConditionsId"); + + b.HasIndex("QuantityId"); + + b.ToTable("water_ingress", "bdms"); + }); + + modelBuilder.Entity("BDMS.Models.Backfill", b => + { + b.HasOne("BDMS.Models.Casing", "Casing") + .WithMany("Backfills") + .HasForeignKey("CasingId"); + + b.HasOne("BDMS.Models.Completion", "Completion") + .WithMany("Backfills") + .HasForeignKey("CompletionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "Kind") + .WithMany() + .HasForeignKey("KindId"); + + b.HasOne("BDMS.Models.Codelist", "Material") + .WithMany() + .HasForeignKey("MaterialId"); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("Casing"); + + b.Navigation("Completion"); + + b.Navigation("CreatedBy"); + + b.Navigation("Kind"); + + b.Navigation("Material"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.Borehole", b => + { + b.HasOne("BDMS.Models.Codelist", "Chronostratigraphy") + .WithMany() + .HasForeignKey("ChronostratigraphyId"); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "ElevationPrecision") + .WithMany() + .HasForeignKey("ElevationPrecisionId"); + + b.HasOne("BDMS.Models.Codelist", "Hrs") + .WithMany() + .HasForeignKey("HrsId"); + + b.HasOne("BDMS.Models.Codelist", "LithologyTopBedrock") + .WithMany() + .HasForeignKey("LithologyTopBedrockId"); + + b.HasOne("BDMS.Models.Codelist", "Lithostratigraphy") + .WithMany() + .HasForeignKey("LithostratigraphyId"); + + b.HasOne("BDMS.Models.Codelist", "LocationPrecision") + .WithMany() + .HasForeignKey("LocationPrecisionId"); + + b.HasOne("BDMS.Models.User", "LockedBy") + .WithMany() + .HasForeignKey("LockedById"); + + b.HasOne("BDMS.Models.Codelist", "Purpose") + .WithMany() + .HasForeignKey("PurposeId"); + + b.HasOne("BDMS.Models.Codelist", "QtDepth") + .WithMany() + .HasForeignKey("QtDepthId"); + + b.HasOne("BDMS.Models.Codelist", "QtReferenceElevation") + .WithMany() + .HasForeignKey("QtReferenceElevationId"); + + b.HasOne("BDMS.Models.Codelist", "ReferenceElevationType") + .WithMany() + .HasForeignKey("ReferenceElevationTypeId"); + + b.HasOne("BDMS.Models.Codelist", "Restriction") + .WithMany() + .HasForeignKey("RestrictionId"); + + b.HasOne("BDMS.Models.Codelist", "Status") + .WithMany() + .HasForeignKey("StatusId"); + + b.HasOne("BDMS.Models.Codelist", "Type") + .WithMany() + .HasForeignKey("TypeId"); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.HasOne("BDMS.Models.Workgroup", "Workgroup") + .WithMany("Boreholes") + .HasForeignKey("WorkgroupId"); + + b.Navigation("Chronostratigraphy"); + + b.Navigation("CreatedBy"); + + b.Navigation("ElevationPrecision"); + + b.Navigation("Hrs"); + + b.Navigation("LithologyTopBedrock"); + + b.Navigation("Lithostratigraphy"); + + b.Navigation("LocationPrecision"); + + b.Navigation("LockedBy"); + + b.Navigation("Purpose"); + + b.Navigation("QtDepth"); + + b.Navigation("QtReferenceElevation"); + + b.Navigation("ReferenceElevationType"); + + b.Navigation("Restriction"); + + b.Navigation("Status"); + + b.Navigation("Type"); + + b.Navigation("UpdatedBy"); + + b.Navigation("Workgroup"); + }); + + modelBuilder.Entity("BDMS.Models.BoreholeCodelist", b => + { + b.HasOne("BDMS.Models.Borehole", "Borehole") + .WithMany("BoreholeCodelists") + .HasForeignKey("BoreholeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Codelist", "Codelist") + .WithMany("BoreholeCodelists") + .HasForeignKey("CodelistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Borehole"); + + b.Navigation("Codelist"); + }); + + modelBuilder.Entity("BDMS.Models.BoreholeFile", b => + { + b.HasOne("BDMS.Models.Borehole", "Borehole") + .WithMany("BoreholeFiles") + .HasForeignKey("BoreholeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.File", "File") + .WithMany("BoreholeFiles") + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.HasOne("BDMS.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Borehole"); + + b.Navigation("CreatedBy"); + + b.Navigation("File"); + + b.Navigation("UpdatedBy"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BDMS.Models.BoreholeGeometryElement", b => + { + b.HasOne("BDMS.Models.Borehole", "Borehole") + .WithMany("BoreholeGeometry") + .HasForeignKey("BoreholeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Borehole"); + }); + + modelBuilder.Entity("BDMS.Models.Casing", b => + { + b.HasOne("BDMS.Models.Completion", "Completion") + .WithMany("Casings") + .HasForeignKey("CompletionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("Completion"); + + b.Navigation("CreatedBy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.CasingElement", b => + { + b.HasOne("BDMS.Models.Casing", "Casing") + .WithMany("CasingElements") + .HasForeignKey("CasingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "Kind") + .WithMany() + .HasForeignKey("KindId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("BDMS.Models.Codelist", "Material") + .WithMany() + .HasForeignKey("MaterialId"); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("Casing"); + + b.Navigation("CreatedBy"); + + b.Navigation("Kind"); + + b.Navigation("Material"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.ChronostratigraphyLayer", b => + { + b.HasOne("BDMS.Models.Codelist", "Chronostratigraphy") + .WithMany() + .HasForeignKey("ChronostratigraphyId"); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Stratigraphy", "Stratigraphy") + .WithMany("ChronostratigraphyLayers") + .HasForeignKey("StratigraphyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("Chronostratigraphy"); + + b.Navigation("CreatedBy"); + + b.Navigation("Stratigraphy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.Completion", b => + { + b.HasOne("BDMS.Models.Borehole", "Borehole") + .WithMany("Completions") + .HasForeignKey("BoreholeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "Kind") + .WithMany() + .HasForeignKey("KindId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("Borehole"); + + b.Navigation("CreatedBy"); + + b.Navigation("Kind"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.FaciesDescription", b => + { + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "DescriptionQuality") + .WithMany() + .HasForeignKey("DescriptionQualityId"); + + b.HasOne("BDMS.Models.Stratigraphy", "Stratigraphy") + .WithMany("FaciesDescriptions") + .HasForeignKey("StratigraphyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("DescriptionQuality"); + + b.Navigation("Stratigraphy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.FieldMeasurementResult", b => + { + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.FieldMeasurement", "FieldMeasurement") + .WithMany("FieldMeasurementResults") + .HasForeignKey("FieldMeasurementId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Codelist", "Parameter") + .WithMany() + .HasForeignKey("ParameterId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("BDMS.Models.Codelist", "SampleType") + .WithMany() + .HasForeignKey("SampleTypeId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("FieldMeasurement"); + + b.Navigation("Parameter"); + + b.Navigation("SampleType"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.File", b => + { + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.HydrotestEvaluationMethodCode", b => + { + b.HasOne("BDMS.Models.Codelist", "Codelist") + .WithMany("HydrotestEvaluationMethodCodes") + .HasForeignKey("CodelistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Hydrotest", "Hydrotest") + .WithMany("HydrotestEvaluationMethodCodes") + .HasForeignKey("HydrotestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Codelist"); + + b.Navigation("Hydrotest"); + }); + + modelBuilder.Entity("BDMS.Models.HydrotestFlowDirectionCode", b => + { + b.HasOne("BDMS.Models.Codelist", "Codelist") + .WithMany("HydrotestFlowDirectionCodes") + .HasForeignKey("CodelistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Hydrotest", "Hydrotest") + .WithMany("HydrotestFlowDirectionCodes") + .HasForeignKey("HydrotestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Codelist"); + + b.Navigation("Hydrotest"); + }); + + modelBuilder.Entity("BDMS.Models.HydrotestKindCode", b => + { + b.HasOne("BDMS.Models.Codelist", "Codelist") + .WithMany("HydrotestKindCodes") + .HasForeignKey("CodelistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Hydrotest", "Hydrotest") + .WithMany("HydrotestKindCodes") + .HasForeignKey("HydrotestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Codelist"); + + b.Navigation("Hydrotest"); + }); + + modelBuilder.Entity("BDMS.Models.HydrotestResult", b => + { + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Hydrotest", "Hydrotest") + .WithMany("HydrotestResults") + .HasForeignKey("HydrotestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Codelist", "Parameter") + .WithMany() + .HasForeignKey("ParameterId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Hydrotest"); + + b.Navigation("Parameter"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.Instrumentation", b => + { + b.HasOne("BDMS.Models.Casing", "Casing") + .WithMany("Instrumentations") + .HasForeignKey("CasingId"); + + b.HasOne("BDMS.Models.Completion", "Completion") + .WithMany("Instrumentations") + .HasForeignKey("CompletionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "Kind") + .WithMany() + .HasForeignKey("KindId"); + + b.HasOne("BDMS.Models.Codelist", "Status") + .WithMany() + .HasForeignKey("StatusId"); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("Casing"); + + b.Navigation("Completion"); + + b.Navigation("CreatedBy"); + + b.Navigation("Kind"); + + b.Navigation("Status"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.Layer", b => + { + b.HasOne("BDMS.Models.Codelist", "Alteration") + .WithMany() + .HasForeignKey("AlterationId"); + + b.HasOne("BDMS.Models.Codelist", "Cohesion") + .WithMany() + .HasForeignKey("CohesionId"); + + b.HasOne("BDMS.Models.Codelist", "Compactness") + .WithMany() + .HasForeignKey("CompactnessId"); + + b.HasOne("BDMS.Models.Codelist", "Consistance") + .WithMany() + .HasForeignKey("ConsistanceId"); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "DescriptionQuality") + .WithMany() + .HasForeignKey("DescriptionQualityId"); + + b.HasOne("BDMS.Models.Codelist", "Gradation") + .WithMany() + .HasForeignKey("GradationId"); + + b.HasOne("BDMS.Models.Codelist", "GrainSize1") + .WithMany() + .HasForeignKey("GrainSize1Id"); + + b.HasOne("BDMS.Models.Codelist", "GrainSize2") + .WithMany() + .HasForeignKey("GrainSize2Id"); + + b.HasOne("BDMS.Models.Codelist", "Humidity") + .WithMany() + .HasForeignKey("HumidityId"); + + b.HasOne("BDMS.Models.Codelist", "Lithology") + .WithMany() + .HasForeignKey("LithologyId"); + + b.HasOne("BDMS.Models.Codelist", "LithologyTopBedrock") + .WithMany() + .HasForeignKey("LithologyTopBedrockId"); + + b.HasOne("BDMS.Models.Codelist", "Lithostratigraphy") + .WithMany() + .HasForeignKey("LithostratigraphyId"); + + b.HasOne("BDMS.Models.Codelist", "Plasticity") + .WithMany() + .HasForeignKey("PlasticityId"); + + b.HasOne("BDMS.Models.Stratigraphy", "Stratigraphy") + .WithMany("Layers") + .HasForeignKey("StratigraphyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.HasOne("BDMS.Models.Codelist", "Uscs1") + .WithMany() + .HasForeignKey("Uscs1Id"); + + b.HasOne("BDMS.Models.Codelist", "Uscs2") + .WithMany() + .HasForeignKey("Uscs2Id"); + + b.HasOne("BDMS.Models.Codelist", "UscsDetermination") + .WithMany() + .HasForeignKey("UscsDeterminationId"); + + b.Navigation("Alteration"); + + b.Navigation("Cohesion"); + + b.Navigation("Compactness"); + + b.Navigation("Consistance"); + + b.Navigation("CreatedBy"); + + b.Navigation("DescriptionQuality"); + + b.Navigation("Gradation"); + + b.Navigation("GrainSize1"); + + b.Navigation("GrainSize2"); + + b.Navigation("Humidity"); + + b.Navigation("Lithology"); + + b.Navigation("LithologyTopBedrock"); + + b.Navigation("Lithostratigraphy"); + + b.Navigation("Plasticity"); + + b.Navigation("Stratigraphy"); + + b.Navigation("UpdatedBy"); + + b.Navigation("Uscs1"); + + b.Navigation("Uscs2"); + + b.Navigation("UscsDetermination"); + }); + + modelBuilder.Entity("BDMS.Models.LayerColorCode", b => + { + b.HasOne("BDMS.Models.Codelist", "Codelist") + .WithMany("LayerColorCodes") + .HasForeignKey("CodelistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Layer", "Layer") + .WithMany("LayerColorCodes") + .HasForeignKey("LayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Codelist"); + + b.Navigation("Layer"); + }); + + modelBuilder.Entity("BDMS.Models.LayerDebrisCode", b => + { + b.HasOne("BDMS.Models.Codelist", "Codelist") + .WithMany("LayerDebrisCodes") + .HasForeignKey("CodelistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Layer", "Layer") + .WithMany("LayerDebrisCodes") + .HasForeignKey("LayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Codelist"); + + b.Navigation("Layer"); + }); + + modelBuilder.Entity("BDMS.Models.LayerGrainAngularityCode", b => + { + b.HasOne("BDMS.Models.Codelist", "Codelist") + .WithMany("LayerGrainAngularityCodes") + .HasForeignKey("CodelistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Layer", "Layer") + .WithMany("LayerGrainAngularityCodes") + .HasForeignKey("LayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Codelist"); + + b.Navigation("Layer"); + }); + + modelBuilder.Entity("BDMS.Models.LayerGrainShapeCode", b => + { + b.HasOne("BDMS.Models.Codelist", "Codelist") + .WithMany("LayerGrainShapeCodes") + .HasForeignKey("CodelistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Layer", "Layer") + .WithMany("LayerGrainShapeCodes") + .HasForeignKey("LayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Codelist"); + + b.Navigation("Layer"); + }); + + modelBuilder.Entity("BDMS.Models.LayerOrganicComponentCode", b => + { + b.HasOne("BDMS.Models.Codelist", "Codelist") + .WithMany("LayerOrganicComponentCodes") + .HasForeignKey("CodelistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Layer", "Layer") + .WithMany("LayerOrganicComponentCodes") + .HasForeignKey("LayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Codelist"); + + b.Navigation("Layer"); + }); + + modelBuilder.Entity("BDMS.Models.LayerUscs3Code", b => + { + b.HasOne("BDMS.Models.Codelist", "Codelist") + .WithMany("LayerUscs3Codes") + .HasForeignKey("CodelistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Layer", "Layer") + .WithMany("LayerUscs3Codes") + .HasForeignKey("LayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Codelist"); + + b.Navigation("Layer"); + }); + + modelBuilder.Entity("BDMS.Models.LithologicalDescription", b => + { + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "DescriptionQuality") + .WithMany() + .HasForeignKey("DescriptionQualityId"); + + b.HasOne("BDMS.Models.Stratigraphy", "Stratigraphy") + .WithMany("LithologicalDescriptions") + .HasForeignKey("StratigraphyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("DescriptionQuality"); + + b.Navigation("Stratigraphy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.LithostratigraphyLayer", b => + { + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "Lithostratigraphy") + .WithMany() + .HasForeignKey("LithostratigraphyId"); + + b.HasOne("BDMS.Models.Stratigraphy", "Stratigraphy") + .WithMany("LithostratigraphyLayers") + .HasForeignKey("StratigraphyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Lithostratigraphy"); + + b.Navigation("Stratigraphy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.Observation", b => + { + b.HasOne("BDMS.Models.Borehole", "Borehole") + .WithMany("Observations") + .HasForeignKey("BoreholeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Casing", "Casing") + .WithMany("Observations") + .HasForeignKey("CasingId"); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "Reliability") + .WithMany() + .HasForeignKey("ReliabilityId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("Borehole"); + + b.Navigation("Casing"); + + b.Navigation("CreatedBy"); + + b.Navigation("Reliability"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.Section", b => + { + b.HasOne("BDMS.Models.Borehole", "Borehole") + .WithMany("Sections") + .HasForeignKey("BoreholeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("Borehole"); + + b.Navigation("CreatedBy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.SectionElement", b => + { + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "Cuttings") + .WithMany() + .HasForeignKey("CuttingsId"); + + b.HasOne("BDMS.Models.Codelist", "DrillingMethod") + .WithMany() + .HasForeignKey("DrillingMethodId"); + + b.HasOne("BDMS.Models.Codelist", "DrillingMudSubtype") + .WithMany() + .HasForeignKey("DrillingMudSubtypeId"); + + b.HasOne("BDMS.Models.Codelist", "DrillingMudType") + .WithMany() + .HasForeignKey("DrillingMudTypeId"); + + b.HasOne("BDMS.Models.Section", "Section") + .WithMany("SectionElements") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Cuttings"); + + b.Navigation("DrillingMethod"); + + b.Navigation("DrillingMudSubtype"); + + b.Navigation("DrillingMudType"); + + b.Navigation("Section"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.Stratigraphy", b => + { + b.HasOne("BDMS.Models.Borehole", "Borehole") + .WithMany("Stratigraphies") + .HasForeignKey("BoreholeId"); + + b.HasOne("BDMS.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("BDMS.Models.Codelist", "Quality") + .WithMany() + .HasForeignKey("QualityId"); + + b.HasOne("BDMS.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("Borehole"); + + b.Navigation("CreatedBy"); + + b.Navigation("Quality"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("BDMS.Models.UserEvent", b => + { + b.HasOne("BDMS.Models.User", "User") + .WithMany("BoringEvents") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BDMS.Models.UserWorkgroupRole", b => + { + b.HasOne("BDMS.Models.User", null) + .WithMany("WorkgroupRoles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BDMS.Models.Workflow", b => + { + b.HasOne("BDMS.Models.Borehole", "Borehole") + .WithMany("Workflows") + .HasForeignKey("BoreholeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Borehole"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BDMS.Models.FieldMeasurement", b => + { + b.HasOne("BDMS.Models.Observation", null) + .WithOne() + .HasForeignKey("BDMS.Models.FieldMeasurement", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BDMS.Models.GroundwaterLevelMeasurement", b => + { + b.HasOne("BDMS.Models.Observation", null) + .WithOne() + .HasForeignKey("BDMS.Models.GroundwaterLevelMeasurement", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Codelist", "Kind") + .WithMany() + .HasForeignKey("KindId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Kind"); + }); + + modelBuilder.Entity("BDMS.Models.Hydrotest", b => + { + b.HasOne("BDMS.Models.Observation", null) + .WithOne() + .HasForeignKey("BDMS.Models.Hydrotest", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BDMS.Models.WaterIngress", b => + { + b.HasOne("BDMS.Models.Codelist", "Conditions") + .WithMany() + .HasForeignKey("ConditionsId"); + + b.HasOne("BDMS.Models.Observation", null) + .WithOne() + .HasForeignKey("BDMS.Models.WaterIngress", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BDMS.Models.Codelist", "Quantity") + .WithMany() + .HasForeignKey("QuantityId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Conditions"); + + b.Navigation("Quantity"); + }); + + modelBuilder.Entity("BDMS.Models.Borehole", b => + { + b.Navigation("BoreholeCodelists"); + + b.Navigation("BoreholeFiles"); + + b.Navigation("BoreholeGeometry"); + + b.Navigation("Completions"); + + b.Navigation("Observations"); + + b.Navigation("Sections"); + + b.Navigation("Stratigraphies"); + + b.Navigation("Workflows"); + }); + + modelBuilder.Entity("BDMS.Models.Casing", b => + { + b.Navigation("Backfills"); + + b.Navigation("CasingElements"); + + b.Navigation("Instrumentations"); + + b.Navigation("Observations"); + }); + + modelBuilder.Entity("BDMS.Models.Codelist", b => + { + b.Navigation("BoreholeCodelists"); + + b.Navigation("HydrotestEvaluationMethodCodes"); + + b.Navigation("HydrotestFlowDirectionCodes"); + + b.Navigation("HydrotestKindCodes"); + + b.Navigation("LayerColorCodes"); + + b.Navigation("LayerDebrisCodes"); + + b.Navigation("LayerGrainAngularityCodes"); + + b.Navigation("LayerGrainShapeCodes"); + + b.Navigation("LayerOrganicComponentCodes"); + + b.Navigation("LayerUscs3Codes"); + }); + + modelBuilder.Entity("BDMS.Models.Completion", b => + { + b.Navigation("Backfills"); + + b.Navigation("Casings"); + + b.Navigation("Instrumentations"); + }); + + modelBuilder.Entity("BDMS.Models.File", b => + { + b.Navigation("BoreholeFiles"); + }); + + modelBuilder.Entity("BDMS.Models.Layer", b => + { + b.Navigation("LayerColorCodes"); + + b.Navigation("LayerDebrisCodes"); + + b.Navigation("LayerGrainAngularityCodes"); + + b.Navigation("LayerGrainShapeCodes"); + + b.Navigation("LayerOrganicComponentCodes"); + + b.Navigation("LayerUscs3Codes"); + }); + + modelBuilder.Entity("BDMS.Models.Section", b => + { + b.Navigation("SectionElements"); + }); + + modelBuilder.Entity("BDMS.Models.Stratigraphy", b => + { + b.Navigation("ChronostratigraphyLayers"); + + b.Navigation("FaciesDescriptions"); + + b.Navigation("Layers"); + + b.Navigation("LithologicalDescriptions"); + + b.Navigation("LithostratigraphyLayers"); + }); + + modelBuilder.Entity("BDMS.Models.User", b => + { + b.Navigation("BoringEvents"); + + b.Navigation("WorkgroupRoles"); + }); + + modelBuilder.Entity("BDMS.Models.Workgroup", b => + { + b.Navigation("Boreholes"); + }); + + modelBuilder.Entity("BDMS.Models.FieldMeasurement", b => + { + b.Navigation("FieldMeasurementResults"); + }); + + modelBuilder.Entity("BDMS.Models.Hydrotest", b => + { + b.Navigation("HydrotestEvaluationMethodCodes"); + + b.Navigation("HydrotestFlowDirectionCodes"); + + b.Navigation("HydrotestKindCodes"); + + b.Navigation("HydrotestResults"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/api/Migrations/20240723071757_MakeReliabilityIdNullable.cs b/src/api/Migrations/20240723071757_MakeReliabilityIdNullable.cs new file mode 100644 index 000000000..c8d0eb49d --- /dev/null +++ b/src/api/Migrations/20240723071757_MakeReliabilityIdNullable.cs @@ -0,0 +1,27 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BDMS.Migrations; + +/// +public partial class MakeReliabilityIdNullable : Migration +{ + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "reliability", + schema: "bdms", + table: "observation", + type: "integer", + nullable: true, + oldClrType: typeof(int), + oldType: "integer"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + } +} diff --git a/src/api/Migrations/BdmsContextModelSnapshot.cs b/src/api/Migrations/BdmsContextModelSnapshot.cs index f8c4e6ae3..2ea5df4d3 100644 --- a/src/api/Migrations/BdmsContextModelSnapshot.cs +++ b/src/api/Migrations/BdmsContextModelSnapshot.cs @@ -265,11 +265,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("integer") .HasColumnName("status_id_cli"); - b.Property("TopBedrockFresh") + b.Property("TopBedrockFreshMd") .HasColumnType("double precision") .HasColumnName("top_bedrock_fresh_md"); - b.Property("TopBedrockWeathered") + b.Property("TopBedrockWeatheredMd") .HasColumnType("double precision") .HasColumnName("top_bedrock_weathered_md"); @@ -1552,7 +1552,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("boolean") .HasColumnName("is_open_borehole"); - b.Property("ReliabilityId") + b.Property("ReliabilityId") .HasColumnType("integer") .HasColumnName("reliability"); @@ -2927,8 +2927,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("BDMS.Models.Codelist", "Reliability") .WithMany() .HasForeignKey("ReliabilityId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); + .OnDelete(DeleteBehavior.NoAction); b.HasOne("BDMS.Models.User", "UpdatedBy") .WithMany() diff --git a/src/api/Models/Observation.cs b/src/api/Models/Observation.cs index 43e5a90ce..07d126157 100644 --- a/src/api/Models/Observation.cs +++ b/src/api/Models/Observation.cs @@ -91,7 +91,7 @@ public class Observation : IChangeTracking, IIdentifyable /// Gets or sets the 's reliability id. /// [Column("reliability")] - public int ReliabilityId { get; set; } + public int? ReliabilityId { get; set; } /// /// Gets or sets the 's reliability. diff --git a/src/client/cypress/e2e/boreholeList.cy.js b/src/client/cypress/e2e/boreholeList.cy.js index fa3d6251c..f1f556e96 100644 --- a/src/client/cypress/e2e/boreholeList.cy.js +++ b/src/client/cypress/e2e/boreholeList.cy.js @@ -1,4 +1,4 @@ -import { loginAsAdmin, loginAsEditor } from "../e2e/helpers/testHelpers"; +import { loginAsAdmin, loginAsEditor, returnToOverview } from "./helpers/testHelpers.js"; describe("Borehole list tests", () => { it("Boreholes are displayed in correct order with admin login", () => { @@ -136,8 +136,7 @@ describe("Borehole list tests", () => { cy.wait("@edit_list"); // return to list - cy.get('[data-cy="backButton"]').click(); - cy.wait("@edit_list"); + returnToOverview(); // verify current page is still 4 cy.get("a").should("have.class", "active item").contains("4"); diff --git a/src/client/cypress/e2e/editor/attachments.cy.js b/src/client/cypress/e2e/editor/attachments.cy.js index f55c8cb8e..37ce1bb9e 100644 --- a/src/client/cypress/e2e/editor/attachments.cy.js +++ b/src/client/cypress/e2e/editor/attachments.cy.js @@ -1,4 +1,11 @@ -import { createAndEditBoreholeAsAdmin, deleteDownloadedFile, readDownloadedFile } from "../helpers/testHelpers"; +import { + createAndEditBoreholeAsAdmin, + deleteDownloadedFile, + readDownloadedFile, + returnToOverview, + startBoreholeEditing, + stopBoreholeEditing, +} from "../helpers/testHelpers"; describe("Tests for 'Attachments' edit page.", () => { it("creates, downloads and deletes attachments.", () => { @@ -6,8 +13,7 @@ describe("Tests for 'Attachments' edit page.", () => { "extended.original_name": "JUNIORSOUFFLE", }); - cy.get('[data-cy="edit-button"]').click(); - cy.wait("@edit_lock"); + startBoreholeEditing(); // navigate to attachments tab cy.get('[data-cy="attachments-menu-item"]').click(); @@ -89,10 +95,8 @@ describe("Tests for 'Attachments' edit page.", () => { cy.get("tbody").children().should("have.length", 0); // stop editing - cy.get('[data-cy="editingStop-button"]').click(); - cy.wait("@edit_unlock"); - cy.get('[data-cy="backButton"]').click(); - cy.wait(["@edit_list", "@borehole"]); + stopBoreholeEditing(); + returnToOverview(); // reset test data cy.get('[data-cy="showTableButton"]').click(); diff --git a/src/client/cypress/e2e/editor/boreholeEditorTable.cy.js b/src/client/cypress/e2e/editor/boreholeEditorTable.cy.js index 059e6375a..ed500606a 100644 --- a/src/client/cypress/e2e/editor/boreholeEditorTable.cy.js +++ b/src/client/cypress/e2e/editor/boreholeEditorTable.cy.js @@ -1,4 +1,4 @@ -import { loginAsAdmin } from "../../e2e/helpers/testHelpers"; +import { loginAsAdmin, returnToOverview } from "../helpers/testHelpers.js"; describe("Borehole editor table tests", () => { it("preserves column sorting and active page when navigating", () => { @@ -24,8 +24,7 @@ describe("Borehole editor table tests", () => { // open first borehole and return to list cy.get("tbody").children().eq(0).contains("td", "Andres Miller").click(); - cy.get('[data-cy="backButton"]').click(); - cy.wait("@edit_list"); + returnToOverview(); // verify current page is 2 cy.get("a").should("have.class", "active item").contains("2"); diff --git a/src/client/cypress/e2e/editor/boreholeform.cy.js b/src/client/cypress/e2e/editor/boreholeform.cy.js index 607a21d60..21c52f929 100644 --- a/src/client/cypress/e2e/editor/boreholeform.cy.js +++ b/src/client/cypress/e2e/editor/boreholeform.cy.js @@ -1,4 +1,4 @@ -import { newEditableBorehole } from "../helpers/testHelpers"; +import { createBorehole, loginAsAdmin, newEditableBorehole } from "../helpers/testHelpers"; describe("Test for the borehole form.", () => { it("Creates a borehole and fills dropdowns.", () => { @@ -43,4 +43,32 @@ describe("Test for the borehole form.", () => { expect(boreholeDropdownValues).to.deep.eq(["borehole", "geotechnics", "open, no completion", "2"]); }); }); + + it("switches tabs", () => { + let boreholeId; + createBorehole({ "extended.original_name": "LSENALZE" }).as("borehole_id"); + cy.get("@borehole_id").then(id => { + boreholeId = id; + loginAsAdmin(); + cy.visit(`/${id}/borehole`); + }); + cy.location().should(location => { + expect(location.pathname).to.eq(`/${boreholeId}/borehole`); + expect(location.hash).to.eq("#general"); + }); + + cy.get('[data-cy="sections-tab"]').click(); + cy.wait("@get-sections-by-boreholeId"); + cy.location().should(location => { + expect(location.pathname).to.eq(`/${boreholeId}/borehole`); + expect(location.hash).to.eq("#sections"); + }); + + cy.get('[data-cy="geometry-tab"]').click(); + cy.wait("@boreholegeometry_GET"); + cy.location().should(location => { + expect(location.pathname).to.eq(`/${boreholeId}/borehole`); + expect(location.hash).to.eq("#geometry"); + }); + }); }); diff --git a/src/client/cypress/e2e/editor/casing.cy.js b/src/client/cypress/e2e/editor/casing.cy.js index a4c5dee3f..8c7317ce7 100644 --- a/src/client/cypress/e2e/editor/casing.cy.js +++ b/src/client/cypress/e2e/editor/casing.cy.js @@ -37,7 +37,7 @@ describe("Casing crud tests", () => { it("adds, edits and deletes casings", () => { // create casing - addItem("addCasing"); + addItem("addcasing"); cy.wait("@codelist_GET"); cy.get('[data-cy="casingElements.0.delete"]').should("be.disabled"); @@ -56,7 +56,7 @@ describe("Casing crud tests", () => { setInput("casingElements.0.outerDiameter", "4"); // add casing element and verify fromDepth is set to previous toDepth - addItem("addCasingElement"); + addItem("addcasingelement"); cy.get('[name="casingElements.1.fromDepth"]').should("have.value", "10"); cy.get('[data-cy="casingElements.1.delete"]').click(); @@ -168,35 +168,35 @@ describe("Casing crud tests", () => { }); it("checks for unsaved changes when switching between cards", () => { - addItem("addCasing"); - cy.get('[data-cy="addCasing-button"]').should("be.disabled"); + addItem("addcasing"); + cy.get('[data-cy="addcasing-button"]').should("be.disabled"); cy.wait("@codelist_GET"); setInput("name", "casing 1"); setInput("casingElements.0.fromDepth", "5"); setInput("casingElements.0.toDepth", "10"); setSelect("casingElements.0.kindId", 4); saveForm(); - cy.get('[data-cy="addCasing-button"]').should("be.enabled"); + cy.get('[data-cy="addcasing-button"]').should("be.enabled"); // can switch cards without prompt if no changes were made startEditing(); setInput("notes", "Lorem."); // can cancel switching tabs without loosing data - addItem("addCasing"); - handlePrompt("Casing: Unsaved changes", "Cancel"); + addItem("addcasing"); + handlePrompt("Casing: You have unsaved changes. How would you like to proceed?", "Cancel"); evaluateTextarea("notes", "Lorem."); // can reset creating - addItem("addCasing"); - handlePrompt("Casing: Unsaved changes", "Reset"); + addItem("addcasing"); + handlePrompt("Casing: You have unsaved changes. How would you like to proceed?", "Reset"); evaluateDisplayValue("notes", "-"); // can save changes in existing card and switch to new card startEditing(); setInput("notes", "Lorem."); - addItem("addCasing"); - handlePrompt("Casing: Unsaved changes", "Save"); + addItem("addcasing"); + handlePrompt("Casing: You have unsaved changes. How would you like to proceed?", "Save"); evaluateDisplayValue("notes", "Lorem."); // can reset creating and switch to existing card @@ -205,18 +205,18 @@ describe("Casing crud tests", () => { setInput("casingElements.0.toDepth", "5"); setSelect("casingElements.0.kindId", 4); startEditing(); - handlePrompt("Casing: Unsaved changes", "Reset"); + handlePrompt("Casing: You have unsaved changes. How would you like to proceed?", "Reset"); cy.get('[data-cy="casing-card.0.edit"]').should("be.visible"); cy.get('[data-cy="casing-card.1"]').should("not.exist"); // can save new card and switch to existing card - addItem("addCasing"); + addItem("addcasing"); setInput("name", "casing 2"); setInput("casingElements.0.fromDepth", "0"); setInput("casingElements.0.toDepth", "5"); setSelect("casingElements.0.kindId", 4); startEditing(); - handlePrompt("Casing: Unsaved changes", "Save"); + handlePrompt("Casing: You have unsaved changes. How would you like to proceed?", "Save"); cy.get('[data-cy="casing-card.0.edit"]').should("exist"); cy.get('[data-cy="casing-card.1"]').should("exist"); }); diff --git a/src/client/cypress/e2e/editor/chronostratigraphy.cy.js b/src/client/cypress/e2e/editor/chronostratigraphy.cy.js index d66a873ab..2f9be1de2 100644 --- a/src/client/cypress/e2e/editor/chronostratigraphy.cy.js +++ b/src/client/cypress/e2e/editor/chronostratigraphy.cy.js @@ -1,4 +1,10 @@ -import { bearerAuth, createBorehole, createStratigraphy, loginAsAdmin } from "../helpers/testHelpers"; +import { + bearerAuth, + createBorehole, + createStratigraphy, + loginAsAdmin, + startBoreholeEditing, +} from "../helpers/testHelpers"; describe("Tests for the chronostratigraphy editor.", () => { beforeEach(function () { @@ -75,8 +81,7 @@ describe("Tests for the chronostratigraphy editor.", () => { cy.wait("@get-layers-by-profileId"); // start editing session - cy.get('[data-cy="edit-button"]').click(); - cy.wait("@edit_lock"); + startBoreholeEditing(); cy.wait("@chronostratigraphy_GET"); }); diff --git a/src/client/cypress/e2e/editor/completion.cy.js b/src/client/cypress/e2e/editor/completion.cy.js index 65e086d1c..3b3d2b8a4 100644 --- a/src/client/cypress/e2e/editor/completion.cy.js +++ b/src/client/cypress/e2e/editor/completion.cy.js @@ -95,16 +95,16 @@ describe("completion crud tests", () => { // add completion addCompletion(); - cy.get('[data-cy="addCompletion-button"]').should("be.disabled"); + cy.get('[data-cy="addcompletion-button"]').should("be.disabled"); cy.contains("Not specified"); cy.get('[data-cy="save-button"]').should("be.disabled"); cy.get('[data-cy="cancel-button"]').should("be.enabled"); cancelEditing(); - cy.get('[data-cy="addCompletion-button"]').should("be.enabled"); + cy.get('[data-cy="addcompletion-button"]').should("be.enabled"); cy.get('[data-cy="completion-header-tab-0"]').should("not.exist"); addCompletion(); - cy.get('[data-cy="addCompletion-button"]').should("be.disabled"); + cy.get('[data-cy="addcompletion-button"]').should("be.disabled"); setInput("name", "Compl-1"); setSelect("kindId", 2); @@ -114,7 +114,7 @@ describe("completion crud tests", () => { setInput("notes", "Lorem."); saveChanges(); cy.contains("Compl-1"); - cy.get('[data-cy="addCompletion-button"]').should("be.enabled"); + cy.get('[data-cy="addcompletion-button"]').should("be.enabled"); // copy completion copyCompletion(); @@ -227,7 +227,7 @@ describe("completion crud tests", () => { startEditHeader(); setInput("name", "Compl-1 updated"); setHeaderTab(1); - handlePrompt("Completion: Unsaved changes", "Cancel"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Cancel"); isHeaderTabSelected(0); cy.location().should(location => { expect(location.pathname).to.eq(`/${boreholeId}/completion/${completion1Id}`); @@ -237,7 +237,7 @@ describe("completion crud tests", () => { // existing editing to other existing: changes can be reverted in prompt setHeaderTab(1); - handlePrompt("Completion: Unsaved changes", "Reset"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Reset"); isHeaderTabSelected(1); cy.contains("Compl-1"); cy.location().should(location => { @@ -249,7 +249,7 @@ describe("completion crud tests", () => { startEditHeader(); setInput("name", "Compl-2 updated"); setHeaderTab(0); - handlePrompt("Completion: Unsaved changes", "Save"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Save"); cy.wait("@get-completions-by-boreholeId"); isHeaderTabSelected(0); cy.contains("Compl-2 updated"); @@ -276,13 +276,13 @@ describe("completion crud tests", () => { }); setInput("name", "new completion"); setHeaderTab(0); - cy.get('[data-cy="prompt-button-Save"]').should("be.disabled"); - handlePrompt("Completion: Unsaved changes", "Cancel"); + cy.get('[data-cy="prompt"]').find('[data-cy="save-button"]').should("be.disabled"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Cancel"); // new to existing: changes can be reverted in prompt setSelect("kindId", 1); setHeaderTab(0); - handlePrompt("Completion: Unsaved changes", "Reset"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Reset"); cy.wait("@casing_GET"); cy.location().should(location => { expect(location.pathname).to.eq(`/${boreholeId}/completion/${completion1Id}`); @@ -299,7 +299,7 @@ describe("completion crud tests", () => { setInput("name", "new completion"); setSelect("kindId", 1); setHeaderTab(0); - handlePrompt("Completion: Unsaved changes", "Save"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Save"); cy.wait("@casing_GET"); cy.location().should(location => { expect(location.pathname).to.eq(`/${boreholeId}/completion/${completion1Id}`); @@ -343,7 +343,7 @@ describe("completion crud tests", () => { startEditHeader(); setInput("name", "Reset compl-1"); addCompletion(); - handlePrompt("Completion: Unsaved changes", "Reset"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Reset"); cy.location().should(location => { expect(location.pathname).to.eq(`/${boreholeId}/completion/new`); expect(location.hash).to.eq(""); @@ -359,7 +359,7 @@ describe("completion crud tests", () => { startEditHeader(); setInput("name", "Reset compl-1"); addCompletion(); - handlePrompt("Completion: Unsaved changes", "Save"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Save"); cy.location().should(location => { expect(location.pathname).to.eq(`/${boreholeId}/completion/new`); expect(location.hash).to.eq(""); @@ -409,19 +409,19 @@ describe("completion crud tests", () => { // cancel switching content tabs cy.wait(1000); - addItem("addCasing"); + addItem("addcasing"); cy.wait("@codelist_GET"); setInput("name", "casing 1", "casing-card.0.edit"); setInput("casingElements.0.fromDepth", "0"); setInput("casingElements.0.toDepth", "10"); setSelect("casingElements.0.kindId", 2); setContentTab("instrumentation"); - handlePrompt("Casing: Unsaved changes", "Cancel"); + handlePrompt("Casing: You have unsaved changes. How would you like to proceed?", "Cancel"); isContentTabSelected("casing"); // reset when switching content tabs setContentTab("instrumentation"); - handlePrompt("Casing: Unsaved changes", "Reset"); + handlePrompt("Casing: You have unsaved changes. How would you like to proceed?", "Reset"); isContentTabSelected("instrumentation"); setContentTab("casing"); cy.wait("@casing_GET"); @@ -429,14 +429,14 @@ describe("completion crud tests", () => { // save when switching content tabs cy.wait(1000); - addItem("addCasing"); + addItem("addcasing"); cy.wait("@codelist_GET"); setInput("name", "casing 1", "casing-card.0.edit"); setInput("casingElements.0.fromDepth", "0"); setInput("casingElements.0.toDepth", "10"); setSelect("casingElements.0.kindId", 2); setContentTab("backfill"); - handlePrompt("Casing: Unsaved changes", "Save"); + handlePrompt("Casing: You have unsaved changes. How would you like to proceed?", "Save"); isContentTabSelected("backfill"); setContentTab("casing"); cy.contains("casing 1").should("be.visible"); @@ -453,13 +453,13 @@ describe("completion crud tests", () => { setSelect("materialId", 1); addCompletion(); - handlePrompt("Sealing/Backfilling: Unsaved changes", "Cancel"); + handlePrompt("Sealing/Backfilling: You have unsaved changes. How would you like to proceed?", "Cancel"); isHeaderTabSelected(0); isContentTabSelected("backfill"); // reset content changes when switching header tabs addCompletion(); - handlePrompt("Sealing/Backfilling: Unsaved changes", "Reset"); + handlePrompt("Sealing/Backfilling: You have unsaved changes. How would you like to proceed?", "Reset"); isHeaderTabSelected(1); cancelEditing(); setContentTab("backfill"); @@ -475,7 +475,7 @@ describe("completion crud tests", () => { setSelect("kindId", 1); setSelect("materialId", 1); addCompletion(); - handlePrompt("Sealing/Backfilling: Unsaved changes", "Save"); + handlePrompt("Sealing/Backfilling: You have unsaved changes. How would you like to proceed?", "Save"); isHeaderTabSelected(1); cancelEditing(); setContentTab("backfill"); @@ -497,7 +497,7 @@ describe("completion crud tests", () => { startEditHeader(); setInput("name", "Compl-1 updated", "completion-header"); addCompletion(); - handlePrompt("Completion: Unsaved changes", "Cancel"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Cancel"); cy.get('[data-cy="prompt"]').should("not.exist"); isHeaderTabSelected(0); isContentTabSelected("instrumentation"); @@ -507,9 +507,9 @@ describe("completion crud tests", () => { // reset header changes, cancel content changes addCompletion(); - handlePrompt("Completion: Unsaved changes", "Reset"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Reset"); cy.wait(1000); - handlePrompt("Instrumentation: Unsaved changes", "Cancel"); + handlePrompt("Instrumentation: You have unsaved changes. How would you like to proceed?", "Cancel"); isHeaderTabSelected(0); isContentTabSelected("instrumentation"); evaluateInput("fromDepth", "0"); @@ -520,9 +520,9 @@ describe("completion crud tests", () => { startEditHeader(); setInput("name", "Compl-1 updated", "completion-header"); addCompletion(); - handlePrompt("Completion: Unsaved changes", "Reset"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Reset"); cy.wait(1000); - handlePrompt("Instrumentation: Unsaved changes", "Reset"); + handlePrompt("Instrumentation: You have unsaved changes. How would you like to proceed?", "Reset"); isHeaderTabSelected(1); setHeaderTab(0); evaluateDisplayValue("name", "Compl-1", "completion-header"); @@ -542,9 +542,9 @@ describe("completion crud tests", () => { startEditHeader(); setInput("name", "Compl-1 updated", "completion-header"); addCompletion(); - handlePrompt("Completion: Unsaved changes", "Reset"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Reset"); cy.wait(1000); - handlePrompt("Instrumentation: Unsaved changes", "Save"); + handlePrompt("Instrumentation: You have unsaved changes. How would you like to proceed?", "Save"); isHeaderTabSelected(1); setHeaderTab(0); evaluateDisplayValue("name", "Compl-1", "completion-header"); @@ -558,9 +558,9 @@ describe("completion crud tests", () => { startEditHeader(); setInput("name", "Compl-1 updated", "completion-header"); addCompletion(); - handlePrompt("Completion: Unsaved changes", "Save"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Save"); cy.wait(1000); - handlePrompt("Instrumentation: Unsaved changes", "Cancel"); + handlePrompt("Instrumentation: You have unsaved changes. How would you like to proceed?", "Cancel"); isHeaderTabSelected(0); isContentTabSelected("instrumentation"); evaluateTextarea("notes", "Lorem."); @@ -570,9 +570,9 @@ describe("completion crud tests", () => { startEditHeader(); setInput("name", "Compl-1 updated again", "completion-header"); addCompletion(); - handlePrompt("Completion: Unsaved changes", "Save"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Save"); cy.wait(1000); - handlePrompt("Instrumentation: Unsaved changes", "Reset"); + handlePrompt("Instrumentation: You have unsaved changes. How would you like to proceed?", "Reset"); isHeaderTabSelected(1); setHeaderTab(0); evaluateDisplayValue("name", "Compl-1 updated again", "completion-header"); @@ -588,9 +588,9 @@ describe("completion crud tests", () => { startEditHeader(); setInput("name", "Compl-1 updated again and again", "completion-header"); addCompletion(); - handlePrompt("Completion: Unsaved changes", "Save"); + handlePrompt("Completion: You have unsaved changes. How would you like to proceed?", "Save"); cy.wait(1000); - handlePrompt("Instrumentation: Unsaved changes", "Save"); + handlePrompt("Instrumentation: You have unsaved changes. How would you like to proceed?", "Save"); isHeaderTabSelected(1); setHeaderTab(0); evaluateDisplayValue("name", "Compl-1 updated again and again", "completion-header"); diff --git a/src/client/cypress/e2e/editor/copyBorehole.cy.js b/src/client/cypress/e2e/editor/copyBorehole.cy.js index 24ad4c039..2bdbcc676 100644 --- a/src/client/cypress/e2e/editor/copyBorehole.cy.js +++ b/src/client/cypress/e2e/editor/copyBorehole.cy.js @@ -1,4 +1,4 @@ -import { createBorehole, loginAsAdmin } from "../helpers/testHelpers"; +import { createBorehole, handlePrompt, loginAsAdmin, startBoreholeEditing } from "../helpers/testHelpers"; describe("Test copying of boreholes", () => { it("copies a borehole", () => { @@ -16,10 +16,9 @@ describe("Test copying of boreholes", () => { cy.contains("label", "Original name").next().children("input").should("contain.value", " (Copy)"); - cy.get('[data-cy="edit-button"]').click(); - cy.wait("@edit_lock"); + startBoreholeEditing(); - cy.get('[data-cy="deleteBorehole-button"]').click(); - cy.get('[class="ui negative button"]').click(); + cy.get('[data-cy="deleteborehole-button"]').click(); + handlePrompt("Do you really want to delete this borehole? This cannot be undone.", "Delete"); }); }); diff --git a/src/client/cypress/e2e/editor/dataCards.cy.js b/src/client/cypress/e2e/editor/dataCards.cy.js index 60062d02f..69f232517 100644 --- a/src/client/cypress/e2e/editor/dataCards.cy.js +++ b/src/client/cypress/e2e/editor/dataCards.cy.js @@ -1,6 +1,6 @@ import { createBorehole, handlePrompt, loginAsAdmin, startBoreholeEditing } from "../helpers/testHelpers"; import { evaluateDisplayValue, evaluateTextarea, setInput, setSelect } from "../helpers/formHelpers"; -import { addItem, saveForm, startEditing } from "../helpers/buttonHelpers"; +import { addItem, saveForm, startEditing, stopEditing } from "../helpers/buttonHelpers"; describe("Tests for the data cards in the editor.", () => { it("resets datacards when stop editing", () => { @@ -12,14 +12,14 @@ describe("Tests for the data cards in the editor.", () => { startBoreholeEditing(); cy.wait(500); - addItem("addWaterIngress"); + addItem("addwateringress"); cy.get('[data-cy="waterIngress-card.0.edit"]').should("exist"); - cy.get('[data-cy="editingStop-button"]').click(); + stopEditing(); cy.get('[data-cy="waterIngress-card.0.edit"]').should("not.exist"); startBoreholeEditing(); cy.wait(500); - addItem("addWaterIngress"); + addItem("addwateringress"); cy.wait("@casing_GET"); setInput("startTime", "2012-11-14T12:06"); setSelect("reliabilityId", 2); @@ -28,7 +28,7 @@ describe("Tests for the data cards in the editor.", () => { cy.wait("@wateringress_GET"); startEditing(); setInput("comment", "Lorem."); - cy.get('[data-cy="editingStop-button"]').click(); + stopEditing(); evaluateDisplayValue("comment", "-"); }); @@ -40,50 +40,50 @@ describe("Tests for the data cards in the editor.", () => { }); startBoreholeEditing(); - addItem("addWaterIngress"); - cy.get('[data-cy="addWaterIngress-button"]').should("be.disabled"); + addItem("addwateringress"); + cy.get('[data-cy="addwateringress-button"]').should("be.disabled"); cy.wait("@casing_GET"); setInput("startTime", "2012-11-14T12:06"); setSelect("reliabilityId", 2); setSelect("quantityId", 3); saveForm(); - cy.get('[data-cy="addWaterIngress-button"]').should("be.enabled"); + cy.get('[data-cy="addwateringress-button"]').should("be.enabled"); startEditing(); setInput("comment", "Lorem."); // can cancel switching tabs without loosing data - addItem("addWaterIngress"); - handlePrompt("Water ingress: Unsaved changes", "Cancel"); + addItem("addwateringress"); + handlePrompt("Water ingress: You have unsaved changes. How would you like to proceed?", "Cancel"); evaluateTextarea("comment", "Lorem."); // can reset creating - addItem("addWaterIngress"); - handlePrompt("Water ingress: Unsaved changes", "Reset"); + addItem("addwateringress"); + handlePrompt("Water ingress: You have unsaved changes. How would you like to proceed?", "Reset"); evaluateDisplayValue("comment", "-"); // can save changes in existing card and switch to new card startEditing(); setInput("comment", "Lorem."); - addItem("addWaterIngress"); - handlePrompt("Water ingress: Unsaved changes", "Save"); + addItem("addwateringress"); + handlePrompt("Water ingress: You have unsaved changes. How would you like to proceed?", "Save"); evaluateDisplayValue("comment", "Lorem."); // can reset creating and switch to existing card setInput("startTime", "2012-11-14T12:06"); setSelect("reliabilityId", 2); startEditing(); - handlePrompt("Water ingress: Unsaved changes", "Reset"); + handlePrompt("Water ingress: You have unsaved changes. How would you like to proceed?", "Reset"); cy.get('[data-cy="waterIngress-card.0.edit"]').should("exist"); cy.get('[data-cy="waterIngress-card.1"]').should("not.exist"); // can save new card and switch to existing card - addItem("addWaterIngress"); + addItem("addwateringress"); setInput("startTime", "2013-10-02T14:06"); setSelect("reliabilityId", 3); setSelect("quantityId", 3); startEditing(); - handlePrompt("Water ingress: Unsaved changes", "Save"); + handlePrompt("Water ingress: You have unsaved changes. How would you like to proceed?", "Save"); cy.get('[data-cy="waterIngress-card.0.edit"]').should("exist"); cy.get('[data-cy="waterIngress-card.1"]').should("exist"); }); diff --git a/src/client/cypress/e2e/editor/emptyMessages.cy.js b/src/client/cypress/e2e/editor/emptyMessages.cy.js index cc5eda347..9331f4627 100644 --- a/src/client/cypress/e2e/editor/emptyMessages.cy.js +++ b/src/client/cypress/e2e/editor/emptyMessages.cy.js @@ -1,4 +1,4 @@ -import { newUneditableBorehole } from "../helpers/testHelpers"; +import { newUneditableBorehole, startBoreholeEditing } from "../helpers/testHelpers"; describe("Messages for empty profiles", () => { beforeEach(() => { @@ -9,8 +9,7 @@ describe("Messages for empty profiles", () => { cy.get('[data-cy="stratigraphy-menu-item"]').click(); cy.get('[data-cy="lithology-menu-item"]').click(); cy.get('[data-cy="stratigraphy-message"]').should("contain", "No stratigraphy available"); - cy.get('[data-cy="edit-button"]').click(); - cy.wait("@edit_lock"); + startBoreholeEditing(); cy.get('[data-cy="stratigraphy-message"]').should( "contain", "For the recording of a stratigraphic profile please click the plus symbol at the top left", diff --git a/src/client/cypress/e2e/editor/fieldMeasurement.cy.js b/src/client/cypress/e2e/editor/fieldMeasurement.cy.js index 077a39a87..d908ab1d9 100644 --- a/src/client/cypress/e2e/editor/fieldMeasurement.cy.js +++ b/src/client/cypress/e2e/editor/fieldMeasurement.cy.js @@ -5,6 +5,7 @@ import { createFieldMeasurement, handlePrompt, loginAsAdmin, + selectLanguage, startBoreholeEditing, } from "../helpers/testHelpers"; import { evaluateDisplayValue, setInput, setSelect } from "../helpers/formHelpers"; @@ -31,9 +32,7 @@ describe("Tests for the field measurement editor.", () => { cy.visit(`/${id}/hydrogeology/fieldmeasurement`); startBoreholeEditing(); - // switch to german - cy.contains("span", "DE").click({ force: true }); - cy.wait(1000); + selectLanguage("de"); // create field measurement addItem("addFieldMeasurement"); diff --git a/src/client/cypress/e2e/editor/geometry.cy.js b/src/client/cypress/e2e/editor/geometry.cy.js index 5853c1a58..a614af804 100644 --- a/src/client/cypress/e2e/editor/geometry.cy.js +++ b/src/client/cypress/e2e/editor/geometry.cy.js @@ -8,18 +8,15 @@ describe("Geometry crud tests", () => { // open section editor cy.get("@borehole_id").then(id => { loginAsAdmin(); - cy.visit(`/${id}/borehole`); + cy.visit(`/${id}/borehole#geometry`); }); // start editing session startBoreholeEditing(); - - cy.get('[data-cy="geometry-tab"]').click(); - cy.wait("@boreholegeometry_GET"); }); it("adds and deletes borehole geometry", () => { - cy.get('[data-cy="boreholeGeometryImport-button"]').should("be.disabled"); + cy.get('[data-cy="boreholegeometryimport-button"]').should("be.disabled"); // Select geometry csv file let geometryFile = new DataTransfer(); @@ -36,18 +33,18 @@ describe("Geometry crud tests", () => { }); }); - cy.get('[data-cy="boreholeGeometryImport-button"]').should("be.enabled"); + cy.get('[data-cy="boreholegeometryimport-button"]').should("be.enabled"); // the selected format is wrong expect an alert setSelect("geometryFormat", 1); - cy.get('[data-cy="boreholeGeometryImport-button"]').click(); + cy.get('[data-cy="boreholegeometryimport-button"]').click(); cy.wait("@boreholegeometry_POST"); cy.get(".MuiAlert-message").contains("Header with name 'X_m'[0] was not found."); cy.get(".MuiAlert-action > .MuiButtonBase-root").click(); // correct format for selected CSV setSelect("geometryFormat", 2); - cy.get('[data-cy="boreholeGeometryImport-button"]').click(); + cy.get('[data-cy="boreholegeometryimport-button"]').click(); cy.wait("@boreholegeometry_POST"); cy.wait("@boreholegeometry_GET"); cy.get(".MuiTableBody-root").should("exist"); diff --git a/src/client/cypress/e2e/editor/groundwaterLevelMeasurement.cy.js b/src/client/cypress/e2e/editor/groundwaterLevelMeasurement.cy.js index 425d83b9a..1f2658596 100644 --- a/src/client/cypress/e2e/editor/groundwaterLevelMeasurement.cy.js +++ b/src/client/cypress/e2e/editor/groundwaterLevelMeasurement.cy.js @@ -5,6 +5,7 @@ import { createGroundwaterLevelMeasurement, handlePrompt, loginAsAdmin, + selectLanguage, startBoreholeEditing, } from "../helpers/testHelpers"; import { evaluateDisplayValue, setInput, setSelect } from "../helpers/formHelpers"; @@ -36,18 +37,14 @@ describe("Tests for the groundwater level measurement editor.", () => { force: true, }); - // switch to german - cy.contains("span", "DE").click({ force: true }); - cy.wait(1000); + selectLanguage("de"); // create groundwater level measurement addItem("addGroundwaterLevelMeasurement"); cy.wait("@casing_GET"); setSelect("kindId", 3); - setSelect("reliabilityId", 2); setSelect("casingId", 2); - setInput("startTime", "2012-11-14T12:06"); setInput("levelM", "789.12"); setInput("levelMasl", "5.4567"); @@ -57,7 +54,6 @@ describe("Tests for the groundwater level measurement editor.", () => { evaluateDisplayValue("gwlm_kind", "Manometer"); evaluateDisplayValue("gwlm_levelm", "789.12"); evaluateDisplayValue("gwlm_levelmasl", "5.4567"); - evaluateDisplayValue("reliability", "fraglich"); // edit groundwater level measurement startEditing(); diff --git a/src/client/cypress/e2e/editor/hydrotest.cy.js b/src/client/cypress/e2e/editor/hydrotest.cy.js index adfa63490..51c9e8e77 100644 --- a/src/client/cypress/e2e/editor/hydrotest.cy.js +++ b/src/client/cypress/e2e/editor/hydrotest.cy.js @@ -5,6 +5,7 @@ import { createHydrotest, handlePrompt, loginAsAdmin, + selectLanguage, startBoreholeEditing, } from "../helpers/testHelpers"; import { @@ -41,9 +42,7 @@ describe("Tests for the hydrotest editor.", () => { cy.get('[data-cy="hydrogeology-menu-item"]').click({ force: true }); cy.get('[data-cy="hydrotest-menu-item"]').click({ force: true }); - // switch to german - cy.contains("span", "DE").click({ force: true }); - cy.wait(1000); + selectLanguage("de"); // create hydrotest addItem("addHydrotest"); @@ -149,39 +148,39 @@ describe("Tests for the hydrotest editor.", () => { startBoreholeEditing(); addItem("addHydrotest"); - cy.get('[data-cy="addHydrotest-button"]').should("be.disabled"); + cy.get('[data-cy="addhydrotest-button"]').should("be.disabled"); cy.wait("@casing_GET"); setInput("startTime", "2012-11-14T12:06"); setSelect("reliabilityId", 2); toggleMultiSelect("testKindId", [3]); saveForm(); - cy.get('[data-cy="addHydrotest-button"]').should("be.enabled"); + cy.get('[data-cy="addhydrotest-button"]').should("be.enabled"); startEditing(); setInput("comment", "Lorem."); // can cancel switching tabs without loosing data addItem("addHydrotest"); - handlePrompt("Hydrotest: Unsaved changes", "Cancel"); + handlePrompt("Hydrotest: You have unsaved changes. How would you like to proceed?", "Cancel"); evaluateTextarea("comment", "Lorem."); // can reset creating addItem("addHydrotest"); - handlePrompt("Hydrotest: Unsaved changes", "Reset"); + handlePrompt("Hydrotest: You have unsaved changes. How would you like to proceed?", "Reset"); evaluateDisplayValue("comment", "-"); // can save changes in existing card and switch to new card startEditing(); setInput("comment", "Lorem."); addItem("addHydrotest"); - handlePrompt("Hydrotest: Unsaved changes", "Save"); + handlePrompt("Hydrotest: You have unsaved changes. How would you like to proceed?", "Save"); evaluateDisplayValue("comment", "Lorem."); // can reset creating and switch to existing card setInput("startTime", "2012-11-14T12:06"); setSelect("reliabilityId", 2); startEditing(); - handlePrompt("Hydrotest: Unsaved changes", "Reset"); + handlePrompt("Hydrotest: You have unsaved changes. How would you like to proceed?", "Reset"); cy.get('[data-cy="hydrotest-card.0.edit"]').should("be.visible"); cy.get('[data-cy="hydrotest-card.1"]').should("not.exist"); @@ -191,7 +190,7 @@ describe("Tests for the hydrotest editor.", () => { setSelect("reliabilityId", 2); toggleMultiSelect("testKindId", [4]); startEditing(); - handlePrompt("Hydrotest: Unsaved changes", "Save"); + handlePrompt("Hydrotest: You have unsaved changes. How would you like to proceed?", "Save"); cy.get('[data-cy="hydrotest-card.0.edit"]').should("exist"); cy.get('[data-cy="hydrotest-card.1"]').should("exist"); }); diff --git a/src/client/cypress/e2e/editor/instrumentation.cy.js b/src/client/cypress/e2e/editor/instrumentation.cy.js index 1821824f4..d4db76c0d 100644 --- a/src/client/cypress/e2e/editor/instrumentation.cy.js +++ b/src/client/cypress/e2e/editor/instrumentation.cy.js @@ -108,9 +108,7 @@ describe("Instrumentation crud tests", () => { cy.get('[data-cy="instrumentation-card.0"] [data-cy="name-formDisplay"]').contains("Inst-1"); cy.get('[data-cy="instrumentation-card.1"] [data-cy="name-formDisplay"]').contains("Inst-2"); - cy.get('[data-cy="instrumentation-card.1"] [data-cy="edit-button"]').click({ - force: true, - }); + startEditing("instrumentation-card.1"); setInput("toDepth", "8"); saveForm(); cy.wait("@instrumentation_GET"); diff --git a/src/client/cypress/e2e/editor/layerform.cy.js b/src/client/cypress/e2e/editor/layerform.cy.js index b76e707ee..1dd2be8f2 100644 --- a/src/client/cypress/e2e/editor/layerform.cy.js +++ b/src/client/cypress/e2e/editor/layerform.cy.js @@ -1,4 +1,4 @@ -import { newEditableBorehole } from "../helpers/testHelpers"; +import { newEditableBorehole, returnToOverview, stopBoreholeEditing } from "../helpers/testHelpers"; describe("Tests for the layer form.", () => { it("Creates a layer and fills all dropdowns with multiple selection.", () => { @@ -75,9 +75,7 @@ describe("Tests for the layer form.", () => { cy.get('[data-cy="styled-layer-0"] [data-testid="ClearIcon"]').click(); // stop editing - cy.get('[data-cy="editingStop-button"]').click(); - cy.wait("@edit_unlock"); - cy.get('[data-cy="backButton"]').click(); - cy.wait(["@edit_list", "@borehole"]); + stopBoreholeEditing(); + returnToOverview(); }); }); diff --git a/src/client/cypress/e2e/editor/lithologicalDescription.cy.js b/src/client/cypress/e2e/editor/lithologicalDescription.cy.js index 9580f6314..e56cc2f99 100644 --- a/src/client/cypress/e2e/editor/lithologicalDescription.cy.js +++ b/src/client/cypress/e2e/editor/lithologicalDescription.cy.js @@ -1,4 +1,4 @@ -import { newEditableBorehole } from "../helpers/testHelpers"; +import { newEditableBorehole, returnToOverview, stopBoreholeEditing } from "../helpers/testHelpers"; import { deleteItem } from "../helpers/buttonHelpers"; describe("Tests for the lithological description column.", () => { @@ -44,7 +44,7 @@ describe("Tests for the lithological description column.", () => { cy.get('[data-cy="styled-layer-2"] [data-testid="ClearIcon"]').click(); // workaround because close button of profile attributes is sometimes not clickable - cy.get('[data-cy="borehole-menu-item"]').click(); + cy.get('[data-cy="location-menu-item"]').click(); cy.get('[data-cy="stratigraphy-menu-item"]').click(); cy.get('[data-cy="lithology-menu-item"]').click(); @@ -130,9 +130,7 @@ describe("Tests for the lithological description column.", () => { cy.get('[data-cy="description-1"]').contains("Quality of the description: -"); // stop editing - cy.get('[data-cy="editingStop-button"]').click(); - cy.wait("@edit_unlock"); - cy.get('[data-cy="backButton"]').click(); - cy.wait(["@edit_list", "@borehole"]); + stopBoreholeEditing(); + returnToOverview(); }); }); diff --git a/src/client/cypress/e2e/editor/lithostratigraphy.cy.js b/src/client/cypress/e2e/editor/lithostratigraphy.cy.js index bf1d43dd0..5ead53862 100644 --- a/src/client/cypress/e2e/editor/lithostratigraphy.cy.js +++ b/src/client/cypress/e2e/editor/lithostratigraphy.cy.js @@ -1,4 +1,10 @@ -import { bearerAuth, createBorehole, createStratigraphy, loginAsAdmin } from "../helpers/testHelpers"; +import { + bearerAuth, + createBorehole, + createStratigraphy, + loginAsAdmin, + startBoreholeEditing, +} from "../helpers/testHelpers"; describe("Tests for the lithostratigraphy editor.", () => { beforeEach(function () { @@ -60,8 +66,7 @@ describe("Tests for the lithostratigraphy editor.", () => { cy.wait("@get-layers-by-profileId"); // start editing session - cy.get('[data-cy="edit-button"]').click(); - cy.wait("@edit_lock"); + startBoreholeEditing(); cy.wait("@lithostratigraphy_GET"); }); diff --git a/src/client/cypress/e2e/editor/location.cy.js b/src/client/cypress/e2e/editor/location.cy.js index 2538dea4b..1b2c2f751 100644 --- a/src/client/cypress/e2e/editor/location.cy.js +++ b/src/client/cypress/e2e/editor/location.cy.js @@ -1,4 +1,4 @@ -import { newEditableBorehole } from "../helpers/testHelpers"; +import { newEditableBorehole, returnToOverview, stopBoreholeEditing } from "../helpers/testHelpers"; describe("Tests for 'Location' edit page.", () => { it("creates and deletes a borehole.", () => { @@ -9,11 +9,9 @@ describe("Tests for 'Location' edit page.", () => { cy.wait("@edit_patch"); // stop editing - cy.get('[data-cy="editingStop-button"]').click(); - cy.wait("@edit_unlock"); - cy.get('[data-cy="backButton"]').click(); + stopBoreholeEditing(); + returnToOverview(); cy.get('[data-cy="showTableButton"]').click(); - cy.wait(["@edit_list", "@borehole"]); // search the newly created borehole and delete it cy.get('[data-cy="borehole-table"]').within(() => { diff --git a/src/client/cypress/e2e/editor/publicationWorkflow.cy.js b/src/client/cypress/e2e/editor/publicationWorkflow.cy.js index 7d3b2f9cc..d7949ee90 100644 --- a/src/client/cypress/e2e/editor/publicationWorkflow.cy.js +++ b/src/client/cypress/e2e/editor/publicationWorkflow.cy.js @@ -1,4 +1,5 @@ import { createBorehole, loginAsAdmin } from "../helpers/testHelpers"; +import { startEditing } from "../helpers/buttonHelpers.js"; const verifyColorForStatus = (status, color) => { cy.get(`[data-cy="workflow_status_color_${status}"]`).should("have.have.class", `ui ${color} circular label`); @@ -31,7 +32,8 @@ describe("Tests the publication workflow.", () => { loginAsAdmin(); cy.visit(`/${id}/status`); }); - cy.get('[data-cy="edit-button"]').click(); + + startEditing(); verifyStatusTextsInHeader(["edit"]); verifyStatusTextsNotInHeader(["control", "valid", "public"]); @@ -48,7 +50,7 @@ describe("Tests the publication workflow.", () => { verifyColorForStatus("control", "orange"); // Submit for validation - cy.get('[data-cy="edit-button"]').click(); + startEditing(); cy.get('[data-cy="workflow_submit"]').click(); cy.get('[data-cy="workflow_dialog_submit"]').click(); cy.wait("@workflow_edit_list"); @@ -60,7 +62,7 @@ describe("Tests the publication workflow.", () => { verifyColorForStatus("valid", "orange"); // Submit for publication - cy.get('[data-cy="edit-button"]').click(); + startEditing(); cy.get('[data-cy="workflow_submit"]').click(); cy.get('[data-cy="workflow_dialog_submit"]').click(); cy.wait("@workflow_edit_list"); @@ -73,7 +75,7 @@ describe("Tests the publication workflow.", () => { verifyColorForStatus("public", "orange"); // Publish - cy.get('[data-cy="edit-button"]').click(); + startEditing(); cy.get('[data-cy="workflow_submit"]').click(); cy.get('[data-cy="workflow_dialog_submit"]').click(); cy.wait("@workflow_edit_list"); @@ -81,7 +83,7 @@ describe("Tests the publication workflow.", () => { verifyColorForStatus("public", "green"); // Restart workflow - cy.get('[data-cy="edit-button"]').click(); + startEditing(); cy.get('[data-cy="workflow_restart"]').click(); cy.wait("@workflow_edit_list"); diff --git a/src/client/cypress/e2e/editor/sections.cy.js b/src/client/cypress/e2e/editor/sections.cy.js index f01cefe60..b0cf66e94 100644 --- a/src/client/cypress/e2e/editor/sections.cy.js +++ b/src/client/cypress/e2e/editor/sections.cy.js @@ -1,6 +1,6 @@ -import { loginAsAdmin, createBorehole, startBoreholeEditing, handlePrompt } from "../helpers/testHelpers"; +import { createBorehole, handlePrompt, loginAsAdmin, startBoreholeEditing } from "../helpers/testHelpers"; import { evaluateDisplayValue, evaluateInput, setInput, setSelect } from "../helpers/formHelpers"; -import { addItem, startEditing, saveForm, deleteItem } from "../helpers/buttonHelpers"; +import { addItem, deleteItem, saveForm, startEditing } from "../helpers/buttonHelpers"; describe("Section crud tests", () => { beforeEach(() => { @@ -9,14 +9,11 @@ describe("Section crud tests", () => { // open section editor cy.get("@borehole_id").then(id => { loginAsAdmin(); - cy.visit(`/${id}/borehole`); + cy.visit(`/${id}/borehole#sections`); }); // start editing session startBoreholeEditing(); - - cy.get('[data-cy="sections-tab"]').click(); - cy.wait("@get-sections-by-boreholeId"); }); it("adds, edits and deletes sections", () => { @@ -25,7 +22,7 @@ describe("Section crud tests", () => { addItem("addSection"); cy.wait("@codelist_GET"); cy.get('[data-cy="sectionElements.0.delete"]').should("be.disabled"); - cy.get('[data-cy="addSection-button"]').should("be.disabled"); + cy.get('[data-cy="addsection-button"]').should("be.disabled"); cy.get('[data-cy="save-button"]').should("be.disabled"); setInput("name", "section-1"); diff --git a/src/client/cypress/e2e/editor/waterIngress.cy.js b/src/client/cypress/e2e/editor/waterIngress.cy.js index c26bf706b..ce3bfeff7 100644 --- a/src/client/cypress/e2e/editor/waterIngress.cy.js +++ b/src/client/cypress/e2e/editor/waterIngress.cy.js @@ -5,6 +5,7 @@ import { createWateringress, handlePrompt, loginAsAdmin, + selectLanguage, startBoreholeEditing, } from "../helpers/testHelpers"; import { evaluateDisplayValue, setInput, setSelect } from "../helpers/formHelpers"; @@ -39,9 +40,7 @@ describe("Tests for the wateringress editor.", () => { cy.wait("@wateringress_GET"); - // switch to german - cy.contains("span", "DE").click({ force: true }); - cy.wait(1000); + selectLanguage("de"); // create wateringress addItem("addWaterIngress"); diff --git a/src/client/cypress/e2e/filters/identifierFilter.cy.js b/src/client/cypress/e2e/filters/identifierFilter.cy.js index b12fa3410..026fe7296 100644 --- a/src/client/cypress/e2e/filters/identifierFilter.cy.js +++ b/src/client/cypress/e2e/filters/identifierFilter.cy.js @@ -1,4 +1,4 @@ -import { newEditableBorehole } from "../helpers/testHelpers.js"; +import { newEditableBorehole, returnToOverview, stopBoreholeEditing } from "../helpers/testHelpers.js"; describe("Tests for filtering data by identifier.", () => { it("can filter by identifier", () => { @@ -12,10 +12,8 @@ describe("Tests for filtering data by identifier.", () => { cy.get('[data-cy="identifier-value"] input').type(819544732); cy.get('[data-cy="identifier-add"]').click(); - cy.get('[data-cy="editingStop-button"]').click(); - cy.wait("@edit_unlock"); - cy.get('[data-cy="backButton"]').click(); - cy.wait(["@edit_list", "@borehole"]); + stopBoreholeEditing(); + returnToOverview(); cy.get('[data-cy="show-filter-button"]').click(); cy.contains("h6", "Location").click(); @@ -49,10 +47,8 @@ describe("Tests for filtering data by identifier.", () => { cy.get('[data-cy="identifier-value"] input').type(64531274); cy.get('[data-cy="identifier-add"]').click(); - cy.get('[data-cy="editingStop-button"]').click(); - cy.wait("@edit_unlock"); - cy.get('[data-cy="backButton"]').click(); - cy.wait(["@edit_list", "@borehole"]); + stopBoreholeEditing(); + returnToOverview(); newEditableBorehole().as("borehole_id_2"); identifierDropdown = cy.get('[data-cy="identifier-dropdown"]'); @@ -64,10 +60,8 @@ describe("Tests for filtering data by identifier.", () => { cy.get('[data-cy="identifier-value"] input').type(436584127); cy.get('[data-cy="identifier-add"]').click(); - cy.get('[data-cy="editingStop-button"]').click(); - cy.wait("@edit_unlock"); - cy.get('[data-cy="backButton"]').click(); - cy.wait(["@edit_list", "@borehole"]); + stopBoreholeEditing(); + returnToOverview(); cy.get('[data-cy="show-filter-button"]').click(); cy.contains("h6", "Location").click(); diff --git a/src/client/cypress/e2e/filters/srsFilter.cy.js b/src/client/cypress/e2e/filters/srsFilter.cy.js index d5fb9bd0f..eb8c5fe17 100644 --- a/src/client/cypress/e2e/filters/srsFilter.cy.js +++ b/src/client/cypress/e2e/filters/srsFilter.cy.js @@ -1,4 +1,4 @@ -import { loginAsAdmin, newEditableBorehole } from "../helpers/testHelpers.js"; +import { loginAsAdmin, newEditableBorehole, returnToOverview, stopBoreholeEditing } from "../helpers/testHelpers.js"; describe("Tests for filtering data by reference system.", () => { function goToEditorLocationFilter() { @@ -43,10 +43,8 @@ describe("Tests for filtering data by reference system.", () => { cy.wait(["@edit_patch", "@edit_patch", "@edit_patch", "@edit_patch"]); - cy.get('[data-cy="editingStop-button"]').click(); - cy.wait("@edit_unlock"); - cy.get('[data-cy="backButton"]').click(); - cy.wait(["@edit_list", "@borehole"]); + stopBoreholeEditing(); + returnToOverview(); cy.get('[data-cy="show-filter-button"]').click(); cy.contains("h6", "Location").click(); diff --git a/src/client/cypress/e2e/helpers/buttonHelpers.js b/src/client/cypress/e2e/helpers/buttonHelpers.js index 98905b187..43b9fece7 100644 --- a/src/client/cypress/e2e/helpers/buttonHelpers.js +++ b/src/client/cypress/e2e/helpers/buttonHelpers.js @@ -18,6 +18,15 @@ export const startEditing = parent => { cy.get(selector).click({ force: true }); }; +/** + * Clicks on the stop editing button. + * @param {string} parent (optional) The parent of the button. + */ +export const stopEditing = parent => { + var selector = createBaseSelector(parent) + '[data-cy="editingstop-button"]'; + cy.get(selector).click({ force: true }); +}; + /** * Clicks on the cancel button. * @param {string} parent (optional) The parent of the button. @@ -50,5 +59,5 @@ export const copyItem = parent => { * @param {string} itemLabel The label name of the button. */ export const addItem = itemLabel => { - cy.get(`[data-cy="${itemLabel}-button"]`).click({ force: true }); + cy.get(`[data-cy="${itemLabel.toLowerCase()}-button"]`).click({ force: true }); }; diff --git a/src/client/cypress/e2e/helpers/testHelpers.js b/src/client/cypress/e2e/helpers/testHelpers.js index aeec33644..08d8ad0a3 100644 --- a/src/client/cypress/e2e/helpers/testHelpers.js +++ b/src/client/cypress/e2e/helpers/testHelpers.js @@ -1,6 +1,7 @@ import adminUser from "../../fixtures/adminUser.json"; import editorUser from "../../fixtures/editorUser.json"; import viewerUser from "../../fixtures/viewerUser.json"; +import { startEditing, stopEditing } from "./buttonHelpers.js"; export const bearerAuth = token => ({ bearer: token }); @@ -166,8 +167,7 @@ export const loginAsViewer = () => { export const newEditableBorehole = () => { const id = newUneditableBorehole(); - cy.get('[data-cy="edit-button"]').click(); - cy.wait("@edit_lock"); + startBoreholeEditing(); return id; }; @@ -230,10 +230,20 @@ export const createAndEditBoreholeAsAdmin = values => { }; export const startBoreholeEditing = () => { - cy.get('[data-cy="edit-button"]').click(); + startEditing(); cy.wait("@edit_lock"); }; +export const stopBoreholeEditing = () => { + stopEditing(); + cy.wait("@edit_unlock"); +}; + +export const returnToOverview = () => { + cy.get('[data-cy="backButton"]').click(); + cy.wait(["@edit_list", "@borehole"]); +}; + export const deleteBorehole = id => { loginAsAdmin(); cy.get("@id_token").then(token => { @@ -581,10 +591,10 @@ export const createInstrument = (completionId, casingId, name, statusId, kindId, }); }; -export const handlePrompt = (title, action) => { +export const handlePrompt = (message, action) => { cy.get('[data-cy="prompt"]').should("be.visible"); - cy.contains(title); - cy.get('[data-cy="prompt-button-' + action + '"]').click(); + cy.contains(message); + cy.get('[data-cy="prompt"]').find(`[data-cy="${action.toLowerCase()}-button"]`).click(); }; export const createBaseSelector = parent => { @@ -594,3 +604,9 @@ export const createBaseSelector = parent => { return ""; } }; + +export const selectLanguage = language => { + cy.get('[data-cy="language-selector"]').click({ force: true }); + cy.get(`[data-cy="language-${language.toLowerCase()}"]`).click({ force: true }); + cy.wait(1000); +}; diff --git a/src/client/package-lock.json b/src/client/package-lock.json index 5e1077e36..2d646d6c2 100644 --- a/src/client/package-lock.json +++ b/src/client/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.14.19", + "@mui/icons-material": "^5.16.4", "@mui/material": "^5.14.20", "@react-hook/resize-observer": "^1.2.6", "@types/ol": "^7.0.0", @@ -1424,9 +1424,9 @@ } }, "node_modules/@mui/icons-material": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.11.tgz", - "integrity": "sha512-R5ZoQqnKpd+5Ew7mBygTFLxgYsQHPhgR3TDXSgIHYIjGzYuyPLmGLSdcPUoMdi6kxiYqHlpPj4NJxlbaFD0UHA==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.4.tgz", + "integrity": "sha512-j9/CWctv6TH6Dou2uR2EH7UOgu79CW/YcozxCYVLJ7l03pCsiOlJ5sBArnWJxJ+nGkFwyL/1d1k8JEPMDR125A==", "dependencies": { "@babel/runtime": "^7.23.9" }, diff --git a/src/client/package.json b/src/client/package.json index 0024531df..b7c1523fa 100644 --- a/src/client/package.json +++ b/src/client/package.json @@ -25,7 +25,7 @@ "dependencies": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.14.19", + "@mui/icons-material": "^5.16.4", "@mui/material": "^5.14.20", "@react-hook/resize-observer": "^1.2.6", "@types/ol": "^7.0.0", diff --git a/src/client/public/icons/arrow_down.svg b/src/client/public/icons/arrow_down.svg new file mode 100644 index 000000000..cd0753eb6 --- /dev/null +++ b/src/client/public/icons/arrow_down.svg @@ -0,0 +1,14 @@ + + + + diff --git a/src/client/public/icons/arrow_up.svg b/src/client/public/icons/arrow_up.svg new file mode 100644 index 000000000..f2c46f207 --- /dev/null +++ b/src/client/public/icons/arrow_up.svg @@ -0,0 +1,14 @@ + + + + diff --git a/src/client/public/icons/help.svg b/src/client/public/icons/help.svg index 5efd24d9e..2c5d0a9a2 100644 --- a/src/client/public/icons/help.svg +++ b/src/client/public/icons/help.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/client/public/locale/de/common.json b/src/client/public/locale/de/common.json index 247a53479..eee34cff9 100644 --- a/src/client/public/locale/de/common.json +++ b/src/client/public/locale/de/common.json @@ -90,11 +90,10 @@ "degree": "Grad", "delete": "Löschen", "deleteBorehole": "Bohrloch löschen", - "deleteCompletionMessage": "Der Ausbau wird zusammen mit seinen Verrohrungen, Instrumentierungen und Verfüllung/Hinterfüllungen dauerhaft gelöscht.", - "deleteCompletionTitle": "Wollen Sie diesen Ausbau wirklich löschen?", + "deleteBoreholeMessage": "Wollen Sie dieses Bohrloch wirklich löschen? Dies kann nicht rückgängig gemacht werden.", + "deleteCompletionMessage": "Wollen Sie diesen Ausbau wirklich löschen? Der Ausbau wird zusammen mit seinen Verrohrungen, Instrumentierungen und Verfüllung/Hinterfüllungen dauerhaft gelöscht.", "deleteForever": "Dauerhaft löschen", - "deleteMessage": "Der Eintrag wird dauerhaft aus der Datenbank gelöscht.", - "deleteTitle": "Wollen Sie diesen Eintrag wirklich löschen?", + "deleteMessage": "Wollen Sie diesen Eintrag wirklich löschen? Der Eintrag wird dauerhaft aus der Datenbank gelöscht.", "deletelayer": "Bestehende Schicht löschen", "deletelayerconfirmation": "Sie löschen diese Schicht. Wie wollen Sie fortfahren?", "deleting": "{{what}} löschen", @@ -430,8 +429,7 @@ "totaldepth": "Bohrlochlänge [m MD]", "transparency": "Transparenz", "type": "Typ", - "unsavedChangesMessage": "Sie haben ungespeicherte Änderungen. Wie möchten Sie fortfahren?", - "unsavedChangesTitle": "{{where}}: Ungespeicherte Änderungen", + "unsavedChangesMessage": "{{where}}: Sie haben ungespeicherte Änderungen. Wie möchten Sie fortfahren?", "unselectAll": "Alle abwählen", "updateDate": "Bearbeitungsdatum", "updatedBy": "Aktualisiert durch", diff --git a/src/client/public/locale/en/common.json b/src/client/public/locale/en/common.json index 8b09c1035..d63eda1d4 100644 --- a/src/client/public/locale/en/common.json +++ b/src/client/public/locale/en/common.json @@ -90,11 +90,10 @@ "degree": "Degrees", "delete": "Delete", "deleteBorehole": "Delete borehole", - "deleteCompletionMessage": "This completion including its casings, instruments and sealing/backfilling will be permanently deleted from the database.", - "deleteCompletionTitle": "Do you really want to delete this completion?", + "deleteBoreholeMessage": "Do you really want to delete this borehole? This cannot be undone.", + "deleteCompletionMessage": "Do you really want to delete this completion? This completion including its casings, instruments and sealing/backfilling will be permanently deleted from the database.", "deleteForever": "Delete permanently", - "deleteMessage": "The entry will be permanently deleted from the database.", - "deleteTitle": "Do you really want to delete this entry?", + "deleteMessage": "Do you really want to delete this entry? The entry will be permanently deleted from the database.", "deletelayer": "Delete this layer", "deletelayerconfirmation": "You are about to delete this layer, how do you want to proceed?", "deleting": "Deleting {{what}}", @@ -431,8 +430,7 @@ "totaldepth": "Borehole length [m MD]", "transparency": "Transparency", "type": "Type", - "unsavedChangesMessage": "You have unsaved changes. How would you like to proceed?", - "unsavedChangesTitle": "{{where}}: Unsaved changes", + "unsavedChangesMessage": "{{where}}: You have unsaved changes. How would you like to proceed?", "unselectAll": "Unselect all", "updateDate": "Update date", "updatedBy": "Updated by", diff --git a/src/client/public/locale/fr/common.json b/src/client/public/locale/fr/common.json index c5eed6015..5923c306a 100644 --- a/src/client/public/locale/fr/common.json +++ b/src/client/public/locale/fr/common.json @@ -90,11 +90,10 @@ "degree": "Degrés", "delete": "Supprimer", "deleteBorehole": "Supprimer forage", - "deleteCompletionMessage": "Cet aménagement, y compris les tubage, les instruments et les remplissages/remblayages, sera définitivement supprimé de la base de données.", - "deleteCompletionTitle": "Voulez-vous vraiment supprimer cet aménagement?", + "deleteBoreholeMessage": "Voulez-vous vraiment effacer ce trou de forage? Cela ne peut pas être annulé.", + "deleteCompletionMessage": "Voulez-vous vraiment supprimer cet aménagement? Cet aménagement, y compris les tubage, les instruments et les remplissages/remblayages, sera définitivement supprimé de la base de données.", "deleteForever": "Supprimer définitivement", - "deleteMessage": "L'entrée sera définitivement supprimée de la base de données.", - "deleteTitle": "Voulez-vous vraiment supprimer cette entrée ?", + "deleteMessage": "Voulez-vous vraiment supprimer cette entrée? L'entrée sera définitivement supprimée de la base de données.", "deletelayer": "Supprimer cette couche", "deletelayerconfirmation": "Vous êtes sur le point de supprimer cette couche, comment voulez-vous procéder?", "deleting": "Suppression de {{what}}", @@ -430,8 +429,7 @@ "totaldepth": "Longueur du forage [m MD]", "transparency": "Transparence", "type": "Type", - "unsavedChangesMessage": "Vous avez des modifications non enregistrés. Comment souhaitez-vous continuer?", - "unsavedChangesTitle": "{{where}}: Changements non enregistrés", + "unsavedChangesMessage": "{{where}}: Vous avez des modifications non enregistrés. Comment souhaitez-vous continuer?", "unselectAll": "Tout désélectionner", "updateDate": "Date de modification", "updatedBy": "Mis à jour par", diff --git a/src/client/public/locale/it/common.json b/src/client/public/locale/it/common.json index 427634a7a..993980ad5 100644 --- a/src/client/public/locale/it/common.json +++ b/src/client/public/locale/it/common.json @@ -90,11 +90,10 @@ "degree": "Gradi", "delete": "Elimina", "deleteBorehole": "Elimina perforazione", - "deleteCompletionMessage": "Questo installazione, compresi gli tubazione, gli strumenti e i riempimenti/rinterri, sarà cancellato definitivamente dal database.", - "deleteCompletionTitle": "Volete davvero cancellare questo installazione?", + "deleteBoreholeMessage": "Volete davvero cancellare questo foro? Non è possibile annullare questa operazione.", + "deleteCompletionMessage": "Volete davvero cancellare questo installazione? Questo installazione, compresi gli tubazione, gli strumenti e i riempimenti/rinterri, sarà cancellato definitivamente dal database.", "deleteForever": "Elimina definitivamente", - "deleteMessage": "La voce verrà eliminata definitivamente dal database.", - "deleteTitle": "Volete davvero eliminare questa voce?", + "deleteMessage": "Volete davvero eliminare questa voce? La voce verrà eliminata definitivamente dal database.", "deletelayer": "Elimina questo livello", "deletelayerconfirmation": "Stai per eliminare questo livello, come vuoi procedere?", "deleting": "Eliminazione {{what}}", @@ -430,8 +429,7 @@ "totaldepth": "Lunghezza della perforazione [m MD]", "transparency": "Trasparenza", "type": "Tipo", - "unsavedChangesMessage": "Le modifiche non sono state salvate. Come volete procedere?", - "unsavedChangesTitle": "{{where}}: Modifiche non salvate", + "unsavedChangesMessage": "{{where}}: Le modifiche non sono state salvate. Come volete procedere?", "unselectAll": "Deseleziona tutto", "updateDate": "Data di aggiornamento", "updatedBy": "Aggiornato da", diff --git a/src/client/src/App.jsx b/src/client/src/App.tsx similarity index 77% rename from src/client/src/App.jsx rename to src/client/src/App.tsx index eb955a36e..10a290fdd 100644 --- a/src/client/src/App.jsx +++ b/src/client/src/App.tsx @@ -11,17 +11,19 @@ import AcceptTerms from "./pages/term/accept"; import { AlertProvider } from "./components/alert/alertContext"; import { AlertBanner } from "./components/alert/alertBanner"; import { DataCardProvider } from "./components/dataCard/dataCardContext.jsx"; -import { PromptProvider } from "./components/prompt/promptContext.jsx"; -import { Prompt } from "./components/prompt/prompt"; +import { PromptProvider } from "./components/prompt/promptContext.tsx"; +import { Prompt } from "./components/prompt/prompt.tsx"; import { BasemapProvider } from "./components/basemapSelector/basemapContext.tsx"; import { FilterProvider } from "./components/filter/filterContext.tsx"; const queryClient = new QueryClient(); class App extends React.Component { - handleDragOver = e => { + handleDragOver = (e: DragEvent) => { e.preventDefault(); - e.dataTransfer.dropEffect = "none"; + if (e.dataTransfer) { + e.dataTransfer.dropEffect = "none"; + } }; componentDidMount() { @@ -35,16 +37,16 @@ class App extends React.Component { render() { return ( - - - - - - - - - - + + + + + + + + + + @@ -70,14 +72,14 @@ class App extends React.Component { - - - - - - - - + + + + + + + + ); } } diff --git a/src/client/src/AppTheme.ts b/src/client/src/AppTheme.ts index 7ec3f81a2..4ad220edc 100644 --- a/src/client/src/AppTheme.ts +++ b/src/client/src/AppTheme.ts @@ -43,7 +43,7 @@ export const theme = createTheme({ lightgrey: "#f1f3f5", darkgrey: "#787878", dark: "rgba(0, 0, 0, 0.5)", - menuItemActive: "#D92B04", + menuItemActive: "#A65462", filterItemActive: "#1C2834", }, @@ -135,5 +135,21 @@ export const theme = createTheme({ }, }, }, + MuiBadge: { + styleOverrides: { + badge: { + backgroundColor: "#FF0000", + color: "#FFFFFF", + }, + }, + }, + MuiDialogContentText: { + styleOverrides: { + root: { + fontSize: "16px", + color: "#1c2834", + }, + }, + }, }, }); diff --git a/src/client/src/commons/form/borehole/borehole/boreholePanel.jsx b/src/client/src/commons/form/borehole/borehole/boreholePanel.jsx index 0f98e9971..e785f59ce 100644 --- a/src/client/src/commons/form/borehole/borehole/boreholePanel.jsx +++ b/src/client/src/commons/form/borehole/borehole/boreholePanel.jsx @@ -1,22 +1,55 @@ import BoreholeGeneralSegment from "../segments/boreholeGeneralSegment"; import BoreholeDetailSegment from "../segments/boreholeDetailSegment"; import { useTranslation } from "react-i18next"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import Sections from "./sections"; import Geometry from "./geometry"; -import { BdmsTabContentBox, BdmsTabs, BdmsTab } from "../../../../components/styledTabComponents"; +import { BdmsTab, BdmsTabContentBox, BdmsTabs } from "../../../../components/styledTabComponents"; +import { useHistory, useLocation } from "react-router-dom"; const BoreholePanel = ({ size, boreholeId, borehole, updateChange, updateNumber, isEditable }) => { const { t } = useTranslation(); - + const history = useHistory(); + const location = useLocation(); const [activeIndex, setActiveIndex] = useState(0); + const tabs = [ + { + label: t("general"), + hash: "general", + }, + { label: t("sections"), hash: "sections" }, + { label: t("boreholeGeometry"), hash: "geometry" }, + ]; + + const handleIndexChange = (event, index) => { + setActiveIndex(index); + const newLocation = location.pathname + "#" + tabs[index].hash; + if (location.pathname + location.hash !== newLocation) { + history.push(newLocation); + } + }; + + useEffect(() => { + const newTabIndex = tabs.findIndex(t => t.hash === location.hash.replace("#", "")); + if (newTabIndex > -1 && activeIndex !== newTabIndex) { + handleIndexChange(null, newTabIndex); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [location.hash]); + + useEffect(() => { + if (!location.hash) { + history.replace(location.pathname + "#" + tabs[activeIndex].hash); + } + // eslint-disable-next-line + }, []); return ( <> - setActiveIndex(newValue)}> - - - + + {tabs.map((tab, index) => { + return ; + })} {activeIndex === 0 && ( diff --git a/src/client/src/commons/form/borehole/boreholeForm.jsx b/src/client/src/commons/form/borehole/boreholeForm.jsx index cf2b18adb..13f83bea1 100644 --- a/src/client/src/commons/form/borehole/boreholeForm.jsx +++ b/src/client/src/commons/form/borehole/boreholeForm.jsx @@ -386,11 +386,6 @@ class BoreholeForm extends React.Component { path={"/:id/hydrogeology/hydrotest"} render={() => } /> - } - /> { diff --git a/src/client/src/commons/form/borehole/completion/casingInput.jsx b/src/client/src/commons/form/borehole/completion/casingInput.jsx index 21d4935a0..2b0dd7147 100644 --- a/src/client/src/commons/form/borehole/completion/casingInput.jsx +++ b/src/client/src/commons/form/borehole/completion/casingInput.jsx @@ -11,7 +11,7 @@ import { DataCardButtonContainer } from "../../../../components/dataCard/dataCar import { AddButton, CancelButton, SaveButton } from "../../../../components/buttons/buttons.tsx"; import { extractCasingDepth } from "./casingUtils"; import { DataCardContext, DataCardSwitchContext } from "../../../../components/dataCard/dataCardContext"; -import { PromptContext } from "../../../../components/prompt/promptContext"; +import { PromptContext } from "../../../../components/prompt/promptContext.tsx"; const CasingInput = props => { const { item, parentId } = props; @@ -100,7 +100,7 @@ const CasingInput = props => { useEffect(() => { if (checkIsDirty) { if (Object.keys(formMethods.formState.dirtyFields).length > 0) { - showPrompt(t("unsavedChangesTitle", { where: t("casing") }), t("unsavedChangesMessage"), [ + showPrompt(t("unsavedChangesMessage", { where: t("casing") }), [ { label: t("cancel"), action: () => { diff --git a/src/client/src/commons/form/borehole/completion/completion.jsx b/src/client/src/commons/form/borehole/completion/completion.jsx index fb518d52d..5923d48c4 100644 --- a/src/client/src/commons/form/borehole/completion/completion.jsx +++ b/src/client/src/commons/form/borehole/completion/completion.jsx @@ -16,7 +16,8 @@ import CompletionHeaderDisplay from "./completionHeaderDisplay"; import { AddButton } from "../../../../components/buttons/buttons.tsx"; import { FullPage } from "../../../../components/baseComponents"; import { DataCardExternalContext } from "../../../../components/dataCard/dataCardContext"; -import { PromptContext } from "../../../../components/prompt/promptContext"; +import { PromptContext } from "../../../../components/prompt/promptContext.tsx"; +import TrashIcon from "../../../../../public/icons/trash.svg?react"; const Completion = props => { const { isEditable } = props; @@ -214,13 +215,15 @@ const Completion = props => { }; const deleteSelectedCompletion = () => { - showPrompt(t("deleteCompletionTitle"), t("deleteCompletionMessage"), [ + showPrompt(t("deleteCompletionMessage"), [ { label: t("cancel"), action: null, }, { label: t("delete"), + icon: , + variant: "contained", action: onDeleteConfirmed, }, ]); diff --git a/src/client/src/commons/form/borehole/completion/completionHeaderInput.jsx b/src/client/src/commons/form/borehole/completion/completionHeaderInput.jsx index 107afc40a..c4b5bd1ca 100644 --- a/src/client/src/commons/form/borehole/completion/completionHeaderInput.jsx +++ b/src/client/src/commons/form/borehole/completion/completionHeaderInput.jsx @@ -7,7 +7,7 @@ import { completionSchemaConstants } from "./completionSchemaConstants"; import { DataCardButtonContainer } from "../../../../components/dataCard/dataCard"; import { FormCheckbox, FormInput, FormSelect } from "../../../../components/form/form"; import { CancelButton, SaveButton } from "../../../../components/buttons/buttons.tsx"; -import { PromptContext } from "../../../../components/prompt/promptContext"; +import { PromptContext } from "../../../../components/prompt/promptContext.tsx"; const CompletionHeaderInput = props => { const { completion, cancelChanges, saveCompletion, trySwitchTab, switchTabs } = props; @@ -33,7 +33,7 @@ const CompletionHeaderInput = props => { useEffect(() => { if (trySwitchTab) { if (Object.keys(formMethods.formState.dirtyFields).length > 0) { - showPrompt(t("unsavedChangesTitle", { where: t("completion") }), t("unsavedChangesMessage"), [ + showPrompt(t("unsavedChangesMessage", { where: t("completion") }), [ { label: t("cancel"), action: () => { diff --git a/src/client/src/commons/form/borehole/hydrogeology/fieldMeasurementInput.jsx b/src/client/src/commons/form/borehole/hydrogeology/fieldMeasurementInput.jsx index a87604118..2d2951204 100644 --- a/src/client/src/commons/form/borehole/hydrogeology/fieldMeasurementInput.jsx +++ b/src/client/src/commons/form/borehole/hydrogeology/fieldMeasurementInput.jsx @@ -6,7 +6,7 @@ import { FormInput, FormSelect } from "../../../../components/form/form"; import { DataCardButtonContainer } from "../../../../components/dataCard/dataCard"; import { addFieldMeasurement, updateFieldMeasurement, useDomains } from "../../../../api/fetchApiV2"; import { DataCardContext, DataCardSwitchContext } from "../../../../components/dataCard/dataCardContext"; -import { PromptContext } from "../../../../components/prompt/promptContext"; +import { PromptContext } from "../../../../components/prompt/promptContext.tsx"; import { useTranslation } from "react-i18next"; import ObservationInput from "./observationInput"; import { ObservationType } from "./observationType"; @@ -39,7 +39,7 @@ const FieldMeasurementInput = props => { useEffect(() => { if (checkIsDirty) { if (Object.keys(formMethods.formState.dirtyFields).length > 0) { - showPrompt(t("unsavedChangesTitle", { where: t("fieldMeasurement") }), t("unsavedChangesMessage"), [ + showPrompt(t("unsavedChangesMessage", { where: t("fieldMeasurement") }), [ { label: t("cancel"), action: () => { @@ -112,6 +112,10 @@ const FieldMeasurementInput = props => { data?.endTime ? (data.endTime += ":00.000Z") : (data.endTime = null); data.type = ObservationType.fieldMeasurement; data.boreholeId = parentId; + + if (data.reliabilityId === "") { + data.reliabilityId = null; + } delete data.reliability; if (data.fieldMeasurementResults) { diff --git a/src/client/src/commons/form/borehole/hydrogeology/groundwaterLevelMeasurementInput.jsx b/src/client/src/commons/form/borehole/hydrogeology/groundwaterLevelMeasurementInput.jsx index 658b46e52..7538eaa6a 100644 --- a/src/client/src/commons/form/borehole/hydrogeology/groundwaterLevelMeasurementInput.jsx +++ b/src/client/src/commons/form/borehole/hydrogeology/groundwaterLevelMeasurementInput.jsx @@ -27,6 +27,9 @@ const GroundwaterLevelMeasurementInput = props => { if (data.casingId == null) { data.casingId = item.casingId; } + if (data.reliabilityId === "") { + data.reliabilityId = null; + } delete data.reliability; return data; diff --git a/src/client/src/commons/form/borehole/hydrogeology/hydrotestInput.jsx b/src/client/src/commons/form/borehole/hydrogeology/hydrotestInput.jsx index ff21756e0..bbb476916 100644 --- a/src/client/src/commons/form/borehole/hydrogeology/hydrotestInput.jsx +++ b/src/client/src/commons/form/borehole/hydrogeology/hydrotestInput.jsx @@ -13,7 +13,7 @@ import { hydrogeologySchemaConstants } from "./hydrogeologySchemaConstants"; import { getHydrotestParameterUnits } from "./parameterUnits"; import Delete from "@mui/icons-material/Delete"; import { DataCardContext, DataCardSwitchContext } from "../../../../components/dataCard/dataCardContext"; -import { PromptContext } from "../../../../components/prompt/promptContext"; +import { PromptContext } from "../../../../components/prompt/promptContext.tsx"; import { prepareCasingDataForSubmit } from "../completion/casingUtils"; const HydrotestInput = props => { @@ -41,7 +41,7 @@ const HydrotestInput = props => { useEffect(() => { if (checkIsDirty) { if (Object.keys(formMethods.formState.dirtyFields).length > 0) { - showPrompt(t("unsavedChangesTitle", { where: t("hydrotest") }), t("unsavedChangesMessage"), [ + showPrompt(t("unsavedChangesMessage", { where: t("hydrotest") }), [ { label: t("cancel"), action: () => { @@ -177,6 +177,10 @@ const HydrotestInput = props => { }); } + if (data.reliabilityId === "") { + data.reliabilityId = null; + } + delete data.testKindId; delete data.flowDirectionId; delete data.evaluationMethodId; diff --git a/src/client/src/commons/form/borehole/hydrogeology/observationInput.jsx b/src/client/src/commons/form/borehole/hydrogeology/observationInput.jsx index f34a47b36..41e3f01bd 100644 --- a/src/client/src/commons/form/borehole/hydrogeology/observationInput.jsx +++ b/src/client/src/commons/form/borehole/hydrogeology/observationInput.jsx @@ -1,7 +1,7 @@ -import { useState, useEffect } from "react"; +import { useEffect, useState } from "react"; import { Stack } from "@mui/material"; import { FormInput, FormSelect } from "../../../../components/form/form"; -import { useDomains, getCasingsByBoreholeId } from "../../../../api/fetchApiV2"; +import { getCasingsByBoreholeId, useDomains } from "../../../../api/fetchApiV2"; import { useTranslation } from "react-i18next"; import { hydrogeologySchemaConstants } from "./hydrogeologySchemaConstants"; import { StackHalfWidth } from "../../../../components/baseComponents"; @@ -33,13 +33,7 @@ const ObservationInput = props => { - + @@ -48,7 +42,6 @@ const ObservationInput = props => { fieldName="reliabilityId" label="reliability" selected={observation.reliabilityId} - required={true} values={domains?.data ?.filter(d => d.schema === hydrogeologySchemaConstants.observationReliability) .sort((a, b) => a.order - b.order) diff --git a/src/client/src/commons/form/borehole/hydrogeology/waterIngressInput.jsx b/src/client/src/commons/form/borehole/hydrogeology/waterIngressInput.jsx index 7abb5451d..949a4b7af 100644 --- a/src/client/src/commons/form/borehole/hydrogeology/waterIngressInput.jsx +++ b/src/client/src/commons/form/borehole/hydrogeology/waterIngressInput.jsx @@ -22,6 +22,9 @@ const WaterIngressInput = props => { if (data.conditionsId === "") { data.conditionsId = null; } + if (data.reliabilityId === "") { + data.reliabilityId = null; + } delete data.reliability; return data; }; diff --git a/src/client/src/commons/map/mapComponent.jsx b/src/client/src/commons/map/mapComponent.jsx index 4f87c4c20..aebc1c106 100644 --- a/src/client/src/commons/map/mapComponent.jsx +++ b/src/client/src/commons/map/mapComponent.jsx @@ -23,17 +23,17 @@ import { Box } from "@mui/material"; import ZoomControls from "./zoomControls"; import NamePopup from "./namePopup"; import { BasemapSelector } from "../../components/basemapSelector/basemapSelector"; -import { attributions, crossOrigin, swissExtent, updateBasemap } from "../../components/basemapSelector/basemaps"; +import { swissExtent, updateBasemap } from "../../components/basemapSelector/basemaps"; import { BasemapContext } from "../../components/basemapSelector/basemapContext"; import { clusterStyleFunction, drawStyle, styleFunction } from "./mapStyleFunctions"; import { projections } from "./mapProjections"; import { theme } from "../../AppTheme"; import Draw from "ol/interaction/Draw.js"; import { withTranslation } from "react-i18next"; -import XYZ from "ol/source/XYZ"; class MapComponent extends React.Component { static contextType = BasemapContext; + constructor(props) { super(props); this.onSelected = this.onSelected.bind(this); @@ -300,22 +300,6 @@ class MapComponent extends React.Component { this.setState({ displayedBaseMap: this.context.currentBasemapName }); - const mapLayers = - this.context.currentBasemapName === "nomap" - ? [] - : [ - new TileLayer({ - properties: { - name: this.context.currentBasemapName, - }, - source: new XYZ({ - url: `https://wmts100.geo.admin.ch/1.0.0/${this.context.currentBasemapName}/default/current/3857/{z}/{x}/{y}.jpeg`, - crossOrigin: crossOrigin, - attributions: attributions, - }), - }), - ]; - this.map = new Map({ controls: defaultControls({ attribution: true, @@ -328,7 +312,7 @@ class MapComponent extends React.Component { }), loadTilesWhileAnimating: true, loadTilesWhileInteracting: true, - layers: mapLayers, + layers: [], target: "map", view: new View({ minResolution: 0.1, @@ -339,6 +323,8 @@ class MapComponent extends React.Component { showFullExtent: true, }), }); + + updateBasemap(this.map, this.context.currentBasemapName); } handleHighlights(currentHighlights, hoverCallback, previousHighlights) { diff --git a/src/client/src/commons/menu/detailView/confirmDeleteModal.tsx b/src/client/src/commons/menu/detailView/confirmDeleteModal.tsx deleted file mode 100644 index b5e1d614d..000000000 --- a/src/client/src/commons/menu/detailView/confirmDeleteModal.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { Button, Header, Icon, Modal } from "semantic-ui-react"; -import TranslationText from "../../form/translationText.jsx"; -import { useSelector } from "react-redux"; -import { Borehole, ReduxRootState } from "../../../ReduxStateInterfaces"; -import { useState } from "react"; -import { useHistory } from "react-router-dom"; -import { deleteBorehole } from "../../../api-lib"; -import { ConfirmDeleteModalInterface } from "./confirmDeleteModalInterface"; - -export function ConfirmDeleteModal({ onClose, open, trigger }: ConfirmDeleteModalInterface) { - const borehole: Borehole = useSelector((state: ReduxRootState) => state.core_borehole); - const [deleting, setDeleting] = useState(false); - const history = useHistory(); - - const confirmDelete = async () => { - setDeleting(true); - await deleteBorehole(borehole.data.id); - history.push("/"); - }; - - return ( - -
} /> - -

- -

-
- - - - - ); -} diff --git a/src/client/src/commons/menu/detailView/confirmDeleteModalInterface.ts b/src/client/src/commons/menu/detailView/confirmDeleteModalInterface.ts deleted file mode 100644 index e24870f97..000000000 --- a/src/client/src/commons/menu/detailView/confirmDeleteModalInterface.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface ConfirmDeleteModalInterface { - open: boolean; - onClose: () => void; - trigger: React.ReactNode; -} diff --git a/src/client/src/commons/menu/detailView/detailHeader.tsx b/src/client/src/commons/menu/detailView/detailHeader.tsx index 0b65c15f4..ef62c6159 100644 --- a/src/client/src/commons/menu/detailView/detailHeader.tsx +++ b/src/client/src/commons/menu/detailView/detailHeader.tsx @@ -1,26 +1,27 @@ -import { useEffect, useState } from "react"; +import { useContext, useEffect, useState } from "react"; import { Chip, IconButton, Stack, Typography } from "@mui/material"; import { theme } from "../../../AppTheme"; import ArrowLeftIcon from "../../../../public/icons/arrow_left.svg?react"; import CheckmarkIcon from "../../../../public/icons/checkmark.svg?react"; +import TrashIcon from "../../../../public/icons/trash.svg?react"; import { useHistory, useLocation } from "react-router-dom"; import { DeleteButton, EditButton, EndEditButton } from "../../../components/buttons/buttons"; -import { ConfirmDeleteModal } from "./confirmDeleteModal"; import { useDispatch, useSelector } from "react-redux"; import { Borehole, ReduxRootState } from "../../../ReduxStateInterfaces"; -import { lockBorehole, unlockBorehole } from "../../../api-lib"; +import { deleteBorehole, lockBorehole, unlockBorehole } from "../../../api-lib"; import { useTranslation } from "react-i18next"; +import { PromptContext } from "../../../components/prompt/promptContext"; const DetailHeader = () => { const [editingEnabled, setEditingEnabled] = useState(false); const [editableByCurrentUser, setEditableByCurrentUser] = useState(false); - const [confirmDelete, setConfirmDelete] = useState(false); const borehole: Borehole = useSelector((state: ReduxRootState) => state.core_borehole); const user = useSelector((state: ReduxRootState) => state.core_user); const history = useHistory(); const location = useLocation(); const dispatch = useDispatch(); const { t } = useTranslation(); + const { showPrompt } = useContext(PromptContext); const toggleEditing = (editingEnabled: boolean) => { setEditingEnabled(editingEnabled); @@ -39,8 +40,9 @@ const DetailHeader = () => { toggleEditing(false); }; - const handleClose = () => { - setConfirmDelete(false); + const handleDelete = async () => { + await deleteBorehole(borehole.data.id); + history.push("/"); }; useEffect(() => { @@ -109,13 +111,22 @@ const DetailHeader = () => { {editableByCurrentUser && ( <> {editingEnabled && ( - - setConfirmDelete(true)} /> - + + showPrompt(t("deleteBoreholeMessage"), [ + { + label: t("cancel"), + }, + { + label: t("delete"), + icon: , + variant: "contained", + action: () => { + handleDelete(); + }, + }, + ]) } /> )} diff --git a/src/client/src/commons/menu/detailView/detailSideNav.jsx b/src/client/src/commons/menu/detailView/detailSideNav.jsx index 0396efa7f..660731743 100644 --- a/src/client/src/commons/menu/detailView/detailSideNav.jsx +++ b/src/client/src/commons/menu/detailView/detailSideNav.jsx @@ -190,50 +190,46 @@ const DetailSideNav = ({ borehole, history, match }) => { - + { - history.push(`/${id}/hydrogeology/hydrotest`); + history.push(`/${id}/hydrogeology/groundwaterlevelmeasurement`); }}> - + - + - - )} - {hydrogeologyIsVisible && ( - <> { - history.push(`/${id}/hydrogeology/groundwaterlevelmeasurement`); + history.push(`/${id}/hydrogeology/fieldmeasurement`); }}> - + - + { - history.push(`/${id}/hydrogeology/fieldmeasurement`); + history.push(`/${id}/hydrogeology/hydrotest`); }}> - + - + diff --git a/src/client/src/commons/menu/headerComponent.tsx b/src/client/src/commons/menu/headerComponent.tsx index 2e2a33e87..5b1b8551f 100644 --- a/src/client/src/commons/menu/headerComponent.tsx +++ b/src/client/src/commons/menu/headerComponent.tsx @@ -1,10 +1,10 @@ import { Box, Stack } from "@mui/material"; import { theme } from "../../AppTheme"; -import TranslationKeys from "../translationKeys"; import { VersionTag } from "./versionTag"; import { ProfilePopup } from "./profilePopup"; import { ReduxRootState, User } from "../../ReduxStateInterfaces"; import { useSelector } from "react-redux"; +import { LanguagePopup } from "./languagePopup.tsx"; const HeaderComponent = () => { const user: User = useSelector((state: ReduxRootState) => state.core_user); @@ -31,7 +31,7 @@ const HeaderComponent = () => { - + diff --git a/src/client/src/commons/menu/languagePopup.tsx b/src/client/src/commons/menu/languagePopup.tsx new file mode 100644 index 000000000..22e4513a2 --- /dev/null +++ b/src/client/src/commons/menu/languagePopup.tsx @@ -0,0 +1,106 @@ +import { Button, List, ListItem, ListItemIcon, ListItemText, Popover } from "@mui/material"; +import { theme } from "../../AppTheme.ts"; +import { MouseEvent, useEffect, useState } from "react"; +import CheckIcon from "@mui/icons-material/Check"; +import ArrowDownIcon from "../../../public/icons/arrow_down.svg?react"; +import ArrowUpIcon from "../../../public/icons/arrow_up.svg?react"; +import i18n from "../../i18n"; + +const languages = ["de", "fr", "it", "en"]; + +export function LanguagePopup() { + const [selectedLanguage, setSelectedLanguage] = useState(languages[0]); + const [anchorEl, setAnchorEl] = useState(); + const isOpen = Boolean(anchorEl); + + const handleClick = (event: MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(undefined); + }; + + useEffect(() => { + const handleLanguageChange = () => { + const languageIndex = languages.indexOf(i18n.language); + if (languageIndex !== -1) { + setSelectedLanguage(languages[languageIndex]); + } else { + setSelectedLanguage(languages[0]); + } + }; + + i18n.on("languageChanged", handleLanguageChange); + + return () => { + i18n.off("languageChanged", handleLanguageChange); + }; + }, []); + + const onLanguageChanged = (language: string) => { + i18n.changeLanguage(language); + handleClose(); + }; + + return ( + <> + + + + {languages.map(language => ( + { + onLanguageChanged(language); + }} + sx={{ + cursor: "pointer", + "&:hover": { backgroundColor: theme.palette.background.lightgrey }, + }}> + {selectedLanguage === language && ( + + + + )} + + {language.toUpperCase()} + + + ))} + + + + ); +} diff --git a/src/client/src/commons/menu/mainView/bottomBar.tsx b/src/client/src/commons/menu/mainView/bottomBar.tsx index 5b0bec1b9..2da119337 100644 --- a/src/client/src/commons/menu/mainView/bottomBar.tsx +++ b/src/client/src/commons/menu/mainView/bottomBar.tsx @@ -1,6 +1,6 @@ import { Box, Button } from "@mui/material"; -import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; -import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import ArrowDownIcon from "../../../../public/icons/arrow_down.svg?react"; +import ArrowUpIcon from "../../../../public/icons/arrow_up.svg?react"; import { BottomBarProps } from "./menuComponents/menuComponentInterfaces"; import { BoreholeNumbersPreview } from "./menuComponents/boreholeNumbersPreview"; import { useTranslation } from "react-i18next"; @@ -27,17 +27,9 @@ const BottomBar = ({ toggleBottomDrawer, bottomDrawerOpen, boreholes }: BottomBa ); diff --git a/src/client/src/commons/menu/mainView/mainSideNav.tsx b/src/client/src/commons/menu/mainView/mainSideNav.tsx index 9314c0442..c6d67a979 100644 --- a/src/client/src/commons/menu/mainView/mainSideNav.tsx +++ b/src/client/src/commons/menu/mainView/mainSideNav.tsx @@ -1,7 +1,7 @@ import { useContext, useEffect, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useHistory } from "react-router-dom"; -import { Badge, IconButton, Stack } from "@mui/material"; +import { Badge, Stack } from "@mui/material"; import { ImportErrorModal } from "./menuComponents/importErrorModal"; import FilterIcon from "../../../../public/icons/filter.svg?react"; import AddIcon from "../../../../public/icons/add.svg?react"; @@ -10,27 +10,13 @@ import SettingsIcon from "../../../../public/icons/settings.svg?react"; import HelpIcon from "../../../../public/icons/help.svg?react"; import LayersIcon from "../../../../public/icons/layers.svg?react"; import { theme } from "../../../AppTheme"; -import { styled } from "@mui/system"; import ImportModal from "./actions/importModal"; import { DrawerContentTypes } from "../../../pages/editor/editorComponentInterfaces"; import { ErrorResponse, MainSideNavProps } from "./menuComponents/menuComponentInterfaces"; import { ReduxRootState, User } from "../../../ReduxStateInterfaces"; import { FilterContext } from "../../../components/filter/filterContext"; - -const StyledIconButton = styled(IconButton)({ - padding: "10px", - marginBottom: "25px", - color: theme.palette.neutral.contrastText, - "&:hover": { - backgroundColor: theme.palette.background.lightgrey, - }, - borderRadius: "10px", -}); - -const selectedButtonStyle = { - color: theme.palette.primary.contrastText, - backgroundColor: theme.palette.background.menuItemActive + " !important", -}; +import { useTranslation } from "react-i18next"; +import { NavButton } from "../../../components/buttons/navButton"; const MainSideNav = ({ toggleDrawer, @@ -44,6 +30,7 @@ const MainSideNav = ({ }: MainSideNavProps) => { const history = useHistory(); const menuRef = useRef(null); + const { t } = useTranslation(); const [creating, setCreating] = useState(false); const [modal, setModal] = useState(false); const [upload, setUpload] = useState(false); @@ -112,47 +99,58 @@ const MainSideNav = ({ padding: "1em", flex: "1 1 100%", }}> - {activeFilterCount > 0 && } - 0 && } + } + label={t("searchfilters")} + selected={isFilterPanelVisible} onClick={handleToggleFilter} - sx={isFilterPanelVisible ? selectedButtonStyle : {}}> - - - + } + label={t("add")} + selected={isAddPanelVisible} disabled={user.data.roles.indexOf("EDIT") === -1} - sx={isAddPanelVisible ? selectedButtonStyle : {}}> - - - + } + label={t("upload")} + disabled={user.data.roles.indexOf("EDIT") === -1} onClick={() => { + toggleDrawer(false); setModal(true); setUpload(true); }} - disabled={user.data.roles.indexOf("EDIT") === -1}> - - - + } + label={t("usersMap")} + selected={isLayersPanelVisible} onClick={handleToggleLayers} - sx={isLayersPanelVisible ? selectedButtonStyle : {}}> - - + /> - history.push(`/setting`)}> - - - - window.open(`/help`)} /> - + } + label={t("header_settings")} + onClick={() => history.push(`/setting`)} + /> + } + label={t("header_help")} + onClick={() => window.open(`/help`)} + /> { return ( - + {this.state?.searchList?.map((filter, idx) => { @@ -237,7 +238,7 @@ class FilterComponent extends React.Component { return ( } + expandIcon={} onClick={() => { this.setState(prevState => ({ ...prevState, @@ -246,10 +247,8 @@ class FilterComponent extends React.Component { ), })); }}> - - {t(filter?.translationId)}{" "} - - + {t(filter?.translationId)} + {filter?.name === "workgroup" && filter?.isSelected && ( diff --git a/src/client/src/components/basemapSelector/basemaps.ts b/src/client/src/components/basemapSelector/basemaps.ts index d734c33ee..608e1a09b 100644 --- a/src/client/src/components/basemapSelector/basemaps.ts +++ b/src/client/src/components/basemapSelector/basemaps.ts @@ -22,12 +22,11 @@ export const basemaps: Basemap[] = [ { name: "ch.swisstopo.pixelkarte-farbe", layer: new TileLayer({ - minResolution: 0.1, - maxZoom: 27, properties: { name: "ch.swisstopo.pixelkarte-farbe", }, source: new XYZ({ + maxZoom: 19, cacheSize: 2048 * 3, // increase initial cache size, as seen in map.geo.admin url: `https://wmts100.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/3857/{z}/{x}/{y}.jpeg`, crossOrigin, @@ -38,12 +37,11 @@ export const basemaps: Basemap[] = [ { name: "ch.swisstopo.swissimage", layer: new TileLayer({ - minResolution: 0.1, - maxZoom: 27, properties: { name: "ch.swisstopo.swissimage", }, source: new XYZ({ + maxZoom: 20, cacheSize: 2048 * 3, // increase initial cache size, as seen in map.geo.admin url: `https://wmts100.geo.admin.ch/1.0.0/ch.swisstopo.swissimage/default/current/3857/{z}/{x}/{y}.jpeg`, crossOrigin, @@ -54,12 +52,11 @@ export const basemaps: Basemap[] = [ { name: "ch.swisstopo.pixelkarte-grau", layer: new TileLayer({ - minResolution: 0.1, - maxZoom: 27, properties: { name: "ch.swisstopo.pixelkarte-grau", }, source: new XYZ({ + maxZoom: 19, cacheSize: 2048 * 3, // increase initial cache size, as seen in map.geo.admin url: `https://wmts100.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-grau/default/current/3857/{z}/{x}/{y}.jpeg`, crossOrigin, diff --git a/src/client/src/components/buttons/buttons.tsx b/src/client/src/components/buttons/buttons.tsx index 07b2208b5..cc128803d 100644 --- a/src/client/src/components/buttons/buttons.tsx +++ b/src/client/src/components/buttons/buttons.tsx @@ -15,7 +15,7 @@ export const BdmsBaseButton = forwardRef((props,