refactor(infra): directory structure (#4615)

This commit is contained in:
Joooye_34
2023-10-18 23:30:08 +08:00
committed by GitHub
parent 814d552be8
commit bed9310519
1150 changed files with 539 additions and 584 deletions
@@ -0,0 +1,6 @@
export { SettingHeader } from './setting-header';
export { SettingRow } from './setting-row';
export * from './storage-progess';
export * from './workspace-detail-skeleton';
export * from './workspace-list-skeleton';
export { SettingWrapper } from './wrapper';
@@ -0,0 +1,22 @@
import type { HTMLAttributes, ReactNode } from 'react';
import { settingHeader } from './share.css';
interface SettingHeaderProps
extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
title: ReactNode;
subtitle?: ReactNode;
}
export const SettingHeader = ({
title,
subtitle,
...otherProps
}: SettingHeaderProps) => {
return (
<div className={settingHeader} {...otherProps}>
<div className="title">{title}</div>
<div className="subtitle">{subtitle}</div>
</div>
);
};
@@ -0,0 +1,43 @@
import clsx from 'clsx';
import type { CSSProperties, PropsWithChildren, ReactNode } from 'react';
import { settingRow } from './share.css';
export type SettingRowProps = PropsWithChildren<{
name: ReactNode;
desc: ReactNode;
style?: CSSProperties;
onClick?: () => void;
spreadCol?: boolean;
'data-testid'?: string;
disabled?: boolean;
}>;
export const SettingRow = ({
name,
desc,
children,
onClick,
style,
spreadCol = true,
disabled = false,
...props
}: PropsWithChildren<SettingRowProps>) => {
return (
<div
className={clsx(settingRow, {
'two-col': spreadCol,
disabled,
})}
style={style}
onClick={onClick}
data-testid={props['data-testid']}
>
<div className="left-col">
<div className="name">{name}</div>
<div className="desc">{desc}</div>
</div>
{spreadCol ? <div className="right-col">{children}</div> : children}
</div>
);
};
@@ -0,0 +1,146 @@
import { globalStyle, style } from '@vanilla-extract/css';
export const settingHeader = style({
height: '68px',
borderBottom: '1px solid var(--affine-border-color)',
marginBottom: '24px',
});
globalStyle(`${settingHeader} .title`, {
fontSize: 'var(--affine-font-base)',
fontWeight: 600,
lineHeight: '24px',
marginBottom: '4px',
});
globalStyle(`${settingHeader} .subtitle`, {
fontSize: 'var(--affine-font-xs)',
lineHeight: '16px',
color: 'var(--affine-text-secondary-color)',
});
export const wrapper = style({
borderBottom: '1px solid var(--affine-border-color)',
paddingBottom: '24px',
marginBottom: '24px',
selectors: {
'&:last-of-type': {
borderBottom: 'none',
paddingBottom: '0',
marginBottom: '0',
},
},
});
globalStyle(`${wrapper} .title`, {
fontSize: 'var(--affine-font-sm)',
fontWeight: 600,
lineHeight: '18px',
color: 'var(--affine-text-secondary-color)',
marginBottom: '16px',
});
export const settingRow = style({
marginBottom: '25px',
color: 'var(--affine-text-primary-color)',
borderRadius: '8px',
selectors: {
'&.two-col': {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
},
'&:last-of-type': {
marginBottom: '0',
},
'&.disabled': {
position: 'relative',
},
'&.disabled::after': {
content: '',
position: 'absolute',
left: 0,
top: 0,
width: '100%',
height: '100%',
backgroundColor: 'rgba(255,255,255,0.5)',
},
},
});
globalStyle(`${settingRow} .left-col`, {
flex: 1,
maxWidth: '100%',
});
globalStyle(`${settingRow}.two-col .left-col`, {
flexShrink: 0,
maxWidth: '80%',
});
globalStyle(`${settingRow} .name`, {
marginBottom: '2px',
fontSize: 'var(--affine-font-sm)',
fontWeight: 600,
});
globalStyle(`${settingRow} .desc`, {
fontSize: 'var(--affine-font-xs)',
color: 'var(--affine-text-secondary-color)',
});
globalStyle(`${settingRow} .right-col`, {
width: '250px',
display: 'flex',
justifyContent: 'flex-end',
paddingLeft: '15px',
flexShrink: 0,
});
export const storageProgressContainer = style({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
});
export const storageProgressWrapper = style({
flexGrow: 1,
marginRight: '20px',
});
globalStyle(`${storageProgressWrapper} .storage-progress-desc`, {
fontSize: 'var(--affine-font-xs)',
color: 'var(--affine-text-secondary-color)',
height: '20px',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 2,
});
globalStyle(`${storageProgressWrapper} .storage-progress-bar-wrapper`, {
height: '8px',
borderRadius: '4px',
backgroundColor: 'var(--affine-pure-black-10)',
overflow: 'hidden',
});
export const storageProgressBar = style({
height: '100%',
backgroundColor: 'var(--affine-processing-color)',
selectors: {
'&.warning': {
// Wait for design
backgroundColor: '#FF7C09',
},
'&.danger': {
backgroundColor: 'var(--affine-error-color)',
},
},
});
export const storageExtendHint = style({
borderRadius: '4px',
padding: '4px 8px',
backgroundColor: 'var(--affine-background-secondary-color)',
color: 'var(--affine-text-secondary-color)',
fontSize: 'var(--affine-font-xs)',
lineHeight: '20px',
marginTop: 8,
});
globalStyle(`${storageExtendHint} a`, {
color: 'var(--affine-link-color)',
});
@@ -0,0 +1,81 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Button } from '@toeverything/components/button';
import { Tooltip } from '@toeverything/components/tooltip';
import clsx from 'clsx';
import { useMemo } from 'react';
import * as styles from './share.css';
export interface StorageProgressProgress {
max: number;
value: number;
onUpgrade: () => void;
}
const transformBytesToMB = (bytes: number) => {
return (bytes / 1024 / 1024).toFixed(2);
};
const transformBytesToGB = (bytes: number) => {
return (bytes / 1024 / 1024 / 1024).toFixed(2);
};
export const StorageProgress = ({
max: upperLimit,
value,
onUpgrade,
}: StorageProgressProgress) => {
const t = useAFFiNEI18N();
const percent = useMemo(
() => Math.round((value / upperLimit) * 100),
[upperLimit, value]
);
const used = useMemo(() => transformBytesToMB(value), [value]);
const max = useMemo(() => transformBytesToGB(upperLimit), [upperLimit]);
return (
<>
<div className={styles.storageProgressContainer}>
<div className={styles.storageProgressWrapper}>
<div className="storage-progress-desc">
<span>{t['com.affine.storage.used.hint']()}</span>
<span>
{used}MB/{max}GB
</span>
</div>
<div className="storage-progress-bar-wrapper">
<div
className={clsx(styles.storageProgressBar, {
warning: percent > 80,
danger: percent > 99,
})}
style={{ width: `${percent}%` }}
></div>
</div>
</div>
<Tooltip content={t['com.affine.storage.disabled.hint']()}>
<span tabIndex={0}>
<Button disabled onClick={onUpgrade}>
{t['com.affine.storage.upgrade']()}
</Button>
</span>
</Tooltip>
</div>
{percent > 80 ? (
<div className={styles.storageExtendHint}>
{t['com.affine.storage.extend.hint']()}
<a
href="https://community.affine.pro/c/insider-general/"
target="_blank"
rel="noreferrer"
>
{t['com.affine.storage.extend.link']()}
</a>
</div>
) : null}
</>
);
};
@@ -0,0 +1,25 @@
import { Skeleton } from '@mui/material';
import { SettingHeader } from './setting-header';
import { SettingRow } from './setting-row';
import { SettingWrapper } from './wrapper';
export const WorkspaceDetailSkeleton = () => {
return (
<>
<SettingHeader title={<Skeleton />} subtitle={<Skeleton />} />
{new Array(3).fill(0).map((_, index) => {
return (
<SettingWrapper title={<Skeleton />} key={index}>
<SettingRow
name={<Skeleton />}
desc={<Skeleton />}
spreadCol={false}
></SettingRow>
</SettingWrapper>
);
})}
</>
);
};
@@ -0,0 +1,30 @@
import { Skeleton } from '@mui/material';
import { FlexWrapper } from '../../ui/layout';
export const WorkspaceListItemSkeleton = () => {
return (
<FlexWrapper
alignItems="center"
style={{ padding: '0 8px', height: 30, marginBottom: 4 }}
>
<Skeleton
variant="circular"
width={14}
height={14}
style={{ marginRight: 10 }}
/>
<Skeleton variant="rectangular" height={16} style={{ flexGrow: 1 }} />
</FlexWrapper>
);
};
export const WorkspaceListSkeleton = () => {
return (
<>
{new Array(5).fill(0).map((_, index) => {
return <WorkspaceListItemSkeleton key={index} />;
})}
</>
);
};
@@ -0,0 +1,19 @@
import type { PropsWithChildren, ReactNode } from 'react';
import { wrapper } from './share.css';
interface SettingWrapperProps {
title?: ReactNode;
}
export const SettingWrapper = ({
title,
children,
}: PropsWithChildren<SettingWrapperProps>) => {
return (
<div className={wrapper}>
{title ? <div className="title">{title}</div> : null}
{children}
</div>
);
};