feat(selection): 支持选股结果服务端分页
This commit is contained in:
@@ -15,7 +15,7 @@ import {
|
||||
} from "./selection-presentation"
|
||||
import { SignalTable } from "./signal-table"
|
||||
|
||||
const PAGE_SIZE_OPTIONS = [5, 10, 20] as const
|
||||
const PAGE_SIZE_OPTIONS = [5, 10, 15] as const
|
||||
|
||||
interface SelectionResultsWorkbenchProps {
|
||||
result: SelectionResults
|
||||
@@ -26,14 +26,14 @@ export function SelectionResultsWorkbench({
|
||||
}: SelectionResultsWorkbenchProps) {
|
||||
const search = useSearch({ from: "/_workspace/selection" })
|
||||
const navigate = useNavigate({ from: "/selection" })
|
||||
const [query, setQuery] = useState("")
|
||||
const [category, setCategory] = useState<SignalCategoryFilter>("all")
|
||||
const query = search.search ?? ""
|
||||
const category = search.category ?? "all"
|
||||
const [selectedKey, setSelectedKey] = useState<string | null>(null)
|
||||
const [expandedKeys, setExpandedKeys] = useState<ReadonlySet<string>>(
|
||||
new Set(),
|
||||
)
|
||||
|
||||
const filteredSignals = useMemo(() => {
|
||||
const visibleSignals = useMemo(() => {
|
||||
const normalized = query.trim().toLowerCase()
|
||||
return result.signals.filter((signal) => {
|
||||
const matchesQuery =
|
||||
@@ -46,12 +46,10 @@ export function SelectionResultsWorkbench({
|
||||
|
||||
const page = search.page
|
||||
const pageSize = search.pageSize
|
||||
const pageCount = Math.max(1, Math.ceil(filteredSignals.length / pageSize))
|
||||
const signalsTotal = result.signals_total ?? result.signal_count
|
||||
const pageCount = Math.max(1, Math.ceil(signalsTotal / pageSize))
|
||||
const currentPage = Math.min(page, pageCount)
|
||||
const currentSignals = filteredSignals.slice(
|
||||
(currentPage - 1) * pageSize,
|
||||
currentPage * pageSize,
|
||||
)
|
||||
const currentSignals = visibleSignals
|
||||
const selectedSignal =
|
||||
currentSignals.find((signal) => getSignalKey(signal) === selectedKey) ??
|
||||
currentSignals[0]
|
||||
@@ -64,18 +62,21 @@ export function SelectionResultsWorkbench({
|
||||
}
|
||||
}, [navigate, page, pageCount])
|
||||
|
||||
function updateSearch(next: { page?: number; pageSize?: number }) {
|
||||
function updateSearch(next: {
|
||||
page?: number
|
||||
pageSize?: number
|
||||
search?: string
|
||||
category?: SignalCategoryFilter
|
||||
}) {
|
||||
void navigate({ search: (previous) => ({ ...previous, ...next }) })
|
||||
}
|
||||
|
||||
function handleQueryChange(value: string) {
|
||||
setQuery(value)
|
||||
updateSearch({ page: 1 })
|
||||
updateSearch({ page: 1, search: value })
|
||||
}
|
||||
|
||||
function handleCategoryChange(value: SignalCategoryFilter) {
|
||||
setCategory(value)
|
||||
updateSearch({ page: 1 })
|
||||
updateSearch({ category: value, page: 1 })
|
||||
}
|
||||
|
||||
function handleToggleExpanded(signal: SelectionSignal) {
|
||||
@@ -115,7 +116,7 @@ export function SelectionResultsWorkbench({
|
||||
))}
|
||||
</select>
|
||||
<span className="text-xs tabular-nums text-muted-foreground sm:justify-self-end">
|
||||
筛选结果 {filteredSignals.length} 条
|
||||
筛选结果 {signalsTotal} 条
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -141,7 +142,7 @@ export function SelectionResultsWorkbench({
|
||||
page={currentPage}
|
||||
pageSize={pageSize}
|
||||
pageSizeOptions={PAGE_SIZE_OPTIONS}
|
||||
total={filteredSignals.length}
|
||||
total={signalsTotal}
|
||||
/>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user