feat(web): add file manager and task types with API clients

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
dailz
2026-04-20 10:39:38 +08:00
parent d71cda3420
commit f5e021d652
4 changed files with 211 additions and 0 deletions

49
web/src/api/files.ts Normal file
View File

@@ -0,0 +1,49 @@
import type { ApiResponse } from '@/types/jobs'
import apiClient from '@/api/client'
import type { FileResponse, ListFilesResponse, UploadSessionResponse, InitUploadRequest, FolderResponse, CreateFolderRequest } from '@/types/files'
export function listFiles(params?: { folder_id?: number; page?: number; page_size?: number; search?: string }): Promise<ApiResponse<ListFilesResponse>> {
return apiClient.get('/files', { params })
}
export function getFile(id: number): Promise<ApiResponse<FileResponse>> {
return apiClient.get(`/files/${id}`)
}
export function deleteFile(id: number): Promise<ApiResponse<{ message: string }>> {
return apiClient.delete(`/files/${id}`)
}
export function downloadFileUrl(id: number): string {
return `/api/v1/files/${id}/download`
}
export function initUpload(data: InitUploadRequest): Promise<ApiResponse<FileResponse | UploadSessionResponse>> {
return apiClient.post('/files/uploads', data)
}
export function uploadChunk(sessionId: number, chunkIndex: number, chunk: Blob): Promise<ApiResponse<{ message: string }>> {
const formData = new FormData()
formData.append('chunk', chunk)
return apiClient.put(`/files/uploads/${sessionId}/chunks/${chunkIndex}`, formData)
}
export function completeUpload(sessionId: number): Promise<ApiResponse<FileResponse>> {
return apiClient.post(`/files/uploads/${sessionId}/complete`)
}
export function cancelUpload(sessionId: number): Promise<ApiResponse<{ message: string }>> {
return apiClient.post(`/files/uploads/${sessionId}/cancel`)
}
export function listFolders(params?: { parent_id?: number | null }): Promise<ApiResponse<FolderResponse[]>> {
return apiClient.get('/files/folders', { params })
}
export function createFolder(data: CreateFolderRequest): Promise<ApiResponse<FolderResponse>> {
return apiClient.post('/files/folders', data)
}
export function deleteFolder(id: number): Promise<ApiResponse<{ message: string }>> {
return apiClient.delete(`/files/folders/${id}`)
}

15
web/src/api/tasks.ts Normal file
View File

@@ -0,0 +1,15 @@
import type { ApiResponse } from '@/types/jobs'
import apiClient from '@/api/client'
import type { ApplicationListResponse, CreateTaskRequest, TaskListResponse } from '@/types/tasks'
export function getApplications(params?: { page?: number; page_size?: number }): Promise<ApiResponse<ApplicationListResponse>> {
return apiClient.get('/applications', { params })
}
export function createTask(data: CreateTaskRequest): Promise<ApiResponse<{ id: number }>> {
return apiClient.post('/tasks', data)
}
export function listTasks(params?: { page?: number; page_size?: number; status?: string }): Promise<ApiResponse<TaskListResponse>> {
return apiClient.get('/tasks', { params })
}

56
web/src/types/files.ts Normal file
View File

@@ -0,0 +1,56 @@
export interface FileResponse {
id: number
name: string
folder_id?: number | null
sha256: string
size: number
mime_type: string
folder_path?: string
user_id?: number | null
created_at: string
updated_at: string
}
export interface ListFilesResponse {
files?: FileResponse[]
total?: number
page?: number
page_size?: number
}
export interface FolderResponse {
id: number
name: string
parent_id?: number | null
path: string
file_count: number
subfolder_count: number
created_at: string
}
export interface CreateFolderRequest {
name: string
parent_id?: number | null
}
export interface UploadSessionResponse {
id: number
file_name: string
file_size: number
sha256: string
chunk_size: number
total_chunks: number
status: string
uploaded_chunks?: number[]
created_at?: string
expires_at?: string
}
export interface InitUploadRequest {
file_name: string
file_size: number
sha256: string
chunk_size?: number
mime_type?: string
folder_id?: number | null
}

91
web/src/types/tasks.ts Normal file
View File

@@ -0,0 +1,91 @@
export interface ParameterSchema {
name: string
label?: string
type: string
required?: boolean
default?: string
options?: string[]
description?: string
}
export interface Application {
id: number
name: string
description?: string
icon?: string
category?: string
script_template: string
parameters?: ParameterSchema[] | null
scope?: string
created_by?: number
created_at: string
updated_at: string
}
export interface ApplicationListResponse {
applications?: Application[]
total?: number
page?: number
page_size?: number
}
export interface CreateTaskRequest {
app_id: number
task_name?: string
values?: Record<string, string>
partition?: string
cpus?: number
job_name?: string
memory_per_node?: number
nodes?: string
tasks?: number
cpus_per_task?: number
file_ids?: number[]
}
export interface TaskResponse {
id: number
task_name: string
app_id: number
app_name: string
status: string
current_step: string
retry_count: number
slurm_job_id: number | null
work_dir: string
error_message: string
created_at: string
updated_at: string
partition?: string
cpus?: number | null
memory_per_node?: number | null
memory_per_cpu?: number | null
time_limit?: number | null
qos?: string
job_name?: string
nodes?: string
tasks?: number | null
cpus_per_task?: number | null
constraints?: string
reservation?: string
account?: string
nice?: number | null
mail_type?: string
mail_user?: string
standard_output?: string
standard_error?: string
standard_input?: string
required_nodes?: string
excluded_nodes?: string
begin_time?: number | null
deadline?: number | null
array?: string
dependency?: string
requeue?: boolean
kill_on_node_fail?: boolean
}
export interface TaskListResponse {
items?: TaskResponse[]
total?: number
}