agent-ecosystem/src/renderer/components/chat/items/TextItem.tsx
iliya 2ceed41e00 fix: resolve all CI lint errors and flaky test
- Fix React hooks violations: ref updates during render (useDraftPersistence,
  useChipDraftPersistence, useAttachments), setState in effects across 15+
  components, useCallback self-reference TDZ in useResizableColumns
- Fix TypeScript lint: remove unnecessary type assertions, replace inline
  import() annotations with direct imports, remove unused variables/imports
- Fix SonarJS issues: prefer-regexp-exec, slow-regex in SubagentResolver,
  no-misleading-array-reverse in TeamProvisioningService, use-type-alias
  in ClaudeLogsSection, variable shadowing in ChangeExtractorService
- Fix accessibility: associate labels with controls in filter popovers
- Fix template expression safety: wrap unknown errors with String()
- Fix flaky FileWatcher test: floor instanceCreatedAt to second granularity
  to match filesystem birthtimeMs resolution on Linux
- Replace TODO comments with NOTE where features are intentionally disabled
- Remove unused leadContextByTeam from TeamDetailView store selector

62 files changed across main process, renderer, shared types, and hooks.
All 1646 tests pass, typecheck clean, 0 lint errors.
2026-03-05 21:09:45 +02:00

79 lines
2.2 KiB
TypeScript

import React from 'react';
import { MessageSquare } from 'lucide-react';
import { highlightQueryInText } from '../searchHighlightUtils';
import { MarkdownViewer } from '../viewers';
import { BaseItem } from './BaseItem';
import { truncateText } from './baseItemHelpers';
import type { SemanticStep } from '@renderer/types/data';
import type { TriggerColor } from '@shared/constants/triggerColors';
interface TextItemProps {
step: SemanticStep;
preview: string;
onClick: () => void;
isExpanded: boolean;
/** Optional local search query for inline highlighting */
searchQueryOverride?: string;
/** Optional stable item id for search highlighting */
markdownItemId?: string;
/** Additional classes for highlighting (e.g., error deep linking) */
highlightClasses?: string;
/** Inline styles for highlighting (used by custom hex colors) */
highlightStyle?: React.CSSProperties;
/** Notification dot color for custom triggers */
notificationDotColor?: TriggerColor;
}
export const TextItem: React.FC<TextItemProps> = ({
step,
preview,
onClick,
isExpanded,
searchQueryOverride,
markdownItemId,
highlightClasses,
highlightStyle,
notificationDotColor,
}) => {
const fullContent = step.content.outputText ?? preview;
const truncatedPreview = truncateText(preview, 60);
const summary = searchQueryOverride
? highlightQueryInText(
truncatedPreview,
searchQueryOverride,
`${markdownItemId ?? step.id}:summary`,
{
forceAllActive: true,
}
)
: truncatedPreview;
// Get token count from step.tokens.output or step.content.tokenCount
const tokenCount = step.tokens?.output ?? step.content.tokenCount ?? 0;
return (
<BaseItem
icon={<MessageSquare className="size-4" />}
label="Output"
summary={summary}
tokenCount={tokenCount}
onClick={onClick}
isExpanded={isExpanded}
highlightClasses={highlightClasses}
highlightStyle={highlightStyle}
notificationDotColor={notificationDotColor}
>
<MarkdownViewer
content={fullContent}
maxHeight="max-h-96"
copyable
itemId={markdownItemId}
searchQueryOverride={searchQueryOverride}
/>
</BaseItem>
);
};