import React, { useMemo, useState } from 'react';
import { Text, View } from 'react-native';
import { Database } from 'lucide-react-native';
import { useAgentBi } from '../../analytics/mixpanelContext';
import type { SuperagentToolRendererProps } from '../../types';
import {
getEntityName,
getEntitySummary,
getRecordArg,
PREVIOUS_APPROVAL_NOTE,
toKeyValueItems,
} from '../entityWidgetUtils';
import { ApprovalCard } from '../primitives/ApprovalCard';
import { ExpandableSection } from '../primitives/ExpandableSection';
import { KeyValueList } from '../primitives/KeyValueList';
import { ToolWidgetRow } from '../primitives/ToolWidgetRow';
import { toolWidgetStyles } from '../primitives/toolWidgetStyles';
import { getWidgetStatus, isActionableTurn, parseToolArgs } from '../toolWidgetUtils';
import { useApprovalSubmit } from '../useApprovalSubmit';
const COPY = {
delete_entities: { active: 'Deleting', base: 'Delete', done: 'Deleted' },
update_entities: { active: 'Updating', base: 'Update', done: 'Updated' },
} as const;
// update_entities — native port of the web UpdateEntities card.
export function UpdateEntitiesWidget(props: SuperagentToolRendererProps) {
return ;
}
// delete_entities — native port of the web DeleteEntities card.
export function DeleteEntitiesWidget(props: SuperagentToolRendererProps) {
return ;
}
function EntityWriteWidget({
isLastAssistantMessage,
submitToolCallInput,
toolCall,
toolName,
}: SuperagentToolRendererProps & { toolName: keyof typeof COPY }) {
const args = useMemo(() => parseToolArgs(toolCall), [toolCall]);
const status = getWidgetStatus(toolCall.status);
const [expanded, setExpanded] = useState(false);
const hasDetails = hasEntityWriteDetails(toolName, args);
if (status === 'waiting') {
return (
);
}
const copy = COPY[toolName];
const title = status === 'running' ? copy.active : status === 'success' ? copy.done : copy.base;
const rejected = status === 'stopped' && Boolean(toolCall.requires_user_input);
return (
setExpanded((current) => !current) : undefined}
status={status}
title={title}
>
);
}
export function hasEntityWriteDetails(toolName: string, args: Record | null): boolean {
if (Object.keys(getRecordArg(args, 'query')).length > 0) return true;
return toolName === 'update_entities' && Object.keys(getRecordArg(args, 'data')).length > 0;
}
/** Query / "Update with" sections — the web EntityExpandableContent. */
export function EntityWriteDetails({
args,
toolName,
}: {
args: Record | null;
toolName: string;
}) {
const queryItems = toKeyValueItems(getRecordArg(args, 'query'));
const dataItems = toolName === 'update_entities' ? toKeyValueItems(getRecordArg(args, 'data')) : [];
return (
{queryItems.length > 0 ? (
Query:
) : null}
{dataItems.length > 0 ? (
Update with:
) : null}
);
}
/** Single pending update/delete — the web EntityApprovalCard path. */
function EntityApprovalSingleCard({
args,
isLastAssistantMessage,
submitToolCallInput,
toolCall,
toolName,
}: {
args: Record | null;
isLastAssistantMessage: SuperagentToolRendererProps['isLastAssistantMessage'];
submitToolCallInput: SuperagentToolRendererProps['submitToolCallInput'];
toolCall: SuperagentToolRendererProps['toolCall'];
toolName: string;
}) {
const { canAct, error, isSubmitting, submit } = useApprovalSubmit(toolCall, submitToolCallInput);
const bi = useAgentBi();
const summary = getEntitySummary(toolName, args);
// Stale turn (web EntityApprovalCard parity): keep the summary, drop the buttons.
const actionable = canAct && isActionableTurn(isLastAssistantMessage);
return (
{ if (await submit(true)) void bi.trackEditor('Entity Write Approval', { batch: false, decision: 'approved' }); } : undefined}
onReject={actionable ? async () => { if (await submit(false)) void bi.trackEditor('Entity Write Approval', { batch: false, decision: 'rejected' }); } : undefined}
rejectLabel="Reject"
title="Approval Required"
unavailableNote={isActionableTurn(isLastAssistantMessage) ? undefined : PREVIOUS_APPROVAL_NOTE}
>
{hasEntityWriteDetails(toolName, args) ? (
) : (
{summary}
)}
);
}