From 9030ca511e13692a8d81b4c7673664fafb7ddb9a Mon Sep 17 00:00:00 2001 From: JimmFly <447268514@qq.com> Date: Tue, 19 Mar 2024 08:39:15 +0000 Subject: [PATCH] refactor(core): refactor tag to use di (#6079) use case ``` const tagService = useService(TagService); const tags = useLiveData(tagService.tags); const currentTagLiveData = tagService.tagByTagId(tagId); const currentTag = useLiveData(currentTagLiveData); ``` --- packages/common/env/src/filter.ts | 4 + .../affine/page-properties/common.ts | 2 +- .../property-row-value-renderer.tsx | 17 +- .../page-properties/tags-inline-editor.tsx | 179 +++++++----------- .../page-list/docs/page-list-header.tsx | 79 ++++---- .../page-list/docs/page-list-item.tsx | 10 +- .../components/page-list/docs/page-tags.tsx | 85 +++++++-- .../page-list/docs/virtualized-page-list.tsx | 3 +- .../core/src/components/page-list/index.tsx | 1 - .../components/page-list/tags/create-tag.tsx | 87 ++++----- .../page-list/tags/tag-list-item.tsx | 4 +- .../page-list/tags/virtualized-tag-list.tsx | 2 +- .../core/src/components/page-list/types.ts | 12 +- .../src/components/page-list/use-tag-metas.ts | 71 ------- .../core/src/components/page-list/utils.tsx | 17 -- .../frontend/core/src/modules/services.ts | 5 +- .../core/src/modules/tag/entities/tag.ts | 71 +++++++ .../core/src/modules/tag/entities/utils.ts | 16 ++ .../frontend/core/src/modules/tag/index.ts | 3 + .../core/src/modules/tag/service/tag.ts | 85 +++++++++ .../workspace/properties/legacy-properties.ts | 3 +- .../src/pages/workspace/all-tag/index.tsx | 24 ++- .../core/src/pages/workspace/tag/index.tsx | 40 ++-- .../src/stories/page-list.stories.tsx | 3 +- 24 files changed, 468 insertions(+), 355 deletions(-) delete mode 100644 packages/frontend/core/src/components/page-list/use-tag-metas.ts create mode 100644 packages/frontend/core/src/modules/tag/entities/tag.ts create mode 100644 packages/frontend/core/src/modules/tag/entities/utils.ts create mode 100644 packages/frontend/core/src/modules/tag/index.ts create mode 100644 packages/frontend/core/src/modules/tag/service/tag.ts diff --git a/packages/common/env/src/filter.ts b/packages/common/env/src/filter.ts index c0c1deb454..55c60bb6f9 100644 --- a/packages/common/env/src/filter.ts +++ b/packages/common/env/src/filter.ts @@ -53,6 +53,8 @@ export const collectionSchema = z.object({ name: z.string(), filterList: z.array(filterSchema), allowList: z.array(z.string()), + createDate: z.union([z.date(), z.number()]).optional(), + updateDate: z.union([z.date(), z.number()]).optional(), }); export const deletedCollectionSchema = z.object({ userId: z.string().optional(), @@ -78,6 +80,8 @@ export const tagSchema = z.object({ value: z.string(), color: z.string(), parentId: z.string().optional(), + createDate: z.union([z.date(), z.number()]).optional(), + updateDate: z.union([z.date(), z.number()]).optional(), }); export type Tag = z.input; diff --git a/packages/frontend/core/src/components/affine/page-properties/common.ts b/packages/frontend/core/src/components/affine/page-properties/common.ts index 466b4254e0..772b069d03 100644 --- a/packages/frontend/core/src/components/affine/page-properties/common.ts +++ b/packages/frontend/core/src/components/affine/page-properties/common.ts @@ -7,7 +7,7 @@ import type { PagePropertiesManager } from './page-properties-manager'; export const managerContext = createContext(); type TagColorHelper = T extends `paletteLine${infer Color}` ? Color : never; -type TagColorName = TagColorHelper[0]>; +export type TagColorName = TagColorHelper[0]>; const tagColorIds: TagColorName[] = [ 'Red', diff --git a/packages/frontend/core/src/components/affine/page-properties/property-row-value-renderer.tsx b/packages/frontend/core/src/components/affine/page-properties/property-row-value-renderer.tsx index 42c15248e5..dac2faab4b 100644 --- a/packages/frontend/core/src/components/affine/page-properties/property-row-value-renderer.tsx +++ b/packages/frontend/core/src/components/affine/page-properties/property-row-value-renderer.tsx @@ -1,6 +1,5 @@ import { Checkbox, DatePicker, Menu } from '@affine/component'; import { useAllBlockSuiteDocMeta } from '@affine/core/hooks/use-all-block-suite-page-meta'; -import { WorkspaceLegacyProperties } from '@affine/core/modules/workspace'; import type { PageInfoCustomProperty, PageInfoCustomPropertyMeta, @@ -9,7 +8,7 @@ import type { import { timestampToLocalDate } from '@affine/core/utils'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { assertExists } from '@blocksuite/global/utils'; -import { Doc, useLiveData, useService, Workspace } from '@toeverything/infra'; +import { Doc, useService, Workspace } from '@toeverything/infra'; import { noop } from 'lodash-es'; import { type ChangeEventHandler, @@ -179,29 +178,17 @@ export const TagsValue = () => { const page = useService(Doc); const docCollection = workspace.docCollection; const pageMetas = useAllBlockSuiteDocMeta(docCollection); - const legacyProperties = useService(WorkspaceLegacyProperties); - const options = useLiveData(legacyProperties.tagOptions$); const pageMeta = pageMetas.find(x => x.id === page.id); assertExists(pageMeta, 'pageMeta should exist'); - const tagIds = pageMeta.tags; const t = useAFFiNEI18N(); - const onChange = useCallback( - (tags: string[]) => { - legacyProperties.updatePageTags(page.id, tags); - }, - [legacyProperties, page.id] - ); return ( ); }; diff --git a/packages/frontend/core/src/components/affine/page-properties/tags-inline-editor.tsx b/packages/frontend/core/src/components/affine/page-properties/tags-inline-editor.tsx index 19d84cad91..eb45cd670f 100644 --- a/packages/frontend/core/src/components/affine/page-properties/tags-inline-editor.tsx +++ b/packages/frontend/core/src/components/affine/page-properties/tags-inline-editor.tsx @@ -6,13 +6,13 @@ import { Scrollable, } from '@affine/component'; import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper'; +import { TagService } from '@affine/core/modules/tag'; import { WorkspaceLegacyProperties } from '@affine/core/modules/workspace'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { DeleteIcon, MoreHorizontalIcon, TagsIcon } from '@blocksuite/icons'; -import type { Tag } from '@blocksuite/store'; +import { useLiveData } from '@toeverything/infra'; import { useService } from '@toeverything/infra/di'; import clsx from 'clsx'; -import { nanoid } from 'nanoid'; import { type HTMLAttributes, type PropsWithChildren, @@ -22,16 +22,13 @@ import { useState, } from 'react'; -import { TagItem } from '../../page-list'; +import { TagItem, TempTagItem } from '../../page-list'; import { tagColors } from './common'; import { type MenuItemOption, renderMenuItemOptions } from './menu-items'; import * as styles from './tags-inline-editor.css'; interface TagsEditorProps { - value: string[]; // selected tag ids - onChange?: (value: string[]) => void; - options: Tag[]; - onOptionsChange?: (options: Tag[]) => void; // adding/updating/removing tags + pageId: string; readonly?: boolean; } @@ -40,25 +37,26 @@ interface InlineTagsListProps Omit {} const InlineTagsList = ({ - value, - onChange, - options, + pageId, readonly, children, }: PropsWithChildren) => { + const tagService = useService(TagService); + const tags = useLiveData(tagService.tags); + const tagIds = useLiveData(tagService.tagIdsByPageId(pageId)); + return (
- {value.map((tagId, idx) => { - const tag = options.find(t => t.id === tagId); + {tagIds.map((tagId, idx) => { + const tag = tags.find(t => t.id === tagId); if (!tag) { return null; } - const onRemoved = - readonly || !onChange - ? undefined - : () => { - onChange(value.filter(v => v !== tagId)); - }; + const onRemoved = readonly + ? undefined + : () => { + tag.untag(pageId); + }; return ( { - const trimmedValue = inputValue?.trim().toLowerCase() ?? ''; - const trimmedOptionValue = option.value.trim().toLowerCase(); - return trimmedOptionValue.includes(trimmedValue); -}; - export const EditTagMenu = ({ - tag, + tagId, children, -}: PropsWithChildren<{ tag: Tag }>) => { +}: PropsWithChildren<{ tagId: string }>) => { const t = useAFFiNEI18N(); const legacyProperties = useService(WorkspaceLegacyProperties); + const tagService = useService(TagService); + const tag = useLiveData(tagService.tagByTagId(tagId)); + const tagColor = useLiveData(tag?.color); + const tagValue = useLiveData(tag?.value); const navigate = useNavigateHelper(); const menuProps = useMemo(() => { @@ -94,14 +90,11 @@ export const EditTagMenu = ({ if (name.trim() === '') { return; } - legacyProperties.updateTagOption(tag.id, { - ...tag, - value: name, - }); + tag?.rename(name); }; options.push( { updateTagName(e.currentTarget.value); }} @@ -123,7 +116,7 @@ export const EditTagMenu = ({ icon: , type: 'danger', onClick() { - legacyProperties.removeTagOption(tag.id); + tagService.deleteTag(tag?.id || ''); }, }); @@ -131,7 +124,7 @@ export const EditTagMenu = ({ text: t['com.affine.page-properties.tags.open-tags-page'](), icon: , onClick() { - navigate.jumpToTag(legacyProperties.workspaceId, tag.id); + navigate.jumpToTag(legacyProperties.workspaceId, tag?.id || ''); }, }); @@ -151,12 +144,9 @@ export const EditTagMenu = ({ />
), - checked: tag.color === color, + checked: tagColor === color, onClick() { - legacyProperties.updateTagOption(tag.id, { - ...tag, - color, - }); + tag?.changeColor(color); }, }; }) @@ -171,26 +161,35 @@ export const EditTagMenu = ({ }, items, } satisfies Partial; - }, [legacyProperties, navigate, t, tag]); + }, [ + legacyProperties.workspaceId, + navigate, + t, + tag, + tagColor, + tagService, + tagValue, + ]); return {children}; }; -export const TagsEditor = ({ - options, - value, - onChange, - onOptionsChange, - readonly, -}: TagsEditorProps) => { +export const TagsEditor = ({ pageId, readonly }: TagsEditorProps) => { const t = useAFFiNEI18N(); + const tagService = useService(TagService); + const tags = useLiveData(tagService.tags); + const tagIds = useLiveData(tagService.tagIdsByPageId(pageId)); const [inputValue, setInputValue] = useState(''); - const exactMatch = options.find(o => o.value === inputValue); - const filteredOptions = useMemo( - () => - options.filter(o => (inputValue ? filterOption(o, inputValue) : true)), - [inputValue, options] - ); + + const exactMatch = useLiveData(tagService.tagByTagValue(inputValue)); + + const filteredLiveData = useMemo(() => { + if (inputValue) { + return tagService.filterTagsByName(inputValue); + } + return tagService.tags; + }, [inputValue, tagService]); + const filteredTags = useLiveData(filteredLiveData); const onInputChange = useCallback( (e: React.ChangeEvent) => { @@ -201,11 +200,11 @@ export const TagsEditor = ({ const onAddTag = useCallback( (id: string) => { - if (!value.includes(id)) { - onChange?.([...value, id]); + if (!tagIds.includes(id)) { + tags.find(o => o.id === id)?.tag(pageId); } }, - [onChange, value] + [pageId, tagIds, tags] ); const [nextColor, rotateNextColor] = useReducer( @@ -221,17 +220,11 @@ export const TagsEditor = ({ if (!name.trim()) { return; } - - const newTag = { - id: nanoid(), - value: name.trim(), - color: nextColor, - }; rotateNextColor(); - onOptionsChange?.([...options, newTag]); - onChange?.([...value, newTag.id]); + const newTag = tagService.createTag(name.trim(), nextColor); + newTag.tag(pageId); }, - [nextColor, onChange, onOptionsChange, options, value] + [nextColor, pageId, tagService] ); const onInputKeyDown = useCallback( @@ -243,22 +236,18 @@ export const TagsEditor = ({ onCreateTag(inputValue); } setInputValue(''); - } else if (e.key === 'Backspace' && inputValue === '' && value.length) { - onChange?.(value.slice(0, value.length - 1)); + } else if (e.key === 'Backspace' && inputValue === '' && tagIds.length) { + const lastTagId = tagIds[tagIds.length - 1]; + tags.find(tag => tag.id === lastTagId)?.untag(pageId); } }, - [exactMatch, inputValue, onAddTag, onChange, onCreateTag, value] + [exactMatch, inputValue, onAddTag, onCreateTag, pageId, tagIds, tags] ); return (
- + - {filteredOptions.map(tag => { + {filteredTags.map(tag => { return (
- + {t['Create']()}{' '} - +
)} @@ -337,15 +318,14 @@ interface TagsInlineEditorProps extends TagsEditorProps { // this tags value renderer right now only renders the legacy tags for now export const TagsInlineEditor = ({ - value, - onChange, - options, - onOptionsChange, + pageId, readonly, placeholder, className, }: TagsInlineEditorProps) => { - const empty = !value || value.length === 0; + const tagService = useService(TagService); + const tagIds = useLiveData(tagService.tagIdsByPageId(pageId)); + const empty = !tagIds || tagIds.length === 0; return ( - } + items={} >
- {empty ? ( - placeholder - ) : ( - - )} + {empty ? placeholder : }
); diff --git a/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx b/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx index 363fdd8cb9..d44771f357 100644 --- a/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx +++ b/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx @@ -1,8 +1,8 @@ import { Button, Divider, Menu, Scrollable } from '@affine/component'; import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper'; -import { WorkspaceLegacyProperties } from '@affine/core/modules/workspace'; -import type { Collection, Tag } from '@affine/env/filter'; +import { type Tag, TagService } from '@affine/core/modules/tag'; +import type { Collection } from '@affine/env/filter'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { ArrowDownSmallIcon, @@ -18,7 +18,6 @@ import { Link } from 'react-router-dom'; import { CollectionService } from '../../../modules/collection'; import { createTagFilter } from '../filter/utils'; import { createEmptyCollection } from '../use-collection-manager'; -import { tagColorMap } from '../utils'; import type { AllPageListConfig } from '../view/edit-collection/edit-collection'; import { useEditCollection, @@ -95,8 +94,9 @@ export const TagPageListHeader = ({ tag: Tag; workspaceId: string; }) => { - const legacyProperties = useService(WorkspaceLegacyProperties); - const options = useLiveData(legacyProperties.tagOptions$); + const tagColor = useLiveData(tag.color); + const tagTitle = useLiveData(tag.value); + const t = useAFFiNEI18N(); const { jumpToTags, jumpToCollection } = useNavigateHelper(); const collectionService = useService(CollectionService); @@ -153,16 +153,16 @@ export const TagPageListHeader = ({ avoidCollisions: false, className: styles.tagsMenu, }} - items={} + items={} >
-
{tag.value}
+
{tagTitle}
@@ -175,25 +175,21 @@ export const TagPageListHeader = ({ ); }; -const filterOption = (option: Tag, inputValue?: string) => { - const trimmedValue = inputValue?.trim().toLowerCase() ?? ''; - const trimmedOptionValue = option.value.trim().toLowerCase(); - return trimmedOptionValue.includes(trimmedValue); -}; - -interface TagsEditorProps { - options: Tag[]; +interface SwitchTagProps { onClick: (open: boolean) => void; } -export const TagsEditor = ({ options, onClick }: TagsEditorProps) => { +export const SwitchTag = ({ onClick }: SwitchTagProps) => { const t = useAFFiNEI18N(); const [inputValue, setInputValue] = useState(''); - const filteredOptions = useMemo( - () => - options.filter(o => (inputValue ? filterOption(o, inputValue) : true)), - [inputValue, options] - ); + const tagService = useService(TagService); + const filteredLiveData = useMemo(() => { + if (inputValue) { + return tagService.filterTagsByName(inputValue); + } + return tagService.tags; + }, [inputValue, tagService]); + const filteredTags = useLiveData(filteredLiveData); const onInputChange = useCallback( (e: React.ChangeEvent) => { @@ -225,25 +221,10 @@ export const TagsEditor = ({ options, onClick }: TagsEditorProps) => { - {filteredOptions.map(tag => { - return ( - -
-
{tag.value}
- - ); + {filteredTags.map(tag => { + return ; })} - {filteredOptions.length === 0 ? ( + {filteredTags.length === 0 ? (
{t['Find 0 result']()}
@@ -255,3 +236,21 @@ export const TagsEditor = ({ options, onClick }: TagsEditorProps) => {
); }; + +const TagLink = ({ tag, onClick }: { tag: Tag; onClick: () => void }) => { + const tagColor = useLiveData(tag.color); + const tagTitle = useLiveData(tag.value); + return ( + +
+
{tagTitle}
+ + ); +}; diff --git a/packages/frontend/core/src/components/page-list/docs/page-list-item.tsx b/packages/frontend/core/src/components/page-list/docs/page-list-item.tsx index 3e8ed841d4..a366630d81 100644 --- a/packages/frontend/core/src/components/page-list/docs/page-list-item.tsx +++ b/packages/frontend/core/src/components/page-list/docs/page-list-item.tsx @@ -1,5 +1,7 @@ import { Checkbox } from '@affine/component'; +import { TagService } from '@affine/core/modules/tag'; import { useDraggable } from '@dnd-kit/core'; +import { useLiveData, useService } from '@toeverything/infra'; import { type PropsWithChildren, useCallback, useMemo } from 'react'; import { WorkbenchLink } from '../../../modules/workbench/view/workbench-link'; @@ -65,7 +67,11 @@ const PageSelectionCell = ({ ); }; -export const PageTagsCell = ({ tags }: Pick) => { +export const PageTagsCell = ({ pageId }: Pick) => { + const tagsService = useService(TagService); + const tagsLiveData = tagsService.tagsByPageId(pageId); + const tags = useLiveData(tagsLiveData); + return (
{ - + diff --git a/packages/frontend/core/src/components/page-list/docs/page-tags.tsx b/packages/frontend/core/src/components/page-list/docs/page-tags.tsx index 20504f4baf..550c2ac5aa 100644 --- a/packages/frontend/core/src/components/page-list/docs/page-tags.tsx +++ b/packages/frontend/core/src/components/page-list/docs/page-tags.tsx @@ -1,11 +1,12 @@ import { Menu } from '@affine/component'; -import type { Tag } from '@affine/env/filter'; +import { type Tag } from '@affine/core/modules/tag'; import { CloseIcon, MoreHorizontalIcon } from '@blocksuite/icons'; +import { LiveData, useLiveData } from '@toeverything/infra'; import { assignInlineVars } from '@vanilla-extract/dynamic'; import clsx from 'clsx'; import { type MouseEventHandler, useCallback, useMemo } from 'react'; -import { stopPropagation, tagColorMap } from '../utils'; +import { stopPropagation } from '../utils'; import * as styles from './page-tags.css'; export interface PageTagsProps { @@ -16,7 +17,7 @@ export interface PageTagsProps { } interface TagItemProps { - tag: Tag; + tag?: Tag; idx?: number; maxWidth?: number | string; mode: 'inline' | 'list-item'; @@ -24,6 +25,30 @@ interface TagItemProps { style?: React.CSSProperties; } +export const TempTagItem = ({ + value, + color, + maxWidth = '100%', +}: { + value: string; + color: string; + maxWidth?: number | string; +}) => { + return ( +
+
+
+
{value}
+
+
+ ); +}; + export const TagItem = ({ tag, idx, @@ -32,6 +57,8 @@ export const TagItem = ({ style, maxWidth, }: TagItemProps) => { + const value = useLiveData(tag?.value); + const color = useLiveData(tag?.color); const handleRemove: MouseEventHandler = useCallback( e => { e.stopPropagation(); @@ -44,9 +71,9 @@ export const TagItem = ({ data-testid="page-tag" className={styles.tag} data-idx={idx} - data-tag-id={tag.id} - data-tag-value={tag.value} - title={tag.value} + data-tag-id={tag?.id} + data-tag-value={value} + title={value} style={style} >
-
{tag.value}
+
{value}
{onRemoved ? (
{ + const nTags = useMemo(() => { + return maxItems ? tags.slice(0, maxItems) : tags; + }, [maxItems, tags]); + + const tagsOrderedLiveData = useMemo(() => { + return LiveData.computed(get => + [...nTags].sort((a, b) => get(a.value).length - get(b.value).length) + ); + }, [nTags]); + + const tagsOrdered = useLiveData(tagsOrderedLiveData); + + return useMemo( + () => + tagsOrdered.map((tag, idx) => ( + + )), + [tagsOrdered] + ); +}; + export const PageTags = ({ tags, widthOnHover, @@ -97,16 +152,6 @@ export const PageTags = ({ ); }, [maxItems, tags]); - const tagsNormal = useMemo(() => { - const nTags = maxItems ? tags.slice(0, maxItems) : tags; - - // sort tags by length - nTags.sort((a, b) => a.value.length - b.value.length); - - return nTags.map((tag, idx) => ( - - )); - }, [maxItems, tags]); return (
-
{tagsNormal}
+
+ +
{maxItems && tags.length > maxItems ? ( ( const randomTagColor = () => { const randomIndex = Math.floor(Math.random() * tagColors.length); - return tagColors[randomIndex]; + return tagColors[randomIndex][1]; }; export const CreateOrEditTag = ({ @@ -33,39 +32,44 @@ export const CreateOrEditTag = ({ onOpenChange: (open: boolean) => void; tagMeta?: TagMeta; }) => { - const legacyProperties = useService(WorkspaceLegacyProperties); - const tagOptions = useLiveData(legacyProperties.tagOptions$); + const tagService = useService(TagService); + const tagOptions = useLiveData(tagService.tagMetas); + const tag = useLiveData(tagService.tagByTagId(tagMeta?.id)); const t = useAFFiNEI18N(); const [menuOpen, setMenuOpen] = useState(false); - const [tagName, setTagName] = useState(tagMeta?.title || ''); - const [activeTagIcon, setActiveTagIcon] = useState(() => { - return ( - tagColors.find(([_, color]) => color === tagMeta?.color) || - randomTagColor() - ); - }); + + const [tagName, setTagName] = useState(tagMeta?.title); + const handleChangeName = useCallback((value: string) => { + setTagName(value); + }, []); + + const [tagIcon, setTagIcon] = useState(tagMeta?.color || randomTagColor()); + + const handleChangeIcon = useCallback((value: string) => { + setTagIcon(value); + }, []); const tags = useMemo(() => { - return tagColors.map(([name, color]) => { + return tagColors.map(([_, color]) => { return { name: name, color: color, onClick: () => { - setActiveTagIcon([name, color]); + handleChangeIcon(color); setMenuOpen(false); }, }; }); - }, []); + }, [handleChangeIcon]); const items = useMemo(() => { const tagItems = tags.map(item => { return (
@@ -73,52 +77,38 @@ export const CreateOrEditTag = ({ ); }); return
{tagItems}
; - }, [activeTagIcon, tags]); + }, [tagIcon, tags]); const onClose = useCallback(() => { if (!tagMeta) { - setActiveTagIcon(randomTagColor); + handleChangeIcon(randomTagColor()); setTagName(''); } onOpenChange(false); - }, [onOpenChange, tagMeta]); + }, [handleChangeIcon, onOpenChange, tagMeta]); const onConfirm = useCallback(() => { - if (!tagName.trim()) return; - if (tagOptions.some(tag => tag.value === tagName.trim()) && !tagMeta) { + if (!tagName?.trim()) return; + if ( + tagOptions.some( + tag => tag.title === tagName.trim() && tag.id !== tagMeta?.id + ) + ) { return toast(t['com.affine.tags.create-tag.toast.exist']()); } if (!tagMeta) { - const newTag = { - id: nanoid(), - value: tagName.trim(), - color: activeTagIcon[1] || tagColors[0][1], - }; - - legacyProperties.updateTagOptions([...tagOptions, newTag]); + tagService.createTag(tagName.trim(), tagIcon); toast(t['com.affine.tags.create-tag.toast.success']()); onClose(); return; } + tag?.rename(tagName.trim()); + tag?.changeColor(tagIcon); - const updatedTag = { - id: tagMeta.id, - value: tagName.trim(), - color: activeTagIcon[1] || tagColors[0][1], - }; - legacyProperties.updateTagOption(tagMeta.id, updatedTag); toast(t['com.affine.tags.edit-tag.toast.success']()); onClose(); return; - }, [ - activeTagIcon, - legacyProperties, - onClose, - t, - tagMeta, - tagName, - tagOptions, - ]); + }, [onClose, t, tag, tagIcon, tagMeta, tagName, tagOptions, tagService]); useEffect(() => { if (!open) return; @@ -137,6 +127,11 @@ export const CreateOrEditTag = ({ }; }, [open, onOpenChange, menuOpen, onClose]); + useEffect(() => { + setTagName(tagMeta?.title); + setTagIcon(tagMeta?.color || randomTagColor()); + }, [tagMeta?.color, tagMeta?.title]); + return (
@@ -156,7 +151,7 @@ export const CreateOrEditTag = ({ inputStyle={{ fontSize: 'var(--affine-font-xs)' }} onEnter={onConfirm} value={tagName} - onChange={setTagName} + onChange={handleChangeName} />