From 6714508133a1f842923678162612f1e6a589cc6c Mon Sep 17 00:00:00 2001 From: Mirko Sekulic Date: Fri, 20 Dec 2024 09:00:28 +0100 Subject: [PATCH 01/10] feat: serialize nillable copmlex types as nil (#14320) --- .../Csharp/JsonMetadataToCsharpConverter.cs | 2 +- testdata/Model/CSharp/Gitea/krt-1188a-1.cs | 64 +++++++++---------- .../CSharp/Gitea/srf-fufinn-behovsendring.cs | 54 ++++++++-------- .../Gitea/srf-fufinn-behovskartleggin.cs | 54 ++++++++-------- .../Gitea/srf-melding-til-statsforvalteren.cs | 18 +++--- .../XsAll/ferdigattest/v4/ferdigattest.cs | 50 +++++++-------- .../v4/igangsettingstillatelse.cs | 44 ++++++------- .../v4/midlertidigbrukstillatelse.cs | 50 +++++++-------- .../CSharp/XsAll/planvarsel/v2/planvarsel.cs | 30 ++++----- .../XsAll/xsall-example-nillable-sample.xml | 1 + .../Model/XmlSchema/XsAll/xsall-example.xsd | 7 ++ 11 files changed, 191 insertions(+), 183 deletions(-) diff --git a/backend/src/DataModeling/Converter/Csharp/JsonMetadataToCsharpConverter.cs b/backend/src/DataModeling/Converter/Csharp/JsonMetadataToCsharpConverter.cs index 938e0ada84b..2d4791185a7 100644 --- a/backend/src/DataModeling/Converter/Csharp/JsonMetadataToCsharpConverter.cs +++ b/backend/src/DataModeling/Converter/Csharp/JsonMetadataToCsharpConverter.cs @@ -223,7 +223,7 @@ private void ParseGroupProperty(ElementMetadata element, StringBuilder classBuil var nullableReference = useNullableReferenceTypes ? "?" : string.Empty; WriteRestrictionAnnotations(classBuilder, element); elementOrder += 1; - AddXmlElementAnnotation(element, classBuilder, elementOrder); + AddXmlElementAnnotation(element, classBuilder, elementOrder, element.Nillable ?? false); // Temporary fix - as long as we use System.Text.Json for serialization and Newtonsoft.Json for // deserialization, we need both JsonProperty and JsonPropertyName annotations. diff --git a/testdata/Model/CSharp/Gitea/krt-1188a-1.cs b/testdata/Model/CSharp/Gitea/krt-1188a-1.cs index 29c1f0bb226..29771886bcc 100644 --- a/testdata/Model/CSharp/Gitea/krt-1188a-1.cs +++ b/testdata/Model/CSharp/Gitea/krt-1188a-1.cs @@ -33,12 +33,12 @@ public class KRT1226Gjenopprettingsplaner_M public class rapport { - [XmlElement("innsender", Order = 1)] + [XmlElement("innsender", Order = 1, IsNullable = true)] [JsonProperty("innsender")] [JsonPropertyName("innsender")] public Innsender innsender { get; set; } - [XmlElement("rapportering", Order = 2)] + [XmlElement("rapportering", Order = 2, IsNullable = true)] [JsonProperty("rapportering")] [JsonPropertyName("rapportering")] public Rapportering rapportering { get; set; } @@ -47,17 +47,17 @@ public class rapport public class Innsender { - [XmlElement("adresse", Order = 1)] + [XmlElement("adresse", Order = 1, IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public Adresse adresse { get; set; } - [XmlElement("foretak", Order = 2)] + [XmlElement("foretak", Order = 2, IsNullable = true)] [JsonProperty("foretak")] [JsonPropertyName("foretak")] public Foretak foretak { get; set; } - [XmlElement("maalform", Order = 3)] + [XmlElement("maalform", Order = 3, IsNullable = true)] [JsonProperty("maalform")] [JsonPropertyName("maalform")] public Maalform maalform { get; set; } @@ -68,21 +68,21 @@ public class Innsender public class Adresse { - [XmlElement("postnummer", Order = 1)] + [XmlElement("postnummer", Order = 1, IsNullable = true)] [JsonProperty("postnummer")] [JsonPropertyName("postnummer")] public Postnummer postnummer { get; set; } public bool ShouldSerializepostnummer() => postnummer?.value is not null; - [XmlElement("adresselinje1", Order = 2)] + [XmlElement("adresselinje1", Order = 2, IsNullable = true)] [JsonProperty("adresselinje1")] [JsonPropertyName("adresselinje1")] public Adresselinje1 adresselinje1 { get; set; } public bool ShouldSerializeadresselinje1() => adresselinje1?.value is not null; - [XmlElement("poststed", Order = 3)] + [XmlElement("poststed", Order = 3, IsNullable = true)] [JsonProperty("poststed")] [JsonPropertyName("poststed")] public Poststed poststed { get; set; } @@ -129,14 +129,14 @@ public class Poststed public class Foretak { - [XmlElement("organisasjonsnummer", Order = 1)] + [XmlElement("organisasjonsnummer", Order = 1, IsNullable = true)] [JsonProperty("organisasjonsnummer")] [JsonPropertyName("organisasjonsnummer")] public Organisasjonsnummer organisasjonsnummer { get; set; } public bool ShouldSerializeorganisasjonsnummer() => organisasjonsnummer?.value is not null; - [XmlElement("navn", Order = 2)] + [XmlElement("navn", Order = 2, IsNullable = true)] [JsonProperty("navn")] [JsonPropertyName("navn")] public Foretaksnavn navn { get; set; } @@ -199,60 +199,60 @@ public decimal value public class Rapportering { - [XmlElement("arkiv", Order = 1)] + [XmlElement("arkiv", Order = 1, IsNullable = true)] [JsonProperty("arkiv")] [JsonPropertyName("arkiv")] public Arkiv arkiv { get; set; } - [XmlElement("kontaktperson1", Order = 2)] + [XmlElement("kontaktperson1", Order = 2, IsNullable = true)] [JsonProperty("kontaktperson1")] [JsonPropertyName("kontaktperson1")] public Kontaktperson1 kontaktperson1 { get; set; } - [XmlElement("kontaktperson2", Order = 3)] + [XmlElement("kontaktperson2", Order = 3, IsNullable = true)] [JsonProperty("kontaktperson2")] [JsonPropertyName("kontaktperson2")] public Kontaktperson2 kontaktperson2 { get; set; } - [XmlElement("periode", Order = 4)] + [XmlElement("periode", Order = 4, IsNullable = true)] [JsonProperty("periode")] [JsonPropertyName("periode")] public Periode periode { get; set; } - [XmlElement("rapporteringsregisteret", Order = 5)] + [XmlElement("rapporteringsregisteret", Order = 5, IsNullable = true)] [JsonProperty("rapporteringsregisteret")] [JsonPropertyName("rapporteringsregisteret")] public Rapporteringsregisteret rapporteringsregisteret { get; set; } - [XmlElement("sporvalgrappreg", Order = 6)] + [XmlElement("sporvalgrappreg", Order = 6, IsNullable = true)] [JsonProperty("sporvalgrappreg")] [JsonPropertyName("sporvalgrappreg")] public Tekst_60_S1 sporvalgrappreg { get; set; } public bool ShouldSerializesporvalgrappreg() => sporvalgrappreg?.value is not null; - [XmlElement("hjelpefelt", Order = 7)] + [XmlElement("hjelpefelt", Order = 7, IsNullable = true)] [JsonProperty("hjelpefelt")] [JsonPropertyName("hjelpefelt")] public Tekst_120_S01 hjelpefelt { get; set; } public bool ShouldSerializehjelpefelt() => hjelpefelt?.value is not null; - [XmlElement("avdeling", Order = 8)] + [XmlElement("avdeling", Order = 8, IsNullable = true)] [JsonProperty("avdeling")] [JsonPropertyName("avdeling")] public Avdeling avdeling { get; set; } public bool ShouldSerializeavdeling() => avdeling?.value is not null; - [XmlElement("beskrivelse", Order = 9)] + [XmlElement("beskrivelse", Order = 9, IsNullable = true)] [JsonProperty("beskrivelse")] [JsonPropertyName("beskrivelse")] public Tekst_255_S10 beskrivelse { get; set; } public bool ShouldSerializebeskrivelse() => beskrivelse?.value is not null; - [XmlElement("periodeaarstall", Order = 10)] + [XmlElement("periodeaarstall", Order = 10, IsNullable = true)] [JsonProperty("periodeaarstall")] [JsonPropertyName("periodeaarstall")] public AAr_S01 periodeaarstall { get; set; } @@ -263,7 +263,7 @@ public class Rapportering public class Arkiv { - [XmlElement("arkivkode", Order = 1)] + [XmlElement("arkivkode", Order = 1, IsNullable = true)] [JsonProperty("arkivkode")] [JsonPropertyName("arkivkode")] public Arkivkode arkivkode { get; set; } @@ -285,28 +285,28 @@ public class Arkivkode public class Kontaktperson1 { - [XmlElement("epost", Order = 1)] + [XmlElement("epost", Order = 1, IsNullable = true)] [JsonProperty("epost")] [JsonPropertyName("epost")] public Epost_S01 epost { get; set; } public bool ShouldSerializeepost() => epost?.value is not null; - [XmlElement("navn", Order = 2)] + [XmlElement("navn", Order = 2, IsNullable = true)] [JsonProperty("navn")] [JsonPropertyName("navn")] public Navn_S01 navn { get; set; } public bool ShouldSerializenavn() => navn?.value is not null; - [XmlElement("telefonnummer", Order = 3)] + [XmlElement("telefonnummer", Order = 3, IsNullable = true)] [JsonProperty("telefonnummer")] [JsonPropertyName("telefonnummer")] public TelefonNummer_S01 telefonnummer { get; set; } public bool ShouldSerializetelefonnummer() => telefonnummer?.value is not null; - [XmlElement("telefonprefiks", Order = 4)] + [XmlElement("telefonprefiks", Order = 4, IsNullable = true)] [JsonProperty("telefonprefiks")] [JsonPropertyName("telefonprefiks")] public TelefonPrefiks_S01 telefonprefiks { get; set; } @@ -364,28 +364,28 @@ public class TelefonPrefiks_S01 public class Kontaktperson2 { - [XmlElement("epost", Order = 1)] + [XmlElement("epost", Order = 1, IsNullable = true)] [JsonProperty("epost")] [JsonPropertyName("epost")] public Epost_S02 epost { get; set; } public bool ShouldSerializeepost() => epost?.value is not null; - [XmlElement("navn", Order = 2)] + [XmlElement("navn", Order = 2, IsNullable = true)] [JsonProperty("navn")] [JsonPropertyName("navn")] public Navn_S02 navn { get; set; } public bool ShouldSerializenavn() => navn?.value is not null; - [XmlElement("telefonnummer", Order = 3)] + [XmlElement("telefonnummer", Order = 3, IsNullable = true)] [JsonProperty("telefonnummer")] [JsonPropertyName("telefonnummer")] public TelefonNummer_S02 telefonnummer { get; set; } public bool ShouldSerializetelefonnummer() => telefonnummer?.value is not null; - [XmlElement("telefonprefiks", Order = 4)] + [XmlElement("telefonprefiks", Order = 4, IsNullable = true)] [JsonProperty("telefonprefiks")] [JsonPropertyName("telefonprefiks")] public TelefonPrefiks_S02 telefonprefiks { get; set; } @@ -443,14 +443,14 @@ public class TelefonPrefiks_S02 public class Periode { - [XmlElement("aar", Order = 1)] + [XmlElement("aar", Order = 1, IsNullable = true)] [JsonProperty("aar")] [JsonPropertyName("aar")] public AAr aar { get; set; } public bool ShouldSerializeaar() => aar?.value is not null; - [XmlElement("periodetype", Order = 2)] + [XmlElement("periodetype", Order = 2, IsNullable = true)] [JsonProperty("periodetype")] [JsonPropertyName("periodetype")] public Periodetype periodetype { get; set; } @@ -484,7 +484,7 @@ public class Periodetype public class Rapporteringsregisteret { - [XmlElement("rapporteringsid", Order = 1)] + [XmlElement("rapporteringsid", Order = 1, IsNullable = true)] [JsonProperty("rapporteringsid")] [JsonPropertyName("rapporteringsid")] public Rapporteringsid rapporteringsid { get; set; } diff --git a/testdata/Model/CSharp/Gitea/srf-fufinn-behovsendring.cs b/testdata/Model/CSharp/Gitea/srf-fufinn-behovsendring.cs index 85955e6e01b..5877f59879c 100644 --- a/testdata/Model/CSharp/Gitea/srf-fufinn-behovsendring.cs +++ b/testdata/Model/CSharp/Gitea/srf-fufinn-behovsendring.cs @@ -26,22 +26,22 @@ public class Fufinn public class Felles { - [XmlElement("innsenderPerson", Order = 1)] + [XmlElement("innsenderPerson", Order = 1, IsNullable = true)] [JsonProperty("innsenderPerson")] [JsonPropertyName("innsenderPerson")] public InnsenderPerson innsenderPerson { get; set; } - [XmlElement("innsenderOrganisasjon", Order = 2)] + [XmlElement("innsenderOrganisasjon", Order = 2, IsNullable = true)] [JsonProperty("innsenderOrganisasjon")] [JsonPropertyName("innsenderOrganisasjon")] public InnsenderOrganisasjon innsenderOrganisasjon { get; set; } - [XmlElement("hvemGjelderHenvendelsen", Order = 3)] + [XmlElement("hvemGjelderHenvendelsen", Order = 3, IsNullable = true)] [JsonProperty("hvemGjelderHenvendelsen")] [JsonPropertyName("hvemGjelderHenvendelsen")] public HvemGjelderHenvendelsen hvemGjelderHenvendelsen { get; set; } - [XmlElement("hvorSkalHenvendelsenSendes", Order = 4)] + [XmlElement("hvorSkalHenvendelsenSendes", Order = 4, IsNullable = true)] [JsonProperty("hvorSkalHenvendelsenSendes")] [JsonPropertyName("hvorSkalHenvendelsenSendes")] public HvorSkalHenvendelsenSendes hvorSkalHenvendelsenSendes { get; set; } @@ -55,12 +55,12 @@ public class InnsenderPerson [JsonPropertyName("navn")] public string navn { get; set; } - [XmlElement("bostedsadresse", Order = 2)] + [XmlElement("bostedsadresse", Order = 2, IsNullable = true)] [JsonProperty("bostedsadresse")] [JsonPropertyName("bostedsadresse")] public Adresse bostedsadresse { get; set; } - [XmlElement("postadresse", Order = 3)] + [XmlElement("postadresse", Order = 3, IsNullable = true)] [JsonProperty("postadresse")] [JsonPropertyName("postadresse")] public Adresse postadresse { get; set; } @@ -132,12 +132,12 @@ public class InnsenderOrganisasjon [JsonPropertyName("organisasjonsnummer")] public string organisasjonsnummer { get; set; } - [XmlElement("postadresse", Order = 4)] + [XmlElement("postadresse", Order = 4, IsNullable = true)] [JsonProperty("postadresse")] [JsonPropertyName("postadresse")] public Adresse postadresse { get; set; } - [XmlElement("forretningsadresse", Order = 5)] + [XmlElement("forretningsadresse", Order = 5, IsNullable = true)] [JsonProperty("forretningsadresse")] [JsonPropertyName("forretningsadresse")] public Adresse forretningsadresse { get; set; } @@ -193,92 +193,92 @@ public class SkjemaSpesifikt [JsonPropertyName("andreBehov")] public string andreBehov { get; set; } - [XmlElement("bank", Order = 2)] + [XmlElement("bank", Order = 2, IsNullable = true)] [JsonProperty("bank")] [JsonPropertyName("bank")] public Bank bank { get; set; } - [XmlElement("forsikringsselskap", Order = 3)] + [XmlElement("forsikringsselskap", Order = 3, IsNullable = true)] [JsonProperty("forsikringsselskap")] [JsonPropertyName("forsikringsselskap")] public Forsikringsselskap forsikringsselskap { get; set; } - [XmlElement("helfo", Order = 4)] + [XmlElement("helfo", Order = 4, IsNullable = true)] [JsonProperty("helfo")] [JsonPropertyName("helfo")] public Helfo helfo { get; set; } - [XmlElement("husbanken", Order = 5)] + [XmlElement("husbanken", Order = 5, IsNullable = true)] [JsonProperty("husbanken")] [JsonPropertyName("husbanken")] public Husbanken husbanken { get; set; } - [XmlElement("inkassoselskap", Order = 6)] + [XmlElement("inkassoselskap", Order = 6, IsNullable = true)] [JsonProperty("inkassoselskap")] [JsonPropertyName("inkassoselskap")] public Inkassoselskap inkassoselskap { get; set; } - [XmlElement("innkreving", Order = 7)] + [XmlElement("innkreving", Order = 7, IsNullable = true)] [JsonProperty("innkreving")] [JsonPropertyName("innkreving")] public Innkreving innkreving { get; set; } - [XmlElement("kartverket", Order = 8)] + [XmlElement("kartverket", Order = 8, IsNullable = true)] [JsonProperty("kartverket")] [JsonPropertyName("kartverket")] public Kartverket kartverket { get; set; } - [XmlElement("kommune", Order = 9)] + [XmlElement("kommune", Order = 9, IsNullable = true)] [JsonProperty("kommune")] [JsonPropertyName("kommune")] public Kommune kommune { get; set; } - [XmlElement("kredittvurderingsselskap", Order = 10)] + [XmlElement("kredittvurderingsselskap", Order = 10, IsNullable = true)] [JsonProperty("kredittvurderingsselskap")] [JsonPropertyName("kredittvurderingsselskap")] public Kredittvurderingsselskap kredittvurderingsselskap { get; set; } - [XmlElement("namsmannen", Order = 11)] + [XmlElement("namsmannen", Order = 11, IsNullable = true)] [JsonProperty("namsmannen")] [JsonPropertyName("namsmannen")] public Namsmannen namsmannen { get; set; } - [XmlElement("nav", Order = 12)] + [XmlElement("nav", Order = 12, IsNullable = true)] [JsonProperty("nav")] [JsonPropertyName("nav")] public Nav nav { get; set; } - [XmlElement("pasientreiser", Order = 13)] + [XmlElement("pasientreiser", Order = 13, IsNullable = true)] [JsonProperty("pasientreiser")] [JsonPropertyName("pasientreiser")] public Pasientreiser pasientreiser { get; set; } - [XmlElement("skatteetaten", Order = 14)] + [XmlElement("skatteetaten", Order = 14, IsNullable = true)] [JsonProperty("skatteetaten")] [JsonPropertyName("skatteetaten")] public Skatteetaten skatteetaten { get; set; } - [XmlElement("tingretten", Order = 15)] + [XmlElement("tingretten", Order = 15, IsNullable = true)] [JsonProperty("tingretten")] [JsonPropertyName("tingretten")] public Tingretten tingretten { get; set; } - [XmlElement("oevrige", Order = 16)] + [XmlElement("oevrige", Order = 16, IsNullable = true)] [JsonProperty("oevrige")] [JsonPropertyName("oevrige")] public OEvrige oevrige { get; set; } - [XmlElement("statsforvalter", Order = 17)] + [XmlElement("statsforvalter", Order = 17, IsNullable = true)] [JsonProperty("statsforvalter")] [JsonPropertyName("statsforvalter")] public Statsforvalter statsforvalter { get; set; } - [XmlElement("vergehaver", Order = 18)] + [XmlElement("vergehaver", Order = 18, IsNullable = true)] [JsonProperty("vergehaver")] [JsonPropertyName("vergehaver")] public Vergehaver vergehaver { get; set; } - [XmlElement("hjelpeapparat", Order = 19)] + [XmlElement("hjelpeapparat", Order = 19, IsNullable = true)] [JsonProperty("hjelpeapparat")] [JsonPropertyName("hjelpeapparat")] public Hjelpeapparat hjelpeapparat { get; set; } @@ -601,7 +601,7 @@ public class Vergehaver [JsonPropertyName("hvilkenInstitusjon")] public string hvilkenInstitusjon { get; set; } - [XmlElement("adresse", Order = 5)] + [XmlElement("adresse", Order = 5, IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public Adresse adresse { get; set; } diff --git a/testdata/Model/CSharp/Gitea/srf-fufinn-behovskartleggin.cs b/testdata/Model/CSharp/Gitea/srf-fufinn-behovskartleggin.cs index 85955e6e01b..5877f59879c 100644 --- a/testdata/Model/CSharp/Gitea/srf-fufinn-behovskartleggin.cs +++ b/testdata/Model/CSharp/Gitea/srf-fufinn-behovskartleggin.cs @@ -26,22 +26,22 @@ public class Fufinn public class Felles { - [XmlElement("innsenderPerson", Order = 1)] + [XmlElement("innsenderPerson", Order = 1, IsNullable = true)] [JsonProperty("innsenderPerson")] [JsonPropertyName("innsenderPerson")] public InnsenderPerson innsenderPerson { get; set; } - [XmlElement("innsenderOrganisasjon", Order = 2)] + [XmlElement("innsenderOrganisasjon", Order = 2, IsNullable = true)] [JsonProperty("innsenderOrganisasjon")] [JsonPropertyName("innsenderOrganisasjon")] public InnsenderOrganisasjon innsenderOrganisasjon { get; set; } - [XmlElement("hvemGjelderHenvendelsen", Order = 3)] + [XmlElement("hvemGjelderHenvendelsen", Order = 3, IsNullable = true)] [JsonProperty("hvemGjelderHenvendelsen")] [JsonPropertyName("hvemGjelderHenvendelsen")] public HvemGjelderHenvendelsen hvemGjelderHenvendelsen { get; set; } - [XmlElement("hvorSkalHenvendelsenSendes", Order = 4)] + [XmlElement("hvorSkalHenvendelsenSendes", Order = 4, IsNullable = true)] [JsonProperty("hvorSkalHenvendelsenSendes")] [JsonPropertyName("hvorSkalHenvendelsenSendes")] public HvorSkalHenvendelsenSendes hvorSkalHenvendelsenSendes { get; set; } @@ -55,12 +55,12 @@ public class InnsenderPerson [JsonPropertyName("navn")] public string navn { get; set; } - [XmlElement("bostedsadresse", Order = 2)] + [XmlElement("bostedsadresse", Order = 2, IsNullable = true)] [JsonProperty("bostedsadresse")] [JsonPropertyName("bostedsadresse")] public Adresse bostedsadresse { get; set; } - [XmlElement("postadresse", Order = 3)] + [XmlElement("postadresse", Order = 3, IsNullable = true)] [JsonProperty("postadresse")] [JsonPropertyName("postadresse")] public Adresse postadresse { get; set; } @@ -132,12 +132,12 @@ public class InnsenderOrganisasjon [JsonPropertyName("organisasjonsnummer")] public string organisasjonsnummer { get; set; } - [XmlElement("postadresse", Order = 4)] + [XmlElement("postadresse", Order = 4, IsNullable = true)] [JsonProperty("postadresse")] [JsonPropertyName("postadresse")] public Adresse postadresse { get; set; } - [XmlElement("forretningsadresse", Order = 5)] + [XmlElement("forretningsadresse", Order = 5, IsNullable = true)] [JsonProperty("forretningsadresse")] [JsonPropertyName("forretningsadresse")] public Adresse forretningsadresse { get; set; } @@ -193,92 +193,92 @@ public class SkjemaSpesifikt [JsonPropertyName("andreBehov")] public string andreBehov { get; set; } - [XmlElement("bank", Order = 2)] + [XmlElement("bank", Order = 2, IsNullable = true)] [JsonProperty("bank")] [JsonPropertyName("bank")] public Bank bank { get; set; } - [XmlElement("forsikringsselskap", Order = 3)] + [XmlElement("forsikringsselskap", Order = 3, IsNullable = true)] [JsonProperty("forsikringsselskap")] [JsonPropertyName("forsikringsselskap")] public Forsikringsselskap forsikringsselskap { get; set; } - [XmlElement("helfo", Order = 4)] + [XmlElement("helfo", Order = 4, IsNullable = true)] [JsonProperty("helfo")] [JsonPropertyName("helfo")] public Helfo helfo { get; set; } - [XmlElement("husbanken", Order = 5)] + [XmlElement("husbanken", Order = 5, IsNullable = true)] [JsonProperty("husbanken")] [JsonPropertyName("husbanken")] public Husbanken husbanken { get; set; } - [XmlElement("inkassoselskap", Order = 6)] + [XmlElement("inkassoselskap", Order = 6, IsNullable = true)] [JsonProperty("inkassoselskap")] [JsonPropertyName("inkassoselskap")] public Inkassoselskap inkassoselskap { get; set; } - [XmlElement("innkreving", Order = 7)] + [XmlElement("innkreving", Order = 7, IsNullable = true)] [JsonProperty("innkreving")] [JsonPropertyName("innkreving")] public Innkreving innkreving { get; set; } - [XmlElement("kartverket", Order = 8)] + [XmlElement("kartverket", Order = 8, IsNullable = true)] [JsonProperty("kartverket")] [JsonPropertyName("kartverket")] public Kartverket kartverket { get; set; } - [XmlElement("kommune", Order = 9)] + [XmlElement("kommune", Order = 9, IsNullable = true)] [JsonProperty("kommune")] [JsonPropertyName("kommune")] public Kommune kommune { get; set; } - [XmlElement("kredittvurderingsselskap", Order = 10)] + [XmlElement("kredittvurderingsselskap", Order = 10, IsNullable = true)] [JsonProperty("kredittvurderingsselskap")] [JsonPropertyName("kredittvurderingsselskap")] public Kredittvurderingsselskap kredittvurderingsselskap { get; set; } - [XmlElement("namsmannen", Order = 11)] + [XmlElement("namsmannen", Order = 11, IsNullable = true)] [JsonProperty("namsmannen")] [JsonPropertyName("namsmannen")] public Namsmannen namsmannen { get; set; } - [XmlElement("nav", Order = 12)] + [XmlElement("nav", Order = 12, IsNullable = true)] [JsonProperty("nav")] [JsonPropertyName("nav")] public Nav nav { get; set; } - [XmlElement("pasientreiser", Order = 13)] + [XmlElement("pasientreiser", Order = 13, IsNullable = true)] [JsonProperty("pasientreiser")] [JsonPropertyName("pasientreiser")] public Pasientreiser pasientreiser { get; set; } - [XmlElement("skatteetaten", Order = 14)] + [XmlElement("skatteetaten", Order = 14, IsNullable = true)] [JsonProperty("skatteetaten")] [JsonPropertyName("skatteetaten")] public Skatteetaten skatteetaten { get; set; } - [XmlElement("tingretten", Order = 15)] + [XmlElement("tingretten", Order = 15, IsNullable = true)] [JsonProperty("tingretten")] [JsonPropertyName("tingretten")] public Tingretten tingretten { get; set; } - [XmlElement("oevrige", Order = 16)] + [XmlElement("oevrige", Order = 16, IsNullable = true)] [JsonProperty("oevrige")] [JsonPropertyName("oevrige")] public OEvrige oevrige { get; set; } - [XmlElement("statsforvalter", Order = 17)] + [XmlElement("statsforvalter", Order = 17, IsNullable = true)] [JsonProperty("statsforvalter")] [JsonPropertyName("statsforvalter")] public Statsforvalter statsforvalter { get; set; } - [XmlElement("vergehaver", Order = 18)] + [XmlElement("vergehaver", Order = 18, IsNullable = true)] [JsonProperty("vergehaver")] [JsonPropertyName("vergehaver")] public Vergehaver vergehaver { get; set; } - [XmlElement("hjelpeapparat", Order = 19)] + [XmlElement("hjelpeapparat", Order = 19, IsNullable = true)] [JsonProperty("hjelpeapparat")] [JsonPropertyName("hjelpeapparat")] public Hjelpeapparat hjelpeapparat { get; set; } @@ -601,7 +601,7 @@ public class Vergehaver [JsonPropertyName("hvilkenInstitusjon")] public string hvilkenInstitusjon { get; set; } - [XmlElement("adresse", Order = 5)] + [XmlElement("adresse", Order = 5, IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public Adresse adresse { get; set; } diff --git a/testdata/Model/CSharp/Gitea/srf-melding-til-statsforvalteren.cs b/testdata/Model/CSharp/Gitea/srf-melding-til-statsforvalteren.cs index 196ac7c59c0..4357f3c8b94 100644 --- a/testdata/Model/CSharp/Gitea/srf-melding-til-statsforvalteren.cs +++ b/testdata/Model/CSharp/Gitea/srf-melding-til-statsforvalteren.cs @@ -26,22 +26,22 @@ public class MeldingTilStatsforvalteren public class Felles { - [XmlElement("innsenderPerson", Order = 1)] + [XmlElement("innsenderPerson", Order = 1, IsNullable = true)] [JsonProperty("innsenderPerson")] [JsonPropertyName("innsenderPerson")] public InnsenderPerson innsenderPerson { get; set; } - [XmlElement("innsenderOrganisasjon", Order = 2)] + [XmlElement("innsenderOrganisasjon", Order = 2, IsNullable = true)] [JsonProperty("innsenderOrganisasjon")] [JsonPropertyName("innsenderOrganisasjon")] public InnsenderOrganisasjon innsenderOrganisasjon { get; set; } - [XmlElement("hvemGjelderHenvendelsen", Order = 3)] + [XmlElement("hvemGjelderHenvendelsen", Order = 3, IsNullable = true)] [JsonProperty("hvemGjelderHenvendelsen")] [JsonPropertyName("hvemGjelderHenvendelsen")] public HvemGjelderHenvendelsen hvemGjelderHenvendelsen { get; set; } - [XmlElement("hvorSkalHenvendelsenSendes", Order = 4)] + [XmlElement("hvorSkalHenvendelsenSendes", Order = 4, IsNullable = true)] [JsonProperty("hvorSkalHenvendelsenSendes")] [JsonPropertyName("hvorSkalHenvendelsenSendes")] public HvorSkalHenvendelsenSendes hvorSkalHenvendelsenSendes { get; set; } @@ -55,12 +55,12 @@ public class InnsenderPerson [JsonPropertyName("navn")] public string navn { get; set; } - [XmlElement("bostedsadresse", Order = 2)] + [XmlElement("bostedsadresse", Order = 2, IsNullable = true)] [JsonProperty("bostedsadresse")] [JsonPropertyName("bostedsadresse")] public Adresse bostedsadresse { get; set; } - [XmlElement("postadresse", Order = 3)] + [XmlElement("postadresse", Order = 3, IsNullable = true)] [JsonProperty("postadresse")] [JsonPropertyName("postadresse")] public Adresse postadresse { get; set; } @@ -132,12 +132,12 @@ public class InnsenderOrganisasjon [JsonPropertyName("organisasjonsnummer")] public string organisasjonsnummer { get; set; } - [XmlElement("postadresse", Order = 4)] + [XmlElement("postadresse", Order = 4, IsNullable = true)] [JsonProperty("postadresse")] [JsonPropertyName("postadresse")] public Adresse postadresse { get; set; } - [XmlElement("forretningsadresse", Order = 5)] + [XmlElement("forretningsadresse", Order = 5, IsNullable = true)] [JsonProperty("forretningsadresse")] [JsonPropertyName("forretningsadresse")] public Adresse forretningsadresse { get; set; } @@ -188,7 +188,7 @@ public class HvorSkalHenvendelsenSendes public class SkjemaSpesifikt { - [XmlElement("hvaGjelderHenvendelsen", Order = 1)] + [XmlElement("hvaGjelderHenvendelsen", Order = 1, IsNullable = true)] [JsonProperty("hvaGjelderHenvendelsen")] [JsonPropertyName("hvaGjelderHenvendelsen")] public HvaGjelderHenvendelsen hvaGjelderHenvendelsen { get; set; } diff --git a/testdata/Model/CSharp/XsAll/ferdigattest/v4/ferdigattest.cs b/testdata/Model/CSharp/XsAll/ferdigattest/v4/ferdigattest.cs index 0c71433f931..1128bddd6b0 100644 --- a/testdata/Model/CSharp/XsAll/ferdigattest/v4/ferdigattest.cs +++ b/testdata/Model/CSharp/XsAll/ferdigattest/v4/ferdigattest.cs @@ -24,37 +24,37 @@ public class FerdigattestType [BindNever] public string dataFormatVersion { get; set; } = "4"; - [XmlElement("eiendomByggested")] + [XmlElement("eiendomByggested", IsNullable = true)] [JsonProperty("eiendomByggested")] [JsonPropertyName("eiendomByggested")] public EiendomListe eiendomByggested { get; set; } - [XmlElement("kommunensSaksnummer")] + [XmlElement("kommunensSaksnummer", IsNullable = true)] [JsonProperty("kommunensSaksnummer")] [JsonPropertyName("kommunensSaksnummer")] public SaksnummerType kommunensSaksnummer { get; set; } - [XmlElement("metadata")] + [XmlElement("metadata", IsNullable = true)] [JsonProperty("metadata")] [JsonPropertyName("metadata")] public MetadataType metadata { get; set; } - [XmlElement("generelleVilkaar")] + [XmlElement("generelleVilkaar", IsNullable = true)] [JsonProperty("generelleVilkaar")] [JsonPropertyName("generelleVilkaar")] public GenerelleVilkaarType generelleVilkaar { get; set; } - [XmlElement("soeknadGjelder")] + [XmlElement("soeknadGjelder", IsNullable = true)] [JsonProperty("soeknadGjelder")] [JsonPropertyName("soeknadGjelder")] public BeskrivelseAvTiltakType soeknadGjelder { get; set; } - [XmlElement("utfallBesvarelse")] + [XmlElement("utfallBesvarelse", IsNullable = true)] [JsonProperty("utfallBesvarelse")] [JsonPropertyName("utfallBesvarelse")] public UtfallSvarListe utfallBesvarelse { get; set; } - [XmlElement("kravFerdigattest")] + [XmlElement("kravFerdigattest", IsNullable = true)] [JsonProperty("kravFerdigattest")] [JsonPropertyName("kravFerdigattest")] public KravFerdigattestType kravFerdigattest { get; set; } @@ -69,22 +69,22 @@ public class FerdigattestType [JsonPropertyName("tilstrekkeligDokumentasjonOverlevertEier")] public bool? tilstrekkeligDokumentasjonOverlevertEier { get; set; } - [XmlElement("varmesystem")] + [XmlElement("varmesystem", IsNullable = true)] [JsonProperty("varmesystem")] [JsonPropertyName("varmesystem")] public VarmesystemType varmesystem { get; set; } - [XmlElement("tiltakshaver")] + [XmlElement("tiltakshaver", IsNullable = true)] [JsonProperty("tiltakshaver")] [JsonPropertyName("tiltakshaver")] public PartType tiltakshaver { get; set; } - [XmlElement("ansvarligSoeker")] + [XmlElement("ansvarligSoeker", IsNullable = true)] [JsonProperty("ansvarligSoeker")] [JsonPropertyName("ansvarligSoeker")] public PartType ansvarligSoeker { get; set; } - [XmlElement("ansvarForByggesaken")] + [XmlElement("ansvarForByggesaken", IsNullable = true)] [JsonProperty("ansvarForByggesaken")] [JsonPropertyName("ansvarForByggesaken")] public KodeType ansvarForByggesaken { get; set; } @@ -110,12 +110,12 @@ public class EiendomType public bool ShouldSerializeAltinnRowId() => AltinnRowId != default; - [XmlElement("eiendomsidentifikasjon")] + [XmlElement("eiendomsidentifikasjon", IsNullable = true)] [JsonProperty("eiendomsidentifikasjon")] [JsonPropertyName("eiendomsidentifikasjon")] public MatrikkelnummerType eiendomsidentifikasjon { get; set; } - [XmlElement("adresse")] + [XmlElement("adresse", IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public EiendommensAdresseType adresse { get; set; } @@ -257,7 +257,7 @@ public class MetadataType [JsonPropertyName("prosjektnr")] public string prosjektnr { get; set; } - [XmlElement("foretrukketSpraak")] + [XmlElement("foretrukketSpraak", IsNullable = true)] [JsonProperty("foretrukketSpraak")] [JsonPropertyName("foretrukketSpraak")] public KodeType foretrukketSpraak { get; set; } @@ -297,7 +297,7 @@ public class GenerelleVilkaarType public class BeskrivelseAvTiltakType { - [XmlElement("type")] + [XmlElement("type", IsNullable = true)] [JsonProperty("type")] [JsonPropertyName("type")] public KodeListe type { get; set; } @@ -342,17 +342,17 @@ public class UtfallSvarType [JsonPropertyName("utfallId")] public string utfallId { get; set; } - [XmlElement("utfallType")] + [XmlElement("utfallType", IsNullable = true)] [JsonProperty("utfallType")] [JsonPropertyName("utfallType")] public KodeType utfallType { get; set; } - [XmlElement("utloestFraSjekkpunkt")] + [XmlElement("utloestFraSjekkpunkt", IsNullable = true)] [JsonProperty("utloestFraSjekkpunkt")] [JsonPropertyName("utloestFraSjekkpunkt")] public SjekkpunktType utloestFraSjekkpunkt { get; set; } - [XmlElement("tema")] + [XmlElement("tema", IsNullable = true)] [JsonProperty("tema")] [JsonPropertyName("tema")] public KodeType tema { get; set; } @@ -382,7 +382,7 @@ public class UtfallSvarType [JsonPropertyName("kommentar")] public string kommentar { get; set; } - [XmlElement("vedleggsliste")] + [XmlElement("vedleggsliste", IsNullable = true)] [JsonProperty("vedleggsliste")] [JsonPropertyName("vedleggsliste")] public VedleggListe vedleggsliste { get; set; } @@ -427,7 +427,7 @@ public class VedleggType [JsonPropertyName("versjonsnummer")] public string versjonsnummer { get; set; } - [XmlElement("vedleggstype")] + [XmlElement("vedleggstype", IsNullable = true)] [JsonProperty("vedleggstype")] [JsonPropertyName("vedleggstype")] public KodeType vedleggstype { get; set; } @@ -473,12 +473,12 @@ public class KravFerdigattestType public class VarmesystemType { - [XmlElement("varmefordeling")] + [XmlElement("varmefordeling", IsNullable = true)] [JsonProperty("varmefordeling")] [JsonPropertyName("varmefordeling")] public KodeListe varmefordeling { get; set; } - [XmlElement("energiforsyning")] + [XmlElement("energiforsyning", IsNullable = true)] [JsonProperty("energiforsyning")] [JsonPropertyName("energiforsyning")] public KodeListe energiforsyning { get; set; } @@ -492,7 +492,7 @@ public class VarmesystemType public class PartType { - [XmlElement("partstype")] + [XmlElement("partstype", IsNullable = true)] [JsonProperty("partstype")] [JsonPropertyName("partstype")] public KodeType partstype { get; set; } @@ -512,7 +512,7 @@ public class PartType [JsonPropertyName("navn")] public string navn { get; set; } - [XmlElement("adresse")] + [XmlElement("adresse", IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public EnkelAdresseType adresse { get; set; } @@ -532,7 +532,7 @@ public class PartType [JsonPropertyName("epost")] public string epost { get; set; } - [XmlElement("kontaktperson")] + [XmlElement("kontaktperson", IsNullable = true)] [JsonProperty("kontaktperson")] [JsonPropertyName("kontaktperson")] public KontaktpersonType kontaktperson { get; set; } diff --git a/testdata/Model/CSharp/XsAll/igangsettingstillatelse/v4/igangsettingstillatelse.cs b/testdata/Model/CSharp/XsAll/igangsettingstillatelse/v4/igangsettingstillatelse.cs index fcdc09257b8..11835805cb6 100644 --- a/testdata/Model/CSharp/XsAll/igangsettingstillatelse/v4/igangsettingstillatelse.cs +++ b/testdata/Model/CSharp/XsAll/igangsettingstillatelse/v4/igangsettingstillatelse.cs @@ -24,47 +24,47 @@ public class IgangsettingstillatelseType [BindNever] public string dataFormatVersion { get; set; } = "4"; - [XmlElement("eiendomByggested")] + [XmlElement("eiendomByggested", IsNullable = true)] [JsonProperty("eiendomByggested")] [JsonPropertyName("eiendomByggested")] public EiendomListe eiendomByggested { get; set; } - [XmlElement("kommunensSaksnummer")] + [XmlElement("kommunensSaksnummer", IsNullable = true)] [JsonProperty("kommunensSaksnummer")] [JsonPropertyName("kommunensSaksnummer")] public SaksnummerType kommunensSaksnummer { get; set; } - [XmlElement("metadata")] + [XmlElement("metadata", IsNullable = true)] [JsonProperty("metadata")] [JsonPropertyName("metadata")] public MetadataType metadata { get; set; } - [XmlElement("generelleVilkaar")] + [XmlElement("generelleVilkaar", IsNullable = true)] [JsonProperty("generelleVilkaar")] [JsonPropertyName("generelleVilkaar")] public GenerelleVilkaarType generelleVilkaar { get; set; } - [XmlElement("soeknadGjelder")] + [XmlElement("soeknadGjelder", IsNullable = true)] [JsonProperty("soeknadGjelder")] [JsonPropertyName("soeknadGjelder")] public SoeknadenGjelderType soeknadGjelder { get; set; } - [XmlElement("delsoeknader")] + [XmlElement("delsoeknader", IsNullable = true)] [JsonProperty("delsoeknader")] [JsonPropertyName("delsoeknader")] public DelsoeknadListe delsoeknader { get; set; } - [XmlElement("utfallBesvarelse")] + [XmlElement("utfallBesvarelse", IsNullable = true)] [JsonProperty("utfallBesvarelse")] [JsonPropertyName("utfallBesvarelse")] public UtfallSvarListe utfallBesvarelse { get; set; } - [XmlElement("ansvarligSoeker")] + [XmlElement("ansvarligSoeker", IsNullable = true)] [JsonProperty("ansvarligSoeker")] [JsonPropertyName("ansvarligSoeker")] public PartType ansvarligSoeker { get; set; } - [XmlElement("ansvarForByggesaken")] + [XmlElement("ansvarForByggesaken", IsNullable = true)] [JsonProperty("ansvarForByggesaken")] [JsonPropertyName("ansvarForByggesaken")] public KodeType ansvarForByggesaken { get; set; } @@ -90,12 +90,12 @@ public class EiendomType public bool ShouldSerializeAltinnRowId() => AltinnRowId != default; - [XmlElement("eiendomsidentifikasjon")] + [XmlElement("eiendomsidentifikasjon", IsNullable = true)] [JsonProperty("eiendomsidentifikasjon")] [JsonPropertyName("eiendomsidentifikasjon")] public MatrikkelnummerType eiendomsidentifikasjon { get; set; } - [XmlElement("adresse")] + [XmlElement("adresse", IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public EiendommensAdresseType adresse { get; set; } @@ -237,7 +237,7 @@ public class MetadataType [JsonPropertyName("prosjektnr")] public string prosjektnr { get; set; } - [XmlElement("foretrukketSpraak")] + [XmlElement("foretrukketSpraak", IsNullable = true)] [JsonProperty("foretrukketSpraak")] [JsonPropertyName("foretrukketSpraak")] public KodeType foretrukketSpraak { get; set; } @@ -292,7 +292,7 @@ public class SoeknadenGjelderType [JsonPropertyName("delAvTiltaket")] public string delAvTiltaket { get; set; } - [XmlElement("type")] + [XmlElement("type", IsNullable = true)] [JsonProperty("type")] [JsonPropertyName("type")] public KodeListe type { get; set; } @@ -353,7 +353,7 @@ public class DelsoeknadType [JsonPropertyName("kommentar")] public string kommentar { get; set; } - [XmlElement("type")] + [XmlElement("type", IsNullable = true)] [JsonProperty("type")] [JsonPropertyName("type")] public KodeListe type { get; set; } @@ -389,17 +389,17 @@ public class UtfallSvarType [JsonPropertyName("utfallId")] public string utfallId { get; set; } - [XmlElement("utfallType")] + [XmlElement("utfallType", IsNullable = true)] [JsonProperty("utfallType")] [JsonPropertyName("utfallType")] public KodeType utfallType { get; set; } - [XmlElement("utloestFraSjekkpunkt")] + [XmlElement("utloestFraSjekkpunkt", IsNullable = true)] [JsonProperty("utloestFraSjekkpunkt")] [JsonPropertyName("utloestFraSjekkpunkt")] public SjekkpunktType utloestFraSjekkpunkt { get; set; } - [XmlElement("tema")] + [XmlElement("tema", IsNullable = true)] [JsonProperty("tema")] [JsonPropertyName("tema")] public KodeType tema { get; set; } @@ -429,7 +429,7 @@ public class UtfallSvarType [JsonPropertyName("kommentar")] public string kommentar { get; set; } - [XmlElement("vedleggsliste")] + [XmlElement("vedleggsliste", IsNullable = true)] [JsonProperty("vedleggsliste")] [JsonPropertyName("vedleggsliste")] public VedleggListe vedleggsliste { get; set; } @@ -474,7 +474,7 @@ public class VedleggType [JsonPropertyName("versjonsnummer")] public string versjonsnummer { get; set; } - [XmlElement("vedleggstype")] + [XmlElement("vedleggstype", IsNullable = true)] [JsonProperty("vedleggstype")] [JsonPropertyName("vedleggstype")] public KodeType vedleggstype { get; set; } @@ -494,7 +494,7 @@ public class VedleggType public class PartType { - [XmlElement("partstype")] + [XmlElement("partstype", IsNullable = true)] [JsonProperty("partstype")] [JsonPropertyName("partstype")] public KodeType partstype { get; set; } @@ -514,7 +514,7 @@ public class PartType [JsonPropertyName("navn")] public string navn { get; set; } - [XmlElement("adresse")] + [XmlElement("adresse", IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public EnkelAdresseType adresse { get; set; } @@ -534,7 +534,7 @@ public class PartType [JsonPropertyName("epost")] public string epost { get; set; } - [XmlElement("kontaktperson")] + [XmlElement("kontaktperson", IsNullable = true)] [JsonProperty("kontaktperson")] [JsonPropertyName("kontaktperson")] public KontaktpersonType kontaktperson { get; set; } diff --git a/testdata/Model/CSharp/XsAll/midlertidigbrukstillatelse/v4/midlertidigbrukstillatelse.cs b/testdata/Model/CSharp/XsAll/midlertidigbrukstillatelse/v4/midlertidigbrukstillatelse.cs index feaaea985c9..defbc2cc85f 100644 --- a/testdata/Model/CSharp/XsAll/midlertidigbrukstillatelse/v4/midlertidigbrukstillatelse.cs +++ b/testdata/Model/CSharp/XsAll/midlertidigbrukstillatelse/v4/midlertidigbrukstillatelse.cs @@ -24,47 +24,47 @@ public class MidlertidigBrukstillatelseType [BindNever] public string dataFormatVersion { get; set; } = "4"; - [XmlElement("eiendomByggested")] + [XmlElement("eiendomByggested", IsNullable = true)] [JsonProperty("eiendomByggested")] [JsonPropertyName("eiendomByggested")] public EiendomListe eiendomByggested { get; set; } - [XmlElement("kommunensSaksnummer")] + [XmlElement("kommunensSaksnummer", IsNullable = true)] [JsonProperty("kommunensSaksnummer")] [JsonPropertyName("kommunensSaksnummer")] public SaksnummerType kommunensSaksnummer { get; set; } - [XmlElement("metadata")] + [XmlElement("metadata", IsNullable = true)] [JsonProperty("metadata")] [JsonPropertyName("metadata")] public MetadataType metadata { get; set; } - [XmlElement("generelleVilkaar")] + [XmlElement("generelleVilkaar", IsNullable = true)] [JsonProperty("generelleVilkaar")] [JsonPropertyName("generelleVilkaar")] public GenerelleVilkaarType generelleVilkaar { get; set; } - [XmlElement("soeknadGjelder")] + [XmlElement("soeknadGjelder", IsNullable = true)] [JsonProperty("soeknadGjelder")] [JsonPropertyName("soeknadGjelder")] public SoeknadGjelderType soeknadGjelder { get; set; } - [XmlElement("delsoeknader")] + [XmlElement("delsoeknader", IsNullable = true)] [JsonProperty("delsoeknader")] [JsonPropertyName("delsoeknader")] public DelsoeknadListe delsoeknader { get; set; } - [XmlElement("utfallBesvarelse")] + [XmlElement("utfallBesvarelse", IsNullable = true)] [JsonProperty("utfallBesvarelse")] [JsonPropertyName("utfallBesvarelse")] public UtfallSvarListe utfallBesvarelse { get; set; } - [XmlElement("tiltakshaver")] + [XmlElement("tiltakshaver", IsNullable = true)] [JsonProperty("tiltakshaver")] [JsonPropertyName("tiltakshaver")] public PartType tiltakshaver { get; set; } - [XmlElement("ansvarligSoeker")] + [XmlElement("ansvarligSoeker", IsNullable = true)] [JsonProperty("ansvarligSoeker")] [JsonPropertyName("ansvarligSoeker")] public PartType ansvarligSoeker { get; set; } @@ -75,17 +75,17 @@ public class MidlertidigBrukstillatelseType [JsonPropertyName("datoFerdigattest")] public string datoFerdigattest { get; set; } - [XmlElement("gjenstaaendeArbeider")] + [XmlElement("gjenstaaendeArbeider", IsNullable = true)] [JsonProperty("gjenstaaendeArbeider")] [JsonPropertyName("gjenstaaendeArbeider")] public GjenstaaendeArbeiderType gjenstaaendeArbeider { get; set; } - [XmlElement("sikkerhetsnivaa")] + [XmlElement("sikkerhetsnivaa", IsNullable = true)] [JsonProperty("sikkerhetsnivaa")] [JsonPropertyName("sikkerhetsnivaa")] public SikkerhetsnivaaType sikkerhetsnivaa { get; set; } - [XmlElement("ansvarForByggesaken")] + [XmlElement("ansvarForByggesaken", IsNullable = true)] [JsonProperty("ansvarForByggesaken")] [JsonPropertyName("ansvarForByggesaken")] public KodeType ansvarForByggesaken { get; set; } @@ -111,12 +111,12 @@ public class EiendomType public bool ShouldSerializeAltinnRowId() => AltinnRowId != default; - [XmlElement("eiendomsidentifikasjon")] + [XmlElement("eiendomsidentifikasjon", IsNullable = true)] [JsonProperty("eiendomsidentifikasjon")] [JsonPropertyName("eiendomsidentifikasjon")] public MatrikkelnummerType eiendomsidentifikasjon { get; set; } - [XmlElement("adresse")] + [XmlElement("adresse", IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public EiendommensAdresseType adresse { get; set; } @@ -258,7 +258,7 @@ public class MetadataType [JsonPropertyName("prosjektnr")] public string prosjektnr { get; set; } - [XmlElement("foretrukketSpraak")] + [XmlElement("foretrukketSpraak", IsNullable = true)] [JsonProperty("foretrukketSpraak")] [JsonPropertyName("foretrukketSpraak")] public KodeType foretrukketSpraak { get; set; } @@ -308,7 +308,7 @@ public class SoeknadGjelderType [JsonPropertyName("delAvTiltaket")] public string delAvTiltaket { get; set; } - [XmlElement("type")] + [XmlElement("type", IsNullable = true)] [JsonProperty("type")] [JsonPropertyName("type")] public KodeListe type { get; set; } @@ -369,7 +369,7 @@ public class DelsoeknadType [JsonPropertyName("kommentar")] public string kommentar { get; set; } - [XmlElement("type")] + [XmlElement("type", IsNullable = true)] [JsonProperty("type")] [JsonPropertyName("type")] public KodeListe type { get; set; } @@ -405,17 +405,17 @@ public class UtfallSvarType [JsonPropertyName("utfallId")] public string utfallId { get; set; } - [XmlElement("utfallType")] + [XmlElement("utfallType", IsNullable = true)] [JsonProperty("utfallType")] [JsonPropertyName("utfallType")] public KodeType utfallType { get; set; } - [XmlElement("utloestFraSjekkpunkt")] + [XmlElement("utloestFraSjekkpunkt", IsNullable = true)] [JsonProperty("utloestFraSjekkpunkt")] [JsonPropertyName("utloestFraSjekkpunkt")] public SjekkpunktType utloestFraSjekkpunkt { get; set; } - [XmlElement("tema")] + [XmlElement("tema", IsNullable = true)] [JsonProperty("tema")] [JsonPropertyName("tema")] public KodeType tema { get; set; } @@ -445,7 +445,7 @@ public class UtfallSvarType [JsonPropertyName("kommentar")] public string kommentar { get; set; } - [XmlElement("vedleggsliste")] + [XmlElement("vedleggsliste", IsNullable = true)] [JsonProperty("vedleggsliste")] [JsonPropertyName("vedleggsliste")] public VedleggListe vedleggsliste { get; set; } @@ -490,7 +490,7 @@ public class VedleggType [JsonPropertyName("versjonsnummer")] public string versjonsnummer { get; set; } - [XmlElement("vedleggstype")] + [XmlElement("vedleggstype", IsNullable = true)] [JsonProperty("vedleggstype")] [JsonPropertyName("vedleggstype")] public KodeType vedleggstype { get; set; } @@ -510,7 +510,7 @@ public class VedleggType public class PartType { - [XmlElement("partstype")] + [XmlElement("partstype", IsNullable = true)] [JsonProperty("partstype")] [JsonPropertyName("partstype")] public KodeType partstype { get; set; } @@ -530,7 +530,7 @@ public class PartType [JsonPropertyName("navn")] public string navn { get; set; } - [XmlElement("adresse")] + [XmlElement("adresse", IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public EnkelAdresseType adresse { get; set; } @@ -550,7 +550,7 @@ public class PartType [JsonPropertyName("epost")] public string epost { get; set; } - [XmlElement("kontaktperson")] + [XmlElement("kontaktperson", IsNullable = true)] [JsonProperty("kontaktperson")] [JsonPropertyName("kontaktperson")] public KontaktpersonType kontaktperson { get; set; } diff --git a/testdata/Model/CSharp/XsAll/planvarsel/v2/planvarsel.cs b/testdata/Model/CSharp/XsAll/planvarsel/v2/planvarsel.cs index ebacd19f4e9..ddeaf0bb868 100644 --- a/testdata/Model/CSharp/XsAll/planvarsel/v2/planvarsel.cs +++ b/testdata/Model/CSharp/XsAll/planvarsel/v2/planvarsel.cs @@ -39,27 +39,27 @@ public class PlanvarselType [JsonPropertyName("kommunenavn")] public string kommunenavn { get; set; } - [XmlElement("eiendomByggested")] + [XmlElement("eiendomByggested", IsNullable = true)] [JsonProperty("eiendomByggested")] [JsonPropertyName("eiendomByggested")] public EiendomListe eiendomByggested { get; set; } - [XmlElement("signatur")] + [XmlElement("signatur", IsNullable = true)] [JsonProperty("signatur")] [JsonPropertyName("signatur")] public SignaturType signatur { get; set; } - [XmlElement("gjeldendePlan")] + [XmlElement("gjeldendePlan", IsNullable = true)] [JsonProperty("gjeldendePlan")] [JsonPropertyName("gjeldendePlan")] public GjeldendePlanListe gjeldendePlan { get; set; } - [XmlElement("plankonsulent")] + [XmlElement("plankonsulent", IsNullable = true)] [JsonProperty("plankonsulent")] [JsonPropertyName("plankonsulent")] public PartType plankonsulent { get; set; } - [XmlElement("metadata")] + [XmlElement("metadata", IsNullable = true)] [JsonProperty("metadata")] [JsonPropertyName("metadata")] public MetadataType metadata { get; set; } @@ -73,7 +73,7 @@ public class PlanvarselType public class PartType { - [XmlElement("partstype")] + [XmlElement("partstype", IsNullable = true)] [JsonProperty("partstype")] [JsonPropertyName("partstype")] public KodeType partstype { get; set; } @@ -98,7 +98,7 @@ public class PartType [JsonPropertyName("epost")] public string epost { get; set; } - [XmlElement("adresse")] + [XmlElement("adresse", IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public EnkelAdresseType adresse { get; set; } @@ -177,7 +177,7 @@ public class BeroertPartType public bool ShouldSerializeAltinnRowId() => AltinnRowId != default; - [XmlElement("partstype")] + [XmlElement("partstype", IsNullable = true)] [JsonProperty("partstype")] [JsonPropertyName("partstype")] public KodeType partstype { get; set; } @@ -207,7 +207,7 @@ public class BeroertPartType [JsonPropertyName("epost")] public string epost { get; set; } - [XmlElement("adresse")] + [XmlElement("adresse", IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public EnkelAdresseType adresse { get; set; } @@ -227,7 +227,7 @@ public class BeroertPartType [JsonPropertyName("erHoeringsmyndighet")] public bool? erHoeringsmyndighet { get; set; } - [XmlElement("gjelderEiendom")] + [XmlElement("gjelderEiendom", IsNullable = true)] [JsonProperty("gjelderEiendom")] [JsonPropertyName("gjelderEiendom")] public GjelderEiendomListe gjelderEiendom { get; set; } @@ -253,12 +253,12 @@ public class EiendomType public bool ShouldSerializeAltinnRowId() => AltinnRowId != default; - [XmlElement("eiendomsidentifikasjon")] + [XmlElement("eiendomsidentifikasjon", IsNullable = true)] [JsonProperty("eiendomsidentifikasjon")] [JsonPropertyName("eiendomsidentifikasjon")] public MatrikkelnummerType eiendomsidentifikasjon { get; set; } - [XmlElement("adresse")] + [XmlElement("adresse", IsNullable = true)] [JsonProperty("adresse")] [JsonPropertyName("adresse")] public EiendommensAdresseType adresse { get; set; } @@ -414,7 +414,7 @@ public class GjeldendePlanType [JsonPropertyName("navn")] public string navn { get; set; } - [XmlElement("plantype")] + [XmlElement("plantype", IsNullable = true)] [JsonProperty("plantype")] [JsonPropertyName("plantype")] public KodeType plantype { get; set; } @@ -482,7 +482,7 @@ public class PlanType [JsonPropertyName("hjemmesidePlanprogram")] public string hjemmesidePlanprogram { get; set; } - [XmlElement("plantype")] + [XmlElement("plantype", IsNullable = true)] [JsonProperty("plantype")] [JsonPropertyName("plantype")] public KodeType plantype { get; set; } @@ -492,7 +492,7 @@ public class PlanType [JsonPropertyName("begrunnelseKU")] public string begrunnelseKU { get; set; } - [XmlElement("kommunensSaksnummer")] + [XmlElement("kommunensSaksnummer", IsNullable = true)] [JsonProperty("kommunensSaksnummer")] [JsonPropertyName("kommunensSaksnummer")] public SaksnummerType kommunensSaksnummer { get; set; } diff --git a/testdata/Model/Xml/XsAll/xsall-example-nillable-sample.xml b/testdata/Model/Xml/XsAll/xsall-example-nillable-sample.xml index f2d4f8078f7..0ca1e7b6b71 100644 --- a/testdata/Model/Xml/XsAll/xsall-example-nillable-sample.xml +++ b/testdata/Model/Xml/XsAll/xsall-example-nillable-sample.xml @@ -1,4 +1,5 @@ + diff --git a/testdata/Model/XmlSchema/XsAll/xsall-example.xsd b/testdata/Model/XmlSchema/XsAll/xsall-example.xsd index e7d09bb3df5..e2dcb2f07cc 100644 --- a/testdata/Model/XmlSchema/XsAll/xsall-example.xsd +++ b/testdata/Model/XmlSchema/XsAll/xsall-example.xsd @@ -8,6 +8,13 @@ + + + + + + + From a578aabc5042b0583316a1026055689a0001c6c3 Mon Sep 17 00:00:00 2001 From: andreastanderen <71079896+standeren@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:16:42 +0100 Subject: [PATCH 02/10] refactor: fetch only single needed option list in option list editor (#14266) Co-authored-by: Erling Hauan <148075168+ErlingHauan@users.noreply.github.com> --- frontend/packages/shared/src/api/paths.js | 1 + frontend/packages/shared/src/api/queries.ts | 4 +- .../mutations/useAddOptionListMutation.ts | 8 +- .../useUpdateOptionListIdMutation.test.ts | 22 ++- .../useUpdateOptionListIdMutation.ts | 2 + .../useUpdateOptionListMutation.test.ts | 14 +- .../mutations/useUpdateOptionListMutation.ts | 1 + .../shared/src/hooks/queries/index.ts | 1 + .../hooks/queries/useOptionListQuery.test.ts | 34 ++++ .../src/hooks/queries/useOptionListQuery.ts | 17 ++ .../packages/shared/src/mocks/queriesMock.ts | 3 +- .../packages/shared/src/types/QueryKey.ts | 1 + .../shared/src/types/api/OptionsLists.ts | 4 +- .../OptionTabs/EditTab/EditTab.tsx | 14 +- .../LibraryOptionsEditor.module.css} | 0 .../LibraryOptionsEditor.tsx | 74 ++++++++ .../LibraryOptionsEditor/index.ts | 1 + .../ManualOptionsEditor.module.css | 11 ++ .../ManualOptionsEditor.tsx | 57 ++++++ .../ManualOptionsEditor/index.ts | 1 + .../OptionListEditor.test.tsx | 127 ++++++------- .../OptionListEditor/OptionListEditor.tsx | 173 ++---------------- 22 files changed, 324 insertions(+), 246 deletions(-) create mode 100644 frontend/packages/shared/src/hooks/queries/useOptionListQuery.test.ts create mode 100644 frontend/packages/shared/src/hooks/queries/useOptionListQuery.ts rename frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/{OptionListEditor.module.css => LibraryOptionsEditor/LibraryOptionsEditor.module.css} (100%) create mode 100644 frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/LibraryOptionsEditor/LibraryOptionsEditor.tsx create mode 100644 frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/LibraryOptionsEditor/index.ts create mode 100644 frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/ManualOptionsEditor.module.css create mode 100644 frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/ManualOptionsEditor.tsx create mode 100644 frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/index.ts diff --git a/frontend/packages/shared/src/api/paths.js b/frontend/packages/shared/src/api/paths.js index e749e05eaa1..49277c5dce8 100644 --- a/frontend/packages/shared/src/api/paths.js +++ b/frontend/packages/shared/src/api/paths.js @@ -41,6 +41,7 @@ export const submitFeedbackPath = (org, app) => `${basePath}/${org}/${app}/feedb // FormEditor export const ruleHandlerPath = (org, app, layoutSetName) => `${basePath}/${org}/${app}/app-development/rule-handler?${s({ layoutSetName })}`; // Get, Post export const widgetSettingsPath = (org, app) => `${basePath}/${org}/${app}/app-development/widget-settings`; // Get +export const optionListPath = (org, app, optionsListId) => `${basePath}/${org}/${app}/options/${optionsListId}`; // Get export const optionListsPath = (org, app) => `${basePath}/${org}/${app}/options/option-lists`; // Get export const optionListIdsPath = (org, app) => `${basePath}/${org}/${app}/app-development/option-list-ids`; // Get export const optionListUpdatePath = (org, app, optionsListId) => `${basePath}/${org}/${app}/options/${optionsListId}`; // Put diff --git a/frontend/packages/shared/src/api/queries.ts b/frontend/packages/shared/src/api/queries.ts index 57002072126..251d5e7896f 100644 --- a/frontend/packages/shared/src/api/queries.ts +++ b/frontend/packages/shared/src/api/queries.ts @@ -56,6 +56,7 @@ import { authStatusAnsattporten, availableMaskinportenScopesPath, selectedMaskinportenScopesPath, + optionListPath, } from './paths'; import type { AppReleasesResponse, DataModelMetadataResponse, SearchRepoFilterParams, SearchRepositoryResponse } from 'app-shared/types/api'; @@ -87,7 +88,7 @@ import type { Policy } from 'app-shared/types/Policy'; import type { RepoDiffResponse } from 'app-shared/types/api/RepoDiffResponse'; import type { ExternalImageUrlValidationResponse } from 'app-shared/types/api/ExternalImageUrlValidationResponse'; import type { MaskinportenScopes } from 'app-shared/types/MaskinportenScope'; -import type { OptionsLists } from 'app-shared/types/api/OptionsLists'; +import type { OptionsList, OptionsLists } from 'app-shared/types/api/OptionsLists'; import type { LayoutSetsModel } from '../types/api/dto/LayoutSetsModel'; export const getIsLoggedInWithAnsattporten = () => get<{ isLoggedIn: boolean }>(authStatusAnsattporten()); @@ -114,6 +115,7 @@ export const getInstanceIdForPreview = (owner: string, app: string) => get get(layoutNamesPath(owner, app)); export const getLayoutSets = (owner: string, app: string) => get(layoutSetsPath(owner, app)); export const getLayoutSetsExtended = (owner: string, app: string) => get(layoutSetsPath(owner, app) + '/extended'); +export const getOptionList = (owner: string, app: string, optionsListId: string) => get(optionListPath(owner, app, optionsListId)); export const getOptionLists = (owner: string, app: string) => get(optionListsPath(owner, app)); export const getOptionListIds = (owner: string, app: string) => get(optionListIdsPath(owner, app)); export const getOrgList = () => get(orgListUrl()); diff --git a/frontend/packages/shared/src/hooks/mutations/useAddOptionListMutation.ts b/frontend/packages/shared/src/hooks/mutations/useAddOptionListMutation.ts index 26c012aa800..50ab147c1e5 100644 --- a/frontend/packages/shared/src/hooks/mutations/useAddOptionListMutation.ts +++ b/frontend/packages/shared/src/hooks/mutations/useAddOptionListMutation.ts @@ -14,11 +14,9 @@ export const useAddOptionListMutation = (org: string, app: string, meta?: Mutati return useMutation({ mutationFn, - onSuccess: async () => { - await Promise.all([ - queryClient.invalidateQueries({ queryKey: [QueryKey.OptionListIds, org, app] }), - queryClient.invalidateQueries({ queryKey: [QueryKey.OptionLists, org, app] }), - ]); + onSuccess: () => { + void queryClient.invalidateQueries({ queryKey: [QueryKey.OptionListIds, org, app] }); + void queryClient.invalidateQueries({ queryKey: [QueryKey.OptionLists, org, app] }); }, meta, }); diff --git a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.test.ts b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.test.ts index 04d4a9551fd..fa78f914d6f 100644 --- a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.test.ts +++ b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.test.ts @@ -62,12 +62,7 @@ describe('useUpdateOptionListIdMutation', () => { test('Invalidates the optionListIds query cache', async () => { const queryClient = createQueryClientMock(); const invalidateQueriesSpy = jest.spyOn(queryClient, 'invalidateQueries'); - const oldData: OptionsLists = { - firstOptionList: optionListMock, - optionListId: optionListMock, - lastOptionList: optionListMock, - }; - queryClient.setQueryData([QueryKey.OptionLists, org, app], oldData); + queryClient.setQueryData([QueryKey.OptionLists, org, app], []); const renderUpdateOptionListMutationResult = renderHookWithProviders( () => useUpdateOptionListIdMutation(org, app), { queryClient }, @@ -78,4 +73,19 @@ describe('useUpdateOptionListIdMutation', () => { queryKey: [QueryKey.OptionListIds, org, app], }); }); + + test('Removes the option list query cache for the old Id', async () => { + const queryClient = createQueryClientMock(); + const removeQueriesSpy = jest.spyOn(queryClient, 'removeQueries'); + queryClient.setQueryData([QueryKey.OptionLists, org, app], []); + const renderUpdateOptionListMutationResult = renderHookWithProviders( + () => useUpdateOptionListIdMutation(org, app), + { queryClient }, + ).result; + await renderUpdateOptionListMutationResult.current.mutateAsync(args); + expect(removeQueriesSpy).toHaveBeenCalledTimes(1); + expect(removeQueriesSpy).toHaveBeenCalledWith({ + queryKey: [QueryKey.OptionList, org, app, optionListId], + }); + }); }); diff --git a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.ts b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.ts index d56dddb6c51..6c5804e284d 100644 --- a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.ts +++ b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.ts @@ -24,6 +24,8 @@ export const useUpdateOptionListIdMutation = (org: string, app: string) => { const oldData: OptionsLists = queryClient.getQueryData([QueryKey.OptionLists, org, app]); const ascSortedData = changeIdAndSortCacheData(optionListId, newOptionListId, oldData); queryClient.setQueryData([QueryKey.OptionLists, org, app], ascSortedData); + // Currently we only need to remove the old and not set the new, since mutating the Id only happens from the library which uses the large OptionLists cache + queryClient.removeQueries({ queryKey: [QueryKey.OptionList, org, app, optionListId] }); queryClient.invalidateQueries({ queryKey: [QueryKey.OptionListIds, org, app] }); }, }); diff --git a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListMutation.test.ts b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListMutation.test.ts index 7ed8ac17e78..851ef6b6461 100644 --- a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListMutation.test.ts +++ b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListMutation.test.ts @@ -27,7 +27,7 @@ describe('useUpdateOptionListMutation', () => { expect(queriesMock.updateOptionList).toHaveBeenCalledWith(org, app, optionListId, optionsList); }); - test('Sets the updated option list on the cache', async () => { + test('Sets the updated option list on the cache for all option lists', async () => { const queryClient = createQueryClientMock(); const renderUpdateOptionListMutationResult = renderHookWithProviders( () => useUpdateOptionListMutation(org, app), @@ -38,4 +38,16 @@ describe('useUpdateOptionListMutation', () => { test: updatedOptionsList, }); }); + + test('Sets the updated option list on the cache for the single option list', async () => { + const queryClient = createQueryClientMock(); + const renderUpdateOptionListMutationResult = renderHookWithProviders( + () => useUpdateOptionListMutation(org, app), + { queries: { updateOptionList }, queryClient }, + ).result; + await renderUpdateOptionListMutationResult.current.mutateAsync(args); + expect(queryClient.getQueryData([QueryKey.OptionList, org, app, optionListId])).toEqual( + updatedOptionsList, + ); + }); }); diff --git a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListMutation.ts b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListMutation.ts index b6bfd00e2e6..2f885ffe0f6 100644 --- a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListMutation.ts +++ b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListMutation.ts @@ -23,6 +23,7 @@ export const useUpdateOptionListMutation = (org: string, app: string, meta?: Mut const newData = { ...oldData }; newData[optionListId] = updatedOptionList; queryClient.setQueryData([QueryKey.OptionLists, org, app], newData); + queryClient.setQueryData([QueryKey.OptionList, org, app, optionListId], updatedOptionList); }, meta, }); diff --git a/frontend/packages/shared/src/hooks/queries/index.ts b/frontend/packages/shared/src/hooks/queries/index.ts index 1f3484f632b..fc03b8ed37f 100644 --- a/frontend/packages/shared/src/hooks/queries/index.ts +++ b/frontend/packages/shared/src/hooks/queries/index.ts @@ -3,6 +3,7 @@ export { useAppVersionQuery } from './useAppVersionQuery'; export { useDataModelsJsonQuery } from './useDataModelsJsonQuery'; export { useDataModelsXsdQuery } from './useDataModelsXsdQuery'; export { useInstanceIdQuery } from './useInstanceIdQuery'; +export { useOptionListQuery } from './useOptionListQuery'; export { useOptionListsQuery } from './useOptionListsQuery'; export { useRepoMetadataQuery } from './useRepoMetadataQuery'; export { useRepoPullQuery } from './useRepoPullQuery'; diff --git a/frontend/packages/shared/src/hooks/queries/useOptionListQuery.test.ts b/frontend/packages/shared/src/hooks/queries/useOptionListQuery.test.ts new file mode 100644 index 00000000000..2876ebefa9f --- /dev/null +++ b/frontend/packages/shared/src/hooks/queries/useOptionListQuery.test.ts @@ -0,0 +1,34 @@ +import { queriesMock } from 'app-shared/mocks/queriesMock'; +import { app, org } from '@studio/testing/testids'; +import { renderHookWithProviders } from 'app-shared/mocks/renderHookWithProviders'; +import { useOptionListQuery } from 'app-shared/hooks/queries/useOptionListQuery'; +import { waitFor } from '@testing-library/react'; +import type { ServicesContextProps } from 'app-shared/contexts/ServicesContext'; +import type { OptionsList } from 'app-shared/types/api/OptionsLists'; +import { createQueryClientMock } from 'app-shared/mocks/queryClientMock'; + +const optionsListId = 'optionsListId'; + +describe('useOptionListQuery', () => { + it('calls getOptionList with the correct parameters', () => { + render(); + expect(queriesMock.getOptionList).toHaveBeenCalledWith(org, app, optionsListId); + }); + + it('getOptionList returns optionList as is', async () => { + const optionsList: OptionsList = [{ value: 'value', label: 'label' }]; + const getOptionList = jest.fn().mockImplementation(() => Promise.resolve(optionsList)); + const { current: currentResult } = await render({ getOptionList }); + expect(currentResult.data).toBe(optionsList); + }); +}); + +const render = async (queries: Partial = {}) => { + const queryClient = createQueryClientMock(); + const { result } = renderHookWithProviders(() => useOptionListQuery(org, app, optionsListId), { + queries, + queryClient, + }); + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + return result; +}; diff --git a/frontend/packages/shared/src/hooks/queries/useOptionListQuery.ts b/frontend/packages/shared/src/hooks/queries/useOptionListQuery.ts new file mode 100644 index 00000000000..91ec12df941 --- /dev/null +++ b/frontend/packages/shared/src/hooks/queries/useOptionListQuery.ts @@ -0,0 +1,17 @@ +import { useServicesContext } from 'app-shared/contexts/ServicesContext'; +import { QueryKey } from 'app-shared/types/QueryKey'; +import type { UseQueryResult } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; +import type { OptionsList } from 'app-shared/types/api/OptionsLists'; + +export const useOptionListQuery = ( + org: string, + app: string, + optionListId: string, +): UseQueryResult => { + const { getOptionList } = useServicesContext(); + return useQuery({ + queryKey: [QueryKey.OptionList, org, app, optionListId], + queryFn: () => getOptionList(org, app, optionListId), + }); +}; diff --git a/frontend/packages/shared/src/mocks/queriesMock.ts b/frontend/packages/shared/src/mocks/queriesMock.ts index 6efd4b3f207..cc0957bfe1a 100644 --- a/frontend/packages/shared/src/mocks/queriesMock.ts +++ b/frontend/packages/shared/src/mocks/queriesMock.ts @@ -69,7 +69,7 @@ import type { DeploymentsResponse } from 'app-shared/types/api/DeploymentsRespon import type { RepoDiffResponse } from 'app-shared/types/api/RepoDiffResponse'; import type { ExternalImageUrlValidationResponse } from 'app-shared/types/api/ExternalImageUrlValidationResponse'; import type { MaskinportenScope } from 'app-shared/types/MaskinportenScope'; -import type { OptionsLists } from 'app-shared/types/api/OptionsLists'; +import type { OptionsList, OptionsLists } from 'app-shared/types/api/OptionsLists'; import type { LayoutSetsModel } from '../types/api/dto/LayoutSetsModel'; import { layoutSetsExtendedMock } from '@altinn/ux-editor/testing/layoutSetsMock'; @@ -109,6 +109,7 @@ export const queriesMock: ServicesContextProps = { .fn() .mockImplementation(() => Promise.resolve(layoutSetsExtendedMock)), getOptionListIds: jest.fn().mockImplementation(() => Promise.resolve([])), + getOptionList: jest.fn().mockImplementation(() => Promise.resolve([])), getOptionLists: jest.fn().mockImplementation(() => Promise.resolve({})), getOrgList: jest.fn().mockImplementation(() => Promise.resolve(orgList)), getOrganizations: jest.fn().mockImplementation(() => Promise.resolve([])), diff --git a/frontend/packages/shared/src/types/QueryKey.ts b/frontend/packages/shared/src/types/QueryKey.ts index 5195acbf358..5db7f25c245 100644 --- a/frontend/packages/shared/src/types/QueryKey.ts +++ b/frontend/packages/shared/src/types/QueryKey.ts @@ -27,6 +27,7 @@ export enum QueryKey { LayoutSchema = 'LayoutSchema', LayoutSets = 'LayoutSets', LayoutSetsExtended = 'LayoutSetsExtended', + OptionList = 'OptionList', OptionLists = 'OptionLists', OptionListIds = 'OptionListIds', OrgList = 'OrgList', diff --git a/frontend/packages/shared/src/types/api/OptionsLists.ts b/frontend/packages/shared/src/types/api/OptionsLists.ts index fa3f5d6d7da..35b59e98882 100644 --- a/frontend/packages/shared/src/types/api/OptionsLists.ts +++ b/frontend/packages/shared/src/types/api/OptionsLists.ts @@ -1,3 +1,5 @@ import type { Option } from 'app-shared/types/Option'; -export type OptionsLists = Record; +export type OptionsList = Option[]; + +export type OptionsLists = Record; diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/EditTab.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/EditTab.tsx index f6d935408a8..0ca7a543443 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/EditTab.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/EditTab.tsx @@ -86,19 +86,9 @@ function SelectedOptionList({ setComponentHasOptionList(false); }; - const label = - component.optionsId !== '' && component.optionsId !== undefined - ? component.optionsId - : t('ux_editor.modal_properties_code_list_custom_list'); - return ( -
- +
+
(optionsList); + const editorTexts: CodeListEditorTexts = useOptionListEditorTexts(); + const modalRef = createRef(); + + const optionListHasChanged = (options: Option[]): boolean => + JSON.stringify(options) !== JSON.stringify(localOptionList); + + const handleBlurAny = (options: Option[]) => { + if (optionListHasChanged(options)) { + updateOptionList({ optionListId: optionsId, optionsList: options }); + setLocalOptionList(options); + doReloadPreview(); + } + }; + + const handleClose = () => { + modalRef.current?.close(); + }; + + return ( + <> + modalRef.current.showModal()} + /> + + {t('ux_editor.modal_properties_code_list_alert_title')} + + } + > + + + + ); +} diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/LibraryOptionsEditor/index.ts b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/LibraryOptionsEditor/index.ts new file mode 100644 index 00000000000..9079180f415 --- /dev/null +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/LibraryOptionsEditor/index.ts @@ -0,0 +1 @@ +export { LibraryOptionsEditor } from './LibraryOptionsEditor'; diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/ManualOptionsEditor.module.css b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/ManualOptionsEditor.module.css new file mode 100644 index 00000000000..ab917c70498 --- /dev/null +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/ManualOptionsEditor.module.css @@ -0,0 +1,11 @@ +.editOptionTabModal[open] { + --code-list-modal-min-width: min(80rem, 100%); + --code-list-modal-height: min(45rem, 100%); + + min-width: var(--code-list-modal-min-width); + height: var(--code-list-modal-height); +} + +.content { + height: 100%; +} diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/ManualOptionsEditor.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/ManualOptionsEditor.tsx new file mode 100644 index 00000000000..e69ccd54298 --- /dev/null +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/ManualOptionsEditor.tsx @@ -0,0 +1,57 @@ +import { useOptionListEditorTexts } from '@altinn/ux-editor/components/config/editModal/EditOptions/OptionTabs/hooks'; +import type { Option } from 'app-shared/types/Option'; +import classes from './ManualOptionsEditor.module.css'; +import type { IGenericEditComponent } from '@altinn/ux-editor/components/config/componentConfig'; +import type { SelectionComponentType } from '@altinn/ux-editor/types/FormComponent'; +import { useTranslation } from 'react-i18next'; +import React, { useRef } from 'react'; +import { StudioCodeListEditor, StudioModal, StudioProperty } from '@studio/components'; + +type ManualOptionsEditorProps = Pick< + IGenericEditComponent, + 'component' | 'handleComponentChange' +>; + +export function ManualOptionsEditor({ + component, + handleComponentChange, +}: ManualOptionsEditorProps): React.ReactNode { + const { t } = useTranslation(); + const modalRef = useRef(null); + const editorTexts = useOptionListEditorTexts(); + + const handleBlurAny = (options: Option[]) => { + if (component.optionsId) { + delete component.optionsId; + } + + handleComponentChange({ + ...component, + options, + }); + }; + + return ( + <> + modalRef.current.showModal()} + /> + + + + + ); +} diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/index.ts b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/index.ts new file mode 100644 index 00000000000..347b765f90d --- /dev/null +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/ManualOptionsEditor/index.ts @@ -0,0 +1 @@ +export { ManualOptionsEditor } from './ManualOptionsEditor'; diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/OptionListEditor.test.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/OptionListEditor.test.tsx index 829ff80aa22..298cdee0755 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/OptionListEditor.test.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/OptionListEditor.test.tsx @@ -1,7 +1,8 @@ import React from 'react'; import { screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react'; -import type { OptionsLists } from 'app-shared/types/api/OptionsLists'; +import type { OptionsList } from 'app-shared/types/api/OptionsLists'; import type { Option } from 'app-shared/types/Option'; +import type { OptionListEditorProps } from './OptionListEditor'; import { OptionListEditor } from './OptionListEditor'; import { textMock } from '@studio/testing/mocks/i18nMock'; import { renderWithProviders } from '../../../../../../../testing/mocks'; @@ -14,28 +15,28 @@ import { ComponentType } from 'app-shared/types/ComponentType'; // Test data: const mockComponent = componentMocks[ComponentType.RadioButtons]; - -const apiResult: OptionsLists = { - options: [ - { value: 'test', label: 'label text', description: 'description', helpText: 'help text' }, - { value: 2, label: 'label number', description: null, helpText: null }, - { value: true, label: 'label boolean', description: null, helpText: null }, - ], -}; +const handleComponentChange = jest.fn(); +const apiResult: OptionsList = [ + { value: 'test', label: 'label text', description: 'description', helpText: 'help text' }, + { value: 2, label: 'label number', description: null, helpText: null }, + { value: true, label: 'label boolean', description: null, helpText: null }, +]; +const getOptionListMock = jest + .fn() + .mockImplementation(() => Promise.resolve(apiResult)); describe('OptionListEditor', () => { afterEach(() => jest.clearAllMocks()); describe('ManualOptionListEditorModal', () => { it('should render the open Dialog button', async () => { - await renderOptionListEditorAndWaitForSpinnerToBeRemoved(); + renderOptionListEditor(); expect(getManualModalButton()).toBeInTheDocument(); }); it('should open Dialog', async () => { const user = userEvent.setup(); - await renderOptionListEditorAndWaitForSpinnerToBeRemoved(); - + renderOptionListEditor(); await user.click(getManualModalButton()); expect(screen.getByRole('dialog')).toBeInTheDocument(); @@ -43,8 +44,7 @@ describe('OptionListEditor', () => { it('should close Dialog', async () => { const user = userEvent.setup(); - await renderOptionListEditorAndWaitForSpinnerToBeRemoved(); - + renderOptionListEditor(); await user.click(getManualModalButton()); await user.click(screen.getByRole('button', { name: 'close modal' })); // Todo: Replace "close modal" with defaultDialogProps.closeButtonTitle when we upgrade to Designsystemet v1 @@ -53,15 +53,24 @@ describe('OptionListEditor', () => { it('should call doReloadPreview when editing', async () => { const user = userEvent.setup(); - const componentWithOptionsId = mockComponent; - componentWithOptionsId.optionsId = 'optionsID'; - const handleComponentChange = jest.fn(); - await renderOptionListEditorAndWaitForSpinnerToBeRemoved({ - handleComponentChange, - component: componentWithOptionsId, - }); + renderOptionListEditor(); const text = 'test'; + await user.click(getManualModalButton()); + const textBox = screen.getByRole('textbox', { + name: textMock('code_list_editor.description_item', { number: 2 }), + }); + await user.type(textBox, text); + await user.tab(); + + expect(handleComponentChange).toHaveBeenCalledTimes(1); + }); + it('should delete optionsId field from component if it was set when manual options editor is blurred', async () => { + const user = userEvent.setup(); + renderOptionListEditor({ + props: { component: { ...mockComponent, optionsId: 'optionsId' } }, + }); + const text = 'test'; await user.click(getManualModalButton()); const textBox = screen.getByRole('textbox', { name: textMock('code_list_editor.description_item', { number: 2 }), @@ -70,20 +79,19 @@ describe('OptionListEditor', () => { await user.tab(); expect(handleComponentChange).toHaveBeenCalledTimes(1); + expect(handleComponentChange).toHaveBeenCalledWith( + expect.not.objectContaining({ optionsId: expect.anything() }), + ); }); }); describe('LibraryOptionListEditorModal', () => { - beforeEach(() => { - mockComponent.optionsId = 'options'; - mockComponent.options = undefined; - }); - it('should render a spinner when there is no data', () => { renderOptionListEditor({ queries: { - getOptionLists: jest.fn().mockImplementation(() => Promise.resolve({})), + getOptionList: jest.fn().mockImplementation(() => Promise.resolve([])), }, + props: { component: { ...mockComponent, options: undefined } }, }); expect( @@ -94,8 +102,9 @@ describe('OptionListEditor', () => { it('should render an error message when getOptionLists throws an error', async () => { await renderOptionListEditorAndWaitForSpinnerToBeRemoved({ queries: { - getOptionLists: jest.fn().mockRejectedValueOnce(new Error('Error')), + getOptionList: jest.fn().mockRejectedValueOnce(new Error('Error')), }, + props: { component: { ...mockComponent, options: undefined } }, }); expect( @@ -104,13 +113,17 @@ describe('OptionListEditor', () => { }); it('should render the open Dialog button', async () => { - await renderOptionListEditorAndWaitForSpinnerToBeRemoved(); + await renderOptionListEditorAndWaitForSpinnerToBeRemoved({ + props: { component: { ...mockComponent, options: undefined } }, + }); expect(getOptionModalButton()).toBeInTheDocument(); }); it('should open Dialog', async () => { const user = userEvent.setup(); - await renderOptionListEditorAndWaitForSpinnerToBeRemoved(); + await renderOptionListEditorAndWaitForSpinnerToBeRemoved({ + props: { component: { ...mockComponent, options: undefined } }, + }); await user.click(getOptionModalButton()); @@ -119,7 +132,9 @@ describe('OptionListEditor', () => { it('should close Dialog', async () => { const user = userEvent.setup(); - await renderOptionListEditorAndWaitForSpinnerToBeRemoved(); + await renderOptionListEditorAndWaitForSpinnerToBeRemoved({ + props: { component: { ...mockComponent, options: undefined } }, + }); await user.click(getOptionModalButton()); await user.click(screen.getByRole('button', { name: 'close modal' })); // Todo: Replace "close modal" with defaultDialogProps.closeButtonTitle when we upgrade to Designsystemet v1 @@ -132,6 +147,7 @@ describe('OptionListEditor', () => { const doReloadPreview = jest.fn(); await renderOptionListEditorAndWaitForSpinnerToBeRemoved({ previewContextProps: { doReloadPreview }, + props: { component: { ...mockComponent, options: undefined } }, }); await user.click(getOptionModalButton()); @@ -146,7 +162,9 @@ describe('OptionListEditor', () => { it('should call updateOptionList with correct parameters when closing Dialog', async () => { const user = userEvent.setup(); - await renderOptionListEditorAndWaitForSpinnerToBeRemoved(); + await renderOptionListEditorAndWaitForSpinnerToBeRemoved({ + props: { component: { ...mockComponent, options: undefined } }, + }); const expectedResultAfterEdit: Option[] = [ { value: 'test', label: 'label text', description: 'description', helpText: 'help text' }, { value: 2, label: 'label number', description: 'test', helpText: null }, @@ -183,45 +201,28 @@ function getManualModalButton() { }); } -const renderOptionListEditor = ({ - previewContextProps = {}, - queries = {}, - component = {}, - handleComponentChange = jest.fn(), -} = {}) => { - return renderWithProviders( - , - { - queries: { - getOptionLists: jest - .fn() - .mockImplementation(() => Promise.resolve(apiResult)), - ...queries, - }, - queryClient: createQueryClientMock(), - previewContextProps, - }, - ); +const defaultProps: OptionListEditorProps = { + component: mockComponent, + handleComponentChange, +}; + +const renderOptionListEditor = ({ previewContextProps = {}, queries = {}, props = {} } = {}) => { + return renderWithProviders(, { + queries: { getOptionList: getOptionListMock, ...queries }, + queryClient: createQueryClientMock(), + previewContextProps, + }); }; const renderOptionListEditorAndWaitForSpinnerToBeRemoved = async ({ previewContextProps = {}, - queries = { - getOptionLists: jest.fn().mockImplementation(() => Promise.resolve(apiResult)), - }, - component = {}, - handleComponentChange = jest.fn(), + queries = {}, + props = {}, } = {}) => { const view = renderOptionListEditor({ previewContextProps, queries, - component, - handleComponentChange, + props, }); await waitForElementToBeRemoved(() => { return screen.queryByText(textMock('ux_editor.modal_properties_code_list_spinner_title')); diff --git a/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/OptionListEditor.tsx b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/OptionListEditor.tsx index 767d9861a24..9b6a58dc430 100644 --- a/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/OptionListEditor.tsx +++ b/frontend/packages/ux-editor/src/components/config/editModal/EditOptions/OptionTabs/EditTab/OptionListEditor/OptionListEditor.tsx @@ -1,38 +1,31 @@ -import React, { createRef, useRef, useState } from 'react'; -import type { Option } from 'app-shared/types/Option'; +import React from 'react'; import { useTranslation } from 'react-i18next'; -import { - StudioCodeListEditor, - StudioModal, - StudioSpinner, - StudioErrorMessage, - StudioAlert, - StudioProperty, -} from '@studio/components'; -import type { CodeListEditorTexts } from '@studio/components'; +import { StudioSpinner, StudioErrorMessage } from '@studio/components'; import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams'; -import { useUpdateOptionListMutation } from 'app-shared/hooks/mutations/useUpdateOptionListMutation'; -import { useOptionListsQuery } from 'app-shared/hooks/queries/useOptionListsQuery'; -import { useOptionListEditorTexts } from '../../hooks/useOptionListEditorTexts'; -import { usePreviewContext } from 'app-development/contexts/PreviewContext'; import type { IGenericEditComponent } from '../../../../../componentConfig'; import type { SelectionComponentType } from '../../../../../../../types/FormComponent'; -import classes from './OptionListEditor.module.css'; +import { useOptionListQuery } from 'app-shared/hooks/queries'; +import { LibraryOptionsEditor } from './LibraryOptionsEditor'; +import { ManualOptionsEditor } from './ManualOptionsEditor'; -type OptionListEditorProps = { - optionsId: string; - label: string; -} & Pick, 'component' | 'handleComponentChange'>; +export type OptionListEditorProps = Pick< + IGenericEditComponent, + 'component' | 'handleComponentChange' +>; export function OptionListEditor({ - optionsId, component, handleComponentChange, - label, }: OptionListEditorProps): React.ReactNode { const { t } = useTranslation(); const { org, app } = useStudioEnvironmentParams(); - const { data: optionsLists, status } = useOptionListsQuery(org, app); + const { data: optionsList, status } = useOptionListQuery(org, app, component.optionsId); + + if (component.options !== undefined) { + return ( + + ); + } switch (status) { case 'pending': @@ -46,139 +39,7 @@ export function OptionListEditor({ ); case 'success': { - if (optionsLists[optionsId] !== undefined) { - return ( - - ); - } - if (component.options !== undefined) { - return ( - - ); - } + return ; } } } - -type EditLibraryOptionListEditorModalProps = { - label: string; - optionsId: string; - optionsList: Option[]; -}; - -function EditLibraryOptionListEditorModal({ - label, - optionsId, - optionsList, -}: EditLibraryOptionListEditorModalProps): React.ReactNode { - const { t } = useTranslation(); - const { org, app } = useStudioEnvironmentParams(); - const { doReloadPreview } = usePreviewContext(); - const { mutate: updateOptionList } = useUpdateOptionListMutation(org, app); - const [localOptionList, setLocalOptionList] = useState(optionsList); - const editorTexts: CodeListEditorTexts = useOptionListEditorTexts(); - const modalRef = createRef(); - - const optionListHasChanged = (options: Option[]): boolean => - JSON.stringify(options) !== JSON.stringify(localOptionList); - - const handleBlurAny = (options: Option[]) => { - if (optionListHasChanged(options)) { - updateOptionList({ optionListId: optionsId, optionsList: options }); - setLocalOptionList(options); - doReloadPreview(); - } - }; - - const handleClose = () => { - modalRef.current?.close(); - }; - - return ( - <> - modalRef.current.showModal()} - /> - - {t('ux_editor.modal_properties_code_list_alert_title')} - - } - > - - - - ); -} - -type EditManualOptionListEditorModalProps = { - label: string; -} & Pick, 'component' | 'handleComponentChange'>; - -function EditManualOptionListEditorModal({ - label, - component, - handleComponentChange, -}: EditManualOptionListEditorModalProps): React.ReactNode { - const { t } = useTranslation(); - const modalRef = useRef(null); - const editorTexts = useOptionListEditorTexts(); - - const handleBlurAny = (options: Option[]) => { - if (component.optionsId) { - delete component.optionsId; - } - - handleComponentChange({ - ...component, - options, - }); - }; - - return ( - <> - modalRef.current.showModal()} - /> - - - - - ); -} From d3590da7ca075b1783e500b461d00e5596f15046 Mon Sep 17 00:00:00 2001 From: andreastanderen <71079896+standeren@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:29:58 +0100 Subject: [PATCH 03/10] fix: remove current code list name from list before passing to findFileNameError (#14310) Co-authored-by: Tomas Engebretsen --- .../pages/CodeListPage/CodeLists/CodeLists.test.tsx | 8 ++++++++ .../CodeListPage/CodeLists/EditCodeList/EditCodeList.tsx | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeLists/CodeLists.test.tsx b/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeLists/CodeLists.test.tsx index d549a24b490..0b6db8e869e 100644 --- a/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeLists/CodeLists.test.tsx +++ b/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeLists/CodeLists.test.tsx @@ -81,6 +81,14 @@ describe('CodeLists', () => { expect(errorMessage).toBeInTheDocument(); }); + it('does not show error message when reassigning the original name ', async () => { + const user = userEvent.setup(); + renderCodeLists({ codeListNames: [codeListName] }); + await changeCodeListId(user, codeListName, codeListName); + const errorMessage = screen.queryByText(textMock('validation_errors.file_name_occupied')); + expect(errorMessage).not.toBeInTheDocument(); + }); + it('does not call onUpdateCodeListId when assigning an invalid id to the code list', async () => { const user = userEvent.setup(); const invalidCodeListName = 'invalidCodeListName'; diff --git a/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeLists/EditCodeList/EditCodeList.tsx b/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeLists/EditCodeList/EditCodeList.tsx index 67b4b19c6b0..9d379fc4604 100644 --- a/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeLists/EditCodeList/EditCodeList.tsx +++ b/frontend/libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage/CodeLists/EditCodeList/EditCodeList.tsx @@ -6,7 +6,7 @@ import type { CodeListWithMetadata } from '../../CodeListPage'; import { useOptionListEditorTexts } from '../../hooks/useCodeListEditorTexts'; import { KeyVerticalIcon } from '@studio/icons'; import { updateCodeListWithMetadata } from '../CodeLists'; -import { FileNameUtils } from '@studio/pure-functions'; +import { ArrayUtils, FileNameUtils } from '@studio/pure-functions'; import { useInputCodeListNameErrorMessage } from '../../hooks/useInputCodeListNameErrorMessage'; import classes from './EditCodeList.module.css'; @@ -37,7 +37,8 @@ export function EditCodeList({ }; const handleValidateCodeListId = (newCodeListId: string) => { - const fileNameError = FileNameUtils.findFileNameError(newCodeListId, codeListNames); + const invalidCodeListNames = ArrayUtils.removeItemByValue(codeListNames, codeList.title); + const fileNameError = FileNameUtils.findFileNameError(newCodeListId, invalidCodeListNames); return getInvalidInputFileNameErrorMessage(fileNameError); }; From cc8754c6e250d288dca0d0171b6d5baf755ff9ec Mon Sep 17 00:00:00 2001 From: William Thorenfeldt <48119543+wrt95@users.noreply.github.com> Date: Fri, 20 Dec 2024 13:44:29 +0100 Subject: [PATCH 04/10] chore: 14264 studio radio (#14265) --- .../studio-components/src/components/StudioRadio/index.tsx | 4 ++++ frontend/libs/studio-components/src/components/index.ts | 1 + 2 files changed, 5 insertions(+) create mode 100644 frontend/libs/studio-components/src/components/StudioRadio/index.tsx diff --git a/frontend/libs/studio-components/src/components/StudioRadio/index.tsx b/frontend/libs/studio-components/src/components/StudioRadio/index.tsx new file mode 100644 index 00000000000..e8800329b68 --- /dev/null +++ b/frontend/libs/studio-components/src/components/StudioRadio/index.tsx @@ -0,0 +1,4 @@ +export { + Radio as StudioRadio, + type RadioProps as StudioRadioProps, +} from '@digdir/designsystemet-react'; diff --git a/frontend/libs/studio-components/src/components/index.ts b/frontend/libs/studio-components/src/components/index.ts index cc33f0a6924..ab5ba6ea451 100644 --- a/frontend/libs/studio-components/src/components/index.ts +++ b/frontend/libs/studio-components/src/components/index.ts @@ -36,6 +36,7 @@ export * from './StudioLabelWrapper'; export * from './StudioLink'; export * from './StudioList'; export * from './StudioModal'; +export * from './StudioRadio'; export * from './StudioNativeSelect'; export * from './StudioNotFoundPage'; export * from './StudioPageError'; From ce1ab8b031d7d62b73ce68035a3c2fe1be216c5e Mon Sep 17 00:00:00 2001 From: Jonas Dyrlie Date: Mon, 23 Dec 2024 08:19:45 +0100 Subject: [PATCH 05/10] feat(subform): Add GET and PUT endpoints for datamodel metadata (#14275) --- .../Controllers/DatamodelsController.cs | 29 ++++++ .../Implementation/SchemaModelService.cs | 25 ++++- .../Interfaces/ISchemaModelService.cs | 10 ++ .../DataModelsController/GetTests.cs | 43 ++++++++- .../DataModelsController/PutDatamodelTests.cs | 50 ++++++++++ .../Services/SchemaModelServiceTests.cs | 96 +++++++------------ 6 files changed, 190 insertions(+), 63 deletions(-) diff --git a/backend/src/Designer/Controllers/DatamodelsController.cs b/backend/src/Designer/Controllers/DatamodelsController.cs index f7c57a88525..6417218debf 100644 --- a/backend/src/Designer/Controllers/DatamodelsController.cs +++ b/backend/src/Designer/Controllers/DatamodelsController.cs @@ -6,6 +6,7 @@ using System.Text.Json.Nodes; using System.Threading; using System.Threading.Tasks; +using Altinn.Platform.Storage.Interface.Models; using Altinn.Studio.DataModeling.Validator.Json; using Altinn.Studio.Designer.Filters; using Altinn.Studio.Designer.Helpers; @@ -248,6 +249,34 @@ public async Task UseXsdFromRepo(string org, string repository, s } } + /// + /// Gets the dataType for a given data model. + /// + [HttpGet("datamodel/{modelName}/dataType")] + [UseSystemTextJson] + public async Task> GetModelDataType(string org, string repository, string modelName) + { + DataType dataType = await _schemaModelService.GetModelDataType(org, repository, modelName); + return Ok(dataType); + } + + /// + /// Updates the dataType for a given data model. + /// + [HttpPut("datamodel/{modelName}/dataType")] + [UseSystemTextJson] + public async Task SetModelDataType(string org, string repository, string modelName, [FromBody] DataType dataType) + { + if (!Equals(modelName, dataType.Id)) + { + return BadRequest("Model name in path and request body does not match"); + } + + await _schemaModelService.SetModelDataType(org, repository, modelName, dataType); + DataType updatedDataType = await _schemaModelService.GetModelDataType(org, repository, modelName); + return Ok(updatedDataType); + } + private static string GetFileNameFromUploadedFile(IFormFile thefile) { return ContentDispositionHeaderValue.Parse(new StringSegment(thefile.ContentDisposition)).FileName.ToString(); diff --git a/backend/src/Designer/Services/Implementation/SchemaModelService.cs b/backend/src/Designer/Services/Implementation/SchemaModelService.cs index 3067a31d98d..556440a7e3c 100644 --- a/backend/src/Designer/Services/Implementation/SchemaModelService.cs +++ b/backend/src/Designer/Services/Implementation/SchemaModelService.cs @@ -40,6 +40,7 @@ public class SchemaModelService : ISchemaModelService private readonly IXmlSchemaToJsonSchemaConverter _xmlSchemaToJsonSchemaConverter; private readonly IJsonSchemaToXmlSchemaConverter _jsonSchemaToXmlSchemaConverter; private readonly IModelMetadataToCsharpConverter _modelMetadataToCsharpConverter; + private readonly IApplicationMetadataService _applicationMetadataService; /// /// Initializes a new instance of the class. @@ -59,13 +60,15 @@ public class SchemaModelService : ISchemaModelService /// /// Class for converting Json schemas to Xml schemas. /// C# model generator + /// public SchemaModelService( IAltinnGitRepositoryFactory altinnGitRepositoryFactory, ILoggerFactory loggerFactory, ServiceRepositorySettings serviceRepositorySettings, IXmlSchemaToJsonSchemaConverter xmlSchemaToJsonSchemaConverter, IJsonSchemaToXmlSchemaConverter jsonSchemaToXmlSchemaConverter, - IModelMetadataToCsharpConverter modelMetadataToCsharpConverter) + IModelMetadataToCsharpConverter modelMetadataToCsharpConverter, + IApplicationMetadataService applicationMetadataService) { _altinnGitRepositoryFactory = altinnGitRepositoryFactory; _loggerFactory = loggerFactory; @@ -73,6 +76,7 @@ public SchemaModelService( _xmlSchemaToJsonSchemaConverter = xmlSchemaToJsonSchemaConverter; _jsonSchemaToXmlSchemaConverter = jsonSchemaToXmlSchemaConverter; _modelMetadataToCsharpConverter = modelMetadataToCsharpConverter; + _applicationMetadataService = applicationMetadataService; } /// @@ -431,5 +435,24 @@ private bool NamespaceNeedsToBeSeparated(ApplicationMetadata application, { return application.DataTypes.All(d => d.AppLogic?.ClassRef != $"Altinn.App.Models.{csharpModelName}"); } + + public async Task GetModelDataType(string org, string app, string modelId) + { + ApplicationMetadata applicationMetadata = await _applicationMetadataService.GetApplicationMetadataFromRepository(org, app); + DataType dataType = applicationMetadata.DataTypes.Find((dataType) => dataType.Id == modelId); + return dataType; + } + + public async Task SetModelDataType(string org, string app, string modelId, DataType dataType) + { + if (dataType.Id != modelId) + { + throw new ArgumentException("Provided modelId does not match the DataType's Id"); + } + ApplicationMetadata applicationMetadata = await _applicationMetadataService.GetApplicationMetadataFromRepository(org, app); + applicationMetadata.DataTypes.RemoveAll((dt) => dt.Id == dataType.Id); + applicationMetadata.DataTypes.Add(dataType); + await _applicationMetadataService.UpdateApplicationMetaDataLocally(org, app, applicationMetadata); + } } } diff --git a/backend/src/Designer/Services/Interfaces/ISchemaModelService.cs b/backend/src/Designer/Services/Interfaces/ISchemaModelService.cs index c043f7fa8cd..16cc0a91f34 100644 --- a/backend/src/Designer/Services/Interfaces/ISchemaModelService.cs +++ b/backend/src/Designer/Services/Interfaces/ISchemaModelService.cs @@ -84,5 +84,15 @@ public interface ISchemaModelService /// An that observes if operation is cancelled. /// Returns the model metadata Task GenerateModelMetadataFromJsonSchema(AltinnRepoEditingContext altinnRepoEditingContext, string relativeFilePath, CancellationToken cancellationToken = default); + + /// + /// Gets the dataType for a given model. + /// + Task GetModelDataType(string org, string app, string modelId); + + /// + /// Updates the dataType for a given model. + /// + Task SetModelDataType(string org, string app, string modelId, DataType dataType); } } diff --git a/backend/tests/Designer.Tests/Controllers/DataModelsController/GetTests.cs b/backend/tests/Designer.Tests/Controllers/DataModelsController/GetTests.cs index bac7b5943e7..31c013aa15f 100644 --- a/backend/tests/Designer.Tests/Controllers/DataModelsController/GetTests.cs +++ b/backend/tests/Designer.Tests/Controllers/DataModelsController/GetTests.cs @@ -1,6 +1,9 @@ -using System.Net; +using System.Collections.Generic; +using System.Net; using System.Net.Http; +using System.Net.Http.Json; using System.Threading.Tasks; +using Altinn.Platform.Storage.Interface.Models; using Designer.Tests.Controllers.ApiTests; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; @@ -26,4 +29,42 @@ public async Task GetDatamodel_ValidPath_ShouldReturnContent(string modelPath, s using var response = await HttpClient.SendAsync(httpRequestMessage); response.StatusCode.Should().Be(HttpStatusCode.OK); } + + [Theory] + [InlineData("Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES", "ttd", "hvem-er-hvem")] + public async Task GetDatamodelDataType_ShouldReturnContent(string modelName, string org, string repo) + { + string url = $"{VersionPrefix(org, repo)}/datamodel/{modelName}/dataType"; + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url); + + using HttpResponseMessage response = await HttpClient.SendAsync(httpRequestMessage); + response.StatusCode.Should().Be(HttpStatusCode.OK); + DataType dataTypeResponse = await response.Content.ReadFromJsonAsync(); + dataTypeResponse.Should().NotBeNull(); + dataTypeResponse.Should().BeEquivalentTo(new DataType + { + Id = "Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES", + AllowedContentTypes = new List { "application/xml" }, + AppLogic = new ApplicationLogic + { + AutoCreate = true, + ClassRef = "Altinn.App.Models.HvemErHvem_M" + }, + TaskId = "Task_1", + MaxCount = 1, + MinCount = 1 + }); + } + + [Theory] + [InlineData("notfound", "ttd", "hvem-er-hvem")] + public async Task GetDatamodelDataType_ShouldNullWhenNotFound(string modelName, string org, string repo) + { + string url = $"{VersionPrefix(org, repo)}/datamodel/{modelName}/dataType"; + using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url); + + using HttpResponseMessage response = await HttpClient.SendAsync(httpRequestMessage); + response.StatusCode.Should().Be(HttpStatusCode.OK); + (await response.Content.ReadAsStringAsync()).Should().Be("null"); + } } diff --git a/backend/tests/Designer.Tests/Controllers/DataModelsController/PutDatamodelTests.cs b/backend/tests/Designer.Tests/Controllers/DataModelsController/PutDatamodelTests.cs index 0ee22606477..4db5c7cf72f 100644 --- a/backend/tests/Designer.Tests/Controllers/DataModelsController/PutDatamodelTests.cs +++ b/backend/tests/Designer.Tests/Controllers/DataModelsController/PutDatamodelTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Http.Json; using System.Net.Mime; using System.Text; using System.Text.Json; @@ -11,6 +12,7 @@ using System.Web; using System.Xml; using System.Xml.Schema; +using Altinn.Platform.Storage.Interface.Models; using Altinn.Studio.DataModeling.Converter.Json; using Altinn.Studio.DataModeling.Converter.Json.Strategy; using Altinn.Studio.DataModeling.Converter.Metadata; @@ -144,6 +146,54 @@ public async Task IncompatibleSchema_ShouldReturn422(string modelPath, string sc } } + [Theory] + [InlineData("testmodelname", "ttd", "hvem-er-hvem")] + public async Task PutDatamodelDataType_ShouldReturnWithoutErrors(string datamodelName, string org, string repo) + { + string url = $"{VersionPrefix(org, TargetTestRepository)}/datamodel/{datamodelName}/dataType"; + await CopyRepositoryForTest(org, repo, "testUser", TargetTestRepository); + + DataType dataType = new() + { + Id = datamodelName, + MaxCount = 1, + MinCount = 1, + }; + using var putRequest = new HttpRequestMessage(HttpMethod.Put, url) + { + Content = JsonContent.Create(dataType) + }; + + HttpResponseMessage response = await HttpClient.SendAsync(putRequest); + response.StatusCode.Should().Be(HttpStatusCode.OK); + DataType dataTypeResponse = await response.Content.ReadFromJsonAsync(); + dataTypeResponse.Should().NotBeNull(); + dataTypeResponse.Should().BeEquivalentTo(dataType); + } + + [Theory] + [InlineData("testmodelname", "ttd", "hvem-er-hvem")] + public async Task PutDatamodelDataType_FailsIfDatamodelNameMismatchesObjectId(string datamodelName, string org, string repo) + { + string url = $"{VersionPrefix(org, TargetTestRepository)}/datamodel/{datamodelName}/dataType"; + await CopyRepositoryForTest(org, repo, "testUser", TargetTestRepository); + + DataType dataType = new() + { + Id = "wrongId", + MaxCount = 1, + MinCount = 1, + }; + using var putRequest = new HttpRequestMessage(HttpMethod.Put, url) + { + Content = JsonContent.Create(dataType) + }; + + HttpResponseMessage response = await HttpClient.SendAsync(putRequest); + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + } + + private async Task FilesWithCorrectNameAndContentShouldBeCreated(string modelName) { var location = Path.GetFullPath(Path.Combine(TestRepoPath, "App", "models")); diff --git a/backend/tests/Designer.Tests/Services/SchemaModelServiceTests.cs b/backend/tests/Designer.Tests/Services/SchemaModelServiceTests.cs index a4febf21116..344f341d896 100644 --- a/backend/tests/Designer.Tests/Services/SchemaModelServiceTests.cs +++ b/backend/tests/Designer.Tests/Services/SchemaModelServiceTests.cs @@ -15,6 +15,7 @@ using Altinn.Studio.Designer.Services.Interfaces; using Designer.Tests.Utils; using FluentAssertions; +using Moq; using SharedResources.Tests; using Xunit; @@ -22,6 +23,17 @@ namespace Designer.Tests.Services { public class SchemaModelServiceTests { + private readonly Mock _applicationMetadataService; + private readonly AltinnGitRepositoryFactory _altinnGitRepositoryFactory; + private readonly ISchemaModelService _schemaModelService; + + public SchemaModelServiceTests() + { + _applicationMetadataService = new Mock(); + _altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); + _schemaModelService = new SchemaModelService(_altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter, _applicationMetadataService.Object); + } + [Fact] public async Task DeleteSchema_AppRepo_ShouldDelete() { @@ -35,22 +47,19 @@ public async Task DeleteSchema_AppRepo_ShouldDelete() await TestDataHelper.CopyRepositoryForTest(org, sourceRepository, developer, targetRepository); try { - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); - - ISchemaModelService schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter); - var schemaFiles = schemaModelService.GetSchemaFiles(editingContext); + var schemaFiles = _schemaModelService.GetSchemaFiles(editingContext); schemaFiles.Should().HaveCount(7); - var altinnAppGitRepository = altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, targetRepository, developer); + var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, targetRepository, developer); var applicationMetadata = await altinnAppGitRepository.GetApplicationMetadata(); applicationMetadata.DataTypes.Should().HaveCount(2); // Act var schemaToDelete = schemaFiles.First(s => s.FileName == "Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES.schema.json"); - await schemaModelService.DeleteSchema(editingContext, schemaToDelete.RepositoryRelativeUrl); + await _schemaModelService.DeleteSchema(editingContext, schemaToDelete.RepositoryRelativeUrl); // Assert - schemaFiles = schemaModelService.GetSchemaFiles(editingContext); + schemaFiles = _schemaModelService.GetSchemaFiles(editingContext); schemaFiles.Should().HaveCount(6); applicationMetadata = await altinnAppGitRepository.GetApplicationMetadata(); applicationMetadata.DataTypes.Should().HaveCount(1); @@ -75,22 +84,20 @@ public async Task DeleteSchema_AppRepoWithLayoutSets_ShouldDelete() try { string dataModelName = "datamodel"; - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); - ISchemaModelService schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter); - var schemaFiles = schemaModelService.GetSchemaFiles(editingContext); + var schemaFiles = _schemaModelService.GetSchemaFiles(editingContext); schemaFiles.Should().HaveCount(1); - var altinnAppGitRepository = altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, targetRepository, developer); + var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, targetRepository, developer); var applicationMetadataBefore = await altinnAppGitRepository.GetApplicationMetadata(); var layoutSetsBefore = await altinnAppGitRepository.GetLayoutSetsFile(); // Act var schemaToDelete = schemaFiles.First(s => s.FileName == $"{dataModelName}.schema.json"); - await schemaModelService.DeleteSchema(editingContext, schemaToDelete.RepositoryRelativeUrl); + await _schemaModelService.DeleteSchema(editingContext, schemaToDelete.RepositoryRelativeUrl); // Assert - schemaFiles = schemaModelService.GetSchemaFiles(editingContext); + schemaFiles = _schemaModelService.GetSchemaFiles(editingContext); schemaFiles.Should().HaveCount(0); var applicationMetadataAfter = await altinnAppGitRepository.GetApplicationMetadata(); applicationMetadataAfter.DataTypes.Should().HaveCount(applicationMetadataBefore.DataTypes.Count - 1); @@ -117,18 +124,16 @@ public async Task DeleteSchema_ModelsRepo_ShouldDelete() await TestDataHelper.CopyRepositoryForTest(org, sourceRepository, developer, targetRepository); try { - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); - ISchemaModelService schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter); - var schemaFiles = schemaModelService.GetSchemaFiles(editingContext); + var schemaFiles = _schemaModelService.GetSchemaFiles(editingContext); schemaFiles.Should().HaveCount(6); // Act var schemaToDelete = schemaFiles.First(s => s.FileName == "Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES.schema.json"); - await schemaModelService.DeleteSchema(editingContext, schemaToDelete.RepositoryRelativeUrl); + await _schemaModelService.DeleteSchema(editingContext, schemaToDelete.RepositoryRelativeUrl); // Assert - schemaFiles = schemaModelService.GetSchemaFiles(editingContext); + schemaFiles = _schemaModelService.GetSchemaFiles(editingContext); schemaFiles.Should().HaveCount(5); } finally @@ -150,15 +155,13 @@ public async Task UpdateSchema_AppRepo_ShouldUpdate() await TestDataHelper.CopyRepositoryForTest(org, sourceRepository, developer, targetRepository); try { - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); // Act - ISchemaModelService schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter); var expectedSchemaUpdates = @"{""properties"":{""rootType1"":{""$ref"":""#/definitions/rootType""}},""definitions"":{""rootType"":{""properties"":{""keyword"":{""type"":""string""}}}}}"; - await schemaModelService.UpdateSchema(editingContext, "App/models/HvemErHvem_SERES.schema.json", expectedSchemaUpdates); + await _schemaModelService.UpdateSchema(editingContext, "App/models/HvemErHvem_SERES.schema.json", expectedSchemaUpdates); // Assert - var altinnGitRepository = altinnGitRepositoryFactory.GetAltinnGitRepository(org, targetRepository, developer); + var altinnGitRepository = _altinnGitRepositoryFactory.GetAltinnGitRepository(org, targetRepository, developer); var updatedSchema = await altinnGitRepository.ReadTextByRelativePathAsync("App/models/HvemErHvem_SERES.schema.json"); string serializedExpectedSchemaUpdates = FormatJsonString(updatedSchema); @@ -199,13 +202,11 @@ public async Task UpdateSchema_ModelMetadataExistForModelInRepo_ShouldDeleteMode await TestDataHelper.CopyRepositoryForTest(org, sourceRepository, developer, targetRepository); try { - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); - ISchemaModelService schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter); var updatedSchema = @"{""properties"":{""rootType1"":{""$ref"":""#/definitions/rootType""}},""definitions"":{""rootType"":{""properties"":{""keyword"":{""type"":""string""}}}}}"; - var altinnGitRepository = altinnGitRepositoryFactory.GetAltinnGitRepository(org, targetRepository, developer); + var altinnGitRepository = _altinnGitRepositoryFactory.GetAltinnGitRepository(org, targetRepository, developer); Assert.True(altinnGitRepository.FileExistsByRelativePath("App/models/Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES.metadata.json")); - await schemaModelService.UpdateSchema(editingContext, "App/models/Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES.schema.json", updatedSchema); + await _schemaModelService.UpdateSchema(editingContext, "App/models/Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES.schema.json", updatedSchema); Assert.False(altinnGitRepository.FileExistsByRelativePath("App/models/Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES.metadata.json")); } finally @@ -227,13 +228,11 @@ public async Task UpdateSchema_NoModelMetadataForModelInRepo_ShouldOnlyUpdate() await TestDataHelper.CopyRepositoryForTest(org, sourceRepository, developer, targetRepository); try { - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); - ISchemaModelService schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter); var expectedUpdatedSchema = @"{""properties"":{""rootType1"":{""$ref"":""#/definitions/rootType""}},""definitions"":{""rootType"":{""properties"":{""keyword"":{""type"":""string""}}}}}"; - var altinnGitRepository = altinnGitRepositoryFactory.GetAltinnGitRepository(org, targetRepository, developer); + var altinnGitRepository = _altinnGitRepositoryFactory.GetAltinnGitRepository(org, targetRepository, developer); Assert.False(altinnGitRepository.FileExistsByRelativePath("App/models/HvemErHvem_SERES.metadata.json")); - await schemaModelService.UpdateSchema(editingContext, "App/models/HvemErHvem_SERES.schema.json", expectedUpdatedSchema); + await _schemaModelService.UpdateSchema(editingContext, "App/models/HvemErHvem_SERES.schema.json", expectedUpdatedSchema); Assert.False(altinnGitRepository.FileExistsByRelativePath("App/models/HvemErHvem_SERES.metadata.json")); var updatedSchema = await altinnGitRepository.ReadTextByRelativePathAsync("App/models/HvemErHvem_SERES.schema.json"); string serializedExpectedSchemaUpdates = FormatJsonString(updatedSchema); @@ -257,37 +256,18 @@ public async Task UpdateSchema_InvalidJsonSchema_ShouldThrowException() await TestDataHelper.CopyRepositoryForTest(org, sourceRepository, developer, targetRepository); - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); - - ISchemaModelService schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, - TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, - TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, - TestDataHelper.ModelMetadataToCsharpConverter); var invalidSchema = @"{""properties"":{""root"":{""$ref"":""#/definitions/rootType""}},""definitions"":{""rootType"":{""properties"":{""keyword"":{""type"":""string""}}}}}"; var exception = await Assert.ThrowsAsync(async () => { - await schemaModelService.UpdateSchema(editingContext, "App/models/HvemErHvem_SERES.schema.json", invalidSchema); + await _schemaModelService.UpdateSchema(editingContext, "App/models/HvemErHvem_SERES.schema.json", invalidSchema); }); Assert.NotNull(exception.CustomErrorMessages); exception.CustomErrorMessages.Should().ContainSingle(c => c.Contains("root': member names cannot be the same as their enclosing type")); } - [Theory] - [InlineData("ttd", "apprepo", "test", "", "http://studio.localhost/repos")] - [InlineData("ttd", "apprepo", "test", "/path/to/folder/", "http://studio.localhost/repos")] - public void GetSchemaUri_ValidNameProvided_ShouldReturnUri(string org, string repository, string schemaName, string relativePath, string repositoryBaseUrl) - { - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); - var schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter); - - var schemaUri = schemaModelService.GetSchemaUri(org, repository, schemaName, relativePath); - - schemaUri.AbsoluteUri.Should().Be($"{repositoryBaseUrl}/{org}/{repository}{(string.IsNullOrEmpty(relativePath) ? "/" : relativePath)}{schemaName}.schema.json"); - } - [Fact] public async Task UploadSchemaFromXsd_InvalidXsd_ThrowsException() { @@ -301,13 +281,11 @@ public async Task UploadSchemaFromXsd_InvalidXsd_ThrowsException() await TestDataHelper.CopyRepositoryForTest(org, sourceRepository, developer, targetRepository); try { - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); - ISchemaModelService schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter); var xsdStream = SharedResourcesHelper.LoadTestData("Model/XmlSchema/General/SimpleInvalidNonSeresSchema.xsd"); var schemaName = "SimpleInvalidNonSeresSchema"; var fileName = $"{schemaName}.xsd"; - Func action = () => schemaModelService.BuildSchemaFromXsd(editingContext, fileName, xsdStream); + Func action = () => _schemaModelService.BuildSchemaFromXsd(editingContext, fileName, xsdStream); // Act/assert await action.Should().ThrowAsync(); @@ -333,8 +311,6 @@ public async Task UploadSchemaFromXsd_ValidNonSeresXsd_ModelsCreated() await TestDataHelper.CopyRepositoryForTest(org, sourceRepository, developer, targetRepository); try { - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); - ISchemaModelService schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter); var xsdStream = SharedResourcesHelper.LoadTestData("Model/XmlSchema/General/SimpleValidNonSeresSchema.xsd"); var schemaName = "SimpleValidNonSeresSchema"; var fileName = $"{schemaName}.xsd"; @@ -342,10 +318,10 @@ public async Task UploadSchemaFromXsd_ValidNonSeresXsd_ModelsCreated() var relativeFilePath = $"{relativeDirectory}/{fileName}"; // Act - await schemaModelService.BuildSchemaFromXsd(editingContext, fileName, xsdStream); + await _schemaModelService.BuildSchemaFromXsd(editingContext, fileName, xsdStream); // Assert - var altinnAppGitRepository = altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, targetRepository, developer); + var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, targetRepository, developer); altinnAppGitRepository.FileExistsByRelativePath($"{relativeDirectory}/{schemaName}.metadata.json").Should().BeFalse(); altinnAppGitRepository.FileExistsByRelativePath($"{relativeDirectory}/{schemaName}.schema.json").Should().BeTrue(); altinnAppGitRepository.FileExistsByRelativePath($"{relativeDirectory}/{schemaName}.cs").Should().BeTrue(); @@ -371,8 +347,6 @@ public async Task UploadSchemaFromXsd_OED_ModelsCreated() await TestDataHelper.CopyRepositoryForTest(org, sourceRepository, developer, targetRepository); try { - var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(TestDataHelper.GetTestDataRepositoriesRootDirectory()); - ISchemaModelService schemaModelService = new SchemaModelService(altinnGitRepositoryFactory, TestDataHelper.LogFactory, TestDataHelper.ServiceRepositorySettings, TestDataHelper.XmlSchemaToJsonSchemaConverter, TestDataHelper.JsonSchemaToXmlSchemaConverter, TestDataHelper.ModelMetadataToCsharpConverter); var xsdStream = SharedResourcesHelper.LoadTestData("Model/XmlSchema/Gitea/OED.xsd"); var schemaName = "OED_M"; var fileName = $"{schemaName}.xsd"; @@ -380,10 +354,10 @@ public async Task UploadSchemaFromXsd_OED_ModelsCreated() var relativeFilePath = $"{relativeDirectory}/{fileName}"; // Act - await schemaModelService.BuildSchemaFromXsd(editingContext, fileName, xsdStream); + await _schemaModelService.BuildSchemaFromXsd(editingContext, fileName, xsdStream); // Assert - var altinnAppGitRepository = altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, targetRepository, developer); + var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, targetRepository, developer); altinnAppGitRepository.FileExistsByRelativePath($"{relativeDirectory}/{schemaName}.metadata.json").Should().BeFalse(); altinnAppGitRepository.FileExistsByRelativePath($"{relativeDirectory}/{schemaName}.schema.json").Should().BeTrue(); altinnAppGitRepository.FileExistsByRelativePath($"{relativeDirectory}/{schemaName}.xsd").Should().BeTrue(); From 9e7c8aa818fea0f2da64bcffa88fbe143db2df4a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 09:53:19 +0100 Subject: [PATCH 06/10] chore(deps): update dependency wiremock.net to 1.6.10 (#14323) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- backend/packagegroups/NuGet.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/packagegroups/NuGet.props b/backend/packagegroups/NuGet.props index 1007d47fed8..fff7d4fe0d7 100644 --- a/backend/packagegroups/NuGet.props +++ b/backend/packagegroups/NuGet.props @@ -62,7 +62,7 @@ - + From ef16e9dfc3ef2e29136fe6bc1581913eb5aa3a56 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:15:43 +0100 Subject: [PATCH 07/10] fix(deps): update npm non-major dependencies (#14325) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: andreastanderen <71079896+standeren@users.noreply.github.com> --- development/azure-devops-mock/package.json | 2 +- frontend/libs/studio-components/package.json | 2 +- frontend/packages/shared/package.json | 2 +- frontend/testing/cypress/package.json | 2 +- package.json | 10 +- yarn.lock | 134 +++++++++++++------ 6 files changed, 100 insertions(+), 52 deletions(-) diff --git a/development/azure-devops-mock/package.json b/development/azure-devops-mock/package.json index 3594cd34bc4..56c1da5a7d8 100644 --- a/development/azure-devops-mock/package.json +++ b/development/azure-devops-mock/package.json @@ -8,7 +8,7 @@ "cors": "2.8.5", "express": "4.21.2", "morgan": "1.10.0", - "nodemon": "3.1.7", + "nodemon": "3.1.9", "p-queue": "8.0.1" }, "license": "MIT", diff --git a/frontend/libs/studio-components/package.json b/frontend/libs/studio-components/package.json index 56a3dd4a574..1debe85a4ef 100644 --- a/frontend/libs/studio-components/package.json +++ b/frontend/libs/studio-components/package.json @@ -20,7 +20,7 @@ "uuid": "10.0.0" }, "devDependencies": { - "@chromatic-com/storybook": "3.2.2", + "@chromatic-com/storybook": "3.2.3", "@storybook/addon-essentials": "8.4.7", "@storybook/addon-interactions": "8.4.7", "@storybook/addon-links": "8.4.7", diff --git a/frontend/packages/shared/package.json b/frontend/packages/shared/package.json index 52e462ff57f..47215eb50e5 100644 --- a/frontend/packages/shared/package.json +++ b/frontend/packages/shared/package.json @@ -10,7 +10,7 @@ "react-router-dom": "6.28.0" }, "devDependencies": { - "@types/react": "18.3.16", + "@types/react": "18.3.18", "jest": "29.7.0", "typescript": "5.7.2" }, diff --git a/frontend/testing/cypress/package.json b/frontend/testing/cypress/package.json index f31efe32e97..5935921731f 100644 --- a/frontend/testing/cypress/package.json +++ b/frontend/testing/cypress/package.json @@ -5,7 +5,7 @@ "devDependencies": { "@testing-library/cypress": "10.0.2", "axe-core": "4.10.2", - "cypress": "13.16.1", + "cypress": "13.17.0", "cypress-axe": "1.5.0", "cypress-plugin-tab": "1.0.5", "eslint": "8.57.1" diff --git a/package.json b/package.json index 10db2015a30..3cf54b1adfe 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "@microsoft/applicationinsights-react-js": "17.3.4", "@microsoft/applicationinsights-web": "3.3.4", "@microsoft/signalr": "8.0.7", - "@tanstack/react-query": "5.62.7", - "@tanstack/react-query-devtools": "5.62.7", + "@tanstack/react-query": "5.62.8", + "@tanstack/react-query-devtools": "5.62.8", "ajv": "8.17.1", "ajv-formats": "3.0.1", "i18next": "23.16.8", @@ -33,7 +33,7 @@ "@testing-library/user-event": "14.5.2", "@types/css-modules": "1.0.5", "@types/jest": "29.5.14", - "@types/react": "18.3.16", + "@types/react": "18.3.18", "@types/react-dom": "18.3.5", "@typescript-eslint/eslint-plugin": "7.18.0", "@typescript-eslint/parser": "7.18.0", @@ -57,7 +57,7 @@ "prettier": "3.4.2", "source-map-loader": "5.0.0", "swc-loader": "0.2.6", - "terser-webpack-plugin": "5.3.10", + "terser-webpack-plugin": "5.3.11", "typescript": "5.7.2", "typescript-plugin-css-modules": "5.1.0", "webpack": "5.97.1", @@ -68,7 +68,7 @@ "resolutions": { "@testing-library/dom": "10.4.0", "@babel/traverse": "7.26.4", - "caniuse-lite": "1.0.30001688" + "caniuse-lite": "1.0.30001690" }, "lint-staged": { "*{js,jsx,tsx,ts,css,md}": "prettier -w", diff --git a/yarn.lock b/yarn.lock index fe8edc9a777..71cc125a53c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1941,9 +1941,9 @@ __metadata: languageName: node linkType: hard -"@chromatic-com/storybook@npm:3.2.2": - version: 3.2.2 - resolution: "@chromatic-com/storybook@npm:3.2.2" +"@chromatic-com/storybook@npm:3.2.3": + version: 3.2.3 + resolution: "@chromatic-com/storybook@npm:3.2.3" dependencies: chromatic: "npm:^11.15.0" filesize: "npm:^10.0.12" @@ -1952,7 +1952,7 @@ __metadata: strip-ansi: "npm:^7.1.0" peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/71338edf56cdbc855074c78981f2e1612b364cd864fa99bbda5c0aad147769b9f476de2fd76816102fd504efc5c0c54ba559d5ac9e3828d53278fe7000863d54 + checksum: 10/6aa32ff8a227c5ada0667457a36d5db1946f9d89b8fb64153150445c8b67f26647aa48a6afce21f6dc2cad4905418f37c2fd0b12d26c3a42a36edf45b52efb7b languageName: node linkType: hard @@ -4131,7 +4131,7 @@ __metadata: version: 0.0.0-use.local resolution: "@studio/components@workspace:frontend/libs/studio-components" dependencies: - "@chromatic-com/storybook": "npm:3.2.2" + "@chromatic-com/storybook": "npm:3.2.3" "@storybook/addon-essentials": "npm:8.4.7" "@storybook/addon-interactions": "npm:8.4.7" "@storybook/addon-links": "npm:8.4.7" @@ -4654,10 +4654,10 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:5.62.7": - version: 5.62.7 - resolution: "@tanstack/query-core@npm:5.62.7" - checksum: 10/84172d297196a5fb5704c75c99deddd776e258ad589cf1a66a2a71341bc81452305b260e57825f729e4d07ca7bc920ba1a3208f7a192b347751fee0fff5fc9fd +"@tanstack/query-core@npm:5.62.8": + version: 5.62.8 + resolution: "@tanstack/query-core@npm:5.62.8" + checksum: 10/6ce74cc1fba12f219db45423602603a129fdf30d29418f9b5950525725119b8dc136c504ee90fb8aa9e5c10b1f9f4eb3ef0b07fe4b71b194c97c32b8d738d09b languageName: node linkType: hard @@ -4668,26 +4668,26 @@ __metadata: languageName: node linkType: hard -"@tanstack/react-query-devtools@npm:5.62.7": - version: 5.62.7 - resolution: "@tanstack/react-query-devtools@npm:5.62.7" +"@tanstack/react-query-devtools@npm:5.62.8": + version: 5.62.8 + resolution: "@tanstack/react-query-devtools@npm:5.62.8" dependencies: "@tanstack/query-devtools": "npm:5.61.4" peerDependencies: - "@tanstack/react-query": ^5.62.7 + "@tanstack/react-query": ^5.62.8 react: ^18 || ^19 - checksum: 10/6c8172551631ea53b9629edeafea00c668f77f3ba17dcda576be652cd5847d08acb5111605bfb6a8002bdf686373427db7b8a3bd03b9dcbf704dee2968c92109 + checksum: 10/6be35af231f6b08f40c1563a167f488dd855dfd5d706339598a9e304e291b5dc60ef1610523bbfb97f4606a9bccbbc8f35fa10cd9c716e5d5fe80e9d5a8c4e00 languageName: node linkType: hard -"@tanstack/react-query@npm:5.62.7": - version: 5.62.7 - resolution: "@tanstack/react-query@npm:5.62.7" +"@tanstack/react-query@npm:5.62.8": + version: 5.62.8 + resolution: "@tanstack/react-query@npm:5.62.8" dependencies: - "@tanstack/query-core": "npm:5.62.7" + "@tanstack/query-core": "npm:5.62.8" peerDependencies: react: ^18 || ^19 - checksum: 10/7943420d1beaa2fd6defa0a9886722af5af940e6d2be3acc6b8b28ee28037ac1e8f302471a63f6692aa84e779fb9444c3a51be2e1e9987dc92d24e4947498221 + checksum: 10/26d642aea205a75a624abc55daa11e5336eddad921a0dd17a6ffc1780b8366feb6cacf25d81cee14c48f2dcc9e4ba46a480d2fe68c7e1b68ff0d83e3ad363fa5 languageName: node linkType: hard @@ -5242,13 +5242,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:18.3.16": - version: 18.3.16 - resolution: "@types/react@npm:18.3.16" +"@types/react@npm:18.3.18": + version: 18.3.18 + resolution: "@types/react@npm:18.3.18" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/971b4f46af9aeda85326000ba4a78973db6a1f11e10665c014e1274a68ae801469f057b56d850512694cf04a69cc264c07e6a507b4613874e8bf6ab4df7904f1 + checksum: 10/7fdd8b853e0d291d4138133f93f8d5c333da918e5804afcea61a923aab4bdfc9bb15eb21a5640959b452972b8715ddf10ffb12b3bd071898b9e37738636463f2 languageName: node linkType: hard @@ -6311,15 +6311,15 @@ __metadata: "@svgr/webpack": "npm:8.1.0" "@swc/core": "npm:1.10.1" "@swc/jest": "npm:0.2.37" - "@tanstack/react-query": "npm:5.62.7" - "@tanstack/react-query-devtools": "npm:5.62.7" + "@tanstack/react-query": "npm:5.62.8" + "@tanstack/react-query-devtools": "npm:5.62.8" "@testing-library/dom": "npm:10.4.0" "@testing-library/jest-dom": "npm:6.6.3" "@testing-library/react": "npm:16.1.0" "@testing-library/user-event": "npm:14.5.2" "@types/css-modules": "npm:1.0.5" "@types/jest": "npm:29.5.14" - "@types/react": "npm:18.3.16" + "@types/react": "npm:18.3.18" "@types/react-dom": "npm:18.3.5" "@typescript-eslint/eslint-plugin": "npm:7.18.0" "@typescript-eslint/parser": "npm:7.18.0" @@ -6353,7 +6353,7 @@ __metadata: react-toastify: "npm:10.0.6" source-map-loader: "npm:5.0.0" swc-loader: "npm:0.2.6" - terser-webpack-plugin: "npm:5.3.10" + terser-webpack-plugin: "npm:5.3.11" typescript: "npm:5.7.2" typescript-plugin-css-modules: "npm:5.1.0" webpack: "npm:5.97.1" @@ -6496,7 +6496,7 @@ __metadata: version: 0.0.0-use.local resolution: "app-shared@workspace:frontend/packages/shared" dependencies: - "@types/react": "npm:18.3.16" + "@types/react": "npm:18.3.18" classnames: "npm:2.5.1" jest: "npm:29.7.0" qs: "npm:6.13.1" @@ -6915,7 +6915,7 @@ __metadata: cors: "npm:2.8.5" express: "npm:4.21.2" morgan: "npm:1.10.0" - nodemon: "npm:3.1.7" + nodemon: "npm:3.1.9" p-queue: "npm:8.0.1" languageName: unknown linkType: soft @@ -7430,10 +7430,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:1.0.30001688": - version: 1.0.30001688 - resolution: "caniuse-lite@npm:1.0.30001688" - checksum: 10/2125e900af866ee211c66beca01220c98e72c8a91d25c87b8ab456d3916f56fb1be5feef72556bca746da7aa852fc0118a04669f5ec2e6511eb77c960479e1c0 +"caniuse-lite@npm:1.0.30001690": + version: 1.0.30001690 + resolution: "caniuse-lite@npm:1.0.30001690" + checksum: 10/9fb4659eb09a298601b9593739072c481e2f5cc524bd0530e5e0f002e66246da5e866669854dfc0d53195ee36b201dab02f7933a7cdf60ccba7adb2d4a304caf languageName: node linkType: hard @@ -8370,16 +8370,16 @@ __metadata: dependencies: "@testing-library/cypress": "npm:10.0.2" axe-core: "npm:4.10.2" - cypress: "npm:13.16.1" + cypress: "npm:13.17.0" cypress-axe: "npm:1.5.0" cypress-plugin-tab: "npm:1.0.5" eslint: "npm:8.57.1" languageName: unknown linkType: soft -"cypress@npm:13.16.1": - version: 13.16.1 - resolution: "cypress@npm:13.16.1" +"cypress@npm:13.17.0": + version: 13.17.0 + resolution: "cypress@npm:13.17.0" dependencies: "@cypress/request": "npm:^3.0.6" "@cypress/xvfb": "npm:^1.2.4" @@ -8426,7 +8426,7 @@ __metadata: yauzl: "npm:^2.10.0" bin: cypress: bin/cypress - checksum: 10/b79835cf5c6bf22a67b4469dc08c805ab3a469d3ea25ff19f700b344b2e790a44462dc2ccdd2c0679f902a44fcbb1efec0b1e9b5ce44be7e99548ce3b9af5cf8 + checksum: 10/6c548e2adf7ae127365570680aa32015dbeb94cad30ce4f8a92e2e58d8ef7033b7f0ece50579a0a13eb07061feede0c813ff8d1e50e0feb87520dece5be4ba95 languageName: node linkType: hard @@ -14027,9 +14027,9 @@ __metadata: languageName: node linkType: hard -"nodemon@npm:3.1.7": - version: 3.1.7 - resolution: "nodemon@npm:3.1.7" +"nodemon@npm:3.1.9": + version: 3.1.9 + resolution: "nodemon@npm:3.1.9" dependencies: chokidar: "npm:^3.5.2" debug: "npm:^4" @@ -14043,7 +14043,7 @@ __metadata: undefsafe: "npm:^2.0.5" bin: nodemon: bin/nodemon.js - checksum: 10/07c6b14e4915bfe11abd0ee95bdfd96087dcdb7a37f9d1a57d9526f5f564268432556aa726a4019abf7e48deeff4628a5b34e88ccba8bf46c310c5910ad4a075 + checksum: 10/7c01ddfa30815f4147006f5b7c015a1f75017118cf398ee8c4ba3ac904667f4555b91cca6b7b191e0f6ccf5072727aa20224a1456d5446f3f6053e15132068a2 languageName: node linkType: hard @@ -16436,6 +16436,18 @@ __metadata: languageName: node linkType: hard +"schema-utils@npm:^4.3.0": + version: 4.3.0 + resolution: "schema-utils@npm:4.3.0" + dependencies: + "@types/json-schema": "npm:^7.0.9" + ajv: "npm:^8.9.0" + ajv-formats: "npm:^2.1.1" + ajv-keywords: "npm:^5.1.0" + checksum: 10/86c5a7c72a275c56f140bc3cdd832d56efb11428c88ad588127db12cb9b2c83ccaa9540e115d7baa9c6175b5e360094457e29c44e6fb76787c9498c2eb6df5d6 + languageName: node + linkType: hard + "select-hose@npm:^2.0.0": version: 2.0.0 resolution: "select-hose@npm:2.0.0" @@ -17485,7 +17497,29 @@ __metadata: languageName: node linkType: hard -"terser-webpack-plugin@npm:5.3.10, terser-webpack-plugin@npm:^5.3.1, terser-webpack-plugin@npm:^5.3.10": +"terser-webpack-plugin@npm:5.3.11": + version: 5.3.11 + resolution: "terser-webpack-plugin@npm:5.3.11" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.25" + jest-worker: "npm:^27.4.5" + schema-utils: "npm:^4.3.0" + serialize-javascript: "npm:^6.0.2" + terser: "npm:^5.31.1" + peerDependencies: + webpack: ^5.1.0 + peerDependenciesMeta: + "@swc/core": + optional: true + esbuild: + optional: true + uglify-js: + optional: true + checksum: 10/a8f7c92c75aa42628adfa4d171d4695c366c1852ecb4a24e72dd6fec86e383e12ac24b627e798fedff4e213c21fe851cebc61be3ab5a2537e6e42bea46690aa3 + languageName: node + linkType: hard + +"terser-webpack-plugin@npm:^5.3.1, terser-webpack-plugin@npm:^5.3.10": version: 5.3.10 resolution: "terser-webpack-plugin@npm:5.3.10" dependencies: @@ -17535,6 +17569,20 @@ __metadata: languageName: node linkType: hard +"terser@npm:^5.31.1": + version: 5.37.0 + resolution: "terser@npm:5.37.0" + dependencies: + "@jridgewell/source-map": "npm:^0.3.3" + acorn: "npm:^8.8.2" + commander: "npm:^2.20.0" + source-map-support: "npm:~0.5.20" + bin: + terser: bin/terser + checksum: 10/3afacf7c38c47a5a25dbe1ba2e7aafd61166474d4377ec0af490bd41ab3686ab12679818d5fe4a3e7f76efee26f639c92ac334940c378bbc31176520a38379c3 + languageName: node + linkType: hard + "test-exclude@npm:^6.0.0": version: 6.0.0 resolution: "test-exclude@npm:6.0.0" From 45196079dc6dc797fb977fbe9c872f929c28acec Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:24:57 +0100 Subject: [PATCH 08/10] chore(deps): update gitea/gitea docker tag to v1.22.6 (#14324) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gitea/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitea/Dockerfile b/gitea/Dockerfile index b96da125070..5c86027806f 100644 --- a/gitea/Dockerfile +++ b/gitea/Dockerfile @@ -7,7 +7,7 @@ RUN node ./merge.js ./base/locale_en-US.ini ./custom/locale_en-US.ini ./locale/l RUN node ./merge.js ./base/locale_nb-NO.ini ./custom/locale_nb-NO.ini ./locale/locale_nb-NO.ini # Ensure to update the locales, templates, and configuration when upgrading Gitea -FROM gitea/gitea:1.22.5-rootless +FROM gitea/gitea:1.22.6-rootless USER 0:0 RUN apk --no-cache upgrade expat git libxml2 libcurl curl USER 1000:1000 From 4e27917c648557d2ee120b77f6479ad393765dc6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:25:06 +0100 Subject: [PATCH 09/10] fix(deps): update maven non-major dependencies (#14326) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- eidlogger/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eidlogger/pom.xml b/eidlogger/pom.xml index fee662753ad..dcc55126bbc 100644 --- a/eidlogger/pom.xml +++ b/eidlogger/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.4.0 + 3.4.1 no.altinn @@ -17,7 +17,7 @@ 21 2.7.0 1.2.2 - 5.18.0 + 5.19.0 From 7738e187128f353e75514ee52a432b0376586979 Mon Sep 17 00:00:00 2001 From: Jonas Dyrlie Date: Mon, 23 Dec 2024 14:22:27 +0100 Subject: [PATCH 10/10] fix: make slider 100% height and hide thumb in firefox (#14305) Co-authored-by: JamalAlabdullah <90609090+JamalAlabdullah@users.noreply.github.com> --- .../StudioGridSelector.module.css | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.module.css b/frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.module.css index 460f8f5bcde..72d49e92e27 100644 --- a/frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.module.css +++ b/frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.module.css @@ -38,19 +38,19 @@ border-radius: var(--border-radius); } -.range::-moz-range-track { - aspect-ratio: 12; - background: var(--background); - border-radius: var(--border-radius); -} - .range::-webkit-slider-thumb { -webkit-appearance: none; - appearance: none; width: var(--thumb-width); } +.range::-moz-range-track { + height: 100%; + background: var(--background); + border-radius: var(--border-radius); +} + .range::-moz-range-thumb { + visibility: hidden; width: var(--thumb-width); }