mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-16 05:47:09 +08:00
@@ -278,6 +278,16 @@ export const BlocksuiteDocEditor = forwardRef<
|
||||
[]
|
||||
);
|
||||
|
||||
const onPropertyInfoChange = useCallback(
|
||||
(property: DocCustomPropertyInfo, field: string) => {
|
||||
track.doc.inlineDocInfo.property.editPropertyMeta({
|
||||
type: property.type,
|
||||
field,
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.affineDocViewport}>
|
||||
@@ -293,6 +303,7 @@ export const BlocksuiteDocEditor = forwardRef<
|
||||
onDatabasePropertyChange={onDatabasePropertyChange}
|
||||
onPropertyChange={onPropertyChange}
|
||||
onPropertyAdded={onPropertyAdded}
|
||||
onPropertyInfoChange={onPropertyInfoChange}
|
||||
defaultOpenProperty={defaultOpenProperty}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -27,9 +27,14 @@ import * as styles from './styles.css';
|
||||
const PropertyItem = ({
|
||||
propertyInfo,
|
||||
defaultOpenEditMenu,
|
||||
onPropertyInfoChange,
|
||||
}: {
|
||||
propertyInfo: DocCustomPropertyInfo;
|
||||
defaultOpenEditMenu?: boolean;
|
||||
onPropertyInfoChange?: (
|
||||
field: keyof DocCustomPropertyInfo,
|
||||
value: string
|
||||
) => void;
|
||||
}) => {
|
||||
const t = useI18n();
|
||||
const workspaceService = useService(WorkspaceService);
|
||||
@@ -130,7 +135,12 @@ const PropertyItem = ({
|
||||
onOpenChange: setMoreMenuOpen,
|
||||
modal: true,
|
||||
}}
|
||||
items={<EditDocPropertyMenuItems propertyId={propertyInfo.id} />}
|
||||
items={
|
||||
<EditDocPropertyMenuItems
|
||||
propertyId={propertyInfo.id}
|
||||
onPropertyInfoChange={onPropertyInfoChange}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<IconButton size={20} iconClassName={styles.itemMore}>
|
||||
<MoreHorizontalIcon />
|
||||
@@ -145,8 +155,16 @@ const PropertyItem = ({
|
||||
export const DocPropertyManager = ({
|
||||
className,
|
||||
defaultOpenEditMenuPropertyId,
|
||||
onPropertyInfoChange,
|
||||
...props
|
||||
}: HTMLProps<HTMLDivElement> & { defaultOpenEditMenuPropertyId?: string }) => {
|
||||
}: HTMLProps<HTMLDivElement> & {
|
||||
defaultOpenEditMenuPropertyId?: string;
|
||||
onPropertyInfoChange?: (
|
||||
property: DocCustomPropertyInfo,
|
||||
field: keyof DocCustomPropertyInfo,
|
||||
value: string
|
||||
) => void;
|
||||
}) => {
|
||||
const docsService = useService(DocsService);
|
||||
|
||||
const properties = useLiveData(docsService.propertyList.sortedProperties$);
|
||||
@@ -160,6 +178,9 @@ export const DocPropertyManager = ({
|
||||
defaultOpenEditMenuPropertyId === propertyInfo.id
|
||||
}
|
||||
key={propertyInfo.id}
|
||||
onPropertyInfoChange={(...args) =>
|
||||
onPropertyInfoChange?.(propertyInfo, ...args)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
MenuSeparator,
|
||||
useConfirmModal,
|
||||
} from '@affine/component';
|
||||
import type { DocCustomPropertyInfo } from '@affine/core/modules/db';
|
||||
import { DocsService } from '@affine/core/modules/doc';
|
||||
import { Trans, useI18n } from '@affine/i18n';
|
||||
import { DeleteIcon, InvisibleIcon, ViewIcon } from '@blocksuite/icons/rc';
|
||||
@@ -26,8 +27,13 @@ import * as styles from './edit-doc-property.css';
|
||||
|
||||
export const EditDocPropertyMenuItems = ({
|
||||
propertyId,
|
||||
onPropertyInfoChange,
|
||||
}: {
|
||||
propertyId: string;
|
||||
onPropertyInfoChange?: (
|
||||
field: keyof DocCustomPropertyInfo,
|
||||
value: string
|
||||
) => void;
|
||||
}) => {
|
||||
const t = useI18n();
|
||||
const docsService = useService(DocsService);
|
||||
@@ -68,8 +74,9 @@ export const EditDocPropertyMenuItems = ({
|
||||
docsService.propertyList.updatePropertyInfo(propertyId, {
|
||||
name: e.currentTarget.value,
|
||||
});
|
||||
onPropertyInfoChange?.('name', e.currentTarget.value);
|
||||
},
|
||||
[docsService.propertyList, propertyId]
|
||||
[docsService.propertyList, propertyId, onPropertyInfoChange]
|
||||
);
|
||||
|
||||
const handleIconChange = useCallback(
|
||||
@@ -77,8 +84,9 @@ export const EditDocPropertyMenuItems = ({
|
||||
docsService.propertyList.updatePropertyInfo(propertyId, {
|
||||
icon: iconName,
|
||||
});
|
||||
onPropertyInfoChange?.('icon', iconName);
|
||||
},
|
||||
[docsService.propertyList, propertyId]
|
||||
[docsService.propertyList, propertyId, onPropertyInfoChange]
|
||||
);
|
||||
|
||||
const handleNameChange = useCallback((e: string) => {
|
||||
@@ -91,8 +99,9 @@ export const EditDocPropertyMenuItems = ({
|
||||
docsService.propertyList.updatePropertyInfo(propertyId, {
|
||||
show: 'always-show',
|
||||
});
|
||||
onPropertyInfoChange?.('show', 'always-show');
|
||||
},
|
||||
[docsService.propertyList, propertyId]
|
||||
[docsService.propertyList, propertyId, onPropertyInfoChange]
|
||||
);
|
||||
|
||||
const handleClickHideWhenEmpty = useCallback(
|
||||
@@ -101,8 +110,9 @@ export const EditDocPropertyMenuItems = ({
|
||||
docsService.propertyList.updatePropertyInfo(propertyId, {
|
||||
show: 'hide-when-empty',
|
||||
});
|
||||
onPropertyInfoChange?.('show', 'hide-when-empty');
|
||||
},
|
||||
[docsService.propertyList, propertyId]
|
||||
[docsService.propertyList, propertyId, onPropertyInfoChange]
|
||||
);
|
||||
|
||||
const handleClickAlwaysHide = useCallback(
|
||||
@@ -111,8 +121,9 @@ export const EditDocPropertyMenuItems = ({
|
||||
docsService.propertyList.updatePropertyInfo(propertyId, {
|
||||
show: 'always-hide',
|
||||
});
|
||||
onPropertyInfoChange?.('show', 'always-hide');
|
||||
},
|
||||
[docsService.propertyList, propertyId]
|
||||
[docsService.propertyList, propertyId, onPropertyInfoChange]
|
||||
);
|
||||
|
||||
if (!propertyInfo || !isSupportedDocPropertyType(propertyType)) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Divider, IconButton, Tooltip } from '@affine/component';
|
||||
import type { DocCustomPropertyInfo } from '@affine/core/modules/db';
|
||||
import { DocsService } from '@affine/core/modules/doc';
|
||||
import { generateUniqueNameInSequence } from '@affine/core/utils/unique-name';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
@@ -59,6 +60,16 @@ export const DocPropertySidebar = () => {
|
||||
[propertyList, properties]
|
||||
);
|
||||
|
||||
const onPropertyInfoChange = useCallback(
|
||||
(property: DocCustomPropertyInfo, field: string) => {
|
||||
track.doc.sidepanel.property.editPropertyMeta({
|
||||
type: property.type,
|
||||
field,
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<CollapsibleRoot defaultOpen>
|
||||
@@ -67,6 +78,7 @@ export const DocPropertySidebar = () => {
|
||||
<DocPropertyManager
|
||||
className={styles.manager}
|
||||
defaultOpenEditMenuPropertyId={newPropertyId}
|
||||
onPropertyInfoChange={onPropertyInfoChange}
|
||||
/>
|
||||
</CollapsibleContent>
|
||||
</CollapsibleRoot>
|
||||
|
||||
@@ -52,6 +52,11 @@ export interface DocPropertiesTableProps {
|
||||
defaultOpenProperty?: DefaultOpenProperty;
|
||||
onPropertyAdded?: (property: DocCustomPropertyInfo) => void;
|
||||
onPropertyChange?: (property: DocCustomPropertyInfo, value: unknown) => void;
|
||||
onPropertyInfoChange?: (
|
||||
property: DocCustomPropertyInfo,
|
||||
field: keyof DocCustomPropertyInfo,
|
||||
value: string
|
||||
) => void;
|
||||
onDatabasePropertyChange?: (
|
||||
row: DatabaseRow,
|
||||
cell: DatabaseValueCell,
|
||||
@@ -106,12 +111,17 @@ interface DocPropertyRowProps {
|
||||
showAll?: boolean;
|
||||
defaultOpenEditMenu?: boolean;
|
||||
onChange?: (value: unknown) => void;
|
||||
onPropertyInfoChange?: (
|
||||
field: keyof DocCustomPropertyInfo,
|
||||
value: string
|
||||
) => void;
|
||||
}
|
||||
|
||||
export const DocPropertyRow = ({
|
||||
propertyInfo,
|
||||
defaultOpenEditMenu,
|
||||
onChange,
|
||||
onPropertyInfoChange,
|
||||
}: DocPropertyRowProps) => {
|
||||
const t = useI18n();
|
||||
const docService = useService(DocService);
|
||||
@@ -213,7 +223,12 @@ export const DocPropertyRow = ({
|
||||
propertyInfo.name ||
|
||||
(typeInfo?.name ? t.t(typeInfo.name) : t['unnamed']())
|
||||
}
|
||||
menuItems={<EditDocPropertyMenuItems propertyId={propertyInfo.id} />}
|
||||
menuItems={
|
||||
<EditDocPropertyMenuItems
|
||||
propertyId={propertyInfo.id}
|
||||
onPropertyInfoChange={onPropertyInfoChange}
|
||||
/>
|
||||
}
|
||||
data-testid="doc-property-name"
|
||||
/>
|
||||
<ValueRenderer
|
||||
@@ -231,6 +246,11 @@ interface DocWorkspacePropertiesTableBodyProps {
|
||||
defaultOpen?: boolean;
|
||||
onChange?: (property: DocCustomPropertyInfo, value: unknown) => void;
|
||||
onPropertyAdded?: (property: DocCustomPropertyInfo) => void;
|
||||
onPropertyInfoChange?: (
|
||||
property: DocCustomPropertyInfo,
|
||||
field: keyof DocCustomPropertyInfo,
|
||||
value: string
|
||||
) => void;
|
||||
}
|
||||
|
||||
// 🏷️ Tags (⋅ xxx) (⋅ yyy)
|
||||
@@ -241,7 +261,15 @@ const DocWorkspacePropertiesTableBody = forwardRef<
|
||||
DocWorkspacePropertiesTableBodyProps
|
||||
>(
|
||||
(
|
||||
{ className, style, defaultOpen, onChange, onPropertyAdded, ...props },
|
||||
{
|
||||
className,
|
||||
style,
|
||||
defaultOpen,
|
||||
onChange,
|
||||
onPropertyAdded,
|
||||
onPropertyInfoChange,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const t = useI18n();
|
||||
@@ -304,6 +332,9 @@ const DocWorkspacePropertiesTableBody = forwardRef<
|
||||
propertyInfo={property}
|
||||
defaultOpenEditMenu={newPropertyId === property.id}
|
||||
onChange={value => onChange?.(property, value)}
|
||||
onPropertyInfoChange={(...args) =>
|
||||
onPropertyInfoChange?.(property, ...args)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
<div className={styles.actionContainer}>
|
||||
@@ -357,6 +388,7 @@ const DocPropertiesTableInner = ({
|
||||
defaultOpenProperty,
|
||||
onPropertyAdded,
|
||||
onPropertyChange,
|
||||
onPropertyInfoChange,
|
||||
onDatabasePropertyChange,
|
||||
className,
|
||||
}: DocPropertiesTableProps) => {
|
||||
@@ -376,6 +408,7 @@ const DocPropertiesTableInner = ({
|
||||
}
|
||||
onPropertyAdded={onPropertyAdded}
|
||||
onChange={onPropertyChange}
|
||||
onPropertyInfoChange={onPropertyInfoChange}
|
||||
/>
|
||||
<div className={styles.tableHeaderDivider} />
|
||||
<DocDatabaseBacklinkInfo
|
||||
|
||||
@@ -89,6 +89,20 @@ export const InfoTable = ({
|
||||
[]
|
||||
);
|
||||
|
||||
const onPropertyInfoChange = useCallback(
|
||||
(
|
||||
property: DocCustomPropertyInfo,
|
||||
field: keyof DocCustomPropertyInfo,
|
||||
_value: string
|
||||
) => {
|
||||
track.$.docInfoPanel.property.editPropertyMeta({
|
||||
type: property.type,
|
||||
field,
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<PropertyCollapsibleSection
|
||||
@@ -120,6 +134,9 @@ export const InfoTable = ({
|
||||
propertyInfo={property}
|
||||
defaultOpenEditMenu={newPropertyId === property.id}
|
||||
onChange={value => onPropertyChange(property, value)}
|
||||
onPropertyInfoChange={(...args) =>
|
||||
onPropertyInfoChange(property, ...args)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
<Menu
|
||||
|
||||
@@ -23,6 +23,16 @@ const WorkspaceSettingPropertiesMain = () => {
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onPropertyInfoChange = useCallback(
|
||||
(property: DocCustomPropertyInfo, field: string) => {
|
||||
track.$.settingsPanel.workspace.editPropertyMeta({
|
||||
type: property.type,
|
||||
field,
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.main}>
|
||||
<div className={styles.listHeader}>
|
||||
@@ -32,7 +42,7 @@ const WorkspaceSettingPropertiesMain = () => {
|
||||
</Button>
|
||||
</Menu>
|
||||
</div>
|
||||
<DocPropertyManager />
|
||||
<DocPropertyManager onPropertyInfoChange={onPropertyInfoChange} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -48,6 +48,7 @@ type DocEvents =
|
||||
| 'copyBlockToLink'
|
||||
| 'bookmark'
|
||||
| 'editProperty'
|
||||
| 'editPropertyMeta'
|
||||
| 'addProperty';
|
||||
type EditorEvents = 'bold' | 'italic' | 'underline' | 'strikeThrough';
|
||||
// END SECTION
|
||||
@@ -168,12 +169,12 @@ const PageEvents = {
|
||||
},
|
||||
docInfoPanel: {
|
||||
$: ['open'],
|
||||
property: ['editProperty', 'addProperty'],
|
||||
property: ['editProperty', 'addProperty', 'editPropertyMeta'],
|
||||
databaseProperty: ['editProperty'],
|
||||
},
|
||||
settingsPanel: {
|
||||
menu: ['openSettings'],
|
||||
workspace: ['viewPlans', 'export', 'addProperty'],
|
||||
workspace: ['viewPlans', 'export', 'addProperty', 'editPropertyMeta'],
|
||||
profileAndBadge: ['viewPlans'],
|
||||
accountUsage: ['viewPlans'],
|
||||
accountSettings: ['uploadAvatar', 'removeAvatar', 'updateUserName'],
|
||||
@@ -316,11 +317,11 @@ const PageEvents = {
|
||||
},
|
||||
inlineDocInfo: {
|
||||
$: ['toggle'],
|
||||
property: ['editProperty', 'addProperty'],
|
||||
property: ['editProperty', 'editPropertyMeta', 'addProperty'],
|
||||
databaseProperty: ['editProperty'],
|
||||
},
|
||||
sidepanel: {
|
||||
property: ['addProperty'],
|
||||
property: ['addProperty', 'editPropertyMeta'],
|
||||
},
|
||||
biDirectionalLinksPanel: {
|
||||
$: ['toggle'],
|
||||
@@ -459,6 +460,7 @@ export type EventArgs = {
|
||||
type: string;
|
||||
};
|
||||
editProperty: { type: string };
|
||||
editPropertyMeta: { type: string; field: string };
|
||||
addProperty: { type: string; control: 'at menu' | 'property list' };
|
||||
linkDoc: { type: string; journal: boolean };
|
||||
drop: { type: string };
|
||||
|
||||
Reference in New Issue
Block a user