Skip to content

Commit

Permalink
Merge branch 'develop' into feature/OH2-287-admin-user-group-crud
Browse files Browse the repository at this point in the history
  • Loading branch information
gasp committed Oct 15, 2024
2 parents be0566b + 1e4b29b commit 7e394b6
Show file tree
Hide file tree
Showing 146 changed files with 2,394 additions and 1,227 deletions.
800 changes: 754 additions & 46 deletions api/oh.yaml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe("Add Ward Activity specs", () => {
});

it("should fail to create a new ward", () => {
cy.byId("code").type("FAIL");
cy.byId("code").type("FL");
cy.byId("description").type("Children ward");
cy.byId("email").type("[email protected]");
cy.byId("telephone").type("698123234");
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ services:
environment: *mariadb-env
ports:
- "3306:3306"
command: mysqld --sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" --lower_case_table_names=1
command: mysqld --sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" --lower_case_table_names=1 --explicit_defaults_for_timestamp=OFF
networks:
- openhospital

Expand Down
211 changes: 146 additions & 65 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@date-io/date-fns": "^1.3.13",
"@emotion/react": "^11.13.0",
"@emotion/styled": "^11.13.0",
Expand Down
3 changes: 1 addition & 2 deletions src/components/Private.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React from "react";
import { Navigate, Outlet, useLocation } from "react-router-dom";
import { Navigate, Outlet } from "react-router-dom";
import { PATHS } from "../consts";
import { isAuthenticated } from "../libraries/authUtils/isAuthenticated";
import { useAuthentication } from "../libraries/authUtils/useAuthentication";

export const Private = () => {
useAuthentication();
const { pathname } = useLocation();

return isAuthenticated() ? <Outlet /> : <Navigate to={PATHS.login} replace />;
};
13 changes: 5 additions & 8 deletions src/components/accessories/admin/diseases/Diseases.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,11 @@ export const Diseases = () => {
});
};

const handleViewChange = useCallback(
(event: any, value: any) => {
if (!isEmpty(value)) {
setView(value);
}
},
[view]
);
const handleViewChange = useCallback((event: any, value: any) => {
if (!isEmpty(value)) {
setView(value);
}
}, []);

