Skip to content

Commit

Permalink
feat(container): updated user widget and support dynamic updates
Browse files Browse the repository at this point in the history
ref:MANAGER-14829

Signed-off-by: Omar ALKABOUSS MOUSSANA <[email protected]>
  • Loading branch information
Omar ALKABOUSS MOUSSANA committed Oct 3, 2024
1 parent 73f8e6b commit ae4ae52
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 14 deletions.
8 changes: 7 additions & 1 deletion packages/components/ovh-shell/src/client/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Environment, ApplicationId } from '@ovh-ux/manager-config';
import { Environment, ApplicationId, User } from '@ovh-ux/manager-config';
import ShellClient from './shell-client';
import { clientAuth } from '../plugin/auth';
import { clientNavigation } from '../plugin/navigation';
Expand Down Expand Up @@ -43,6 +43,12 @@ export default function exposeApi(shellClient: ShellClient) {
method: 'setApplication',
args: [applicationId],
}),
setUser: (user: User) =>
shellClient.invokePluginMethod({
plugin: 'environment',
method: 'setUser',
args: [user],
}),
},
i18n: {
getLocale: () =>
Expand Down
17 changes: 16 additions & 1 deletion packages/components/ovh-shell/src/plugin/environment/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { Environment, ApplicationId } from '@ovh-ux/manager-config';
import { Environment, ApplicationId, User } from '@ovh-ux/manager-config';

export function environment(environment: Environment) {
const listeners: CallableFunction[] = [];
const userListeners: CallableFunction[] = [];

const triggerListeners = (...params: any[]) => {
listeners.forEach((listener) => {
listener.bind(null)(...params);
});
};

const triggerUserListeners = (user: User) => {
userListeners.forEach((listener) => {
listener(user);
});
};

return {
getEnvironment: (): Environment => environment,
setUniverse: (universe: string) => {
Expand All @@ -22,6 +29,14 @@ export function environment(environment: Environment) {
onUniverseChange: (callback: CallableFunction) => {
listeners.push(callback);
},
onUserChange: (callback: CallableFunction) => {
userListeners.push(callback);
},
setUser: (user: User) => {
const updatedUser = { ...environment.user, ...user };
environment.setUser(updatedUser);
triggerUserListeners(updatedUser);
},
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,13 @@ export default {
SMALL_DEVICE_MAX_SIZE,
};

export const MOBILE_WIDTH_RESOLUTION = 1024;
export const MOBILE_WIDTH_RESOLUTION = 1024;

export const LEGAL_FORMS = {
INDIVIDUAL: 'individual',
ADMINISTRATION: 'administration',
CORPORATION: 'corporation',
PERSONALCORPORATION: 'personalcorporation',
ASSOCIATION: 'association',
OTHER: 'other',
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ import style from './navbar.module.scss';

import { useShell } from '@/context';
import { useHeader } from '@/context/header';
import { LEGAL_FORMS } from '@/container/common/constants';
import useUser from '@/hooks/user/useUser';

type Props = {
user: User;
};

function NavbarAccount({ user }: Props): JSX.Element {
function NavbarAccount(): JSX.Element {
const { t } = useTranslation(TRANSLATE_NAMESPACE);
const shell = useShell();
const uxPlugin = shell.getPlugin('ux');
const user = useUser();

const firstName = capitalize(user.firstname).replace(/-[a-z]/g, (match) =>
match.toUpperCase(),
);
Expand Down Expand Up @@ -70,7 +70,8 @@ function NavbarAccount({ user }: Props): JSX.Element {
level={ODS_TEXT_LEVEL.button}
size={ODS_TEXT_SIZE._200}
>
{`${firstName} ${lastName}`}
{user.legalform === LEGAL_FORMS.CORPORATION ?
user.organisation : `${user.firstname} ${user.name}`}
</OsdsText>
</span>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function Navbar({ environment }: Props): JSX.Element {
<div className="oui-navbar-list__item">
<Notifications />
</div>
<Account user={environment.getUser()} />
<Account />
</div>
</div>
{isSmallDevice &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import { OsdsIcon } from '@ovhcloud/ods-components/react';
import { ODS_ICON_NAME, ODS_ICON_SIZE } from '@ovhcloud/ods-components';
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { tracking } from './constants';
import { LEGAL_FORMS } from '@/container/common/constants';
import { Environment } from '@ovh-ux/manager-config';
import useUser from '@/hooks/user/useUser';

type Props = {
onToggle(show: boolean): void;
Expand All @@ -28,8 +31,9 @@ export const UserAccountMenu = ({ onToggle }: Props): JSX.Element => {
const trackingPlugin = shell.getPlugin('tracking');
const { setIsNotificationsSidebarVisible } = useHeader();

const environment = shell.getPlugin('environment').getEnvironment();
const user = environment.getUser();
const pluginEnvironement = shell.getPlugin('environment');
const environment: Environment = pluginEnvironement.getEnvironment();
const user = useUser();
const region = environment.getRegion();

const {
Expand Down Expand Up @@ -100,7 +104,8 @@ export const UserAccountMenu = ({ onToggle }: Props): JSX.Element => {
</span>
<span
className={style.userInfos}
>{`${user.firstname} ${user.name}`}</span>
>{user.legalform === LEGAL_FORMS.CORPORATION ?
user.organisation : `${user.firstname} ${user.name}`}</span>
</UserAccountMenuButton>
<UserAccountMenuContent
defaultPaymentMethod={defaultPaymentMethod}
Expand Down
60 changes: 60 additions & 0 deletions packages/manager/apps/container/src/hooks/user/useUser.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { renderHook, act, waitFor } from '@testing-library/react';
import { User } from '@ovh-ux/manager-config';
import useUser from '@/hooks/user/useUser';
import { describe, it, vi } from 'vitest';

const userMock: Partial<User> = {
phoneCountry: 'FR',
firstname: 'john',
name: 'jihn'
};

const updatedUserMock: Partial<User> = {
...userMock,
phoneCountry: 'EN',
firstname: 'doe',
};

const environmentMock = {
user: userMock,
};
const onUserChangeMock = vi.fn();
const pluginEnvironmentMock = {
getEnvironment: vi.fn(() => environmentMock),
onUserChange: onUserChangeMock,
};

const shellMock = {
getPlugin: vi.fn(() => pluginEnvironmentMock),
};

vi.mock('@/context', () => ({
useShell: vi.fn(() => shellMock),
}));

describe('useUser', () => {
it('returns the initial user from the environment', async () => {
const { result } = renderHook(() => useUser());

onUserChangeMock.mockClear();

await waitFor(() => {
expect(result.current).toEqual(userMock);
expect(shellMock.getPlugin).toHaveBeenCalledWith('environment');
});
});

it('updates the user when onUserChange is triggered', async () => {
const { result } = renderHook(() => useUser());

expect(result.current).not.toEqual(updatedUserMock);

act(() => {
onUserChangeMock.mock.calls[0][0](updatedUserMock);
});

await waitFor(() => {
expect(result.current).toEqual(updatedUserMock);
});
});
});
22 changes: 22 additions & 0 deletions packages/manager/apps/container/src/hooks/user/useUser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Environment, User } from '@ovh-ux/manager-config';
import { useEffect, useState } from 'react';
import { useShell } from '@/context';


const useUser = (): User => {
const shell = useShell();

const pluginEnvironement = shell.getPlugin('environment');
const environment: Environment = pluginEnvironement.getEnvironment();
const [user, setUser] = useState<User>(environment.user);

useEffect(() => {
pluginEnvironement.onUserChange((updatedUser: User) => {
setUser(updatedUser);
});
}, []);

return user;
}

export default useUser;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import find from 'lodash/find';
import flatten from 'lodash/flatten';
import pick from 'lodash/pick';
import values from 'lodash/values';

import { LANGUAGES } from '@ovh-ux/manager-config';

import {
Expand Down Expand Up @@ -36,6 +35,7 @@ export default class NewAccountFormController {
$anchorScroll,
$scope,
ovhFeatureFlipping,
shellClient,
) {
this.$q = $q;
this.$http = $http;
Expand All @@ -58,6 +58,7 @@ export default class NewAccountFormController {
this.$scope = $scope;
this.ovhFeatureFlipping = ovhFeatureFlipping;
this.SECTIONS = SECTIONS;
this.shell = shellClient;
}

$onInit() {
Expand Down Expand Up @@ -337,6 +338,7 @@ export default class NewAccountFormController {
return this.$q.reject(result);
}
this.coreConfig.updateUser(model);
this.shell.environment.setUser(model);
return result;
})
.catch((error) => {
Expand Down

0 comments on commit ae4ae52

Please sign in to comment.