Frontend start to use backend CRUD api

This commit is contained in:
Xin Wang
2026-02-08 15:08:18 +08:00
parent b9a315177a
commit 86744f0842
12 changed files with 768 additions and 154 deletions

View File

@@ -1,17 +1,19 @@
import React, { useState, useRef } from 'react';
import React, { useEffect, useState, useRef } from 'react';
import { Search, Plus, Upload, MoreHorizontal, Code, Edit2, Copy, Trash2, Calendar, CloudUpload, File as FileIcon, X, Layout, FilePlus } from 'lucide-react';
import { Button, Input, TableHeader, TableRow, TableHead, TableCell, Dialog, Card } from '../components/UI';
import { mockWorkflows } from '../services/mockData';
import { useNavigate } from 'react-router-dom';
import { Workflow } from '../types';
import { deleteWorkflow, fetchWorkflows } from '../services/backendApi';
export const WorkflowsPage: React.FC = () => {
const navigate = useNavigate();
const [workflows, setWorkflows] = useState(mockWorkflows);
const [workflows, setWorkflows] = useState<Workflow[]>([]);
const [searchTerm, setSearchTerm] = useState('');
const [isUploadOpen, setIsUploadOpen] = useState(false);
const [isCreateOpen, setIsCreateOpen] = useState(false);
const [activeMenu, setActiveMenu] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [newWfName, setNewWfName] = useState('');
const [selectedTemplate, setSelectedTemplate] = useState<'blank' | 'lead'>('blank');
@@ -20,6 +22,23 @@ export const WorkflowsPage: React.FC = () => {
wf.name.toLowerCase().includes(searchTerm.toLowerCase())
);
useEffect(() => {
const loadWorkflows = async () => {
setIsLoading(true);
try {
const list = await fetchWorkflows();
setWorkflows(list);
} catch (error) {
console.error(error);
alert('加载工作流失败,请检查后端服务。');
} finally {
setIsLoading(false);
}
};
loadWorkflows();
}, []);
const handleCreateWorkflow = () => {
if (!newWfName.trim()) {
alert('请输入工作流名称');
@@ -29,10 +48,16 @@ export const WorkflowsPage: React.FC = () => {
navigate(`/workflows/new?name=${encodeURIComponent(newWfName)}&template=${selectedTemplate}`);
};
const handleDeleteWorkflow = (id: string) => {
const handleDeleteWorkflow = async (id: string) => {
if (confirm('确定要删除这个工作流吗?')) {
setWorkflows(prev => prev.filter(w => w.id !== id));
setActiveMenu(null);
try {
await deleteWorkflow(id);
setWorkflows(prev => prev.filter(w => w.id !== id));
setActiveMenu(null);
} catch (error) {
console.error(error);
alert('删除工作流失败。');
}
}
};
@@ -83,7 +108,7 @@ export const WorkflowsPage: React.FC = () => {
</TableRow>
</TableHeader>
<tbody>
{filteredWorkflows.map(wf => (
{!isLoading && filteredWorkflows.map(wf => (
<TableRow key={wf.id} className="group">
<TableCell className="font-medium">
<button
@@ -125,11 +150,16 @@ export const WorkflowsPage: React.FC = () => {
</TableCell>
</TableRow>
))}
{filteredWorkflows.length === 0 && (
{!isLoading && filteredWorkflows.length === 0 && (
<TableRow>
<TableCell colSpan={5} className="text-center py-12 text-muted-foreground"></TableCell>
</TableRow>
)}
{isLoading && (
<TableRow>
<TableCell colSpan={5} className="text-center py-12 text-muted-foreground">...</TableCell>
</TableRow>
)}
</tbody>
</table>
</div>