0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(console): remove use tenant hook and use cloud SWR instead (#4060)

This commit is contained in:
Darcy Ye 2023-06-20 15:41:13 +08:00 committed by GitHub
parent 42d844f258
commit da6f9eef5c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 86 deletions

View file

@ -1,16 +1,17 @@
import { Theme } from '@logto/schemas'; import { Theme } from '@logto/schemas';
import type { TenantInfo } from '@logto/schemas/models'; import type { TenantInfo } from '@logto/schemas/models';
import classNames from 'classnames'; import classNames from 'classnames';
import { useState } from 'react'; import { useContext, useEffect, useState } from 'react';
import { toast } from 'react-hot-toast'; import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import Plus from '@/assets/icons/plus.svg'; import Plus from '@/assets/icons/plus.svg';
import TenantLandingPageImageDark from '@/assets/images/tenant-landing-page-dark.svg'; import TenantLandingPageImageDark from '@/assets/images/tenant-landing-page-dark.svg';
import TenantLandingPageImage from '@/assets/images/tenant-landing-page.svg'; import TenantLandingPageImage from '@/assets/images/tenant-landing-page.svg';
import { useCloudSwr } from '@/cloud/hooks/use-cloud-swr';
import { TenantsContext } from '@/contexts/TenantsProvider';
import Button from '@/ds-components/Button'; import Button from '@/ds-components/Button';
import DynamicT from '@/ds-components/DynamicT'; import DynamicT from '@/ds-components/DynamicT';
import useTenants from '@/hooks/use-tenants';
import useTheme from '@/hooks/use-theme'; import useTheme from '@/hooks/use-theme';
import CreateTenantModal from './CreateTenantModal'; import CreateTenantModal from './CreateTenantModal';
@ -22,7 +23,15 @@ type Props = {
function TenantLandingPageContent({ className }: Props) { function TenantLandingPageContent({ className }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { tenants, mutate } = useTenants(); const { tenants, setTenants } = useContext(TenantsContext);
const { data: availableTenants, mutate } = useCloudSwr('/api/tenants');
useEffect(() => {
if (availableTenants) {
setTenants(availableTenants);
}
}, [availableTenants, setTenants]);
const theme = useTheme(); const theme = useTheme();
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);

View file

@ -1,18 +1,19 @@
import { type TenantInfo } from '@logto/schemas/models'; import { type TenantInfo } from '@logto/schemas/models';
import classNames from 'classnames'; import classNames from 'classnames';
import { useRef, useState } from 'react'; import { useContext, useRef, useState, useEffect, useMemo } from 'react';
import { toast } from 'react-hot-toast'; import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import KeyboardArrowDown from '@/assets/icons/keyboard-arrow-down.svg'; import KeyboardArrowDown from '@/assets/icons/keyboard-arrow-down.svg';
import PlusSign from '@/assets/icons/plus.svg'; import PlusSign from '@/assets/icons/plus.svg';
import Tick from '@/assets/icons/tick.svg'; import Tick from '@/assets/icons/tick.svg';
import { useCloudSwr } from '@/cloud/hooks/use-cloud-swr';
import CreateTenantModal from '@/cloud/pages/Main/TenantLandingPage/TenantLandingPageContent/CreateTenantModal'; import CreateTenantModal from '@/cloud/pages/Main/TenantLandingPage/TenantLandingPageContent/CreateTenantModal';
import AppError from '@/components/AppError'; import AppError from '@/components/AppError';
import { TenantsContext } from '@/contexts/TenantsProvider';
import Divider from '@/ds-components/Divider'; import Divider from '@/ds-components/Divider';
import Dropdown, { DropdownItem } from '@/ds-components/Dropdown'; import Dropdown, { DropdownItem } from '@/ds-components/Dropdown';
import OverlayScrollbar from '@/ds-components/OverlayScrollbar'; import OverlayScrollbar from '@/ds-components/OverlayScrollbar';
import useTenants from '@/hooks/use-tenants';
import { onKeyDownHandler } from '@/utils/a11y'; import { onKeyDownHandler } from '@/utils/a11y';
import TenantEnvTag from './TenantEnvTag'; import TenantEnvTag from './TenantEnvTag';
@ -20,13 +21,18 @@ import * as styles from './index.module.scss';
function TenantSelector() { function TenantSelector() {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { const { tenants, setTenants, currentTenantId } = useContext(TenantsContext);
tenants, const { data: availableTenants, mutate, error } = useCloudSwr('/api/tenants');
currentTenant: currentTenantInfo,
currentTenantId, useEffect(() => {
error, if (availableTenants) {
mutate, setTenants(availableTenants);
} = useTenants(); }
}, [availableTenants, setTenants]);
const currentTenantInfo = useMemo(() => {
return tenants?.find((tenant) => tenant.id === currentTenantId);
}, [currentTenantId, tenants]);
const anchorRef = useRef<HTMLDivElement>(null); const anchorRef = useRef<HTMLDivElement>(null);
const [showDropdown, setShowDropdown] = useState(false); const [showDropdown, setShowDropdown] = useState(false);

View file

@ -1,64 +0,0 @@
import { useLogto } from '@logto/react';
import { type TenantInfo } from '@logto/schemas/models';
import { type Optional, trySafe } from '@silverhand/essentials';
import { useCallback, useContext, useEffect, useMemo } from 'react';
import { type KeyedMutator } from 'swr';
import { useCloudSwr } from '@/cloud/hooks/use-cloud-swr';
import { TenantsContext } from '@/contexts/TenantsProvider';
type TenantsHook = {
currentTenant?: TenantInfo;
currentTenantId: string;
error?: Error;
isLoaded: boolean;
isLoading: boolean;
isSettle: boolean;
mutate: KeyedMutator<TenantInfo[]>;
setCurrentTenantId: (id: string) => void;
tenants?: TenantInfo[];
};
const useTenants = (): TenantsHook => {
const { signIn, getAccessToken } = useLogto();
const { currentTenantId, setCurrentTenantId, isSettle, setIsSettle } = useContext(TenantsContext);
const { data: availableTenants, error, mutate } = useCloudSwr('/api/tenants');
const isLoading = !availableTenants && !error;
const isLoaded = Boolean(availableTenants && !error);
const validate = useCallback(
async (tenant: TenantInfo) => {
const { id, indicator } = tenant;
if (await trySafe(getAccessToken(indicator))) {
setIsSettle(true);
} else {
void signIn(new URL(`/${id}/callback`, window.location.origin).toString());
}
},
[getAccessToken, setIsSettle, signIn]
);
const currentTenant: Optional<TenantInfo> = useMemo(() => {
return availableTenants?.find(({ id }) => id === currentTenantId);
}, [currentTenantId, availableTenants]);
useEffect(() => {
if (currentTenant) {
void validate(currentTenant);
}
}, [currentTenant, validate]);
return {
currentTenant,
currentTenantId,
error,
isLoaded,
isLoading,
isSettle,
mutate,
setCurrentTenantId, // Will be used to switch to another tenant.
tenants: availableTenants,
};
};
export default useTenants;

View file

@ -1,17 +1,18 @@
import { type TenantInfo, TenantTag } from '@logto/schemas/models'; import { type TenantInfo, TenantTag } from '@logto/schemas/models';
import classNames from 'classnames'; import classNames from 'classnames';
import { useEffect, useState } from 'react'; import { useEffect, useState, useContext, useMemo } from 'react';
import { FormProvider, useForm } from 'react-hook-form'; import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast'; import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useCloudApi } from '@/cloud/hooks/use-cloud-api'; import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
import { useCloudSwr } from '@/cloud/hooks/use-cloud-swr';
import AppError from '@/components/AppError'; import AppError from '@/components/AppError';
import AppLoading from '@/components/AppLoading'; import AppLoading from '@/components/AppLoading';
import PageMeta from '@/components/PageMeta'; import PageMeta from '@/components/PageMeta';
import SubmitFormChangesActionBar from '@/components/SubmitFormChangesActionBar'; import SubmitFormChangesActionBar from '@/components/SubmitFormChangesActionBar';
import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal'; import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal';
import useTenants from '@/hooks/use-tenants'; import { TenantsContext } from '@/contexts/TenantsProvider';
import DeleteCard from './DeleteCard'; import DeleteCard from './DeleteCard';
import DeleteModal from './DeleteModal'; import DeleteModal from './DeleteModal';
@ -28,14 +29,20 @@ const tenantProfileToForm = (tenant?: TenantInfo): TenantSettingsForm => {
function TenantBasicSettings() { function TenantBasicSettings() {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const api = useCloudApi(); const api = useCloudApi();
const { const { tenants, setTenants, currentTenantId } = useContext(TenantsContext);
currentTenant, const { data: availableTenants, mutate, error: requestError } = useCloudSwr('/api/tenants');
currentTenantId, const isLoading = !availableTenants && !requestError;
error: requestError,
mutate, useEffect(() => {
isLoading, if (availableTenants) {
tenants, setTenants(availableTenants);
} = useTenants(); }
}, [availableTenants, setTenants]);
const currentTenant = useMemo(() => {
return tenants?.find((tenant) => tenant.id === currentTenantId);
}, [currentTenantId, tenants]);
const [error, setError] = useState<Error>(); const [error, setError] = useState<Error>();
const [isDeletionModalOpen, setIsDeletionModalOpen] = useState(false); const [isDeletionModalOpen, setIsDeletionModalOpen] = useState(false);
const [isDeleting, setIsDeleting] = useState(false); const [isDeleting, setIsDeleting] = useState(false);