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

fix : fix app menu bug #8

Merged
merged 6 commits into from
Mar 4, 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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"main": "src/index.ts",
"source": true,
"scripts": {
"start": "openmrs develop --backend http://167.71.32.250:8080",
"start": "openmrs develop --backend http://194.163.171.253:8282",
"serve": "webpack serve --mode=development",
"build": "webpack --mode production",
"analyze": "webpack --mode=production --env analyze=true",
Expand Down
129 changes: 47 additions & 82 deletions src/components/app-search-bar/app-search-bar.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,13 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { Search } from "@carbon/react";
import styles from "./app-search-bar.scss";
import MenuItems from "../../menu/menu.component";
import {
Analytics,
AnalyticsCustom,
Db2DataSharingGroup,
DocumentAdd,
DocumentImport,
Events,
VolumeFileStorage,
HospitalBed,
Medication,
User,
Report,
UserActivity,
Grid,
} from "@carbon/react/icons";

import {
AssignedExtension,
ExtensionSlot,
attach,
detachAll,
Extension,
useConnectedExtensions,
} from "@openmrs/esm-framework";
import { ComponentContext } from "@openmrs/esm-framework/src/internal";

const appMenuItemSlot = "app-menu-item-slot";

Expand All @@ -41,100 +25,81 @@ const AppSearchBar = React.forwardRef<
>(({ onChange, onClear, onSubmit, small }, ref) => {
const { t } = useTranslation();

// State for item extensions
const [derivedSlots, setDerivedSlots] = useState<
{ slot: string; extension: string; name: string }[]
>([]);

// State for search term and filtered items
const [derivedSlots, setDerivedSlots] = useState<any>([]);
const [searchTerm, setSearchTerm] = useState("");
const [items, setItems] = useState(derivedSlots);

// Fetch item extensions
const menuItemExtensions = useConnectedExtensions(
appMenuItemSlot
) as AssignedExtension[];

// UseEffect for processing item extensions and attaching/detaching slots
useEffect(() => {
// Filter and process extensions
const filteredExtensions = menuItemExtensions
.filter((extension) => Object.keys(extension).length > 0)
.map((extension, index) => ({
slot: `${appMenuItemSlot}-${index}`,
extension: extension.name,
name: extension.meta.name,
}));
.map((extension) => (
<ComponentContext.Provider
key={extension?.id}
value={{
moduleName: extension?.moduleName,
extension: {
extensionId: extension?.id,
extensionSlotName: appMenuItemSlot,
extensionSlotModuleName: extension?.moduleName,
},
}}
>
<Extension />
</ComponentContext.Provider>
));
setDerivedSlots(filteredExtensions);

// Attach/detach slots
filteredExtensions.forEach(({ slot, extension }) => {
attach(slot, extension);
});

return () => {
filteredExtensions.forEach(({ slot }) => {
detachAll(slot);
});
};
}, [menuItemExtensions]);

// UseEffect for updating items based on derivedSlots
useEffect(() => {
setItems(derivedSlots);
}, [derivedSlots]);

// UseMemo for rendering ExtensionSlots
const extraPanels = useMemo(() => {
return items.map(({ slot }) => <ExtensionSlot key={slot} name={slot} />);
}, [items]);

// Callback for handling search term changes
const handleChange = useCallback(
(val) => {
if (typeof onChange === "function") {
onChange(val);
}
setSearchTerm(val);

// Filter items based on the search term
const filteredItems = derivedSlots.filter((item) =>
item.name.toLowerCase().includes(val.toLowerCase())
const filteredItems = derivedSlots?.filter((item) =>
item?.name?.toLowerCase().includes(val?.toLowerCase())
);
setItems(filteredItems);
setDerivedSlots(filteredItems);
},
[derivedSlots, onChange]
);

// Handle form submission
const handleSubmit = (evt) => {
evt.preventDefault();
onSubmit(searchTerm);
};

return (
<>
<form onSubmit={handleSubmit} className={styles.searchArea}>
{/* Search component */}
<Search
autoFocus
className={styles.appSearchInput}
closeButtonLabelText={t("clearSearch", "Clear")}
labelText=""
onChange={(event) => handleChange(event.target.value)}
onClear={onClear}
placeholder={t(
"searchForApp",
"Search for an application or module by name"
)}
size={small ? "sm" : "lg"}
value={searchTerm}
ref={ref}
data-testid="appSearchBar"
/>
</form>
{/* Render ExtensionSlots */}
<div className={styles.searchItems}>{extraPanels}</div>
{derivedSlots.length >= 0 ? (
<>
<form onSubmit={handleSubmit} className={styles.searchArea}>
<Search
autoFocus
className={styles.appSearchInput}
closeButtonLabelText={t("clearSearch", "Clear")}
labelText=""
onChange={(event) => handleChange(event?.target?.value)}
onClear={onClear}
placeholder={t(
"searchForApp",
"Search for an application or module by name"
)}
size={small ? "sm" : "lg"}
value={searchTerm}
ref={ref}
data-testid="appSearchBar"
/>
</form>
<div className={styles.searchItems}>{derivedSlots}</div>
</>
) : (
<div className={styles.searchItems}>Loading modules...</div>
)}
</>
);
});
Expand Down
19 changes: 0 additions & 19 deletions src/menu/item/item.component.tsx

This file was deleted.

Empty file removed src/menu/item/item.resource.ts
Empty file.
17 changes: 0 additions & 17 deletions src/menu/item/item.scss

This file was deleted.

19 changes: 0 additions & 19 deletions src/menu/menu.component.tsx

This file was deleted.

Empty file removed src/menu/menu.scss
Empty file.
Empty file removed src/menu/menus.resource.ts
Empty file.
Loading