0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-04-07 23:01:25 -05:00

refactor(console): AppEndpointsProvider -> AppDataProvider (#4117)

This commit is contained in:
Gao Sun 2023-07-05 17:00:08 +08:00 committed by GitHub
parent 99aa43216f
commit 736e99fd63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 39 additions and 32 deletions

View file

@ -22,7 +22,7 @@ import ErrorBoundary from './containers/ErrorBoundary';
import LogtoErrorBoundary from './containers/LogtoErrorBoundary';
import TenantAppContainer from './containers/TenantAppContainer';
import AppConfirmModalProvider from './contexts/AppConfirmModalProvider';
import AppEndpointsProvider from './contexts/AppEndpointsProvider';
import AppDataProvider from './contexts/AppDataProvider';
import { AppThemeProvider } from './contexts/AppThemeProvider';
import TenantsProvider, { TenantsContext } from './contexts/TenantsProvider';
import initI18n from './i18n/init';
@ -83,11 +83,11 @@ function Content() {
* if it's Cloud, render the tenant app container only when a tenant ID is available (in a tenant context).
*/}
{!isCloud || currentTenantId ? (
<AppEndpointsProvider>
<AppDataProvider>
<AppConfirmModalProvider>
<TenantAppContainer />
</AppConfirmModalProvider>
</AppEndpointsProvider>
</AppDataProvider>
) : (
<CloudApp />
)}

View file

@ -5,7 +5,7 @@ import { useContext } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import { AppDataContext } from '@/contexts/AppDataProvider';
import CodeEditor from '@/ds-components/CodeEditor';
import CopyToClipboard from '@/ds-components/CopyToClipboard';
import DynamicT from '@/ds-components/DynamicT';
@ -31,7 +31,7 @@ function ConfigForm({ formItems, className, connectorId, connectorType }: Props)
control,
formState: { errors },
} = useFormContext<ConnectorFormType>();
const { userEndpoint } = useContext(AppEndpointsContext);
const { userEndpoint } = useContext(AppDataContext);
const { data: customDomain } = useCustomDomain();
const callbackUri = new URL(`/callback/${connectorId}`, userEndpoint).toString();

View file

