Skip to content

Commit

Permalink
MAT-7796: Edit dialog layout
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmcphillips committed Dec 17, 2024
1 parent d097e0e commit 6797643
Show file tree
Hide file tree
Showing 9 changed files with 316 additions and 28 deletions.
4 changes: 3 additions & 1 deletion src/CqlBuilderPanel/CqlBuilderPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ValueSetsSection from "./ValueSets/ValueSets";
import CodesSection from "./codesSection/CodesSection";
import DefinitionsSection from "./definitionsSection/DefinitionsSection";
import FunctionsSection from "./functionsSection/FunctionsSection";
// import FunctionsSection from ""
import { useFeatureFlags } from "@madie/madie-util";
import IncludesTabSection from "./Includes/Includes";
import Parameters from "./Parameters/Parameters";
Expand Down Expand Up @@ -51,7 +52,7 @@ export default function CqlBuilderPanel({
return "includes";
})();

const [activeTab, setActiveTab] = useState<string>(getStartingPage);
const [activeTab, setActiveTab] = useState<string>("functions");
const [cqlBuilderLookupsTypes, setCqlBuilderLookupsTypes] =
useState<CqlBuilderLookup>();
const [errors, setErrors] = useState<string>(null);
Expand Down Expand Up @@ -247,6 +248,7 @@ export default function CqlBuilderPanel({
loading={loading}
cql={measureStoreCql}
isCQLUnchanged={isCQLUnchanged}
resetCql={resetCql}
/>
)}
</div>
Expand Down
28 changes: 28 additions & 0 deletions src/CqlBuilderPanel/functionsSection/EditFunctionDialog.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as React from "react";
import { parseArgumentsFromLogicString } from "./EditFunctionDialog";

describe("parseArgumentsFromLogicString", () => {
test("Can parse out empty arguments", () => {
const logicString = `define function "Empty Arguments" (): true`;
const result = parseArgumentsFromLogicString(logicString);
expect(result).toEqual([]);
});
test("Can parse out multiple arguments", () => {
const logicString2 = `define function "Function name here" (arg1 "Integer", arg2 "Integer", arg3 "Date"):\n true`;
const result = parseArgumentsFromLogicString(logicString2);

expect(result).toEqual([
{ argumentName: "arg1", dataType: "Integer" },
{ argumentName: "arg2", dataType: "Integer" },
{ argumentName: "arg3", dataType: "Date" },
]);
});
test("Can parse out arguments with commas embedded in dataType", () => {
const logicString3 = `define fluent function "Numerator Observation"(Encounter "Encounter, Performed" ):
duration in hours of Encounter.relevantPeriod`;
const result = parseArgumentsFromLogicString(logicString3);
expect(result).toEqual([
{ argumentName: "Encounter", dataType: "Encounter, Performed" },
]);
});
});
89 changes: 89 additions & 0 deletions src/CqlBuilderPanel/functionsSection/EditFunctionDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React from "react";
import { MadieDialog } from "@madie/madie-design-system/dist/react";
import FunctionBuilder from "./functionBuilder/FunctionBuilder";

interface PropTypes {
open: boolean;
onClose: () => void;
cqlBuilderLookupsTypes?: any;
funct?: any;
setEditFunctionDialogOpen: Function;
handleApplyFunction: Function;
handleFunctionEdit: Function;
}

export const parseArgumentsFromLogicString = (logicString) => {
// `s` flag for multiline content
const argumentListRegex = /\(([^)]*)\)/s;
const match = logicString.match(argumentListRegex);

// Nobody in parenthesis
if (!match) {
return [];
}

const argumentsString = match[1].trim();
// no args
if (!argumentsString) {
return [];
}

// Regex to match argument and data type pairs
const argumentRegex = /([\w]+)\s+"([^"]+)"/g;
const results = [];

let argumentMatch;
while ((argumentMatch = argumentRegex.exec(argumentsString)) !== null) {
const [, argumentName, dataType] = argumentMatch;
results.push({ argumentName, dataType });
}
return results;
};

const EditFunctionDialog = ({
funct,
handleFunctionEdit,
onClose,
open,
setEditFunctionDialogOpen,
cqlBuilderLookupsTypes,
handleApplyFunction,
}: PropTypes) => {
// a property is passed called argument names that does not seem to work for anything with commas.
// the following is regex to grab arguments and dataTypes using a matcher and add them to the function to edit.

const updatedFunction = {
...funct,
fluentFunction: funct?.isFluent === true ? true : false,
functionsArguments: parseArgumentsFromLogicString(
funct?.logic ? funct?.logic : ""
),
expressionEditorValue: funct?.logic,
};

return (
<MadieDialog
title="Edit"
dialogProps={{
open,
onClose: onClose,
fullWidth: true,
maxWidth: "md",
"data-testid": "edit-parameter-dialog",
}}
>
<FunctionBuilder
cqlBuilderLookupsTypes={cqlBuilderLookupsTypes}
canEdit={true}
handleApplyFunction={handleApplyFunction}
funct={updatedFunction}
operation="edit"
handleFunctionEdit={handleFunctionEdit}
onClose={onClose}
setEditFunctionDialogOpen={setEditFunctionDialogOpen}
/>
</MadieDialog>
);
};

