From d48f6aafce3fcc20572b439512c22d275be6eb3c Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Fri, 27 Mar 2026 17:17:27 +0200 Subject: [PATCH] add quick-ask page with default action menu --- surfsense_web/app/quick-ask/actions.ts | 68 ++++++++++++++ surfsense_web/app/quick-ask/page.tsx | 117 +++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 surfsense_web/app/quick-ask/actions.ts create mode 100644 surfsense_web/app/quick-ask/page.tsx diff --git a/surfsense_web/app/quick-ask/actions.ts b/surfsense_web/app/quick-ask/actions.ts new file mode 100644 index 000000000..8d4ff0bb5 --- /dev/null +++ b/surfsense_web/app/quick-ask/actions.ts @@ -0,0 +1,68 @@ +import type { QuickAskAction } from "@/contracts/types/quick-ask-actions.types"; + +export const DEFAULT_ACTIONS: QuickAskAction[] = [ + { + id: "fix-grammar", + name: "Fix grammar", + prompt: "Fix the grammar and spelling in the following text. Return only the corrected text, nothing else.\n\n{selection}", + mode: "transform", + icon: "check", + group: "transform", + }, + { + id: "make-shorter", + name: "Make shorter", + prompt: "Make the following text more concise while preserving its meaning. Return only the shortened text, nothing else.\n\n{selection}", + mode: "transform", + icon: "minimize", + group: "transform", + }, + { + id: "translate", + name: "Translate", + prompt: "Translate the following text to English. If it is already in English, translate it to French. Return only the translation, nothing else.\n\n{selection}", + mode: "transform", + icon: "languages", + group: "transform", + }, + { + id: "rewrite", + name: "Rewrite", + prompt: "Rewrite the following text to improve clarity and readability. Return only the rewritten text, nothing else.\n\n{selection}", + mode: "transform", + icon: "pen-line", + group: "transform", + }, + { + id: "explain", + name: "Explain", + prompt: "Explain the following text in simple terms:\n\n{selection}", + mode: "explore", + icon: "book-open", + group: "explore", + }, + { + id: "summarize", + name: "Summarize", + prompt: "Summarize the following text:\n\n{selection}", + mode: "explore", + icon: "list", + group: "explore", + }, + { + id: "search-knowledge", + name: "Search my knowledge", + prompt: "Search my knowledge base for information related to:\n\n{selection}", + mode: "explore", + icon: "search", + group: "knowledge", + }, + { + id: "search-web", + name: "Search the web", + prompt: "Search the web for information about:\n\n{selection}", + mode: "explore", + icon: "globe", + group: "knowledge", + }, +]; diff --git a/surfsense_web/app/quick-ask/page.tsx b/surfsense_web/app/quick-ask/page.tsx new file mode 100644 index 000000000..22e29b4b7 --- /dev/null +++ b/surfsense_web/app/quick-ask/page.tsx @@ -0,0 +1,117 @@ +"use client"; + +import { + BookOpen, + Check, + Globe, + Languages, + List, + MessageSquare, + Minimize2, + PenLine, + Search, +} from "lucide-react"; +import { useEffect, useState } from "react"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, +} from "@/components/ui/command"; +import { DEFAULT_ACTIONS } from "./actions"; + +const ICONS: Record = { + check: , + minimize: , + languages: , + "pen-line": , + "book-open": , + list: , + search: , + globe: , +}; + +export default function QuickAskPage() { + const [clipboardText, setClipboardText] = useState(""); + + useEffect(() => { + window.electronAPI?.getQuickAskText().then((text) => { + if (text) setClipboardText(text); + }); + }, []); + + const handleAction = (actionId: string) => { + const action = DEFAULT_ACTIONS.find((a) => a.id === actionId); + if (!action || !clipboardText) return; + + const prompt = action.prompt.replace("{selection}", clipboardText); + const encoded = encodeURIComponent(prompt); + const mode = action.mode; + + window.location.href = `/dashboard?quickAskPrompt=${encoded}&quickAskMode=${mode}`; + }; + + const handleAskAnything = () => { + if (!clipboardText) return; + const encoded = encodeURIComponent(clipboardText); + window.location.href = `/dashboard?quickAskPrompt=${encoded}&quickAskMode=explore`; + }; + + const transformActions = DEFAULT_ACTIONS.filter((a) => a.group === "transform"); + const exploreActions = DEFAULT_ACTIONS.filter((a) => a.group === "explore"); + const knowledgeActions = DEFAULT_ACTIONS.filter((a) => a.group === "knowledge"); + + return ( +
+ + + + No actions found. + + + {transformActions.map((action) => ( + handleAction(action.id)}> + {ICONS[action.icon]} + {action.name} + + ))} + + + + + + {exploreActions.map((action) => ( + handleAction(action.id)}> + {ICONS[action.icon]} + {action.name} + + ))} + + + + + + {knowledgeActions.map((action) => ( + handleAction(action.id)}> + {ICONS[action.icon]} + {action.name} + + ))} + + + + + + + + Ask anything... + + + + +
+ ); +}