@f1studio/form-spec 5.0.0-alpha.111 → 5.0.0-alpha.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FormSpec.FS/BitmaskHelpers.d.ts +23 -0
- package/FormSpec.FS/BitmaskHelpers.d.ts.map +1 -0
- package/FormSpec.FS/BlueprintValidation.d.ts +16 -0
- package/FormSpec.FS/BlueprintValidation.d.ts.map +1 -0
- package/FormSpec.FS/FormSpec.d.ts +19 -5
- package/FormSpec.FS/FormSpec.d.ts.map +1 -1
- package/FormSpec.FS/FormSpecHelpers.d.ts +4 -0
- package/FormSpec.FS/FormSpecHelpers.d.ts.map +1 -1
- package/FormSpec.FS/FormSpecValues.d.ts +5 -0
- package/FormSpec.FS/FormSpecValues.d.ts.map +1 -1
- package/FormSpec.FS/Helpers.d.ts.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.d.ts +13 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRElementTypeMap.d.ts +22 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRElementTypeMap.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.d.ts +22 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.d.ts +130 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSectioning.d.ts +37 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSectioning.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSemanticReportBuilder.d.ts +231 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSemanticReportBuilder.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRStepsBuilder.d.ts +10 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRStepsBuilder.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.d.ts +55 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTriggerConverter.d.ts +69 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTriggerConverter.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMREncoder.d.ts +21 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMREncoder.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.d.ts +133 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.d.ts +52 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/FormSystemAdapter.d.ts +46 -0
- package/FormSpec.FS/Integrations/Adapters/FormSystemAdapter.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormAdapter.d.ts +4 -0
- package/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormAdapter.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormTypes.d.ts +36 -0
- package/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormTypes.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/CorEMR/CorEmrTemplates.d.ts +95 -0
- package/FormSpec.FS/Integrations/CorEMR/CorEmrTemplates.d.ts.map +1 -0
- package/FormSpec.FS/Integrations/CorEMR/CoreMRTypes.d.ts +449 -0
- package/FormSpec.FS/Integrations/CorEMR/CoreMRTypes.d.ts.map +1 -0
- package/FormSpec.FS/Interop/FormSpec.Api.Helpers.d.ts.map +1 -1
- package/FormSpec.FS/Interop/FormSpec.Api.Option.d.ts +3 -1
- package/FormSpec.FS/Interop/FormSpec.Api.Option.d.ts.map +1 -1
- package/FormSpec.FS/Provenance.d.ts +10 -0
- package/FormSpec.FS/Provenance.d.ts.map +1 -0
- package/FormSpec.FS/Renderers/FormSpecMarkdownRenderer.d.ts.map +1 -1
- package/FormSpec.TS/FormSpec.FS/BitmaskHelpers.js +56 -0
- package/FormSpec.TS/FormSpec.FS/BitmaskHelpers.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/BitmaskHelpers.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/BlueprintValidation.js +116 -0
- package/FormSpec.TS/FormSpec.FS/BlueprintValidation.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/BlueprintValidation.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Designer.js +2 -2
- package/FormSpec.TS/FormSpec.FS/Designer.js.map +1 -1
- package/FormSpec.TS/FormSpec.FS/Designer.ts.map +1 -1
- package/FormSpec.TS/FormSpec.FS/FormSpec.js +72 -3
- package/FormSpec.TS/FormSpec.FS/FormSpec.js.map +1 -1
- package/FormSpec.TS/FormSpec.FS/FormSpec.ts.map +1 -1
- package/FormSpec.TS/FormSpec.FS/FormSpecHelpers.js +201 -3
- package/FormSpec.TS/FormSpec.FS/FormSpecHelpers.js.map +1 -1
- package/FormSpec.TS/FormSpec.FS/FormSpecHelpers.ts.map +1 -1
- package/FormSpec.TS/FormSpec.FS/FormSpecValues.js +38 -3
- package/FormSpec.TS/FormSpec.FS/FormSpecValues.js.map +1 -1
- package/FormSpec.TS/FormSpec.FS/FormSpecValues.ts.map +1 -1
- package/FormSpec.TS/FormSpec.FS/Helpers.js +44 -27
- package/FormSpec.TS/FormSpec.FS/Helpers.js.map +1 -1
- package/FormSpec.TS/FormSpec.FS/Helpers.ts.map +1 -1
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.js +45 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRElementTypeMap.js +145 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRElementTypeMap.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRElementTypeMap.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.js +139 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.js +801 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSectioning.js +121 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSectioning.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSectioning.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSemanticReportBuilder.js +1380 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSemanticReportBuilder.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSemanticReportBuilder.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRStepsBuilder.js +29 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRStepsBuilder.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRStepsBuilder.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.js +172 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTriggerConverter.js +406 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTriggerConverter.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTriggerConverter.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMREncoder.js +317 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMREncoder.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMREncoder.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.js +622 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.js +448 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/FormSystemAdapter.js +198 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/FormSystemAdapter.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/FormSystemAdapter.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormAdapter.js +57 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormAdapter.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormAdapter.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormTypes.js +144 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormTypes.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormTypes.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/CorEMR/CorEmrTemplates.js +258 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/CorEMR/CorEmrTemplates.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/CorEMR/CorEmrTemplates.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/CorEMR/CoreMRTypes.js +1768 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/CorEMR/CoreMRTypes.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Integrations/CorEMR/CoreMRTypes.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Interop/FormSpec.Api.Helpers.js +22 -18
- package/FormSpec.TS/FormSpec.FS/Interop/FormSpec.Api.Helpers.js.map +1 -1
- package/FormSpec.TS/FormSpec.FS/Interop/FormSpec.Api.Helpers.ts.map +1 -1
- package/FormSpec.TS/FormSpec.FS/Interop/FormSpec.Api.Option.js +18 -6
- package/FormSpec.TS/FormSpec.FS/Interop/FormSpec.Api.Option.js.map +1 -1
- package/FormSpec.TS/FormSpec.FS/Interop/FormSpec.Api.Option.ts.map +1 -1
- package/FormSpec.TS/FormSpec.FS/PathwayExecutor.js +1 -1
- package/FormSpec.TS/FormSpec.FS/Provenance.js +41 -0
- package/FormSpec.TS/FormSpec.FS/Provenance.js.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Provenance.ts.map +1 -0
- package/FormSpec.TS/FormSpec.FS/Renderers/FormSpecMarkdownRenderer.js +36 -13
- package/FormSpec.TS/FormSpec.FS/Renderers/FormSpecMarkdownRenderer.js.map +1 -1
- package/FormSpec.TS/FormSpec.FS/Renderers/FormSpecMarkdownRenderer.ts.map +1 -1
- package/FormSpec.TS/FormSpec.FS/Renderers/PathwayRenderers.js +1 -1
- package/FormSpec.TS/PathwayExecutor.withPlugins.js +0 -5
- package/FormSpec.TS/PathwayExecutor.withPlugins.js.map +1 -1
- package/FormSpec.TS/PluginRegistration.js +2 -0
- package/FormSpec.TS/PluginRegistration.js.map +1 -1
- package/FormSpec.TS/PluginRegistration.ts.map +1 -1
- package/FormSpec.TS/fable_modules/project_cracked.json +1 -1
- package/FormSpec.TS/plugins/demographics/src/DemographicsField.js +918 -0
- package/FormSpec.TS/plugins/demographics/src/DemographicsField.js.map +1 -0
- package/FormSpec.TS/plugins/demographics/src/DemographicsField.ts.map +1 -0
- package/FormSpec.TS/plugins/likert/src/LikertField.js +1 -1
- package/PathwayExecutor.withPlugins.d.ts +0 -5
- package/PathwayExecutor.withPlugins.d.ts.map +1 -1
- package/README.md +7 -7
- package/fable_modules/Thoth.Json.10.4.1/Extra.fs.d.ts +3 -0
- package/fable_modules/Thoth.Json.10.4.1/Extra.fs.d.ts.map +1 -0
- package/package.json +4 -4
- package/plugins/demographics/src/DemographicsField.d.ts +104 -0
- package/plugins/demographics/src/DemographicsField.d.ts.map +1 -0
- package/src/FormSpec.FS/BitmaskHelpers.ts +52 -0
- package/src/FormSpec.FS/BlueprintValidation.ts +108 -0
- package/src/FormSpec.FS/Designer.ts +2 -2
- package/src/FormSpec.FS/FormSpec.ts +39 -8
- package/src/FormSpec.FS/FormSpecHelpers.ts +190 -12
- package/src/FormSpec.FS/FormSpecValues.ts +42 -3
- package/src/FormSpec.FS/Helpers.ts +44 -27
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.ts +37 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRElementTypeMap.ts +103 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.ts +129 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.ts +490 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSectioning.ts +87 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRSemanticReportBuilder.ts +1046 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRStepsBuilder.ts +26 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.ts +161 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTriggerConverter.ts +386 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMREncoder.ts +320 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.ts +371 -0
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.ts +372 -0
- package/src/FormSpec.FS/Integrations/Adapters/FormSystemAdapter.ts +92 -0
- package/src/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormAdapter.ts +51 -0
- package/src/FormSpec.FS/Integrations/Adapters/ReactHookForm/ReactHookFormTypes.ts +71 -0
- package/src/FormSpec.FS/Integrations/CorEMR/CorEmrTemplates.ts +15 -0
- package/src/FormSpec.FS/Integrations/CorEMR/CoreMRTypes.ts +825 -0
- package/src/FormSpec.FS/Interop/FormSpec.Api.Helpers.ts +19 -15
- package/src/FormSpec.FS/Interop/FormSpec.Api.Option.ts +13 -7
- package/src/FormSpec.FS/PathwayExecutor.ts +1 -1
- package/src/FormSpec.FS/Provenance.ts +19 -0
- package/src/FormSpec.FS/Renderers/FormSpecMarkdownRenderer.ts +32 -12
- package/src/FormSpec.FS/Renderers/PathwayRenderers.ts +1 -1
- package/src/PathwayExecutor.withPlugins.ts +0 -5
- package/src/PluginRegistration.ts +2 -0
- package/src/plugins/demographics/src/DemographicsField.ts +502 -0
- package/src/plugins/likert/src/LikertField.ts +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { empty, FSharpList, map, mapIndexed } from "@fable-org/fable-library-js/List.js";
|
|
2
|
+
import { mapToFormField } from "./CorEMRFieldTypeMapper.js";
|
|
3
|
+
import { defaultArg } from "@fable-org/fable-library-js/Option.js";
|
|
4
|
+
import { FSharpMap, tryFind } from "@fable-org/fable-library-js/Map.js";
|
|
5
|
+
import { int32 } from "@fable-org/fable-library-js/Int32.js";
|
|
6
|
+
import { CoreMRItem, CoreMRChoice } from "../../CorEMR/CoreMRTypes.js";
|
|
7
|
+
import { Spec_FormStep$1, Spec_FieldType_$union, Spec_FormField$1 } from "../../../FormSpec.js";
|
|
8
|
+
import { isNullOrWhiteSpace } from "@fable-org/fable-library-js/String.js";
|
|
9
|
+
import { detectHeadings, groupItemsByHeadings, Section } from "./CorEMRSectioning.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Create FormSpec Steps from CoreMR items
|
|
13
|
+
*/
|
|
14
|
+
export function createSteps(formCode: string, items: FSharpList<CoreMRItem>, choicesByItem: FSharpMap<int32, FSharpList<CoreMRChoice>>): FSharpList<Spec_FormStep$1<Spec_FieldType_$union>> {
|
|
15
|
+
return mapIndexed<Section, Spec_FormStep$1<Spec_FieldType_$union>>((index: int32, section: Section): Spec_FormStep$1<Spec_FieldType_$union> => (new Spec_FormStep$1(index + 1, section.HeadingLabel, map<CoreMRItem, Spec_FormField$1<Spec_FieldType_$union>>((item: CoreMRItem): Spec_FormField$1<Spec_FieldType_$union> => {
|
|
16
|
+
const field: Spec_FormField$1<Spec_FieldType_$union> = mapToFormField(formCode, index + 1, item, defaultArg(tryFind<int32, FSharpList<CoreMRChoice>>(item.ItemId, choicesByItem), empty<CoreMRChoice>()));
|
|
17
|
+
if (isNullOrWhiteSpace(field.Label)) {
|
|
18
|
+
return new Spec_FormField$1(field.FieldOrder, field.FieldKey, "_(blank)_", field.Notes, field.DependsOn, field.IsOptional, field.IsDeprecated, field.NeedsDocumentation, field.Documentation, field.FieldType, field.Value);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
return field;
|
|
22
|
+
}
|
|
23
|
+
}, section.Items))), groupItemsByHeadings(detectHeadings(items), items));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=CorEMRStepsBuilder.ts.map
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Helpers_generateDeterministicGuidRaw, Helpers_canonicalizeFieldKey } from "../../../Helpers.js";
|
|
2
|
+
import { tryFind, FSharpMap, ofList } from "@fable-org/fable-library-js/Map.js";
|
|
3
|
+
import { empty, isEmpty, collect, ofArray, sumBy, FSharpList, map } from "@fable-org/fable-library-js/List.js";
|
|
4
|
+
import { int32 } from "@fable-org/fable-library-js/Int32.js";
|
|
5
|
+
import { CoreMRFormData, CoreMRTag, CoreMRItem, CoreMRChoice } from "../../CorEMR/CoreMRTypes.js";
|
|
6
|
+
import { numberHash, comparePrimitives } from "@fable-org/fable-library-js/Util.js";
|
|
7
|
+
import { Spec_FormSpec$1_$reflection, Spec_FieldType_$reflection, Spec_FormSpec$1, Spec_FormLifecycle_Blueprint, ClinicalPathway_ClinicalPathwaySpec, Spec_FormField$1, Shared_FieldKey, Spec_FieldType_$union, Spec_FormStep$1, Spec_Score, Spec_ScoreColor_Danger, Spec_ScoreColor_Warning, Spec_ScoreRange, Spec_ScoreColor_Success } from "../../../FormSpec.js";
|
|
8
|
+
import { defaultArg, Option } from "@fable-org/fable-library-js/Option.js";
|
|
9
|
+
import { toConsoleError, printf, toText, substring } from "@fable-org/fable-library-js/String.js";
|
|
10
|
+
import { createSteps } from "./CorEMRStepsBuilder.js";
|
|
11
|
+
import { List_groupBy } from "@fable-org/fable-library-js/Seq2.js";
|
|
12
|
+
import { generateNamespacedFieldKey } from "./CorEMRFieldTypeMapper.js";
|
|
13
|
+
import { nonHeadingItems } from "./CorEMRSectioning.js";
|
|
14
|
+
import { convertTriggersToSinglePathway } from "./CorEMRTriggerConverter.js";
|
|
15
|
+
import { Auto_generateBoxedEncoder_437914C6, toString } from "../../../../fable_modules/Thoth.Json.10.4.1/Encode.fs.js";
|
|
16
|
+
import { FSharpResult$2_Ok, FSharpResult$2_$union, FSharpResult$2_Error } from "@fable-org/fable-library-js/Result.js";
|
|
17
|
+
import { FormSpecValidator_validateConversion, ValidationResult } from "./CorEMRFormSpecValidator.js";
|
|
18
|
+
import { buildReport } from "./CorEMRSemanticReportBuilder.js";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Use FormSpec's single source of truth for canonicalization
|
|
22
|
+
*/
|
|
23
|
+
export function canonicalizeFieldKey(input: string): string {
|
|
24
|
+
return Helpers_canonicalizeFieldKey(input);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Generate deterministic GUID using FormSpec's single source of truth
|
|
29
|
+
*/
|
|
30
|
+
export function generateStableDeterministicGuid(name: string): string {
|
|
31
|
+
return Helpers_generateDeterministicGuidRaw(`coremr:formspec:${name}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Create mapping from choice ID to actual text value
|
|
36
|
+
*/
|
|
37
|
+
export function createChoiceIdToTextMap(choices: FSharpList<CoreMRChoice>): FSharpMap<int32, string> {
|
|
38
|
+
return ofList<int32, string>(map<CoreMRChoice, [int32, string]>((c: CoreMRChoice): [int32, string] => ([c.ChoiceId, c.Text] as [int32, string]), choices), {
|
|
39
|
+
Compare: comparePrimitives,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Calculate scoring from choice scores
|
|
45
|
+
*/
|
|
46
|
+
export function calculateScore(choices: FSharpList<CoreMRChoice>, formName: string): Option<Spec_Score> {
|
|
47
|
+
const maxScore: int32 = sumBy<CoreMRChoice, int32>((c: CoreMRChoice): int32 => c.Score, choices, {
|
|
48
|
+
GetZero: (): int32 => 0,
|
|
49
|
+
Add: (x: int32, y: int32): int32 => (x + y),
|
|
50
|
+
}) | 0;
|
|
51
|
+
if (maxScore > 0) {
|
|
52
|
+
return new Spec_Score(maxScore, ofArray([new Spec_ScoreRange(generateStableDeterministicGuid(`score_range_${formName}_low`), 0, ~~(maxScore / 3), "Low Risk", Spec_ScoreColor_Success()), new Spec_ScoreRange(generateStableDeterministicGuid(`score_range_${formName}_medium`), ~~(maxScore / 3) + 1, ~~((maxScore * 2) / 3), "Medium Risk", Spec_ScoreColor_Warning()), new Spec_ScoreRange(generateStableDeterministicGuid(`score_range_${formName}_high`), ~~((maxScore * 2) / 3) + 1, maxScore, "High Risk", Spec_ScoreColor_Danger())]));
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Extract form code from form name using patterns:
|
|
61
|
+
* 1. If ends with (CODE) - extract CODE
|
|
62
|
+
* 2. If contains ' - ' - take everything after last dash
|
|
63
|
+
* 3. Otherwise use CORE-{id}
|
|
64
|
+
*/
|
|
65
|
+
export function extractFormCode(formName: string, formId: int32): string {
|
|
66
|
+
const trimmed: string = formName.trim();
|
|
67
|
+
if (trimmed.endsWith(")") && (trimmed.indexOf("(") >= 0)) {
|
|
68
|
+
const lastOpenParen: int32 = trimmed.lastIndexOf("(") | 0;
|
|
69
|
+
const lastCloseParen: int32 = trimmed.lastIndexOf(")") | 0;
|
|
70
|
+
if (lastOpenParen < lastCloseParen) {
|
|
71
|
+
return substring(trimmed, lastOpenParen + 1, (lastCloseParen - lastOpenParen) - 1).trim();
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return `CORE-${formId}`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else if (trimmed.indexOf(" - ") >= 0) {
|
|
78
|
+
const lastDashIndex: int32 = trimmed.lastIndexOf(" - ") | 0;
|
|
79
|
+
return substring(trimmed, lastDashIndex + 3).trim();
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
return `CORE-${formId}`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Convert CoreMR form data to FormSpec
|
|
88
|
+
*/
|
|
89
|
+
export function convertToFormSpec(formData: CoreMRFormData): Spec_FormSpec$1<Spec_FieldType_$union> {
|
|
90
|
+
const formCode: string = extractFormCode(formData.Metadata.FormName, formData.Metadata.FormId);
|
|
91
|
+
const steps: FSharpList<Spec_FormStep$1<Spec_FieldType_$union>> = createSteps(formCode, formData.Items, ofList<int32, FSharpList<CoreMRChoice>>(List_groupBy<CoreMRChoice, int32>((c: CoreMRChoice): int32 => c.ItemId, formData.Choices, {
|
|
92
|
+
Equals: (x: int32, y: int32): boolean => (x === y),
|
|
93
|
+
GetHashCode: numberHash,
|
|
94
|
+
}), {
|
|
95
|
+
Compare: comparePrimitives,
|
|
96
|
+
}));
|
|
97
|
+
const score: Option<Spec_Score> = calculateScore(formData.Choices, formData.Metadata.FormName);
|
|
98
|
+
const fieldKeyBySequence: FSharpMap<int32, Shared_FieldKey> = ofList<int32, Shared_FieldKey>(map<Spec_FormField$1<Spec_FieldType_$union>, [int32, Shared_FieldKey]>((field: Spec_FormField$1<Spec_FieldType_$union>): [int32, Shared_FieldKey] => ([field.FieldOrder, field.FieldKey] as [int32, Shared_FieldKey]), collect<Spec_FormStep$1<Spec_FieldType_$union>, Spec_FormField$1<Spec_FieldType_$union>>((step: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<Spec_FormField$1<Spec_FieldType_$union>> => step.Fields, steps)), {
|
|
99
|
+
Compare: comparePrimitives,
|
|
100
|
+
});
|
|
101
|
+
const itemIdToFieldKeyMap: FSharpMap<int32, Shared_FieldKey> = ofList<int32, Shared_FieldKey>(map<CoreMRItem, [int32, Shared_FieldKey]>((item: CoreMRItem): [int32, Shared_FieldKey] => ([item.ItemId, defaultArg(tryFind<int32, Shared_FieldKey>(item.Sequence, fieldKeyBySequence), generateNamespacedFieldKey(formCode, 1, item))] as [int32, Shared_FieldKey]), nonHeadingItems(formData.Items)), {
|
|
102
|
+
Compare: comparePrimitives,
|
|
103
|
+
});
|
|
104
|
+
const clinicalPathway: Option<ClinicalPathway_ClinicalPathwaySpec> = isEmpty(formData.Triggers) ? undefined : convertTriggersToSinglePathway(formData.Triggers, (itemId: int32): Shared_FieldKey => defaultArg(tryFind<int32, Shared_FieldKey>(itemId, itemIdToFieldKeyMap), new Shared_FieldKey(generateStableDeterministicGuid(`unknown_item_${itemId}`))), createChoiceIdToTextMap(formData.Choices), formData.Metadata, formData.Items);
|
|
105
|
+
return new Spec_FormSpec$1(generateStableDeterministicGuid(`form_${formData.Metadata.FormId}_${formData.Metadata.FormName}`), formCode, formData.Metadata.FormName, defaultArg(formData.Metadata.Description, ""), toText(printf("1.0.0-CoreEMRv%d"))(formData.Metadata.VersionNumber), "5.0.0", steps, map<CoreMRTag, string>((t: CoreMRTag): string => t.TagName, formData.Tags), score, empty<string>(), formData.Metadata.RequiresSignature, false, undefined, Spec_FormLifecycle_Blueprint(), undefined, undefined, undefined);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Serialize FormSpec to JSON
|
|
110
|
+
* Note: The JSON serialization may have issues with ConditionValue discriminated union.
|
|
111
|
+
* This is a known limitation - the MCP enhancement server and YAML conversion
|
|
112
|
+
* handle the FormSpec directly without relying on JSON serialization.
|
|
113
|
+
*/
|
|
114
|
+
export function serializeFormSpec(formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): string {
|
|
115
|
+
try {
|
|
116
|
+
return toString(2, Auto_generateBoxedEncoder_437914C6(Spec_FormSpec$1_$reflection(Spec_FieldType_$reflection()), undefined, undefined, undefined)(formSpec));
|
|
117
|
+
}
|
|
118
|
+
catch (ex: any) {
|
|
119
|
+
toConsoleError(`JSON serialization failed for FormSpec '${formSpec.Title}' (ID: ${formSpec.Id}): ${ex.message}`);
|
|
120
|
+
toConsoleError(`Stack trace: ${ex.stack}`);
|
|
121
|
+
toConsoleError(printf("The FormSpec object is still valid for MCP enhancement"));
|
|
122
|
+
const errorResponse: { error: string, formId: string, formTitle: string, message: string, supportedAlternatives: string[] } = {
|
|
123
|
+
error: "JSON serialization not fully supported for ConditionValue types",
|
|
124
|
+
formId: formSpec.Id,
|
|
125
|
+
formTitle: formSpec.Title,
|
|
126
|
+
message: "Use FormSpec object directly or export to YAML",
|
|
127
|
+
supportedAlternatives: ["MCP Enhancement Server", "YAML Export", "Direct FormSpec Usage"],
|
|
128
|
+
};
|
|
129
|
+
return "Legacy JSON export is deprecated. Use MCP Enhancement Server or YAML export instead.";
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Main conversion function
|
|
135
|
+
*/
|
|
136
|
+
export function convertForm(formData: CoreMRFormData): Spec_FormSpec$1<Spec_FieldType_$union> {
|
|
137
|
+
return convertToFormSpec(formData);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Convert form with validation
|
|
142
|
+
*/
|
|
143
|
+
export function convertFormWithValidation(formData: CoreMRFormData): FSharpResult$2_$union<[Spec_FormSpec$1<Spec_FieldType_$union>, ValidationResult], string> {
|
|
144
|
+
try {
|
|
145
|
+
const formSpec: Spec_FormSpec$1<Spec_FieldType_$union> = convertToFormSpec(formData);
|
|
146
|
+
const matchValue: FSharpResult$2_$union<ValidationResult, string> = FormSpecValidator_validateConversion(formData, formSpec);
|
|
147
|
+
return (matchValue.tag === /* Error */ 1) ? FSharpResult$2_Error<[Spec_FormSpec$1<Spec_FieldType_$union>, ValidationResult], string>(matchValue.fields[0]) : FSharpResult$2_Ok<[Spec_FormSpec$1<Spec_FieldType_$union>, ValidationResult], string>([formSpec, matchValue.fields[0]] as [Spec_FormSpec$1<Spec_FieldType_$union>, ValidationResult]);
|
|
148
|
+
}
|
|
149
|
+
catch (ex: any) {
|
|
150
|
+
return FSharpResult$2_Error<[Spec_FormSpec$1<Spec_FieldType_$union>, ValidationResult], string>(`Conversion failed: ${ex.message}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Convert form with semantic analysis
|
|
156
|
+
*/
|
|
157
|
+
export function convertFormWithSemantics(formData: CoreMRFormData): [Spec_FormSpec$1<Spec_FieldType_$union>, string] {
|
|
158
|
+
return [convertToFormSpec(formData), buildReport(formData)] as [Spec_FormSpec$1<Spec_FieldType_$union>, string];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
//# sourceMappingURL=CorEMRTemplateToFormSpec.ts.map
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import { Helpers_generateDeterministicGuidRaw } from "../../../Helpers.js";
|
|
2
|
+
import { ClinicalPathway_PathwayExecutionMode_MultiPathway, ClinicalPathway_MultiPathwayConfig, ClinicalPathway_ConflictResolution_CombineActions, ClinicalPathway_CombinationStrategy_AllMatching, ClinicalPathway_PathwayExecutionMode_$union, ClinicalPathway_ClinicalPathwaySpec, ClinicalPathway_PathRequirement, ClinicalPathway_ConstraintDefinition, ClinicalPathway_PathwayExecutionMode_TriggerBased, ClinicalPathway_TriggerBasedConfig, ClinicalPathway_TransitionDefinition, ClinicalPathway_StateType_Terminal, ClinicalPathway_TerminalInfo, ClinicalPathway_StateType_CompoundAction, ClinicalPathway_StateType_Action, ClinicalPathway_StateDefinition, ClinicalPathway_StateType_Evaluation, ClinicalPathway_EvaluationInfo, Shared_TransitionKey, Shared_StateKey, ClinicalPathway_TransitionCondition_Always, ClinicalPathway_TransitionCondition_CompositeCondition, ClinicalPathway_LogicalOp_And, ClinicalPathway_TransitionCondition_$union, ClinicalPathway_TransitionCondition_FieldCondition, Shared_ConditionValue_Single, Shared_ConditionValue_Multiple, Shared_FieldKey, ClinicalPathway_ActionInfo_$union, ClinicalPathway_ActionInfo_Prescription, ClinicalPathway_PrescriptionAction, ClinicalPathway_ActionInfo_Medication, ClinicalPathway_MedicationAction, ClinicalPathway_ActionInfo_Problem, ClinicalPathway_ProblemAction, ClinicalPathway_ProblemStatus_Active, ClinicalPathway_ActionInfo_Task, ClinicalPathway_TaskAction, ClinicalPathway_ActionInfo_Alert, ClinicalPathway_AlertAction, ClinicalPathway_AlertSeverity_High, ClinicalPathway_RecurrencePattern, ClinicalPathway_RecurrenceEnd_OnDate, ClinicalPathway_RecurrenceEnd_Never, ClinicalPathway_DueDate_$union, ClinicalPathway_DueDate_DaysFromNow, ClinicalPathway_DueDate_Tomorrow, ClinicalPathway_DueDate_Today, ClinicalPathway_TaskPriority_$union, ClinicalPathway_TaskPriority_Low, ClinicalPathway_TaskPriority_Medium, ClinicalPathway_TaskPriority_High, ClinicalPathway_TriggerTiming_$union, ClinicalPathway_TriggerTiming_OnFormLoad, ClinicalPathway_TriggerTiming_OnFormSubmit, ClinicalPathway_TriggerTiming_OnFormSave, ClinicalPathway_FieldEvaluator_$union, ClinicalPathway_FieldEvaluator_NotInSet, ClinicalPathway_FieldEvaluator_ContainsAll, ClinicalPathway_FieldEvaluator_LessOrEqual, ClinicalPathway_FieldEvaluator_LessThan, ClinicalPathway_FieldEvaluator_GreaterOrEqual, ClinicalPathway_FieldEvaluator_GreaterThan, ClinicalPathway_FieldEvaluator_NotEquals, ClinicalPathway_FieldEvaluator_Equals, ClinicalPathway_FieldEvaluator_InSet } from "../../../FormSpec.js";
|
|
3
|
+
import { join, trimStart, trim, split, replace, toConsoleError, printf, toFail } from "@fable-org/fable-library-js/String.js";
|
|
4
|
+
import { singleton, tryHead, append, cons, collect, mapIndexed, filter, empty, ofArray, map as map_1, item as item_3, length, tryFind as tryFind_1, head, tail, isEmpty, choose, FSharpList } from "@fable-org/fable-library-js/List.js";
|
|
5
|
+
import { tryParse, int32 } from "@fable-org/fable-library-js/Int32.js";
|
|
6
|
+
import { FSharpRef } from "@fable-org/fable-library-js/Types.js";
|
|
7
|
+
import { item as item_2 } from "@fable-org/fable-library-js/Array.js";
|
|
8
|
+
import { fromDays, fromHours } from "@fable-org/fable-library-js/TimeSpan.js";
|
|
9
|
+
import { map, defaultArg, Option, value as value_7 } from "@fable-org/fable-library-js/Option.js";
|
|
10
|
+
import { addDays, now, add } from "@fable-org/fable-library-js/DateOffset.js";
|
|
11
|
+
import { FSharpMap, tryFind } from "@fable-org/fable-library-js/Map.js";
|
|
12
|
+
import { CoreMRFormMetadata, CoreMRTrigger, CoreMRItem, CoreMRTriggerCondition, CoreMRTriggerEvent } from "../../CorEMR/CoreMRTypes.js";
|
|
13
|
+
import { ofList } from "@fable-org/fable-library-js/Set.js";
|
|
14
|
+
import { safeHash, equals, int32ToString, stringHash, comparePrimitives } from "@fable-org/fable-library-js/Util.js";
|
|
15
|
+
import { List_distinctBy, List_distinct } from "@fable-org/fable-library-js/Seq2.js";
|
|
16
|
+
|
|
17
|
+
function generateStableDeterministicGuid(name: string): string {
|
|
18
|
+
return Helpers_generateDeterministicGuidRaw(`coremr:trigger:${name}`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Convert CoreMR operator to FormSpec FieldEvaluator
|
|
23
|
+
* Note: answerValues are now actual text values, not IDs
|
|
24
|
+
*/
|
|
25
|
+
export function convertOperator(operator: string, answerValues: FSharpList<string>): ClinicalPathway_FieldEvaluator_$union {
|
|
26
|
+
const matchValue: string = operator.toLocaleLowerCase();
|
|
27
|
+
switch (matchValue) {
|
|
28
|
+
case "any":
|
|
29
|
+
return ClinicalPathway_FieldEvaluator_InSet(answerValues);
|
|
30
|
+
case "equals":
|
|
31
|
+
return ClinicalPathway_FieldEvaluator_Equals();
|
|
32
|
+
case "not_equals":
|
|
33
|
+
return ClinicalPathway_FieldEvaluator_NotEquals();
|
|
34
|
+
case "greater":
|
|
35
|
+
return ClinicalPathway_FieldEvaluator_GreaterThan();
|
|
36
|
+
case "greater_equals":
|
|
37
|
+
return ClinicalPathway_FieldEvaluator_GreaterOrEqual();
|
|
38
|
+
case "less":
|
|
39
|
+
return ClinicalPathway_FieldEvaluator_LessThan();
|
|
40
|
+
case "less_equals":
|
|
41
|
+
return ClinicalPathway_FieldEvaluator_LessOrEqual();
|
|
42
|
+
case "all":
|
|
43
|
+
return ClinicalPathway_FieldEvaluator_ContainsAll(answerValues);
|
|
44
|
+
case "none":
|
|
45
|
+
return ClinicalPathway_FieldEvaluator_NotInSet(answerValues);
|
|
46
|
+
default:
|
|
47
|
+
return toFail(printf("Unknown CoreMR operator: %s"))(matchValue);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Convert CoreMR trigger_on to FormSpec TriggerTiming
|
|
53
|
+
*/
|
|
54
|
+
export function convertTiming(triggerOn: string): ClinicalPathway_TriggerTiming_$union {
|
|
55
|
+
const matchValue: string = triggerOn.toLocaleLowerCase();
|
|
56
|
+
switch (matchValue) {
|
|
57
|
+
case "save":
|
|
58
|
+
return ClinicalPathway_TriggerTiming_OnFormSave();
|
|
59
|
+
case "lock":
|
|
60
|
+
return ClinicalPathway_TriggerTiming_OnFormSubmit();
|
|
61
|
+
case "open_first_time":
|
|
62
|
+
return ClinicalPathway_TriggerTiming_OnFormLoad();
|
|
63
|
+
default: {
|
|
64
|
+
toConsoleError(printf("Unknown trigger_on value: %s, defaulting to OnFormSave"))(matchValue);
|
|
65
|
+
return ClinicalPathway_TriggerTiming_OnFormSave();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Convert CoreMR priority (1=high, 2=medium, 3=low) to FormSpec TaskPriority
|
|
72
|
+
*/
|
|
73
|
+
export function convertPriority(priority: string): ClinicalPathway_TaskPriority_$union {
|
|
74
|
+
switch (priority) {
|
|
75
|
+
case "1":
|
|
76
|
+
return ClinicalPathway_TaskPriority_High();
|
|
77
|
+
case "2":
|
|
78
|
+
return ClinicalPathway_TaskPriority_Medium();
|
|
79
|
+
default:
|
|
80
|
+
return ClinicalPathway_TaskPriority_Low();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Parse CoreMR due date string to FormSpec DueDate
|
|
86
|
+
*/
|
|
87
|
+
export function parseDueDate(dateStr: string): ClinicalPathway_DueDate_$union {
|
|
88
|
+
let date: string;
|
|
89
|
+
const matchValue: string = dateStr.toLocaleLowerCase().trim();
|
|
90
|
+
switch (matchValue) {
|
|
91
|
+
case "today":
|
|
92
|
+
return ClinicalPathway_DueDate_Today();
|
|
93
|
+
case "tomorrow":
|
|
94
|
+
return ClinicalPathway_DueDate_Tomorrow();
|
|
95
|
+
default:
|
|
96
|
+
if ((date = matchValue, date.startsWith("+") && date.endsWith("days"))) {
|
|
97
|
+
let matchValue_1: [boolean, int32];
|
|
98
|
+
let outArg = 0;
|
|
99
|
+
matchValue_1 = ([tryParse(replace(replace(replace(matchValue, "+", ""), "days", ""), "day", "").trim(), 511, false, 32, new FSharpRef<int32>((): int32 => outArg, (v: int32): void => {
|
|
100
|
+
outArg = (v | 0);
|
|
101
|
+
})), outArg] as [boolean, int32]);
|
|
102
|
+
if (matchValue_1[0]) {
|
|
103
|
+
return ClinicalPathway_DueDate_DaysFromNow(matchValue_1[1]);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
return ClinicalPathway_DueDate_Today();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (matchValue.startsWith("+")) {
|
|
110
|
+
const parts: string[] = split(trim(matchValue, "+").trim(), [" "], undefined, 1);
|
|
111
|
+
if (parts.length > 0) {
|
|
112
|
+
let matchValue_2: [boolean, int32];
|
|
113
|
+
let outArg_1 = 0;
|
|
114
|
+
matchValue_2 = ([tryParse(item_2(0, parts), 511, false, 32, new FSharpRef<int32>((): int32 => outArg_1, (v_1: int32): void => {
|
|
115
|
+
outArg_1 = (v_1 | 0);
|
|
116
|
+
})), outArg_1] as [boolean, int32]);
|
|
117
|
+
if (matchValue_2[0]) {
|
|
118
|
+
return ClinicalPathway_DueDate_DaysFromNow(matchValue_2[1]);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
return ClinicalPathway_DueDate_Today();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
return ClinicalPathway_DueDate_Today();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
return ClinicalPathway_DueDate_Today();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Parse CoreMR recurrence interval (e.g., "+1 day", "+4 hours")
|
|
136
|
+
*/
|
|
137
|
+
export function parseRecurrenceInterval(intervalStr: string): number {
|
|
138
|
+
const parts: string[] = split(trimStart(intervalStr.toLocaleLowerCase().trim(), "+"), [" "], undefined, 1);
|
|
139
|
+
if (parts.length >= 2) {
|
|
140
|
+
const valueStr: string = item_2(0, parts);
|
|
141
|
+
const unit: string = item_2(1, parts);
|
|
142
|
+
let matchValue: [boolean, int32];
|
|
143
|
+
let outArg = 0;
|
|
144
|
+
matchValue = ([tryParse(valueStr, 511, false, 32, new FSharpRef<int32>((): int32 => outArg, (v: int32): void => {
|
|
145
|
+
outArg = (v | 0);
|
|
146
|
+
})), outArg] as [boolean, int32]);
|
|
147
|
+
if (matchValue[0]) {
|
|
148
|
+
const value: int32 = matchValue[1] | 0;
|
|
149
|
+
switch (unit) {
|
|
150
|
+
case "hour":
|
|
151
|
+
case "hours":
|
|
152
|
+
return fromHours(value);
|
|
153
|
+
case "day":
|
|
154
|
+
case "days":
|
|
155
|
+
return fromDays(value);
|
|
156
|
+
case "week":
|
|
157
|
+
case "weeks":
|
|
158
|
+
return fromDays(value * 7);
|
|
159
|
+
default:
|
|
160
|
+
return fromDays(1);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
return fromDays(1);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
return fromDays(1);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Parse recurrence pattern from CoreMR event params
|
|
174
|
+
*/
|
|
175
|
+
export function parseRecurrence(recurEvery: Option<string>, recurEnd: Option<string>): Option<ClinicalPathway_RecurrencePattern> {
|
|
176
|
+
let endStr: string;
|
|
177
|
+
if (recurEvery != null) {
|
|
178
|
+
return new ClinicalPathway_RecurrencePattern(parseRecurrenceInterval(value_7(recurEvery)), (recurEnd == null) ? ClinicalPathway_RecurrenceEnd_Never() : ((endStr = value_7(recurEnd), ClinicalPathway_RecurrenceEnd_OnDate(endStr.startsWith("+") ? add(now(), parseRecurrenceInterval(endStr)) : addDays(now(), 7)))));
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Convert CoreMR event to FormSpec ActionInfo
|
|
187
|
+
*/
|
|
188
|
+
export function convertEvent(event: CoreMRTriggerEvent): ClinicalPathway_ActionInfo_$union {
|
|
189
|
+
const matchValue: string = event.EventType.toLocaleLowerCase();
|
|
190
|
+
switch (matchValue) {
|
|
191
|
+
case "alert": {
|
|
192
|
+
const category: string = defaultArg(tryFind<string, string>("category_desc", event.EventParams), "Alert");
|
|
193
|
+
return ClinicalPathway_ActionInfo_Alert(new ClinicalPathway_AlertAction(category, `Alert: ${category}`, ClinicalPathway_AlertSeverity_High(), undefined));
|
|
194
|
+
}
|
|
195
|
+
case "task": {
|
|
196
|
+
const category_1: string = defaultArg(tryFind<string, string>("cat_desc", event.EventParams), "Task");
|
|
197
|
+
const description: string = defaultArg(tryFind<string, string>("description", event.EventParams), "");
|
|
198
|
+
const priorityStr: string = defaultArg(tryFind<string, string>("priority", event.EventParams), "2");
|
|
199
|
+
const dateStr: string = defaultArg(tryFind<string, string>("date", event.EventParams), "Today");
|
|
200
|
+
const recurEvery: Option<string> = tryFind<string, string>("recur_every", event.EventParams);
|
|
201
|
+
const recurEnd: Option<string> = tryFind<string, string>("recur_end", event.EventParams);
|
|
202
|
+
let assignee: string;
|
|
203
|
+
const parts: string[] = split(category_1, ["-"], 2);
|
|
204
|
+
assignee = ((parts.length > 0) ? item_2(0, parts).trim() : "Staff");
|
|
205
|
+
return ClinicalPathway_ActionInfo_Task(new ClinicalPathway_TaskAction(category_1, description, convertPriority(priorityStr), parseDueDate(dateStr), assignee, parseRecurrence(recurEvery, recurEnd)));
|
|
206
|
+
}
|
|
207
|
+
case "problem":
|
|
208
|
+
return ClinicalPathway_ActionInfo_Problem(new ClinicalPathway_ProblemAction("Problem", undefined, now(), ClinicalPathway_ProblemStatus_Active(), undefined));
|
|
209
|
+
case "medset":
|
|
210
|
+
return ClinicalPathway_ActionInfo_Medication(new ClinicalPathway_MedicationAction("Medication Set", "", "", "", "", false));
|
|
211
|
+
case "prescription":
|
|
212
|
+
return ClinicalPathway_ActionInfo_Prescription(new ClinicalPathway_PrescriptionAction("", "", "PO", "", "", 30, 0, true, undefined));
|
|
213
|
+
default:
|
|
214
|
+
return toFail(printf("Unknown CoreMR event type: %s"))(matchValue);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Convert CoreMR condition to FormSpec TransitionCondition
|
|
220
|
+
*/
|
|
221
|
+
export function convertCondition(condition: CoreMRTriggerCondition, itemIdToFieldKey: ((arg0: int32) => Shared_FieldKey), choiceIdToText: FSharpMap<int32, string>): ClinicalPathway_TransitionCondition_$union {
|
|
222
|
+
let matchValue: string;
|
|
223
|
+
const fieldKey: Shared_FieldKey = itemIdToFieldKey(condition.TriggerId);
|
|
224
|
+
const answerValues: FSharpList<string> = choose<int32, string>((choiceId: int32): Option<string> => tryFind<int32, string>(choiceId, choiceIdToText), condition.Answers);
|
|
225
|
+
return ClinicalPathway_TransitionCondition_FieldCondition(fieldKey, convertOperator(condition.Operator, answerValues), (matchValue = condition.Operator.toLocaleLowerCase(), (matchValue === "any") ? Shared_ConditionValue_Multiple(ofList<string>(answerValues, {
|
|
226
|
+
Compare: comparePrimitives,
|
|
227
|
+
})) : ((matchValue === "all") ? Shared_ConditionValue_Multiple(ofList<string>(answerValues, {
|
|
228
|
+
Compare: comparePrimitives,
|
|
229
|
+
})) : ((matchValue === "none") ? Shared_ConditionValue_Multiple(ofList<string>(answerValues, {
|
|
230
|
+
Compare: comparePrimitives,
|
|
231
|
+
})) : (!isEmpty(answerValues) ? (isEmpty(tail(answerValues)) ? Shared_ConditionValue_Single(head(answerValues)) : Shared_ConditionValue_Single(head<string>(answerValues))) : Shared_ConditionValue_Single(""))))));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Combine multiple conditions with AND logic
|
|
236
|
+
*/
|
|
237
|
+
export function combineConditions(conditions: FSharpList<ClinicalPathway_TransitionCondition_$union>): ClinicalPathway_TransitionCondition_$union {
|
|
238
|
+
if (!isEmpty(conditions)) {
|
|
239
|
+
if (isEmpty(tail(conditions))) {
|
|
240
|
+
return head(conditions);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
return ClinicalPathway_TransitionCondition_CompositeCondition(ClinicalPathway_LogicalOp_And(), conditions);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
return ClinicalPathway_TransitionCondition_Always();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Generate human-readable label for evaluation state based on trigger conditions
|
|
253
|
+
*/
|
|
254
|
+
export function generateEvaluationLabel(trigger: CoreMRTrigger, itemIdToFieldKey: ((arg0: int32) => Shared_FieldKey), choiceIdToText: FSharpMap<int32, string>, items: FSharpList<CoreMRItem>): string {
|
|
255
|
+
let value: string, matchValue: FSharpList<CoreMRTriggerCondition>, answerValues: FSharpList<string>, matchValue_1: string;
|
|
256
|
+
return `When ${(value = (`Field ${trigger.TargetItemId}`), defaultArg(map<CoreMRItem, string>((item_1: CoreMRItem): string => item_1.Label, tryFind_1<CoreMRItem>((item: CoreMRItem): boolean => (item.ItemId === trigger.TargetItemId), items)), value))} ${(matchValue = trigger.Conditions, !isEmpty(matchValue) ? (isEmpty(tail(matchValue)) ? ((answerValues = choose<int32, string>((choiceId: int32): Option<string> => tryFind<int32, string>(choiceId, choiceIdToText), head(matchValue).Answers), (matchValue_1 = head(matchValue).Operator.toLocaleLowerCase(), (matchValue_1 === "any") ? ((length(answerValues) === 1) ? (`= ${item_3(0, answerValues)}`) : (`is ${join(" or ", answerValues)}`)) : ((matchValue_1 === "equals") ? ((length(answerValues) > 0) ? (`= ${item_3(0, answerValues)}`) : (`${matchValue_1} ${join(", ", answerValues)}`)) : ((matchValue_1 === "all") ? (`is all of: ${join(", ", answerValues)}`) : ((matchValue_1 === "none") ? (`is none of: ${join(", ", answerValues)}`) : ((matchValue_1 === "greater") ? ((length(answerValues) > 0) ? (`> ${item_3(0, answerValues)}`) : (`${matchValue_1} ${join(", ", answerValues)}`)) : ((matchValue_1 === "greater_equals") ? ((length(answerValues) > 0) ? (`>= ${item_3(0, answerValues)}`) : (`${matchValue_1} ${join(", ", answerValues)}`)) : ((matchValue_1 === "less") ? ((length(answerValues) > 0) ? (`< ${item_3(0, answerValues)}`) : (`${matchValue_1} ${join(", ", answerValues)}`)) : ((matchValue_1 === "less_equals") ? ((length(answerValues) > 0) ? (`<= ${item_3(0, answerValues)}`) : (`${matchValue_1} ${join(", ", answerValues)}`)) : (`${matchValue_1} ${join(", ", answerValues)}`))))))))))) : "multiple conditions") : "always")}`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Generate human-readable label for action state based on trigger events
|
|
261
|
+
*/
|
|
262
|
+
export function generateActionLabel(trigger: CoreMRTrigger): string {
|
|
263
|
+
const matchValue: FSharpList<CoreMRTriggerEvent> = trigger.Events;
|
|
264
|
+
if (!isEmpty(matchValue)) {
|
|
265
|
+
if (isEmpty(tail(matchValue))) {
|
|
266
|
+
const matchValue_1: string = head(matchValue).EventType.toLocaleLowerCase();
|
|
267
|
+
switch (matchValue_1) {
|
|
268
|
+
case "alert":
|
|
269
|
+
return `Create Alert: ${defaultArg(tryFind<string, string>("category_desc", head(matchValue).EventParams), "Alert")}`;
|
|
270
|
+
case "task": {
|
|
271
|
+
const category_1: string = defaultArg(tryFind<string, string>("cat_desc", head(matchValue).EventParams), "Task");
|
|
272
|
+
const priority: string = defaultArg(tryFind<string, string>("priority", head(matchValue).EventParams), "2");
|
|
273
|
+
return `Create ${`${(priority === "1") ? "High Priority" : ((priority === "2") ? "Medium Priority" : ((priority === "3") ? "Low Priority" : "Priority"))} Task: ${category_1}`}`;
|
|
274
|
+
}
|
|
275
|
+
case "problem":
|
|
276
|
+
return "Add to Problem List";
|
|
277
|
+
case "prescription":
|
|
278
|
+
return "Create Prescription";
|
|
279
|
+
case "medset":
|
|
280
|
+
return "Add Medication Set";
|
|
281
|
+
default:
|
|
282
|
+
return `Execute ${head(matchValue).EventType}`;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
const joined: string = join(", ", List_distinct<string>(map_1<CoreMRTriggerEvent, string>((e: CoreMRTriggerEvent): string => e.EventType, matchValue), {
|
|
287
|
+
Equals: (x: string, y: string): boolean => (x === y),
|
|
288
|
+
GetHashCode: stringHash,
|
|
289
|
+
}));
|
|
290
|
+
return `Execute ${length(matchValue)} actions: ${joined}`;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
return "No actions";
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Convert single CoreMR trigger to complete ClinicalPathwaySpec
|
|
300
|
+
*/
|
|
301
|
+
export function convertTriggerToPathway(trigger: CoreMRTrigger, itemIdToFieldKey: ((arg0: int32) => Shared_FieldKey), choiceIdToText: FSharpMap<int32, string>): ClinicalPathway_ClinicalPathwaySpec {
|
|
302
|
+
const startKey: Shared_StateKey = new Shared_StateKey(generateStableDeterministicGuid(`trigger_${trigger.TriggerId}_state_start`));
|
|
303
|
+
const evalKey: Shared_StateKey = new Shared_StateKey(generateStableDeterministicGuid(`trigger_${trigger.TriggerId}_state_evaluate`));
|
|
304
|
+
const actionKey: Shared_StateKey = new Shared_StateKey(generateStableDeterministicGuid(`trigger_${trigger.TriggerId}_state_action`));
|
|
305
|
+
const endKey: Shared_StateKey = new Shared_StateKey(generateStableDeterministicGuid(`trigger_${trigger.TriggerId}_state_end`));
|
|
306
|
+
const transitionKey1: Shared_TransitionKey = new Shared_TransitionKey(generateStableDeterministicGuid(`trigger_${trigger.TriggerId}_transition_start_to_eval`));
|
|
307
|
+
const transitionKey2: Shared_TransitionKey = new Shared_TransitionKey(generateStableDeterministicGuid(`trigger_${trigger.TriggerId}_transition_eval_to_action`));
|
|
308
|
+
const transitionKey3: Shared_TransitionKey = new Shared_TransitionKey(generateStableDeterministicGuid(`trigger_${trigger.TriggerId}_transition_action_to_end`));
|
|
309
|
+
const startState: ClinicalPathway_StateDefinition = new ClinicalPathway_StateDefinition(startKey, "Start", 0, ClinicalPathway_StateType_Evaluation(new ClinicalPathway_EvaluationInfo("Start", undefined)), undefined);
|
|
310
|
+
const evalState: ClinicalPathway_StateDefinition = new ClinicalPathway_StateDefinition(evalKey, "Evaluate Condition", 1, ClinicalPathway_StateType_Evaluation(new ClinicalPathway_EvaluationInfo(`Check Trigger ${trigger.TriggerId}`, undefined)), undefined);
|
|
311
|
+
let actionState: ClinicalPathway_StateDefinition;
|
|
312
|
+
const actions: FSharpList<ClinicalPathway_ActionInfo_$union> = map_1<CoreMRTriggerEvent, ClinicalPathway_ActionInfo_$union>(convertEvent, trigger.Events);
|
|
313
|
+
actionState = (new ClinicalPathway_StateDefinition(actionKey, "Execute Actions", 2, !isEmpty(actions) ? (isEmpty(tail(actions)) ? ClinicalPathway_StateType_Action(head(actions)) : ClinicalPathway_StateType_CompoundAction(actions)) : (() => {
|
|
314
|
+
throw new Error(`Trigger ${trigger.TriggerId} has no events`);
|
|
315
|
+
})(), undefined));
|
|
316
|
+
const endState: ClinicalPathway_StateDefinition = new ClinicalPathway_StateDefinition(endKey, "End", 3, ClinicalPathway_StateType_Terminal(new ClinicalPathway_TerminalInfo("Complete", "Actions executed", undefined)), undefined);
|
|
317
|
+
const transitions: FSharpList<ClinicalPathway_TransitionDefinition> = ofArray([new ClinicalPathway_TransitionDefinition(transitionKey1, startKey, evalKey, ClinicalPathway_TransitionCondition_Always(), undefined), new ClinicalPathway_TransitionDefinition(transitionKey2, evalKey, actionKey, combineConditions(map_1<CoreMRTriggerCondition, ClinicalPathway_TransitionCondition_$union>((c: CoreMRTriggerCondition): ClinicalPathway_TransitionCondition_$union => convertCondition(c, itemIdToFieldKey, choiceIdToText), trigger.Conditions)), trigger.TriggerOrder), new ClinicalPathway_TransitionDefinition(transitionKey3, actionKey, endKey, ClinicalPathway_TransitionCondition_Always(), undefined)]);
|
|
318
|
+
return new ClinicalPathway_ClinicalPathwaySpec(`coremr_trigger_${trigger.TriggerId}`, `CoreMR Trigger ${trigger.TriggerId}`, "1.0.0", "CoreMR Migration", ClinicalPathway_PathwayExecutionMode_TriggerBased(new ClinicalPathway_TriggerBasedConfig(convertTiming(trigger.TriggerOn), true)), startKey, ofArray([startState, evalState, actionState, endState]), transitions, empty<ClinicalPathway_ConstraintDefinition>(), empty<ClinicalPathway_PathRequirement>(), now(), undefined, undefined, 1);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Convert all active triggers for a form to pathways
|
|
323
|
+
*/
|
|
324
|
+
export function convertAllTriggers(triggers: FSharpList<CoreMRTrigger>, itemIdToFieldKey: ((arg0: int32) => Shared_FieldKey), choiceIdToText: FSharpMap<int32, string>): FSharpList<ClinicalPathway_ClinicalPathwaySpec> {
|
|
325
|
+
return map_1<CoreMRTrigger, ClinicalPathway_ClinicalPathwaySpec>((t_2: CoreMRTrigger): ClinicalPathway_ClinicalPathwaySpec => convertTriggerToPathway(t_2, itemIdToFieldKey, choiceIdToText), filter<CoreMRTrigger>((t_1: CoreMRTrigger): boolean => !isEmpty(t_1.Events), filter<CoreMRTrigger>((t: CoreMRTrigger): boolean => t.Active, triggers)));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Convert all triggers into a SINGLE pathway with one start node and branching logic
|
|
330
|
+
* This creates the proper structure: Start → Multiple Evaluation branches → Actions
|
|
331
|
+
*/
|
|
332
|
+
export function convertTriggersToSinglePathway(triggers: FSharpList<CoreMRTrigger>, itemIdToFieldKey: ((arg0: int32) => Shared_FieldKey), choiceIdToText: FSharpMap<int32, string>, metadata: CoreMRFormMetadata, items: FSharpList<CoreMRItem>): ClinicalPathway_ClinicalPathwaySpec {
|
|
333
|
+
const activeTriggers: FSharpList<CoreMRTrigger> = filter<CoreMRTrigger>((t_1: CoreMRTrigger): boolean => !isEmpty(t_1.Events), filter<CoreMRTrigger>((t: CoreMRTrigger): boolean => t.Active, triggers));
|
|
334
|
+
const pathwayId = `form_${metadata.FormId}_pathway`;
|
|
335
|
+
const startKey: Shared_StateKey = new Shared_StateKey(generateStableDeterministicGuid(`${pathwayId}_start`));
|
|
336
|
+
const startState: ClinicalPathway_StateDefinition = new ClinicalPathway_StateDefinition(startKey, "Start", 0, ClinicalPathway_StateType_Evaluation(new ClinicalPathway_EvaluationInfo("Start", undefined)), undefined);
|
|
337
|
+
const triggerStates: FSharpList<[CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition]> = mapIndexed<CoreMRTrigger, [CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition]>((idx: int32, trigger: CoreMRTrigger): [CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition] => {
|
|
338
|
+
const evalKey: Shared_StateKey = new Shared_StateKey(generateStableDeterministicGuid(`${pathwayId}_eval_${trigger.TriggerId}`));
|
|
339
|
+
const actionKey: Shared_StateKey = new Shared_StateKey(generateStableDeterministicGuid(`${pathwayId}_action_${trigger.TriggerId}`));
|
|
340
|
+
const endKey: Shared_StateKey = new Shared_StateKey(generateStableDeterministicGuid(`${pathwayId}_end_${trigger.TriggerId}`));
|
|
341
|
+
const evalLabel: string = generateEvaluationLabel(trigger, itemIdToFieldKey, choiceIdToText, items);
|
|
342
|
+
const actionLabel: string = generateActionLabel(trigger);
|
|
343
|
+
const evalState: ClinicalPathway_StateDefinition = new ClinicalPathway_StateDefinition(evalKey, evalLabel, (idx * 3) + 1, ClinicalPathway_StateType_Evaluation(new ClinicalPathway_EvaluationInfo(evalLabel, undefined)), undefined);
|
|
344
|
+
const actions: FSharpList<ClinicalPathway_ActionInfo_$union> = map_1<CoreMRTriggerEvent, ClinicalPathway_ActionInfo_$union>(convertEvent, trigger.Events);
|
|
345
|
+
return [trigger, evalKey, actionKey, endKey, evalState, new ClinicalPathway_StateDefinition(actionKey, actionLabel, (idx * 3) + 2, !isEmpty(actions) ? (isEmpty(tail(actions)) ? ClinicalPathway_StateType_Action(head(actions)) : ClinicalPathway_StateType_CompoundAction(actions)) : ClinicalPathway_StateType_CompoundAction(empty<ClinicalPathway_ActionInfo_$union>()), undefined), new ClinicalPathway_StateDefinition(endKey, "End", (idx * 3) + 3, ClinicalPathway_StateType_Terminal(new ClinicalPathway_TerminalInfo("Complete", "Actions executed", undefined)), undefined)] as [CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition];
|
|
346
|
+
}, activeTriggers);
|
|
347
|
+
const allStates: FSharpList<ClinicalPathway_StateDefinition> = cons(startState, collect<[CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition], ClinicalPathway_StateDefinition>((tupledArg: [CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition]): FSharpList<ClinicalPathway_StateDefinition> => ofArray([tupledArg[4], tupledArg[5], tupledArg[6]]), triggerStates));
|
|
348
|
+
const allTransitions: FSharpList<ClinicalPathway_TransitionDefinition> = append(mapIndexed<[CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition], ClinicalPathway_TransitionDefinition>((idx_1: int32, tupledArg_1: [CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition]): ClinicalPathway_TransitionDefinition => (new ClinicalPathway_TransitionDefinition(new Shared_TransitionKey(generateStableDeterministicGuid(`${pathwayId}_start_to_eval_${tupledArg_1[0].TriggerId}`)), startKey, tupledArg_1[1], ClinicalPathway_TransitionCondition_Always(), idx_1)), triggerStates), append(map_1<[CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition], ClinicalPathway_TransitionDefinition>((tupledArg_2: [CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition]): ClinicalPathway_TransitionDefinition => {
|
|
349
|
+
const trigger_2: CoreMRTrigger = tupledArg_2[0];
|
|
350
|
+
const transitionCondition: ClinicalPathway_TransitionCondition_$union = combineConditions(map_1<CoreMRTriggerCondition, ClinicalPathway_TransitionCondition_$union>((c: CoreMRTriggerCondition): ClinicalPathway_TransitionCondition_$union => convertCondition(c, itemIdToFieldKey, choiceIdToText), trigger_2.Conditions));
|
|
351
|
+
return new ClinicalPathway_TransitionDefinition(new Shared_TransitionKey(generateStableDeterministicGuid(`${pathwayId}_eval_to_action_${trigger_2.TriggerId}`)), tupledArg_2[1], tupledArg_2[2], transitionCondition, trigger_2.TriggerOrder);
|
|
352
|
+
}, triggerStates), map_1<[CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition], ClinicalPathway_TransitionDefinition>((tupledArg_3: [CoreMRTrigger, Shared_StateKey, Shared_StateKey, Shared_StateKey, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition, ClinicalPathway_StateDefinition]): ClinicalPathway_TransitionDefinition => (new ClinicalPathway_TransitionDefinition(new Shared_TransitionKey(generateStableDeterministicGuid(`${pathwayId}_action_to_end_${tupledArg_3[0].TriggerId}`)), tupledArg_3[2], tupledArg_3[3], ClinicalPathway_TransitionCondition_Always(), undefined)), triggerStates)));
|
|
353
|
+
let executionMode: ClinicalPathway_PathwayExecutionMode_$union;
|
|
354
|
+
const primaryTiming: ClinicalPathway_TriggerTiming_$union = defaultArg(map<CoreMRTrigger, ClinicalPathway_TriggerTiming_$union>((t_2: CoreMRTrigger): ClinicalPathway_TriggerTiming_$union => convertTiming(t_2.TriggerOn), tryHead<CoreMRTrigger>(activeTriggers)), ClinicalPathway_TriggerTiming_OnFormSave());
|
|
355
|
+
executionMode = ((length(activeTriggers) > 1) ? ClinicalPathway_PathwayExecutionMode_MultiPathway(new ClinicalPathway_MultiPathwayConfig(ClinicalPathway_CombinationStrategy_AllMatching(), ClinicalPathway_ConflictResolution_CombineActions(), undefined)) : ClinicalPathway_PathwayExecutionMode_TriggerBased(new ClinicalPathway_TriggerBasedConfig(primaryTiming, true)));
|
|
356
|
+
return new ClinicalPathway_ClinicalPathwaySpec(pathwayId, `${metadata.FormName} - Clinical Pathway`, int32ToString(metadata.VersionNumber), "CoreMR Migration - Unified Pathway", executionMode, startKey, allStates, allTransitions, empty<ClinicalPathway_ConstraintDefinition>(), empty<ClinicalPathway_PathRequirement>(), now(), undefined, undefined, 1);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Create an orchestrator pathway that coordinates multiple sub-pathways
|
|
361
|
+
*/
|
|
362
|
+
export function createOrchestratorPathway(subPathways: FSharpList<ClinicalPathway_ClinicalPathwaySpec>, metadata: CoreMRFormMetadata): ClinicalPathway_ClinicalPathwaySpec {
|
|
363
|
+
const orchestratorId = `orchestrator_form_${metadata.FormId}`;
|
|
364
|
+
const startKey: Shared_StateKey = new Shared_StateKey(generateStableDeterministicGuid(`${orchestratorId}_start`));
|
|
365
|
+
const endKey: Shared_StateKey = new Shared_StateKey(generateStableDeterministicGuid(`${orchestratorId}_end`));
|
|
366
|
+
const allStates: FSharpList<ClinicalPathway_StateDefinition> = append(singleton(new ClinicalPathway_StateDefinition(startKey, "Orchestrator Start", -1, ClinicalPathway_StateType_Evaluation(new ClinicalPathway_EvaluationInfo("Begin Evaluation", undefined)), undefined)), append(List_distinctBy<ClinicalPathway_StateDefinition, Shared_StateKey>((s: ClinicalPathway_StateDefinition): Shared_StateKey => s.StateKey, collect<ClinicalPathway_ClinicalPathwaySpec, ClinicalPathway_StateDefinition>((p: ClinicalPathway_ClinicalPathwaySpec): FSharpList<ClinicalPathway_StateDefinition> => p.States, subPathways), {
|
|
367
|
+
Equals: equals,
|
|
368
|
+
GetHashCode: safeHash,
|
|
369
|
+
}), singleton(new ClinicalPathway_StateDefinition(endKey, "Orchestrator End", 999999, ClinicalPathway_StateType_Terminal(new ClinicalPathway_TerminalInfo("Complete", "All pathways evaluated", undefined)), undefined))));
|
|
370
|
+
let allTransitions: FSharpList<ClinicalPathway_TransitionDefinition>;
|
|
371
|
+
const subTransitions: FSharpList<ClinicalPathway_TransitionDefinition> = List_distinctBy<ClinicalPathway_TransitionDefinition, Shared_TransitionKey>((t: ClinicalPathway_TransitionDefinition): Shared_TransitionKey => t.TransitionKey, collect<ClinicalPathway_ClinicalPathwaySpec, ClinicalPathway_TransitionDefinition>((p_1: ClinicalPathway_ClinicalPathwaySpec): FSharpList<ClinicalPathway_TransitionDefinition> => p_1.Transitions, subPathways), {
|
|
372
|
+
Equals: equals,
|
|
373
|
+
GetHashCode: safeHash,
|
|
374
|
+
});
|
|
375
|
+
allTransitions = append(mapIndexed<Shared_StateKey, ClinicalPathway_TransitionDefinition>((i: int32, initialState: Shared_StateKey): ClinicalPathway_TransitionDefinition => (new ClinicalPathway_TransitionDefinition(new Shared_TransitionKey(generateStableDeterministicGuid(`${orchestratorId}_start_to_${i}`)), startKey, initialState, ClinicalPathway_TransitionCondition_Always(), i)), choose<ClinicalPathway_ClinicalPathwaySpec, Shared_StateKey>((p_2: ClinicalPathway_ClinicalPathwaySpec): Option<Shared_StateKey> => p_2.InitialState, subPathways)), append(subTransitions, mapIndexed<ClinicalPathway_StateDefinition, ClinicalPathway_TransitionDefinition>((i_1: int32, terminal: ClinicalPathway_StateDefinition): ClinicalPathway_TransitionDefinition => (new ClinicalPathway_TransitionDefinition(new Shared_TransitionKey(generateStableDeterministicGuid(`${orchestratorId}_terminal_${i_1}_to_end`)), terminal.StateKey, endKey, ClinicalPathway_TransitionCondition_Always(), undefined)), filter<ClinicalPathway_StateDefinition>((s_2: ClinicalPathway_StateDefinition): boolean => !equals(s_2.StateKey, endKey), filter<ClinicalPathway_StateDefinition>((s_1: ClinicalPathway_StateDefinition): boolean => {
|
|
376
|
+
if (s_1.StateType.tag === /* Terminal */ 5) {
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
}, allStates)))));
|
|
383
|
+
return new ClinicalPathway_ClinicalPathwaySpec(orchestratorId, `${metadata.FormName} - Orchestrated Pathways`, int32ToString(metadata.VersionNumber), "CoreMR Migration - Multi-Trigger Orchestrator", ClinicalPathway_PathwayExecutionMode_MultiPathway(new ClinicalPathway_MultiPathwayConfig(ClinicalPathway_CombinationStrategy_AllMatching(), ClinicalPathway_ConflictResolution_CombineActions(), undefined)), startKey, allStates, allTransitions, empty<ClinicalPathway_ConstraintDefinition>(), empty<ClinicalPathway_PathRequirement>(), now(), undefined, undefined, 0.9);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
//# sourceMappingURL=CorEMRTriggerConverter.ts.map
|