export default EditFunctionDialog;
34 changes: 34 additions & 0 deletions src/CqlBuilderPanel/functionsSection/FunctionsSection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import userEvent from "@testing-library/user-event";
import { mockMeasureStoreCql } from "../__mocks__/MockMeasureStoreCql";
import { cqlBuilderLookup } from "../__mocks__/MockCqlBuilderLookupsTypes";

const resetCql = jest.fn();

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

describe("FunctionsSection", () => {
Expand Down Expand Up @@ -62,4 +65,35 @@ describe("FunctionsSection", () => {
expect(funct).toBeInTheDocument();
expect(savedfunctions).toBeInTheDocument();
});

it("Should open a confirmation dialog on click", async () => {
render(<FunctionsSection {...props} isCQLUnchanged={false} />);
const funct = await screen.findByTestId("function-tab");
const savedfunctions = await screen.findByText("Saved Functions (2)");
expect(funct).toBeInTheDocument();
expect(savedfunctions).toBeInTheDocument();
await waitFor(() => {
expect(funct).toHaveAttribute("aria-selected", "true");
});
await waitFor(() => {
expect(savedfunctions).toHaveAttribute("aria-selected", "false");
});
userEvent.click(savedfunctions);
await waitFor(() => {
expect(savedfunctions).toHaveAttribute("aria-selected", "true");
});
const editButon0 = screen.getByTestId("edit-button-0");
userEvent.click(editButon0);
expect(screen.getByTestId("discard-dialog")).toBeInTheDocument();
expect(screen.getByText("Discard Changes?")).toBeInTheDocument();
const cancelBtn = screen.getByTestId("discard-dialog-cancel-button");
const discardBtn = screen.getByTestId("discard-dialog-continue-button");
expect(cancelBtn).toBeInTheDocument();
expect(discardBtn).toBeInTheDocument();

userEvent.click(discardBtn);
await waitFor(() => {
expect(screen.getByText("Edit")).toBeInTheDocument();
});
});
});
15 changes: 9 additions & 6 deletions src/CqlBuilderPanel/functionsSection/FunctionsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ import "./Functions.scss";
import FunctionSectionNavTabs from "./FunctionSectionNavTabs";
import Functions from "./functions/Functions";
import FunctionBuilder from "./functionBuilder/FunctionBuilder";
import {
CqlBuilderLookup,
FunctionLookup,
} from "../..//model/CqlBuilderLookup";
import { CqlBuilderLookup, FunctionLookup } from "../../model/CqlBuilderLookup";
import * as _ from "lodash";
import { CqlAntlr } from "@madie/cql-antlr-parser/dist/src";

Expand All @@ -18,7 +15,10 @@ export interface FunctionProps {
cql: string;
isCQLUnchanged: boolean;
functions?: FunctionLookup[];
resetCql?: Function;
cqlBuilderLookupTypes?: any;
}

const getArgumentNames = (logic: string) => {
const args = logic.substring(logic.indexOf("(") + 1, logic.indexOf(")"));
return args.split(",");
Expand All @@ -27,10 +27,11 @@ const getArgumentNames = (logic: string) => {
export default function FunctionsSection({
canEdit,
handleApplyFunction,
loading,
cql,
isCQLUnchanged,
cqlBuilderLookupsTypes,
resetCql,
loading,
}: FunctionProps) {
const [activeTab, setActiveTab] = useState<string>("function");

Expand Down Expand Up @@ -70,7 +71,6 @@ export default function FunctionsSection({
}) || []
);
functionLookups = _.sortBy(functionLookups, (o) => o.name?.toLowerCase());

return (
<>
<FunctionSectionNavTabs
Expand All @@ -89,11 +89,14 @@ export default function FunctionsSection({
)}
{activeTab === "saved-functions" && (
<Functions
cqlBuilderLookupsTypes={cqlBuilderLookupsTypes}
canEdit={canEdit}
loading={loading}
functions={functionLookups}
isCQLUnchanged={isCQLUnchanged}
cql={cql}
resetCql={resetCql}
handleApplyFunction={handleApplyFunction}
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,20 @@ describe("CQL Function Builder Tests", () => {

const functionArgumentTable = screen.getByTestId("function-argument-tbl");
expect(functionArgumentTable).toBeInTheDocument();
await waitFor(() => {
expect(
screen.getByTestId("function-builder-success")
).toBeInTheDocument();
});
const tableRow = functionArgumentTable.querySelector("tbody").children[0];
expect(tableRow.children[1].textContent).toEqual("Test");
const closeButton = screen.getByTestId(
"function-builder-toast-close-button"
);
userEvent.click(closeButton);
await waitFor(() => {
expect(closeButton).not.toBeInTheDocument();
});
});

it("Should delete argument from the table", async () => {
Expand Down
Loading

0 comments on commit 6797643

Please sign in to comment.