feat: 刷新按钮移入任务列表面板头部并增加加载反馈
- 从页面标题栏移除刷新按钮,改放到任务列表搜索框右侧 - 点击时图标旋转动画,完成后 toast「任务列表已刷新」 - 刷新进行中防重复点击
This commit is contained in:
parent
3bea611750
commit
5863baa0ab
@ -258,7 +258,8 @@ export function App() {
|
||||
onOpenEditor={(id) => void openEditor(id)}
|
||||
onRun={(id) => void runTask(id)}
|
||||
onDelete={(id) => void deleteTask(id)}
|
||||
onRefresh={() => void refreshFlows()}
|
||||
onRefresh={() => refreshFlows()}
|
||||
onToast={showToast}
|
||||
/>
|
||||
)}
|
||||
{page === "editor" && <EditorPage catalog={catalog} onToast={showToast} onBack={() => { setPage("tasks"); void refreshFlows(); }} />}
|
||||
|
||||
@ -23,7 +23,8 @@ interface TasksPageProps {
|
||||
onOpenEditor: (id: string) => void;
|
||||
onRun: (id: string) => void;
|
||||
onDelete: (id: string) => void;
|
||||
onRefresh: () => void;
|
||||
onRefresh: () => void | Promise<void>;
|
||||
onToast: (message: string, kind?: "ok" | "error") => void;
|
||||
}
|
||||
|
||||
function formatTime(value: string): string {
|
||||
@ -45,9 +46,21 @@ function formatDuration(value?: number): string {
|
||||
|
||||
const RUN_LABEL = { succeeded: "成功", failed: "失败", cancelled: "已取消", never: "未运行" } as const;
|
||||
|
||||
export function TasksPage({ flows, onCreate, onCreateExamples, onOpenEditor, onRun, onDelete, onRefresh }: TasksPageProps) {
|
||||
export function TasksPage({ flows, onCreate, onCreateExamples, onOpenEditor, onRun, onDelete, onRefresh, onToast }: TasksPageProps) {
|
||||
const [query, setQuery] = useState("");
|
||||
const [selectedId, setSelectedId] = useState<string | null>(flows[0]?.id || null);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
const handleRefresh = async () => {
|
||||
if (refreshing) return;
|
||||
setRefreshing(true);
|
||||
try {
|
||||
await onRefresh();
|
||||
onToast("任务列表已刷新", "ok");
|
||||
} finally {
|
||||
setRefreshing(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!flows.length) {
|
||||
@ -76,9 +89,6 @@ export function TasksPage({ flows, onCreate, onCreateExamples, onOpenEditor, onR
|
||||
<p>选择一个任务开始运行或编辑流程;组件库只在进入编辑时参与搭建。</p>
|
||||
</div>
|
||||
<div className="page-heading-actions">
|
||||
<button type="button" className="icon-btn" title="刷新任务列表" onClick={onRefresh}>
|
||||
<RefreshCw className="icon" />
|
||||
</button>
|
||||
<button type="button" className="btn" onClick={onCreateExamples}>
|
||||
<PackagePlus className="icon" /> 安装示例任务
|
||||
</button>
|
||||
@ -106,6 +116,15 @@ export function TasksPage({ flows, onCreate, onCreateExamples, onOpenEditor, onR
|
||||
<Search className="icon" />
|
||||
<input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="搜索任务" aria-label="搜索任务" />
|
||||
</label>
|
||||
<button
|
||||
type="button"
|
||||
className={`icon-btn refresh-btn${refreshing ? " refreshing" : ""}`}
|
||||
title="刷新任务列表"
|
||||
aria-label="刷新任务列表"
|
||||
onClick={() => void handleRefresh()}
|
||||
>
|
||||
<RefreshCw className="icon" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="task-table-head" aria-hidden="true">
|
||||
|
||||
@ -3294,3 +3294,27 @@ textarea:focus-visible {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 任务列表头部刷新按钮 */
|
||||
.task-list-head {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.task-list-head .task-search {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.icon-btn.refresh-btn {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
flex: none;
|
||||
color: var(--muted, #5b6474);
|
||||
}
|
||||
|
||||
.icon-btn.refresh-btn:hover {
|
||||
color: var(--accent, #2563eb);
|
||||
}
|
||||
|
||||
.icon-btn.refresh-btn.refreshing .icon {
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user