Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creation of bed type, bed tag #15

Merged
merged 1 commit into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/bed-administration/bed-administration-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,11 @@ export interface BedAdministrationData {
occupancyStatus: string;
bedType: string;
}
export interface BedTypeDataAdministration {
name: string;
displayName: string;
description: string;
}
export interface BedTagDataAdministration {
name: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ const ActivePatientsTable: React.FC<ActiveVisitsTableProps> = ({
session?.sessionLocation?.uuid,
status
);

const handleBedAssigmentModal = useCallback(
(entry) => {
setSelectedPatientDetails({
Expand Down
3 changes: 1 addition & 2 deletions src/bed-admission/bed-admission-tabs.component.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Tab, TabList, TabPanel, TabPanels, Tabs } from "@carbon/react";
import { Tab, TabList, TabPanel, TabPanels, Tabs, Button } from "@carbon/react";

Check warning on line 1 in src/bed-admission/bed-admission-tabs.component.tsx

View workflow job for this annotation

GitHub Actions / build

'Button' is defined but never used
import React, { useState } from "react";
import styles from "./bed-admission-tabs-styles.scss";
import { useTranslation } from "react-i18next";
Expand All @@ -12,7 +12,6 @@
const [admittedCount, setAdmittedCount] = useState(0);
const [toAdmitCount, setToAdmitCount] = useState(0);
const [toDischargeCount, setToDischargeCount] = useState(0);

return (
<>
<div className={styles.cardContainer}>
Expand Down
217 changes: 217 additions & 0 deletions src/bed-admission/bed-tag/bed-tag-administration-table.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import React, { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import {
Button,
DataTable,
DataTableSkeleton,
InlineLoading,
Pagination,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableHeader,
TableRow,
Tile,
} from "@carbon/react";
import { Add, Edit } from "@carbon/react/icons";
import {
isDesktop as desktopLayout,
useLayoutType,
} from "@openmrs/esm-framework";
import { CardHeader, ErrorState } from "@openmrs/esm-patient-common-lib";
import type { BedTagData } from "../../types";
import { useBedTag } from "../../summary/summary.resource";
import Header from "../../header/header.component";
import styles from "../../bed-administration/bed-administration-table.scss";
import BedTagForm from "./new-tag-form.component";
import EditBedTagForm from "./edit-tag-form.component";

const BedTagAdministrationTable: React.FC = () => {
const { t } = useTranslation();
const headerTitle = t("bedTag", "Bed Tag");
const layout = useLayoutType();
const isTablet = layout === "tablet";
const responsiveSize = isTablet ? "lg" : "sm";
const isDesktop = desktopLayout(layout);
const [isBedDataLoading] = useState(false);
const [showBedTagsModal, setAddBedTagsModal] = useState(false);
const [showEditBedModal, setShowEditBedModal] = useState(false);
const [editData, setEditData] = useState<BedTagData>();
const [currentPage, setCurrentPage] = useState(1);
const [pageSize] = useState(10);
const { bedTypeData, isError, loading, validate, mutate } = useBedTag();
const [currentPageSize, setPageSize] = useState(10);

Check warning on line 45 in src/bed-admission/bed-tag/bed-tag-administration-table.component.tsx

View workflow job for this annotation

GitHub Actions / build

'currentPageSize' is assigned a value but never used
const pageSizes = [10, 20, 30, 40, 50];

Check warning on line 46 in src/bed-admission/bed-tag/bed-tag-administration-table.component.tsx

View workflow job for this annotation

GitHub Actions / build

'pageSizes' is assigned a value but never used

const tableHeaders = [
{
header: t("ids", "Id"),
key: "ids",
},
{
header: t("name", "Name"),
key: "name",
},
{
header: t("actions", "Actions"),
key: "actions",
},
];

const tableRows = useMemo(() => {
return bedTypeData?.map((entry) => ({
id: entry.uuid,
ids: entry.id,
name: entry?.name,
actions: (
<>
<Button
enterDelayMs={300}
renderIcon={Edit}
onClick={(e) => {
e.preventDefault();
setEditData(entry);
setShowEditBedModal(true);
setAddBedTagsModal(false);
}}
kind={"ghost"}
iconDescription={t("editBedTag", "Edit Bed Tag")}
hasIconOnly
size={responsiveSize}
tooltipAlignment="start"
/>
</>
),
}));
}, [responsiveSize, bedTypeData, t]);

if (isBedDataLoading || loading) {
return (
<>
<Header route="Bed Tag" />
<div className={styles.widgetCard}>
<DataTableSkeleton role="progressbar" compact={isDesktop} zebra />
</div>
</>
);
}

if (isError) {
return (
<>
<Header route="Bed Tag" />
<div className={styles.widgetCard}>
<ErrorState error={isError} headerTitle={headerTitle} />
</div>
</>
);
}

return (
<>
<Header route="Bed Tag" />

<div className={styles.widgetCard}>
{showBedTagsModal ? (
<BedTagForm
onModalChange={setAddBedTagsModal}
showModal={showBedTagsModal}
mutate={mutate}
/>
) : null}
{showEditBedModal ? (
<EditBedTagForm
onModalChange={setShowEditBedModal}
showModal={showEditBedModal}
editData={editData}
mutate={mutate}
/>
) : null}
<CardHeader title={headerTitle}>
<span className={styles.backgroundDataFetchingIndicator}>
<span>{validate ? <InlineLoading /> : null}</span>
</span>
{bedTypeData?.length ? (
<Button
kind="ghost"
renderIcon={(props) => <Add size={16} {...props} />}
onClick={() => setAddBedTagsModal(true)}
>
{t("addBedTag", "Add Bed Tag")}
</Button>
) : null}
</CardHeader>
<DataTable
rows={tableRows}
headers={tableHeaders}
isSortable
size={isTablet ? "lg" : "sm"}
useZebraStyles
>
{({ rows, headers, getTableProps }) => (
<TableContainer>
<Table {...getTableProps()}>
<TableHead>
<TableRow>
{headers.map((header) => (
<TableHeader>
{header.header?.content ?? header.header}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key={row.id}>
{row.cells.map((cell) => (
<TableCell key={cell.id}>
{cell.value?.content ?? cell.value}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
{rows.length === 0 ? (
<div className={styles.tileContainer}>
<Tile className={styles.tile}>
<div className={styles.tileContent}>
<p className={styles.content}>
{t("No data", "No data to display")}
</p>
<p className={styles.helper}>
{t("checkFilters", "Check the filters above")}
</p>
</div>
<p className={styles.separator}>{t("or", "or")}</p>
<Button
kind="ghost"
size="sm"
renderIcon={(props) => <Add size={16} {...props} />}
onClick={() => setAddBedTagsModal(true)}
>
{t("bedTag", "Add Bed Tag")}
</Button>
</Tile>
</div>
) : null}
<Pagination
page={currentPage}
pageSize={pageSize}
pageSizes={[10, 20, 30, 40, 50]}
totalItems={bedTypeData.length}
onChange={({ page, pageSize }) => {
setCurrentPage(page);
setPageSize(pageSize);
}}
/>
</TableContainer>
)}
</DataTable>
</div>
</>
);
};
export default BedTagAdministrationTable;
131 changes: 131 additions & 0 deletions src/bed-admission/bed-tag/bed-tags-admin-form.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import React, { useState } from "react";
import { z } from "zod";
import { useForm, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import {
Button,
ComposedModal,
Form,
FormGroup,
ModalBody,
ModalFooter,
ModalHeader,
Stack,
TextInput,
InlineNotification,
} from "@carbon/react";
import { useTranslation } from "react-i18next";
import { Location } from "@openmrs/esm-framework";
import type { BedTagData } from "../../types";

const BedTagAdministrationSchema = z.object({
name: z.string().max(255),
});

interface BedTagAdministrationFormProps {
showModal: boolean;
onModalChange: (showModal: boolean) => void;
availableBedTypes: Array<BedTagData>;
allLocations: Location[];
handleCreateQuestion?: (formData: BedTagData) => void;
handleDeleteBedTag?: () => void;
headerTitle: string;
initialData: BedTagData;
}

interface ErrorType {
message: string;
}

const BedTagsAdministrationForm: React.FC<BedTagAdministrationFormProps> = ({
showModal,
onModalChange,
handleCreateQuestion,
headerTitle,
initialData,
}) => {
const { t } = useTranslation();

const [showErrorNotification, setShowErrorNotification] = useState(false);
const [formStateError, setFormStateError] = useState("");

const {
handleSubmit,
control,
formState: { isDirty },
} = useForm<BedTagData>({
mode: "all",
resolver: zodResolver(BedTagAdministrationSchema),
defaultValues: {
name: initialData.name || "",
},
});

const onSubmit = (formData: BedTagData) => {
const result = BedTagAdministrationSchema.safeParse(formData);
if (result.success) {
setShowErrorNotification(false);
handleCreateQuestion(formData);
}
};

const onError = (error: { [key: string]: ErrorType }) => {
setFormStateError(Object.entries(error)[0][1].message);
setShowErrorNotification(true);
};

return (
<ComposedModal
open={showModal}
onClose={() => onModalChange(false)}
preventCloseOnClickOutside
>
<ModalHeader title={headerTitle} />
<Form onSubmit={handleSubmit(onSubmit, onError)}>
<ModalBody hasScrollingContent>
<Stack gap={3}>
<FormGroup legendText={""}>
<Controller
name="name"
control={control}
render={({ field, fieldState }) => (
<>
<TextInput
id="bedTag"
labelText={t("bedTag", "Bed Tag Name")}
placeholder={t("bedTagPlaceholder", "")}
invalidText={fieldState.error?.message}
{...field}
/>
</>
)}
/>
</FormGroup>

{showErrorNotification && (
<InlineNotification
lowContrast
title={t("error", "Error")}
style={{ minWidth: "100%", margin: "0rem", padding: "0rem" }}
role="alert"
kind="error"
subtitle={t("pleaseFillField", formStateError) + "."}
onClose={() => setShowErrorNotification(false)}
/>
)}
</Stack>
</ModalBody>
<ModalFooter>
<Button onClick={() => onModalChange(false)} kind="secondary">
{t("cancel", "Cancel")}
</Button>
<Button disabled={!isDirty} type="submit">
<span>{t("save", "Save")}</span>
</Button>
</ModalFooter>
</Form>
</ComposedModal>
);
};

export default BedTagsAdministrationForm;
Loading
Loading