@ -4,7 +4,7 @@ import { useContext } from 'react';
import { useTranslation } from 'react-i18next';
import ExternalLinkIcon from '@/assets/icons/external-link.svg';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import { AppDataContext } from '@/contexts/AppDataProvider';
import type { Props as ButtonProps, ButtonType } from '@/ds-components/Button';
import Button from '@/ds-components/Button';
import { Tooltip } from '@/ds-components/Tip';
@ -20,7 +20,7 @@ type Props = {
function LivePreviewButton({ size, type, isDisabled }: Props) {
const { configs, updateConfigs } = useConfigs();
const { userEndpoint } = useContext(AppEndpointsContext);
const { userEndpoint } = useContext(AppDataContext);
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
return (

View file

@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
import useSWR from 'swr';
import PhoneInfo from '@/assets/images/phone-info.svg';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import { AppDataContext } from '@/contexts/AppDataProvider';
import type { RequestError } from '@/hooks/use-api';
import useUiLanguages from '@/hooks/use-ui-languages';
@ -29,7 +29,7 @@ function SignInExperiencePreview({ platform, mode, language = 'en', signInExperi
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { customPhrases } = useUiLanguages();
const { userEndpoint } = useContext(AppEndpointsContext);
const { userEndpoint } = useContext(AppDataContext);
const previewRef = useRef<HTMLIFrameElement>(null);
const { data: allConnectors } = useSWR<ConnectorResponse[], RequestError>('api/connectors');
const [iframeLoaded, setIframeLoaded] = useState(false);

View file

@ -5,7 +5,8 @@ import { RouterProvider, createBrowserRouter } from 'react-router-dom';
import AppLoading from '@/components/AppLoading';
import { getBasename } from '@/consts';
import { isCloud } from '@/consts/env';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import { AppDataContext } from '@/contexts/AppDataProvider';
import useMeCustomData from '@/hooks/use-me-custom-data';
import useTrackUserId from '@/hooks/use-track-user-id';
import { OnboardingRoutes } from '@/onboarding';
import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data';
@ -13,8 +14,9 @@ import { ConsoleRoutes } from '@/pages/ConsoleRoutes';
/** @deprecated Remove this layer. */
function TenantAppContainer() {
const { userEndpoint } = useContext(AppEndpointsContext);
const { isOnboarding, isLoaded } = useUserOnboardingData();
const { userEndpoint } = useContext(AppDataContext);
const { isLoaded } = useMeCustomData();
const { isOnboarding } = useUserOnboardingData();
const { isAuthenticated } = useLogto();
const router = useMemo(

View file

@ -10,7 +10,7 @@ type Props = {
children: ReactNode;
};
type AppEndpoints = {
type AppData = {
/**
* The Logto endpoint for the current tenant.
*
@ -19,12 +19,19 @@ type AppEndpoints = {
userEndpoint?: URL;
};
export const AppEndpointsContext = createContext<AppEndpoints>({});
export const AppDataContext = createContext<AppData>({});
function AppEndpointsProvider({ children }: Props) {
const [endpoints, setEndpoints] = useState<AppEndpoints>({});
/** The context provider for the global app data. */
function AppDataProvider({ children }: Props) {
const [userEndpoint, setUserEndpoint] = useState<URL>();
const { currentTenantId } = useContext(TenantsContext);
const memorizedContext = useMemo(() => endpoints, [endpoints]);
const memorizedContext = useMemo(
() =>
({
userEndpoint,
} satisfies AppData),
[userEndpoint]
);
useEffect(() => {
const getEndpoint = async () => {
@ -35,15 +42,13 @@ function AppEndpointsProvider({ children }: Props) {
const { user } = await ky
.get(new URL(`api/.well-known/endpoints/${currentTenantId}`, adminTenantEndpoint))
.json<{ user: string }>();
setEndpoints({ userEndpoint: new URL(user) });
setUserEndpoint(new URL(user));
};
void getEndpoint();
}, [currentTenantId]);
return (
<AppEndpointsContext.Provider value={memorizedContext}>{children}</AppEndpointsContext.Provider>
);
return <AppDataContext.Provider value={memorizedContext}>{children}</AppDataContext.Provider>;
}
export default AppEndpointsProvider;
export default AppDataProvider;

View file

@ -7,7 +7,7 @@ import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
import { getBasename, getManagementApi, requestTimeout } from '@/consts';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import { AppDataContext } from '@/contexts/AppDataProvider';
import { TenantsContext } from '@/contexts/TenantsProvider';
import { useConfirmModal } from './use-confirm-modal';
@ -106,7 +106,7 @@ export const useStaticApi = ({
};
const useApi = (props: Omit<StaticApiProps, 'prefixUrl'> = {}) => {
const { userEndpoint } = useContext(AppEndpointsContext);
const { userEndpoint } = useContext(AppDataContext);
return useStaticApi({ ...props, prefixUrl: userEndpoint });
};

View file

@ -12,7 +12,7 @@ import { Trans, useTranslation } from 'react-i18next';
import FormCard from '@/components/FormCard';
import { openIdProviderConfigPath } from '@/consts/oidc';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import { AppDataContext } from '@/contexts/AppDataProvider';
import CopyToClipboard from '@/ds-components/CopyToClipboard';
import DynamicT from '@/ds-components/DynamicT';
import FormField from '@/ds-components/FormField';
@ -30,7 +30,7 @@ type Props = {
};
function AdvancedSettings({ applicationType, oidcConfig }: Props) {
const { userEndpoint } = useContext(AppEndpointsContext);
const { userEndpoint } = useContext(AppDataContext);
const {
register,
formState: { errors },

View file

@ -6,7 +6,7 @@ import type { MDXProps } from 'mdx/types';
import type { LazyExoticComponent } from 'react';
import { useEffect, useContext, cloneElement, lazy, Suspense, useState } from 'react';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import { AppDataContext } from '@/contexts/AppDataProvider';
import CodeEditor from '@/ds-components/CodeEditor';
import TextLink from '@/ds-components/TextLink';
import useCustomDomain from '@/hooks/use-custom-domain';
@ -56,7 +56,7 @@ function Guide({ app, isCompact, onClose }: Props) {
const sdks = app && applicationTypeAndSdkTypeMappings[app.type];
const [selectedSdk, setSelectedSdk] = useState<Optional<SupportedSdk>>();
const [activeStepIndex, setActiveStepIndex] = useState(-1);
const { userEndpoint } = useContext(AppEndpointsContext);
const { userEndpoint } = useContext(AppDataContext);
const { data: customDomain } = useCustomDomain();
const isCustomDomainActive = customDomain?.status === DomainStatus.Active;

View file

@ -21,7 +21,7 @@ import PasswordlessDark from '@/assets/icons/passwordless-dark.svg';
import Passwordless from '@/assets/icons/passwordless.svg';
import { discordLink } from '@/consts';
import { ConnectorsTabs } from '@/consts/page-tabs';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import { AppDataContext } from '@/contexts/AppDataProvider';
import useConfigs from '@/hooks/use-configs';
import useDocumentationUrl from '@/hooks/use-documentation-url';
import useTheme from '@/hooks/use-theme';
@ -40,7 +40,7 @@ type GetStartedMetadata = {
const useGetStartedMetadata = () => {
const { configs, updateConfigs } = useConfigs();
const { userEndpoint } = useContext(AppEndpointsContext);
const { userEndpoint } = useContext(AppDataContext);
const theme = useTheme();
const isLightMode = theme === Theme.Light;
const navigate = useNavigate();

View file

@ -1,6 +1,6 @@
import { useContext } from 'react';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import { AppDataContext } from '@/contexts/AppDataProvider';
import CopyToClipboard from '@/ds-components/CopyToClipboard';
import DynamicT from '@/ds-components/DynamicT';
import Tag from '@/ds-components/Tag';
@ -8,7 +8,7 @@ import Tag from '@/ds-components/Tag';
import * as styles from './index.module.scss';
function DefaultDomain() {
const { userEndpoint } = useContext(AppEndpointsContext);
const { userEndpoint } = useContext(AppDataContext);
if (!userEndpoint) {
return null;