mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
Merge pull request #4811 from logto-io/charles-add-org-guide-drawer
feat(console): add organization details guide drawer
This commit is contained in:
commit
9ea79a18d6
7 changed files with 94 additions and 60 deletions
|
@ -7,7 +7,7 @@
|
|||
bottom: 0;
|
||||
width: 50%;
|
||||
max-width: 900px;
|
||||
min-width: 770px;
|
||||
min-width: 800px;
|
||||
outline: none;
|
||||
background: var(--color-base);
|
||||
|
||||
|
|
|
@ -4,19 +4,23 @@ import { useTranslation } from 'react-i18next';
|
|||
import { Navigate, Route, Routes, useParams } from 'react-router-dom';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import Delete from '@/assets/icons/delete.svg';
|
||||
import File from '@/assets/icons/file.svg';
|
||||
import OrganizationIcon from '@/assets/icons/organization-preview.svg';
|
||||
import ActionsButton from '@/components/ActionsButton';
|
||||
import AppError from '@/components/AppError';
|
||||
import DetailsPage from '@/components/DetailsPage';
|
||||
import DetailsPageHeader from '@/components/DetailsPage/DetailsPageHeader';
|
||||
import Skeleton from '@/components/DetailsPage/Skeleton';
|
||||
import Drawer from '@/components/Drawer';
|
||||
import PageMeta from '@/components/PageMeta';
|
||||
import ThemedIcon from '@/components/ThemedIcon';
|
||||
import Card from '@/ds-components/Card';
|
||||
import CopyToClipboard from '@/ds-components/CopyToClipboard';
|
||||
import DeleteConfirmModal from '@/ds-components/DeleteConfirmModal';
|
||||
import TabNav, { TabNavItem } from '@/ds-components/TabNav';
|
||||
import useApi, { type RequestError } from '@/hooks/use-api';
|
||||
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
||||
|
||||
import IntroductionAndPermissions from '../Organizations/Guide/IntroductionAndPermissions';
|
||||
|
||||
import Members from './Members';
|
||||
import Settings from './Settings';
|
||||
import * as styles from './index.module.scss';
|
||||
|
@ -35,6 +39,8 @@ function OrganizationDetails() {
|
|||
id && `api/organizations/${id}`
|
||||
);
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
const [isGuideDrawerOpen, setIsGuideDrawerOpen] = useState(false);
|
||||
const [isDeleteFormOpen, setIsDeleteFormOpen] = useState(false);
|
||||
const api = useApi();
|
||||
|
||||
const deleteOrganization = useCallback(async () => {
|
||||
|
@ -60,27 +66,46 @@ function OrganizationDetails() {
|
|||
{error && <AppError errorCode={error.body?.code} errorMessage={error.body?.message} />}
|
||||
{data && (
|
||||
<>
|
||||
<Card className={styles.header}>
|
||||
<div className={styles.metadata}>
|
||||
<ThemedIcon for={OrganizationIcon} size={60} />
|
||||
<div>
|
||||
<div className={styles.name}>{data.name}</div>
|
||||
<div className={styles.row}>
|
||||
<span className={styles.label}>{t('organization_details.organization_id')} </span>
|
||||
<CopyToClipboard size="default" value={data.id} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ActionsButton
|
||||
buttonProps={{
|
||||
type: 'default',
|
||||
size: 'large',
|
||||
<DetailsPageHeader
|
||||
icon={<ThemedIcon for={OrganizationIcon} size={60} />}
|
||||
title={data.name}
|
||||
identifier={{ name: t('organization_details.organization_id'), value: data.id }}
|
||||
additionalActionButton={{
|
||||
icon: <File />,
|
||||
title: 'application_details.check_guide',
|
||||
onClick: () => {
|
||||
setIsGuideDrawerOpen(true);
|
||||
},
|
||||
}}
|
||||
deleteConfirmation="organization_details.delete_confirmation"
|
||||
fieldName="organizations.title"
|
||||
onDelete={deleteOrganization}
|
||||
actionMenuItems={[
|
||||
{
|
||||
icon: <Delete />,
|
||||
title: 'general.delete',
|
||||
type: 'danger',
|
||||
onClick: () => {
|
||||
setIsDeleteFormOpen(true);
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Card>
|
||||
<Drawer
|
||||
isOpen={isGuideDrawerOpen}
|
||||
onClose={() => {
|
||||
setIsGuideDrawerOpen(false);
|
||||
}}
|
||||
>
|
||||
<IntroductionAndPermissions isReadonly />
|
||||
</Drawer>
|
||||
<DeleteConfirmModal
|
||||
isOpen={isDeleteFormOpen}
|
||||
isLoading={isDeleting}
|
||||
onCancel={() => {
|
||||
setIsDeleteFormOpen(false);
|
||||
}}
|
||||
onConfirm={deleteOrganization}
|
||||
>
|
||||
{t('organization_details.delete_confirmation')}
|
||||
</DeleteConfirmModal>
|
||||
<TabNav>
|
||||
<TabNavItem href={`${pathname}/${data.id}/${tabs.settings}`}>
|
||||
{t('general.settings_nav')}
|
||||
|
|
|
@ -39,9 +39,14 @@ type PermissionForm = {
|
|||
permissions: Array<Omit<OrganizationScope, 'id' | 'tenantId'>>;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
/* True if the guide is in the "Check guide" drawer of organization details page */
|
||||
isReadonly?: boolean;
|
||||
};
|
||||
|
||||
const defaultPermission = { name: '', description: '' };
|
||||
|
||||
function CreatePermissions() {
|
||||
function IntroductionAndPermissions({ isReadonly }: Props) {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console.organizations.guide' });
|
||||
const theme = useTheme();
|
||||
const { OrganizationIcon, PermissionIcon } = icons[theme];
|
||||
|
@ -100,6 +105,7 @@ function CreatePermissions() {
|
|||
<OrganizationIcon className={styles.icon} />
|
||||
<Introduction />
|
||||
</Card>
|
||||
{!isReadonly && (
|
||||
<Card className={styles.card}>
|
||||
<PermissionIcon className={styles.icon} />
|
||||
<div className={styles.title}>{t('step_1')}</div>
|
||||
|
@ -128,13 +134,16 @@ function CreatePermissions() {
|
|||
/>
|
||||
</form>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
</OverlayScrollbar>
|
||||
{!isReadonly && (
|
||||
<ActionBar step={1} totalSteps={3}>
|
||||
<Button isLoading={isSubmitting} title="general.next" type="primary" onClick={onSubmit} />
|
||||
</ActionBar>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default CreatePermissions;
|
||||
export default IntroductionAndPermissions;
|
|
@ -7,8 +7,8 @@ import useTenantPathname from '@/hooks/use-tenant-pathname';
|
|||
import * as modalStyles from '@/scss/modal.module.scss';
|
||||
|
||||
import CreateOrganization from './CreateOrganization';
|
||||
import CreatePermissions from './CreatePermissions';
|
||||
import CreateRoles from './CreateRoles';
|
||||
import IntroductionAndPermissions from './IntroductionAndPermissions';
|
||||
import { steps } from './const';
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
|
@ -29,7 +29,7 @@ function Guide() {
|
|||
/>
|
||||
<Routes>
|
||||
<Route index element={<Navigate replace to={steps.createPermissions} />} />
|
||||
<Route path={steps.createPermissions} element={<CreatePermissions />} />
|
||||
<Route path={steps.createPermissions} element={<IntroductionAndPermissions />} />
|
||||
<Route path={steps.createRoles} element={<CreateRoles />} />
|
||||
<Route path={steps.createOrganization} element={<CreateOrganization />} />
|
||||
</Routes>
|
||||
|
|
Loading…
Reference in a new issue