0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-31 22:51:25 -05:00

refactor(ui): refactor app notification logic (#1241)

refactor app notification logic
This commit is contained in:
simeng-li 2022-06-27 13:22:17 +08:00 committed by GitHub
parent 2d663025ec
commit 6865efff27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 66 additions and 61 deletions

View file

@ -1,7 +1,12 @@
import { ConnectorMetadata } from '@logto/connector-types';
import { SignInMode } from '@logto/schemas';
import { adminConsoleApplicationId, adminConsoleSignInMethods } from '@logto/schemas/lib/seeds';
import {
adminConsoleApplicationId,
adminConsoleSignInMethods,
demoAppApplicationId,
} from '@logto/schemas/lib/seeds';
import etag from 'etag';
import i18next from 'i18next';
import { Provider, errors } from 'oidc-provider';
import { getConnectorInstances } from '@/connectors';
@ -56,6 +61,17 @@ export default function signInSettingsRoutes<T extends AnonymousRouter>(
return next();
}
// Insert Notification Message to DemoApp
if (interaction?.params.client_id === demoAppApplicationId) {
ctx.body = {
...signInExperience,
socialConnectors,
notification: i18next.t('demo_app.notification'),
};
return next();
}
ctx.body = { ...signInExperience, socialConnectors };
return next();

View file

@ -1,5 +1,4 @@
import { LogtoProvider, useLogto, UserInfoResponse } from '@logto/react';
import { signInNotificationStorageKey } from '@logto/schemas';
import { demoAppApplicationId } from '@logto/schemas/lib/seeds';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
@ -32,7 +31,6 @@ const Main = () => {
setUser(userInfo);
})();
} else {
sessionStorage.setItem(signInNotificationStorageKey, t('notification'));
void signIn(window.location.href);
}
}, [fetchUserInfo, isAuthenticated, isInCallback, signIn, t]);

View file

@ -1 +0,0 @@
export const signInNotificationStorageKey = 'logto:client:notification';

View file

@ -1,4 +1,3 @@
export * from './consts';
export * from './foundations';
export * from './db-entries';
export * from './types';

View file

@ -1,23 +1,31 @@
import { signInNotificationStorageKey } from '@logto/schemas';
import { render, fireEvent } from '@testing-library/react';
import { fireEvent } from '@testing-library/react';
import React from 'react';
import AppNotification from '.';
import renderWithPageContext from '@/__mocks__/RenderWithPageContext';
import SettingsProvider from '@/__mocks__/RenderWithPageContext/SettingsProvider';
import { mockSignInExperienceSettings } from '@/__mocks__/logto';
describe('AppNotification', () => {
it('render properly', () => {
const message = 'This is a notification message';
sessionStorage.setItem(signInNotificationStorageKey, message);
const { queryByText, getByText } = render(<AppNotification />);
import Notification from './index';
expect(queryByText(message)).not.toBeNull();
describe('Notification', () => {
it('render Notification', () => {
const notification = 'text notification';
const closeLink = getByText('action.got_it');
const { queryByText, getByText } = renderWithPageContext(
<SettingsProvider
settings={{
...mockSignInExperienceSettings,
notification,
}}
>
<Notification />
</SettingsProvider>
);
expect(closeLink).not.toBeNull();
expect(queryByText(notification)).not.toBeNull();
fireEvent.click(closeLink);
expect(queryByText(message)).toBeNull();
const closeButton = getByText('action.got_it');
fireEvent.click(closeButton);
expect(queryByText(notification)).toBeNull();
});
});

View file

@ -1,23 +1,27 @@
import { Nullable } from '@silverhand/essentials';
import React, { useState, useEffect, useCallback } from 'react';
import React, { useCallback, useContext } from 'react';
import Notification from '@/components/Notification';
import { getAppNotificationInfo, clearAppNotificationInfo } from '@/utils/session-storage';
import { PageContext } from '@/hooks/use-page-context';
import * as styles from './index.module.scss';
const AppNotification = () => {
const [notification, setNotification] = useState<Nullable<string>>(null);
const { experienceSettings, setExperienceSettings } = useContext(PageContext);
const notification = experienceSettings?.notification;
const onClose = useCallback(() => {
setNotification(null);
clearAppNotificationInfo();
}, []);
// Clear notification
setExperienceSettings((settings) => {
if (!settings) {
return;
}
useEffect(() => {
const notification = getAppNotificationInfo();
setNotification(notification);
}, []);
return {
...settings,
notification: undefined,
};
});
}, [setExperienceSettings]);
if (!notification) {
return null;

View file

@ -10,12 +10,12 @@ export type Context = {
platform: Platform;
termsAgreement: boolean;
experienceSettings: SignInExperienceSettings | undefined;
setTheme: (theme: Theme) => void;
setToast: (message: string) => void;
setLoading: (loading: boolean) => void;
setPlatform: (platform: Platform) => void;
setTermsAgreement: (termsAgreement: boolean) => void;
setExperienceSettings: (settings: SignInExperienceSettings) => void;
setTheme: React.Dispatch<React.SetStateAction<Theme>>;
setToast: React.Dispatch<React.SetStateAction<string>>;
setLoading: React.Dispatch<React.SetStateAction<boolean>>;
setPlatform: React.Dispatch<React.SetStateAction<Platform>>;
setTermsAgreement: React.Dispatch<React.SetStateAction<boolean>>;
setExperienceSettings: React.Dispatch<React.SetStateAction<SignInExperienceSettings | undefined>>;
};
const noop = () => {

View file

@ -1,12 +1,4 @@
import {
Branding,
LanguageInfo,
TermsOfUse,
SignInExperience,
ConnectorMetadata,
SignInMode,
Color,
} from '@logto/schemas';
import { SignInExperience, ConnectorMetadata } from '@logto/schemas';
export type UserFlow = 'sign-in' | 'register';
export type SignInMethod = 'username' | 'email' | 'sms' | 'social';
@ -28,15 +20,13 @@ export interface ConnectorData extends ConnectorMetadata {
export type SignInExperienceSettingsResponse = SignInExperience & {
socialConnectors: ConnectorData[];
notification?: string;
};
export type SignInExperienceSettings = {
color: Color;
branding: Branding;
languageInfo: LanguageInfo;
termsOfUse: TermsOfUse;
export type SignInExperienceSettings = Omit<
SignInExperienceSettingsResponse,
'id' | 'signInMethods' | 'socialSignInConnectorTargets'
> & {
primarySignInMethod: SignInMethod;
secondarySignInMethods: SignInMethod[];
socialConnectors: ConnectorData[];
signInMode: SignInMode;
};

View file

@ -1,9 +0,0 @@
import { signInNotificationStorageKey } from '@logto/schemas';
export const getAppNotificationInfo = () => {
return sessionStorage.getItem(signInNotificationStorageKey);
};
export const clearAppNotificationInfo = () => {
sessionStorage.removeItem(signInNotificationStorageKey);
};