feat(workbench): redesign investigation reports and diagrams
This commit is contained in:
@@ -19,6 +19,8 @@ import type {
|
||||
} from "../types";
|
||||
import { createConditionConversationPrompt } from "../utils/scheduled-condition-prompts";
|
||||
import type { OperationalTaskDecision } from "../api/operational-task-client";
|
||||
import type { InvestigationDiscussion } from "../api/investigation-report";
|
||||
import type { OperationalTaskReportPage } from "../api/operational-task-client";
|
||||
import type { OperationalTaskDataSnapshot } from "../api/operational-task-client";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import {
|
||||
@@ -82,7 +84,7 @@ type ScheduledConditionFeedProps = {
|
||||
onClose?: () => void;
|
||||
onLoadHistorySession: (sessionId: string) => void | Promise<void>;
|
||||
onSubmitPrompt: (prompt: string) => void | Promise<void>;
|
||||
onOpenTaskCollaboration?: (taskId: string) => Promise<void>;
|
||||
onOpenTaskCollaboration?: (taskId: string, discussion?: InvestigationDiscussion) => Promise<void>;
|
||||
onTaskDecision?: (taskId: string, actionId: string, expectedVersion: number, decision: OperationalTaskDecision, comment?: string) => Promise<unknown>;
|
||||
onTaskExecute?: (taskId: string, actionId: string, expectedVersion: number) => Promise<unknown>;
|
||||
onTaskDraftUpdate?: (taskId: string, actionId: string, expectedVersion: number, payload: Record<string, unknown>) => Promise<unknown>;
|
||||
@@ -91,12 +93,15 @@ type ScheduledConditionFeedProps = {
|
||||
onTaskReconcile?: (taskId: string, actionId: string, expectedVersion: number) => Promise<unknown>;
|
||||
onLoadTaskEvidenceSnapshot?: (taskId: string, evidenceId: string) => Promise<OperationalTaskDataSnapshot>;
|
||||
onTaskRefresh?: () => void;
|
||||
onLoadTaskReports?: (taskId: string, offset: number) => Promise<OperationalTaskReportPage>;
|
||||
onReportViewed?: (taskId: string, generation: number, revision: number) => void;
|
||||
onRefresh?: () => void | Promise<void>;
|
||||
};
|
||||
|
||||
type ScheduledConditionFeedFocusRequest = {
|
||||
conditionId: string;
|
||||
requestId: number;
|
||||
actionId?: string | null;
|
||||
};
|
||||
|
||||
export function ScheduledConditionFeed({
|
||||
@@ -127,6 +132,8 @@ export function ScheduledConditionFeed({
|
||||
onTaskReconcile,
|
||||
onLoadTaskEvidenceSnapshot,
|
||||
onTaskRefresh,
|
||||
onLoadTaskReports,
|
||||
onReportViewed,
|
||||
onRefresh
|
||||
}: ScheduledConditionFeedProps) {
|
||||
const [uncontrolledExpanded, setUncontrolledExpanded] = useState(false);
|
||||
@@ -200,6 +207,7 @@ export function ScheduledConditionFeed({
|
||||
null;
|
||||
const focusConditionId = focusRequest?.conditionId;
|
||||
const focusRequestId = focusRequest?.requestId;
|
||||
const [focusedAction, setFocusedAction] = useState<{ conditionId: string; actionId: string } | null>(null);
|
||||
const updateExpanded = useCallback(
|
||||
(nextExpanded: boolean) => {
|
||||
if (controlledExpanded === undefined) {
|
||||
@@ -261,12 +269,14 @@ export function ScheduledConditionFeed({
|
||||
setTaskFilter(CONDITION_FILTER_ALL);
|
||||
setStatusFilter(CONDITION_FILTER_ALL);
|
||||
updateSelectedConditionId(targetCondition.id);
|
||||
setFocusedAction(focusRequest?.actionId ? { conditionId: targetCondition.id, actionId: focusRequest.actionId } : null);
|
||||
updateExpanded(true);
|
||||
onFocusRequestHandled?.(focusRequestId);
|
||||
}, [
|
||||
conditions,
|
||||
focusConditionId,
|
||||
focusRequestId,
|
||||
focusRequest?.actionId,
|
||||
onFocusRequestHandled,
|
||||
updateExpanded,
|
||||
updateSelectedConditionId
|
||||
@@ -325,14 +335,14 @@ export function ScheduledConditionFeed({
|
||||
}
|
||||
}
|
||||
|
||||
function handleContinueConversation(condition: ScheduledConditionItem) {
|
||||
function handleContinueConversation(condition: ScheduledConditionItem, discussion?: InvestigationDiscussion) {
|
||||
if (condition.kind === "work_order") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (condition.operationalTask) {
|
||||
onExpandAgent();
|
||||
void Promise.resolve(onOpenTaskCollaboration?.(condition.operationalTask.task_id))
|
||||
void Promise.resolve(onOpenTaskCollaboration?.(condition.operationalTask.task_id, discussion))
|
||||
.catch((error) => showMapNotice({
|
||||
id: "operational-task-collaboration",
|
||||
tone: "error",
|
||||
@@ -385,6 +395,7 @@ export function ScheduledConditionFeed({
|
||||
return (
|
||||
<section
|
||||
aria-label="工况任务"
|
||||
data-task-category={taskCategory}
|
||||
aria-hidden={!visible}
|
||||
className={cn(
|
||||
"scheduled-feed-panel-shell pointer-events-auto overflow-hidden p-3 motion-reduce:transition-none",
|
||||
@@ -506,14 +517,14 @@ export function ScheduledConditionFeed({
|
||||
)}
|
||||
aria-hidden={!expanded}
|
||||
>
|
||||
{activeLoading && expanded ? (
|
||||
{activeLoading && expanded && !selectedCondition ? (
|
||||
<ConditionDetailSkeleton />
|
||||
) : expanded && selectedCondition ? (
|
||||
<ConditionDetailPanel
|
||||
condition={selectedCondition}
|
||||
dataSource={dataSource}
|
||||
workOrderDataSource={workOrderDataSource}
|
||||
onContinueConversation={() => handleContinueConversation(selectedCondition)}
|
||||
onContinueConversation={(discussion) => handleContinueConversation(selectedCondition, discussion)}
|
||||
onTaskDecision={onTaskDecision}
|
||||
onTaskExecute={onTaskExecute}
|
||||
onTaskDraftUpdate={onTaskDraftUpdate}
|
||||
@@ -522,6 +533,9 @@ export function ScheduledConditionFeed({
|
||||
onTaskReconcile={onTaskReconcile}
|
||||
onLoadTaskEvidenceSnapshot={onLoadTaskEvidenceSnapshot}
|
||||
onTaskRefresh={onTaskRefresh}
|
||||
onLoadTaskReports={onLoadTaskReports}
|
||||
onReportViewed={onReportViewed}
|
||||
focusActionId={focusedAction?.conditionId === selectedConditionId ? focusedAction.actionId : undefined}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
@@ -1098,14 +1112,15 @@ function ConditionTimelineRow({
|
||||
>
|
||||
<span className="flex min-w-0 items-center gap-2">
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block truncate text-xs font-semibold leading-4">
|
||||
<span className="scheduled-condition-title block truncate text-xs font-semibold leading-4">
|
||||
{condition.title}
|
||||
</span>
|
||||
<span className="block truncate text-xs leading-4 text-[var(--ink-muted)]">
|
||||
{condition.summary}
|
||||
</span>
|
||||
</span>
|
||||
<StatusPill condition={condition} className="shrink-0 text-xs" />
|
||||
<StatusPill condition={condition} className="scheduled-condition-status shrink-0 text-xs" />
|
||||
{condition.kind === "condition" && condition.hasNewReport ? <span className="text-xs font-medium text-[var(--action-blue)]">新报告</span> : null}
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user