Skip to content

Commit

Permalink
(fix) Locale switcher should default to user's defaultLocale or the s…
Browse files Browse the repository at this point in the history
…ession locale (openmrs#783)

* Locale switcher should use the session value

* Passing locale from user panel slot

* Removed useEffect and changes should happen on input change

* Cleanup

* (improvement) using session locale as the truth value and setting defaultLocale in user properties on change

* (fix) Updated tests
  • Loading branch information
vasharma05 authored Oct 30, 2023
1 parent e18c5dd commit 51ceb5a
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@ import {
useConnectivity,
} from "@openmrs/esm-framework";
import {
PostSessionLocale,
PostUserProperties,
postUserPropertiesOnline,
postUserPropertiesOffline,
postSessionLocaleOnline,
postSessionLocaleOffline,
} from "./change-locale.resource";
import { useTranslation } from "react-i18next";

Expand All @@ -21,24 +18,18 @@ export interface ChangeLocaleProps {
user: LoggedInUser;
locale: string;
postUserProperties: PostUserProperties;
postSessionLocale: PostSessionLocale;
}

const ChangeLocaleWrapper: React.FC<
Pick<ChangeLocaleProps, "allowedLocales" | "user" | "locale">
> = (props) => {
const isOnline = useConnectivity();
const [postUserProperties, postSessionLocale] = useMemo(
() =>
isOnline
? [postUserPropertiesOnline, postSessionLocaleOnline]
: [postUserPropertiesOffline, postSessionLocaleOffline],
const postUserProperties = useMemo(
() => (isOnline ? postUserPropertiesOnline : postUserPropertiesOffline),
[isOnline]
);

return (
<ChangeLocale {...props} {...{ postUserProperties, postSessionLocale }} />
);
return <ChangeLocale {...props} postUserProperties={postUserProperties} />;
};

// exported for tests
Expand All @@ -47,36 +38,30 @@ export const ChangeLocale: React.FC<ChangeLocaleProps> = ({
locale,
user,
postUserProperties,
postSessionLocale,
}) => {
const { t } = useTranslation();
const [selectedLocale, setSelectedLocale] = useState(
user?.userProperties?.defaultLocale ?? locale
);
const [selectedLocale, setSelectedLocale] = useState(locale);
const options = allowedLocales?.map((locale) => (
<SelectItem text={locale} value={locale} key={locale} />
));

useEffect(() => {
if (user.userProperties.defaultLocale !== selectedLocale) {
const ac = new AbortController();
postUserProperties(
user.uuid,
{
...(user.userProperties ?? {}),
defaultLocale: selectedLocale,
},
ac
);
postSessionLocale(selectedLocale, ac);
return () => ac.abort();
}
}, [selectedLocale, postUserProperties, user, postSessionLocale]);

const onChange = useCallback(
(event: React.ChangeEvent<HTMLSelectElement>) =>
setSelectedLocale(event.target.value),
[setSelectedLocale]
(event: React.ChangeEvent<HTMLSelectElement>) => {
const newLocale = event.target.value;
if (newLocale !== selectedLocale) {
const ac = new AbortController();
postUserProperties(
user.uuid,
{
...(user.userProperties ?? {}),
defaultLocale: newLocale,
},
ac
);
setSelectedLocale(newLocale);
}
},
[postUserProperties, user.userProperties, user.uuid, selectedLocale]
);

const onClick = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,3 @@ export async function postUserPropertiesOffline(
}
);
}

export type PostSessionLocale = (
locale: string,
abortController: AbortController
) => Promise<void>;

export async function postSessionLocaleOnline(
locale: string,
abortController: AbortController
): Promise<void> {
await openmrsFetch(`/ws/rest/v1/session`, {
method: "POST",
body: { locale },
headers: { "Content-Type": "application/json" },
signal: abortController.signal,
});
}

export async function postSessionLocaleOffline(
locale: string,
abortController: AbortController
) {}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import React from "react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { ChangeLocale } from "./change-locale.component";
import type {
PostSessionLocale,
PostUserProperties,
} from "./change-locale.resource";
import type { PostUserProperties } from "./change-locale.resource";

const allowedLocales = ["en", "fr", "it", "pt"];
const user: any = {
Expand All @@ -18,55 +15,16 @@ describe(`<ChangeLocale />`, () => {
let postUserPropertiesMock: PostUserProperties = jest.fn(() =>
Promise.resolve()
);
let postSessionLocaleMock: PostSessionLocale = jest.fn(() =>
Promise.resolve()
);

it("should have user's defaultLocale as initial value", async () => {
postUserPropertiesMock = jest.fn(() => Promise.resolve());
postSessionLocaleMock = jest.fn(() => Promise.resolve());

render(
<ChangeLocale
locale={"en"}
allowedLocales={allowedLocales}
user={user}
postUserProperties={postUserPropertiesMock}
postSessionLocale={postSessionLocaleMock}
/>
);
expect(screen.getByLabelText(/Select locale/)).toHaveValue("fr");
});

it("should have session locale as initial value if no defaultLocale for user found", async () => {
postUserPropertiesMock = jest.fn(() => Promise.resolve());
postSessionLocaleMock = jest.fn(() => Promise.resolve());
const wrapper = render(
<ChangeLocale
locale={"en"}
allowedLocales={allowedLocales}
user={{
...user,
userProperties: {},
}}
postUserProperties={postUserPropertiesMock}
postSessionLocale={postSessionLocaleMock}
/>
);
expect(wrapper.getByLabelText(/Select locale/)).toHaveValue("en");
});

it("should change user locale", async () => {
postUserPropertiesMock = jest.fn(() => Promise.resolve());
postSessionLocaleMock = jest.fn(() => Promise.resolve());

render(
<ChangeLocale
locale={"en"}
locale={"fr"}
allowedLocales={allowedLocales}
user={user}
postUserProperties={postUserPropertiesMock}
postSessionLocale={postSessionLocaleMock}
/>
);
expect(screen.getByLabelText(/Select locale/)).toHaveValue("fr");
Expand All @@ -79,10 +37,6 @@ describe(`<ChangeLocale />`, () => {
{ defaultLocale: "en" },
expect.anything()
);
expect(postSessionLocaleMock).toHaveBeenCalledWith(
"en",
expect.anything()
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ import React from "react";
import {
ExtensionSlot,
LoggedInUser,
Session,
useOnClickOutside,
} from "@openmrs/esm-framework";
import { HeaderPanel, HeaderPanelProps } from "@carbon/react";
import { UserSession } from "../../types";
import styles from "../../root.scss";

interface UserMenuPanelProps extends HeaderPanelProps {
expanded: boolean;
user: LoggedInUser | false | null;
allowedLocales: any;
onLogout(): void;
session: UserSession;
session: Session;
hidePanel: () => void;
}

Expand Down Expand Up @@ -43,6 +43,7 @@ const UserMenuPanel: React.FC<UserMenuPanelProps> = ({
onLogout: onLogout,
referer: window.location.pathname,
currentLocation: session?.sessionLocation?.display,
locale: session?.locale,
}}
/>
</HeaderPanel>
Expand Down
5 changes: 0 additions & 5 deletions packages/apps/esm-primary-navigation-app/src/types/index.ts

This file was deleted.

0 comments on commit 51ceb5a

Please sign in to comment.