Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(console): reorg resource details page #5634

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ function PermissionsTable({
render: ({ resource }) => (
<TextLink
className={styles.link}
to={`/api-resources/${resource.id}/${ApiResourceDetailsTabs.Settings}`}
to={`/api-resources/${resource.id}/${ApiResourceDetailsTabs.General}`}
>
{resource.name}
</TextLink>
Expand Down
2 changes: 1 addition & 1 deletion packages/console/src/consts/page-tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export enum ApplicationDetailsTabs {
}

export enum ApiResourceDetailsTabs {
Settings = 'settings',
Permissions = 'permissions',
General = 'general',
}

export enum ConnectorsTabs {
Expand Down
12 changes: 1 addition & 11 deletions packages/console/src/containers/ConsoleContent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useContext } from 'react';
import { Navigate, Route, Routes, useOutletContext } from 'react-router-dom';

import {
ApiResourceDetailsTabs,
ApplicationDetailsTabs,
ConnectorsTabs,
EnterpriseSsoDetailsTabs,
Expand All @@ -17,8 +16,6 @@ import { TenantsContext } from '@/contexts/TenantsProvider';
import OverlayScrollbar from '@/ds-components/OverlayScrollbar';
import useCurrentTenantScopes from '@/hooks/use-current-tenant-scopes';
import ApiResourceDetails from '@/pages/ApiResourceDetails';
import ApiResourcePermissions from '@/pages/ApiResourceDetails/ApiResourcePermissions';
import ApiResourceSettings from '@/pages/ApiResourceDetails/ApiResourceSettings';
import ApiResources from '@/pages/ApiResources';
import ApplicationDetails from '@/pages/ApplicationDetails';
import Applications from '@/pages/Applications';
Expand Down Expand Up @@ -112,14 +109,7 @@ function ConsoleContent() {
<Route index element={<ApiResources />} />
<Route path="create" element={<ApiResources />} />
<Route path=":id/guide/:guideId" element={<ApiResourceDetails />} />
<Route path=":id" element={<ApiResourceDetails />}>
<Route index element={<Navigate replace to={ApiResourceDetailsTabs.Settings} />} />
<Route path={ApiResourceDetailsTabs.Settings} element={<ApiResourceSettings />} />
<Route
path={ApiResourceDetailsTabs.Permissions}
element={<ApiResourcePermissions />}
/>
</Route>
<Route path=":id/*" element={<ApiResourceDetails />} />
</Route>
<Route path="sign-in-experience">
<Route index element={<Navigate replace to={SignInExperienceTab.Branding} />} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { ScopeResponse } from '@logto/schemas';
import { isManagementApi, type Resource, type ScopeResponse } from '@logto/schemas';
import { conditional } from '@silverhand/essentials';
import { useState } from 'react';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
import { useOutletContext } from 'react-router-dom';
import useSWR from 'swr';

import PermissionsTable from '@/components/PermissionsTable';
Expand All @@ -13,17 +12,17 @@ import useApi from '@/hooks/use-api';
import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher';
import { buildUrl, formatSearchKeyword } from '@/utils/url';

import type { ApiResourceDetailsOutletContext } from '../types';

import CreatePermissionModal from './components/CreatePermissionModal';

const pageSize = defaultPageSize;

function ApiResourcePermissions() {
const {
resource: { id: resourceId },
isLogtoManagementApiResource,
} = useOutletContext<ApiResourceDetailsOutletContext>();
type Props = {
resource: Resource;
};

function ApiResourcePermissions({ resource }: Props) {
const { id: resourceId, indicator } = resource;
const isLogtoManagementApiResource = isManagementApi(indicator);

const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { Resource } from '@logto/schemas';
import { isManagementApi, type Resource } from '@logto/schemas';
import { useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { Trans, useTranslation } from 'react-i18next';
import { useOutletContext } from 'react-router-dom';

import DetailsForm from '@/components/DetailsForm';
import FormCard from '@/components/FormCard';
Expand All @@ -15,11 +14,14 @@ import useApi from '@/hooks/use-api';
import useDocumentationUrl from '@/hooks/use-documentation-url';
import { trySubmitSafe } from '@/utils/form';

import type { ApiResourceDetailsOutletContext } from '../types';
type Props = {
resource: Resource;
isDeleting: boolean;
onResourceUpdated: (updatedData: Resource) => void;
};

function ApiResourceSettings() {
const { resource, isDeleting, isLogtoManagementApiResource, onResourceUpdated } =
useOutletContext<ApiResourceDetailsOutletContext>();
function ApiResourceSettings({ resource, isDeleting, onResourceUpdated }: Props) {
const isLogtoManagementApiResource = isManagementApi(resource.indicator);

const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { getDocumentationUrl } = useDocumentationUrl();
Expand Down
42 changes: 25 additions & 17 deletions packages/console/src/pages/ApiResourceDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import classNames from 'classnames';
import { useEffect, useState } from 'react';
import { toast } from 'react-hot-toast';
import { Trans, useTranslation } from 'react-i18next';
import { Outlet, useLocation, useParams } from 'react-router-dom';
import { Navigate, Route, Routes, useLocation, useParams } from 'react-router-dom';
import useSWR from 'swr';

import ApiResourceDark from '@/assets/icons/api-resource-dark.svg';
Expand All @@ -28,11 +28,12 @@ import useDocumentationUrl from '@/hooks/use-documentation-url';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import useTheme from '@/hooks/use-theme';

import ApiResourcePermissions from './ApiResourcePermissions';
import ApiResourceSettings from './ApiResourceSettings';
import GuideDrawer from './components/GuideDrawer';
import GuideModal from './components/GuideModal';
import ManagementApiNotice from './components/ManagementApiNotice';
import * as styles from './index.module.scss';
import { type ApiResourceDetailsOutletContext } from './types';

const icons = {
[Theme.Light]: { ApiIcon: ApiResource, ManagementApiIcon: ManagementApiResource },
Expand Down Expand Up @@ -170,25 +171,32 @@ function ApiResourceDetails() {
</DeleteConfirmModal>
)}
<TabNav>
<TabNavItem href={`/api-resources/${data.id}/${ApiResourceDetailsTabs.Settings}`}>
{t('api_resource_details.settings_tab')}
</TabNavItem>
<TabNavItem href={`/api-resources/${data.id}/${ApiResourceDetailsTabs.Permissions}`}>
{t('api_resource_details.permissions_tab')}
</TabNavItem>
<TabNavItem href={`/api-resources/${data.id}/${ApiResourceDetailsTabs.General}`}>
{t('api_resource_details.general_tab')}
</TabNavItem>
</TabNav>
<Outlet
context={
{
resource: data,
isDeleting,
isLogtoManagementApiResource,
onResourceUpdated: (resource: Resource) => {
void mutate(resource);
},
} satisfies ApiResourceDetailsOutletContext
}
/>
<Routes>
<Route index element={<Navigate replace to={ApiResourceDetailsTabs.Permissions} />} />
<Route
path={ApiResourceDetailsTabs.Permissions}
element={<ApiResourcePermissions resource={data} />}
/>
<Route
path={ApiResourceDetailsTabs.General}
element={
<ApiResourceSettings
resource={data}
isDeleting={isDeleting}
onResourceUpdated={(updatedData: Resource) => {
void mutate(updatedData);
}}
/>
}
/>
</Routes>
</>
)}
</DetailsPage>
Expand Down
8 changes: 0 additions & 8 deletions packages/console/src/pages/ApiResourceDetails/types.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/console/src/pages/ApiResources/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const pageSize = defaultPageSize;
const apiResourcesPathname = '/api-resources';
const createApiResourcePathname = `${apiResourcesPathname}/create`;
const buildDetailsPathname = (id: string) =>
`${apiResourcesPathname}/${id}/${ApiResourceDetailsTabs.Settings}`;
`${apiResourcesPathname}/${id}/${ApiResourceDetailsTabs.Permissions}`;

const icons = {
[Theme.Light]: { ApiIcon: ApiResource, ManagementApiIcon: ManagementApiResource },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
expectConfirmModalAndAct,
expectModalWithTitle,
expectToClickModalAction,
expectToClickNavTab,
goToAdminConsole,
waitForToast,
} from '#src/ui-helpers/index.js';
Expand Down Expand Up @@ -91,9 +92,7 @@ describe('M2M RBAC', () => {
});

it('create permission for api resource', async () => {
await expect(page).toClick('nav div[class$=item] div[class$=link] a', {
text: 'Permissions',
});
await expectToClickNavTab(page, 'Permissions');

await expect(page).toClick('div[class$=filter] button[class$=createButton] span', {
text: 'Create permission',
Expand Down Expand Up @@ -190,9 +189,7 @@ describe('M2M RBAC', () => {
});

it('delete a permission from a role on the role details page', async () => {
await expect(page).toClick('nav div[class$=item] div[class$=link] a', {
text: 'Permissions',
});
await expectToClickNavTab(page, 'Permissions');

await expectToSelectPermissionAction(page, {
permissionName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
expectModalWithTitle,
expectToClickDetailsPageOption,
expectToClickModalAction,
expectToClickNavTab,
goToAdminConsole,
waitForToast,
} from '#src/ui-helpers/index.js';
Expand Down Expand Up @@ -80,7 +81,7 @@ describe('User RBAC', () => {
});

it('create api permissions', async () => {
await expect(page).toClick('nav div[class$=item] div[class$=link] a', {
await expect(page).toClick('nav div[class$=item] div[class*=link] a', {
text: 'Permissions',
});

Expand Down Expand Up @@ -194,9 +195,7 @@ describe('User RBAC', () => {
});

it('delete a permission from a role on the role details page', async () => {
await expect(page).toClick('nav div[class$=item] div[class$=link] a', {
text: 'Permissions',
});
await expectToClickNavTab(page, 'Permissions');

await expectToSelectPermissionAction(page, {
permissionName,
Expand Down Expand Up @@ -390,9 +389,7 @@ describe('User RBAC', () => {
});

// Navigate to permissions tab
await expect(page).toClick('nav div[class$=item] div[class$=link] a', {
text: 'Permissions',
});
await expectToClickNavTab(page, 'Permissions');

await expectToSelectPermissionAction(page, {
permissionName,
Expand Down
2 changes: 1 addition & 1 deletion packages/integration-tests/src/ui-helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export const expectConfirmModalAndAct = async (
};

export const expectToClickNavTab = async (page: Page, tab: string) => {
await expect(page).toClick('nav div[class$=item] div[class$=link] a', {
await expect(page).toClick('nav div[class$=item] div[class*=link] a', {
text: tab,
});
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'API Ressourcendetails',
back_to_api_resources: 'Zurück zu API Ressourcen',
settings_tab: 'Einstellungen',
general_tab: 'Allgemein',
permissions_tab: 'Berechtigungen',
settings: 'Einstellungen',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'API resource details',
back_to_api_resources: 'Back to API resources',
settings_tab: 'Settings',
general_tab: 'General',
permissions_tab: 'Permissions',
settings: 'Settings',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'Detalles del recurso de la API',
back_to_api_resources: 'Volver a los recursos de la API',
settings_tab: 'Configuración',
general_tab: 'General',
permissions_tab: 'Permisos',
settings: 'Configuración',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'Détails de la ressource API',
back_to_api_resources: 'Retour aux ressources API',
settings_tab: 'Paramètres',
general_tab: 'Général',
permissions_tab: 'Autorisations',
settings: 'Paramètres',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'Dettagli delle risorse API',
back_to_api_resources: 'Torna alle risorse API',
settings_tab: 'Impostazioni',
general_tab: 'Generale',
permissions_tab: 'Autorizzazioni',
settings: 'Impostazioni',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'APIリソースの詳細 ',
back_to_api_resources: 'APIリソースに戻る',
settings_tab: '設定',
general_tab: '一般',
permissions_tab: '権限',
settings: '設定',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'API 리소스 세부 정보',
back_to_api_resources: 'API 리소스로 돌아가기',
settings_tab: '설정',
general_tab: '일반',
permissions_tab: '권한',
settings: '설정',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'Szczegóły zasobów API',
back_to_api_resources: 'Powróć do zasobów API',
settings_tab: 'Ustawienia',
general_tab: 'Ogólne',
permissions_tab: 'Uprawnienia',
settings: 'Ustawienia',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'Detalhes do Recurso da API',
back_to_api_resources: 'Voltar para os recursos da API',
settings_tab: 'Configurações',
general_tab: 'Geral',
permissions_tab: 'Permissões',
settings: 'Configurações',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'Detalhes do recurso da API',
back_to_api_resources: 'Voltar aos recursos da API',
settings_tab: 'Configurações',
general_tab: 'Geral',
permissions_tab: 'Permissões',
settings: 'Configurações',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'Детали ресурса API',
back_to_api_resources: 'Вернуться к Ресурсам API',
settings_tab: 'Настройки',
general_tab: 'Общее',
permissions_tab: 'Разрешения',
settings: 'Настройки',
settings_description:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const api_resource_details = {
page_title: 'API Kaynak detayları',
back_to_api_resources: 'API Kaynaklarına geri dön',
settings_tab: 'Ayarlar',
general_tab: 'Genel',
permissions_tab: 'İzinler',
settings: 'Ayarlar',
settings_description:
Expand Down
Loading
Loading