mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
fix(core): select all in page list group header does not need to enable selection (#4869)
This commit is contained in:
@@ -3,6 +3,7 @@ import * as Toolbar from '@radix-ui/react-toolbar';
|
||||
import clsx from 'clsx';
|
||||
import {
|
||||
type CSSProperties,
|
||||
type HTMLAttributes,
|
||||
type MouseEventHandler,
|
||||
type PropsWithChildren,
|
||||
type ReactNode,
|
||||
@@ -16,13 +17,11 @@ interface FloatingToolbarProps {
|
||||
open?: boolean;
|
||||
}
|
||||
|
||||
interface FloatingToolbarButtonProps {
|
||||
interface FloatingToolbarButtonProps extends HTMLAttributes<HTMLButtonElement> {
|
||||
icon: ReactNode;
|
||||
onClick: MouseEventHandler;
|
||||
type?: 'danger' | 'default';
|
||||
label?: ReactNode;
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
}
|
||||
|
||||
interface FloatingToolbarItemProps {}
|
||||
@@ -40,7 +39,12 @@ export function FloatingToolbar({
|
||||
<Popover.Portal>
|
||||
{/* always pop up on top for now */}
|
||||
<Popover.Content side="top" className={styles.popoverContent}>
|
||||
<Toolbar.Root className={clsx(styles.root)}>{children}</Toolbar.Root>
|
||||
<Toolbar.Root
|
||||
data-testid="floating-toolbar"
|
||||
className={clsx(styles.root)}
|
||||
>
|
||||
{children}
|
||||
</Toolbar.Root>
|
||||
</Popover.Content>
|
||||
</Popover.Portal>
|
||||
</Popover.Root>
|
||||
@@ -62,6 +66,7 @@ export function FloatingToolbarButton({
|
||||
className,
|
||||
style,
|
||||
label,
|
||||
...props
|
||||
}: FloatingToolbarButtonProps) {
|
||||
return (
|
||||
<Toolbar.Button
|
||||
@@ -72,6 +77,7 @@ export function FloatingToolbarButton({
|
||||
className
|
||||
)}
|
||||
style={style}
|
||||
{...props}
|
||||
>
|
||||
<div className={styles.buttonIcon}>{icon}</div>
|
||||
{label}
|
||||
|
||||
@@ -119,19 +119,18 @@ export const PageGroupHeader = ({ id, items, label }: PageGroupProps) => {
|
||||
[id, setCollapseState]
|
||||
);
|
||||
|
||||
const selectionState = useAtomValue(selectionStateAtom);
|
||||
const [selectionState, setSelectionActive] = useAtom(selectionStateAtom);
|
||||
const selectedItems = useMemo(() => {
|
||||
const selectedPageIds = selectionState.selectedPageIds ?? [];
|
||||
return items.filter(item => selectedPageIds.includes(item.id));
|
||||
}, [items, selectionState.selectedPageIds]);
|
||||
|
||||
const allSelected = useMemo(() => {
|
||||
return items.every(
|
||||
item => selectionState.selectedPageIds?.includes(item.id)
|
||||
);
|
||||
}, [items, selectionState.selectedPageIds]);
|
||||
const allSelected = selectedItems.length === items.length;
|
||||
|
||||
const onSelectAll = useCallback(() => {
|
||||
// also enable selection active
|
||||
setSelectionActive(true);
|
||||
|
||||
const nonCurrentGroupIds =
|
||||
selectionState.selectedPageIds?.filter(
|
||||
id => !items.map(item => item.id).includes(id)
|
||||
@@ -142,12 +141,18 @@ export const PageGroupHeader = ({ id, items, label }: PageGroupProps) => {
|
||||
: [...nonCurrentGroupIds, ...items.map(item => item.id)];
|
||||
|
||||
selectionState.onSelectedPageIdsChange?.(newSelectedPageIds);
|
||||
}, [items, selectionState, allSelected]);
|
||||
}, [setSelectionActive, selectionState, allSelected, items]);
|
||||
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
return label ? (
|
||||
<div data-testid="page-list-group-header" className={styles.header}>
|
||||
<div
|
||||
data-testid="page-list-group-header"
|
||||
className={styles.header}
|
||||
data-group-id={id}
|
||||
data-group-items-count={items.length}
|
||||
data-group-selected-items-count={selectedItems.length}
|
||||
>
|
||||
<div
|
||||
role="button"
|
||||
onClick={onExpandedClicked}
|
||||
@@ -166,15 +171,13 @@ export const PageGroupHeader = ({ id, items, label }: PageGroupProps) => {
|
||||
</div>
|
||||
) : null}
|
||||
<div className={styles.spacer} />
|
||||
{selectionState.selectionActive ? (
|
||||
<button className={styles.selectAllButton} onClick={onSelectAll}>
|
||||
{t[
|
||||
allSelected
|
||||
? 'com.affine.page.group-header.clear'
|
||||
: 'com.affine.page.group-header.select-all'
|
||||
]()}
|
||||
</button>
|
||||
) : null}
|
||||
<button className={styles.selectAllButton} onClick={onSelectAll}>
|
||||
{t[
|
||||
allSelected
|
||||
? 'com.affine.page.group-header.clear'
|
||||
: 'com.affine.page.group-header.select-all'
|
||||
]()}
|
||||
</button>
|
||||
</div>
|
||||
) : null;
|
||||
};
|
||||
|
||||
@@ -101,6 +101,7 @@ const PageListHeaderCheckbox = () => {
|
||||
|
||||
return (
|
||||
<div
|
||||
data-testid="page-list-header-selection-checkbox"
|
||||
className={styles.headerTitleSelectionIconWrapper}
|
||||
onClick={onActivateSelection}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user