mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-22 19:53:48 +08:00
fix(core): adjust new doc list filter style (#12629)
close AF-2678, AF-2677, AF-2674, AF-2655 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added customizable spacing for dividers. - Introduced a flexible filter value menu for easier filter editing. - Added options to control visibility of creation actions in empty document views. - **Improvements** - Enhanced menu components for filter values with a more declarative and simplified interface. - Improved vertical alignment in some UI containers. - Updated divider spacing for more consistent UI appearance. - **Bug Fixes** - Menu popups for filters now appear in correct positions. - **Removals** - Removed support for the "zotero" integration type from integration settings and filters. - **Style** - Updated CSS for better menu positioning and alignment. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import type { HTMLAttributes, PropsWithChildren } from 'react';
|
import type { HTMLAttributes, PropsWithChildren } from 'react';
|
||||||
import { forwardRef } from 'react';
|
import { forwardRef } from 'react';
|
||||||
@@ -8,6 +9,7 @@ export type DividerProps = PropsWithChildren &
|
|||||||
Omit<HTMLAttributes<HTMLDivElement>, 'type'> & {
|
Omit<HTMLAttributes<HTMLDivElement>, 'type'> & {
|
||||||
orientation?: DividerOrientation;
|
orientation?: DividerOrientation;
|
||||||
size?: 'thinner' | 'default';
|
size?: 'thinner' | 'default';
|
||||||
|
space?: number;
|
||||||
dividerColor?: string;
|
dividerColor?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -16,6 +18,7 @@ export const Divider = forwardRef<HTMLDivElement, DividerProps>(
|
|||||||
{
|
{
|
||||||
orientation = 'horizontal',
|
orientation = 'horizontal',
|
||||||
size = 'default',
|
size = 'default',
|
||||||
|
space: propSpace,
|
||||||
dividerColor,
|
dividerColor,
|
||||||
style,
|
style,
|
||||||
className,
|
className,
|
||||||
@@ -23,6 +26,8 @@ export const Divider = forwardRef<HTMLDivElement, DividerProps>(
|
|||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
|
const space = propSpace ?? (orientation === 'horizontal' ? 8 : 2);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
data-divider
|
data-divider
|
||||||
@@ -38,6 +43,7 @@ export const Divider = forwardRef<HTMLDivElement, DividerProps>(
|
|||||||
style={{
|
style={{
|
||||||
borderColor: dividerColor ? dividerColor : undefined,
|
borderColor: dividerColor ? dividerColor : undefined,
|
||||||
...style,
|
...style,
|
||||||
|
...assignInlineVars({ [styles.dividerSpace]: `${space}px` }),
|
||||||
}}
|
}}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
import { cssVar } from '@toeverything/theme';
|
import { cssVar } from '@toeverything/theme';
|
||||||
import { style } from '@vanilla-extract/css';
|
import { createVar, style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
export const dividerSpace = createVar('dividerSpace');
|
||||||
|
|
||||||
export const divider = style({
|
export const divider = style({
|
||||||
|
vars: {
|
||||||
|
[dividerSpace]: '8px',
|
||||||
|
},
|
||||||
borderBottom: `1px solid ${cssVar('borderColor')}`,
|
borderBottom: `1px solid ${cssVar('borderColor')}`,
|
||||||
height: 0,
|
height: 0,
|
||||||
margin: '8px 0',
|
margin: `${dividerSpace} 0`,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -11,7 +17,7 @@ export const verticalDivider = style({
|
|||||||
borderLeft: `1px solid ${cssVar('borderColor')}`,
|
borderLeft: `1px solid ${cssVar('borderColor')}`,
|
||||||
width: 0,
|
width: 0,
|
||||||
height: '100%',
|
height: '100%',
|
||||||
margin: '0 2px',
|
margin: `0 ${dividerSpace}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const thinner = style({
|
export const thinner = style({
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ export interface EmptyDocsProps extends UniversalEmptyProps {
|
|||||||
* Used for "New doc", if provided, new doc will be created with this tag.
|
* Used for "New doc", if provided, new doc will be created with this tag.
|
||||||
*/
|
*/
|
||||||
tagId?: string;
|
tagId?: string;
|
||||||
|
allowCreate?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EmptyDocs = ({
|
export const EmptyDocs = ({
|
||||||
type = 'all',
|
type = 'all',
|
||||||
tagId,
|
tagId,
|
||||||
|
allowCreate = true,
|
||||||
...props
|
...props
|
||||||
}: EmptyDocsProps) => {
|
}: EmptyDocsProps) => {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
@@ -56,7 +58,7 @@ export const EmptyDocs = ({
|
|||||||
: t['com.affine.empty.docs.all-description']()
|
: t['com.affine.empty.docs.all-description']()
|
||||||
}
|
}
|
||||||
action={
|
action={
|
||||||
showActionButton ? (
|
allowCreate && showActionButton ? (
|
||||||
<ActionButton onClick={onCreate} prefix={<AllDocsIcon />}>
|
<ActionButton onClick={onCreate} prefix={<AllDocsIcon />}>
|
||||||
{t['com.affine.empty.docs.action.new-doc']()}
|
{t['com.affine.empty.docs.action.new-doc']()}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
|
|||||||
@@ -81,12 +81,13 @@ const ExplorerDisplayMenu = ({
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</MenuSub>
|
</MenuSub>
|
||||||
<Divider size="thinner" />
|
<Divider space={4} size="thinner" />
|
||||||
<DisplayProperties
|
<DisplayProperties
|
||||||
displayPreference={displayPreference}
|
displayPreference={displayPreference}
|
||||||
onDisplayPreferenceChange={onDisplayPreferenceChange}
|
onDisplayPreferenceChange={onDisplayPreferenceChange}
|
||||||
/>
|
/>
|
||||||
<Divider size="thinner" />
|
|
||||||
|
<Divider space={4} size="thinner" />
|
||||||
<QuickActionsConfig
|
<QuickActionsConfig
|
||||||
displayPreference={displayPreference}
|
displayPreference={displayPreference}
|
||||||
onDisplayPreferenceChange={onDisplayPreferenceChange}
|
onDisplayPreferenceChange={onDisplayPreferenceChange}
|
||||||
|
|||||||
@@ -102,26 +102,30 @@ export const DisplayProperties = ({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<Divider size="thinner" />
|
{displayPreference.view === 'list' ? (
|
||||||
<section className={styles.sectionLabel}>
|
<>
|
||||||
{t['com.affine.all-docs.display.list-view']()}
|
<Divider space={4} size="thinner" />
|
||||||
</section>
|
<section className={styles.sectionLabel}>
|
||||||
<div className={styles.properties}>
|
{t['com.affine.all-docs.display.list-view']()}
|
||||||
<Button
|
</section>
|
||||||
className={styles.property}
|
<div className={styles.properties}>
|
||||||
data-show={showIcon}
|
<Button
|
||||||
onClick={toggleIcon}
|
className={styles.property}
|
||||||
>
|
data-show={showIcon}
|
||||||
{t['com.affine.all-docs.display.list-view.icon']()}
|
onClick={toggleIcon}
|
||||||
</Button>
|
>
|
||||||
<Button
|
{t['com.affine.all-docs.display.list-view.icon']()}
|
||||||
className={styles.property}
|
</Button>
|
||||||
data-show={showBody}
|
<Button
|
||||||
onClick={toggleBody}
|
className={styles.property}
|
||||||
>
|
data-show={showBody}
|
||||||
{t['com.affine.all-docs.display.list-view.body']()}
|
onClick={toggleBody}
|
||||||
</Button>
|
>
|
||||||
</div>
|
{t['com.affine.all-docs.display.list-view.body']()}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { useLiveData, useService } from '@toeverything/infra';
|
|||||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||||
import { memo, useCallback, useContext, useEffect, useMemo } from 'react';
|
import { memo, useCallback, useContext, useEffect, useMemo } from 'react';
|
||||||
|
|
||||||
|
import { EmptyDocs } from '../../affine/empty';
|
||||||
import { ListFloatingToolbar } from '../../page-list/components/list-floating-toolbar';
|
import { ListFloatingToolbar } from '../../page-list/components/list-floating-toolbar';
|
||||||
import { SystemPropertyTypes } from '../../system-property-types';
|
import { SystemPropertyTypes } from '../../system-property-types';
|
||||||
import { WorkspacePropertyTypes } from '../../workspace-property-types';
|
import { WorkspacePropertyTypes } from '../../workspace-property-types';
|
||||||
@@ -228,6 +229,12 @@ export const DocsExplorer = ({
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isEmpty = masonryItems.length === 0;
|
||||||
|
|
||||||
|
if (isEmpty) {
|
||||||
|
return <EmptyDocs allowCreate={false} style={{ height: '100%' }} />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Masonry
|
<Masonry
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { Menu, type MenuProps, type MenuRef } from '@affine/component';
|
||||||
|
import { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
export const FilterValueMenu = ({
|
||||||
|
isDraft,
|
||||||
|
rootOptions,
|
||||||
|
contentOptions,
|
||||||
|
onDraftCompleted,
|
||||||
|
...otherProps
|
||||||
|
}: { isDraft?: boolean; onDraftCompleted?: () => void } & MenuProps) => {
|
||||||
|
const menuRef = useRef<MenuRef>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isDraft) {
|
||||||
|
menuRef.current?.changeOpen(true);
|
||||||
|
}
|
||||||
|
}, [isDraft]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Menu
|
||||||
|
ref={menuRef}
|
||||||
|
rootOptions={{
|
||||||
|
onClose: onDraftCompleted,
|
||||||
|
...rootOptions,
|
||||||
|
}}
|
||||||
|
contentOptions={{
|
||||||
|
alignOffset: -4,
|
||||||
|
...contentOptions,
|
||||||
|
}}
|
||||||
|
{...otherProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Menu, MenuItem, type MenuRef } from '@affine/component';
|
import { MenuItem } from '@affine/component';
|
||||||
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
||||||
import { useEffect, useRef } from 'react';
|
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
|
|
||||||
export const FavoriteFilterValue = ({
|
export const FavoriteFilterValue = ({
|
||||||
filter,
|
filter,
|
||||||
@@ -13,20 +14,10 @@ export const FavoriteFilterValue = ({
|
|||||||
onDraftCompleted?: () => void;
|
onDraftCompleted?: () => void;
|
||||||
onChange?: (filter: FilterParams) => void;
|
onChange?: (filter: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
isDraft={isDraft}
|
||||||
rootOptions={{
|
onDraftCompleted={onDraftCompleted}
|
||||||
onClose: onDraftCompleted,
|
|
||||||
}}
|
|
||||||
items={
|
items={
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -55,6 +46,6 @@ export const FavoriteFilterValue = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>{filter.value === 'true' ? 'True' : 'False'}</span>
|
<span>{filter.value === 'true' ? 'True' : 'False'}</span>
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
import { Menu, MenuItem, type MenuRef } from '@affine/component';
|
import { MenuItem } from '@affine/component';
|
||||||
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
||||||
import type { DocRecord } from '@affine/core/modules/doc';
|
import type { DocRecord } from '@affine/core/modules/doc';
|
||||||
|
import { IntegrationTypeIcon } from '@affine/core/modules/integration';
|
||||||
|
import { INTEGRATION_TYPE_NAME_MAP } from '@affine/core/modules/integration/constant';
|
||||||
|
import type { IntegrationType } from '@affine/core/modules/integration/type';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { IntegrationsIcon, ReadwiseIcon } from '@blocksuite/icons/rc';
|
import { IntegrationsIcon, ReadwiseIcon } from '@blocksuite/icons/rc';
|
||||||
import { useLiveData } from '@toeverything/infra';
|
import { useLiveData } from '@toeverything/infra';
|
||||||
import { useEffect, useRef } from 'react';
|
|
||||||
|
|
||||||
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
||||||
import { StackProperty } from '../explorer/docs-view/stack-property';
|
import { StackProperty } from '../explorer/docs-view/stack-property';
|
||||||
import type { GroupHeaderProps } from '../explorer/types';
|
import type { GroupHeaderProps } from '../explorer/types';
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
|
|
||||||
export const IntegrationTypeFilterValue = ({
|
export const IntegrationTypeFilterValue = ({
|
||||||
filter,
|
filter,
|
||||||
@@ -22,41 +25,37 @@ export const IntegrationTypeFilterValue = ({
|
|||||||
onChange?: (filter: FilterParams) => void;
|
onChange?: (filter: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
isDraft={isDraft}
|
||||||
rootOptions={{
|
onDraftCompleted={onDraftCompleted}
|
||||||
onClose: onDraftCompleted,
|
items={Object.entries(INTEGRATION_TYPE_NAME_MAP).map(entries => {
|
||||||
}}
|
const type = entries[0] as IntegrationType;
|
||||||
items={
|
const i18nKey = entries[1];
|
||||||
<MenuItem
|
return (
|
||||||
onClick={() => {
|
<MenuItem
|
||||||
onChange?.({
|
key={type}
|
||||||
...filter,
|
onClick={() => {
|
||||||
value: 'readwise',
|
onChange?.({
|
||||||
});
|
...filter,
|
||||||
}}
|
value: type,
|
||||||
prefixIcon={<ReadwiseIcon />}
|
});
|
||||||
selected={filter.value === 'readwise'}
|
}}
|
||||||
>
|
prefixIcon={<IntegrationTypeIcon type={type} />}
|
||||||
{t['com.affine.integration.readwise.name']()}
|
selected={filter.value === type}
|
||||||
</MenuItem>
|
>
|
||||||
}
|
{t.t(i18nKey)}
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
{filter.value === 'readwise'
|
{INTEGRATION_TYPE_NAME_MAP[filter.value as IntegrationType]
|
||||||
? t['com.affine.integration.readwise.name']()
|
? t.t(INTEGRATION_TYPE_NAME_MAP[filter.value as IntegrationType])
|
||||||
: filter.value}
|
: filter.value}
|
||||||
</span>
|
</span>
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Menu, MenuItem, type MenuRef } from '@affine/component';
|
import { MenuItem } from '@affine/component';
|
||||||
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
||||||
import { useEffect, useRef } from 'react';
|
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
|
|
||||||
export const SharedFilterValue = ({
|
export const SharedFilterValue = ({
|
||||||
filter,
|
filter,
|
||||||
@@ -13,20 +14,10 @@ export const SharedFilterValue = ({
|
|||||||
onDraftCompleted?: () => void;
|
onDraftCompleted?: () => void;
|
||||||
onChange?: (filter: FilterParams) => void;
|
onChange?: (filter: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
isDraft={isDraft}
|
||||||
rootOptions={{
|
onDraftCompleted={onDraftCompleted}
|
||||||
onClose: onDraftCompleted,
|
|
||||||
}}
|
|
||||||
items={
|
items={
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -55,6 +46,6 @@ export const SharedFilterValue = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>{filter.value === 'true' ? 'True' : 'False'}</span>
|
<span>{filter.value === 'true' ? 'True' : 'False'}</span>
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,18 +1,13 @@
|
|||||||
import {
|
import { Checkbox, MenuItem, PropertyValue } from '@affine/component';
|
||||||
Checkbox,
|
|
||||||
Menu,
|
|
||||||
MenuItem,
|
|
||||||
type MenuRef,
|
|
||||||
PropertyValue,
|
|
||||||
} from '@affine/component';
|
|
||||||
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { CheckBoxCheckLinearIcon } from '@blocksuite/icons/rc';
|
import { CheckBoxCheckLinearIcon } from '@blocksuite/icons/rc';
|
||||||
import { useCallback, useEffect, useRef } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
||||||
import { StackProperty } from '../explorer/docs-view/stack-property';
|
import { StackProperty } from '../explorer/docs-view/stack-property';
|
||||||
import type { DocListPropertyProps, GroupHeaderProps } from '../explorer/types';
|
import type { DocListPropertyProps, GroupHeaderProps } from '../explorer/types';
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
import type { PropertyValueProps } from '../properties/types';
|
import type { PropertyValueProps } from '../properties/types';
|
||||||
import * as styles from './checkbox.css';
|
import * as styles from './checkbox.css';
|
||||||
|
|
||||||
@@ -55,20 +50,10 @@ export const CheckboxFilterValue = ({
|
|||||||
onDraftCompleted?: () => void;
|
onDraftCompleted?: () => void;
|
||||||
onChange?: (filter: FilterParams) => void;
|
onChange?: (filter: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
isDraft={isDraft}
|
||||||
rootOptions={{
|
onDraftCompleted={onDraftCompleted}
|
||||||
onClose: onDraftCompleted,
|
|
||||||
}}
|
|
||||||
items={
|
items={
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -97,7 +82,7 @@ export const CheckboxFilterValue = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>{filter.value === 'true' ? 'True' : 'False'}</span>
|
<span>{filter.value === 'true' ? 'True' : 'False'}</span>
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+4
@@ -9,3 +9,7 @@ export const userLabelContainer = style({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const filterValueMenu = style({
|
||||||
|
top: 'calc(var(--radix-popper-anchor-height) - 18px) !important',
|
||||||
|
});
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ export const CreatedByUpdatedByFilterValue = ({
|
|||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
ref={menuRef}
|
ref={menuRef}
|
||||||
onEditorClose={onDraftCompleted}
|
onEditorClose={onDraftCompleted}
|
||||||
|
menuClassName={styles.filterValueMenu}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
||||||
import { StackProperty } from '../explorer/docs-view/stack-property';
|
import { StackProperty } from '../explorer/docs-view/stack-property';
|
||||||
import type { DocListPropertyProps, GroupHeaderProps } from '../explorer/types';
|
import type { DocListPropertyProps, GroupHeaderProps } from '../explorer/types';
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
import { FilterOptionsGroup } from '../filter/options';
|
import { FilterOptionsGroup } from '../filter/options';
|
||||||
import type { PropertyValueProps } from '../properties/types';
|
import type { PropertyValueProps } from '../properties/types';
|
||||||
import * as styles from './date.css';
|
import * as styles from './date.css';
|
||||||
@@ -123,11 +124,14 @@ const DateSelectorMenu = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
rootOptions={{
|
rootOptions={{
|
||||||
open,
|
open,
|
||||||
onOpenChange: handleOpenChange,
|
onOpenChange: handleOpenChange,
|
||||||
}}
|
}}
|
||||||
|
contentOptions={{
|
||||||
|
style: { padding: '12px 16px' },
|
||||||
|
}}
|
||||||
items={<DatePicker value={value || undefined} onChange={handleChange} />}
|
items={<DatePicker value={value || undefined} onChange={handleChange} />}
|
||||||
>
|
>
|
||||||
{value ? (
|
{value ? (
|
||||||
@@ -137,7 +141,7 @@ const DateSelectorMenu = ({
|
|||||||
{t['com.affine.filter.empty']()}
|
{t['com.affine.filter.empty']()}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+6
-16
@@ -1,7 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
Menu,
|
|
||||||
MenuItem,
|
MenuItem,
|
||||||
type MenuRef,
|
|
||||||
notify,
|
notify,
|
||||||
PropertyValue,
|
PropertyValue,
|
||||||
type RadioItem,
|
type RadioItem,
|
||||||
@@ -12,11 +10,12 @@ import { useI18n } from '@affine/i18n';
|
|||||||
import type { DocMode } from '@blocksuite/affine/model';
|
import type { DocMode } from '@blocksuite/affine/model';
|
||||||
import { EdgelessIcon, PageIcon } from '@blocksuite/icons/rc';
|
import { EdgelessIcon, PageIcon } from '@blocksuite/icons/rc';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
||||||
import { StackProperty } from '../explorer/docs-view/stack-property';
|
import { StackProperty } from '../explorer/docs-view/stack-property';
|
||||||
import type { DocListPropertyProps, GroupHeaderProps } from '../explorer/types';
|
import type { DocListPropertyProps, GroupHeaderProps } from '../explorer/types';
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
import type { PropertyValueProps } from '../properties/types';
|
import type { PropertyValueProps } from '../properties/types';
|
||||||
import { PropertyRadioGroup } from '../properties/widgets/radio-group';
|
import { PropertyRadioGroup } from '../properties/widgets/radio-group';
|
||||||
import * as styles from './doc-primary-mode.css';
|
import * as styles from './doc-primary-mode.css';
|
||||||
@@ -89,20 +88,11 @@ export const DocPrimaryModeFilterValue = ({
|
|||||||
onChange?: (filter: FilterParams) => void;
|
onChange?: (filter: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
isDraft={isDraft}
|
||||||
rootOptions={{
|
onDraftCompleted={onDraftCompleted}
|
||||||
onClose: onDraftCompleted,
|
|
||||||
}}
|
|
||||||
items={
|
items={
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -131,7 +121,7 @@ export const DocPrimaryModeFilterValue = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>{filter.value === 'edgeless' ? t['Edgeless']() : t['Page']()}</span>
|
<span>{filter.value === 'edgeless' ? t['Edgeless']() : t['Page']()}</span>
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,15 @@
|
|||||||
import {
|
import { MenuItem, PropertyValue, type RadioItem } from '@affine/component';
|
||||||
Menu,
|
|
||||||
MenuItem,
|
|
||||||
type MenuRef,
|
|
||||||
PropertyValue,
|
|
||||||
type RadioItem,
|
|
||||||
} from '@affine/component';
|
|
||||||
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
||||||
import { type DocRecord, DocService } from '@affine/core/modules/doc';
|
import { type DocRecord, DocService } from '@affine/core/modules/doc';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { EdgelessIcon } from '@blocksuite/icons/rc';
|
import { EdgelessIcon } from '@blocksuite/icons/rc';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
||||||
import { StackProperty } from '../explorer/docs-view/stack-property';
|
import { StackProperty } from '../explorer/docs-view/stack-property';
|
||||||
import type { GroupHeaderProps } from '../explorer/types';
|
import type { GroupHeaderProps } from '../explorer/types';
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
import type { PropertyValueProps } from '../properties/types';
|
import type { PropertyValueProps } from '../properties/types';
|
||||||
import { PropertyRadioGroup } from '../properties/widgets/radio-group';
|
import { PropertyRadioGroup } from '../properties/widgets/radio-group';
|
||||||
import * as styles from './edgeless-theme.css';
|
import * as styles from './edgeless-theme.css';
|
||||||
@@ -97,20 +92,11 @@ export const EdgelessThemeFilterValue = ({
|
|||||||
onChange?: (filter: FilterParams) => void;
|
onChange?: (filter: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
isDraft={isDraft}
|
||||||
rootOptions={{
|
onDraftCompleted={onDraftCompleted}
|
||||||
onClose: onDraftCompleted,
|
|
||||||
}}
|
|
||||||
items={
|
items={
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -156,7 +142,7 @@ export const EdgelessThemeFilterValue = ({
|
|||||||
? t['com.affine.themeSettings.light']()
|
? t['com.affine.themeSettings.light']()
|
||||||
: t['com.affine.themeSettings.dark']()}
|
: t['com.affine.themeSettings.dark']()}
|
||||||
</span>
|
</span>
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import {
|
|||||||
DatePicker,
|
DatePicker,
|
||||||
Menu,
|
Menu,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
type MenuRef,
|
|
||||||
PropertyValue,
|
PropertyValue,
|
||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
import { MobileJournalConflictList } from '@affine/core/mobile/pages/workspace/detail/menu/journal-conflicts';
|
import { MobileJournalConflictList } from '@affine/core/mobile/pages/workspace/detail/menu/journal-conflicts';
|
||||||
@@ -25,6 +24,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|||||||
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
||||||
import { StackProperty } from '../explorer/docs-view/stack-property';
|
import { StackProperty } from '../explorer/docs-view/stack-property';
|
||||||
import type { DocListPropertyProps, GroupHeaderProps } from '../explorer/types';
|
import type { DocListPropertyProps, GroupHeaderProps } from '../explorer/types';
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
import type { PropertyValueProps } from '../properties/types';
|
import type { PropertyValueProps } from '../properties/types';
|
||||||
import * as styles from './journal.css';
|
import * as styles from './journal.css';
|
||||||
|
|
||||||
@@ -192,20 +192,10 @@ export const JournalFilterValue = ({
|
|||||||
onDraftCompleted?: () => void;
|
onDraftCompleted?: () => void;
|
||||||
onChange?: (filter: FilterParams) => void;
|
onChange?: (filter: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
isDraft={isDraft}
|
||||||
rootOptions={{
|
onDraftCompleted={onDraftCompleted}
|
||||||
onClose: onDraftCompleted,
|
|
||||||
}}
|
|
||||||
items={
|
items={
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -234,7 +224,7 @@ export const JournalFilterValue = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>{filter.value === 'true' ? 'True' : 'False'}</span>
|
<span>{filter.value === 'true' ? 'True' : 'False'}</span>
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Input, Menu, type MenuRef, PropertyValue } from '@affine/component';
|
import { Input, PropertyValue } from '@affine/component';
|
||||||
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { NumberIcon } from '@blocksuite/icons/rc';
|
import { NumberIcon } from '@blocksuite/icons/rc';
|
||||||
@@ -8,13 +8,13 @@ import {
|
|||||||
type ChangeEventHandler,
|
type ChangeEventHandler,
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useRef,
|
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
||||||
import { StackProperty } from '../explorer/docs-view/stack-property';
|
import { StackProperty } from '../explorer/docs-view/stack-property';
|
||||||
import type { GroupHeaderProps } from '../explorer/types';
|
import type { GroupHeaderProps } from '../explorer/types';
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
import type { PropertyValueProps } from '../properties/types';
|
import type { PropertyValueProps } from '../properties/types';
|
||||||
import * as styles from './number.css';
|
import * as styles from './number.css';
|
||||||
|
|
||||||
@@ -77,15 +77,8 @@ export const NumberFilterValue = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [tempValue, setTempValue] = useState(filter.value || '');
|
const [tempValue, setTempValue] = useState(filter.value || '');
|
||||||
const [valueMenuOpen, setValueMenuOpen] = useState(false);
|
const [valueMenuOpen, setValueMenuOpen] = useState(false);
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// update temp value with new filter value
|
// update temp value with new filter value
|
||||||
setTempValue(filter.value || '');
|
setTempValue(filter.value || '');
|
||||||
@@ -126,8 +119,7 @@ export const NumberFilterValue = ({
|
|||||||
}, [isDraft, filter.method, onDraftCompleted]);
|
}, [isDraft, filter.method, onDraftCompleted]);
|
||||||
|
|
||||||
return filter.method !== 'is-not-empty' && filter.method !== 'is-empty' ? (
|
return filter.method !== 'is-not-empty' && filter.method !== 'is-empty' ? (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
|
||||||
rootOptions={{
|
rootOptions={{
|
||||||
open: valueMenuOpen,
|
open: valueMenuOpen,
|
||||||
onOpenChange: setValueMenuOpen,
|
onOpenChange: setValueMenuOpen,
|
||||||
@@ -135,7 +127,6 @@ export const NumberFilterValue = ({
|
|||||||
}}
|
}}
|
||||||
contentOptions={{
|
contentOptions={{
|
||||||
onPointerDownOutside: submitTempValue,
|
onPointerDownOutside: submitTempValue,
|
||||||
sideOffset: -28,
|
|
||||||
}}
|
}}
|
||||||
items={
|
items={
|
||||||
<Input
|
<Input
|
||||||
@@ -163,7 +154,7 @@ export const NumberFilterValue = ({
|
|||||||
{t['com.affine.filter.empty']()}
|
{t['com.affine.filter.empty']()}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,16 @@
|
|||||||
import {
|
import { MenuItem, PropertyValue, type RadioItem } from '@affine/component';
|
||||||
Menu,
|
|
||||||
MenuItem,
|
|
||||||
type MenuRef,
|
|
||||||
PropertyValue,
|
|
||||||
type RadioItem,
|
|
||||||
} from '@affine/component';
|
|
||||||
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
||||||
import { type DocRecord, DocService } from '@affine/core/modules/doc';
|
import { type DocRecord, DocService } from '@affine/core/modules/doc';
|
||||||
import { EditorSettingService } from '@affine/core/modules/editor-setting';
|
import { EditorSettingService } from '@affine/core/modules/editor-setting';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { LongerIcon } from '@blocksuite/icons/rc';
|
import { LongerIcon } from '@blocksuite/icons/rc';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
||||||
import { StackProperty } from '../explorer/docs-view/stack-property';
|
import { StackProperty } from '../explorer/docs-view/stack-property';
|
||||||
import type { GroupHeaderProps } from '../explorer/types';
|
import type { GroupHeaderProps } from '../explorer/types';
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
import type { PropertyValueProps } from '../properties/types';
|
import type { PropertyValueProps } from '../properties/types';
|
||||||
import { PropertyRadioGroup } from '../properties/widgets/radio-group';
|
import { PropertyRadioGroup } from '../properties/widgets/radio-group';
|
||||||
import { container } from './page-width.css';
|
import { container } from './page-width.css';
|
||||||
@@ -99,20 +94,11 @@ export const PageWidthFilterValue = ({
|
|||||||
onChange?: (filter: FilterParams) => void;
|
onChange?: (filter: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
isDraft={isDraft}
|
||||||
rootOptions={{
|
onDraftCompleted={onDraftCompleted}
|
||||||
onClose: onDraftCompleted,
|
|
||||||
}}
|
|
||||||
items={
|
items={
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -153,7 +139,7 @@ export const PageWidthFilterValue = ({
|
|||||||
'com.affine.settings.editorSettings.page.default-page-width.standard'
|
'com.affine.settings.editorSettings.page.default-page-width.standard'
|
||||||
]()}
|
]()}
|
||||||
</span>
|
</span>
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -24,3 +24,6 @@ export const groupHeaderLabel = style({
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: 4,
|
gap: 4,
|
||||||
});
|
});
|
||||||
|
export const filterValueMenu = style({
|
||||||
|
top: 'calc(var(--radix-popper-anchor-height) - 18px) !important',
|
||||||
|
});
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ export const TagsFilterValue = ({
|
|||||||
selectedTags={selectedTags}
|
selectedTags={selectedTags}
|
||||||
onSelectTag={handleSelectTag}
|
onSelectTag={handleSelectTag}
|
||||||
onDeselectTag={handleDeselectTag}
|
onDeselectTag={handleDeselectTag}
|
||||||
|
menuClassName={styles.filterValueMenu}
|
||||||
tagMode="inline-tag"
|
tagMode="inline-tag"
|
||||||
ref={menuRef}
|
ref={menuRef}
|
||||||
onEditorClose={onDraftCompleted}
|
onEditorClose={onDraftCompleted}
|
||||||
|
|||||||
@@ -1,20 +1,15 @@
|
|||||||
import {
|
import { Checkbox, MenuItem, PropertyValue } from '@affine/component';
|
||||||
Checkbox,
|
|
||||||
Menu,
|
|
||||||
MenuItem,
|
|
||||||
type MenuRef,
|
|
||||||
PropertyValue,
|
|
||||||
} from '@affine/component';
|
|
||||||
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
||||||
import { type DocRecord, DocService } from '@affine/core/modules/doc';
|
import { type DocRecord, DocService } from '@affine/core/modules/doc';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { TemplateIcon } from '@blocksuite/icons/rc';
|
import { TemplateIcon } from '@blocksuite/icons/rc';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
import { type ChangeEvent, useCallback, useEffect, useRef } from 'react';
|
import { type ChangeEvent, useCallback } from 'react';
|
||||||
|
|
||||||
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
||||||
import { StackProperty } from '../explorer/docs-view/stack-property';
|
import { StackProperty } from '../explorer/docs-view/stack-property';
|
||||||
import type { GroupHeaderProps } from '../explorer/types';
|
import type { GroupHeaderProps } from '../explorer/types';
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
import type { PropertyValueProps } from '../properties/types';
|
import type { PropertyValueProps } from '../properties/types';
|
||||||
import * as styles from './template.css';
|
import * as styles from './template.css';
|
||||||
|
|
||||||
@@ -95,20 +90,10 @@ export const TemplateFilterValue = ({
|
|||||||
onDraftCompleted?: () => void;
|
onDraftCompleted?: () => void;
|
||||||
onChange?: (filter: FilterParams) => void;
|
onChange?: (filter: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
isDraft={isDraft}
|
||||||
rootOptions={{
|
onDraftCompleted={onDraftCompleted}
|
||||||
onClose: onDraftCompleted,
|
|
||||||
}}
|
|
||||||
items={
|
items={
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -137,6 +122,6 @@ export const TemplateFilterValue = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>{filter.value === 'true' ? 'True' : 'False'}</span>
|
<span>{filter.value === 'true' ? 'True' : 'False'}</span>
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Input, Menu, type MenuRef, PropertyValue } from '@affine/component';
|
import { Input, PropertyValue } from '@affine/component';
|
||||||
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { TextIcon, TextTypeIcon } from '@blocksuite/icons/rc';
|
import { TextIcon, TextTypeIcon } from '@blocksuite/icons/rc';
|
||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
import { PlainTextDocGroupHeader } from '../explorer/docs-view/group-header';
|
||||||
import { StackProperty } from '../explorer/docs-view/stack-property';
|
import { StackProperty } from '../explorer/docs-view/stack-property';
|
||||||
import type { GroupHeaderProps } from '../explorer/types';
|
import type { GroupHeaderProps } from '../explorer/types';
|
||||||
|
import { FilterValueMenu } from '../filter/filter-value-menu';
|
||||||
import { ConfigModal } from '../mobile';
|
import { ConfigModal } from '../mobile';
|
||||||
import type { PropertyValueProps } from '../properties/types';
|
import type { PropertyValueProps } from '../properties/types';
|
||||||
import * as styles from './text.css';
|
import * as styles from './text.css';
|
||||||
@@ -188,15 +189,8 @@ export const TextFilterValue = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [tempValue, setTempValue] = useState(filter.value || '');
|
const [tempValue, setTempValue] = useState(filter.value || '');
|
||||||
const [valueMenuOpen, setValueMenuOpen] = useState(false);
|
const [valueMenuOpen, setValueMenuOpen] = useState(false);
|
||||||
const menuRef = useRef<MenuRef>(null);
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDraft) {
|
|
||||||
menuRef.current?.changeOpen(true);
|
|
||||||
}
|
|
||||||
}, [isDraft]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// update temp value with new filter value
|
// update temp value with new filter value
|
||||||
setTempValue(filter.value || '');
|
setTempValue(filter.value || '');
|
||||||
@@ -237,8 +231,8 @@ export const TextFilterValue = ({
|
|||||||
}, [isDraft, filter.method, onDraftCompleted]);
|
}, [isDraft, filter.method, onDraftCompleted]);
|
||||||
|
|
||||||
return filter.method !== 'is-not-empty' && filter.method !== 'is-empty' ? (
|
return filter.method !== 'is-not-empty' && filter.method !== 'is-empty' ? (
|
||||||
<Menu
|
<FilterValueMenu
|
||||||
ref={menuRef}
|
isDraft={isDraft}
|
||||||
rootOptions={{
|
rootOptions={{
|
||||||
open: valueMenuOpen,
|
open: valueMenuOpen,
|
||||||
onOpenChange: setValueMenuOpen,
|
onOpenChange: setValueMenuOpen,
|
||||||
@@ -246,7 +240,6 @@ export const TextFilterValue = ({
|
|||||||
}}
|
}}
|
||||||
contentOptions={{
|
contentOptions={{
|
||||||
onPointerDownOutside: submitTempValue,
|
onPointerDownOutside: submitTempValue,
|
||||||
sideOffset: -28,
|
|
||||||
}}
|
}}
|
||||||
items={
|
items={
|
||||||
<Input
|
<Input
|
||||||
@@ -272,7 +265,7 @@ export const TextFilterValue = ({
|
|||||||
{t['com.affine.filter.empty']()}
|
{t['com.affine.filter.empty']()}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</Menu>
|
</FilterValueMenu>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -45,4 +45,5 @@ export const container = style({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
gap: 4,
|
gap: 4,
|
||||||
|
alignItems: 'center',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { nanoid } from 'nanoid';
|
|||||||
|
|
||||||
import type { WorkspacePropertyType } from '../../workspace-property';
|
import type { WorkspacePropertyType } from '../../workspace-property';
|
||||||
|
|
||||||
const integrationType = f.enum('readwise', 'zotero');
|
const integrationType = f.enum('readwise');
|
||||||
|
|
||||||
export const AFFiNE_WORKSPACE_DB_SCHEMA = {
|
export const AFFiNE_WORKSPACE_DB_SCHEMA = {
|
||||||
folders: {
|
folders: {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import type { IntegrationProperty, IntegrationType } from './type';
|
|||||||
// name
|
// name
|
||||||
export const INTEGRATION_TYPE_NAME_MAP: Record<IntegrationType, I18nString> = {
|
export const INTEGRATION_TYPE_NAME_MAP: Record<IntegrationType, I18nString> = {
|
||||||
readwise: 'com.affine.integration.name.readwise',
|
readwise: 'com.affine.integration.name.readwise',
|
||||||
zotero: 'Zotero',
|
// zotero: 'Zotero',
|
||||||
};
|
};
|
||||||
|
|
||||||
// schema
|
// schema
|
||||||
@@ -50,7 +50,7 @@ export const INTEGRATION_PROPERTY_SCHEMA: {
|
|||||||
icon: HistoryIcon,
|
icon: HistoryIcon,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
zotero: {},
|
// zotero: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
// icon
|
// icon
|
||||||
@@ -59,5 +59,5 @@ export const INTEGRATION_ICON_MAP: Record<
|
|||||||
React.ComponentType<SVGProps<SVGSVGElement>>
|
React.ComponentType<SVGProps<SVGSVGElement>>
|
||||||
> = {
|
> = {
|
||||||
readwise: ReadwiseLogoDuotoneIcon,
|
readwise: ReadwiseLogoDuotoneIcon,
|
||||||
zotero: () => null,
|
// zotero: () => null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ export type IntegrationType = NonNullable<DocIntegrationRef['type']>;
|
|||||||
|
|
||||||
export type IntegrationDocPropertiesMap = {
|
export type IntegrationDocPropertiesMap = {
|
||||||
readwise: ReadwiseDocProperties;
|
readwise: ReadwiseDocProperties;
|
||||||
zotero: never;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IntegrationProperty<T extends IntegrationType> = {
|
export type IntegrationProperty<T extends IntegrationType> = {
|
||||||
|
|||||||
Reference in New Issue
Block a user