mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Add sorting to task history
This commit is contained in:
@@ -1,17 +1,31 @@
|
|||||||
import { VSCodeButton, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
|
import { VSCodeButton, VSCodeTextField, VSCodeRadioGroup, VSCodeRadio } from "@vscode/webview-ui-toolkit/react"
|
||||||
import { useExtensionState } from "../context/ExtensionStateContext"
|
import { useExtensionState } from "../context/ExtensionStateContext"
|
||||||
import { vscode } from "../utils/vscode"
|
import { vscode } from "../utils/vscode"
|
||||||
import { Virtuoso } from "react-virtuoso"
|
import { Virtuoso } from "react-virtuoso"
|
||||||
import { memo, useMemo, useState } from "react"
|
import { memo, useMemo, useState, useEffect } from "react"
|
||||||
import Fuse, { FuseResult } from "fuse.js"
|
import Fuse, { FuseResult } from "fuse.js"
|
||||||
|
|
||||||
type HistoryViewProps = {
|
type HistoryViewProps = {
|
||||||
onDone: () => void
|
onDone: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SortOption = "newest" | "oldest" | "mostExpensive" | "mostTokens" | "mostRelevant"
|
||||||
|
|
||||||
const HistoryView = ({ onDone }: HistoryViewProps) => {
|
const HistoryView = ({ onDone }: HistoryViewProps) => {
|
||||||
const { taskHistory } = useExtensionState()
|
const { taskHistory } = useExtensionState()
|
||||||
const [searchQuery, setSearchQuery] = useState("")
|
const [searchQuery, setSearchQuery] = useState("")
|
||||||
|
const [sortOption, setSortOption] = useState<SortOption>("newest")
|
||||||
|
const [lastNonRelevantSort, setLastNonRelevantSort] = useState<SortOption | null>("newest")
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (searchQuery && sortOption !== "mostRelevant" && !lastNonRelevantSort) {
|
||||||
|
setLastNonRelevantSort(sortOption)
|
||||||
|
setSortOption("mostRelevant")
|
||||||
|
} else if (!searchQuery && sortOption === "mostRelevant" && lastNonRelevantSort) {
|
||||||
|
setSortOption(lastNonRelevantSort)
|
||||||
|
setLastNonRelevantSort(null)
|
||||||
|
}
|
||||||
|
}, [searchQuery, sortOption, lastNonRelevantSort])
|
||||||
|
|
||||||
const handleHistorySelect = (id: string) => {
|
const handleHistorySelect = (id: string) => {
|
||||||
vscode.postMessage({ type: "showTaskWithId", text: id })
|
vscode.postMessage({ type: "showTaskWithId", text: id })
|
||||||
@@ -43,20 +57,42 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
|
|||||||
const fuse = useMemo(() => {
|
const fuse = useMemo(() => {
|
||||||
return new Fuse(presentableTasks, {
|
return new Fuse(presentableTasks, {
|
||||||
keys: ["task"],
|
keys: ["task"],
|
||||||
threshold: 0.4,
|
threshold: 0.6,
|
||||||
shouldSort: true,
|
shouldSort: true,
|
||||||
isCaseSensitive: false,
|
isCaseSensitive: false,
|
||||||
ignoreLocation: true,
|
ignoreLocation: false,
|
||||||
includeMatches: true,
|
includeMatches: true,
|
||||||
minMatchCharLength: 1,
|
minMatchCharLength: 1,
|
||||||
})
|
})
|
||||||
}, [presentableTasks])
|
}, [presentableTasks])
|
||||||
|
|
||||||
const taskHistorySearchResults = useMemo(() => {
|
const taskHistorySearchResults = useMemo(() => {
|
||||||
if (!searchQuery) return presentableTasks
|
let results = searchQuery ? highlight(fuse.search(searchQuery)) : presentableTasks
|
||||||
const searchResults = fuse.search(searchQuery)
|
|
||||||
return highlight(searchResults)
|
results.sort((a, b) => {
|
||||||
}, [presentableTasks, searchQuery, fuse])
|
switch (sortOption) {
|
||||||
|
case "oldest":
|
||||||
|
return a.ts - b.ts
|
||||||
|
case "mostExpensive":
|
||||||
|
return (b.totalCost || 0) - (a.totalCost || 0)
|
||||||
|
case "mostTokens":
|
||||||
|
return (
|
||||||
|
(b.tokensIn || 0) +
|
||||||
|
(b.tokensOut || 0) +
|
||||||
|
(b.cacheWrites || 0) +
|
||||||
|
(b.cacheReads || 0) -
|
||||||
|
((a.tokensIn || 0) + (a.tokensOut || 0) + (a.cacheWrites || 0) + (a.cacheReads || 0))
|
||||||
|
)
|
||||||
|
case "mostRelevant":
|
||||||
|
return searchQuery ? 0 : b.ts - a.ts // Keep fuse order if searching, otherwise sort by newest
|
||||||
|
case "newest":
|
||||||
|
default:
|
||||||
|
return b.ts - a.ts
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return results
|
||||||
|
}, [presentableTasks, searchQuery, fuse, sortOption])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -78,6 +114,13 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
|
|||||||
background-color: var(--vscode-editor-findMatchHighlightBackground);
|
background-color: var(--vscode-editor-findMatchHighlightBackground);
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
.clear-search-button {
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
.clear-search-button:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
`}
|
`}
|
||||||
</style>
|
</style>
|
||||||
<div
|
<div
|
||||||
@@ -101,26 +144,56 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
|
|||||||
<h3 style={{ color: "var(--vscode-foreground)", margin: 0 }}>History</h3>
|
<h3 style={{ color: "var(--vscode-foreground)", margin: 0 }}>History</h3>
|
||||||
<VSCodeButton onClick={onDone}>Done</VSCodeButton>
|
<VSCodeButton onClick={onDone}>Done</VSCodeButton>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ padding: "5px 17px 10px 17px" }}>
|
<div style={{ padding: "5px 17px 6px 17px" }}>
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}>
|
||||||
<VSCodeTextField
|
<VSCodeTextField
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
placeholder="Search history..."
|
placeholder="Fuzzy search history..."
|
||||||
value={searchQuery}
|
value={searchQuery}
|
||||||
onInput={(e) => setSearchQuery((e.target as HTMLInputElement)?.value)}>
|
onInput={(e) => {
|
||||||
|
const newValue = (e.target as HTMLInputElement)?.value
|
||||||
|
setSearchQuery(newValue)
|
||||||
|
if (newValue && !searchQuery && sortOption !== "mostRelevant") {
|
||||||
|
setLastNonRelevantSort(sortOption)
|
||||||
|
setSortOption("mostRelevant")
|
||||||
|
}
|
||||||
|
}}>
|
||||||
<div
|
<div
|
||||||
slot="start"
|
slot="start"
|
||||||
className="codicon codicon-search"
|
className="codicon codicon-search"
|
||||||
style={{ fontSize: 13, marginTop: 2.5, opacity: 0.8 }}></div>
|
style={{ fontSize: 13, marginTop: 2.5, opacity: 0.8 }}></div>
|
||||||
{searchQuery && (
|
{searchQuery && (
|
||||||
<VSCodeButton
|
<div
|
||||||
appearance="icon"
|
className="clear-search-button"
|
||||||
aria-label="Clear search"
|
aria-label="Clear search"
|
||||||
onClick={() => setSearchQuery("")}
|
onClick={() => setSearchQuery("")}
|
||||||
slot="end">
|
slot="end"
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100%",
|
||||||
|
}}>
|
||||||
<span className="codicon codicon-close"></span>
|
<span className="codicon codicon-close"></span>
|
||||||
</VSCodeButton>
|
</div>
|
||||||
)}
|
)}
|
||||||
</VSCodeTextField>
|
</VSCodeTextField>
|
||||||
|
<VSCodeRadioGroup
|
||||||
|
style={{ display: "flex", flexWrap: "wrap" }}
|
||||||
|
value={sortOption}
|
||||||
|
onChange={(e) => setSortOption((e.target as HTMLInputElement).value as SortOption)}>
|
||||||
|
<VSCodeRadio value="newest">Newest</VSCodeRadio>
|
||||||
|
<VSCodeRadio value="oldest">Oldest</VSCodeRadio>
|
||||||
|
<VSCodeRadio value="mostExpensive">Most Expensive</VSCodeRadio>
|
||||||
|
<VSCodeRadio value="mostTokens">Most Tokens</VSCodeRadio>
|
||||||
|
<VSCodeRadio
|
||||||
|
value="mostRelevant"
|
||||||
|
disabled={!searchQuery}
|
||||||
|
style={{ opacity: searchQuery ? 1 : 0.5 }}>
|
||||||
|
Most Relevant
|
||||||
|
</VSCodeRadio>
|
||||||
|
</VSCodeRadioGroup>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ flexGrow: 1, overflowY: "auto", margin: 0 }}>
|
<div style={{ flexGrow: 1, overflowY: "auto", margin: 0 }}>
|
||||||
{presentableTasks.length === 0 && (
|
{presentableTasks.length === 0 && (
|
||||||
@@ -139,11 +212,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
|
|||||||
<span
|
<span
|
||||||
className="codicon codicon-archive"
|
className="codicon codicon-archive"
|
||||||
style={{ fontSize: "50px", marginBottom: "15px" }}></span>
|
style={{ fontSize: "50px", marginBottom: "15px" }}></span>
|
||||||
<div>
|
<div>No history found</div>
|
||||||
No history found,
|
|
||||||
<br />
|
|
||||||
start a new task to see it here...
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Virtuoso
|
<Virtuoso
|
||||||
|
|||||||
Reference in New Issue
Block a user