Commit 9c0fe5ee by luoqi

feat(web/plans): per-view filter options + priority hover integration

FilterBar 增 view prop:
  我的工单 / 召回池 两个 view 的 status 选项应该不同(工单看跟进状态,
  召回池看入池状态)。setView 时清 status 避免无效组合残留。

行级优先级数字接 PriorityHover:鼠标悬浮看 6 因子算分明细,
跟详情页效果一致。
parent 8d708bac
......@@ -33,6 +33,7 @@ import { plansApi } from './plans-api';
import { usePlansList } from './use-plans-list';
import { usePlanCounts } from './use-plan-counts';
import { ReasonLine } from '@/components/plan-detail/reason-line';
import { PriorityHover, type PriorityBreakdown } from '@/components/priority-hover';
// ─────────────────────────────────────────────────────────────────
// 召回任务工作台(/plans)
......@@ -201,8 +202,10 @@ export function PlansListApp() {
};
// 切换 view / status / q / sort 时回到第一页 + 清空选择(常识)
// ⭐ 切 view 时清空 status — 不同 view 状态可选项不同(pool 无 filter,mine 不可选 active)
// 不清会出现 mine + status=active 这种空查询的怪状态
const setView = (v: View) => {
setQuery({ view: v, page: 1 });
setQuery({ view: v, status: undefined, page: 1 });
clearSelected();
};
const setStatus = (s: ListPlansQuery['status'] | undefined) => {
......@@ -226,6 +229,7 @@ export function PlansListApp() {
</div>
<FilterBar
view={view}
q={q}
setQ={setQ}
status={query.status}
......@@ -467,10 +471,12 @@ function ViewTabs({
// ─────────────────────────────────────────────────────────────────
function FilterBar({
view,
q, setQ, status, setStatus,
sort, setSort, density, setDensity,
allSelected, someSelected, onTogglePage,
}: {
view: View;
q: string;
setQ: (v: string) => void;
status: ListPlansQuery['status'] | undefined;
......@@ -483,6 +489,27 @@ function FilterBar({
someSelected: boolean;
onTogglePage: () => void;
}) {
// 按 view 决定状态可选 — 跟后端 view filter 口径对齐(plan.service.ts)
// pool: WHERE status=active AND assigneeUserId IS NULL → 全部都是"待认领",status filter 无意义,隐藏
// mine: WHERE assigneeUserId=user → 可能 assigned/completed/abandoned,不会有 active
// all: 无 view 过滤,全状态可见
const statusOptions: Array<{ value: string; label: string }> | null =
view === 'pool'
? null // pool 隐藏 status filter(语义上等价"待认领")
: view === 'mine'
? [
{ value: '__all', label: '全部我的' },
{ value: 'assigned', label: '进行中' },
{ value: 'completed', label: '已完成' },
{ value: 'abandoned', label: '已放弃' },
]
: [
{ value: '__all', label: '全部状态' },
{ value: 'active', label: '待认领' },
{ value: 'assigned', label: '已认领' },
{ value: 'completed', label: '已完成' },
{ value: 'abandoned', label: '已放弃' },
];
return (
<div className="flex flex-none flex-wrap items-center gap-2 border-b border-slate-200 bg-white px-5 py-2.5">
<div className="relative">
......@@ -496,16 +523,16 @@ function FilterBar({
className="w-64 pl-8"
/>
</div>
{statusOptions && (
<Select value={status ?? '__all'} onValueChange={(v) => setStatus(v === '__all' ? undefined : (v as ListPlansQuery['status']))}>
<SelectTrigger className="h-8 w-32 text-xs"><SelectValue placeholder="状态" /></SelectTrigger>
<SelectContent>
<SelectItem value="__all">全部状态</SelectItem>
<SelectItem value="active">待认领</SelectItem>
<SelectItem value="assigned">我的工单</SelectItem>
<SelectItem value="completed">已完成</SelectItem>
<SelectItem value="abandoned">已放弃</SelectItem>
{statusOptions.map((o) => (
<SelectItem key={o.value} value={o.value}>{o.label}</SelectItem>
))}
</SelectContent>
</Select>
)}
<Select value={sort} onValueChange={(v) => setSort(v as SortKey)}>
<SelectTrigger className="h-8 w-44 text-xs"><SelectValue placeholder="排序" /></SelectTrigger>
<SelectContent>
......@@ -654,16 +681,18 @@ function PatientPlanCard({
)}
</div>
</div>
<span
className="inline-flex items-center gap-1 cursor-help group/score relative"
title={`优先级 ${p.priorityScore}/100 — 由 6 因子算分(临床基线 × 时间窗 + 价值 + 转化 + 紧迫,× 信号置信)。点开详情查完整拆解。`}
<PriorityHover
score={p.priorityScore}
breakdown={(p.reasons[0]?.breakdown as { priority?: PriorityBreakdown } | null | undefined)?.priority}
>
<span className="inline-flex items-center gap-1 cursor-help group/score">
<PriorityBar score={p.priorityScore} />
<svg className="w-3 h-3 text-slate-400 opacity-0 group-hover/score:opacity-100 transition-opacity" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="12" cy="12" r="10" />
<path d="M12 16v-4M12 8h.01" strokeLinecap="round" />
</svg>
</span>
</PriorityHover>
</div>
{/* 中:scenario + status */}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment