Skip to content

Commit

Permalink
Merge branch 'develop' into MAT-6401_noContextError
Browse files Browse the repository at this point in the history
  • Loading branch information
sb-cecilialiu authored Dec 4, 2024
2 parents f5d607b + e8c59ec commit c23f892
Show file tree
Hide file tree
Showing 10 changed files with 624 additions and 16 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"webpack-merge": "^5.8.0"
},
"dependencies": {
"@madie/cql-antlr-parser": "^1.0.7",
"@madie/cql-antlr-parser": "^1.0.8",
"@madie/madie-design-system": "^1.2.37",
"@material-ui/core": "^4.12.4",
"@mui/icons-material": "^5.5.1",
Expand Down
3 changes: 3 additions & 0 deletions src/CqlBuilderPanel/CqlBuilderPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ export default function CqlBuilderPanel({
canEdit={canEdit}
handleApplyFunction={handleApplyFunction}
loading={loading}
cql={measureStoreCql}
isCQLUnchanged={isCQLUnchanged}
cqlBuilderLookupsTypes={cqlBuilderLookupsTypes}
/>
)}
</div>
Expand Down
26 changes: 24 additions & 2 deletions src/CqlBuilderPanel/__mocks__/MockCqlBuilderLookupsTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,28 @@ const edEncounter = {
logic: "define",
comment: "",
} as Lookup;
const functions = [
{
name: "MyFunctions",
libraryName: null,
libraryAlias: null,
logic:
"define function MyFunctions(encounter1 Encounter, encounter2 Encounter, encounter3 Encounter, encounter4 Encounter):\n 3",
startLine: 0,
comment: null,
},
];
const fluentFunctions = [
{
name: "isFinishedEncounter",
libraryName: null,
libraryAlias: null,
logic:
"define fluent function \"isFinishedEncounter\"(Enc Encounter):\n(Enc E where E.status = 'finished') is not null",
startLine: 0,
comment: null,
},
];
export const cqlBuilderLookup = {
parameters: [tjcMeasurementPeriod],
definitions: [
Expand All @@ -88,6 +110,6 @@ export const cqlBuilderLookup = {
numerator,
edEncounter,
],
functions: [],
fluentFunctions: [],
functions: functions,
fluentFunctions: fluentFunctions,
} as CqlBuilderLookup;
19 changes: 19 additions & 0 deletions src/CqlBuilderPanel/__mocks__/MockMeasureStoreCql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,23 @@ define "Denominator Exclusions":
or AIFrailLTCF."Is Age 66 to 80 with Advanced Illness and Frailty or Is Age 81 or Older with Frailty"
or AIFrailLTCF."Is Age 66 or Older Living Long Term in a Nursing Home"
or PalliativeCare."Has Palliative Care in the Measurement Period"
/*
fluent
function
comments
*/
define fluent function "isFinishedEncounter"(Enc Encounter):
(Enc E where E.status = 'finished') is not null
/*
this is
multiline
comment
for function
...
*/
// comment 2
define function MyFunctions(encounter1 Encounter, encounter2 Encounter, encounter3 Encounter, encounter4 Encounter):
3
`;
25 changes: 23 additions & 2 deletions src/CqlBuilderPanel/functionsSection/FunctionsSection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@ import * as React from "react";
import { render, screen, waitFor, act } from "@testing-library/react";
import FunctionsSection from "./FunctionsSection";
import userEvent from "@testing-library/user-event";
import { mockMeasureStoreCql } from "../__mocks__/MockMeasureStoreCql";
import { cqlBuilderLookup } from "../__mocks__/MockCqlBuilderLookupsTypes";

const props = {
canEdit: true,
loading: false,
handleApplyFunction: jest.fn(),
cql: mockMeasureStoreCql,
isCQLUnchanged: false,
cqlBuilderLookupsTypes: cqlBuilderLookup,
};

describe("FunctionsSection", () => {
it("Should display function section", async () => {
render(<FunctionsSection {...props} />);
const funct = await screen.findByTestId("function-tab");
const savedfunctions = await screen.findByText("Saved Functions (0)");
const savedfunctions = await screen.findByText("Saved Functions (2)");
expect(funct).toBeInTheDocument();
expect(savedfunctions).toBeInTheDocument();
await waitFor(() => {
Expand All @@ -27,7 +32,7 @@ describe("FunctionsSection", () => {
it("Should display saved function section", async () => {
render(<FunctionsSection {...props} />);
const funct = await screen.findByTestId("function-tab");
const savedfunctions = await screen.findByText("Saved Functions (0)");
const savedfunctions = await screen.findByText("Saved Functions (2)");
expect(funct).toBeInTheDocument();
expect(savedfunctions).toBeInTheDocument();
await waitFor(() => {
Expand All @@ -41,4 +46,20 @@ describe("FunctionsSection", () => {
expect(savedfunctions).toHaveAttribute("aria-selected", "true");
});
});

it("Should display saved function section", async () => {
const propsNoSql = {
canEdit: true,
loading: false,
handleApplyFunction: jest.fn(),
cql: undefined,
isCQLUnchanged: false,
cqlBuilderLookupsTypes: undefined,
};
render(<FunctionsSection {...propsNoSql} />);
const funct = await screen.findByTestId("function-tab");
const savedfunctions = await screen.findByText("Saved Functions (0)");
expect(funct).toBeInTheDocument();
expect(savedfunctions).toBeInTheDocument();
});
});
70 changes: 66 additions & 4 deletions src/CqlBuilderPanel/functionsSection/FunctionsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,80 @@ import "./Functions.scss";
import FunctionSectionNavTabs from "./FunctionSectionNavTabs";
import Functions from "./functions/Functions";
import FunctionBuilder from "./functionBuilder/FunctionBuilder";
import {
CqlBuilderLookup,
FunctionLookup,
} from "../..//model/CqlBuilderLookup";
import * as _ from "lodash";
import { CqlAntlr } from "@madie/cql-antlr-parser/dist/src";

interface FunctionProps {
export interface FunctionProps {
canEdit: boolean;
handleApplyFunction: Function;
handleApplyFunction?: Function;
loading: boolean;
cqlBuilderLookupsTypes?: CqlBuilderLookup;
cql: string;
isCQLUnchanged: boolean;
functions?: FunctionLookup[];
}
const getArgumentNames = (logic: string) => {
const args = logic.substring(logic.indexOf("(") + 1, logic.indexOf(")"));
return args.split(",");
};

export default function FunctionsSection({
canEdit,
handleApplyFunction,
loading,
cql,
isCQLUnchanged,
cqlBuilderLookupsTypes,
}: FunctionProps) {
const [activeTab, setActiveTab] = useState<string>("function");

const expressionDefinitions = cql
? new CqlAntlr(cql).parse().expressionDefinitions
: [];

let functionLookups: FunctionLookup[] =
cqlBuilderLookupsTypes?.functions
?.filter((func) => !func.libraryName)
.map((func) => {
// get the comments for CQL definition from antlr parser expressions
const expression = expressionDefinitions.find(
(expression) => func.logic == expression.text?.replace(/["']/g, "")
);
return {
...func,
comment: expression?.comment,
isFluent: "-",
argumentNames: getArgumentNames(func.logic),
} as FunctionLookup;
}) || [];

functionLookups = functionLookups.concat(
cqlBuilderLookupsTypes?.fluentFunctions
?.filter((func) => !func.libraryName)
.map((func) => {
const expression = expressionDefinitions.find(
(expression) => func.logic == expression.text
);
return {
...func,
comment: expression?.comment,
isFluent: "Yes",
argumentNames: getArgumentNames(func.logic),
};
}) || []
);
functionLookups = _.sortBy(functionLookups, (o) => o.name?.toLowerCase());

return (
<>
<FunctionSectionNavTabs
activeTab={activeTab}
setActiveTab={setActiveTab}
functionCount={0}
functionCount={functionLookups ? functionLookups.length : 0}
loading={loading}
/>
<div>
Expand All @@ -32,7 +86,15 @@ export default function FunctionsSection({
handleApplyFunction={handleApplyFunction}
/>
)}
{activeTab === "saved-functions" && <Functions />}
{activeTab === "saved-functions" && (
<Functions
canEdit={canEdit}
loading={loading}
functions={functionLookups}
isCQLUnchanged={isCQLUnchanged}
cql={cql}
/>
)}
</div>
</>
);
Expand Down
Loading

0 comments on commit c23f892

Please sign in to comment.