mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-22 21:28:12 +02:00
Fix delete notion page tool implementation
This commit is contained in:
parent
11e1c01847
commit
97d5b046d4
5 changed files with 216 additions and 44 deletions
|
|
@ -1,7 +1,14 @@
|
|||
"use client";
|
||||
|
||||
import { makeAssistantToolUI } from "@assistant-ui/react";
|
||||
import { AlertTriangleIcon, CheckIcon, Loader2Icon, XIcon } from "lucide-react";
|
||||
import {
|
||||
AlertTriangleIcon,
|
||||
CheckIcon,
|
||||
InfoIcon,
|
||||
Loader2Icon,
|
||||
TriangleAlertIcon,
|
||||
XIcon,
|
||||
} from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
|
|
@ -17,6 +24,8 @@ interface InterruptResult {
|
|||
action_name: string;
|
||||
allowed_decisions: Array<"approve" | "reject">;
|
||||
}>;
|
||||
interrupt_type?: string;
|
||||
message?: string;
|
||||
context?: {
|
||||
account?: {
|
||||
id: number;
|
||||
|
|
@ -36,7 +45,9 @@ interface InterruptResult {
|
|||
interface SuccessResult {
|
||||
status: "success";
|
||||
page_id: string;
|
||||
title?: string;
|
||||
message?: string;
|
||||
deleted_from_db?: boolean;
|
||||
}
|
||||
|
||||
interface ErrorResult {
|
||||
|
|
@ -44,7 +55,20 @@ interface ErrorResult {
|
|||
message: string;
|
||||
}
|
||||
|
||||
type DeleteNotionPageResult = InterruptResult | SuccessResult | ErrorResult;
|
||||
interface InfoResult {
|
||||
status: "not_found";
|
||||
message: string;
|
||||
}
|
||||
|
||||
interface WarningResult {
|
||||
status: "success";
|
||||
warning: string;
|
||||
page_id?: string;
|
||||
title?: string;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
type DeleteNotionPageResult = InterruptResult | SuccessResult | ErrorResult | InfoResult | WarningResult;
|
||||
|
||||
function isInterruptResult(result: unknown): result is InterruptResult {
|
||||
return (
|
||||
|
|
@ -64,6 +88,26 @@ function isErrorResult(result: unknown): result is ErrorResult {
|
|||
);
|
||||
}
|
||||
|
||||
function isInfoResult(result: unknown): result is InfoResult {
|
||||
return (
|
||||
typeof result === "object" &&
|
||||
result !== null &&
|
||||
"status" in result &&
|
||||
(result as InfoResult).status === "not_found"
|
||||
);
|
||||
}
|
||||
|
||||
function isWarningResult(result: unknown): result is WarningResult {
|
||||
return (
|
||||
typeof result === "object" &&
|
||||
result !== null &&
|
||||
"status" in result &&
|
||||
(result as WarningResult).status === "success" &&
|
||||
"warning" in result &&
|
||||
typeof (result as WarningResult).warning === "string"
|
||||
);
|
||||
}
|
||||
|
||||
function ApprovalCard({
|
||||
args,
|
||||
interruptData,
|
||||
|
|
@ -82,6 +126,9 @@ function ApprovalCard({
|
|||
);
|
||||
const [deleteFromDb, setDeleteFromDb] = useState(false);
|
||||
|
||||
const account = interruptData.context?.account;
|
||||
const currentTitle = interruptData.context?.current_title;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`my-4 max-w-full overflow-hidden rounded-xl transition-all duration-300 ${
|
||||
|
|
@ -116,23 +163,34 @@ function ApprovalCard({
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2 px-4 py-3 bg-card">
|
||||
{interruptData.context?.account && (
|
||||
<div>
|
||||
<p className="text-xs font-medium text-muted-foreground">Notion Account</p>
|
||||
<p className="text-sm text-foreground">
|
||||
{interruptData.context.account.workspace_icon}{" "}
|
||||
{interruptData.context.account.workspace_name}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{interruptData.context?.current_title && (
|
||||
<div>
|
||||
<p className="text-xs font-medium text-muted-foreground">Page</p>
|
||||
<p className="text-sm text-foreground">📄 {interruptData.context.current_title}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* Context section - READ ONLY account and page info */}
|
||||
{!decided && interruptData.context && (
|
||||
<div className="border-b border-border px-4 py-3 bg-muted/30 space-y-3">
|
||||
{interruptData.context.error ? (
|
||||
<p className="text-sm text-destructive">{interruptData.context.error}</p>
|
||||
) : (
|
||||
<>
|
||||
{account && (
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-medium text-muted-foreground">Notion Account</div>
|
||||
<div className="w-full rounded-md border border-input bg-muted/50 px-3 py-2 text-sm">
|
||||
{account.workspace_icon} {account.workspace_name}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{currentTitle && (
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-medium text-muted-foreground">Page to Delete</div>
|
||||
<div className="w-full rounded-md border border-input bg-muted/50 px-3 py-2 text-sm">
|
||||
📄 {currentTitle}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Checkbox for deleting from knowledge base */}
|
||||
{!decided && (
|
||||
|
|
@ -184,7 +242,8 @@ function ApprovalCard({
|
|||
edited_action: {
|
||||
name: interruptData.action_requests[0].name,
|
||||
args: {
|
||||
...interruptData.action_requests[0].args,
|
||||
page_id: interruptData.context?.page_id,
|
||||
connector_id: account?.id,
|
||||
delete_from_db: deleteFromDb,
|
||||
},
|
||||
},
|
||||
|
|
@ -230,6 +289,45 @@ function ErrorCard({ result }: { result: ErrorResult }) {
|
|||
);
|
||||
}
|
||||
|
||||
function InfoCard({ result }: { result: InfoResult }) {
|
||||
return (
|
||||
<div className="my-4 max-w-md overflow-hidden rounded-xl border border-amber-500/50 bg-card">
|
||||
<div className="flex items-start gap-3 px-4 py-3">
|
||||
<div className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-amber-500/10">
|
||||
<InfoIcon className="size-4 text-amber-500" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1 pt-2">
|
||||
<p className="text-sm text-muted-foreground">{result.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function WarningCard({ result }: { result: WarningResult }) {
|
||||
return (
|
||||
<div className="my-4 max-w-md overflow-hidden rounded-xl border border-amber-500/50 bg-card">
|
||||
<div className="flex items-center gap-3 border-b border-amber-500/50 px-4 py-3">
|
||||
<div className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-amber-500/10">
|
||||
<TriangleAlertIcon className="size-4 text-amber-500" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-sm font-medium text-amber-600 dark:text-amber-500">Partial success</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2 px-4 py-3 text-xs">
|
||||
<p className="text-sm text-muted-foreground">{result.warning}</p>
|
||||
{result.title && (
|
||||
<div className="pt-2">
|
||||
<span className="font-medium text-muted-foreground">Deleted page: </span>
|
||||
<span>{result.title}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SuccessCard({ result }: { result: SuccessResult }) {
|
||||
return (
|
||||
<div className="my-4 max-w-md overflow-hidden rounded-xl border border-border bg-card">
|
||||
|
|
@ -238,18 +336,27 @@ function SuccessCard({ result }: { result: SuccessResult }) {
|
|||
<CheckIcon className="size-4 text-green-500" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className=" text-[.8rem] text-muted-foreground">
|
||||
<p className="text-[.8rem] text-muted-foreground">
|
||||
{result.message || "Notion page deleted successfully"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{result.deleted_from_db || result.title && (
|
||||
<div className="space-y-2 px-4 py-3 text-xs">
|
||||
<div>
|
||||
<span className="font-medium text-muted-foreground">Page ID: </span>
|
||||
<span className="font-mono">{result.page_id}</span>
|
||||
</div>
|
||||
</div>
|
||||
{result.title && (
|
||||
<div>
|
||||
<span className="font-medium text-muted-foreground">Deleted page: </span>
|
||||
<span>{result.title}</span>
|
||||
</div>
|
||||
)}
|
||||
{result.deleted_from_db && (
|
||||
<div className="pt-1">
|
||||
<span className="text-green-600 dark:text-green-500">
|
||||
✓ Also removed from knowledge base
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -288,6 +395,23 @@ export const DeleteNotionPageToolUI = makeAssistantToolUI<
|
|||
);
|
||||
}
|
||||
|
||||
if (
|
||||
typeof result === "object" &&
|
||||
result !== null &&
|
||||
"status" in result &&
|
||||
(result as { status: string }).status === "rejected"
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isInfoResult(result)) {
|
||||
return <InfoCard result={result} />;
|
||||
}
|
||||
|
||||
if (isWarningResult(result)) {
|
||||
return <WarningCard result={result} />;
|
||||
}
|
||||
|
||||
if (isErrorResult(result)) {
|
||||
return <ErrorCard result={result} />;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue