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.
This commit is contained in:
iliya 2026-03-03 01:12:28 +02:00
parent 59c5ee3836
commit 1100d8fa3d
5 changed files with 13 additions and 22 deletions

View file

@ -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<void>(TEAM_ADD_MEMBER, teamName, request);
},
replaceMembers: async (
teamName: string,
request: import('@shared/types').ReplaceMembersRequest
) => {
replaceMembers: async (teamName: string, request: ReplaceMembersRequest) => {
return invokeIpcWithResult<void>(TEAM_REPLACE_MEMBERS, teamName, request);
},
removeMember: async (teamName: string, memberName: string) => {

View file

@ -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';

View file

@ -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]

View file

@ -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)));
};

View file

@ -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',