Skip to content

Commit

Permalink
Merge pull request #136 from Samstar10/feat/message-dashboard
Browse files Browse the repository at this point in the history
Feat/message dashboard
  • Loading branch information
Michaelndula authored Feb 18, 2025
2 parents b5c0e91 + 2a332f2 commit 1cacd3d
Show file tree
Hide file tree
Showing 12 changed files with 366 additions and 85 deletions.
4 changes: 2 additions & 2 deletions packages/esm-messages-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ehospital/esm-messages-app",
"version": "1.0.5",
"version": "1.0.7",
"description": "Patient flags microfrontend for the OpenMRS SPA",
"browser": "dist/ehospital-esm-patient-flags-app.js",
"main": "src/index.ts",
Expand Down Expand Up @@ -51,5 +51,5 @@
"@openmrs/esm-patient-common-lib": "next",
"webpack": "^5.74.0"
},
"gitHead": "29e926ce1a1c39bd6f38af7950c5a4d8e010658a"
"gitHead": "08b0218499452455453b6985a96be728b2d222a2"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from "react";

const EmptyStateIllustration = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
xmlSpace="preserve"
width={100}
height={100}
viewBox="0 0 2048 2048"
style={{
shapeRendering: "geometricPrecision",
textRendering: "geometricPrecision",
imageRendering: "optimizeQuality",
fillRule: "evenodd",
clipRule: "evenodd",
}}
{...props}
>
<defs>
<style>
{".fil0,.fil1{fill:#858585;fill-rule:nonzero}.fil1{fill:#858585}"}
</style>
</defs>
<g id="Layer_x0020_1">
<path
className="fil0"
d="M303.999 914.955v519.372h192.142c13.254 0 24 10.746 24 24 0 3.452-.73 6.736-2.043 9.702l-73.93 222.526 279.187-250.032-.065-.074a23.905 23.905 0 0 1 16.01-6.119v-.002h597.409V914.956H303.999zm-48 543.372V890.955c0-13.254 10.746-24 24-24h1080.71c13.254 0 24 10.746 24 24v567.372c0 13.254-10.746 24-24 24h-612.38L410.76 1784.646c-6.202 6.685-15.96 9.524-25.178 6.462-12.578-4.179-19.387-17.765-15.209-30.344l.1.033 92.515-278.47h-182.99c-13.254 0-24-10.746-24-24z"
/>
<path
className="fil1"
d="M403.029 1042.03h834.651v48H403.029zM403.029 1265.49h834.651v48H403.029z"
/>
<path
className="fil0"
d="M1792 279.668v489.833c0 13.254-10.746 24-24 24h-153.45l78.44 236.105.099-.033c4.177 12.579-2.632 26.165-15.21 30.342-9.218 3.062-18.976.224-25.177-6.461L1362.441 793.5H834.985c-13.254 0-24-10.746-24-24V279.668c0-13.255 10.746-24 24-24H1768c13.254 0 24 10.745 24 24zm-48 465.833V303.668H858.985v441.833h512.484v.002a23.905 23.905 0 0 1 16.011 6.12l-.065.073 231.878 207.666-59.852-180.161a23.898 23.898 0 0 1-2.044-9.7c0-13.255 10.746-24 24-24H1744z"
/>
<path
className="fil1"
d="M1661.78 454.819H941.2v-48h720.58zM1661.78 647.737H941.2v-48h720.58z"
/>
</g>
<path
style={{
fill: "none",
}}
d="M0 0h2048v2048H0z"
/>
</svg>
);
export default EmptyStateIllustration;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import styles from './empty-state.scss'
import EmptyStateIllustration from './empty-state-illustration.component';

const EmptyState = () => {
return (
<div className={styles.container}>
<div className={styles.content}>
<EmptyStateIllustration />
<p className={styles.text}>There are no messages to display</p>
</div>
</div>
)
}

export default EmptyState
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@use '@carbon/styles/scss/spacing';
@use '@carbon/colors';
@use '@carbon/styles/scss/type';
@import '~@openmrs/esm-styleguide/src/vars';

.container {
padding: 0 spacing.$spacing-05;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid $ui-03;
}

