From c40a7d3a7a3603649b8b042093d67ca842485909 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Wed, 16 Aug 2023 23:16:18 -0500 Subject: [PATCH] refactor(console): hide navigation anchors from guide in compact view (#4347) * refactor(console): hide navigation anchors from guide in compact view * refactor(console): check app guide drawer in app details page (#4348) --- .../console/src/assets/docs/guides/index.ts | 7 - .../components/EnableAdminAccess.tsx | 2 +- .../assets/docs/guides/web-chatgpt/README.mdx | 1 - .../assets/docs/guides/web-chatgpt/index.ts | 12 - .../assets/docs/guides/web-chatgpt/logo.svg | 11 - .../components/AlwaysIssueRefreshToken.tsx | 2 +- .../components/ClientBasics/index.tsx | 2 +- .../docs/guides/web-gpt-plugin/index.ts | 1 + .../docs/guides/web-gpt-plugin/logo.svg | 17 +- .../components/EnvironmentVariables.tsx | 2 +- .../console/src/assets/icons/arrow-left.svg | 2 +- .../ApplicationCredentials/index.tsx | 2 +- .../src/mdx-components-v2/Sample/index.tsx | 2 +- .../mdx-components-v2/Steps/index.module.scss | 4 + .../src/mdx-components-v2/Steps/index.tsx | 32 +-- .../mdx-components-v2/UriInputField/index.tsx | 2 +- .../components/GuideDrawer/index.module.scss | 37 +++ .../components/GuideDrawer/index.tsx | 101 ++++++++ .../src/pages/ApplicationDetails/index.tsx | 14 +- .../components/Guide/GuideModal.tsx | 4 +- .../components/Guide/index.module.scss | 59 ++++- .../Applications/components/Guide/index.tsx | 217 +++++++++--------- .../components/GuideCard/index.module.scss | 4 + .../components/GuideCard/index.tsx | 31 ++- .../components/GuideGroup/index.module.scss | 35 +++ .../components/GuideGroup/index.tsx | 48 ++++ .../components/GuideLibrary/index.module.scss | 32 --- .../components/GuideLibrary/index.tsx | 87 +++---- .../components/GuideLibraryModal/index.tsx | 2 +- .../components/GuideV2/index.module.scss | 75 ------ .../Applications/components/GuideV2/index.tsx | 145 ------------ .../components/SdkSelector/index.module.scss | 75 ------ .../components/SdkSelector/index.tsx | 99 -------- packages/console/src/types/applications.ts | 21 -- .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + .../translation/admin-console/applications.ts | 2 + 49 files changed, 524 insertions(+), 693 deletions(-) delete mode 100644 packages/console/src/assets/docs/guides/web-chatgpt/README.mdx delete mode 100644 packages/console/src/assets/docs/guides/web-chatgpt/index.ts delete mode 100644 packages/console/src/assets/docs/guides/web-chatgpt/logo.svg create mode 100644 packages/console/src/pages/ApplicationDetails/components/GuideDrawer/index.module.scss create mode 100644 packages/console/src/pages/ApplicationDetails/components/GuideDrawer/index.tsx create mode 100644 packages/console/src/pages/Applications/components/GuideGroup/index.module.scss create mode 100644 packages/console/src/pages/Applications/components/GuideGroup/index.tsx delete mode 100644 packages/console/src/pages/Applications/components/GuideV2/index.module.scss delete mode 100644 packages/console/src/pages/Applications/components/GuideV2/index.tsx delete mode 100644 packages/console/src/pages/Applications/components/SdkSelector/index.module.scss delete mode 100644 packages/console/src/pages/Applications/components/SdkSelector/index.tsx diff --git a/packages/console/src/assets/docs/guides/index.ts b/packages/console/src/assets/docs/guides/index.ts index f34deea49..ce6387ae0 100644 --- a/packages/console/src/assets/docs/guides/index.ts +++ b/packages/console/src/assets/docs/guides/index.ts @@ -12,7 +12,6 @@ import spaReact from './spa-react/index'; import spaVanilla from './spa-vanilla/index'; import spaVue from './spa-vue/index'; import { type Guide } from './types'; -import webChatgpt from './web-chatgpt/index'; import webCsharp from './web-csharp/index'; import webExpress from './web-express/index'; import webGo from './web-go/index'; @@ -80,12 +79,6 @@ const guides: Readonly = Object.freeze([ Component: lazy(async () => import('./spa-vue/README.mdx')), metadata: spaVue, }, - { - id: 'web-chatgpt', - Logo: lazy(async () => import('./web-chatgpt/logo.svg')), - Component: lazy(async () => import('./web-chatgpt/README.mdx')), - metadata: webChatgpt, - }, { id: 'web-csharp', Logo: lazy(async () => import('./web-csharp/logo.svg')), diff --git a/packages/console/src/assets/docs/guides/m2m-general/components/EnableAdminAccess.tsx b/packages/console/src/assets/docs/guides/m2m-general/components/EnableAdminAccess.tsx index e374c693c..7ed7eea0b 100644 --- a/packages/console/src/assets/docs/guides/m2m-general/components/EnableAdminAccess.tsx +++ b/packages/console/src/assets/docs/guides/m2m-general/components/EnableAdminAccess.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'; import FormField from '@/ds-components/FormField'; import Switch from '@/ds-components/Switch'; import useApi from '@/hooks/use-api'; -import { GuideContext } from '@/pages/Applications/components/GuideV2'; +import { GuideContext } from '@/pages/Applications/components/Guide'; export default function EnableAdminAccess() { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); diff --git a/packages/console/src/assets/docs/guides/web-chatgpt/README.mdx b/packages/console/src/assets/docs/guides/web-chatgpt/README.mdx deleted file mode 100644 index ae759f749..000000000 --- a/packages/console/src/assets/docs/guides/web-chatgpt/README.mdx +++ /dev/null @@ -1 +0,0 @@ -## Replace this with actual guide \ No newline at end of file diff --git a/packages/console/src/assets/docs/guides/web-chatgpt/index.ts b/packages/console/src/assets/docs/guides/web-chatgpt/index.ts deleted file mode 100644 index c61b0f6ec..000000000 --- a/packages/console/src/assets/docs/guides/web-chatgpt/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ApplicationType } from '@logto/schemas'; - -import { type GuideMetadata } from '../types'; - -const metadata: Readonly = Object.freeze({ - name: 'ChatGPT plugin', - description: 'Integrate ChatGPT Plugin OAuth with Logto.', - target: ApplicationType.Traditional, - isFeatured: true, -}); - -export default metadata; diff --git a/packages/console/src/assets/docs/guides/web-chatgpt/logo.svg b/packages/console/src/assets/docs/guides/web-chatgpt/logo.svg deleted file mode 100644 index b153d5dee..000000000 --- a/packages/console/src/assets/docs/guides/web-chatgpt/logo.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/packages/console/src/assets/docs/guides/web-gpt-plugin/components/AlwaysIssueRefreshToken.tsx b/packages/console/src/assets/docs/guides/web-gpt-plugin/components/AlwaysIssueRefreshToken.tsx index 37ad6199b..777ab413a 100644 --- a/packages/console/src/assets/docs/guides/web-gpt-plugin/components/AlwaysIssueRefreshToken.tsx +++ b/packages/console/src/assets/docs/guides/web-gpt-plugin/components/AlwaysIssueRefreshToken.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'; import FormField from '@/ds-components/FormField'; import Switch from '@/ds-components/Switch'; import useApi from '@/hooks/use-api'; -import { GuideContext } from '@/pages/Applications/components/GuideV2'; +import { GuideContext } from '@/pages/Applications/components/Guide'; export default function AlwaysIssueRefreshToken() { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); diff --git a/packages/console/src/assets/docs/guides/web-gpt-plugin/components/ClientBasics/index.tsx b/packages/console/src/assets/docs/guides/web-gpt-plugin/components/ClientBasics/index.tsx index ee0c93bce..ad1b757f0 100644 --- a/packages/console/src/assets/docs/guides/web-gpt-plugin/components/ClientBasics/index.tsx +++ b/packages/console/src/assets/docs/guides/web-gpt-plugin/components/ClientBasics/index.tsx @@ -2,7 +2,7 @@ import { useContext } from 'react'; import CopyToClipboard from '@/ds-components/CopyToClipboard'; import FormField from '@/ds-components/FormField'; -import { GuideContext } from '@/pages/Applications/components/GuideV2'; +import { GuideContext } from '@/pages/Applications/components/Guide'; import * as styles from './index.module.scss'; diff --git a/packages/console/src/assets/docs/guides/web-gpt-plugin/index.ts b/packages/console/src/assets/docs/guides/web-gpt-plugin/index.ts index 77a6a6d89..154f6589a 100644 --- a/packages/console/src/assets/docs/guides/web-gpt-plugin/index.ts +++ b/packages/console/src/assets/docs/guides/web-gpt-plugin/index.ts @@ -6,6 +6,7 @@ const metadata: Readonly = Object.freeze({ name: 'ChatGPT plugin', description: 'Use Logto as an OAuth identity provider for ChatGPT plugins.', target: ApplicationType.Traditional, + isFeatured: true, }); export default metadata; diff --git a/packages/console/src/assets/docs/guides/web-gpt-plugin/logo.svg b/packages/console/src/assets/docs/guides/web-gpt-plugin/logo.svg index 1fcac110f..b153d5dee 100644 --- a/packages/console/src/assets/docs/guides/web-gpt-plugin/logo.svg +++ b/packages/console/src/assets/docs/guides/web-gpt-plugin/logo.svg @@ -1,8 +1,11 @@ - - - + + + + + + + + + + diff --git a/packages/console/src/assets/docs/guides/web-outline/components/EnvironmentVariables.tsx b/packages/console/src/assets/docs/guides/web-outline/components/EnvironmentVariables.tsx index aff527ca0..e594f5104 100644 --- a/packages/console/src/assets/docs/guides/web-outline/components/EnvironmentVariables.tsx +++ b/packages/console/src/assets/docs/guides/web-outline/components/EnvironmentVariables.tsx @@ -5,7 +5,7 @@ import useSWR from 'swr'; import { openIdProviderConfigPath } from '@/consts/oidc'; import CopyToClipboard from '@/ds-components/CopyToClipboard'; import { type RequestError } from '@/hooks/use-api'; -import { GuideContext } from '@/pages/Applications/components/GuideV2'; +import { GuideContext } from '@/pages/Applications/components/Guide'; export default function EnvironmentVariables() { const { diff --git a/packages/console/src/assets/icons/arrow-left.svg b/packages/console/src/assets/icons/arrow-left.svg index 88c49ec93..c43c64e78 100644 --- a/packages/console/src/assets/icons/arrow-left.svg +++ b/packages/console/src/assets/icons/arrow-left.svg @@ -1,3 +1,3 @@ - + diff --git a/packages/console/src/mdx-components-v2/ApplicationCredentials/index.tsx b/packages/console/src/mdx-components-v2/ApplicationCredentials/index.tsx index 47963de77..dea42acf8 100644 --- a/packages/console/src/mdx-components-v2/ApplicationCredentials/index.tsx +++ b/packages/console/src/mdx-components-v2/ApplicationCredentials/index.tsx @@ -4,7 +4,7 @@ import { Trans, useTranslation } from 'react-i18next'; import CopyToClipboard from '@/ds-components/CopyToClipboard'; import FormField from '@/ds-components/FormField'; import TextLink from '@/ds-components/TextLink'; -import { GuideContext } from '@/pages/Applications/components/GuideV2'; +import { GuideContext } from '@/pages/Applications/components/Guide'; import * as styles from './index.module.scss'; diff --git a/packages/console/src/mdx-components-v2/Sample/index.tsx b/packages/console/src/mdx-components-v2/Sample/index.tsx index 1deff3272..ec93dc1a2 100644 --- a/packages/console/src/mdx-components-v2/Sample/index.tsx +++ b/packages/console/src/mdx-components-v2/Sample/index.tsx @@ -5,7 +5,7 @@ import { githubOrgLink } from '@/consts'; import { LinkButton } from '@/ds-components/Button'; import DangerousRaw from '@/ds-components/DangerousRaw'; import Spacer from '@/ds-components/Spacer'; -import { GuideContext } from '@/pages/Applications/components/GuideV2'; +import { GuideContext } from '@/pages/Applications/components/Guide'; import * as styles from './index.module.scss'; diff --git a/packages/console/src/mdx-components-v2/Steps/index.module.scss b/packages/console/src/mdx-components-v2/Steps/index.module.scss index 68ffb9bc3..e262f7aa0 100644 --- a/packages/console/src/mdx-components-v2/Steps/index.module.scss +++ b/packages/console/src/mdx-components-v2/Steps/index.module.scss @@ -4,6 +4,10 @@ position: relative; } +.fullWidth { + width: 100%; +} + .navigationAnchor { position: absolute; inset: 0 auto 0 0; diff --git a/packages/console/src/mdx-components-v2/Steps/index.tsx b/packages/console/src/mdx-components-v2/Steps/index.tsx index bde701bb7..4da29a37d 100644 --- a/packages/console/src/mdx-components-v2/Steps/index.tsx +++ b/packages/console/src/mdx-components-v2/Steps/index.tsx @@ -1,8 +1,9 @@ import { type Nullable } from '@silverhand/essentials'; import classNames from 'classnames'; -import React, { useRef, type ReactElement, useEffect, useState, useMemo } from 'react'; +import React, { useRef, type ReactElement, useEffect, useState, useMemo, useContext } from 'react'; import useScroll from '@/hooks/use-scroll'; +import { GuideContext } from '@/pages/Applications/components/Guide'; import Sample from '../Sample'; import { type Props as StepProps } from '../Step'; @@ -46,6 +47,7 @@ export default function Steps({ children: reactChildren }: Props) { : [reactChildren, furtherReadings], [furtherReadings, reactChildren] ); + const { isCompact } = useContext(GuideContext); useEffect(() => { // Make sure the step references length matches the number of children. @@ -75,19 +77,21 @@ export default function Steps({ children: reactChildren }: Props) { }, [children.length, scrollTop]); return ( -
-
- -
+
+ {!isCompact && ( +
+ +
+ )}
{children.map((component, index) => diff --git a/packages/console/src/mdx-components-v2/UriInputField/index.tsx b/packages/console/src/mdx-components-v2/UriInputField/index.tsx index cef99d0b5..0978fd3d7 100644 --- a/packages/console/src/mdx-components-v2/UriInputField/index.tsx +++ b/packages/console/src/mdx-components-v2/UriInputField/index.tsx @@ -18,7 +18,7 @@ import { import TextInput from '@/ds-components/TextInput'; import type { RequestError } from '@/hooks/use-api'; import useApi from '@/hooks/use-api'; -import { GuideContext } from '@/pages/Applications/components/GuideV2'; +import { GuideContext } from '@/pages/Applications/components/Guide'; import type { GuideForm } from '@/types/guide'; import { trySubmitSafe } from '@/utils/form'; import { uriValidator } from '@/utils/validator'; diff --git a/packages/console/src/pages/ApplicationDetails/components/GuideDrawer/index.module.scss b/packages/console/src/pages/ApplicationDetails/components/GuideDrawer/index.module.scss new file mode 100644 index 000000000..3beba0c2c --- /dev/null +++ b/packages/console/src/pages/ApplicationDetails/components/GuideDrawer/index.module.scss @@ -0,0 +1,37 @@ +@use '@/scss/underscore' as _; + +.drawerContainer { + height: 100%; + display: flex; + flex-direction: column; +} + +.header { + flex: 0 0 64px; + display: flex; + align-items: center; + padding: 0 _.unit(6); + background-color: var(--color-layer-1); + font: var(--font-title-2); + color: var(--color-text); + box-shadow: var(--shadow-1); + z-index: 1; + + .separator { + border-left: 1px solid var(--color-border); + height: 20px; + width: 0; + margin: 0 _.unit(5); + } +} + +.cardGroup { + flex: 1; + padding: _.unit(6); +} + +.guide { + flex: 1; + height: unset; + overflow: hidden; +} diff --git a/packages/console/src/pages/ApplicationDetails/components/GuideDrawer/index.tsx b/packages/console/src/pages/ApplicationDetails/components/GuideDrawer/index.tsx new file mode 100644 index 000000000..f31171283 --- /dev/null +++ b/packages/console/src/pages/ApplicationDetails/components/GuideDrawer/index.tsx @@ -0,0 +1,101 @@ +import { type ApplicationResponse } from '@logto/schemas'; +import { useEffect, useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; + +import ArrowLeft from '@/assets/icons/arrow-left.svg'; +import Close from '@/assets/icons/close.svg'; +import IconButton from '@/ds-components/IconButton'; +import Spacer from '@/ds-components/Spacer'; +import Guide from '@/pages/Applications/components/Guide'; +import { type SelectedGuide } from '@/pages/Applications/components/GuideCard'; +import GuideGroup from '@/pages/Applications/components/GuideGroup'; +import useAppGuideMetadata from '@/pages/Applications/components/GuideLibrary/hook'; + +import * as styles from './index.module.scss'; + +type Props = { + app: ApplicationResponse; + onClose: () => void; +}; + +function GuideDrawer({ app, onClose }: Props) { + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console.applications.guide' }); + const [_, getStructuredMetadata] = useAppGuideMetadata(); + const [selectedGuide, setSelectedGuide] = useState(); + + const structuredMetadata = useMemo( + () => getStructuredMetadata({ categories: [app.type] }), + [getStructuredMetadata, app.type] + ); + + const hasSingleGuide = useMemo(() => { + return structuredMetadata[app.type].length === 1; + }, [app.type, structuredMetadata]); + + useEffect(() => { + if (hasSingleGuide) { + const guide = structuredMetadata[app.type][0]; + if (guide) { + const { + id, + metadata: { target, name }, + } = guide; + setSelectedGuide({ id, target, name }); + } + } + }, [hasSingleGuide, app.type, structuredMetadata]); + + return ( +
+
+ {selectedGuide && ( + <> + {!hasSingleGuide && ( + <> + { + setSelectedGuide(undefined); + }} + > + + +
+ + )} + {t('checkout_tutorial', { name: selectedGuide.name })} + + )} + {!selectedGuide && t('select_a_framework')} + + + + +
+ {!selectedGuide && ( + { + setSelectedGuide(guide); + }} + /> + )} + {selectedGuide && ( + { + setSelectedGuide(undefined); + }} + /> + )} +
+ ); +} + +export default GuideDrawer; diff --git a/packages/console/src/pages/ApplicationDetails/index.tsx b/packages/console/src/pages/ApplicationDetails/index.tsx index fc986e789..fa374a5ff 100644 --- a/packages/console/src/pages/ApplicationDetails/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/index.tsx @@ -3,7 +3,6 @@ import { type Application, type ApplicationResponse, type SnakeCaseOidcConfig, - ApplicationType, customClientMetadataDefault, } from '@logto/schemas'; import { useEffect, useState } from 'react'; @@ -36,10 +35,10 @@ import useTenantPathname from '@/hooks/use-tenant-pathname'; import { applicationTypeI18nKey } from '@/types/applications'; import { trySubmitSafe } from '@/utils/form'; -import Guide from '../Applications/components/Guide'; import GuideModal from '../Applications/components/Guide/GuideModal'; import AdvancedSettings from './components/AdvancedSettings'; +import GuideDrawer from './components/GuideDrawer'; import Settings from './components/Settings'; import * as styles from './index.module.scss'; @@ -172,24 +171,15 @@ function ApplicationDetails() {
- {/* TODO: @Charles figure out a better way to check guide availability */}
+ + )}
); diff --git a/packages/console/src/pages/Applications/components/GuideCard/index.module.scss b/packages/console/src/pages/Applications/components/GuideCard/index.module.scss index c87131f53..1defb5a4b 100644 --- a/packages/console/src/pages/Applications/components/GuideCard/index.module.scss +++ b/packages/console/src/pages/Applications/components/GuideCard/index.module.scss @@ -12,6 +12,10 @@ max-width: 460px; justify-content: space-between; + &.compact { + cursor: pointer; + } + &.hasBorder { border-color: var(--color-divider); } diff --git a/packages/console/src/pages/Applications/components/GuideCard/index.tsx b/packages/console/src/pages/Applications/components/GuideCard/index.tsx index 0a42e3c9b..e84dd0ec3 100644 --- a/packages/console/src/pages/Applications/components/GuideCard/index.tsx +++ b/packages/console/src/pages/Applications/components/GuideCard/index.tsx @@ -10,25 +10,28 @@ import { TenantsContext } from '@/contexts/TenantsProvider'; import Button from '@/ds-components/Button'; import useSubscriptionPlan from '@/hooks/use-subscription-plan'; import useTenantPathname from '@/hooks/use-tenant-pathname'; +import { onKeyDownHandler } from '@/utils/a11y'; import * as styles from './index.module.scss'; export type SelectedGuide = { - target: GuideMetadata['target']; id: Guide['id']; + target: GuideMetadata['target']; + name: GuideMetadata['name']; }; type Props = { data: Guide; onClick: (data: SelectedGuide) => void; hasBorder?: boolean; + isCompact?: boolean; }; function LogoSkeleton() { return
; } -function GuideCard({ data, onClick, hasBorder }: Props) { +function GuideCard({ data, onClick, hasBorder, isCompact }: Props) { const { navigate } = useTenantPathname(); const { currentTenantId } = useContext(TenantsContext); const { data: currentPlan } = useSubscriptionPlan(currentTenantId); @@ -42,8 +45,28 @@ function GuideCard({ data, onClick, hasBorder }: Props) { metadata: { target, name, description }, } = data; + const onClickCard = () => { + if (!isCompact) { + return; + } + + onClick({ id, target, name }); + }; + return ( -
+
}> @@ -63,7 +86,7 @@ function GuideCard({ data, onClick, hasBorder }: Props) { if (isSubscriptionRequired) { navigate(subscriptionPage); } else { - onClick({ target, id }); + onClick({ id, target, name }); } }} /> diff --git a/packages/console/src/pages/Applications/components/GuideGroup/index.module.scss b/packages/console/src/pages/Applications/components/GuideGroup/index.module.scss new file mode 100644 index 000000000..841767ece --- /dev/null +++ b/packages/console/src/pages/Applications/components/GuideGroup/index.module.scss @@ -0,0 +1,35 @@ +@use '@/scss/underscore' as _; + +.guideGroup { + display: flex; + flex-direction: column; + container-type: inline-size; + + label { + @include _.section-head-1; + margin-bottom: _.unit(4); + } + + .grid { + display: grid; + gap: _.unit(4) _.unit(3); + } + + @container (max-width: 680px) { + .grid { + grid-template-columns: repeat(2, 1fr); + } + } + + @container (min-width: 681px) and (max-width: 1080px) { + .grid { + grid-template-columns: repeat(3, 1fr); + } + } + + @container (min-width: 1081px) { + .grid { + grid-template-columns: repeat(4, 1fr); + } + } +} diff --git a/packages/console/src/pages/Applications/components/GuideGroup/index.tsx b/packages/console/src/pages/Applications/components/GuideGroup/index.tsx new file mode 100644 index 000000000..0888da16d --- /dev/null +++ b/packages/console/src/pages/Applications/components/GuideGroup/index.tsx @@ -0,0 +1,48 @@ +import classNames from 'classnames'; + +import { type Guide } from '@/assets/docs/guides/types'; + +import GuideCard, { type SelectedGuide } from '../GuideCard'; + +import * as styles from './index.module.scss'; + +type GuideGroupProps = { + className?: string; + categoryName?: string; + guides?: readonly Guide[]; + hasCardBorder?: boolean; + isCompact?: boolean; + onClickGuide: (data: SelectedGuide) => void; +}; + +function GuideGroup({ + className, + categoryName, + guides, + hasCardBorder, + isCompact, + onClickGuide, +}: GuideGroupProps) { + if (!guides?.length) { + return null; + } + + return ( +
+ {categoryName && } +
+ {guides.map((guide) => ( + + ))} +
+
+ ); +} + +export default GuideGroup; diff --git a/packages/console/src/pages/Applications/components/GuideLibrary/index.module.scss b/packages/console/src/pages/Applications/components/GuideLibrary/index.module.scss index fa2d25f34..909dd6755 100644 --- a/packages/console/src/pages/Applications/components/GuideLibrary/index.module.scss +++ b/packages/console/src/pages/Applications/components/GuideLibrary/index.module.scss @@ -54,37 +54,5 @@ .guideGroup { flex: 1; - display: flex; - flex-direction: column; margin: _.unit(8) _.unit(8) 0 0; - max-width: 1876px; - container-type: inline-size; - - label { - @include _.section-head-1; - margin-bottom: _.unit(4); - } - - .grid { - display: grid; - gap: _.unit(4) _.unit(3); - } - - @container (max-width: 680px) { - .grid { - grid-template-columns: repeat(2, 1fr); - } - } - - @container (min-width: 681px) and (max-width: 1080px) { - .grid { - grid-template-columns: repeat(3, 1fr); - } - } - - @container (min-width: 1081px) { - .grid { - grid-template-columns: repeat(4, 1fr); - } - } } diff --git a/packages/console/src/pages/Applications/components/GuideLibrary/index.tsx b/packages/console/src/pages/Applications/components/GuideLibrary/index.tsx index 0649993aa..e62a1f647 100644 --- a/packages/console/src/pages/Applications/components/GuideLibrary/index.tsx +++ b/packages/console/src/pages/Applications/components/GuideLibrary/index.tsx @@ -3,7 +3,6 @@ import classNames from 'classnames'; import { useCallback, useContext, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { type Guide } from '@/assets/docs/guides/types'; import SearchIcon from '@/assets/icons/search.svg'; import ProTag from '@/components/ProTag'; import { isCloud } from '@/consts/env'; @@ -16,42 +15,18 @@ import useTenantPathname from '@/hooks/use-tenant-pathname'; import { allAppGuideCategories, type AppGuideCategory } from '@/types/applications'; import CreateForm from '../CreateForm'; -import GuideCard, { type SelectedGuide } from '../GuideCard'; +import { type SelectedGuide } from '../GuideCard'; +import GuideGroup from '../GuideGroup'; import useAppGuideMetadata from './hook'; import * as styles from './index.module.scss'; type Props = { className?: string; - hasFilter?: boolean; hasCardBorder?: boolean; }; -type GuideGroupProps = { - categoryName?: string; - guides?: readonly Guide[]; - hasCardBorder?: boolean; - onClickGuide: (data: SelectedGuide) => void; -}; - -function GuideGroup({ categoryName, guides, hasCardBorder, onClickGuide }: GuideGroupProps) { - if (!guides?.length) { - return null; - } - - return ( -
- {categoryName && } -
- {guides.map((guide) => ( - - ))} -
-
- ); -} - -function GuideLibrary({ className, hasFilter, hasCardBorder }: Props) { +function GuideLibrary({ className, hasCardBorder }: Props) { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console.applications.guide' }); const { navigate } = useTenantPathname(); const [keyword, setKeyword] = useState(''); @@ -93,39 +68,38 @@ function GuideLibrary({ className, hasFilter, hasCardBorder }: Props) { return (
- {hasFilter && ( -
- - } - placeholder={t('filter.placeholder')} - value={keyword} - onChange={(event) => { - setKeyword(event.currentTarget.value); +
+ + } + placeholder={t('filter.placeholder')} + value={keyword} + onChange={(event) => { + setKeyword(event.currentTarget.value); + }} + /> +
+ ({ + title: `applications.guide.categories.${category}`, + value: category, + }))} + value={filterCategories} + onChange={(value) => { + const sortedValue = allAppGuideCategories.filter((category) => + value.includes(category) + ); + setFilterCategories(sortedValue); }} /> -
- ({ - title: `applications.guide.categories.${category}`, - value: category, - }))} - value={filterCategories} - onChange={(value) => { - const sortedValue = allAppGuideCategories.filter((category) => - value.includes(category) - ); - setFilterCategories(sortedValue); - }} - /> - {isM2mDisabledForCurrentPlan && } -
+ {isM2mDisabledForCurrentPlan && }
- )} +
{keyword && ( 0 && (
- +
- -
-
- ); -} - -export default GuideV2; diff --git a/packages/console/src/pages/Applications/components/SdkSelector/index.module.scss b/packages/console/src/pages/Applications/components/SdkSelector/index.module.scss deleted file mode 100644 index e8803138d..000000000 --- a/packages/console/src/pages/Applications/components/SdkSelector/index.module.scss +++ /dev/null @@ -1,75 +0,0 @@ -@use '@/scss/underscore' as _; - -.card { - padding: _.unit(5) _.unit(6); - display: block; - flex-direction: column; - scroll-margin: _.unit(5); - - .congrats { - display: block; - width: 160px; - height: 160px; - margin: _.unit(1) auto _.unit(8); - } - - .congratsText { - width: 100%; - } - - .title { - font: var(--font-title-1); - } - - .subtitle { - font: var(--font-body-2); - color: var(--color-text); - margin-top: _.unit(3); - } - - .radioGroup { - width: 100%; - margin-top: _.unit(6); - margin-right: 0; - display: flex; - flex-wrap: wrap; - gap: _.unit(5); - } - - .radio { - border-radius: _.unit(2); - padding: _.unit(5); - width: 240px; - max-width: unset; - font: var(--font-label-2); - } - - .select { - background: var(--color-guide-dropdown-background); - border-color: var(--color-guide-dropdown-border); - } - - &.folded { - display: flex; - flex-direction: row; - align-items: center; - flex: 0 0 56px; - height: 56px; - background: var(--color-neutral-variant-90); - border-radius: _.unit(2); - padding: 0 _.unit(4); - font: var(--font-body-2); - color: var(--color-text); - - .tada { - margin: 0 _.unit(4) 0 0; - } - } - - .buttonWrapper { - width: 100%; - display: flex; - justify-content: flex-end; - margin-top: _.unit(6); - } -} diff --git a/packages/console/src/pages/Applications/components/SdkSelector/index.tsx b/packages/console/src/pages/Applications/components/SdkSelector/index.tsx deleted file mode 100644 index 3cbebdd64..000000000 --- a/packages/console/src/pages/Applications/components/SdkSelector/index.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import { Theme } from '@logto/schemas'; -import classNames from 'classnames'; -import { useState } from 'react'; -import { useTranslation } from 'react-i18next'; - -import TadaDark from '@/assets/icons/tada-dark.svg'; -import Tada from '@/assets/icons/tada.svg'; -import CongratsDark from '@/assets/images/congrats-dark.svg'; -import Congrats from '@/assets/images/congrats.svg'; -import Button from '@/ds-components/Button'; -import Card from '@/ds-components/Card'; -import RadioGroup, { Radio } from '@/ds-components/RadioGroup'; -import Select from '@/ds-components/Select'; -import Spacer from '@/ds-components/Spacer'; -import useTheme from '@/hooks/use-theme'; -import type { SupportedSdk } from '@/types/applications'; - -import * as styles from './index.module.scss'; - -type Props = { - className?: string; - sdks: readonly SupportedSdk[]; - selectedSdk: SupportedSdk; - isCompact?: boolean; - onChange?: (value: string) => void; - onToggle?: () => void; -}; - -function SdkSelector({ - className, - sdks, - selectedSdk, - isCompact = false, - onChange, - onToggle, -}: Props) { - const [isFolded, setIsFolded] = useState(isCompact); - const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - const theme = useTheme(); - const isLightMode = theme === Theme.Light; - const CongratsIcon = isLightMode ? Congrats : CongratsDark; - const TadaIcon = isLightMode ? Tada : TadaDark; - - if (isFolded) { - return ( -
- - {t('applications.guide.description_by_sdk', { sdk: selectedSdk })} - -