diff --git a/packages/console/src/cloud/pages/Main/AutoCreateTenant/index.tsx b/packages/console/src/cloud/pages/Main/AutoCreateTenant/index.tsx index 4dfb9888d..b467441d2 100644 --- a/packages/console/src/cloud/pages/Main/AutoCreateTenant/index.tsx +++ b/packages/console/src/cloud/pages/Main/AutoCreateTenant/index.tsx @@ -6,18 +6,18 @@ import { TenantsContext } from '@/contexts/TenantsProvider'; export default function AutoCreateTenant() { const api = useCloudApi(); - const { appendTenant, tenants } = useContext(TenantsContext); + const { prependTenant, tenants } = useContext(TenantsContext); useEffect(() => { const createTenant = async () => { const newTenant = await api.post('/api/tenants', { body: {} }); - appendTenant(newTenant); + prependTenant(newTenant); }; if (tenants.length === 0) { void createTenant(); } - }, [api, appendTenant, tenants.length]); + }, [api, prependTenant, tenants.length]); return ; } diff --git a/packages/console/src/cloud/pages/Main/TenantLandingPage/TenantLandingPageContent/index.tsx b/packages/console/src/cloud/pages/Main/TenantLandingPage/TenantLandingPageContent/index.tsx index 86f46587f..4502ebc2a 100644 --- a/packages/console/src/cloud/pages/Main/TenantLandingPage/TenantLandingPageContent/index.tsx +++ b/packages/console/src/cloud/pages/Main/TenantLandingPage/TenantLandingPageContent/index.tsx @@ -19,7 +19,7 @@ type Props = { }; function TenantLandingPageContent({ className }: Props) { - const { tenants, appendTenant, navigateTenant } = useContext(TenantsContext); + const { tenants, prependTenant, navigateTenant } = useContext(TenantsContext); const theme = useTheme(); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); @@ -55,7 +55,7 @@ function TenantLandingPageContent({ className }: Props) { isOpen={isCreateModalOpen} onClose={async (tenant?: TenantInfo) => { if (tenant) { - appendTenant(tenant); + prependTenant(tenant); navigateTenant(tenant.id); } setIsCreateModalOpen(false); diff --git a/packages/console/src/containers/AppContent/components/Topbar/TenantSelector/index.tsx b/packages/console/src/containers/AppContent/components/Topbar/TenantSelector/index.tsx index 256c8654e..c4b06bd71 100644 --- a/packages/console/src/containers/AppContent/components/Topbar/TenantSelector/index.tsx +++ b/packages/console/src/containers/AppContent/components/Topbar/TenantSelector/index.tsx @@ -22,7 +22,7 @@ export default function TenantSelector() { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { tenants, - appendTenant, + prependTenant, currentTenant: currentTenantInfo, currentTenantId, navigateTenant, @@ -111,7 +111,7 @@ export default function TenantSelector() { isOpen={showCreateTenantModal} onClose={async (tenant?: TenantInfo) => { if (tenant) { - appendTenant(tenant); + prependTenant(tenant); navigateTenant(tenant.id); } setShowCreateTenantModal(false); diff --git a/packages/console/src/containers/TenantAccess/index.tsx b/packages/console/src/containers/TenantAccess/index.tsx index e74023077..ff9de67ec 100644 --- a/packages/console/src/containers/TenantAccess/index.tsx +++ b/packages/console/src/containers/TenantAccess/index.tsx @@ -47,27 +47,29 @@ export default function TenantAccess() { useContext(TenantsContext); useEffect(() => { - const validate = async ({ indicator, id }: TenantInfo) => { + const validate = async ({ indicator, id: tenantId }: TenantInfo) => { // Test fetching an access token for the current Tenant ID. // If failed, it means the user finishes the first auth, ands still needs to auth again to // fetch the full-scoped (with all available tenants) token. if (await trySafe(getAccessToken(indicator))) { setCurrentTenantStatus('validated'); } else { - void signIn(getCallbackUrl(id).href); + void signIn(getCallbackUrl(tenantId).href); } }; if (isAuthenticated && currentTenantId && currentTenantStatus === 'pending') { setCurrentTenantStatus('validating'); - if (currentTenant) { - void validate(currentTenant); - } else { - // The current tenant is unavailable to the user, maybe a deleted tenant or a tenant that - // the user has no access to. Fall back to the home page. + + // The current tenant is unavailable to the user, maybe a deleted tenant or a tenant that + // the user has no access to. Fall back to the home page. + if (!currentTenant) { // eslint-disable-next-line @silverhand/fp/no-mutation window.location.href = '/'; + return; } + + void validate(currentTenant); } }, [ currentTenant, diff --git a/packages/console/src/contexts/TenantsProvider.tsx b/packages/console/src/contexts/TenantsProvider.tsx index 47a6d17a1..b3b3e7e32 100644 --- a/packages/console/src/contexts/TenantsProvider.tsx +++ b/packages/console/src/contexts/TenantsProvider.tsx @@ -8,6 +8,10 @@ import type { NavigateOptions } from 'react-router-dom'; import { isCloud } from '@/consts/env'; import { getUserTenantId } from '@/consts/tenants'; +/** + * The current tenant status of access validation. When it's `validated`, it indicates that a + * valid Access Token for the current tenant is available. + */ type CurrentTenantStatus = 'pending' | 'validating' | 'validated'; /** @see {@link TenantsProvider} for why `useSWR()` is not applicable for this context. */ @@ -17,8 +21,8 @@ type Tenants = { isInitComplete: boolean; /** Reset tenants to the given value. It will overwrite the current tenants data and set `isInitComplete` to `true`. */ resetTenants: (tenants: TenantInfo[]) => void; - /** Append a new tenant to the current tenants data. */ - appendTenant: (tenant: TenantInfo) => void; + /** Prepend a new tenant to the current tenants data. */ + prependTenant: (tenant: TenantInfo) => void; /** Remove a tenant by ID from the current tenants data. */ removeTenant: (tenantId: string) => void; /** Update a tenant by ID if it exists in the current tenants data. */ @@ -30,7 +34,11 @@ type Tenants = { */ currentTenantId: string; currentTenant?: TenantInfo; - /** Indicates if the Access Token has been validated for use. Will be reset to false when the current tenant changes. */ + /** + * Indicates if the Access Token has been validated for use. Will be reset to `pending` when the current tenant changes. + * + * @see {@link CurrentTenantStatus} + */ currentTenantStatus: CurrentTenantStatus; setCurrentTenantStatus: (status: CurrentTenantStatus) => void; navigateTenant: (tenantId: string, options?: NavigateOptions) => void; @@ -52,7 +60,7 @@ export const TenantsContext = createContext({ tenants: initialTenants, isInitComplete: false, resetTenants: noop, - appendTenant: noop, + prependTenant: noop, removeTenant: noop, updateTenant: noop, currentTenantId: '', @@ -103,8 +111,8 @@ function TenantsProvider({ children }: Props) { setCurrentTenantStatus('pending'); setIsInitComplete(true); }, - appendTenant: (tenant: TenantInfo) => { - setTenants((tenants) => [...tenants, tenant]); + prependTenant: (tenant: TenantInfo) => { + setTenants((tenants) => [tenant, ...tenants]); }, removeTenant: (tenantId: string) => { setTenants((tenants) => tenants.filter((tenant) => tenant.id !== tenantId));