Skip to content

Commit

Permalink
Merge pull request #574 from CBIIT/CRDCDH-2118
Browse files Browse the repository at this point in the history
CRDCDH-2118 Operation Dashboard – Studies filter utilizes "All" studies selected
  • Loading branch information
amattu2 authored Dec 31, 2024
2 parents 3c7dc67 + ca9a60d commit 22fa12d
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 19 deletions.
35 changes: 16 additions & 19 deletions src/content/OperationDashboard/DashboardView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import StyledLabel from "../../components/StyledFormComponents/StyledLabel";
import SuspenseLoader from "../../components/SuspenseLoader";
import bannerSvg from "../../assets/banner/submission_banner.png";
import { useAuthContext } from "../../components/Contexts/AuthContext";
import { Logger } from "../../utils";
import { addDataCommonsParameter, addStudiesParameter } from "../../utils";
import { RequiresStudiesAssigned } from "../../config/AuthRoles";

export type DashboardViewProps = {
url: string;
Expand Down Expand Up @@ -87,32 +88,28 @@ const DashboardView: FC<DashboardViewProps> = ({
const dashboardElementRef = useRef<HTMLDivElement>(null);

const contentParameters = useMemo<DashboardContentOptions["parameters"]>(() => {
const { role, studies, dataCommons } = user || {};
const params: DashboardContentOptions["parameters"] = [];

if (role === "Federal Lead" && Array.isArray(studies) && studies.length > 0) {
params.push({
Name: "studiesParameter",
Values: studies?.map((study: ApprovedStudy) => study?._id),
});
} else if (role === "Federal Lead") {
Logger.error("This role requires studies to be set but none were found.", studies);
params.push({ Name: "studiesParameter", Values: ["NO-CONTENT"] });
if (!user?.role) {
return [];
}

if (role === "Data Commons Personnel" && Array.isArray(dataCommons) && dataCommons.length > 0) {
params.push({ Name: "dataCommonsParameter", Values: dataCommons });
} else if (role === "Data Commons Personnel") {
Logger.error("This role requires dataCommons to be set but none were found.", dataCommons);
params.push({ Name: "dataCommonsParameter", Values: ["NO-CONTENT"] });
const { role } = user;

if (RequiresStudiesAssigned.includes(role)) {
return addStudiesParameter(user);
}

if (role === "Data Commons Personnel") {
return addDataCommonsParameter(user);
}

return params;
return [];
}, [user]);

const handleDashboardChange = (e: SelectChangeEvent) => {
setSearchParams({ type: e.target.value });
dashboardElementRef.current.innerHTML = "";
if (dashboardElementRef.current) {
dashboardElementRef.current.innerHTML = "";
}
setEmbeddedDashboard(null);
};

Expand Down
177 changes: 177 additions & 0 deletions src/utils/dashboardUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import { DashboardContentOptions } from "amazon-quicksight-embedding-sdk";
import { addStudiesParameter, addDataCommonsParameter } from "./dashboardUtils";
import { Logger } from "./logger";

jest.mock("./logger", () => ({
Logger: {
error: jest.fn(),
},
}));

describe("addStudiesParameter", () => {
beforeEach(() => {
jest.clearAllMocks();
});

it("should return an empty array if user has 'All' as the first study", () => {
const user = {
studies: [{ _id: "All" }, { _id: "AnotherStudy" }],
} as unknown as User;

const result = addStudiesParameter(user);
expect(result).toEqual([]);
expect(Logger.error).not.toHaveBeenCalled();
});

it("should return an array with studiesParameter if user has valid studies", () => {
const user = {
studies: [{ _id: "StudyA" }, { _id: "StudyB" }],
} as unknown as User;

const result = addStudiesParameter(user);
expect(result).toEqual<DashboardContentOptions["parameters"]>([
{
Name: "studiesParameter",
Values: ["StudyA", "StudyB"],
},
]);
expect(Logger.error).not.toHaveBeenCalled();
});

it("should return NO-CONTENT if user has an empty studies array", () => {
const user = {
studies: [],
} as unknown as User;

const result = addStudiesParameter(user);
expect(result).toEqual<DashboardContentOptions["parameters"]>([
{
Name: "studiesParameter",
Values: ["NO-CONTENT"],
},
]);
expect(Logger.error).toHaveBeenCalledTimes(1);
expect(Logger.error).toHaveBeenCalledWith(
"Federal Lead requires studies to be set but none or invalid values were found.",
[]
);
});

it("should return NO-CONTENT if user studies is undefined or null", () => {
const user = {
studies: null,
} as unknown as User;

const result = addStudiesParameter(user);
expect(result).toEqual<DashboardContentOptions["parameters"]>([
{
Name: "studiesParameter",
Values: ["NO-CONTENT"],
},
]);
expect(Logger.error).toHaveBeenCalledTimes(1);
});

it("should handle a null user gracefully", () => {
const user = null as unknown as User;
const result = addStudiesParameter(user);
expect(result).toEqual<DashboardContentOptions["parameters"]>([
{
Name: "studiesParameter",
Values: ["NO-CONTENT"],
},
]);
expect(Logger.error).toHaveBeenCalledTimes(1);
});

it("should handle an undefined user gracefully", () => {
const user = undefined as unknown as User;
const result = addStudiesParameter(user);
expect(result).toEqual<DashboardContentOptions["parameters"]>([
{
Name: "studiesParameter",
Values: ["NO-CONTENT"],
},
]);
expect(Logger.error).toHaveBeenCalledTimes(1);
});
});

describe("addDataCommonsParameter", () => {
beforeEach(() => {
jest.clearAllMocks();
});

it("should return an array with dataCommonsParameter if user has valid dataCommons", () => {
const user = {
dataCommons: ["CommonsA", "CommonsB"],
} as unknown as User;

const result = addDataCommonsParameter(user);
expect(result).toEqual<DashboardContentOptions["parameters"]>([
{
Name: "dataCommonsParameter",
Values: ["CommonsA", "CommonsB"],
},
]);
expect(Logger.error).not.toHaveBeenCalled();
});

it("should return NO-CONTENT if user dataCommons is an empty array", () => {
const user = {
dataCommons: [],
} as unknown as User;

const result = addDataCommonsParameter(user);
expect(result).toEqual<DashboardContentOptions["parameters"]>([
{
Name: "dataCommonsParameter",
Values: ["NO-CONTENT"],
},
]);
expect(Logger.error).toHaveBeenCalledTimes(1);
expect(Logger.error).toHaveBeenCalledWith(
"Data Commons Personnel requires dataCommons to be set but none were found.",
[]
);
});

it("should return NO-CONTENT if user dataCommons is null or undefined", () => {
const user = {
dataCommons: null,
} as unknown as User;

const result = addDataCommonsParameter(user);
expect(result).toEqual<DashboardContentOptions["parameters"]>([
{
Name: "dataCommonsParameter",
Values: ["NO-CONTENT"],
},
]);
expect(Logger.error).toHaveBeenCalledTimes(1);
});

it("should handle a null user gracefully", () => {
const user = null as unknown as User;
const result = addDataCommonsParameter(user);
expect(result).toEqual<DashboardContentOptions["parameters"]>([
{
Name: "dataCommonsParameter",
Values: ["NO-CONTENT"],
},
]);
expect(Logger.error).toHaveBeenCalledTimes(1);
});

it("should handle an undefined user gracefully", () => {
const user = undefined as unknown as User;
const result = addDataCommonsParameter(user);
expect(result).toEqual<DashboardContentOptions["parameters"]>([
{
Name: "dataCommonsParameter",
Values: ["NO-CONTENT"],
},
]);
expect(Logger.error).toHaveBeenCalledTimes(1);
});
});
66 changes: 66 additions & 0 deletions src/utils/dashboardUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { DashboardContentOptions } from "amazon-quicksight-embedding-sdk";
import { Logger } from "./logger";

/**
* Constructs and returns an array of QuickSight parameter objects for a user's studies.
*
* - If the user's first study is `All`, the function returns an empty array (allowing QuickSight to display all data).
* - If the user has a valid array of studies, it creates a `studiesParameter` whose values are the `_id` fields of each study.
* - Otherwise, it logs an error and returns a parameter array with `["NO-CONTENT"]`.
*
*
* @param {User} user - The current user
* @returns {DashboardContentOptions["parameters"]} The updated dashboard parameters
*/
export const addStudiesParameter = (user: User): DashboardContentOptions["parameters"] => {
const params: DashboardContentOptions["parameters"] = [];
const { studies } = user || {};

// If user contains the "All" study, do NOT push the "studiesParameter"
if ((studies || [])?.findIndex((s) => s?._id === "All") !== -1) {
return params;
}

// Otherwise, push a real or fallback param
if (Array.isArray(studies) && studies.length > 0) {
params.push({
Name: "studiesParameter",
Values: studies.map((s) => s._id),
});
return params;
}

Logger.error(
"Federal Lead requires studies to be set but none or invalid values were found.",
studies
);
params.push({ Name: "studiesParameter", Values: ["NO-CONTENT"] });
return params;
};

/**
* Constructs and returns an array of QuickSight parameter objects for a user's data commons.
*
* - If the user has a valid array of data commons, it creates a `dataCommonsParameter` whose values are the array elements.
* - Otherwise, it logs an error and returns a parameter array with `["NO-CONTENT"]`.
*
*
* @param {User} user - The current user
* @returns {DashboardContentOptions["parameters"]} The updated dashboard parameters
*/
export const addDataCommonsParameter = (user: User): DashboardContentOptions["parameters"] => {
const params: DashboardContentOptions["parameters"] = [];
const { dataCommons } = user || {};

if (Array.isArray(dataCommons) && dataCommons.length > 0) {
params.push({ Name: "dataCommonsParameter", Values: dataCommons });
return params;
}

Logger.error(
"Data Commons Personnel requires dataCommons to be set but none were found.",
dataCommons
);
params.push({ Name: "dataCommonsParameter", Values: ["NO-CONTENT"] });
return params;
};
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export * from "./searchParamUtils";
export * from "./envUtils";
export * from "./logger";
export * from "./fetchUtils";
export * from "./dashboardUtils";

0 comments on commit 22fa12d

Please sign in to comment.