fix(editor): some bugs of member column (#11033)

fix: BS-2840
This commit is contained in:
zzj3720
2025-03-20 12:24:25 +00:00
parent 66ea3038af
commit 8a5393ea50
6 changed files with 98 additions and 73 deletions

View File

@@ -0,0 +1,23 @@
import { keyframes, style } from '@vanilla-extract/css';
export const progressSvg = style({
transform: 'rotate(-90deg)',
});
export const progressIconContainer = style({
position: 'relative',
width: '24px',
height: '24px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
});
export const progressCircle = style({
transition: 'stroke-dasharray 0.3s ease-in-out',
});
const spin = keyframes({
from: { transform: 'rotate(0deg)' },
to: { transform: 'rotate(360deg)' },
});
export const spinnerAnimation = style({
animation: `${spin} 1s linear infinite`,
});

View File

@@ -0,0 +1,61 @@
import { cssVarV2 } from '@toeverything/theme/v2';
import { progressCircle, progressSvg, spinnerAnimation } from './loading.css';
export const CircularProgress = ({ progress }: { progress: number }) => {
const circumference = 2 * Math.PI * 10;
return (
<svg width="18" height="18" viewBox="0 0 24 24" className={progressSvg}>
<circle
cx="12"
cy="12"
r="10"
fill="none"
stroke={cssVarV2.loading.background}
strokeWidth="4"
/>
<circle
cx="12"
cy="12"
r="10"
fill="none"
stroke={cssVarV2.loading.foreground}
strokeWidth="4"
strokeDasharray={`${(progress / 100) * circumference} ${circumference}`}
strokeLinecap="round"
className={progressCircle}
/>
</svg>
);
};
export const Spinner = () => {
return (
<svg
width="18"
height="18"
viewBox="0 0 24 24"
className={spinnerAnimation}
>
<circle
cx="12"
cy="12"
r="10"
fill="none"
stroke={cssVarV2.loading.background}
strokeWidth="4"
/>
<circle
cx="12"
cy="12"
r="10"
fill="none"
stroke={cssVarV2.loading.foreground}
strokeWidth="4"
strokeDasharray="15 85"
strokeLinecap="round"
/>
</svg>
);
};

View File

@@ -104,23 +104,6 @@ export const fileItemImagePreview = style({
borderRadius: '2px',
});
export const progressIconContainer = style({
position: 'relative',
width: '24px',
height: '24px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
});
export const progressSvg = style({
transform: 'rotate(-90deg)',
});
export const progressCircle = style({
transition: 'stroke-dasharray 0.3s ease-in-out',
});
export const imagePreviewIcon = style({
borderRadius: '2px',
height: '100%',

View File

@@ -27,7 +27,6 @@ import {
generateFractionalIndexingKeyBetween,
useService,
} from '@toeverything/infra';
import { cssVarV2 } from '@toeverything/theme/v2';
import { fileTypeFromBuffer, type FileTypeResult } from 'file-type';
import { nanoid } from 'nanoid';
import type { ForwardRefRenderFunction, MouseEvent, ReactNode } from 'react';
@@ -41,6 +40,8 @@ import {
import { WorkspaceDialogService } from '../../../../modules/dialogs';
import { useSignalValue } from '../../../../modules/doc-info/utils';
import { CircularProgress } from '../../components/loading';
import { progressIconContainer } from '../../components/loading.css';
import type {
FileCellJsonValueType,
FileCellRawValueType,
@@ -198,38 +199,6 @@ type FileItemUploadingType = {
order: string;
};
type FileItemRenderType = FileItemDoneType | FileItemUploadingType;
const CircularProgress = ({ progress }: { progress: number }) => {
const circumference = 2 * Math.PI * 10;
return (
<svg
width="18"
height="18"
viewBox="0 0 24 24"
className={styles.progressSvg}
>
<circle
cx="12"
cy="12"
r="10"
fill="none"
stroke={cssVarV2.loading.background}
strokeWidth="4"
/>
<circle
cx="12"
cy="12"
r="10"
fill="none"
stroke={cssVarV2.loading.foreground}
strokeWidth="4"
strokeDasharray={`${(progress / 100) * circumference} ${circumference}`}
strokeLinecap="round"
className={styles.progressCircle}
/>
</svg>
);
};
class FileCellManager {
private readonly cell: Cell<FileCellRawValueType, FileCellJsonValueType, {}>;
@@ -481,7 +450,7 @@ const useFilePreview = (
if (uploadProgress != null) {
return {
preview: (
<div className={styles.progressIconContainer}>
<div className={progressIconContainer}>
<CircularProgress progress={uploadProgress.progress} />
</div>
),

View File

@@ -15,6 +15,7 @@ import {
} from 'react';
import { useSignalValue } from '../../../../../modules/doc-info/utils';
import { Spinner } from '../../../components/loading';
import * as styles from './style.css';
type BaseOptions = {
@@ -315,14 +316,17 @@ export const MultiMemberSelect: React.FC<MemberManagerOptions> = props => {
<input
ref={inputRef}
className={styles.memberSearchInput}
placeholder="Search members..."
placeholder={selectedMembers.length > 0 ? '' : 'Search members...'}
value={memberManager.userListService.searchText$.value}
onChange={handleInputChange}
/>
</div>
<div className={styles.memberListContainer} ref={memberListRef}>
{isLoading ? (
<div className={styles.loadingContainer}>Loading...</div>
<div className={styles.loadingContainer}>
<Spinner />
Loading...
</div>
) : filteredMemberList.length === 0 ? (
<div className={styles.noResultContainer}>No results</div>
) : (

View File

@@ -66,6 +66,7 @@ export const memberDeleteIcon = style({
export const memberPreviewContainer = style({
display: 'flex',
gap: '4px',
alignItems: 'center',
overflow: 'hidden',
padding: '2px',
@@ -75,14 +76,6 @@ export const memberPreviewContainer = style({
backgroundColor: cssVarV2.button.secondary,
});
export const memberPreview = style({
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
fontSize: '14px',
lineHeight: '22px',
});
export const memberItem = style({
display: 'flex',
alignItems: 'center',
@@ -92,20 +85,12 @@ export const memberItem = style({
borderRadius: '4px',
});
export const memberItemContent = style({
display: 'flex',
alignItems: 'center',
gap: '8px',
overflow: 'hidden',
});
export const memberName = style({
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
fontSize: '12px',
lineHeight: '20px',
padding: '0 4px',
fontSize: '14px',
lineHeight: '22px',
flex: 1,
});
@@ -118,9 +103,9 @@ export const avatar = style({
export const loadingContainer = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: '16px',
padding: '4px 0',
gap: '8px',
});
export const noResultContainer = style({