diff --git a/i18n/en.pot b/i18n/en.pot index 032455b5..af7e7915 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,11 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2024-12-19T11:55:32.909Z\n" -"PO-Revision-Date: 2024-12-19T11:55:32.909Z\n" - -msgid "There was a problem with {{dataElementErrorIdentifiers}}" -msgstr "" +"POT-Creation-Date: 2024-12-19T15:42:35.172Z\n" +"PO-Revision-Date: 2024-12-19T15:42:35.172Z\n" msgid "Facilities" msgstr "" diff --git a/i18n/es.po b/i18n/es.po index c0fdd55e..9e55f18d 100644 --- a/i18n/es.po +++ b/i18n/es.po @@ -1,16 +1,13 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-12-19T11:55:32.909Z\n" +"POT-Creation-Date: 2024-12-19T15:42:35.172Z\n" "PO-Revision-Date: 2018-10-25T09:02:35.143Z\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -msgid "There was a problem with {{dataElementErrorIdentifiers}}" -msgstr "" - msgid "Facilities" msgstr "" diff --git a/src/data/entities/D2Program.ts b/src/data/entities/D2Program.ts index 643d86cf..7bb5ad86 100644 --- a/src/data/entities/D2Program.ts +++ b/src/data/entities/D2Program.ts @@ -1,5 +1,4 @@ import { Id } from "../../domain/entities/Ref"; -import { Codec, Schema } from "../../utils/codec"; export type ProgramRuleActionType = | "DISPLAYTEXT" @@ -43,25 +42,15 @@ export interface ProgramStage { } export interface ProgramDataElement { - code: string; + code?: string; id: string; name: string; - formName: string; + formName?: string; valueType: string; optionSet?: { id: string }; sortOrder?: number | undefined; } -export const ProgramDataElementModel: Codec = Schema.object({ - code: Schema.string, - id: Schema.string, - name: Schema.string, - formName: Schema.string, - valueType: Schema.string, - optionSet: Schema.optional(Schema.object({ id: Schema.string })), - sortOrder: Schema.optional(Schema.number), -}); - export interface OptionSet { id: string; name: string; @@ -78,9 +67,9 @@ export interface Option { export interface TrackedEntityAttibute { id: string; - code: string; + code?: string; name: string; - formName: string; + formName?: string; sortOrder: number; valueType: string; optionSet?: { id: string }; diff --git a/src/data/repositories/SurveyFormD2Repository.ts b/src/data/repositories/SurveyFormD2Repository.ts index 3bd0ea7c..62ceab7b 100644 --- a/src/data/repositories/SurveyFormD2Repository.ts +++ b/src/data/repositories/SurveyFormD2Repository.ts @@ -38,7 +38,6 @@ import { Questionnaire } from "../../domain/entities/Questionnaire/Questionnaire import { ASTGUIDELINE_TYPES } from "../../domain/entities/ASTGuidelines"; import { getSurveyChildCount, SurveyChildCountType } from "../utils/surveyChildCountHelper"; import { TrackerPostResponse } from "@eyeseetea/d2-api/api/tracker"; -import { validateDataElements } from "../utils/validationHelper"; const OU_CHUNK_SIZE = 500; export class SurveyD2Repository implements SurveyRepository { @@ -90,11 +89,6 @@ export class SurveyD2Repository implements SurveyRepository { }; }); - const dataElementErrors = validateDataElements(dataElementsWithSortOrder); - if (dataElementErrors) { - return Future.error(new Error(dataElementErrors)); - } - const sortedTrackedentityAttr = resp.programTrackedEntityAttributes ? _( _(resp.programTrackedEntityAttributes) diff --git a/src/data/utils/questionHelper.ts b/src/data/utils/questionHelper.ts index 6c79834e..f99b3a69 100644 --- a/src/data/utils/questionHelper.ts +++ b/src/data/utils/questionHelper.ts @@ -43,16 +43,19 @@ const SPECIES_QUESTION_FORNAME = "Specify the specie"; const ANTIBIOTIC_QUESTION_FORNAME = "Specify the antibiotic"; const getQuestionBase = ( id: Id, - code: string, + code: string | undefined, name: string, - formName: string, + formName: string | undefined, sortOrder: number | undefined ): QuestionBase => { + if (formName === undefined || code === undefined) { + console.debug("formName or code undefined. Defaulting to ''", { id, name, code, formName }); + } return { id: id, - code: code, //code + code: code ?? "", name: name, - text: formName, //formName + text: formName ?? "", isVisible: true, sortOrder: sortOrder, errors: [], @@ -81,9 +84,9 @@ const getSelectQuestionBase = ( export const getQuestion = ( valueType: string, id: Id, - code: string, + code: string | undefined, name: string, - formName: string, + formName: string | undefined, sortOrder: number | undefined, options: Option[], optionSet?: { id: string }, @@ -128,7 +131,7 @@ export const getQuestion = ( case "EMAIL": case "TEXT": { if (optionSet) { - const isSpeciesQuestion = formName.includes(SPECIES_QUESTION_FORNAME); + const isSpeciesQuestion = formName?.includes(SPECIES_QUESTION_FORNAME) ?? false; const isAntibioticQuestion = name.startsWith(ANTIBIOTIC_QUESTION_FORNAME); const selectBase = getSelectQuestionBase(base, options, optionSet, dataValue); diff --git a/src/data/utils/validationHelper.ts b/src/data/utils/validationHelper.ts deleted file mode 100644 index 5dbd8708..00000000 --- a/src/data/utils/validationHelper.ts +++ /dev/null @@ -1,20 +0,0 @@ -import _ from "../../domain/entities/generic/Collection"; -import { getValidationErrorsByItem } from "../../utils/validations"; -import { ProgramDataElement, ProgramDataElementModel } from "../entities/D2Program"; -import i18n from "../../utils/i18n"; - -export function validateDataElements(dataElements: ProgramDataElement[]): string | null { - const dataElementErrors = getValidationErrorsByItem(ProgramDataElementModel, dataElements); - if (dataElementErrors) { - const dataElementErrorIdentifiers = _(dataElementErrors) - .map(de => de.item.code) - .uniq() - .join(", "); - console.error("DataElement validation errors", dataElementErrors); - return i18n.t("There was a problem with {{dataElementErrorIdentifiers}}", { - dataElementErrorIdentifiers, - }); - } else { - return null; - } -} diff --git a/src/utils/codec.ts b/src/utils/codec.ts deleted file mode 100644 index 353def9e..00000000 --- a/src/utils/codec.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { - array, - Codec, - date, - Either as PurifyEither, - enumeration, - exactly, - identity, - intersect, - lazy, - Left, - maybe, - nonEmptyList, - nullable, - nullType, - number, - oneOf, - optional, - record, - Right, - string, - unknown, -} from "purify-ts"; -import { - chainCodec, - DateFromStringFormatOf, - FormattedStringFromDate, - Integer, - IntegerFromString, - Interface, - JsonFromString, - NonEmptyString, - NumberFromString, - NumberRangedIn, - StringLengthRangedIn, -} from "purify-ts-extra-codec"; -import { Either } from "../domain/entities/generic/Either"; - -function isFunction(value: unknown): value is Function { - return typeof value === "function"; -} - -type DefaultValue = T | (() => T); - -export const decodeModel = (model: Codec, value: unknown): Either => { - try { - const either = model.decode(value); - - if (either.isRight()) { - return Either.success(either.extract()); - } - - return Either.error(either.leftOrDefault("Couldn't decode input")); - } catch (error: any) { - console.error(error); - return Either.error("Couldn't read JSON"); - } -}; - -const optionalSafe = (codec: Codec, defaultValue: DefaultValue): Codec => { - const decode = (input: unknown): PurifyEither => { - if (input === undefined) { - const value = isFunction(defaultValue) ? defaultValue() : defaultValue; - return PurifyEither.of(value); - } else { - return codec.decode(input); - } - }; - - // Need to force type due private _isOptional flag - return { ...codec, decode, _isOptional: true } as Codec; -}; - -const booleanFromString = Codec.custom({ - decode: value => { - if (String(value).toLowerCase() === "true") return Right(true); - if (String(value).toLowerCase() === "false") return Right(false); - return Left(`${value} is not a parsable boolean`); - }, - encode: value => `${value}`, -}); - -const undefinedType = Codec.custom({ - decode: value => (value === undefined ? Right(value) : Left(`${value} is not undefined`)), - encode: identity, - schema: () => ({ type: "null" }), -}); - -export const Schema = { - object: Interface, - stringObject: JsonFromString, - array, - nonEmptyArray: nonEmptyList, - dictionary: record, - string, - nonEmptyString: NonEmptyString, - stringLength: StringLengthRangedIn, - integer: oneOf([Integer, IntegerFromString]), - number: oneOf([number, NumberFromString]), - numberBetween: NumberRangedIn, - boolean: booleanFromString, - null: nullType, - undefined: undefinedType, - unknown, - date, - formattedDate: FormattedStringFromDate, - stringDate: DateFromStringFormatOf, - oneOf, - optional, - optionalSafe, - nullable, - enum: enumeration, - exact: exactly, - extend: intersect, - maybe, - chain: chainCodec, - custom: Codec.custom, - lazy, -}; - -export declare type FromType = { - [P in keyof Required]: Pick extends Required> ? T[P] : T[P] | undefined; -}; - -export { Codec, parseError as parseSchemaError } from "purify-ts"; -export type { DecodeError as SchemaDecodeError } from "purify-ts"; diff --git a/src/utils/validations.ts b/src/utils/validations.ts deleted file mode 100644 index 1c523537..00000000 --- a/src/utils/validations.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Codec, decodeModel } from "./codec"; - -export function getValidationErrorsByItem( - model: Codec, - collection: T[] -): { item: T; error: string }[] | null { - const validationErrors = collection - .map(item => ({ item, validation: decodeModel(model, item) })) - .filter(({ validation }) => validation.isError()) - .map(({ item, validation }) => ({ item, error: validation.value.error as string })); - return validationErrors.length ? validationErrors : null; -}