Develop Frontend Components for Project, Package, and Instance Views

This commit is contained in:
Mondo Diaz
2025-12-12 10:23:44 -06:00
parent 8b7b523aa8
commit e89947f3d3
25 changed files with 2123 additions and 170 deletions

View File

@@ -1,4 +1,17 @@
import { Project, Package, Tag, Artifact, UploadResponse } from './types';
import {
Project,
Package,
Tag,
TagDetail,
Artifact,
ArtifactDetail,
UploadResponse,
PaginatedResponse,
ListParams,
TagListParams,
PackageListParams,
ArtifactListParams,
} from './types';
const API_BASE = '/api/v1';
@@ -10,21 +23,26 @@ async function handleResponse<T>(response: Response): Promise<T> {
return response.json();
}
// Paginated response type
interface PaginatedResponse<T> {
items: T[];
pagination: {
page: number;
limit: number;
total: number;
total_pages: number;
};
function buildQueryString(params: Record<string, unknown>): string {
const searchParams = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== '') {
searchParams.append(key, String(value));
}
});
const query = searchParams.toString();
return query ? `?${query}` : '';
}
// Project API
export async function listProjects(): Promise<Project[]> {
const response = await fetch(`${API_BASE}/projects`);
const data = await handleResponse<PaginatedResponse<Project>>(response);
export async function listProjects(params: ListParams = {}): Promise<PaginatedResponse<Project>> {
const query = buildQueryString(params as Record<string, unknown>);
const response = await fetch(`${API_BASE}/projects${query}`);
return handleResponse<PaginatedResponse<Project>>(response);
}
export async function listProjectsSimple(params: ListParams = {}): Promise<Project[]> {
const data = await listProjects(params);
return data.items;
}
@@ -43,12 +61,22 @@ export async function getProject(name: string): Promise<Project> {
}
// Package API
export async function listPackages(projectName: string): Promise<Package[]> {
const response = await fetch(`${API_BASE}/project/${projectName}/packages`);
const data = await handleResponse<PaginatedResponse<Package>>(response);
export async function listPackages(projectName: string, params: PackageListParams = {}): Promise<PaginatedResponse<Package>> {
const query = buildQueryString(params as Record<string, unknown>);
const response = await fetch(`${API_BASE}/project/${projectName}/packages${query}`);
return handleResponse<PaginatedResponse<Package>>(response);
}
export async function listPackagesSimple(projectName: string, params: PackageListParams = {}): Promise<Package[]> {
const data = await listPackages(projectName, params);
return data.items;
}
export async function getPackage(projectName: string, packageName: string): Promise<Package> {
const response = await fetch(`${API_BASE}/project/${projectName}/packages/${packageName}`);
return handleResponse<Package>(response);
}
export async function createPackage(projectName: string, data: { name: string; description?: string }): Promise<Package> {
const response = await fetch(`${API_BASE}/project/${projectName}/packages`, {
method: 'POST',
@@ -59,9 +87,20 @@ export async function createPackage(projectName: string, data: { name: string; d
}
// Tag API
export async function listTags(projectName: string, packageName: string): Promise<Tag[]> {
const response = await fetch(`${API_BASE}/project/${projectName}/${packageName}/tags`);
return handleResponse<Tag[]>(response);
export async function listTags(projectName: string, packageName: string, params: TagListParams = {}): Promise<PaginatedResponse<TagDetail>> {
const query = buildQueryString(params as Record<string, unknown>);
const response = await fetch(`${API_BASE}/project/${projectName}/${packageName}/tags${query}`);
return handleResponse<PaginatedResponse<TagDetail>>(response);
}
export async function listTagsSimple(projectName: string, packageName: string, params: TagListParams = {}): Promise<TagDetail[]> {
const data = await listTags(projectName, packageName, params);
return data.items;
}
export async function getTag(projectName: string, packageName: string, tagName: string): Promise<TagDetail> {
const response = await fetch(`${API_BASE}/project/${projectName}/${packageName}/tags/${tagName}`);
return handleResponse<TagDetail>(response);
}
export async function createTag(projectName: string, packageName: string, data: { name: string; artifact_id: string }): Promise<Tag> {
@@ -74,9 +113,19 @@ export async function createTag(projectName: string, packageName: string, data:
}
// Artifact API
export async function getArtifact(artifactId: string): Promise<Artifact> {
export async function getArtifact(artifactId: string): Promise<ArtifactDetail> {
const response = await fetch(`${API_BASE}/artifact/${artifactId}`);
return handleResponse<Artifact>(response);
return handleResponse<ArtifactDetail>(response);
}
export async function listPackageArtifacts(
projectName: string,
packageName: string,
params: ArtifactListParams = {}
): Promise<PaginatedResponse<Artifact & { tags: string[] }>> {
const query = buildQueryString(params as Record<string, unknown>);
const response = await fetch(`${API_BASE}/project/${projectName}/${packageName}/artifacts${query}`);
return handleResponse<PaginatedResponse<Artifact & { tags: string[] }>>(response);
}
// Upload