diff --git a/frontend/cypress/e2e/result.cy.js b/frontend/cypress/e2e/result.cy.js
index 9a4f4f3b9..c42053f53 100644
--- a/frontend/cypress/e2e/result.cy.js
+++ b/frontend/cypress/e2e/result.cy.js
@@ -209,7 +209,7 @@ describe("Result By Referred Out Tests", function () {
// );
// });
});
-//commented due to UI changes
+ //commented due to UI changes
// it("should select the respecting referred test and print the selected patient reports", function () {
// result.selectRefferedTest();
// result.printReport();
diff --git a/frontend/cypress/e2e/validation.cy.js b/frontend/cypress/e2e/validation.cy.js
index 4aecae333..3e0f947f6 100644
--- a/frontend/cypress/e2e/validation.cy.js
+++ b/frontend/cypress/e2e/validation.cy.js
@@ -67,6 +67,6 @@ describe("Validation By Range Of Order", function () {
});
it("Should Save the results", function () {
- validation.saveResults('Test Note');
+ validation.saveResults("Test Note");
});
});
diff --git a/frontend/cypress/pages/HomePage.js b/frontend/cypress/pages/HomePage.js
index 8b5e46a5a..dfedb13fc 100755
--- a/frontend/cypress/pages/HomePage.js
+++ b/frontend/cypress/pages/HomePage.js
@@ -105,7 +105,6 @@ class HomePage {
return new NonConform();
}
-
goToResultsByUnit() {
this.openNavigationMenu();
cy.get("#menu_results").click();
@@ -150,22 +149,22 @@ class HomePage {
goToValidationByRoutine() {
this.openNavigationMenu();
- cy.get('#menu_resultvalidation').click();
- cy.get('#menu_resultvalidation_routine ').click();
+ cy.get("#menu_resultvalidation").click();
+ cy.get("#menu_resultvalidation_routine ").click();
return new Validation();
}
goToValidationByOrder() {
this.openNavigationMenu();
cy.get("#menu_resultvalidation").click();
- cy.get('#menu_accession_validation ').click();
+ cy.get("#menu_accession_validation ").click();
return new Validation();
}
goToValidationByRangeOrder() {
this.openNavigationMenu();
cy.get("#menu_resultvalidation").click();
- cy.get('#menu_accession_validation_range ').click();
+ cy.get("#menu_accession_validation_range ").click();
return new Validation();
- }
+ }
goToRoutineReports() {
this.openNavigationMenu();
diff --git a/frontend/cypress/pages/ResultsPage.js b/frontend/cypress/pages/ResultsPage.js
index cacab599a..75aa6a77c 100644
--- a/frontend/cypress/pages/ResultsPage.js
+++ b/frontend/cypress/pages/ResultsPage.js
@@ -38,8 +38,14 @@ class Result {
}
validatePatientResult(patient) {
- cy.get('tbody > :nth-child(1) > :nth-child(2)').should("contain.text", patient.lastName);
- cy.get('tbody > :nth-child(1) > :nth-child(3)').should("contain.text", patient.firstName);
+ cy.get("tbody > :nth-child(1) > :nth-child(2)").should(
+ "contain.text",
+ patient.lastName,
+ );
+ cy.get("tbody > :nth-child(1) > :nth-child(3)").should(
+ "contain.text",
+ patient.firstName,
+ );
}
referSample(index = 0, reason, institute) {
diff --git a/frontend/cypress/pages/Validation.js b/frontend/cypress/pages/Validation.js
index 5ffe48859..d6ed96eb8 100644
--- a/frontend/cypress/pages/Validation.js
+++ b/frontend/cypress/pages/Validation.js
@@ -1,28 +1,27 @@
class Validation {
- checkForHeading() {
- cy.get('section > h3').should("contain.text", "Validation");
- }
-
- selectTestUnit(unitType) {
- cy.get('#unitType').select(unitType);
- }
+ checkForHeading() {
+ cy.get("section > h3").should("contain.text", "Validation");
+ }
+
+ selectTestUnit(unitType) {
+ cy.get("#unitType").select(unitType);
+ }
+
+ validateTestUnit(unitType) {
+ cy.get("#cell-testName-0 > .sampleInfo").should("contain.text", unitType);
+ }
+
+ enterLabNumberAndSearch(labNo) {
+ cy.get("#accessionNumber").type(labNo);
+ cy.get(".cds--sm\\:col-span-4.cds--lg\\:col-span-16 > #submit").click();
+ cy.get("#cell-sampleInfo-0 > .sampleInfo").should("contain.text", labNo);
+ }
- validateTestUnit(unitType) {
- cy.get('#cell-testName-0 > .sampleInfo').should("contain.text", unitType);
- }
-
- enterLabNumberAndSearch(labNo) {
- cy.get('#accessionNumber').type(labNo);
- cy.get('.cds--sm\\:col-span-4.cds--lg\\:col-span-16 > #submit').click();
- cy.get('#cell-sampleInfo-0 > .sampleInfo').should("contain.text", labNo);
- }
-
- saveResults(note) {
- cy.get('#cell-save-0 > .cds--form-item > .cds--checkbox-label').click();
- cy.get('#resultList0\\.note').type(note);
- cy.get(':nth-child(3) > #submit').click();
- }
+ saveResults(note) {
+ cy.get("#cell-save-0 > .cds--form-item > .cds--checkbox-label").click();
+ cy.get("#resultList0\\.note").type(note);
+ cy.get(":nth-child(3) > #submit").click();
}
-
- export default Validation;
-
\ No newline at end of file
+}
+
+export default Validation;
diff --git a/frontend/src/components/admin/Admin.js b/frontend/src/components/admin/Admin.js
index 541f29442..4738e7abc 100644
--- a/frontend/src/components/admin/Admin.js
+++ b/frontend/src/components/admin/Admin.js
@@ -29,6 +29,7 @@ import {
Bullhorn,
User,
BatchJob,
+ Popup,
} from "@carbon/icons-react";
import PathRoute from "../utils/PathRoute";
import CalculatedValue from "./calculatedValue/CalculatedValueForm";
@@ -54,6 +55,8 @@ import UserManagement from "./userManagement/UserManagement";
import UserAddModify from "./userManagement/UserAddModify";
import ManageMethod from "./testManagement/ManageMethod.js";
import BatchTestReassignmentAndCancelation from "./BatchTestReassignmentAndCancellation/BatchTestReassignmentAndCancelation.js";
+import TestNotificationConfigMenu from "./testNotificationConfigMenu/TestNotificationConfigMenu.js";
+import TestNotificationConfigEdit from "./testNotificationConfigMenu/TestNotificationConfigEdit.js";
function Admin() {
const intl = useIntl();
@@ -188,6 +191,9 @@ function Admin() {
defaultMessage={"Common Properties"}
/>
+
+
+
@@ -325,6 +331,12 @@ function Admin() {
id="sidenav.label.admin.formEntry.PrintedReportsconfig"
/>
+
+
+
+
+
+
diff --git a/frontend/src/components/admin/testNotificationConfigMenu/TestNotificationConfigEdit.js b/frontend/src/components/admin/testNotificationConfigMenu/TestNotificationConfigEdit.js
new file mode 100644
index 000000000..f61a05a65
--- /dev/null
+++ b/frontend/src/components/admin/testNotificationConfigMenu/TestNotificationConfigEdit.js
@@ -0,0 +1,803 @@
+import React, { useContext, useState, useEffect, useRef } from "react";
+import {
+ Heading,
+ Button,
+ Loading,
+ Grid,
+ Column,
+ Section,
+ DataTable,
+ Table,
+ TableHead,
+ TableRow,
+ TableBody,
+ TableHeader,
+ TableCell,
+ TableSelectRow,
+ TableSelectAll,
+ TableContainer,
+ Pagination,
+ Search,
+ Modal,
+ TextInput,
+ Dropdown,
+ TextArea,
+ Checkbox,
+} from "@carbon/react";
+import {
+ getFromOpenElisServer,
+ postToOpenElisServerFullResponse,
+ postToOpenElisServerJsonResponse,
+} from "../../utils/Utils.js";
+import {
+ ConfigurationContext,
+ NotificationContext,
+} from "../../layout/Layout.js";
+import {
+ AlertDialog,
+ NotificationKinds,
+} from "../../common/CustomNotification.js";
+import { FormattedMessage, injectIntl, useIntl } from "react-intl";
+import PageBreadCrumb from "../../common/PageBreadCrumb.js";
+import { ArrowLeft, ArrowRight, Cost } from "@carbon/icons-react";
+import ActionPaginationButtonType from "../../common/ActionPaginationButtonType.js";
+
+let breadcrumbs = [
+ { label: "home.label", link: "/" },
+ { label: "breadcrums.admin.managment", link: "/MasterListsPage" },
+ {
+ label: "testnotificationconfig.browse.title",
+ link: "/MasterListsPage#testNotificationConfigMenu",
+ },
+];
+
+function TestNotificationConfigEdit() {
+ const { notificationVisible, setNotificationVisible, addNotification } =
+ useContext(NotificationContext);
+
+ const intl = useIntl();
+
+ const ID = (() => {
+ const hash = window.location.hash;
+ if (hash.includes("?")) {
+ const queryParams = hash.split("?")[1];
+ const urlParams = new URLSearchParams(queryParams);
+ return urlParams.get("testId");
+ }
+ return "0";
+ })();
+
+ const componentMounted = useRef(false);
+ const [indMsg, setIndMsg] = useState("0");
+ const [loading, setLoading] = useState(true);
+ const [saveButton, setSaveButton] = useState(false);
+ const [sysDefaultMsg, setSysDefaultMsg] = useState(true);
+ const [testNotificationConfigEditData, setTestNotificationConfigEditData] =
+ useState({});
+ const [
+ testNotificationConfigEditDataPost,
+ setTestNotificationConfigEditDataPost,
+ ] = useState({});
+ const [testNamesList, setTestNamesList] = useState([]);
+ const [testName, setTestName] = useState("");
+ const [testNotificationConfigMenuList, setTestNotificationConfigMenuList] =
+ useState([]);
+
+ useEffect(() => {
+ if (testNotificationConfigEditData) {
+ setTestNotificationConfigEditDataPost(
+ (prevSetTestNotificationConfigDataPost) => ({
+ ...prevSetTestNotificationConfigDataPost,
+ formName: testNotificationConfigEditData.formName,
+ formMethod: testNotificationConfigEditData.formMethod,
+ cancelAction: testNotificationConfigEditData.cancelAction,
+ submitOnCancel: testNotificationConfigEditData.submitOnCancel,
+ cancelMethod: testNotificationConfigEditData.cancelMethod,
+ config: testNotificationConfigEditData.config,
+ systemDefaultPayloadTemplate:
+ testNotificationConfigEditData.systemDefaultPayloadTemplate,
+ editSystemDefaultPayloadTemplate:
+ testNotificationConfigEditData.editSystemDefaultPayloadTemplate,
+ }),
+ );
+ }
+ }, [testNotificationConfigEditData]);
+
+ const handleMenuItems = (res) => {
+ if (res) {
+ setTestNotificationConfigEditData(res);
+ }
+ setLoading(false);
+ };
+
+ const handleTestNamesList = (res) => {
+ if (res) {
+ setTestNamesList(res);
+ }
+ setLoading(false);
+ };
+
+ useEffect(() => {
+ componentMounted.current = true;
+ getFromOpenElisServer(
+ `/rest/TestNotificationConfig?testId=${ID}`,
+ handleMenuItems,
+ );
+ getFromOpenElisServer(`/rest/test-list`, handleTestNamesList);
+ return () => {
+ componentMounted.current = false;
+ };
+ }, [ID]);
+
+ useEffect(() => {
+ const testId = testNotificationConfigEditData?.config?.testId;
+ if (testNamesList && testId) {
+ const test = testNamesList.find((item) => item.id === testId);
+ if (test) {
+ setTestName(test.value);
+ }
+ }
+ }, [testNamesList, testNotificationConfigEditData]);
+
+ function handleSubjectTemplateChange(e) {
+ setTestNotificationConfigEditDataPost((prev) => ({
+ ...prev,
+ editSystemDefaultPayloadTemplate: true,
+ }));
+ setTestNotificationConfigEditDataPost((prev) => ({
+ ...prev,
+ systemDefaultPayloadTemplate: {
+ ...prev.systemDefaultPayloadTemplate,
+ subjectTemplate: e.target.value,
+ },
+ }));
+ }
+
+ function handleMessageTemplateChange(e) {
+ setTestNotificationConfigEditDataPost((prev) => ({
+ ...prev,
+ editSystemDefaultPayloadTemplate: true,
+ }));
+ setTestNotificationConfigEditDataPost((prev) => ({
+ ...prev,
+ systemDefaultPayloadTemplate: {
+ ...prev.systemDefaultPayloadTemplate,
+ messageTemplate: e.target.value,
+ },
+ }));
+ }
+
+ const handleCheckboxChange = (e) => {
+ const { id, checked } = e.target;
+
+ setTestNotificationConfigEditDataPost((prev) => {
+ const updatedConfig = { ...prev.config };
+
+ switch (id) {
+ case "providerEmail":
+ updatedConfig.providerEmail.active = checked;
+ break;
+ case "patientEmail":
+ updatedConfig.patientEmail.active = checked;
+ break;
+ case "patientSMS":
+ updatedConfig.patientSMS.active = checked;
+ break;
+ case "providerSMS":
+ updatedConfig.providerSMS.active = checked;
+ break;
+ default:
+ break;
+ }
+
+ return {
+ ...prev,
+ config: updatedConfig,
+ };
+ });
+ };
+
+ function testNotificationConfigEditSavePostCall() {
+ setLoading(true);
+ postToOpenElisServerJsonResponse(
+ `/rest/TestNotificationConfig`,
+ JSON.stringify(testNotificationConfigEditDataPost),
+ (res) => {
+ testNotificationConfigEditSavePostCallBack(res);
+ },
+ );
+ }
+
+ function testNotificationConfigEditSavePostCallBack(res) {
+ if (res) {
+ addNotification({
+ title: intl.formatMessage({
+ id: "notification.title",
+ }),
+ message: intl.formatMessage({
+ id: "notification.user.post.save.success",
+ }),
+ kind: NotificationKinds.success,
+ });
+ setNotificationVisible(true);
+ } else {
+ addNotification({
+ kind: NotificationKinds.error,
+ title: intl.formatMessage({ id: "notification.title" }),
+ message: intl.formatMessage({ id: "server.error.msg" }),
+ });
+ setNotificationVisible(true);
+ }
+ setLoading(false);
+ }
+
+ return (
+ <>
+ {notificationVisible === true ? : ""}
+ {loading && }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {testNotificationConfigEditDataPost?.config && (
+
+
+
+ }
+ checked={
+ testNotificationConfigEditDataPost.config.patientEmail
+ ?.active ?? false
+ }
+ onChange={handleCheckboxChange}
+ />
+
+
+
+ }
+ checked={
+ testNotificationConfigEditDataPost.config.patientSMS
+ ?.active ?? false
+ }
+ onChange={handleCheckboxChange}
+ />
+
+
+
+ }
+ checked={
+ testNotificationConfigEditDataPost.config.providerSMS
+ ?.active ?? false
+ }
+ onChange={handleCheckboxChange}
+ />
+
+
+
+ }
+ checked={
+ testNotificationConfigEditDataPost.config.providerEmail
+ ?.active ?? false
+ }
+ onChange={handleCheckboxChange}
+ />
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ handleSubjectTemplateChange(e)}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ handleUserLoginNameChange(e)}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {" "}
+
+
+ {" "}
+
+
+ {" "}
+
+
+
+
+
+
+
+ {indMsg === "0" || indMsg === "2" ? (
+ <>
+
+
+
+
+
+
+ {indMsg === "0" ? (
+ <>
+
+ >
+ ) : (
+ <>
+
+ >
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+ handleUserLoginNameChange(e)}
+ />
+
+
+
+
+
+
+
+
+ handleUserLoginNameChange(e)}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ ) : (
+ <>
+
+
+
+
+
+
+ {indMsg === "1" ? (
+ <>
+
+ >
+ ) : (
+ <>
+
+ >
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+
+
+
+
+ {" "}
+
+
+
+
+
+
+ >
+ );
+}
+
+export default injectIntl(TestNotificationConfigEdit);
diff --git a/frontend/src/components/admin/testNotificationConfigMenu/TestNotificationConfigMenu.js b/frontend/src/components/admin/testNotificationConfigMenu/TestNotificationConfigMenu.js
new file mode 100644
index 000000000..0cad171f1
--- /dev/null
+++ b/frontend/src/components/admin/testNotificationConfigMenu/TestNotificationConfigMenu.js
@@ -0,0 +1,473 @@
+import React, { useContext, useState, useEffect, useRef } from "react";
+import {
+ Heading,
+ Button,
+ Loading,
+ Grid,
+ Column,
+ Section,
+ DataTable,
+ Table,
+ TableHead,
+ TableRow,
+ TableBody,
+ TableHeader,
+ TableCell,
+ TableSelectRow,
+ TableSelectAll,
+ TableContainer,
+ Pagination,
+ Search,
+ Modal,
+ TextInput,
+ Dropdown,
+ Checkbox,
+} from "@carbon/react";
+import {
+ getFromOpenElisServer,
+ postToOpenElisServerFullResponse,
+ postToOpenElisServerJsonResponse,
+} from "../../utils/Utils.js";
+import {
+ ConfigurationContext,
+ NotificationContext,
+} from "../../layout/Layout.js";
+import {
+ AlertDialog,
+ NotificationKinds,
+} from "../../common/CustomNotification.js";
+import { FormattedMessage, injectIntl, useIntl } from "react-intl";
+import PageBreadCrumb from "../../common/PageBreadCrumb.js";
+import { Settings } from "@carbon/icons-react";
+import ActionPaginationButtonType from "../../common/ActionPaginationButtonType.js";
+
+let breadcrumbs = [
+ { label: "home.label", link: "/" },
+ { label: "breadcrums.admin.managment", link: "/MasterListsPage" },
+ {
+ label: "testnotificationconfig.browse.title",
+ link: "/MasterListsPage#testNotificationConfigMenu",
+ },
+];
+
+function TestNotificationConfigMenu() {
+ const { notificationVisible, setNotificationVisible, addNotification } =
+ useContext(NotificationContext);
+
+ const intl = useIntl();
+
+ const componentMounted = useRef(false);
+ const [page, setPage] = useState(1);
+ const [pageSize, setPageSize] = useState(20);
+ const [loading, setLoading] = useState(true);
+ const [saveButton, setSaveButton] = useState(true);
+ const [testNamesList, setTestNamesList] = useState([]);
+ const [testNotificationConfigMenuData, setTestNotificationConfigMenuData] =
+ useState({});
+ const [
+ testNotificationConfigMenuDataPost,
+ setTestNotificationConfigMenuDataPost,
+ ] = useState({ menuList: [] });
+ const [testNamesMap, setTestNamesMap] = useState({});
+
+ const handleMenuItems = (res) => {
+ if (res) {
+ setTestNotificationConfigMenuData(res);
+ }
+ setLoading(false);
+ };
+
+ const handleTestNamesList = (res) => {
+ if (res) {
+ setTestNamesList(res);
+ }
+ setLoading(false);
+ };
+
+ useEffect(() => {
+ componentMounted.current = true;
+ getFromOpenElisServer(`/rest/TestNotificationConfigMenu`, handleMenuItems);
+ getFromOpenElisServer(`/rest/test-list`, handleTestNamesList);
+ return () => {
+ componentMounted.current = false;
+ };
+ }, []);
+
+ useEffect(() => {
+ if (
+ testNotificationConfigMenuData &&
+ testNotificationConfigMenuData.menuList
+ ) {
+ setTestNotificationConfigMenuDataPost((prevTestNotificationDataPost) => ({
+ ...prevTestNotificationDataPost,
+ formMethod: testNotificationConfigMenuData.formMethod,
+ // formAction: testNotificationConfigMenuData.formAction,
+ // formName: testNotificationConfigMenuData.formName,
+ // config: testNotificationConfigMenuData.config,
+ cancelAction: testNotificationConfigMenuData.cancelAction,
+ submitOnCancel: testNotificationConfigMenuData.submitOnCancel,
+ cancelMethod: testNotificationConfigMenuData.cancelMethod,
+ adminMenuItems: testNotificationConfigMenuData.adminMenuItems,
+ totalRecordCount: testNotificationConfigMenuData.totalRecordCount,
+ fromRecordCount: testNotificationConfigMenuData.fromRecordCount,
+ toRecordCount: testNotificationConfigMenuData.toRecordCount,
+ selectedIDs: testNotificationConfigMenuData.selectedIDs,
+ menuList: testNotificationConfigMenuData.menuList,
+ }));
+ }
+ }, [testNotificationConfigMenuData]);
+
+ useEffect(() => {
+ const map = testNamesList.reduce((acc, item) => {
+ acc[item.id] = item.value;
+ return acc;
+ }, {});
+ setTestNamesMap(map);
+ }, [testNamesList]);
+
+ const handleEditButtonClick = (id) => {
+ window.location.assign(
+ `/MasterListsPage#testNotificationConfig?testId=${id}`,
+ );
+ };
+
+ function testNotificationConfigMenuSavePostCall() {
+ setLoading(true);
+ postToOpenElisServerJsonResponse(
+ `/rest/TestNotificationConfigMenu`,
+ JSON.stringify(testNotificationConfigMenuDataPost),
+ (res) => {
+ testNotificationConfigMenuSavePostCallBack(res);
+ },
+ );
+ }
+
+ function testNotificationConfigMenuSavePostCallBack(res) {
+ if (res) {
+ addNotification({
+ title: intl.formatMessage({
+ id: "notification.title",
+ }),
+ message: intl.formatMessage({
+ id: "notification.user.post.save.success",
+ }),
+ kind: NotificationKinds.success,
+ });
+ setNotificationVisible(true);
+ } else {
+ addNotification({
+ kind: NotificationKinds.error,
+ title: intl.formatMessage({ id: "notification.title" }),
+ message: intl.formatMessage({ id: "server.error.msg" }),
+ });
+ setNotificationVisible(true);
+ }
+ setLoading(false);
+ }
+
+ const handleCheckboxChange = (e, rowId, header) => {
+ const isChecked = e.target.checked;
+
+ setTestNotificationConfigMenuDataPost((prevData) => {
+ const updatedMenuList = prevData.menuList.map((item) => {
+ if (item.id === rowId) {
+ switch (header) {
+ case "patientEmail":
+ return {
+ ...item,
+ patientEmail: { ...item.patientEmail, active: isChecked },
+ };
+ case "patientSMS":
+ return {
+ ...item,
+ patientSMS: { ...item.patientSMS, active: isChecked },
+ };
+ case "providerEmail":
+ return {
+ ...item,
+ providerEmail: { ...item.providerEmail, active: isChecked },
+ };
+ case "providerSMS":
+ return {
+ ...item,
+ providerSMS: { ...item.providerSMS, active: isChecked },
+ };
+ default:
+ return item;
+ }
+ }
+ return item;
+ });
+
+ return {
+ ...prevData,
+ menuList: updatedMenuList,
+ };
+ });
+ };
+
+ const handlePageChange = ({ page, pageSize }) => {
+ setPage(page);
+ setPageSize(pageSize);
+ };
+
+ const renderCell = (cell, row) => {
+ if (cell.info.header === "testId") {
+ return {cell.value};
+ } else if (cell.info.header === "testName") {
+ return {cell.value};
+ } else if (
+ cell.info.header === "patientEmail" ||
+ cell.info.header === "patientSMS" ||
+ cell.info.header === "providerEmail" ||
+ cell.info.header === "providerSMS"
+ ) {
+ return (
+
+ {
+ setSaveButton(false);
+ handleCheckboxChange(e, row.id, cell.info.header);
+ }}
+ />
+
+ );
+ } else if (cell.info.header === "edit") {
+ return (
+
+
+ );
+ } else {
+ return {cell.value};
+ }
+ };
+
+ return (
+ <>
+ {notificationVisible === true ? : ""}
+ {loading && }
+
+
+
+
+
+
+
+
+
+
+
+ {" "}
+
+
+
+
+
+
+
+ ({
+ id: item.id,
+ testId: item.testId,
+ patientEmail: item.patientEmail.active ? "true" : "false",
+ patientSMS: item.patientSMS.active ? "true" : "false",
+ providerEmail: item.providerEmail.active
+ ? "true"
+ : "false",
+ providerSMS: item.providerSMS.active ? "true" : "false",
+ testName: testNamesMap[item.testId] || item.testId,
+ })) || []
+ }
+ headers={[
+ {
+ key: "testId",
+ header: intl.formatMessage({
+ id: "column.name.testId",
+ }),
+ },
+ {
+ key: "testName",
+ header: intl.formatMessage({
+ id: "label.testName",
+ }),
+ },
+ {
+ key: "patientEmail",
+ header: intl.formatMessage({
+ id: "testnotification.patient.email",
+ }),
+ },
+ {
+ key: "patientSMS",
+ header: intl.formatMessage({
+ id: "testnotification.patient.sms",
+ }),
+ },
+ {
+ key: "providerEmail",
+ header: intl.formatMessage({
+ id: "testnotification.provider.email",
+ }),
+ },
+ {
+ key: "providerSMS",
+ header: intl.formatMessage({
+ id: "testnotification.provider.sms",
+ }),
+ },
+ {
+ key: "edit",
+ header: intl.formatMessage({
+ id: "banner.menu.patientEdit",
+ }),
+ },
+ ]}
+ >
+ {({
+ rows,
+ headers,
+ getHeaderProps,
+ getTableProps,
+ getSelectionProps,
+ }) => (
+
+
+
+
+ {headers.map((header) => (
+ // header.key !== "id" &&
+
+ {header.header}
+
+ ))}
+
+
+
+ <>
+ {rows.map((row) => (
+
+ {row.cells.map((cell) => renderCell(cell, row))}
+
+ ))}
+ >
+
+
+
+ )}
+
+
+ intl.formatMessage(
+ { id: "pagination.item-range" },
+ { min: min, max: max, total: total },
+ )
+ }
+ itemsPerPageText={intl.formatMessage({
+ id: "pagination.items-per-page",
+ })}
+ itemText={(min, max) =>
+ intl.formatMessage(
+ { id: "pagination.item" },
+ { min: min, max: max },
+ )
+ }
+ pageNumberText={intl.formatMessage({
+ id: "pagination.page-number",
+ })}
+ pageRangeText={(_current, total) =>
+ intl.formatMessage(
+ { id: "pagination.page-range" },
+ { total: total },
+ )
+ }
+ pageText={(page, pagesUnknown) =>
+ intl.formatMessage(
+ { id: "pagination.page" },
+ { page: pagesUnknown ? "" : page },
+ )
+ }
+ />
+
+
+
+
+
+
+ {" "}
+
+
+
+
+
+ >
+ );
+}
+
+export default injectIntl(TestNotificationConfigMenu);
diff --git a/frontend/src/languages/en.json b/frontend/src/languages/en.json
index 2dc47150e..b018fe2ac 100644
--- a/frontend/src/languages/en.json
+++ b/frontend/src/languages/en.json
@@ -1240,5 +1240,31 @@
"notification.slideover.button.unsubscribe.success": "Unsubscribed successfully",
"notification.slideover.button.unsubscribe.fail": "Unsubscribe failed",
"notification.slideover.button.subscribe.success": "Subscribed successfully",
- "notification.slideover.button.subscribe.fail": "Subscribe failed"
+ "notification.slideover.button.subscribe.fail": "Subscribe failed",
+ "testnotificationconfig.browse.title": "Test Notification Configuration",
+ "label.testName": "Test names",
+ "testnotification.instructionis.variables.body": "[testName] : Name of the test this is for",
+ "testnotification.instructionis.variables.body.0": "[testResult] : Result of the test",
+ "testnotification.instructionis.variables.body.1": "[patientFirstName] : Patient's first name ",
+ "testnotification.instructionis.variables.body.2": "[patientLastNameInitial] : Patient's last name's initial",
+ "testnotification.instructionis.variables.header": "List of variables:",
+ "testnotification.instructions.body": "When a notification is created, it will first check if a message template is defined for the recipient/message type.",
+ "testnotification.instructions.body.0": "If none exists, it will use the test default message.",
+ "testnotification.instructions.body.1": "If that does not exist, it will use the system default message.",
+ "testnotification.instructions.body.2": "Variables will be replaced by their corresponding values in the message body and the subject.",
+ "testnotification.instructions.body.3": "Variables should always include the square brackets and should have no whitespace.",
+ "testnotification.instructions.header": "Instructions:",
+ "testnotification.messagetemplate": "Message",
+ "testnotification.options": "Individiual Messages",
+ "testnotification.patient.email": "Patient Email",
+ "testnotification.patient.sms": "Patient SMS",
+ "testnotification.patiententry.header": "Result Reporting",
+ "testnotification.provider.email": "Provider Email",
+ "testnotification.provider.sms": "Provider SMS",
+ "testnotification.subjecttemplate": "Subject",
+ "testnotification.systemdefault.template": "System Default Message",
+ "testnotification.testdefault.template": "Default Message for Test",
+ "testnotification.testdefault.editIcon": "Edit Test Notification",
+ "testnotification.bcc": "BCC",
+ "column.name.testId": "Test Id"
}
diff --git a/frontend/src/languages/fr.json b/frontend/src/languages/fr.json
index daee73d56..7eee8008d 100644
--- a/frontend/src/languages/fr.json
+++ b/frontend/src/languages/fr.json
@@ -1144,5 +1144,31 @@
"notification.slideover.button.unsubscribe.success": "Désabonnement réussi",
"notification.slideover.button.unsubscribe.fail": "Échec de l'annulation de l'abonnement",
"notification.slideover.button.subscribe.success": "Abonnement réussi",
- "notification.slideover.button.subscribe.fail": "Échec de l'abonnement"
+ "notification.slideover.button.subscribe.fail": "Échec de l'abonnement",
+ "testnotificationconfig.browse.title": "Configuration des notifications de test",
+ "label.testName": "Noms des tests",
+ "testnotification.instructionis.variables.body": "[testName] : Nom du test pour lequel cela est",
+ "testnotification.instructionis.variables.body.0": "[testResult] : Résultat du test",
+ "testnotification.instructionis.variables.body.1": "[patientFirstName] : Prénom du patient",
+ "testnotification.instructionis.variables.body.2": "[patientLastNameInitial] : Initiale du nom de famille du patient",
+ "testnotification.instructionis.variables.header": "Liste des variables :",
+ "testnotification.instructions.body": "Lorsqu'une notification est créée, elle vérifiera d'abord si un modèle de message est défini pour le destinataire/type de message.",
+ "testnotification.instructions.body.0": "S'il n'en existe pas, elle utilisera le message par défaut du test.",
+ "testnotification.instructions.body.1": "Si cela n'existe pas, elle utilisera le message par défaut du système.",
+ "testnotification.instructions.body.2": "Les variables seront remplacées par leurs valeurs correspondantes dans le corps du message et l'objet.",
+ "testnotification.instructions.body.3": "Les variables doivent toujours inclure les crochets et ne doivent pas contenir d'espaces.",
+ "testnotification.instructions.header": "Instructions :",
+ "testnotification.messagetemplate": "Message",
+ "testnotification.options": "Messages individuels",
+ "testnotification.patient.email": "E-mail du patient",
+ "testnotification.patient.sms": "SMS du patient",
+ "testnotification.patiententry.header": "Rapport de résultats",
+ "testnotification.provider.email": "E-mail du fournisseur",
+ "testnotification.provider.sms": "SMS du fournisseur",
+ "testnotification.subjecttemplate": "Objet",
+ "testnotification.systemdefault.template": "Message par défaut du système",
+ "testnotification.testdefault.template": "Message par défaut pour le test",
+ "testnotification.testdefault.editIcon": "Modifier la notification de test",
+ "testnotification.bcc": "BCC",
+ "column.name.testId": "Id du Test"
}
diff --git a/src/main/java/org/openelisglobal/notification/controller/rest/TestNotificationConfigMenuRestController.java b/src/main/java/org/openelisglobal/notification/controller/rest/TestNotificationConfigMenuRestController.java
new file mode 100644
index 000000000..2107db9e5
--- /dev/null
+++ b/src/main/java/org/openelisglobal/notification/controller/rest/TestNotificationConfigMenuRestController.java
@@ -0,0 +1,131 @@
+package org.openelisglobal.notification.controller.rest;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import org.openelisglobal.common.controller.BaseMenuController;
+import org.openelisglobal.common.form.AdminOptionMenuForm;
+import org.openelisglobal.common.log.LogEvent;
+import org.openelisglobal.common.validator.BaseErrors;
+import org.openelisglobal.notification.form.TestNotificationConfigMenuForm;
+import org.openelisglobal.notification.service.TestNotificationConfigService;
+import org.openelisglobal.notification.valueholder.TestNotificationConfig;
+import org.openelisglobal.test.service.TestService;
+import org.openelisglobal.test.valueholder.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.Errors;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/rest")
+public class TestNotificationConfigMenuRestController extends BaseMenuController {
+
+ private static final String[] ALLOWED_FIELDS = new String[] { "menuList*.id", "menuList*.test.id",
+ "menuList*.providerSMS.active", "menuList*.providerEmail.active", "menuList*.patientEmail.active",
+ "menuList*.patientSMS.active", "menuList*.defaultPayloadTemplate.id" };
+
+ @InitBinder
+ public void initBinder(WebDataBinder binder) {
+ binder.setAllowedFields(ALLOWED_FIELDS);
+ }
+
+ @Autowired
+ private TestService testService;
+ @Autowired
+ private TestNotificationConfigService testNotificationConfigService;
+
+ @Override
+ protected int getPageSize() {
+ return -1;
+ }
+
+ @GetMapping("/TestNotificationConfigMenu")
+ public TestNotificationConfigMenuForm displayNotificationConfig()
+ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ TestNotificationConfigMenuForm form = new TestNotificationConfigMenuForm();
+ // request.setAttribute("menuDefinition", "TestNotificationMenuDefinition");
+ // String forward = performMenuAction(form, request);
+ // return findForward(forward, form);
+ form.setMenuList(createMenuList(form, request));
+ return form;
+ }
+
+ @PostMapping("/TestNotificationConfigMenu")
+ public TestNotificationConfigMenuForm updateNotificationConfig(
+ @RequestBody @Valid TestNotificationConfigMenuForm form, BindingResult result) {
+ if (result.hasErrors()) {
+ // saveErrors(result);
+ // return displayNotificationConfig();
+ throw new RuntimeException("Validation errors occurred");
+ }
+ try {
+ testNotificationConfigService.saveTestNotificationConfigsActiveStatuses(form.getMenuList(),
+ this.getSysUserId(request));
+ } catch (RuntimeException e) {
+ LogEvent.logError("could not save result notification configs", e);
+ Errors errors = new BaseErrors();
+ errors.reject("alert.error", "An error occured while saving");
+ // saveErrors(errors);
+ // return displayNotificationConfig();
+ throw new RuntimeException("An error occurred while saving");
+ }
+
+ // redirectAttributes.addFlashAttribute(FWD_SUCCESS, true);
+ // return findForward(FWD_SUCCESS_INSERT, form);
+ return form;
+ }
+
+ @Override
+ protected List createMenuList(AdminOptionMenuForm form,
+ HttpServletRequest request) {
+ List allOrderableTests = testService.getAllActiveOrderableTests();
+
+ List testNotificationConfigs = new ArrayList<>();
+ for (Test test : allOrderableTests) {
+ TestNotificationConfig testNotificationConfig = testNotificationConfigService
+ .getTestNotificationConfigForTestId(test.getId()).orElse(new TestNotificationConfig());
+ testNotificationConfig.setTest(test);
+ testNotificationConfigs.add(testNotificationConfig);
+ }
+ return testNotificationConfigs;
+ }
+
+ @Override
+ protected String getDeactivateDisabled() {
+ return "false";
+ }
+
+ @Override
+ protected String findLocalForward(String forward) {
+ if (FWD_SUCCESS.equals(forward)) {
+ return "testNotificationMasterListsPageDefinition";
+ } else if (FWD_FAIL.equals(forward)) {
+ return "redirect:/MasterListsPage";
+ } else if (FWD_SUCCESS_INSERT.equals(forward)) {
+ return "redirect:/TestNotificationConfigMenu";
+ } else if (FWD_FAIL_INSERT.equals(forward)) {
+ return "haitiMasterListsPageDefinition";
+ } else {
+ return "PageNotFound";
+ }
+ }
+
+ @Override
+ protected String getPageTitleKey() {
+ return "testnotificationconfig.browse.title";
+ }
+
+ @Override
+ protected String getPageSubtitleKey() {
+ return "testnotificationconfig.browse.title";
+ }
+}
diff --git a/src/main/java/org/openelisglobal/notification/controller/rest/TestNotificationConfigRestController.java b/src/main/java/org/openelisglobal/notification/controller/rest/TestNotificationConfigRestController.java
new file mode 100644
index 000000000..1c6fa6985
--- /dev/null
+++ b/src/main/java/org/openelisglobal/notification/controller/rest/TestNotificationConfigRestController.java
@@ -0,0 +1,117 @@
+package org.openelisglobal.notification.controller.rest;
+
+import java.util.List;
+import javax.validation.Valid;
+import org.apache.commons.validator.GenericValidator;
+import org.openelisglobal.common.controller.BaseController;
+import org.openelisglobal.notification.form.TestNotificationConfigForm;
+import org.openelisglobal.notification.service.NotificationPayloadTemplateService;
+import org.openelisglobal.notification.service.TestNotificationConfigService;
+import org.openelisglobal.notification.valueholder.NotificationPayloadTemplate.NotificationPayloadType;
+import org.openelisglobal.notification.valueholder.TestNotificationConfig;
+import org.openelisglobal.test.service.TestService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/rest")
+public class TestNotificationConfigRestController extends BaseController {
+
+ private static final String[] ALLOWED_FIELDS = new String[] { "config*", "editSystemDefaultPayloadTemplate",
+ "systemDefaultPayloadTemplate*" };
+
+ @Autowired
+ private TestNotificationConfigService testNotificationConfigService;
+
+ @Autowired
+ private NotificationPayloadTemplateService payloadTemplateService;
+ @Autowired
+ private TestService testService;
+
+ @InitBinder
+ public void initBinder(WebDataBinder binder) {
+ binder.setAllowedFields(ALLOWED_FIELDS);
+ }
+
+ @GetMapping("/TestNotificationConfig")
+ public TestNotificationConfigForm displayNotificationConfig(
+ @RequestParam(name = "testId", required = false) String testId) {
+ TestNotificationConfigForm form = new TestNotificationConfigForm();
+
+ form.setFormName("TestNotificationConfigForm");
+ form.setSystemDefaultPayloadTemplate(
+ payloadTemplateService.getSystemDefaultPayloadTemplateForType(NotificationPayloadType.TEST_RESULT));
+ form.setConfig(testNotificationConfigService.getTestNotificationConfigForTestId(testId)
+ .orElse(new TestNotificationConfig()));
+ if (form.getConfig().getTest() == null || GenericValidator.isBlankOrNull(form.getConfig().getTest().getId())) {
+ form.getConfig().setTest(testService.get(testId));
+ }
+ // return findForward(FWD_SUCCESS, form);
+ return form;
+ }
+
+ @GetMapping(value = "/TestNotificationConfig/raw/list", produces = MediaType.APPLICATION_JSON_VALUE)
+ public List getNotificationConfigs(
+ @RequestParam(name = "testIds", required = false) List testIds) {
+ List configs = testNotificationConfigService
+ .getTestNotificationConfigsForTestId(testIds);
+ return configs;
+ }
+
+ @PostMapping("/TestNotificationConfig")
+ public TestNotificationConfigForm updateNotificationConfig(@RequestBody @Valid TestNotificationConfigForm form,
+ BindingResult result) {
+ if (result.hasErrors()) {
+ // saveErrors(result);
+ // return displayNotificationConfig(form.getConfig().getTest().getId());
+ throw new RuntimeException("Validation errors occurred");
+ }
+ String sysUserId = this.getSysUserId(request);
+ if (form.getConfig().getDefaultPayloadTemplate() == null) {
+ form.getConfig().setDefaultPayloadTemplate(form.getSystemDefaultPayloadTemplate());
+ }
+ testNotificationConfigService.saveStatusAndMessages(form.getConfig(), sysUserId);
+ if (form.getEditSystemDefaultPayloadTemplate()) {
+ payloadTemplateService.updatePayloadTemplateMessagesAndSubject(form.getSystemDefaultPayloadTemplate(),
+ sysUserId);
+ }
+ testNotificationConfigService.removeEmptyPayloadTemplates(form.getConfig(), sysUserId);
+ // redirectAttributes.addFlashAttribute(FWD_SUCCESS, true);
+ // return findForward(FWD_SUCCESS_INSERT, form);
+ return form;
+ }
+
+ @Override
+ protected String findLocalForward(String forward) {
+ if (FWD_SUCCESS.equals(forward)) {
+ return "testNotificationConfigDefinition";
+ } else if (FWD_FAIL.equals(forward)) {
+ return "redirect:/TestNotificationConfigMenu";
+ } else if (FWD_SUCCESS_INSERT.equals(forward)) {
+ return "redirect:/TestNotificationConfigMenu";
+ } else if (FWD_FAIL_INSERT.equals(forward)) {
+ return "testNotificationConfigDefinition";
+ } else {
+ return "PageNotFound";
+ }
+ }
+
+ @Override
+ protected String getPageTitleKey() {
+ return "testnotificationconfig.browse.title";
+ }
+
+ @Override
+ protected String getPageSubtitleKey() {
+ return "testnotificationconfig.browse.title";
+ }
+}
diff --git a/src/main/java/org/openelisglobal/notification/service/TestNotificationConfigServiceImpl.java b/src/main/java/org/openelisglobal/notification/service/TestNotificationConfigServiceImpl.java
index 9456e6b9c..d353c3e9a 100644
--- a/src/main/java/org/openelisglobal/notification/service/TestNotificationConfigServiceImpl.java
+++ b/src/main/java/org/openelisglobal/notification/service/TestNotificationConfigServiceImpl.java
@@ -137,8 +137,8 @@ public void updatePayloadTemplatesMessageAndSubject(TestNotificationConfig newTe
} else {
oldPayloadTemplate.setSubjectTemplate(newPayloadTemplate.getSubjectTemplate());
oldPayloadTemplate.setMessageTemplate(newPayloadTemplate.getMessageTemplate());
+ oldPayloadTemplate.setSysUserId(sysUserId);
}
- oldPayloadTemplate.setSysUserId(sysUserId);
}
} else {
oldConfig = newTestNotificationConfig;
diff --git a/src/main/java/org/openelisglobal/notification/valueholder/TestNotificationConfig.java b/src/main/java/org/openelisglobal/notification/valueholder/TestNotificationConfig.java
index 7d1bcfdec..f17c8230a 100644
--- a/src/main/java/org/openelisglobal/notification/valueholder/TestNotificationConfig.java
+++ b/src/main/java/org/openelisglobal/notification/valueholder/TestNotificationConfig.java
@@ -21,6 +21,8 @@
import org.openelisglobal.notification.valueholder.NotificationConfigOption.NotificationMethod;
import org.openelisglobal.notification.valueholder.NotificationConfigOption.NotificationNature;
import org.openelisglobal.notification.valueholder.NotificationConfigOption.NotificationPersonType;
+import org.openelisglobal.spring.util.SpringContext;
+import org.openelisglobal.test.service.TestService;
import org.openelisglobal.test.valueholder.Test;
@Entity
@@ -93,6 +95,10 @@ public String getTestId() {
return test.getId();
}
+ public void setTestId(String testId) {
+ this.test = SpringContext.getBean(TestService.class).get(testId);
+ }
+
public void setTest(Test test) {
this.test = test;
}
@@ -107,6 +113,9 @@ public void setDefaultPayloadTemplate(NotificationPayloadTemplate defaultPayload
@Override
public List getOptions() {
+ if (options == null) {
+ options = new ArrayList<>();
+ }
return options;
}
@@ -156,4 +165,20 @@ public NotificationConfigOption getProviderSMS() {
return getOptionFor(NotificationNature.RESULT_VALIDATION, NotificationMethod.SMS,
NotificationPersonType.PROVIDER);
}
+
+ public void setPatientEmail(NotificationConfigOption option) {
+ getOptions().add(option);
+ }
+
+ public void setPatientSMS(NotificationConfigOption option) {
+ getOptions().add(option);
+ }
+
+ public void setProviderEmail(NotificationConfigOption option) {
+ getOptions().add(option);
+ }
+
+ public void setProviderSMS(NotificationConfigOption option) {
+ getOptions().add(option);
+ }
}