diff --git a/package-lock.json b/package-lock.json index 6bfaa16..6d5eaf3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "@babel/preset-react": "^7.14.5", "@babel/preset-typescript": "^7.14.5", "@babel/runtime": "^7.14.6", - "@madie/madie-models": "^1.4.14", + "@madie/madie-models": "^1.4.15", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.0.0", "@testing-library/user-event": "^13.5.0", diff --git a/package.json b/package.json index a03baa0..10805a7 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@babel/preset-react": "^7.14.5", "@babel/preset-typescript": "^7.14.5", "@babel/runtime": "^7.14.6", - "@madie/madie-models": "^1.4.14", + "@madie/madie-models": "^1.4.15", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.0.0", "@testing-library/user-event": "^13.5.0", diff --git a/src/api/useCqlLibraryServiceApi.tsx b/src/api/useCqlLibraryServiceApi.tsx index 24ad830..650e111 100644 --- a/src/api/useCqlLibraryServiceApi.tsx +++ b/src/api/useCqlLibraryServiceApi.tsx @@ -82,11 +82,12 @@ export class CqlLibraryServiceApi { async createDraft( cqlLibraryId: string, - cqlLibraryName: string + cqlLibraryName: string, + model: string ): Promise { return await axios.post( `${this.baseUrl}/cql-libraries/draft/${cqlLibraryId}`, - { cqlLibraryName: cqlLibraryName }, + { cqlLibraryName: cqlLibraryName, model: model }, { headers: { Authorization: `Bearer ${this.getAccessToken()}`, diff --git a/src/components/cqlLibraryList/CqlLibraryList.test.tsx b/src/components/cqlLibraryList/CqlLibraryList.test.tsx index cc20d38..66514b6 100644 --- a/src/components/cqlLibraryList/CqlLibraryList.test.tsx +++ b/src/components/cqlLibraryList/CqlLibraryList.test.tsx @@ -19,6 +19,9 @@ jest.mock("@madie/madie-util", () => ({ checkUserCanDelete: jest.fn(() => { return true; }), + useFeatureFlags: jest.fn().mockReturnValue({ + qiCore6: true, + }), })); const mockPush = jest.fn(); @@ -43,6 +46,7 @@ const cqlLibrary: CqlLibrary[] = [ version: "0.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, librarySet: { id: "1", librarySetId: "librarySetId1", @@ -62,6 +66,7 @@ const cqlLibrary: CqlLibrary[] = [ version: "0.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, librarySet: { id: "2", librarySetId: "librarySetId2", @@ -210,6 +215,7 @@ describe("CqlLibrary List component", () => { version: "0.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, }, ]; @@ -691,6 +697,7 @@ describe("CqlLibrary List component", () => { version: "0.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, }, ]; render( @@ -726,6 +733,7 @@ describe("CqlLibrary List component", () => { version: "0.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, }, { id: "650359394b0427f896ced541", @@ -740,6 +748,7 @@ describe("CqlLibrary List component", () => { version: "1.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, }, ]; render( @@ -784,6 +793,7 @@ describe("CqlLibrary List component", () => { version: "0.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, }, ]; render( @@ -844,6 +854,7 @@ describe("CqlLibrary List component", () => { version: "0.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, }, ]; render( @@ -903,6 +914,7 @@ describe("CqlLibrary List component", () => { version: "0.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, }, { id: "650359394b0427f896ced541", @@ -917,6 +929,7 @@ describe("CqlLibrary List component", () => { version: "1.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, }, ]; render( @@ -961,6 +974,7 @@ describe("CqlLibrary List component", () => { version: "0.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, }, ]; render( @@ -998,6 +1012,7 @@ describe("CqlLibrary List component", () => { version: "0.0.000", cql: "library AdvancedIllnessandFrailtyExclusion_QICore4 version '5.0.00'", cqlErrors: false, + active: true, }, ]; render( diff --git a/src/components/cqlLibraryList/CqlLibraryList.tsx b/src/components/cqlLibraryList/CqlLibraryList.tsx index 5d94638..4cb133b 100644 --- a/src/components/cqlLibraryList/CqlLibraryList.tsx +++ b/src/components/cqlLibraryList/CqlLibraryList.tsx @@ -6,7 +6,7 @@ import { useHistory } from "react-router-dom"; import { CqlLibrary } from "@madie/madie-models"; import CreatVersionDialog from "../createVersionDialog/CreateVersionDialog"; import useCqlLibraryServiceApi from "../../api/useCqlLibraryServiceApi"; -import CreatDraftDialog from "../createDraftDialog/CreateDraftDialog"; +import CreateDraftDialog from "../createDraftDialog/CreateDraftDialog"; import Snackbar from "@mui/material/Snackbar"; import MuiAlert, { AlertProps } from "@mui/material/Alert"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; @@ -108,9 +108,9 @@ export default function CqlLibraryList({ cqlLibraryList, onListUpdate }) { }); }; - const createDraft = async (cqlLibrary: CqlLibrary) => { + const createDraft = async (cqlLibrary: CqlLibrary, model: string) => { await cqlLibraryServiceApi - .createDraft(cqlLibrary.id, cqlLibrary.cqlLibraryName) + .createDraft(cqlLibrary.id, cqlLibrary.cqlLibraryName, model) .then(async () => { handleDialogClose(); await onListUpdate(); @@ -246,7 +246,7 @@ export default function CqlLibraryList({ cqlLibraryList, onListUpdate }) { cqlLibraryError={createVersionDialog.cqlLibraryError} isCqlPresent={createVersionDialog.isCqlPresent} /> - ({ + useFeatureFlags: jest.fn().mockReturnValue({ + qiCore6: true, + }), +})); + describe("Create Draft Dialog component", () => { beforeEach(() => { clearAllMocks(); @@ -27,7 +34,7 @@ describe("Create Draft Dialog component", () => { it("should render Draft dialog with cql library name", () => { render( - { it("should generate field level error for required Cql Library name", async () => { render( - { }); }); + it("should display a model version option for QI-Core measures", async () => { + render( + + ); + const cqlLibraryName = (await screen.findByRole("textbox", { + name: "CQL Library Name", + })) as HTMLInputElement; + expect(cqlLibraryName.value).toEqual(cqlLibrary.cqlLibraryName); + expect(await screen.findByText("Create Draft")).toBeInTheDocument(); + expect(await screen.findByText("Update Model Version")).toBeInTheDocument(); + expect(await screen.findByText("QI-Core v4.1.1")).toBeInTheDocument(); + + expect(screen.getByTestId("create-draft-continue-button")).toBeEnabled(); + }); + + it("should not display a model version option for QDM measures", async () => { + const qdmLibrary = Object.assign({}, cqlLibrary); + qdmLibrary.model = Model.QDM_5_6; + render( + + ); + expect(await screen.findByText("Create Draft")).toBeInTheDocument(); + const cqlLibraryName = (await screen.findByRole("textbox", { + name: "CQL Library Name", + })) as HTMLInputElement; + expect(cqlLibraryName.value).toEqual(cqlLibrary.cqlLibraryName); + expect(screen.queryByText("Update Model Version")).not.toBeInTheDocument(); + + expect(screen.getByTestId("create-draft-continue-button")).toBeEnabled(); + }); + it("should generate field level error for at least one alphabet in cql library name", async () => { render( - { it("should generate field level error for underscore in cql library name", async () => { render( - { it("should generate field level error for library name starting with lower case", async () => { render( - { it("should generate field level error for library name with a space", async () => { render( - { it("should navigate to cql library home page on cancel", async () => { const onCloseFn = jest.fn(); render( - { it("should not change cql but continue drafting by calling onSubmit when user does not rename library", async () => { const onSubmitFn = jest.fn(); render( - { expect(cqlLibraryNameInput.value).toBe(cqlLibrary.cqlLibraryName); userEvent.click(screen.getByRole("button", { name: "Continue" })); await waitFor(() => { - expect(onSubmitFn).toHaveBeenCalledWith(cqlLibrary); + expect(onSubmitFn).toHaveBeenCalledWith(cqlLibrary, cqlLibrary.model); }); }); it("should update the cql and continue drafting by calling onSubmit when user renames the library", async () => { const onSubmitFn = jest.fn(); render( - { userEvent.type(cqlLibraryNameInput, "TestingLibraryName12"); userEvent.click(screen.getByRole("button", { name: "Continue" })); await waitFor(() => { - expect(onSubmitFn).toHaveBeenCalledWith({ - ...cqlLibrary, - cqlLibraryName: "TestingLibraryName12", - }); + expect(onSubmitFn).toHaveBeenCalledWith( + { + ...cqlLibrary, + cqlLibraryName: "TestingLibraryName12", + }, + "QI-Core v4.1.1" + ); }); }); it("should not update cql even if user renames library when there is no cql", async () => { const onSubmitFn = jest.fn(); render( - { userEvent.type(cqlLibraryNameInput, "TestingLibraryName12"); userEvent.click(screen.getByRole("button", { name: "Continue" })); await waitFor(() => { - expect(onSubmitFn).toHaveBeenCalledWith({ - ...cqlLibrary, - cqlLibraryName: "TestingLibraryName12", - cql: null, - }); + expect(onSubmitFn).toHaveBeenCalledWith( + { + ...cqlLibrary, + cqlLibraryName: "TestingLibraryName12", + cql: null, + }, + "QI-Core v4.1.1" + ); }); }); }); diff --git a/src/components/createDraftDialog/CreateDraftDialog.tsx b/src/components/createDraftDialog/CreateDraftDialog.tsx index da96973..48fa264 100644 --- a/src/components/createDraftDialog/CreateDraftDialog.tsx +++ b/src/components/createDraftDialog/CreateDraftDialog.tsx @@ -1,11 +1,16 @@ import React from "react"; import "twin.macro"; import "styled-components/macro"; -import { DialogContent, Box, Typography } from "@mui/material"; +import { DialogContent, Box, MenuItem, Typography } from "@mui/material"; import { useFormik } from "formik"; import * as Yup from "yup"; -import { CqlLibrary } from "@madie/madie-models"; -import { MadieDialog, TextField } from "@madie/madie-design-system/dist/react"; +import { CqlLibrary, Model } from "@madie/madie-models"; +import { + MadieDialog, + Select, + TextField, +} from "@madie/madie-design-system/dist/react"; +import { useFeatureFlags } from "@madie/madie-util"; interface CreateDraftDialogProps { open: boolean; @@ -14,15 +19,19 @@ interface CreateDraftDialogProps { cqlLibrary: CqlLibrary; } -const CreatDraftDialog = ({ +const CreateDraftDialog = ({ open, onClose, onSubmit, cqlLibrary, }: CreateDraftDialogProps) => { + let modelOptions = Object.keys(Model); + const featureFlags = useFeatureFlags(); + const formik = useFormik({ initialValues: { cqlLibraryName: cqlLibrary?.cqlLibraryName, + model: cqlLibrary?.model, } as CqlLibrary, validationSchema: Yup.object().shape({ cqlLibraryName: Yup.string() @@ -34,10 +43,26 @@ const CreatDraftDialog = ({ ), }), enableReinitialize: true, - onSubmit: async ({ cqlLibraryName }) => - onSubmit({ ...cqlLibrary, cqlLibraryName }), + onSubmit: async ({ cqlLibraryName, model }) => + onSubmit({ ...cqlLibrary, cqlLibraryName }, model), }); + const row = { + display: "flex", + flexDirection: "row", + }; + const spaced = { + marginTop: "23px", + }; + const formRow = Object.assign({}, row, spaced); + const gap = { + columnGap: "24px", + "& > * ": { + flex: 1, + }, + }; + const formRowGapped = Object.assign({}, formRow, gap); + return ( + <> + {featureFlags?.qiCore6 && !cqlLibrary?.model.includes("QDM") ? ( + +