e.stopPropagation()}
>
{ setViewArtifactId(t.artifact_id); setShowArtifactIdModal(true); setOpenMenuId(null); setMenuPosition(null); }}>
View Artifact ID
{ navigator.clipboard.writeText(t.artifact_id); setOpenMenuId(null); setMenuPosition(null); }}>
Copy Artifact ID
{ fetchEnsureFileForTag(t.name); setOpenMenuId(null); setMenuPosition(null); }}>
View Ensure File
{canWrite && !isSystemProject && (
{ setCreateTagArtifactId(t.artifact_id); setShowCreateTagModal(true); setOpenMenuId(null); setMenuPosition(null); }}>
Create/Update Tag
)}
{ handleTagSelect(t); setShowDepsModal(true); setOpenMenuId(null); setMenuPosition(null); }}>
View Dependencies
);
};
if (loading && !tagsData) {
return Loading...
;
}
if (accessDenied) {
return (
{packageName}
{pkg &&
{pkg.format} }
{user && canWrite && !isSystemProject && (
setShowUploadModal(true)}
>
Upload
)}
{pkg?.description &&
{pkg.description}
}
in {projectName}
{pkg && (
<>
Created {new Date(pkg.created_at).toLocaleDateString()}
{pkg.updated_at !== pkg.created_at && (
Updated {new Date(pkg.updated_at).toLocaleDateString()}
)}
>
)}
{pkg && (pkg.tag_count !== undefined || pkg.artifact_count !== undefined) && (
{!isSystemProject && pkg.tag_count !== undefined && (
{pkg.tag_count} tags
)}
{pkg.artifact_count !== undefined && (
{pkg.artifact_count} {isSystemProject ? 'versions' : 'artifacts'}
)}
{pkg.total_size !== undefined && pkg.total_size > 0 && (
{formatBytes(pkg.total_size)} total
)}
{!isSystemProject && pkg.latest_tag && (
Latest: {pkg.latest_tag}
)}
)}
{error &&
{error}
}
{uploadSuccess &&
{uploadSuccess}
}
{isSystemProject ? 'Versions' : 'Tags / Versions'}
{hasActiveFilters && (
{search && handleSearchChange('')} />}
)}
t.id}
emptyMessage={
hasActiveFilters
? 'No tags match your filters. Try adjusting your search.'
: 'No tags yet. Upload an artifact with a tag to create one!'
}
onSort={handleSortChange}
sortKey={sort}
sortOrder={order}
/>
{pagination && pagination.total_pages > 1 && (
)}
{/* Used By (Reverse Dependencies) Section */}
Used By
{reverseDepsLoading ? (
Loading reverse dependencies...
) : reverseDepsError ? (
{reverseDepsError}
) : reverseDeps.length === 0 ? (
No packages depend on this package
) : (
{reverseDepsTotal} {reverseDepsTotal === 1 ? 'package depends' : 'packages depend'} on this:
{reverseDeps.map((dep) => (
{dep.project}/{dep.package}
{dep.version && (
v{dep.version}
)}
requires @ {dep.constraint_value}
))}
{(reverseDepsHasMore || reverseDepsPage > 1) && (
fetchReverseDeps(reverseDepsPage - 1)}
disabled={reverseDepsPage <= 1 || reverseDepsLoading}
>
Previous
Page {reverseDepsPage}
fetchReverseDeps(reverseDepsPage + 1)}
disabled={!reverseDepsHasMore || reverseDepsLoading}
>
Next
)}
)}
Usage
Download artifacts using:
curl -O {window.location.origin}/api/v1/project/{projectName}/{packageName}/+/latest
Or with a specific tag:
curl -O {window.location.origin}/api/v1/project/{projectName}/{packageName}/+/v1.0.0
{/* Dependency Graph Modal */}
{showGraph && selectedTag && (
setShowGraph(false)}
/>
)}
{/* Upload Modal */}
{showUploadModal && (
setShowUploadModal(false)}>
e.stopPropagation()}>
Upload Artifact
setShowUploadModal(false)}
title="Close"
>
)}
{/* Create/Update Tag Modal */}
{showCreateTagModal && (
setShowCreateTagModal(false)}>
e.stopPropagation()}>
Create / Update Tag
{ setShowCreateTagModal(false); setCreateTagName(''); setCreateTagArtifactId(''); }}
title="Close"
>
Point a tag at an artifact by its ID
)}
{/* Ensure File Modal */}
{showEnsureFile && (
setShowEnsureFile(false)}>
e.stopPropagation()}>
orchard.ensure for {ensureFileTagName}
{ensureFileContent && (
)}
setShowEnsureFile(false)}
title="Close"
>
{ensureFileLoading ? (
Loading...
) : ensureFileError ? (
{ensureFileError}
) : ensureFileContent ? (
{ensureFileContent}
) : (
No dependencies defined for this artifact.
)}
Save this as orchard.ensure in your project root to declare dependencies.
)}
{/* Dependencies Modal */}
{showDepsModal && selectedTag && (
setShowDepsModal(false)}>
e.stopPropagation()}>
Dependencies for {selectedTag.version || selectedTag.name}
setShowDepsModal(false)}
title="Close"
>
View Ensure File
{ setShowDepsModal(false); setShowGraph(true); }}
>
View Graph
{depsLoading ? (
Loading dependencies...
) : depsError ? (
{depsError}
) : dependencies.length === 0 ? (
No dependencies
) : (
{dependencies.length} {dependencies.length === 1 ? 'dependency' : 'dependencies'}:
{dependencies.map((dep) => (
setShowDepsModal(false)}
>
{dep.project}/{dep.package}
@ {dep.version || dep.tag}
✓
))}
)}
)}
{/* Artifact ID Modal */}
{showArtifactIdModal && viewArtifactId && (
setShowArtifactIdModal(false)}>
e.stopPropagation()}>
Artifact ID
setShowArtifactIdModal(false)}
title="Close"
>
SHA256 hash identifying this artifact:
{viewArtifactId}
)}
{/* Action Menu Dropdown */}
{renderActionMenu()}
);
}
export default PackagePage;