0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-10 22:22:45 -05:00

feat(console): add live preview entry in the sie preview (#3270)

This commit is contained in:
Xiao Yijun 2023-03-03 13:41:23 +08:00 committed by GitHub
parent 05441a869f
commit 49c7c68fb7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 113 additions and 17 deletions

View file

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 7.21325C11.8232 7.21325 11.6537 7.28349 11.5286 7.40851C11.4036 7.53354 11.3334 7.70311 11.3334 7.87992V12.6666C11.3334 12.8434 11.2631 13.013 11.1381 13.138C11.0131 13.263 10.8435 13.3333 10.6667 13.3333H3.33337C3.15656 13.3333 2.98699 13.263 2.86197 13.138C2.73695 13.013 2.66671 12.8434 2.66671 12.6666V5.33325C2.66671 5.15644 2.73695 4.98687 2.86197 4.86185C2.98699 4.73682 3.15656 4.66659 3.33337 4.66659H8.12004C8.29685 4.66659 8.46642 4.59635 8.59145 4.47132C8.71647 4.3463 8.78671 4.17673 8.78671 3.99992C8.78671 3.82311 8.71647 3.65354 8.59145 3.52851C8.46642 3.40349 8.29685 3.33325 8.12004 3.33325H3.33337C2.80294 3.33325 2.29423 3.54397 1.91916 3.91904C1.54409 4.29411 1.33337 4.80282 1.33337 5.33325V12.6666C1.33337 13.197 1.54409 13.7057 1.91916 14.0808C2.29423 14.4559 2.80294 14.6666 3.33337 14.6666H10.6667C11.1971 14.6666 11.7058 14.4559 12.0809 14.0808C12.456 13.7057 12.6667 13.197 12.6667 12.6666V7.87992C12.6667 7.70311 12.5965 7.53354 12.4714 7.40851C12.3464 7.28349 12.1769 7.21325 12 7.21325ZM14.6134 1.74659C14.5457 1.58369 14.4163 1.45424 14.2534 1.38659C14.1732 1.35242 14.0872 1.33431 14 1.33325H10C9.82323 1.33325 9.65366 1.40349 9.52864 1.52851C9.40361 1.65354 9.33337 1.82311 9.33337 1.99992C9.33337 2.17673 9.40361 2.3463 9.52864 2.47132C9.65366 2.59635 9.82323 2.66659 10 2.66659H12.3934L5.52671 9.52659C5.46422 9.58856 5.41463 9.66229 5.38078 9.74353C5.34693 9.82477 5.32951 9.91191 5.32951 9.99992C5.32951 10.0879 5.34693 10.1751 5.38078 10.2563C5.41463 10.3375 5.46422 10.4113 5.52671 10.4733C5.58868 10.5357 5.66242 10.5853 5.74366 10.6192C5.8249 10.653 5.91203 10.6705 6.00004 10.6705C6.08805 10.6705 6.17519 10.653 6.25643 10.6192C6.33767 10.5853 6.4114 10.5357 6.47337 10.4733L13.3334 3.60659V5.99992C13.3334 6.17673 13.4036 6.3463 13.5286 6.47132C13.6537 6.59635 13.8232 6.66659 14 6.66659C14.1769 6.66659 14.3464 6.59635 14.4714 6.47132C14.5965 6.3463 14.6667 6.17673 14.6667 5.99992V1.99992C14.6657 1.9128 14.6475 1.82673 14.6134 1.74659Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -48,12 +48,6 @@
}
}
.trailingIcon {
display: block;
width: 16px;
height: 16px;
}
&.small {
height: 30px;
padding: 0 _.unit(3);
@ -98,8 +92,8 @@
border-style: solid;
&:disabled {
background: var(--color-neutral-70);
border-color: var(--color-neutral-70);
color: var(--color-neutral-70);
}
&:focus-visible {

View file

@ -86,7 +86,7 @@ const Button = ({
{showSpinner && <Spinner className={styles.spinner} />}
{icon && <span className={styles.icon}>{icon}</span>}
{title && (typeof title === 'string' ? <span>{t(title)}</span> : title)}
{trailingIcon && <span className={styles.trailingIcon}>{trailingIcon}</span>}
{trailingIcon}
</button>
);
};

View file

@ -0,0 +1,10 @@
@use '@/scss/underscore' as _;
.icon {
color: var(--color-text-secondary);
margin-left: _.unit(1.5);
&.disabled {
color: var(--color-neutral-70);
}
}

View file

@ -0,0 +1,46 @@
import { conditional } from '@silverhand/essentials';
import classNames from 'classnames';
import { useContext } from 'react';
import { useTranslation } from 'react-i18next';
import ExternalLinkIcon from '@/assets/images/external-link.svg';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import useConfigs from '@/hooks/use-configs';
import type { Props as ButtonProps } from '../Button';
import Button from '../Button';
import { Tooltip } from '../Tip';
import * as styles from './index.module.scss';
type Props = {
size?: ButtonProps['size'];
isDisabled: boolean;
};
const LivePreviewButton = ({ size = 'medium', isDisabled }: Props) => {
const { configs, updateConfigs } = useConfigs();
const { userEndpoint } = useContext(AppEndpointsContext);
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
return (
<Tooltip content={conditional(isDisabled && t('sign_in_exp.preview.live_preview_tip'))}>
<Button
size={size}
disabled={isDisabled}
title="sign_in_exp.preview.live_preview"
trailingIcon={
<ExternalLinkIcon className={classNames(styles.icon, isDisabled && styles.disabled)} />
}
onClick={() => {
if (!configs?.livePreviewChecked) {
void updateConfigs({ livePreviewChecked: true });
}
window.open(new URL('/demo-app', userEndpoint), '_blank');
}}
/>
</Tooltip>
);
};
export default LivePreviewButton;

View file

@ -9,3 +9,9 @@
.fieldButton {
margin-top: _.unit(2);
}
.trailingIcon {
display: block;
width: 16px;
height: 16px;
}

View file

@ -43,6 +43,12 @@ const BasicForm = ({
setDarkVisible((previous) => !previous);
};
const toggleVisibleButtonTitle = darkVisible
? 'connectors.guide.logo_dark_collapse'
: 'connectors.guide.logo_dark_show';
const ToggleVisibleCaretIcon = darkVisible ? CaretUp : CaretDown;
const syncProfileOptions = [
{
value: SyncProfileMode.OnlyAtRegister,
@ -93,12 +99,8 @@ const BasicForm = ({
<Button
size="small"
type="text"
title={
darkVisible
? 'connectors.guide.logo_dark_collapse'
: 'connectors.guide.logo_dark_show'
}
trailingIcon={darkVisible ? <CaretUp /> : <CaretDown />}
title={toggleVisibleButtonTitle}
trailingIcon={<ToggleVisibleCaretIcon className={styles.trailingIcon} />}
onClick={toggleDarkVisible}
/>
</div>

View file

@ -10,6 +10,7 @@ import { useTranslation } from 'react-i18next';
import useSWR from 'swr';
import PhoneInfo from '@/assets/images/phone-info.svg';
import LivePreviewButton from '@/components/LivePreviewButton';
import Select from '@/components/Select';
import TabNav, { TabNavItem } from '@/components/TabNav';
import ToggleThemeButton from '@/components/ToggleThemeButton';
@ -20,11 +21,18 @@ import useUiLanguages from '@/hooks/use-ui-languages';
import * as styles from './index.module.scss';
type Props = {
isLivePreviewDisabled?: boolean;
isLivePreviewEntryInvisible?: boolean;
signInExperience?: SignInExperience;
className?: string;
};
const Preview = ({ signInExperience, className }: Props) => {
const Preview = ({
isLivePreviewDisabled = false,
isLivePreviewEntryInvisible = false,
signInExperience,
className,
}: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const [language, setLanguage] = useState<LanguageTag>('en');
const [mode, setMode] = useState<Omit<AppearanceMode, AppearanceMode.SyncWithSystem>>(
@ -143,6 +151,9 @@ const Preview = ({ signInExperience, className }: Props) => {
}
}}
/>
{!isLivePreviewEntryInvisible && (
<LivePreviewButton isDisabled={isLivePreviewDisabled} size="small" />
)}
</div>
</div>
<TabNav className={styles.nav}>

View file

@ -122,7 +122,11 @@ const GuideModal = ({ isOpen, onClose }: Props) => {
<LanguagesForm />
</div>
{formData.id && (
<Preview signInExperience={previewConfigs} className={styles.preview} />
<Preview
isLivePreviewEntryInvisible
signInExperience={previewConfigs}
className={styles.preview}
/>
)}
</div>
<div className={styles.footer}>

View file

@ -196,7 +196,11 @@ const SignInExperience = () => {
</form>
</FormProvider>
{formData.id && (
<Preview signInExperience={previewConfigs} className={styles.preview} />
<Preview
isLivePreviewDisabled={isDirty}
signInExperience={previewConfigs}
className={styles.preview}
/>
)}
</div>
<SubmitFormChangesActionBar

View file

@ -166,6 +166,8 @@ const sign_in_exp = {
},
preview: {
title: 'Vorschau',
live_preview: 'Live preview', // UNTRANSLATED
live_preview_tip: 'Save to preview changes', // UNTRANSLATED
native: 'Nativ',
desktop_web: 'Desktop Web',
mobile_web: 'Mobil Web',

View file

@ -160,6 +160,8 @@ const sign_in_exp = {
},
preview: {
title: 'Sign-in preview',
live_preview: 'Live preview',
live_preview_tip: 'Save to preview changes',
native: 'Native',
desktop_web: 'Desktop Web',
mobile_web: 'Mobile Web',

View file

@ -162,6 +162,8 @@ const sign_in_exp = {
},
preview: {
title: "Aperçu de l'expérience de connexion",
live_preview: 'Live preview', // UNTRANSLATED
live_preview_tip: 'Save to preview changes', // UNTRANSLATED
native: 'Natif',
desktop_web: 'Web ordinateur',
mobile_web: 'Web mobile',

View file

@ -155,6 +155,8 @@ const sign_in_exp = {
},
preview: {
title: '로그인 화면 미리보기',
live_preview: 'Live preview', // UNTRANSLATED
live_preview_tip: 'Save to preview changes', // UNTRANSLATED
native: 'Native',
desktop_web: 'Desktop 웹',
mobile_web: 'Mobile 웹',

View file

@ -162,6 +162,8 @@ const sign_in_exp = {
},
preview: {
title: 'Visualização de login',
live_preview: 'Live preview', // UNTRANSLATED
live_preview_tip: 'Save to preview changes', // UNTRANSLATED
native: 'Native',
desktop_web: 'Desktop Web',
mobile_web: 'Mobile Web',

View file

@ -160,6 +160,8 @@ const sign_in_exp = {
},
preview: {
title: 'Pre-visualização do login',
live_preview: 'Live preview', // UNTRANSLATED
live_preview_tip: 'Save to preview changes', // UNTRANSLATED
native: 'Nativo',
desktop_web: 'Web computador',
mobile_web: 'Web móvel',

View file

@ -161,6 +161,8 @@ const sign_in_exp = {
},
preview: {
title: 'Oturum Açma Önizlemesi',
live_preview: 'Live preview', // UNTRANSLATED
live_preview_tip: 'Save to preview changes', // UNTRANSLATED
native: 'Doğal',
desktop_web: 'Masaüstü Web',
mobile_web: 'Mobil Web',

View file

@ -151,6 +151,8 @@ const sign_in_exp = {
},
preview: {
title: '登录预览',
live_preview: 'Live preview', // UNTRANSLATED
live_preview_tip: 'Save to preview changes', // UNTRANSLATED
native: '移动原生',
desktop_web: '桌面网页',
mobile_web: '移动网页',