diff --git a/assets/templates/first.html b/assets/templates/first.html index 32f28c639..15586fada 100644 --- a/assets/templates/first.html +++ b/assets/templates/first.html @@ -13,7 +13,7 @@ {{ document.header.documentTitle }} - {{ document.header.organisation }} + {{ document.header.organization }} {{ document.header.labCourse }} diff --git a/assets/translations/de_by.json b/assets/translations/de_by.json index 78c872da2..089656713 100644 --- a/assets/translations/de_by.json +++ b/assets/translations/de_by.json @@ -37,7 +37,7 @@ }, "header": { "docTitle": "Titl vom Wisch:", - "organisation": "Organisation:", + "organization": "Organisation:", "labCourse": "Gruppn:", "name": "Nama:", "place": "Blotz:", diff --git a/assets/translations/de_de.json b/assets/translations/de_de.json index 339486281..55bd5b915 100644 --- a/assets/translations/de_de.json +++ b/assets/translations/de_de.json @@ -37,7 +37,7 @@ }, "header": { "docTitle": "Dokument Titel:", - "organisation": "Organisation:", + "organization": "Organisation:", "labCourse": "Lab/Kurs:", "name": "Name:", "place": "Platz:", diff --git a/assets/translations/en_us.json b/assets/translations/en_us.json index 25ba434c6..f52331a2b 100644 --- a/assets/translations/en_us.json +++ b/assets/translations/en_us.json @@ -37,7 +37,7 @@ }, "header": { "docTitle": "Document title:", - "organisation": "Organization:", + "organization": "Organization:", "labCourse": "Lab/Course:", "name": "Name:", "place": "Place:", diff --git a/assets/translations/hr_hr.json b/assets/translations/hr_hr.json index afea3e9b3..6829a2958 100644 --- a/assets/translations/hr_hr.json +++ b/assets/translations/hr_hr.json @@ -37,7 +37,7 @@ }, "header": { "docTitle": "Naslov dokumenta:", - "organisation": "Organizacija:", + "organization": "Organizacija:", "labCourse": "Laboratorij / Predavanje:", "name": "Ime:", "place": "Mjesto:", diff --git a/assets/translations/ru_ru.json b/assets/translations/ru_ru.json index b4ba09221..0acc59e7d 100644 --- a/assets/translations/ru_ru.json +++ b/assets/translations/ru_ru.json @@ -37,7 +37,7 @@ }, "header": { "docTitle": "Название документа:", - "organisation": "Организация:", + "organization": "Организация:", "labCourse": "Лаборатория / Курс:", "name": "Имя:", "place": "Место:", diff --git a/crates/load_save/src/cabr2/migrations.rs b/crates/load_save/src/cabr2/migrations.rs index f2c153b34..1b109b034 100644 --- a/crates/load_save/src/cabr2/migrations.rs +++ b/crates/load_save/src/cabr2/migrations.rs @@ -1,8 +1,8 @@ -use types::{Data, SubstanceData}; +use types::{Amount, Data, SubstanceData}; use crate::types::{CaBr2Document, Header}; -use super::types::{CaBr2DocumentV0, DataV0, SubstanceDataV0}; +use super::types::{AmountV0, CaBr2DocumentV0, DataV0, SubstanceDataV0}; impl From for CaBr2Document { fn from(old: CaBr2DocumentV0) -> Self { @@ -48,13 +48,22 @@ impl From for SubstanceData { symbols: old.symbols.into(), lethal_dose: old.lethal_dose.into(), mak: old.mak.into(), - amount: old.amount, + amount: old.amount.map(|a| a.into()), source: old.source, checked: old.checked, } } } +impl From for Amount { + fn from(old: AmountV0) -> Self { + Amount { + value: old.value, + unit: old.unit, + } + } +} + impl From>> for Data { fn from(old: DataV0>) -> Self { Data { diff --git a/crates/load_save/src/cabr2/types.rs b/crates/load_save/src/cabr2/types.rs index ba5747889..e22d35b8f 100644 --- a/crates/load_save/src/cabr2/types.rs +++ b/crates/load_save/src/cabr2/types.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -use types::{Amount, Source}; +use types::{Source, Unit}; use crate::types::CaBr2Document; @@ -52,11 +52,17 @@ pub struct SubstanceDataV0 { pub symbols: DataV0>, pub lethal_dose: DataV0>, pub mak: DataV0>, - pub amount: Option, + pub amount: Option, pub source: Source, pub checked: bool, } +#[derive(Debug, Deserialize, Serialize)] +pub struct AmountV0 { + pub value: String, + pub unit: Unit, +} + #[derive(Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct DataV0 { diff --git a/crates/load_save/tests/assets/Knallerbsen_v1.cb2 b/crates/load_save/tests/assets/Knallerbsen_v1.cb2 index cb229eec6..c001d9082 100644 --- a/crates/load_save/tests/assets/Knallerbsen_v1.cb2 +++ b/crates/load_save/tests/assets/Knallerbsen_v1.cb2 @@ -1 +1 @@ -{"version":"1","header":{"documentTitle":"Betriebsanweisungen nach EG Nr. 1272/2008","organization":"Für chemische Laboratorien des Campus Burghausen","labCourse":"Praktikum Anorganische Chemie","name":"Max Musterstudent","place":"42","assistant":"Hans Wurst","preparation":"Knallerbsen"},"substanceData":[{"name":{"originalData":["Cobalt(II)-nitrat","Kobalt(II)-nitrat","Cobaltdinitrat"]},"cas":{"originalData":["10141-05-6"]},"molecularFormula":{"originalData":["Co(NO3)2"]},"molarMass":{"originalData":["182,95 g/mol"]},"meltingPoint":{"originalData":[]},"boilingPoint":{"originalData":[]},"waterHazardClass":{"originalData":["WGK 3"]},"hPhrases":{"originalData":[[["H272","Kann Brand verstärken; Oxidationsmittel."],["H302","Gesundheitsschädlich bei Verschlucken."],["H317","Kann allergische Hautreaktionen verursachen."],["H318","Verursacht schwere Augenschäden."],["H332","Gesundheitsschädlich bei Einatmen."],["H334","Kann bei Einatmen Allergie, asthmaartige Symptome oder Atembeschwerden verursachen."],["H341","Kann vermutlich genetische Defekte verursachen."],["H350i","Kann bei Einatmen Krebs erzeugen."],["H360F","Kann die Fruchtbarkeit beeinträchtigen."],["H410","Sehr giftig für Wasserorganismen mit langfristiger Wirkung."]]]},"pPhrases":{"originalData":[[["P210","Von Hitze, heißen Oberflächen, Funken, offenen Flammen sowie anderen Zündquellen fernhalten. Nicht rauchen."],["P280","Schutzhandschuhe/Schutzkleidung/Augenschutz/Gesichtsschutz tragen."],["P301+P330+P331","BEI VERSCHLUCKEN: Mund ausspülen. KEIN Erbrechen herbeiführen."],["P302+P352","BEI BERÜHRUNG MIT DER HAUT: Mit viel Wasser und Seife waschen."],["P304+P340","BEI EINATMEN: Die Person an die frische Luft bringen und für ungehinderte Atmung sorgen."],["P305+P351+P338","BEI KONTAKT MIT DEN AUGEN: Einige Minuten lang behutsam mit Wasser spülen. Eventuell vorhandene Kontaktlinsen nach Möglichkeit entfernen. Weiter spülen."],["P310","Sofort GIFTINFORMATIONSZENTRUM oder Arzt anrufen."]]]},"signalWord":{"originalData":["Gefahr"]},"symbols":{"originalData":[["ghs03","ghs05","ghs07","ghs08","ghs09"]]},"lethalDose":{"originalData":["691 mg/kg"]},"mak":{"originalData":[]},"amount":{"value":"10","unit":{"type":"GRAM"}},"source":{"provider":"gestis","url":"https://gestis-api.dguv.de/api/article/de/005340","lastUpdated":"2022-04-07T00:47:08.984Z"},"checked":true},{"name":{"modifiedData":"Puffreis","originalData":[""]},"cas":{"originalData":[]},"molecularFormula":{"originalData":[]},"molarMass":{"modifiedData":"","originalData":[]},"meltingPoint":{"originalData":[]},"boilingPoint":{"originalData":[]},"waterHazardClass":{"modifiedData":"","originalData":[]},"hPhrases":{"originalData":[]},"pPhrases":{"originalData":[]},"signalWord":{"modifiedData":"","originalData":[]},"symbols":{"modifiedData":["ghs01","ghs06","ghs08","ghs02"],"originalData":[]},"lethalDose":{"originalData":[]},"mak":{"originalData":[]},"amount":{"value":"20","unit":{"type":"PIECES"}},"source":{"provider":"custom","url":"","lastUpdated":"2022-04-07T00:47:11.602Z"},"checked":true}],"humanAndEnvironmentDanger":["Bei anhaltender Augenreizung ärztlichen Rat einholen. Funkenerzeugung und elektrische Aufladung vermeiden."],"rulesOfConduct":["Hautschutz und Schutzkleidung mit Schutzbrille tragen."],"inCaseOfDanger":["Nach Einatmen: An die frische Luft bringen. Sofort Arzt hinzuziehen.","Nach Hautkontakt: Sofort mit Wasser abwaschen. Kontaminierte Kleidung entfernen. Sofort Arzt hinzuziehen.","Nach Verschlucken: Mund mit Wasser spülen, Wasser trinken lassen. Kein Erbrechen auslösen. Nur bei Bewusstsein!","Nach Augenkontakt: Mit Wasser spülen. Falls vorhanden nach Möglichkeit Kontaktlinsen entfernen und weiter spülen. Sofort Augenarzt hinzuziehen."],"disposal":["metallsalzhaltige, wässrige Lösungen, neutral-basisch","metallsalzhaltige, wässrige Lösungen, neutral-sauer","halogenfreier, wässriger Lösemittelabfall","halogenhaltige, wässrige organische Lösungen","Sammelbehälter für Lösemittel zum Recycling","Sammelbehälter Präparate","Feststoff-Abfall organisch","Feststoff-Abfall anorganisch"]} \ No newline at end of file +{"version":"1","header":{"documentTitle":"Betriebsanweisungen nach EG Nr. 1272/2008","organization":"Für chemische Laboratorien des Campus Burghausen","labCourse":"Praktikum Anorganische Chemie","name":"Max Musterstudent","place":"42","assistant":"Hans Wurst","preparation":"Knallerbsen"},"substanceData":[{"name":{"originalData":["Cobalt(II)-nitrat","Kobalt(II)-nitrat","Cobaltdinitrat"]},"cas":{"originalData":["10141-05-6"]},"molecularFormula":{"originalData":["Co(NO3)2"]},"molarMass":{"originalData":["182,95 g/mol"]},"meltingPoint":{"originalData":[]},"boilingPoint":{"originalData":[]},"waterHazardClass":{"originalData":["WGK 3"]},"hPhrases":{"originalData":[[["H272","Kann Brand verstärken; Oxidationsmittel."],["H302","Gesundheitsschädlich bei Verschlucken."],["H317","Kann allergische Hautreaktionen verursachen."],["H318","Verursacht schwere Augenschäden."],["H332","Gesundheitsschädlich bei Einatmen."],["H334","Kann bei Einatmen Allergie, asthmaartige Symptome oder Atembeschwerden verursachen."],["H341","Kann vermutlich genetische Defekte verursachen."],["H350i","Kann bei Einatmen Krebs erzeugen."],["H360F","Kann die Fruchtbarkeit beeinträchtigen."],["H410","Sehr giftig für Wasserorganismen mit langfristiger Wirkung."]]]},"pPhrases":{"originalData":[[["P210","Von Hitze, heißen Oberflächen, Funken, offenen Flammen sowie anderen Zündquellen fernhalten. Nicht rauchen."],["P280","Schutzhandschuhe/Schutzkleidung/Augenschutz/Gesichtsschutz tragen."],["P301+P330+P331","BEI VERSCHLUCKEN: Mund ausspülen. KEIN Erbrechen herbeiführen."],["P302+P352","BEI BERÜHRUNG MIT DER HAUT: Mit viel Wasser und Seife waschen."],["P304+P340","BEI EINATMEN: Die Person an die frische Luft bringen und für ungehinderte Atmung sorgen."],["P305+P351+P338","BEI KONTAKT MIT DEN AUGEN: Einige Minuten lang behutsam mit Wasser spülen. Eventuell vorhandene Kontaktlinsen nach Möglichkeit entfernen. Weiter spülen."],["P310","Sofort GIFTINFORMATIONSZENTRUM oder Arzt anrufen."]]]},"signalWord":{"originalData":["Gefahr"]},"symbols":{"originalData":[["ghs03","ghs05","ghs07","ghs08","ghs09"]]},"lethalDose":{"originalData":["691 mg/kg"]},"mak":{"originalData":[]},"amount":{"value":"10","type":"GRAM"},"source":{"provider":"gestis","url":"https://gestis-api.dguv.de/api/article/de/005340","lastUpdated":"2022-04-07T00:47:08.984Z"},"checked":true},{"name":{"modifiedData":"Puffreis","originalData":[""]},"cas":{"originalData":[]},"molecularFormula":{"originalData":[]},"molarMass":{"modifiedData":"","originalData":[]},"meltingPoint":{"originalData":[]},"boilingPoint":{"originalData":[]},"waterHazardClass":{"modifiedData":"","originalData":[]},"hPhrases":{"originalData":[]},"pPhrases":{"originalData":[]},"signalWord":{"modifiedData":"","originalData":[]},"symbols":{"modifiedData":["ghs01","ghs06","ghs08","ghs02"],"originalData":[]},"lethalDose":{"originalData":[]},"mak":{"originalData":[]},"amount":{"value":"20","type":"PIECES"},"source":{"provider":"custom","url":"","lastUpdated":"2022-04-07T00:47:11.602Z"},"checked":true}],"humanAndEnvironmentDanger":["Bei anhaltender Augenreizung ärztlichen Rat einholen. Funkenerzeugung und elektrische Aufladung vermeiden."],"rulesOfConduct":["Hautschutz und Schutzkleidung mit Schutzbrille tragen."],"inCaseOfDanger":["Nach Einatmen: An die frische Luft bringen. Sofort Arzt hinzuziehen.","Nach Hautkontakt: Sofort mit Wasser abwaschen. Kontaminierte Kleidung entfernen. Sofort Arzt hinzuziehen.","Nach Verschlucken: Mund mit Wasser spülen, Wasser trinken lassen. Kein Erbrechen auslösen. Nur bei Bewusstsein!","Nach Augenkontakt: Mit Wasser spülen. Falls vorhanden nach Möglichkeit Kontaktlinsen entfernen und weiter spülen. Sofort Augenarzt hinzuziehen."],"disposal":["metallsalzhaltige, wässrige Lösungen, neutral-basisch","metallsalzhaltige, wässrige Lösungen, neutral-sauer","halogenfreier, wässriger Lösemittelabfall","halogenhaltige, wässrige organische Lösungen","Sammelbehälter für Lösemittel zum Recycling","Sammelbehälter Präparate","Feststoff-Abfall organisch","Feststoff-Abfall anorganisch"]} \ No newline at end of file diff --git a/crates/load_save/tests/assets/all_v1.cb2 b/crates/load_save/tests/assets/all_v1.cb2 index 696d83267..439db4f65 100644 --- a/crates/load_save/tests/assets/all_v1.cb2 +++ b/crates/load_save/tests/assets/all_v1.cb2 @@ -1 +1 @@ -{"version":"1","header":{"documentTitle":"Betriebsanweisungen nach EG Nr. 1272/2008","organization":"Für chemische Laboratorien des Campus Burghausen","labCourse":"Praktikum Anorganische Chemie","name":"Max Musterstudent","place":"21","assistant":"Erika Musterstudentin","preparation":"Banane"},"substanceData":[{"name":{"originalData":["Pentylacetat","Amylacetat","Essigsäureamylester","1-Pentanolacetat","Birnenöl","Birnenether","Bananenöl","Amylessigester"]},"cas":{"originalData":["628-63-7"]},"molecularFormula":{"originalData":["C7H14O2"]},"molarMass":{"originalData":["130,19 g/mol"]},"meltingPoint":{"originalData":["-71 °C"]},"boilingPoint":{"originalData":["149 °C"]},"waterHazardClass":{"originalData":["WGK 1"]},"hPhrases":{"originalData":[[["H226","Flüssigkeit und Dampf entzündbar."]]]},"pPhrases":{"originalData":[[["P210","Von Hitze, heißen Oberflächen, Funken, offenen Flammen sowie anderen Zündquellen fernhalten. Nicht rauchen."],["P233","Behälter dicht verschlossen halten."],["P240","Behälter und zu befüllende Anlage erden."],["P241","Explosionsgeschützte elektrische/Lüftungs-/Beleuchtungs-/… Geräte verwenden."],["P242","Funkenarmes Werkzeug verwenden."],["P243","Maßnahmen gegen elektrostatische Entladungen treffen."]]]},"signalWord":{"originalData":["Achtung"]},"symbols":{"originalData":[["ghs02"]]},"lethalDose":{"originalData":["> 1600 mg/kg"]},"mak":{"originalData":[]},"amount":null,"source":{"provider":"gestis","url":"https://gestis-api.dguv.de/api/article/de/031930","lastUpdated":"2022-04-07T11:44:56.322Z"},"checked":false},{"name":{"modifiedData":"Cobalt(II)-nitrata","originalData":["Cobalt(II)-nitrat","Kobalt(II)-nitrat","Cobaltdinitrat"]},"cas":{"modifiedData":"10141-05-6a","originalData":["10141-05-6"]},"molecularFormula":{"modifiedData":"Co(NO3)2a","originalData":["Co(NO3)2"]},"molarMass":{"modifiedData":"182,95 g/mola","originalData":["182,95 g/mol"]},"meltingPoint":{"modifiedData":"a","originalData":[]},"boilingPoint":{"modifiedData":"a","originalData":[]},"waterHazardClass":{"modifiedData":"WGK 3a","originalData":["WGK 3"]},"hPhrases":{"modifiedData":[["H272a","Kann Brand verstärken; Oxidationsmittel.a"],["H302a","Gesundheitsschädlich bei Verschlucken.a"],["H317a","Kann allergische Hautreaktionen verursachen.a"],["H318a","Verursacht schwere Augenschäden.a"],["H332a","Gesundheitsschädlich bei Einatmen.a"],["H334a","Kann bei Einatmen Allergie, asthmaartige Symptome oder Atembeschwerden verursachen.a"],["H341a","Kann vermutlich genetische Defekte verursachen.a"],["H350i","Kann bei Einatmen Krebs erzeugen.a"],["H360F","Kann die Fruchtbarkeit beeinträchtigen.a"],["H410a","Sehr giftig für Wasserorganismen mit langfristiger Wirkung.a"]],"originalData":[[["H272","Kann Brand verstärken; Oxidationsmittel."],["H302","Gesundheitsschädlich bei Verschlucken."],["H317","Kann allergische Hautreaktionen verursachen."],["H318","Verursacht schwere Augenschäden."],["H332","Gesundheitsschädlich bei Einatmen."],["H334","Kann bei Einatmen Allergie, asthmaartige Symptome oder Atembeschwerden verursachen."],["H341","Kann vermutlich genetische Defekte verursachen."],["H350i","Kann bei Einatmen Krebs erzeugen."],["H360F","Kann die Fruchtbarkeit beeinträchtigen."],["H410","Sehr giftig für Wasserorganismen mit langfristiger Wirkung."]]]},"pPhrases":{"modifiedData":[["P219","Von Hitze, heißen Oberflächen, Funken, offenen Flammen sowie anderen Zündquellen fernhalten. Nicht rauchen.a"],["P289","Schutzhandschuhe/Schutzkleidung/Augenschutz/Gesichtsschutz tragen.a"],["P301+P330+P339","BEI VERSCHLUCKEN: Mund ausspülen. KEIN Erbrechen herbeiführen.a"],["P302+P359","BEI BERÜHRUNG MIT DER HAUT: Mit viel Wasser und Seife waschen.a"],["P304+P349","BEI EINATMEN: Die Person an die frische Luft bringen und für ungehinderte Atmung sorgen.a"],["P305+P351+P339","BEI KONTAKT MIT DEN AUGEN: Einige Minuten lang behutsam mit Wasser spülen. Eventuell vorhandene Kontaktlinsen nach Möglichkeit entfernen. Weiter spülen.a"],["P319","Sofort GIFTINFORMATIONSZENTRUM oder Arzt anrufen.a"]],"originalData":[[["P210","Von Hitze, heißen Oberflächen, Funken, offenen Flammen sowie anderen Zündquellen fernhalten. Nicht rauchen."],["P280","Schutzhandschuhe/Schutzkleidung/Augenschutz/Gesichtsschutz tragen."],["P301+P330+P331","BEI VERSCHLUCKEN: Mund ausspülen. KEIN Erbrechen herbeiführen."],["P302+P352","BEI BERÜHRUNG MIT DER HAUT: Mit viel Wasser und Seife waschen."],["P304+P340","BEI EINATMEN: Die Person an die frische Luft bringen und für ungehinderte Atmung sorgen."],["P305+P351+P338","BEI KONTAKT MIT DEN AUGEN: Einige Minuten lang behutsam mit Wasser spülen. Eventuell vorhandene Kontaktlinsen nach Möglichkeit entfernen. Weiter spülen."],["P310","Sofort GIFTINFORMATIONSZENTRUM oder Arzt anrufen."]]]},"signalWord":{"modifiedData":"Gefahra","originalData":["Gefahr"]},"symbols":{"modifiedData":["ghs01","ghs02","ghs04","ghs06"],"originalData":[["ghs03","ghs05","ghs07","ghs08","ghs09"]]},"lethalDose":{"modifiedData":"691 mg/kga","originalData":["691 mg/kg"]},"mak":{"modifiedData":"a","originalData":[]},"amount":{"value":"a","unit":{"type":"GRAM"}},"source":{"provider":"gestis","url":"https://gestis-api.dguv.de/api/article/de/005340","lastUpdated":"2022-04-07T11:45:01.604Z"},"checked":true},{"name":{"modifiedData":"a","originalData":[""]},"cas":{"modifiedData":"a","originalData":[]},"molecularFormula":{"modifiedData":"a","originalData":[]},"molarMass":{"modifiedData":"a","originalData":[]},"meltingPoint":{"modifiedData":"a","originalData":[]},"boilingPoint":{"modifiedData":"a","originalData":[]},"waterHazardClass":{"modifiedData":"a","originalData":[]},"hPhrases":{"modifiedData":[["H999","a"]],"originalData":[]},"pPhrases":{"modifiedData":[["P999","a"]],"originalData":[]},"signalWord":{"modifiedData":"a","originalData":[]},"symbols":{"modifiedData":["ghs01","ghs03","ghs05","ghs07","ghs09"],"originalData":[]},"lethalDose":{"modifiedData":"a","originalData":[]},"mak":{"modifiedData":"a","originalData":[]},"amount":{"value":"a","unit":{"type":"CUSTOM","name":"a"}},"source":{"provider":"custom","url":"","lastUpdated":"2022-04-07T11:46:31.994Z"},"checked":true}],"humanAndEnvironmentDanger":["Bei anhaltender Augenreizung ärztlichen Rat einholen. Funkenerzeugung und elektrische Aufladung vermeiden.a","a"],"rulesOfConduct":["Hautschutz und Schutzkleidung mit Schutzbrille tragen.a","a"],"inCaseOfDanger":["Nach Einatmen: An die frische Luft bringen. Sofort Arzt hinzuziehen.a","Nach Hautkontakt: Sofort mit Wasser abwaschen. Kontaminierte Kleidung entfernen. Sofort Arzt hinzuziehen.a","Nach Verschlucken: Mund mit Wasser spülen, Wasser trinken lassen. Kein Erbrechen auslösen. Nur bei Bewusstsein!a","aNach Augenkontakt: Mit Wasser spülen. Falls vorhanden nach Möglichkeit Kontaktlinsen entfernen und weiter spülen. Sofort Augenarzt hinzuziehen.","a"],"disposal":["metallsalzhaltige, wässrige Lösungen, neutral-basischa","ametallsalzhaltige, wässrige Lösungen, neutral-sauer","halogenfreier, wässriger Lösemittelabfalla","halogenhaltige, wässrige organische Lösungena","Sammelbehälter für Lösemittel zum Recyclinga","Sammelbehälter Präparatea","Feststoff-Abfall organischa","aFeststoff-Abfall anorganisch","a"]} \ No newline at end of file +{"version":"1","header":{"documentTitle":"Betriebsanweisungen nach EG Nr. 1272/2008","organization":"Für chemische Laboratorien des Campus Burghausen","labCourse":"Praktikum Anorganische Chemie","name":"Max Musterstudent","place":"21","assistant":"Erika Musterstudentin","preparation":"Banane"},"substanceData":[{"name":{"originalData":["Pentylacetat","Amylacetat","Essigsäureamylester","1-Pentanolacetat","Birnenöl","Birnenether","Bananenöl","Amylessigester"]},"cas":{"originalData":["628-63-7"]},"molecularFormula":{"originalData":["C7H14O2"]},"molarMass":{"originalData":["130,19 g/mol"]},"meltingPoint":{"originalData":["-71 °C"]},"boilingPoint":{"originalData":["149 °C"]},"waterHazardClass":{"originalData":["WGK 1"]},"hPhrases":{"originalData":[[["H226","Flüssigkeit und Dampf entzündbar."]]]},"pPhrases":{"originalData":[[["P210","Von Hitze, heißen Oberflächen, Funken, offenen Flammen sowie anderen Zündquellen fernhalten. Nicht rauchen."],["P233","Behälter dicht verschlossen halten."],["P240","Behälter und zu befüllende Anlage erden."],["P241","Explosionsgeschützte elektrische/Lüftungs-/Beleuchtungs-/… Geräte verwenden."],["P242","Funkenarmes Werkzeug verwenden."],["P243","Maßnahmen gegen elektrostatische Entladungen treffen."]]]},"signalWord":{"originalData":["Achtung"]},"symbols":{"originalData":[["ghs02"]]},"lethalDose":{"originalData":["> 1600 mg/kg"]},"mak":{"originalData":[]},"amount":null,"source":{"provider":"gestis","url":"https://gestis-api.dguv.de/api/article/de/031930","lastUpdated":"2022-04-07T11:44:56.322Z"},"checked":false},{"name":{"modifiedData":"Cobalt(II)-nitrata","originalData":["Cobalt(II)-nitrat","Kobalt(II)-nitrat","Cobaltdinitrat"]},"cas":{"modifiedData":"10141-05-6a","originalData":["10141-05-6"]},"molecularFormula":{"modifiedData":"Co(NO3)2a","originalData":["Co(NO3)2"]},"molarMass":{"modifiedData":"182,95 g/mola","originalData":["182,95 g/mol"]},"meltingPoint":{"modifiedData":"a","originalData":[]},"boilingPoint":{"modifiedData":"a","originalData":[]},"waterHazardClass":{"modifiedData":"WGK 3a","originalData":["WGK 3"]},"hPhrases":{"modifiedData":[["H272a","Kann Brand verstärken; Oxidationsmittel.a"],["H302a","Gesundheitsschädlich bei Verschlucken.a"],["H317a","Kann allergische Hautreaktionen verursachen.a"],["H318a","Verursacht schwere Augenschäden.a"],["H332a","Gesundheitsschädlich bei Einatmen.a"],["H334a","Kann bei Einatmen Allergie, asthmaartige Symptome oder Atembeschwerden verursachen.a"],["H341a","Kann vermutlich genetische Defekte verursachen.a"],["H350i","Kann bei Einatmen Krebs erzeugen.a"],["H360F","Kann die Fruchtbarkeit beeinträchtigen.a"],["H410a","Sehr giftig für Wasserorganismen mit langfristiger Wirkung.a"]],"originalData":[[["H272","Kann Brand verstärken; Oxidationsmittel."],["H302","Gesundheitsschädlich bei Verschlucken."],["H317","Kann allergische Hautreaktionen verursachen."],["H318","Verursacht schwere Augenschäden."],["H332","Gesundheitsschädlich bei Einatmen."],["H334","Kann bei Einatmen Allergie, asthmaartige Symptome oder Atembeschwerden verursachen."],["H341","Kann vermutlich genetische Defekte verursachen."],["H350i","Kann bei Einatmen Krebs erzeugen."],["H360F","Kann die Fruchtbarkeit beeinträchtigen."],["H410","Sehr giftig für Wasserorganismen mit langfristiger Wirkung."]]]},"pPhrases":{"modifiedData":[["P219","Von Hitze, heißen Oberflächen, Funken, offenen Flammen sowie anderen Zündquellen fernhalten. Nicht rauchen.a"],["P289","Schutzhandschuhe/Schutzkleidung/Augenschutz/Gesichtsschutz tragen.a"],["P301+P330+P339","BEI VERSCHLUCKEN: Mund ausspülen. KEIN Erbrechen herbeiführen.a"],["P302+P359","BEI BERÜHRUNG MIT DER HAUT: Mit viel Wasser und Seife waschen.a"],["P304+P349","BEI EINATMEN: Die Person an die frische Luft bringen und für ungehinderte Atmung sorgen.a"],["P305+P351+P339","BEI KONTAKT MIT DEN AUGEN: Einige Minuten lang behutsam mit Wasser spülen. Eventuell vorhandene Kontaktlinsen nach Möglichkeit entfernen. Weiter spülen.a"],["P319","Sofort GIFTINFORMATIONSZENTRUM oder Arzt anrufen.a"]],"originalData":[[["P210","Von Hitze, heißen Oberflächen, Funken, offenen Flammen sowie anderen Zündquellen fernhalten. Nicht rauchen."],["P280","Schutzhandschuhe/Schutzkleidung/Augenschutz/Gesichtsschutz tragen."],["P301+P330+P331","BEI VERSCHLUCKEN: Mund ausspülen. KEIN Erbrechen herbeiführen."],["P302+P352","BEI BERÜHRUNG MIT DER HAUT: Mit viel Wasser und Seife waschen."],["P304+P340","BEI EINATMEN: Die Person an die frische Luft bringen und für ungehinderte Atmung sorgen."],["P305+P351+P338","BEI KONTAKT MIT DEN AUGEN: Einige Minuten lang behutsam mit Wasser spülen. Eventuell vorhandene Kontaktlinsen nach Möglichkeit entfernen. Weiter spülen."],["P310","Sofort GIFTINFORMATIONSZENTRUM oder Arzt anrufen."]]]},"signalWord":{"modifiedData":"Gefahra","originalData":["Gefahr"]},"symbols":{"modifiedData":["ghs01","ghs02","ghs04","ghs06"],"originalData":[["ghs03","ghs05","ghs07","ghs08","ghs09"]]},"lethalDose":{"modifiedData":"691 mg/kga","originalData":["691 mg/kg"]},"mak":{"modifiedData":"a","originalData":[]},"amount":{"value":"a","type":"GRAM"},"source":{"provider":"gestis","url":"https://gestis-api.dguv.de/api/article/de/005340","lastUpdated":"2022-04-07T11:45:01.604Z"},"checked":true},{"name":{"modifiedData":"a","originalData":[""]},"cas":{"modifiedData":"a","originalData":[]},"molecularFormula":{"modifiedData":"a","originalData":[]},"molarMass":{"modifiedData":"a","originalData":[]},"meltingPoint":{"modifiedData":"a","originalData":[]},"boilingPoint":{"modifiedData":"a","originalData":[]},"waterHazardClass":{"modifiedData":"a","originalData":[]},"hPhrases":{"modifiedData":[["H999","a"]],"originalData":[]},"pPhrases":{"modifiedData":[["P999","a"]],"originalData":[]},"signalWord":{"modifiedData":"a","originalData":[]},"symbols":{"modifiedData":["ghs01","ghs03","ghs05","ghs07","ghs09"],"originalData":[]},"lethalDose":{"modifiedData":"a","originalData":[]},"mak":{"modifiedData":"a","originalData":[]},"amount":{"value":"a","type":"CUSTOM","name":"a"},"source":{"provider":"custom","url":"","lastUpdated":"2022-04-07T11:46:31.994Z"},"checked":true}],"humanAndEnvironmentDanger":["Bei anhaltender Augenreizung ärztlichen Rat einholen. Funkenerzeugung und elektrische Aufladung vermeiden.a","a"],"rulesOfConduct":["Hautschutz und Schutzkleidung mit Schutzbrille tragen.a","a"],"inCaseOfDanger":["Nach Einatmen: An die frische Luft bringen. Sofort Arzt hinzuziehen.a","Nach Hautkontakt: Sofort mit Wasser abwaschen. Kontaminierte Kleidung entfernen. Sofort Arzt hinzuziehen.a","Nach Verschlucken: Mund mit Wasser spülen, Wasser trinken lassen. Kein Erbrechen auslösen. Nur bei Bewusstsein!a","aNach Augenkontakt: Mit Wasser spülen. Falls vorhanden nach Möglichkeit Kontaktlinsen entfernen und weiter spülen. Sofort Augenarzt hinzuziehen.","a"],"disposal":["metallsalzhaltige, wässrige Lösungen, neutral-basischa","ametallsalzhaltige, wässrige Lösungen, neutral-sauer","halogenfreier, wässriger Lösemittelabfalla","halogenhaltige, wässrige organische Lösungena","Sammelbehälter für Lösemittel zum Recyclinga","Sammelbehälter Präparatea","Feststoff-Abfall organischa","aFeststoff-Abfall anorganisch","a"]} \ No newline at end of file diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 88ce8a73c..079439b9a 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -60,6 +60,7 @@ pub struct Source { #[derive(Debug, Deserialize, Serialize)] pub struct Amount { pub value: String, + #[serde(flatten)] pub unit: Unit, } diff --git a/frontend/src/app/@core/interfaces/DocTemplate.ts b/frontend/src/app/@core/interfaces/DocTemplate.ts index 76b51c013..6c3de322a 100644 --- a/frontend/src/app/@core/interfaces/DocTemplate.ts +++ b/frontend/src/app/@core/interfaces/DocTemplate.ts @@ -3,7 +3,7 @@ export interface Header { documentTitle: string; labCourse: string; name: string; - organisation: string; + organization: string; place: string; preparation: string; } diff --git a/frontend/src/app/@core/models/header.model.ts b/frontend/src/app/@core/models/header.model.ts index 933c0fdee..b376a8c10 100644 --- a/frontend/src/app/@core/models/header.model.ts +++ b/frontend/src/app/@core/models/header.model.ts @@ -5,7 +5,7 @@ export const EMPTY_HEADER: Header = { documentTitle: '', labCourse: '', name: '', - organisation: '', + organization: '', place: '', preparation: '', }; diff --git a/frontend/src/app/@core/models/substances.model.ts b/frontend/src/app/@core/models/substances.model.ts index 2e9a12a12..2c7f34ccf 100644 --- a/frontend/src/app/@core/models/substances.model.ts +++ b/frontend/src/app/@core/models/substances.model.ts @@ -3,14 +3,13 @@ import { SafeResourceUrl } from '@angular/platform-browser'; export type GHSSymbols = Map; interface EmptyData { - originalData: T; + originalData: T[]; } // these are needed to create new objects every time and don't copy a reference // because otherwise every field would reference the same values -const EMPTY_DATA = (): EmptyData => ({ originalData: undefined }); -const EMPTY_STRING_DATA = (): EmptyData => ({ originalData: '' }); -const EMPTY_LIST_DATA = (): EmptyData<[]> => ({ originalData: [] }); +const EMPTY_DATA = (): EmptyData => ({ originalData: [] }); +const EMPTY_LIST_DATA = (): EmptyData => ({ originalData: [] }); export const EMPTY_VIEW_SUBSTANCE_DATA: ViewSubstanceData = { name: '', @@ -31,33 +30,31 @@ export const EMPTY_VIEW_SUBSTANCE_DATA: ViewSubstanceData = { export class SubstanceData { name: Data; - readonly alternativeNames: string[]; + cas: Data; - cas: Data; + molecularFormula: Data; - molecularFormula: Data; + molarMass: Data; - molarMass: Data; + meltingPoint: Data; - meltingPoint: Data; + boilingPoint: Data; - boilingPoint: Data; + waterHazardClass: Data; - waterHazardClass: Data; + hPhrases: Data void>[]>; - hPhrases: Data<[string, string][]>; + pPhrases: Data void>[]>; - pPhrases: Data<[string, string][]>; - - signalWord: Data; + signalWord: Data; symbols: Data; - lethalDose: Data; + lethalDose: Data; - mak: Data; + mak: Data; - amount: Amount | undefined; + amount?: Amount; readonly source: Source; @@ -69,7 +66,7 @@ export class SubstanceData { * If `source` is empty it will be treated as custom substance. */ constructor(data?: Partial) { - this.name = EMPTY_STRING_DATA(); + this.name = EMPTY_DATA(); this.cas = EMPTY_DATA(); this.molecularFormula = EMPTY_DATA(); this.molarMass = EMPTY_DATA(); @@ -83,8 +80,6 @@ export class SubstanceData { this.lethalDose = EMPTY_DATA(); this.mak = EMPTY_DATA(); - this.alternativeNames = []; - this.source = { url: '', provider: 'custom', lastUpdated: new Date() }; this.checked = false; @@ -125,20 +120,22 @@ export class SubstanceData { } convertToViewSubstanceData(): ViewSubstanceData { + const evaluate = (data: Data): T | undefined => data.modifiedData ?? data.originalData[0]; + return { - name: this.name.modifiedData ?? this.name.originalData, - cas: this.cas.modifiedData ?? this.cas.originalData, - molecularFormula: this.molecularFormula.modifiedData ?? this.molecularFormula.originalData, - molarMass: this.molarMass.modifiedData ?? this.molarMass.originalData, - meltingPoint: this.meltingPoint.modifiedData ?? this.meltingPoint.originalData, - boilingPoint: this.boilingPoint.modifiedData ?? this.boilingPoint.originalData, - waterHazardClass: this.waterHazardClass.modifiedData ?? this.waterHazardClass.originalData, - hPhrases: this.hPhrases.modifiedData ?? this.hPhrases.originalData, - pPhrases: this.pPhrases.modifiedData ?? this.pPhrases.originalData, - signalWord: this.signalWord.modifiedData ?? this.signalWord.originalData, - symbols: this.symbols.modifiedData ?? this.symbols.originalData, - lethalDose: this.lethalDose.modifiedData ?? this.lethalDose.originalData, - mak: this.mak.modifiedData ?? this.mak.originalData, + name: evaluate(this.name) ?? '', + cas: evaluate(this.cas), + molecularFormula: evaluate(this.molecularFormula), + molarMass: evaluate(this.molarMass), + meltingPoint: evaluate(this.meltingPoint), + boilingPoint: evaluate(this.boilingPoint), + waterHazardClass: evaluate(this.waterHazardClass), + hPhrases: evaluate(this.hPhrases) ?? [], + pPhrases: evaluate(this.pPhrases) ?? [], + signalWord: evaluate(this.signalWord), + symbols: evaluate(this.symbols) ?? [], + lethalDose: evaluate(this.lethalDose), + mak: evaluate(this.mak), amount: this.amount, }; } @@ -148,14 +145,10 @@ export class SubstanceData { * If the Data object has a modified value set it returns this modified value * else it returns the original value. */ -// eslint-disable-next-line prefer-arrow/prefer-arrow-functions -function modifiedOrOriginal(obj: Data): T { - return obj.modifiedData ?? obj.originalData; -} - +const modifiedOrOriginal = (obj: Data, index = 0): T => obj.modifiedData ?? obj.originalData[index]; export interface Data { modifiedData?: T; - readonly originalData: T; + readonly originalData: T[]; } export interface Image { @@ -168,38 +161,32 @@ export interface Source { url: string; lastUpdated: Date; } - -export interface Amount { - value: string; - unit: Unit; -} - export interface ViewSubstanceData { - name: string; - cas?: string; - molecularFormula?: string; - molarMass?: string; - meltingPoint?: string; - boilingPoint?: string; - waterHazardClass?: string; - hPhrases: [string, string][]; - pPhrases: [string, string][]; - signalWord?: string; - symbols: string[]; - lethalDose?: string; - mak?: string; - amount?: Amount; -} - -export interface Unit { - type: UnitType; - name?: string; + readonly name: string; + readonly cas?: string; + readonly molecularFormula?: string; + readonly molarMass?: string; + readonly meltingPoint?: string; + readonly boilingPoint?: string; + readonly waterHazardClass?: string; + readonly hPhrases: Parameters<(phraseNumber: string, phrase: string) => void>[]; + readonly pPhrases: Parameters<(phraseNumber: string, phrase: string) => void>[]; + readonly signalWord?: string; + readonly symbols: string[]; + readonly lethalDose?: string; + readonly mak?: string; + readonly amount?: Amount; } export interface GroupMapping { viewValue: string; unitMappings: UnitType[]; } +export interface Amount { + value: string; + type: UnitType; + name?: string; +} export enum UnitType { LITER = 'LITER', @@ -263,8 +250,8 @@ const unitMapping = new Map([ [UnitType.FAHRENHEIT, 'F'], ]); -const getViewName = (unit: Unit): string => { - const value = unitMapping.get(unit.type); +const getViewName = ({ type }: Pick): string => { + const value = unitMapping.get(type); if (value === undefined) { throw Error('unknown unit'); @@ -273,12 +260,11 @@ const getViewName = (unit: Unit): string => { return value; }; -const getViewValue = (unit: Unit): string => { - if (unit.type === UnitType.CUSTOM) { - return unit.name ?? ''; +const getViewValue = (amount: Amount): string => { + if (amount.type === UnitType.CUSTOM) { + return amount.name ?? ''; } - - return getViewName(unit); + return getViewName(amount); }; class UnitGroups { diff --git a/frontend/src/app/@core/services/document/document.service.ts b/frontend/src/app/@core/services/document/document.service.ts index 49bd2b173..c46ad5d23 100644 --- a/frontend/src/app/@core/services/document/document.service.ts +++ b/frontend/src/app/@core/services/document/document.service.ts @@ -204,11 +204,11 @@ export default class DocumentService { /** * Returns `true` if the `CaBr2Document has some unchecked default values */ - private checkUnmodified(document: CaBr2Document, docsTemplate: DocsTemplate): string[] { + private checkUnmodified(document: CaBr2Document, docsTemplate: DocsTemplate, index = 0): string[] { const unmodified: string[] = []; for (const substance of document.substanceData) { if (!substance.checked) { - unmodified.push(substance.name.modifiedData ?? substance.name.originalData); + unmodified.push(substance.name.modifiedData ?? substance.name.originalData[index]); } } for (const section of [ diff --git a/frontend/src/app/@core/services/loadSave/web/loadSave.service.ts b/frontend/src/app/@core/services/loadSave/web/loadSave.service.ts index b1ba3cf77..dd96e3a94 100644 --- a/frontend/src/app/@core/services/loadSave/web/loadSave.service.ts +++ b/frontend/src/app/@core/services/loadSave/web/loadSave.service.ts @@ -15,14 +15,7 @@ const logger = new Logger('loadSaveService.web'); const URL = window.webkitURL || window.URL; -const SERVER_URL = - ((): string => { - if (environment.production) { - return 'https://api.cabr2.de/'; - } else { - return 'http://localhost:3030/'; - } - })() + 'api/v1/'; +const SERVER_URL = environment.serverUrl; const getFileType = (file: File): string => { const fileTypeSplit = file.name.split('.'); @@ -108,27 +101,17 @@ export class LoadSaveService implements ILoadSaveService { const fileType = getFileType(file); const reader = new FileReader(); - - switch (fileType) { - case 'cb2': - return new Observable((sub) => { - reader.onload = () => sub.next(JSON.parse(reader.result as string)); - reader.readAsText(file); - }); - - default: - logger.debug('opening file with wasm:', file.name); - return new Observable((sub) => { - reader.onload = () => { - const res = reader.result as ArrayBuffer; - wasm - .load_document(fileType, new Uint8Array(res)) - .then((contents: string) => sub.next(JSON.parse(contents))) - .catch((err: any) => sub.error(err)); - }; - reader.readAsArrayBuffer(file); - }); - } + logger.debug('opening file with wasm:', file.name); + return new Observable((sub) => { + reader.onload = () => { + const res = reader.result as ArrayBuffer; + wasm + .load_document(fileType, new Uint8Array(res)) + .then((contents: string) => sub.next(JSON.parse(contents))) + .catch((err: any) => sub.error(err)); + }; + reader.readAsArrayBuffer(file); + }); } getAvailableDocumentTypes(): Observable { diff --git a/frontend/src/app/@core/states/substance-data.state.ts b/frontend/src/app/@core/states/substance-data.state.ts index 0fa9cd864..282dacc57 100644 --- a/frontend/src/app/@core/states/substance-data.state.ts +++ b/frontend/src/app/@core/states/substance-data.state.ts @@ -4,7 +4,12 @@ import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; import { Injectable } from '@angular/core'; import { translate } from '@ngneat/transloco'; -import { Data, EMPTY_VIEW_SUBSTANCE_DATA, SubstanceData, ViewSubstanceData } from '../models/substances.model'; +import { + EMPTY_VIEW_SUBSTANCE_DATA, + modifiedOrOriginal, + SubstanceData, + ViewSubstanceData, +} from '../models/substances.model'; import { AlertService } from '../services/alertsnackbar/alertsnackbar.service'; import { IProviderService } from '../services/provider/provider.interface'; import Logger from '../utils/logger'; @@ -96,8 +101,8 @@ export class SubstanceDataState { addSubstanceData(context: StateContext, action: AddSubstanceData): void { const substanceState = context.getState().substanceData; const providers = new Set(context.getState().providers); - const cas = this.modifiedOrOriginal(action.substanceData.cas); - if (cas && substanceState.some((s) => cas === this.modifiedOrOriginal(s.cas))) { + const cas = modifiedOrOriginal(action.substanceData.cas); + if (cas && substanceState.some((s) => cas === modifiedOrOriginal(s.cas))) { logger.warning('substance with same cas number already present:', cas); this.alertService.error(translate('error.substanceWithCASExist')); return; @@ -151,10 +156,6 @@ export class SubstanceDataState { }); } - private modifiedOrOriginal(obj: Data): T { - return obj.modifiedData ?? obj.originalData; - } - private setProviders(providers: Set, data: SubstanceData): void { const provider = this.providerMapping.get(data.source.provider); if (provider && provider.identifier !== 'custom') { diff --git a/frontend/src/app/components/edit-substance-data/edit-substance-data.component.ts b/frontend/src/app/components/edit-substance-data/edit-substance-data.component.ts index 737798ceb..aac84ccf4 100644 --- a/frontend/src/app/components/edit-substance-data/edit-substance-data.component.ts +++ b/frontend/src/app/components/edit-substance-data/edit-substance-data.component.ts @@ -85,8 +85,8 @@ export class EditSubstanceDataComponent implements OnInit, OnDestroy { let amount; if (this.data.amount) { - const a = this.data.amount; - amount = { value: a.value, unit: a.unit.type, unitName: a.unit.name ?? '' }; + const amountData = this.data.amount; + amount = { value: amountData.value, unit: amountData.type, unitName: amountData.name ?? '' }; } else { amount = { value: '', unit: UnitType.GRAM, unitName: '' }; } @@ -100,13 +100,13 @@ export class EditSubstanceDataComponent implements OnInit, OnDestroy { boilingPoint: modifiedOrOriginal(this.data.boilingPoint) ?? '', waterHazardClass: modifiedOrOriginal(this.data.waterHazardClass) ?? '', hPhrases: this.formBuilder.array( - modifiedOrOriginal<[string, string][]>(this.data.hPhrases).map((hPhrase) => this.initHPhrases(hPhrase)), + (modifiedOrOriginal<[string, string][]>(this.data.hPhrases) ?? []).map((hPhrase) => this.initHPhrases(hPhrase)), ), pPhrases: this.formBuilder.array( - modifiedOrOriginal<[string, string][]>(this.data.pPhrases).map((pPhrase) => this.initPPhrases(pPhrase)), + (modifiedOrOriginal<[string, string][]>(this.data.pPhrases) ?? []).map((pPhrase) => this.initPPhrases(pPhrase)), ), signalWord: modifiedOrOriginal(this.data.signalWord) ?? '', - symbols: this.formBuilder.array(modifiedOrOriginal(this.data.symbols)), + symbols: this.formBuilder.array(modifiedOrOriginal(this.data.symbols) ?? []), lethalDose: modifiedOrOriginal(this.data.lethalDose) ?? '', mak: modifiedOrOriginal(this.data.mak) ?? '', amount: this.formBuilder.group(amount), @@ -188,44 +188,44 @@ export class EditSubstanceDataComponent implements OnInit, OnDestroy { event.preventDefault(); event.stopPropagation(); - fixNumberOfControls(this.hPhrases, this.data.hPhrases.originalData.length, this.hPhrases.length, () => + fixNumberOfControls(this.hPhrases, this.data.hPhrases.originalData[0].length, this.hPhrases.length, () => this.initHPhrases(['', '']), ); - fixNumberOfControls(this.pPhrases, this.data.pPhrases.originalData.length, this.pPhrases.length, () => + fixNumberOfControls(this.pPhrases, this.data.pPhrases.originalData[0].length, this.pPhrases.length, () => this.initPPhrases(['', '']), ); fixNumberOfControls( this.symbols, - this.data.symbols.originalData.length, + this.data.symbols.originalData[0].length, this.symbols.length, () => new FormControl(), ); this.form.patchValue({ - name: this.data.name.originalData, - cas: this.data.cas.originalData ?? '', - molecularFormula: this.data.molecularFormula.originalData ?? '', - molarMass: this.data.molarMass.originalData ?? '', - meltingPoint: this.data.meltingPoint.originalData ?? '', - boilingPoint: this.data.boilingPoint.originalData ?? '', - waterHazardClass: this.data.waterHazardClass.originalData ?? '', - signalWord: this.data.signalWord.originalData ?? '', - lethalDose: this.data.lethalDose.originalData ?? '', - mak: this.data.mak.originalData ?? '', + name: this.data.name.originalData[0], + cas: this.data.cas.originalData[0] ?? '', + molecularFormula: this.data.molecularFormula.originalData[0] ?? '', + molarMass: this.data.molarMass.originalData[0] ?? '', + meltingPoint: this.data.meltingPoint.originalData[0] ?? '', + boilingPoint: this.data.boilingPoint.originalData[0] ?? '', + waterHazardClass: this.data.waterHazardClass.originalData[0] ?? '', + signalWord: this.data.signalWord.originalData[0] ?? '', + lethalDose: this.data.lethalDose.originalData[0] ?? '', + mak: this.data.mak.originalData[0] ?? '', amount: { value: '', unit: UnitType.GRAM }, - hPhrases: this.data.hPhrases.originalData.map((phrase) => ({ + hPhrases: this.data.hPhrases.originalData[0].map((phrase) => ({ hNumber: phrase[0], hPhrase: phrase[1], hover: false, })), - pPhrases: this.data.pPhrases.originalData.map((phrase) => ({ + pPhrases: this.data.pPhrases.originalData[0].map((phrase) => ({ pNumber: phrase[0], pPhrase: phrase[1], hover: false, })), - symbols: this.data.symbols.originalData, + symbols: this.data.symbols.originalData[0], }); this.form.markAllAsTouched(); @@ -308,10 +308,10 @@ export class EditSubstanceDataComponent implements OnInit, OnDestroy { const unit = this.amount.get('unit')?.value; if ((unit as UnitType) === UnitType.CUSTOM) { - return { value, unit: { type: unit, name: this.amount.get('unitName')?.value } }; + return { value, type: unit, name: this.amount.get('unitName')?.value }; } - return { value, unit: { type: unit } }; + return { value, type: unit }; } else { return this.data.amount; } @@ -339,13 +339,14 @@ export class EditSubstanceDataComponent implements OnInit, OnDestroy { formArray: FormArray, mapCallback: (value: AbstractControl) => T, currentData: Data, + index = 0, ): Data { if (formArray.touched) { const newArray = formArray.controls.map(mapCallback); let retData: Data = { originalData: currentData.originalData }; // if new value is still/again the original value don't set modified field // arrays won't be undefined, so we don't need the extra check here - if (!compareArrays(newArray, currentData.originalData)) { + if (!compareArrays(newArray, currentData.originalData[index] ?? [])) { retData = { ...retData, modifiedData: newArray }; } return retData; diff --git a/frontend/src/app/components/header/header.component.html b/frontend/src/app/components/header/header.component.html index 067491744..ab982b5c2 100644 --- a/frontend/src/app/components/header/header.component.html +++ b/frontend/src/app/components/header/header.component.html @@ -5,8 +5,8 @@ - {{ t('organisation') }} - + {{ t('organization') }} + {{ t('labCourse') }} diff --git a/frontend/src/app/components/preview/preview.component.html b/frontend/src/app/components/preview/preview.component.html index 760df2daa..be869341c 100644 --- a/frontend/src/app/components/preview/preview.component.html +++ b/frontend/src/app/components/preview/preview.component.html @@ -10,7 +10,7 @@

{{ (header | async)?.documentTitle }} - {{ (header | async)?.organisation }} + {{ (header | async)?.organization }} {{ (header | async)?.labCourse }} @@ -66,7 +66,7 @@

{{ getPhraseNumber(data.hPhrases).join(', ') }}
{{ getPhraseNumber(data.pPhrases).join(', ') }} {{ data.mak }}
{{ data.waterHazardClass }} - {{ data.amount?.value }} {{ data.amount ? getViewValue(data.amount.unit) : '' }} + {{ data.amount?.value }} {{ data.amount ? getViewValue(data.amount) : '' }} diff --git a/frontend/src/app/components/preview/preview.component.ts b/frontend/src/app/components/preview/preview.component.ts index 84a2f7100..9405b216e 100644 --- a/frontend/src/app/components/preview/preview.component.ts +++ b/frontend/src/app/components/preview/preview.component.ts @@ -58,7 +58,7 @@ export class PreviewComponent implements OnInit { .pipe(map((state) => state.form.model?.elements ?? [])); } - getPhraseNumber(phrases: [string, string][]): string[] { + getPhraseNumber(phrases: Parameters<(phraseNumber: string, phrase: string) => void>[]): string[] { return phrases.map((p) => p[0]); } diff --git a/frontend/src/assets/docsTemplate.json b/frontend/src/assets/docsTemplate.json index 1e48e4855..56e5650c3 100644 --- a/frontend/src/assets/docsTemplate.json +++ b/frontend/src/assets/docsTemplate.json @@ -5,7 +5,7 @@ "documentTitle": "Betriebsanweisungen nach EG Nr. 1272/2008", "labCourse": "Praktikum Anorganische Chemie", "name": "", - "organisation": "Für chemische Laboratorien des Campus Burghausen", + "organization": "Für chemische Laboratorien des Campus Burghausen", "place": "", "preparation": "" }, diff --git a/frontend/src/environments/environment.prod.ts b/frontend/src/environments/environment.prod.ts index 90b1d240a..2b4a43951 100644 --- a/frontend/src/environments/environment.prod.ts +++ b/frontend/src/environments/environment.prod.ts @@ -1,4 +1,5 @@ export const environment = { production: true, web: false, + serverUrl: 'not implemented in tauri-target', }; diff --git a/frontend/src/environments/environment.ts b/frontend/src/environments/environment.ts index dcf8f9b09..249a0b48d 100644 --- a/frontend/src/environments/environment.ts +++ b/frontend/src/environments/environment.ts @@ -5,6 +5,7 @@ export const environment = { production: false, web: false, + serverUrl: 'not implemented in tauri-target', }; /* diff --git a/frontend/src/environments/environment.web.prod.ts b/frontend/src/environments/environment.web.prod.ts index 6b1d31f2f..a87a2c895 100644 --- a/frontend/src/environments/environment.web.prod.ts +++ b/frontend/src/environments/environment.web.prod.ts @@ -1,4 +1,5 @@ export const environment = { production: true, web: true, + serverUrl: 'https://api.cabr2.de/api/v1/', }; diff --git a/frontend/src/environments/environment.web.ts b/frontend/src/environments/environment.web.ts index 13aca1b18..21f9c204b 100644 --- a/frontend/src/environments/environment.web.ts +++ b/frontend/src/environments/environment.web.ts @@ -3,4 +3,5 @@ export const environment = { production: false, web: true, + serverUrl: 'http://localhost:3030/api/v1/', };