feat(project): add workspace directory configuration and management (#1)
- Add projectDir field to Project model for workspace directory management - Implement workspace directory creation, validation and Git initialization - Add workspace status query endpoint with directory info and Git status - Create GitManager for Git repository operations (clone, branch, commit info) - Add PathValidator for secure path validation and traversal attack prevention - Implement execution queue with concurrency control for build tasks - Refactor project list UI to remove edit/delete actions from cards - Add project settings tab in detail page with edit/delete functionality - Add icons to all tabs (History, Code, Settings) - Implement time formatting with dayjs in YYYY-MM-DD HH:mm:ss format - Display all timestamps using browser's local timezone - Update PipelineRunner to use workspace directory for command execution - Add workspace status card showing directory path, size, Git info - Enhance CreateProjectModal with repository URL validation Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -4,7 +4,6 @@ import { useState } from 'react';
|
||||
import { useAsyncEffect } from '../../../hooks/useAsyncEffect';
|
||||
import type { Project } from '../types';
|
||||
import CreateProjectModal from './components/CreateProjectModal';
|
||||
import EditProjectModal from './components/EditProjectModal';
|
||||
import ProjectCard from './components/ProjectCard';
|
||||
import { projectService } from './service';
|
||||
|
||||
@@ -12,8 +11,6 @@ const { Text } = Typography;
|
||||
|
||||
function ProjectPage() {
|
||||
const [projects, setProjects] = useState<Project[]>([]);
|
||||
const [editModalVisible, setEditModalVisible] = useState(false);
|
||||
const [editingProject, setEditingProject] = useState<Project | null>(null);
|
||||
const [createModalVisible, setCreateModalVisible] = useState(false);
|
||||
|
||||
useAsyncEffect(async () => {
|
||||
@@ -21,22 +18,6 @@ function ProjectPage() {
|
||||
setProjects(response.data);
|
||||
}, []);
|
||||
|
||||
const handleEditProject = (project: Project) => {
|
||||
setEditingProject(project);
|
||||
setEditModalVisible(true);
|
||||
};
|
||||
|
||||
const handleEditSuccess = (updatedProject: Project) => {
|
||||
setProjects((prev) =>
|
||||
prev.map((p) => (p.id === updatedProject.id ? updatedProject : p)),
|
||||
);
|
||||
};
|
||||
|
||||
const handleEditCancel = () => {
|
||||
setEditModalVisible(false);
|
||||
setEditingProject(null);
|
||||
};
|
||||
|
||||
const handleCreateProject = () => {
|
||||
setCreateModalVisible(true);
|
||||
};
|
||||
@@ -49,17 +30,6 @@ function ProjectPage() {
|
||||
setCreateModalVisible(false);
|
||||
};
|
||||
|
||||
const handleDeleteProject = async (project: Project) => {
|
||||
try {
|
||||
await projectService.delete(project.id);
|
||||
setProjects((prev) => prev.filter((p) => p.id !== project.id));
|
||||
Message.success('项目删除成功');
|
||||
} catch (error) {
|
||||
console.error('删除项目失败:', error);
|
||||
Message.error('删除项目失败,请稍后重试');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-6">
|
||||
<div className="mb-6 flex items-center justify-between">
|
||||
@@ -82,22 +52,11 @@ function ProjectPage() {
|
||||
<Grid.Row gutter={[16, 16]}>
|
||||
{projects.map((project) => (
|
||||
<Grid.Col key={project.id} span={8}>
|
||||
<ProjectCard
|
||||
project={project}
|
||||
onEdit={handleEditProject}
|
||||
onDelete={handleDeleteProject}
|
||||
/>
|
||||
<ProjectCard project={project} />
|
||||
</Grid.Col>
|
||||
))}
|
||||
</Grid.Row>
|
||||
|
||||
<EditProjectModal
|
||||
visible={editModalVisible}
|
||||
project={editingProject}
|
||||
onCancel={handleEditCancel}
|
||||
onSuccess={handleEditSuccess}
|
||||
/>
|
||||
|
||||
<CreateProjectModal
|
||||
visible={createModalVisible}
|
||||
onCancel={handleCreateCancel}
|
||||
|
||||
Reference in New Issue
Block a user