mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
refactor(console): update organization guide and tenant member routers (#5766)
This commit is contained in:
parent
fcfa2c7d26
commit
711c51c0fd
4 changed files with 36 additions and 36 deletions
|
@ -1,6 +1,6 @@
|
||||||
import { condArray } from '@silverhand/essentials';
|
import { condArray } from '@silverhand/essentials';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { type RouteObject } from 'react-router-dom';
|
import { Navigate, type RouteObject } from 'react-router-dom';
|
||||||
|
|
||||||
import { isCloud, isDevFeaturesEnabled } from '@/consts/env';
|
import { isCloud, isDevFeaturesEnabled } from '@/consts/env';
|
||||||
import Dashboard from '@/pages/Dashboard';
|
import Dashboard from '@/pages/Dashboard';
|
||||||
|
@ -8,6 +8,11 @@ import GetStarted from '@/pages/GetStarted';
|
||||||
import Mfa from '@/pages/Mfa';
|
import Mfa from '@/pages/Mfa';
|
||||||
import NotFound from '@/pages/NotFound';
|
import NotFound from '@/pages/NotFound';
|
||||||
import OrganizationGuide from '@/pages/Organizations/Guide';
|
import OrganizationGuide from '@/pages/Organizations/Guide';
|
||||||
|
import Introduction from '@/pages/Organizations/Guide/Introduction';
|
||||||
|
import OrganizationInfo from '@/pages/Organizations/Guide/OrganizationInfo';
|
||||||
|
import OrganizationPermissions from '@/pages/Organizations/Guide/OrganizationPermissions';
|
||||||
|
import OrganizationRoles from '@/pages/Organizations/Guide/OrganizationRoles';
|
||||||
|
import { steps } from '@/pages/Organizations/Guide/const';
|
||||||
import SigningKeys from '@/pages/SigningKeys';
|
import SigningKeys from '@/pages/SigningKeys';
|
||||||
|
|
||||||
import { apiResources } from './routes/api-resources';
|
import { apiResources } from './routes/api-resources';
|
||||||
|
@ -46,7 +51,17 @@ export const useConsoleRoutes = () => {
|
||||||
roles,
|
roles,
|
||||||
isDevFeaturesEnabled && organizationTemplate,
|
isDevFeaturesEnabled && organizationTemplate,
|
||||||
organizations,
|
organizations,
|
||||||
!isDevFeaturesEnabled && { path: 'organization-guide/*', element: <OrganizationGuide /> },
|
!isDevFeaturesEnabled && {
|
||||||
|
path: 'organization-guide/*',
|
||||||
|
element: <OrganizationGuide />,
|
||||||
|
children: [
|
||||||
|
{ index: true, element: <Navigate replace to={steps.introduction} /> },
|
||||||
|
{ path: steps.introduction, element: <Introduction /> },
|
||||||
|
{ path: steps.permissions, element: <OrganizationPermissions /> },
|
||||||
|
{ path: steps.roles, element: <OrganizationRoles /> },
|
||||||
|
{ path: steps.organizationInfo, element: <OrganizationInfo /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
profile,
|
profile,
|
||||||
{ path: 'signing-keys', element: <SigningKeys /> },
|
{ path: 'signing-keys', element: <SigningKeys /> },
|
||||||
isCloud && tenantSettings,
|
isCloud && tenantSettings,
|
||||||
|
|
|
@ -5,17 +5,20 @@ import { Navigate, type RouteObject } from 'react-router-dom';
|
||||||
import { TenantSettingsTabs } from '@/consts';
|
import { TenantSettingsTabs } from '@/consts';
|
||||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||||
import useCurrentTenantScopes from '@/hooks/use-current-tenant-scopes';
|
import useCurrentTenantScopes from '@/hooks/use-current-tenant-scopes';
|
||||||
|
import NotFound from '@/pages/NotFound';
|
||||||
import TenantSettings from '@/pages/TenantSettings';
|
import TenantSettings from '@/pages/TenantSettings';
|
||||||
import BillingHistory from '@/pages/TenantSettings/BillingHistory';
|
import BillingHistory from '@/pages/TenantSettings/BillingHistory';
|
||||||
import Subscription from '@/pages/TenantSettings/Subscription';
|
import Subscription from '@/pages/TenantSettings/Subscription';
|
||||||
import TenantBasicSettings from '@/pages/TenantSettings/TenantBasicSettings';
|
import TenantBasicSettings from '@/pages/TenantSettings/TenantBasicSettings';
|
||||||
import TenantDomainSettings from '@/pages/TenantSettings/TenantDomainSettings';
|
import TenantDomainSettings from '@/pages/TenantSettings/TenantDomainSettings';
|
||||||
import TenantMembers from '@/pages/TenantSettings/TenantMembers';
|
import TenantMembers from '@/pages/TenantSettings/TenantMembers';
|
||||||
|
import Invitations from '@/pages/TenantSettings/TenantMembers/Invitations';
|
||||||
|
import Members from '@/pages/TenantSettings/TenantMembers/Members';
|
||||||
|
|
||||||
export const useTenantSettings = () => {
|
export const useTenantSettings = () => {
|
||||||
const { isDevTenant } = useContext(TenantsContext);
|
const { isDevTenant } = useContext(TenantsContext);
|
||||||
const {
|
const {
|
||||||
access: { canManageTenant },
|
access: { canInviteMember, canManageTenant },
|
||||||
} = useCurrentTenantScopes();
|
} = useCurrentTenantScopes();
|
||||||
|
|
||||||
const tenantSettings: RouteObject = useMemo(
|
const tenantSettings: RouteObject = useMemo(
|
||||||
|
@ -33,7 +36,15 @@ export const useTenantSettings = () => {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ path: TenantSettingsTabs.Settings, element: <TenantBasicSettings /> },
|
{ path: TenantSettingsTabs.Settings, element: <TenantBasicSettings /> },
|
||||||
{ path: `${TenantSettingsTabs.Members}/*`, element: <TenantMembers /> },
|
{
|
||||||
|
path: `${TenantSettingsTabs.Members}/*`,
|
||||||
|
element: <TenantMembers />,
|
||||||
|
children: [
|
||||||
|
{ path: '*', element: <NotFound /> },
|
||||||
|
{ index: true, element: <Members /> },
|
||||||
|
...condArray(canInviteMember && [{ path: 'invitations', element: <Invitations /> }]),
|
||||||
|
],
|
||||||
|
},
|
||||||
{ path: TenantSettingsTabs.Domains, element: <TenantDomainSettings /> },
|
{ path: TenantSettingsTabs.Domains, element: <TenantDomainSettings /> },
|
||||||
!isDevTenant &&
|
!isDevTenant &&
|
||||||
canManageTenant && [
|
canManageTenant && [
|
||||||
|
@ -42,7 +53,7 @@ export const useTenantSettings = () => {
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
[canManageTenant, isDevTenant]
|
[canInviteMember, canManageTenant, isDevTenant]
|
||||||
);
|
);
|
||||||
|
|
||||||
return tenantSettings;
|
return tenantSettings;
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import Modal from 'react-modal';
|
import Modal from 'react-modal';
|
||||||
// FIXME: @charles
|
import { Outlet } from 'react-router-dom';
|
||||||
// eslint-disable-next-line no-restricted-imports
|
|
||||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
|
||||||
|
|
||||||
import DsModalHeader from '@/ds-components/ModalHeader';
|
import DsModalHeader from '@/ds-components/ModalHeader';
|
||||||
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
||||||
import * as modalStyles from '@/scss/modal.module.scss';
|
import * as modalStyles from '@/scss/modal.module.scss';
|
||||||
|
|
||||||
import Introduction from './Introduction';
|
|
||||||
import OrganizationInfo from './OrganizationInfo';
|
|
||||||
import OrganizationPermissions from './OrganizationPermissions';
|
|
||||||
import OrganizationRoles from './OrganizationRoles';
|
|
||||||
import { steps } from './const';
|
|
||||||
import * as styles from './index.module.scss';
|
import * as styles from './index.module.scss';
|
||||||
|
|
||||||
function Guide() {
|
function Guide() {
|
||||||
|
@ -30,13 +23,7 @@ function Guide() {
|
||||||
subtitle="organizations.guide.subtitle"
|
subtitle="organizations.guide.subtitle"
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
/>
|
/>
|
||||||
<Routes>
|
<Outlet />
|
||||||
<Route index element={<Navigate replace to={steps.introduction} />} />
|
|
||||||
<Route path={steps.introduction} element={<Introduction />} />
|
|
||||||
<Route path={steps.permissions} element={<OrganizationPermissions />} />
|
|
||||||
<Route path={steps.roles} element={<OrganizationRoles />} />
|
|
||||||
<Route path={steps.organizationInfo} element={<OrganizationInfo />} />
|
|
||||||
</Routes>
|
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useContext, useState } from 'react';
|
import { useContext, useState } from 'react';
|
||||||
// FIXME: @charles
|
import { Outlet } from 'react-router-dom';
|
||||||
// eslint-disable-next-line no-restricted-imports
|
|
||||||
import { Route, Routes } from 'react-router-dom';
|
|
||||||
import useSWRMutation from 'swr/mutation';
|
import useSWRMutation from 'swr/mutation';
|
||||||
|
|
||||||
import InvitationIcon from '@/assets/icons/invitation.svg';
|
import InvitationIcon from '@/assets/icons/invitation.svg';
|
||||||
|
@ -16,16 +14,11 @@ import Button from '@/ds-components/Button';
|
||||||
import Spacer from '@/ds-components/Spacer';
|
import Spacer from '@/ds-components/Spacer';
|
||||||
import useCurrentTenantScopes from '@/hooks/use-current-tenant-scopes';
|
import useCurrentTenantScopes from '@/hooks/use-current-tenant-scopes';
|
||||||
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
||||||
import NotFound from '@/pages/NotFound';
|
|
||||||
|
|
||||||
import Invitations from './Invitations';
|
|
||||||
import InviteMemberModal from './InviteMemberModal';
|
import InviteMemberModal from './InviteMemberModal';
|
||||||
import Members from './Members';
|
|
||||||
import useTenantMembersUsage from './hooks';
|
import useTenantMembersUsage from './hooks';
|
||||||
import * as styles from './index.module.scss';
|
import * as styles from './index.module.scss';
|
||||||
|
|
||||||
const invitationsRoute = 'invitations';
|
|
||||||
|
|
||||||
function TenantMembers() {
|
function TenantMembers() {
|
||||||
const { hasTenantMembersSurpassedLimit } = useTenantMembersUsage();
|
const { hasTenantMembersSurpassedLimit } = useTenantMembersUsage();
|
||||||
const { navigate, match } = useTenantPathname();
|
const { navigate, match } = useTenantPathname();
|
||||||
|
@ -34,9 +27,7 @@ function TenantMembers() {
|
||||||
access: { canInviteMember },
|
access: { canInviteMember },
|
||||||
} = useCurrentTenantScopes();
|
} = useCurrentTenantScopes();
|
||||||
|
|
||||||
const isInvitationTab = match(
|
const isInvitationTab = match(`/tenant-settings/${TenantSettingsTabs.Members}/invitations`);
|
||||||
`/tenant-settings/${TenantSettingsTabs.Members}/${invitationsRoute}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const { currentTenantId } = useContext(TenantsContext);
|
const { currentTenantId } = useContext(TenantsContext);
|
||||||
const cloudApi = useAuthedCloudApi();
|
const cloudApi = useAuthedCloudApi();
|
||||||
|
@ -84,11 +75,7 @@ function TenantMembers() {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Routes>
|
<Outlet />
|
||||||
<Route path="*" element={<NotFound />} />
|
|
||||||
<Route index element={<Members />} />
|
|
||||||
{canInviteMember && <Route path={invitationsRoute} element={<Invitations />} />}
|
|
||||||
</Routes>
|
|
||||||
{canInviteMember && (
|
{canInviteMember && (
|
||||||
<InviteMemberModal
|
<InviteMemberModal
|
||||||
isOpen={showInviteModal}
|
isOpen={showInviteModal}
|
||||||
|
|
Loading…
Reference in a new issue