From 1100d8fa3dd94f7496bef915dcf3702dceeca3a6 Mon Sep 17 00:00:00 2001 From: iliya Date: Tue, 3 Mar 2026 01:12:28 +0200 Subject: [PATCH] refactor: streamline member handling and improve type usage - Updated the ReplaceMembersRequest import in preload to use a local type definition for consistency. - Refactored MemberDraftRow and MembersEditorSection components to utilize InlineChip type directly, enhancing type clarity. - Improved performance by using useMemo for workflow chips in MemberDraftRow, optimizing re-renders. - Adjusted the JSON text setting in MembersEditorSection to use queueMicrotask for better asynchronous handling. - Added TEAM_REPLACE_MEMBERS to IPC mock definitions for improved testing coverage. --- src/preload/index.ts | 6 ++---- .../components/team/dialogs/EditTeamDialog.tsx | 2 +- .../components/team/members/MemberDraftRow.tsx | 12 +++++------- .../team/members/MembersEditorSection.tsx | 14 ++++---------- test/main/ipc/teams.test.ts | 1 + 5 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/preload/index.ts b/src/preload/index.ts index 72ac0752..0bc646dc 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -174,6 +174,7 @@ import type { MemberLogSummary, NotificationTrigger, RejectResult, + ReplaceMembersRequest, SendMessageRequest, SendMessageResult, SessionsByIdsOptions, @@ -742,10 +743,7 @@ const electronAPI: ElectronAPI = { addMember: async (teamName: string, request: AddMemberRequest) => { return invokeIpcWithResult(TEAM_ADD_MEMBER, teamName, request); }, - replaceMembers: async ( - teamName: string, - request: import('@shared/types').ReplaceMembersRequest - ) => { + replaceMembers: async (teamName: string, request: ReplaceMembersRequest) => { return invokeIpcWithResult(TEAM_REPLACE_MEMBERS, teamName, request); }, removeMember: async (teamName: string, memberName: string) => { diff --git a/src/renderer/components/team/dialogs/EditTeamDialog.tsx b/src/renderer/components/team/dialogs/EditTeamDialog.tsx index dd2262ac..97459018 100644 --- a/src/renderer/components/team/dialogs/EditTeamDialog.tsx +++ b/src/renderer/components/team/dialogs/EditTeamDialog.tsx @@ -17,7 +17,7 @@ import { DialogTitle, } from '@renderer/components/ui/dialog'; import { getTeamColorSet } from '@renderer/constants/teamColors'; -import { CUSTOM_ROLE, NO_ROLE, PRESET_ROLES } from '@renderer/constants/teamRoles'; +import { CUSTOM_ROLE, PRESET_ROLES } from '@renderer/constants/teamRoles'; import { useFileListCacheWarmer } from '@renderer/hooks/useFileListCacheWarmer'; import { cn } from '@renderer/lib/utils'; import { Loader2 } from 'lucide-react'; diff --git a/src/renderer/components/team/members/MemberDraftRow.tsx b/src/renderer/components/team/members/MemberDraftRow.tsx index 91b2db4d..094019af 100644 --- a/src/renderer/components/team/members/MemberDraftRow.tsx +++ b/src/renderer/components/team/members/MemberDraftRow.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Button } from '@renderer/components/ui/button'; import { Input } from '@renderer/components/ui/input'; @@ -18,6 +18,7 @@ import { getMemberColor } from '@shared/constants/memberColors'; import { ChevronDown, ChevronRight } from 'lucide-react'; import type { MemberDraft } from './membersEditorTypes'; +import type { InlineChip } from '@renderer/types/inlineChip'; import type { MentionSuggestion } from '@renderer/types/mention'; interface MemberDraftRowProps { @@ -30,10 +31,7 @@ interface MemberDraftRowProps { onRemove: (id: string) => void; showWorkflow?: boolean; onWorkflowChange?: (id: string, workflow: string) => void; - onWorkflowChipsChange?: ( - id: string, - chips: import('@renderer/types/inlineChip').InlineChip[] - ) => void; + onWorkflowChipsChange?: (id: string, chips: InlineChip[]) => void; draftKeyPrefix?: string; projectPath?: string | null; mentionSuggestions?: MentionSuggestion[]; @@ -68,7 +66,7 @@ export const MemberDraftRow = ({ enabled: !!draftKey, }); - const chips = member.workflowChips ?? []; + const chips = useMemo(() => member.workflowChips ?? [], [member.workflowChips]); const handleWorkflowChange = useCallback( (v: string) => { @@ -83,7 +81,7 @@ export const MemberDraftRow = ({ ); const handleFileChipInsert = useCallback( - (chip: import('@renderer/types/inlineChip').InlineChip) => { + (chip: InlineChip) => { onWorkflowChipsChange?.(member.id, [...chips, chip]); }, [member.id, chips, onWorkflowChipsChange] diff --git a/src/renderer/components/team/members/MembersEditorSection.tsx b/src/renderer/components/team/members/MembersEditorSection.tsx index 9f7f9ab1..27e50f73 100644 --- a/src/renderer/components/team/members/MembersEditorSection.tsx +++ b/src/renderer/components/team/members/MembersEditorSection.tsx @@ -8,13 +8,10 @@ import { getMemberColor } from '@shared/constants/memberColors'; import { MembersJsonEditor } from '../dialogs/MembersJsonEditor'; import { MemberDraftRow } from './MemberDraftRow'; -import { - buildMembersFromDrafts, - createMemberDraft, - getWorkflowForExport, -} from './membersEditorUtils'; +import { createMemberDraft, getWorkflowForExport } from './membersEditorUtils'; import type { MemberDraft } from './membersEditorTypes'; +import type { InlineChip } from '@renderer/types/inlineChip'; import type { MentionSuggestion } from '@renderer/types/mention'; function membersToJsonText(drafts: MemberDraft[]): string { @@ -91,7 +88,7 @@ export const MembersEditorSection = ({ useEffect(() => { if (!jsonEditorOpen || jsonError !== null) return; - setJsonText(membersToJsonText(members)); + queueMicrotask(() => setJsonText(membersToJsonText(members))); }, [members, jsonEditorOpen, jsonError]); const handleJsonChange = (text: string): void => { @@ -132,10 +129,7 @@ export const MembersEditorSection = ({ onChange(members.map((c) => (c.id === memberId ? { ...c, workflow } : c))); }; - const updateMemberWorkflowChips = ( - memberId: string, - workflowChips: import('@renderer/types/inlineChip').InlineChip[] - ): void => { + const updateMemberWorkflowChips = (memberId: string, workflowChips: InlineChip[]): void => { onChange(members.map((c) => (c.id === memberId ? { ...c, workflowChips } : c))); }; diff --git a/test/main/ipc/teams.test.ts b/test/main/ipc/teams.test.ts index 3906797f..ef0a4da8 100644 --- a/test/main/ipc/teams.test.ts +++ b/test/main/ipc/teams.test.ts @@ -39,6 +39,7 @@ vi.mock('@preload/constants/ipcChannels', () => ({ TEAM_GET_ALL_TASKS: 'team:getAllTasks', TEAM_ADD_TASK_COMMENT: 'team:addTaskComment', TEAM_ADD_MEMBER: 'team:addMember', + TEAM_REPLACE_MEMBERS: 'team:replaceMembers', TEAM_REMOVE_MEMBER: 'team:removeMember', TEAM_UPDATE_MEMBER_ROLE: 'team:updateMemberRole', TEAM_GET_PROJECT_BRANCH: 'team:getProjectBranch',