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

refactor(console): replace info tooltips with toggle tips (#2590)

This commit is contained in:
Xiao Yijun 2022-12-06 13:08:35 +08:00 committed by GitHub
parent 0bec9f0ff5
commit b997d6f420
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 30 additions and 60 deletions

View file

@ -16,11 +16,8 @@
color: var(--color-text);
}
.icon {
.toggleTipButton {
margin-left: _.unit(1);
width: 16px;
height: 16px;
color: var(--color-text-secondary);
}
.required {

View file

@ -1,14 +1,11 @@
import type { AdminConsoleKey } from '@logto/phrases';
import classNames from 'classnames';
import type { ReactElement, ReactNode } from 'react';
import { useRef } from 'react';
import { useTranslation } from 'react-i18next';
import Tip from '@/assets/images/tip.svg';
import type DangerousRaw from '../DangerousRaw';
import Spacer from '../Spacer';
import Tooltip from '../Tooltip';
import ToggleTipButton from '../ToggleTipButton';
import * as styles from './index.module.scss';
export type Props = {
@ -17,29 +14,18 @@ export type Props = {
isRequired?: boolean;
className?: string;
headlineClassName?: string;
tooltip?: AdminConsoleKey;
tip?: AdminConsoleKey;
};
const FormField = ({
title,
children,
isRequired,
className,
tooltip,
headlineClassName,
}: Props) => {
const FormField = ({ title, children, isRequired, className, tip, headlineClassName }: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const tipRef = useRef<HTMLDivElement>(null);
return (
<div className={classNames(styles.field, className)}>
<div className={classNames(styles.headline, headlineClassName)}>
<div className={styles.title}>{typeof title === 'string' ? t(title) : title}</div>
{tooltip && (
<div ref={tipRef} className={styles.icon}>
<Tip />
<Tooltip anchorRef={tipRef} content={t(tooltip)} />
</div>
{tip && (
<ToggleTipButton className={styles.toggleTipButton} render={() => <div>{t(tip)}</div>} />
)}
<Spacer />
{isRequired && <div className={styles.required}>{t('general.required')}</div>}

View file

@ -8,14 +8,14 @@ import MultiTextInput from '../MultiTextInput';
import * as styles from './index.module.scss';
type Props = MultiTextInputProps &
Pick<FormFieldProps, 'isRequired' | 'tooltip'> & {
Pick<FormFieldProps, 'isRequired' | 'tip'> & {
formFieldClassName?: FormFieldProps['className'];
};
const MultiTextInputField = ({
title,
isRequired,
tooltip,
tip,
formFieldClassName,
value,
...rest
@ -23,7 +23,7 @@ const MultiTextInputField = ({
<FormField
title={title}
isRequired={isRequired}
tooltip={tooltip}
tip={tip}
className={formFieldClassName}
headlineClassName={conditional(value && value.length > 1 && styles.headlineWithMultiInputs)}
>

View file

@ -64,7 +64,7 @@ const CreateForm = ({ onClose }: Props) => {
<FormField
isRequired
title="api_resources.api_identifier"
tooltip="api_resources.api_identifier_tip"
tip="api_resources.api_identifier_tip"
>
<TextInput
{...register('indicator', { required: true })}

View file

@ -27,7 +27,7 @@ const AdvancedSettings = ({ applicationType, oidcConfig }: Props) => {
>
<FormField
title="application_details.authorization_endpoint"
tooltip="application_details.authorization_endpoint_tip"
tip="application_details.authorization_endpoint_tip"
>
<CopyToClipboard
className={styles.textField}

View file

@ -85,7 +85,7 @@ const Settings = ({ data }: Props) => {
<MultiTextInputField
isRequired
title="application_details.redirect_uris"
tooltip="application_details.redirect_uri_tip"
tip="application_details.redirect_uri_tip"
value={value}
error={convertRhfErrorMessage(error?.message)}
placeholder={
@ -109,7 +109,7 @@ const Settings = ({ data }: Props) => {
render={({ field: { onChange, value }, fieldState: { error } }) => (
<MultiTextInputField
title="application_details.post_sign_out_redirect_uris"
tooltip="application_details.post_sign_out_redirect_uri_tip"
tip="application_details.post_sign_out_redirect_uri_tip"
value={value}
error={convertRhfErrorMessage(error?.message)}
placeholder={t('application_details.post_sign_out_redirect_uri_placeholder')}
@ -134,7 +134,7 @@ const Settings = ({ data }: Props) => {
render={({ field: { onChange, value }, fieldState: { error } }) => (
<MultiTextInputField
title="application_details.cors_allowed_origins"
tooltip="application_details.cors_allowed_origins_tip"
tip="application_details.cors_allowed_origins_tip"
value={value}
error={convertRhfErrorMessage(error?.message)}
placeholder={t('application_details.cors_allowed_origins_placeholder')}

View file

@ -34,15 +34,8 @@
display: flex;
align-items: center;
.icon {
.toggleTipButton {
margin-left: _.unit(1);
width: 16px;
height: 16px;
color: var(--color-text-secondary);
> svg {
display: block;
}
}
}

View file

@ -1,14 +1,12 @@
import type { AdminConsoleKey } from '@logto/phrases';
import { conditionalString } from '@silverhand/essentials';
import classNames from 'classnames';
import { useRef } from 'react';
import { useTranslation } from 'react-i18next';
import ArrowDown from '@/assets/images/arrow-down.svg';
import ArrowUp from '@/assets/images/arrow-up.svg';
import Tip from '@/assets/images/tip.svg';
import Card from '@/components/Card';
import Tooltip from '@/components/Tooltip';
import ToggleTipButton from '@/components/ToggleTipButton';
import { formatNumberWithComma } from '@/utilities/number';
import * as styles from './Block.module.scss';
@ -17,32 +15,28 @@ type Props = {
count: number;
delta?: number;
title: AdminConsoleKey;
tooltip?: AdminConsoleKey;
tip?: AdminConsoleKey;
variant?: 'bordered' | 'default' | 'plain';
};
const Block = ({ variant = 'default', count, delta, title, tooltip }: Props) => {
const Block = ({ variant = 'default', count, delta, title, tip }: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const tipRef = useRef<HTMLDivElement>(null);
const deltaLable = delta !== undefined && `${conditionalString(delta >= 0 && '+')}${delta}`;
const deltaLabel = delta !== undefined && `${conditionalString(delta >= 0 && '+')}${delta}`;
return (
<Card className={classNames(styles.block, styles[variant])}>
<div className={styles.title}>
{t(title)}
{tooltip && (
<div ref={tipRef} className={styles.icon}>
<Tip />
<Tooltip anchorRef={tipRef} content={t(tooltip)} />
</div>
{tip && (
<ToggleTipButton className={styles.toggleTipButton} render={() => <div>{t(tip)}</div>} />
)}
</div>
<div className={styles.content}>
<div className={styles.number}>{formatNumberWithComma(count)}</div>
{delta !== undefined && (
<div className={classNames(styles.delta, delta < 0 && styles.down)}>
<span>({deltaLable})</span>
<span>({deltaLabel})</span>
{delta > 0 && <ArrowUp />}
{delta < 0 && <ArrowDown />}
</div>

View file

@ -69,18 +69,18 @@ const Dashboard = () => {
<div className={styles.blocks}>
<Block
title="dashboard.total_users"
tooltip="dashboard.total_users_tip"
tip="dashboard.total_users_tip"
count={totalData.totalUserCount}
/>
<Block
title="dashboard.new_users_today"
tooltip="dashboard.new_users_today_tip"
tip="dashboard.new_users_today_tip"
count={newData.today.count}
delta={newData.today.delta}
/>
<Block
title="dashboard.new_users_7_days"
tooltip="dashboard.new_users_7_days_tip"
tip="dashboard.new_users_7_days_tip"
count={newData.last7Days.count}
delta={newData.last7Days.delta}
/>
@ -88,7 +88,7 @@ const Dashboard = () => {
<Card className={styles.activeCard}>
<Block
title="dashboard.daily_active_users"
tooltip="dashboard.daily_active_users_tip"
tip="dashboard.daily_active_users_tip"
count={activeData.dau.count}
delta={activeData.dau.delta}
variant="plain"
@ -130,14 +130,14 @@ const Dashboard = () => {
<div className={styles.blocks}>
<Block
title="dashboard.weekly_active_users"
tooltip="dashboard.weekly_active_users_tip"
tip="dashboard.weekly_active_users_tip"
count={activeData.wau.count}
delta={activeData.wau.delta}
variant="bordered"
/>
<Block
title="dashboard.monthly_active_users"
tooltip="dashboard.monthly_active_users_tip"
tip="dashboard.monthly_active_users_tip"
count={activeData.mau.count}
delta={activeData.mau.delta}
variant="bordered"

View file

@ -32,7 +32,7 @@ const TermsForm = () => {
<FormField
isRequired
title="sign_in_exp.others.terms_of_use.terms_of_use"
tooltip="sign_in_exp.others.terms_of_use.terms_of_use_tip"
tip="sign_in_exp.others.terms_of_use.terms_of_use_tip"
>
<TextInput
{...register('termsOfUse.contentUrl', {

View file

@ -138,7 +138,7 @@ const UserSettings = ({ userData, userFormData, isDeleted, onUserUpdated }: Prop
<FormField
isRequired
title="user_details.field_custom_data"
tooltip="user_details.field_custom_data_tip"
tip="user_details.field_custom_data_tip"
>
<CodeEditor language="json" value={value} onChange={onChange} />
</FormField>