Skip to content

Commit

Permalink
Merge branch 'develop' into issue#7286
Browse files Browse the repository at this point in the history
  • Loading branch information
aeswibon authored Mar 26, 2024
2 parents a2304d3 + a27fe83 commit 26d43a2
Show file tree
Hide file tree
Showing 116 changed files with 720 additions and 422 deletions.
94 changes: 94 additions & 0 deletions plugins/treeShakeCareIcons.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { Plugin } from "vite";
import * as fs from "fs";
import * as path from "path";
import * as glob from "glob";

/**
* Interface defining options for the treeShakeUniconPathsPlugin.
*
* @interface TreeShakeUniconPathsPluginOptions
* @property {string[]} iconWhitelist - An array of icon names to always include, even if not found in code.
*/

export interface TreeShakeCareIconsOptions {
iconWhitelist: string[];
}

/**
* Creates a Webpack plugin that tree-shakes unused Unicon paths from UniconPaths.json in production builds.
*
* @param {TreeShakeCareIconsOptions} [options] - Optional configuration options. Defaults to an empty iconWhitelist.
* @returns {Plugin} Webpack plugin object.
*/

export function treeShakeCareIcons(
options: TreeShakeCareIconsOptions = { iconWhitelist: [] }
): Plugin {
const rootDir = path.resolve(__dirname, ".."); // update this if moving this code to a different file
const lineIconNameRegex = /"l-[a-z]+(?:-[a-z]+)*"/g;
const allUniconPaths = JSON.parse(
fs.readFileSync(
path.resolve(rootDir, "src/CAREUI/icons/UniconPaths.json"),
"utf8"
)
);

// Extracts icon names from a given file's content.
// Returns an array of icon names like ["l-eye", "l-sync", "l-hearbeat"]
function extractCareIconNames(file: string): string[] {
const fileContent = fs.readFileSync(file, "utf8");

const lineIconNameMatches = fileContent.match(lineIconNameRegex) || [];

const lineIconNames = lineIconNameMatches.map(
(lineIconName) => lineIconName.slice(1, -1) // remove quotes
);

return lineIconNames;
}
// Finds all used icon names within the project's source files (`.tsx` or `.res` extensions).
function getAllUsedIconNames() {
const files = glob.sync(path.resolve(rootDir, "src/**/*.{tsx,res}"));
const usedIconsArray: string[] = [];

files.forEach((file) => {
const iconNames = extractCareIconNames(file);
usedIconsArray.push(...iconNames);
});

return new Set(usedIconsArray);
}
// Generates a map of used icon names to their paths from UniconPaths.json, including any whitelisted icons.
function getTreeShakenUniconPaths() {
const usedIcons = [...getAllUsedIconNames(), ...options.iconWhitelist];
const treeshakenCareIconPaths = {};

for (const iconName of usedIcons) {
const path = allUniconPaths[iconName];
if (path === undefined) {
throw new Error(`Icon ${iconName} is not found in UniconPaths.json`);
} else {
treeshakenCareIconPaths[iconName] = path;
}
}

return treeshakenCareIconPaths;
}

return {
name: "tree-shake-care-icons",
transform(_src, id) {
if (process.env.NODE_ENV !== "production") {
return;
}

// Replace the UniconPaths with the tree-shaken version
if (id.endsWith("UniconPaths.json")) {
return {
code: `export default ${JSON.stringify(getTreeShakenUniconPaths())}`,
map: null,
};
}
},
};
}
4 changes: 2 additions & 2 deletions src/CAREUI/display/RecordMeta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const RecordMeta = ({
{user && !inlineUser && (
<span className="flex items-center gap-1">
by
<CareIcon className="care-l-user" />
<CareIcon icon="l-user" />
{formatName(user)}
{isOnline && (
<div className="h-1.5 w-1.5 rounded-full bg-primary-400" />
Expand All @@ -61,7 +61,7 @@ const RecordMeta = ({
{prefix}
{child}
{user && inlineUser && <span>by</span>}
{user && !inlineUser && <CareIcon className="care-l-user" />}
{user && !inlineUser && <CareIcon icon="l-user" />}
{user && inlineUser && (
<span className="font-medium">{formatName(user)}</span>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/CAREUI/display/SubHeading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function SubHeading(props: Props) {
</span>
{props.lastModified && (
<div className="ml-3 flex flex-row gap-2 text-xs font-medium text-gray-600">
<CareIcon className="care-l-history-alt text-sm" />
<CareIcon icon="l-history-alt" className="text-sm" />
<RecordMeta time={props.lastModified} prefix="Last modified" />
</div>
)}
Expand Down
4 changes: 2 additions & 2 deletions src/CAREUI/icons/CareIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import iconData from "./UniconPaths.json";
export type IconName = keyof typeof iconData;

export interface CareIconProps {
icon?: IconName;
icon: IconName;
className?: string | undefined;
onClick?: React.MouseEventHandler<HTMLSpanElement> | undefined;
id?: string;
Expand All @@ -16,7 +16,7 @@ export interface CareIconProps {
* ### CARE's Official Icon Library.
* @param className icon class name
* @returns icon component
* @example ```<CareIcon className="care-l-hospital" /> ```
* @example ```<CareIcon icon="l-hospital"/> ```
*
* @see [icon library](https://iconscout.com/unicons/)
*/
Expand Down
4 changes: 2 additions & 2 deletions src/CAREUI/interactive/FiltersSlideover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function FiltersSlideover({
onClick={onClear}
id="clear-filter"
>
<CareIcon className="care-l-filter-slash text-lg" />
<CareIcon icon="l-filter-slash" className="text-lg" />
<span>{t("clear")}</span>
</ButtonV2>
<ButtonV2 ghost onClick={onApply} id="apply-filter">
Expand All @@ -62,7 +62,7 @@ export const AdvancedFilterButton = ({ onClick }: { onClick: () => void }) => {
onClick={onClick}
id="advanced-filter"
>
<CareIcon className="care-l-filter" />
<CareIcon icon="l-filter" />
<span className="py-0.5">{t("advanced_filters")}</span>
</ButtonV2>
);
Expand Down
3 changes: 2 additions & 1 deletion src/CAREUI/interactive/LegendInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ export default function LegendInput(props: InputProps) {
onClick={() => setShowPassword(!showPassword)}
>
<CareIcon
className={`care-l-eye${showPassword ? "" : "-slash"} text-lg`}
icon={showPassword ? "l-eye" : "l-eye-slash"}
className="text-lg"
/>
</button>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/CAREUI/interactive/SlideOver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export default function SlideOver({
onCloseClick && onCloseClick();
}}
>
<CareIcon className="care-l-arrow-left" />
<CareIcon icon="l-arrow-left" />
</button>
<div className="flex w-full">
<h1 className="w-full text-xl font-black">{title}</h1>
Expand Down
2 changes: 1 addition & 1 deletion src/Common/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ export const GENDER: { [key: number]: string } = GENDER_TYPES.reduce(
);

export type CameraPTZ = {
icon?: string;
icon?: IconName;
label: string;
action: string;
loadingLabel?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/Common/hooks/useRangePagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const useRangePagination = ({ bounds, perPage, ...props }: Props) => {

useEffect(() => {
setCurrentRange(getInitialBounds(bounds, perPage, props.defaultEnd));
}, [bounds, perPage, props.defaultEnd]);
}, [JSON.stringify(bounds), perPage, props.defaultEnd]);

const next = () => {
const { end } = currentRange;
Expand Down
6 changes: 4 additions & 2 deletions src/Components/ABDM/ABHAProfileModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ const ABHAProfileModal = ({ patientId, show, onClose, abha }: IProps) => {
<div className="flex items-center gap-2">
<CareIcon
onClick={() => downloadAbhaCard("pdf")}
className="care-l-print cursor-pointer"
icon="l-print"
className="cursor-pointer"
/>
<CareIcon
onClick={() => downloadAbhaCard("png")}
className="care-l-import cursor-pointer"
icon="l-import"
className="cursor-pointer"
/>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/Components/ABDM/LinkABHANumberModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default function LinkABHANumberModal({

const title = (
<div className="flex items-center gap-3">
<CareIcon className="care-l-link text-xl" />
<CareIcon icon="l-link" className="text-xl" />
<h2 className="text-xl font-bold text-black">
{currentStep === "ScanExistingQR"
? "Link Existing ABHA Number"
Expand Down Expand Up @@ -752,7 +752,7 @@ const VerifyMobileSection = ({
/>
) : (
<p className="-mt-4 text-sm text-warning-600">
<CareIcon className="care-l-exclamation-triangle h-4 w-4" /> OTP is
<CareIcon icon="l-exclamation-triangle" className="h-4 w-4" /> OTP is
generated if the above phone number is not linked with given Aadhaar
number.
</p>
Expand Down Expand Up @@ -833,7 +833,7 @@ const CreateHealthIDSection = ({
/>

<p className="-mt-4 text-sm text-warning-600">
<CareIcon className="care-l-exclamation-triangle h-4 w-4" /> Existing
<CareIcon icon="l-exclamation-triangle" className="h-4 w-4" /> Existing
ABHA Address is used if ABHA Number already exists.
</p>

Expand Down
23 changes: 12 additions & 11 deletions src/Components/Assets/AssetManage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ const AssetManage = (props: AssetManageProps) => {
<div className="flex grow-0 flex-col md:w-[200px]">
<div className="flex-start flex items-center">
<div className="w-8">
<CareIcon className={`care-l-${item.icon} fill-gray-700 text-lg`} />
<CareIcon icon={item.icon} className="fill-gray-700 text-lg" />
</div>
<div className="break-words text-gray-700">{item.label}</div>
</div>
Expand Down Expand Up @@ -332,7 +332,7 @@ const AssetManage = (props: AssetManageProps) => {
ghost
border
>
<CareIcon className="care-l-export text-lg" />
<CareIcon icon="l-export" className="text-lg" />
Export as JSON
</ButtonV2>
}
Expand All @@ -357,7 +357,8 @@ const AssetManage = (props: AssetManageProps) => {
</span>
<div className="tooltip tooltip-bottom">
<CareIcon
className={`care-l-${assetClassProp.icon} fill-gray-700 text-3xl`}
icon={assetClassProp.icon}
className="fill-gray-700 text-3xl"
/>
<span className="tooltip-text">{assetClassProp.name}</span>
</div>
Expand Down Expand Up @@ -397,17 +398,17 @@ const AssetManage = (props: AssetManageProps) => {
{[
{
label: asset?.location_object.facility.name,
icon: "location-pin-alt",
icon: "l-location-pin-alt",
content: asset?.location_object.name,
},
{
label: "Asset QR Code ID",
icon: "qrcode-scan",
icon: "l-qrcode-scan",
content: asset?.qr_code_id,
},
{
label: "Not working reason",
icon: "exclamation-circle",
icon: "l-exclamation-circle",
content: asset?.not_working_reason,
hide: asset?.is_working,
},
Expand All @@ -425,7 +426,7 @@ const AssetManage = (props: AssetManageProps) => {
data-testid="asset-update-button"
authorizeFor={NonReadOnlyUsers}
>
<CareIcon className="care-l-pen mr-1 h-4" />
<CareIcon icon="l-pen" className="mr-1 h-4" />
{t("update")}
</ButtonV2>
{asset?.asset_class &&
Expand All @@ -442,7 +443,7 @@ const AssetManage = (props: AssetManageProps) => {
id="configure-asset"
data-testid="asset-configure-button"
>
<CareIcon className="care-l-setting h-4" />
<CareIcon icon="l-setting" className="h-4" />
{t("configure")}
</ButtonV2>
)}
Expand All @@ -454,7 +455,7 @@ const AssetManage = (props: AssetManageProps) => {
data-testid="asset-delete-button"
className="inline-flex"
>
<CareIcon className="care-l-trash h-4" />
<CareIcon icon="l-trash" className="h-4" />
<span className="md:hidden">{t("delete")}</span>
</ButtonV2>
)}
Expand All @@ -467,14 +468,14 @@ const AssetManage = (props: AssetManageProps) => {
{[
{
label: "Last serviced on",
icon: "wrench",
icon: "l-wrench",
content:
asset?.last_service?.serviced_on &&
formatDate(asset?.last_service?.serviced_on),
},
{
label: "Notes",
icon: "notes",
icon: "l-notes",
content: asset?.last_service?.note,
},
].map(detailBlock)}
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Assets/AssetType/HL7Monitor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const HL7Monitor = (props: HL7MonitorProps) => {
error={ipadrdress_error}
/>
<Submit className="w-full">
<CareIcon className="care-l-save" />
<CareIcon icon="l-save" />
<span>Save Configuration</span>
</Submit>
</div>
Expand Down
17 changes: 12 additions & 5 deletions src/Components/Assets/AssetTypes.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { IconName } from "../../CAREUI/icons/CareIcon";
import { BedModel } from "../Facility/models";
import { PerformedByModel } from "../HCX/misc";
import { PatientModel } from "../Patient/models";
Expand Down Expand Up @@ -42,25 +43,31 @@ export const AssetStatus = {
maintenance: "Under Maintenance",
};

export const assetClassProps = {
export const assetClassProps: {
[key in AssetClass]: {
name: string;
description?: string;
icon: IconName;
};
} = {
ONVIF: {
name: "ONVIF Camera",
description: "",
icon: "camera",
icon: "l-camera",
},
HL7MONITOR: {
name: "HL7 Vitals Monitor",
description: "",
icon: "monitor-heart-rate",
icon: "l-monitor-heart-rate",
},
VENTILATOR: {
name: "Ventilator",
description: "",
icon: "lungs",
icon: "l-lungs",
},
NONE: {
name: "N/A",
icon: "box",
icon: "l-box",
},
};

Expand Down
Loading

0 comments on commit 26d43a2

Please sign in to comment.