const predicate = useCallback(
(disease: DiseaseDTO) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const ExamsTable = ({ onDelete, onEdit, headerActions }: IOwnProps) => {

const filters: TFilterField[] = [
{
key: "type",
key: "examtype",
label: t("exam.examtype"),
type: "select",
options: examTypesOptions,
Expand Down Expand Up @@ -124,7 +124,10 @@ export const ExamsTable = ({ onDelete, onEdit, headerActions }: IOwnProps) => {
onDelete={onDelete}
headerActions={headerActions}
filterColumns={filters}
rawData={data ?? []}
rawData={(data ?? []).map((exam) => ({
...exam,
examtype: exam.examtype?.code,
}))}
manualFilter={false}
rowKey="code"
/>
Expand Down
2 changes: 2 additions & 0 deletions src/components/accessories/admin/operations/Operations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useAppDispatch } from "libraries/hooks/redux";
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router";
import { getOperationTypes } from "state/types/operations";
import { PATHS } from "../../../../consts";
import { OperationDTO } from "../../../../generated";
import {
Expand All @@ -20,6 +21,7 @@ export const Operations = () => {

useEffect(() => {
dispatch(getOperations());
dispatch(getOperationTypes());

return () => {
dispatch(deleteOperationReset());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const EditSupplier = () => {
if (state?.supId !== Number(id)) {
navigate(PATHS.admin_suppliers);
}
}, [id, state]);
}, [id, navigate, state]);

return (
<SupplierForm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ import TextField from "../../../textField/TextField";
import "./styles.scss";
import { ISupplierFormProps } from "./types";

const FORMAT = /^([0-9]{3})?[0-9]{2,10}$/;

const SupplierForm: FC<ISupplierFormProps> = ({
fields,
onSubmit,
Expand Down
10 changes: 7 additions & 3 deletions src/components/accessories/admin/types/TypesAdmin.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useAppSelector } from "libraries/hooks/redux";
import { sortBy } from "lodash";
import React, { useEffect, useState } from "react";
import React, { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { Outlet, useLocation, useNavigate } from "react-router";
import { PATHS } from "../../../../consts";
Expand All @@ -16,7 +16,11 @@ const TypesAdmin = () => {
const { t } = useTranslation();
const location = useLocation();
const navigate = useNavigate();
const defaultTypeOption: TypeOption = { label: "", value: "" };
const defaultTypeOption: TypeOption = useMemo(
() => ({ label: "", value: "" }),
[]
);

const [selectedOption, setSelectedOption] =
useState<TypeOption>(defaultTypeOption);
const mode = useAppSelector((state) => state.types.config.mode);
Expand Down Expand Up @@ -57,7 +61,7 @@ const TypesAdmin = () => {
setSelectedOption(defaultTypeOption);
}
}
}, [location]);
}, [defaultTypeOption, location, typeOptions]);

const handleTypeChange = (value: string) => {
if (value?.length > 0) {
Expand Down
20 changes: 19 additions & 1 deletion src/components/accessories/admin/users/usersTable/UsersTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import InfoBox from "../../../infoBox/InfoBox";
import Table from "../../../table/Table";
import { TFilterField } from "../../../table/filter/types";

import { getUserGroups } from "state/usergroups";
import classes from "./UsersTable.module.scss";

interface IOwnProps {
Expand All @@ -21,6 +22,7 @@ export const UsersTable = ({ headerActions }: IOwnProps) => {

useEffect(() => {
dispatch(getUsers({}));
dispatch(getUserGroups());
}, [dispatch]);

const header = ["userName", "userGroupName", "desc"];
Expand All @@ -31,8 +33,21 @@ export const UsersTable = ({ headerActions }: IOwnProps) => {
desc: t("user.description"),
};
const order = ["userName", "userGroupName", "desc"];
const userGroupOptions = useAppSelector(
(state) =>
state.usergroups.groupList.data?.map((item) => ({
value: item.code ?? "",
label: item.desc ?? item.code ?? "",
})) ?? []
);

const filters: TFilterField[] = [
{
key: "userGroupName",
label: t("user.groups"),
type: "select",
options: userGroupOptions,
},
{ key: "userName", label: t("user.username"), type: "text" },
];

Expand Down Expand Up @@ -75,7 +90,10 @@ export const UsersTable = ({ headerActions }: IOwnProps) => {
filterColumns={filters}
manualFilter={false}
isCollapsabile={false}
rawData={data}
rawData={(data ?? []).map((user) => ({
...user,
userGroupName: user.userGroupName?.code,
}))}
rowKey="userName"
headerActions={headerActions}
/>
Expand Down
11 changes: 8 additions & 3 deletions src/components/accessories/admin/wards/wardForm/WardForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import React, {
} from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router";
import { FIELD_VALIDATION } from "types";
import { number, object, string } from "yup";
import checkIcon from "../../../../../assets/check-icon.png";
import warningIcon from "../../../../../assets/warning-icon.png";
Expand Down Expand Up @@ -49,8 +50,8 @@ const WardForm: FC<IWardProps> = ({
const errorMessage = useMemo(
() =>
(creationMode
? wardStore.create.error?.message
: wardStore.update.error?.message) ?? t("common.somethingwrong"),
? t(wardStore.create.error?.message)
: t(wardStore.update.error?.message)) ?? t("common.somethingwrong"),
[
creationMode,
t,
Expand All @@ -62,7 +63,9 @@ const WardForm: FC<IWardProps> = ({
const initialValues = getFromFields(fields, "value");

const validationSchema = object({
code: string().required(t("common.required")),
code: string()
.max(3, t("validations.maxLength", { max: 3 }))
.required(t("common.required")),
description: string().required(t("common.required")),
email: string().email(t("validations.email")),
beds: number().min(0, t("validations.min", { min: 0 })),
Expand Down Expand Up @@ -133,6 +136,7 @@ const WardForm: FC<IWardProps> = ({
onBlur={formik.handleBlur}
type="text"
disabled={isLoading || !creationMode}
required={FIELD_VALIDATION.REQUIRED}
/>
</div>
<div className="wardForm__item halfWidth">
Expand All @@ -145,6 +149,7 @@ const WardForm: FC<IWardProps> = ({
onBlur={formik.handleBlur}
type="text"
disabled={isLoading}
required={FIELD_VALIDATION.REQUIRED}
/>
</div>
</div>
Expand Down
11 changes: 9 additions & 2 deletions src/components/accessories/admin/wards/wardTable/WardTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next";
import checkIcon from "../../../../../assets/check-icon.png";
import { WardDTO } from "../../../../../generated";
import { scrollToElement } from "../../../../../libraries/uiUtils/scrollToElement";
import { deleteWardReset } from "../../../../../state/ward";
import { deleteWardReset, getWards } from "../../../../../state/ward";
import ConfirmationDialog from "../../../confirmationDialog/ConfirmationDialog";
import InfoBox from "../../../infoBox/InfoBox";
import { TFilterField } from "../../../table/filter/types";
Expand Down Expand Up @@ -72,7 +72,14 @@ export const WardTable: FunctionComponent<IOwnProps> = ({
if (deleteWard.status === "FAIL") {
scrollToElement(infoBoxRef.current);
}
}, [deleteWard.status]);

if (
deleteWard.status === "SUCCESS" ||
deleteWard.status === "SUCCESS_EMPTY"
) {
dispatch(getWards());
}
}, [deleteWard.status, dispatch]);

const formatDataToDisplay = (data: WardDTO[]) => {
return data.map((item) => {
Expand Down
6 changes: 3 additions & 3 deletions src/components/accessories/admission/PatientAdmission.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const PatientAdmission: FC = () => {
if (patientCode && creationMode) {
dispatch(getLastOpd(parseInt(id!!)));
}
}, [dispatch, patientCode, creationMode]);
}, [dispatch, patientCode, creationMode, id]);

const fields = useFields(admissionToEdit, lastOpd?.disease);

Expand Down Expand Up @@ -157,7 +157,7 @@ const PatientAdmission: FC = () => {
dispatch(getPatient(id!!));
dispatch(getCurrentAdmission(parseInt(id!!)));
}
}, [createStatus, updateStatus]);
}, [createStatus, dispatch, id, updateStatus]);

const resetFormCallback = () => {
setCreationMode(true);
Expand All @@ -173,7 +173,7 @@ const PatientAdmission: FC = () => {
return () => {
dispatch(getCurrentAdmissionReset());
};
}, [dispatch]);
}, [dispatch, id]);

const onEdit = (row: AdmissionDTO) => {
setAdmissionToEdit(row);
Expand Down
2 changes: 1 addition & 1 deletion src/components/accessories/appHeader/AppHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const AppHeader: FunctionComponent<IOwnProps> = ({ breadcrumbMap }) => {
);
useEffect(() => {
dispatch(getHospital());
}, [dispatch, getHospital]);
}, [dispatch]);

const hospital = useAppSelector(
(state) => state.hospital.getHospital.data
Expand Down
1 change: 0 additions & 1 deletion src/components/accessories/appHeader/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { TUserCredentials } from "../../../state/main/types";
import { TAPIResponseStatus } from "../../../state/types";

export type TBreadcrumbMap = Record<string, string>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import _ from "lodash";
import React, {
ChangeEvent,
FC,
Fragment,
useCallback,
useEffect,
useState,
Expand Down Expand Up @@ -76,6 +75,7 @@ const AutocompleteField: FC<IProps> = ({
}
};

// eslint-disable-next-line react-hooks/exhaustive-deps
const debounceUpdate = useCallback(
debounce((value: any) => {
setValue(value);
Expand Down Expand Up @@ -111,16 +111,6 @@ const AutocompleteField: FC<IProps> = ({
return option.label;
};

const isSelected = (option: DefaultOptionType, v: DefaultOptionType) => {
return option.value === v.value;
};

const rendOption = (props: any, option: DefaultOptionType | string) => {
return (
<Fragment>{typeof option === "string" ? option : option.label}</Fragment>
);
};

const filter = createFilterOptions<DefaultOptionType>({
limit: options_limit,
});
Expand Down
2 changes: 1 addition & 1 deletion src/components/accessories/billTable/BillTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const BillTable: FC<IBillTableProps> = ({ fields }) => {
dispatch(searchBills(filter));
break;
}
}, [filter]);
}, [dispatch, filter]);

const { setFieldValue, handleBlur } = formik;

Expand Down
4 changes: 2 additions & 2 deletions src/components/accessories/billrecords/BillRecords.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const BillRecords = () => {
dispatch(deleteBillReset());
dispatch(payBillReset());
dispatch(closeBillReset());
}, []);
}, [dispatch]);

useEffect(() => {
if (patient && patient.code) {
Expand Down Expand Up @@ -275,7 +275,7 @@ const BillRecords = () => {
}}
handleSecondaryButtonClick={() => ({})}
/>
<iframe id="ifmcontentstoprint"></iframe>
<iframe id="ifmcontentstoprint" title="ifmcontentstoprint"></iframe>
</div>
);
};
Expand Down
Loading

0 comments on commit 7e394b6

Please sign in to comment.