.content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.text {
@include type.type-style('body-compact-02');
font-weight: 600;
color: $text-02;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react";
import styles from "./full-message.scss";

interface FullMessageProps {
message: string;
timestamp: string;
}

const FullMessageComponent: React.FC<FullMessageProps> = ({ message, timestamp }) => {
return (
<div className={styles.container}>
<h4 className={styles.title}>Message Details</h4>
<p className={styles.text}><span className={styles.bold}>Sent on</span>: {timestamp}</p>
<p className={styles.text}><span className={styles.bold}>Message</span>: {message || "No message available"}</p>
</div>
)
};

export default FullMessageComponent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@use '@carbon/styles/scss/spacing';
@use '@carbon/colors';
@use '@carbon/styles/scss/type';
@import '~@openmrs/esm-styleguide/src/vars';

.container {
background-color: $ui-03;
padding: spacing.$spacing-05;
}

.title {
@include type.type-style('body-compact-02');
color: $text-02;
margin-bottom: spacing.$spacing-03;
}

.text {
@include type.type-style('body-01');
color: $text-02;
display: flex;
gap: spacing.$spacing-03;
}

.bold {
font-weight: bold;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { usePatient } from '@openmrs/esm-framework';
import React from 'react';

const PatientName: React.FC<{ uuid: string }> = ({ uuid }) => {
const { patient } = usePatient(uuid);

return <>{patient?.name || 'Loading...'}</>;
};

export default PatientName;
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import {
TableCell,
TableExpandedRow,
Button,
Tag
} from "@carbon/react";
import { Renew } from "@carbon/react/icons";
import FullMessageComponent from "./full-message/full-message.component";

export interface TableHeaderItem {
key: string;
Expand All @@ -36,11 +38,20 @@ const CustomDataTable: FC<CustomDataTableProps> = ({
rows,
onResend,
}) => {
const handleRowClick = (rowId: string) => {
if (onResend) {
onResend(rowId);

function getTagType(status: string): string {
switch (status?.toLowerCase()) {
case "sent":
return "green";
case "failed":
return "red";
case "scheduled":
return "#ffbff00";
default:
return "gray";
}
};
}


return (
<DataTable rows={rows} headers={headers}>
Expand All @@ -55,39 +66,46 @@ const CustomDataTable: FC<CustomDataTableProps> = ({
}) => (
<TableContainer {...getTableContainerProps()}>
<Table {...getTableProps()}>
<TableHead>
<TableRow>
<TableExpandHeader />
{headers.map((header) => (
<TableHeader
key={header.key}
{...getHeaderProps({ header })}
>
<TableHead>
<TableRow>
<TableExpandHeader />
{headers
.filter((header) => header.key !== "fullMessage" && header.key !== "sentTimestamp" && header.key !== "patientUuid") // Hide the column
.map((header) => (
<TableHeader key={header.key} {...getHeaderProps({ header })}>
{header.header}
</TableHeader>
))}
</TableRow>
</TableHead>
</TableRow>
</TableHead>

<TableBody>
{rows.map((row) => {
const statusCell = row.cells.find(
(cell) => cell.info.header === "status"
);
const messageCell = row.cells.find(
(cell) => cell.info.header === "fullMessage"
);
const timeStampCell = row.cells.find(
(cell) => cell.info.header === "sentTimestamp"
);
const patientUuidCell = row.cells.find(
(cell) => cell.info.header === "patientUuid"
);

const rowStatus = statusCell?.value;

return (
<React.Fragment key={row.id}>
<TableExpandRow
{...getRowProps({ row })}
onClick={() => handleRowClick(row.id)}
>
{row.cells.map((cell) => {
if (cell.info.header === "action") {
return (
<TableCell key={cell.id}>
{rowStatus === "failed" && (
{rowStatus === "FAILED" && (
<Button
kind="danger--tertiary"
renderIcon = {Renew}
Expand All @@ -96,14 +114,34 @@ const CustomDataTable: FC<CustomDataTableProps> = ({
iconDescription="Resend message"
onClick={(e) => {
e.stopPropagation();
onResend?.(row.id);
onResend?.(patientUuidCell?.value);
}}
/>
)}
</TableCell>
);
}

if (cell.info.header === "status") {
return (
<TableCell key={cell.id}>
<Tag type={getTagType(cell.value)}>{cell.value}</Tag>
</TableCell>
);
}

if (cell.info.header === "fullMessage") {
return null;
}

if (cell.info.header === "sentTimestamp") {
return null;
}

if (cell.info.header === "patientUuid") {
return null;
}

return <TableCell key={cell.id}>{cell.value}</TableCell>;
})}
</TableExpandRow>
Expand All @@ -114,7 +152,7 @@ const CustomDataTable: FC<CustomDataTableProps> = ({
className="demo-expanded-td"
{...getExpandedRowProps({ row })}
>
<p>Expanded data goes here...</p>
<FullMessageComponent message={messageCell?.value} timestamp={timeStampCell?.value} />
</TableExpandedRow>
)}
</React.Fragment>
Expand Down
6 changes: 6 additions & 0 deletions packages/esm-messages-app/src/helpers/truncate-message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const truncateMessage = (message: string, wordLimit: number) => {
const words = message.split(" ");
return words.length > wordLimit
? `${words.slice(0, wordLimit).join(" ")}...`
: message;
};
Loading

0 comments on commit 1cacd3d

Please sign in to comment.