2 Commits

Author SHA1 Message Date
Mondo Diaz
2843335f6d Document curl -OJ flag for correct download filenames
- Update download examples to use -OJ flag
- Add note explaining curl download flags (-O, -J, -OJ, -o)
- Add example for saving to a specific filename
2025-12-12 13:53:15 -06:00
Mondo Diaz
2097865874 Remove redundant search bar from Home, rename page filters
- Remove SearchInput from Home page (use GlobalSearch in header instead)
- Rename "Search packages..." to "Filter packages..." on ProjectPage
- Rename "Search tags..." to "Filter tags..." on PackagePage
- Update FilterChip labels from "Search" to "Filter"

This differentiates the global search (header) from page-level filtering.
2025-12-12 12:55:31 -06:00
4 changed files with 19 additions and 24 deletions

View File

@@ -275,14 +275,17 @@ curl -X POST http://localhost:8080/api/v1/project/my-project/releases/upload/abc
### Download an Artifact ### Download an Artifact
```bash ```bash
# By tag # By tag (use -OJ to save with the correct filename from Content-Disposition header)
curl -O http://localhost:8080/api/v1/project/my-project/releases/+/v1.0.0 curl -OJ http://localhost:8080/api/v1/project/my-project/releases/+/v1.0.0
# By artifact ID # By artifact ID
curl -O http://localhost:8080/api/v1/project/my-project/releases/+/artifact:a3f5d8e12b4c6789... curl -OJ http://localhost:8080/api/v1/project/my-project/releases/+/artifact:a3f5d8e12b4c6789...
# Using the short URL pattern # Using the short URL pattern
curl -O http://localhost:8080/project/my-project/releases/+/latest curl -OJ http://localhost:8080/project/my-project/releases/+/latest
# Save to a specific filename
curl -o myfile.tar.gz http://localhost:8080/api/v1/project/my-project/releases/+/v1.0.0
# Partial download (range request) # Partial download (range request)
curl -H "Range: bytes=0-1023" http://localhost:8080/api/v1/project/my-project/releases/+/v1.0.0 curl -H "Range: bytes=0-1023" http://localhost:8080/api/v1/project/my-project/releases/+/v1.0.0
@@ -291,6 +294,12 @@ curl -H "Range: bytes=0-1023" http://localhost:8080/api/v1/project/my-project/re
curl -I http://localhost:8080/api/v1/project/my-project/releases/+/v1.0.0 curl -I http://localhost:8080/api/v1/project/my-project/releases/+/v1.0.0
``` ```
> **Note on curl flags:**
> - `-O` saves the file using the URL path as the filename (e.g., `latest`, `v1.0.0`)
> - `-J` tells curl to use the filename from the `Content-Disposition` header (e.g., `app-v1.0.0.tar.gz`)
> - `-OJ` combines both: download to a file using the server-provided filename
> - `-o <filename>` saves to a specific filename you choose
### Create a Tag ### Create a Tag
```bash ```bash

View File

@@ -3,7 +3,6 @@ import { Link, useSearchParams } from 'react-router-dom';
import { Project, PaginatedResponse } from '../types'; import { Project, PaginatedResponse } from '../types';
import { listProjects, createProject } from '../api'; import { listProjects, createProject } from '../api';
import { Badge } from '../components/Badge'; import { Badge } from '../components/Badge';
import { SearchInput } from '../components/SearchInput';
import { SortDropdown, SortOption } from '../components/SortDropdown'; import { SortDropdown, SortOption } from '../components/SortDropdown';
import { FilterDropdown, FilterOption } from '../components/FilterDropdown'; import { FilterDropdown, FilterOption } from '../components/FilterDropdown';
import { FilterChip, FilterChipGroup } from '../components/FilterChip'; import { FilterChip, FilterChipGroup } from '../components/FilterChip';
@@ -34,7 +33,6 @@ function Home() {
// Get params from URL // Get params from URL
const page = parseInt(searchParams.get('page') || '1', 10); const page = parseInt(searchParams.get('page') || '1', 10);
const search = searchParams.get('search') || '';
const sort = searchParams.get('sort') || 'name'; const sort = searchParams.get('sort') || 'name';
const order = (searchParams.get('order') || 'asc') as 'asc' | 'desc'; const order = (searchParams.get('order') || 'asc') as 'asc' | 'desc';
const visibility = searchParams.get('visibility') || ''; const visibility = searchParams.get('visibility') || '';
@@ -59,7 +57,6 @@ function Home() {
setLoading(true); setLoading(true);
const data = await listProjects({ const data = await listProjects({
page, page,
search,
sort, sort,
order, order,
visibility: visibility as 'public' | 'private' | undefined || undefined, visibility: visibility as 'public' | 'private' | undefined || undefined,
@@ -71,7 +68,7 @@ function Home() {
} finally { } finally {
setLoading(false); setLoading(false);
} }
}, [page, search, sort, order, visibility]); }, [page, sort, order, visibility]);
useEffect(() => { useEffect(() => {
loadProjects(); loadProjects();
@@ -92,10 +89,6 @@ function Home() {
} }
} }
const handleSearchChange = (value: string) => {
updateParams({ search: value, page: '1' });
};
const handleSortChange = (newSort: string, newOrder: 'asc' | 'desc') => { const handleSortChange = (newSort: string, newOrder: 'asc' | 'desc') => {
updateParams({ sort: newSort, order: newOrder, page: '1' }); updateParams({ sort: newSort, order: newOrder, page: '1' });
}; };
@@ -112,7 +105,7 @@ function Home() {
setSearchParams({}); setSearchParams({});
}; };
const hasActiveFilters = search !== '' || visibility !== ''; const hasActiveFilters = visibility !== '';
const projects = projectsData?.items || []; const projects = projectsData?.items || [];
const pagination = projectsData?.pagination; const pagination = projectsData?.pagination;
@@ -172,12 +165,6 @@ function Home() {
)} )}
<div className="list-controls"> <div className="list-controls">
<SearchInput
value={search}
onChange={handleSearchChange}
placeholder="Search projects..."
className="list-controls__search"
/>
<FilterDropdown <FilterDropdown
label="Visibility" label="Visibility"
options={VISIBILITY_OPTIONS} options={VISIBILITY_OPTIONS}
@@ -189,7 +176,6 @@ function Home() {
{hasActiveFilters && ( {hasActiveFilters && (
<FilterChipGroup onClearAll={clearFilters}> <FilterChipGroup onClearAll={clearFilters}>
{search && <FilterChip label="Search" value={search} onRemove={() => handleSearchChange('')} />}
{visibility && ( {visibility && (
<FilterChip <FilterChip
label="Visibility" label="Visibility"

View File

@@ -325,7 +325,7 @@ function PackagePage() {
<SearchInput <SearchInput
value={search} value={search}
onChange={handleSearchChange} onChange={handleSearchChange}
placeholder="Search tags..." placeholder="Filter tags..."
className="list-controls__search" className="list-controls__search"
/> />
<SortDropdown options={SORT_OPTIONS} value={sort} order={order} onChange={handleSortChange} /> <SortDropdown options={SORT_OPTIONS} value={sort} order={order} onChange={handleSortChange} />
@@ -333,7 +333,7 @@ function PackagePage() {
{hasActiveFilters && ( {hasActiveFilters && (
<FilterChipGroup onClearAll={clearFilters}> <FilterChipGroup onClearAll={clearFilters}>
{search && <FilterChip label="Search" value={search} onRemove={() => handleSearchChange('')} />} {search && <FilterChip label="Filter" value={search} onRemove={() => handleSearchChange('')} />}
</FilterChipGroup> </FilterChipGroup>
)} )}

View File

@@ -226,7 +226,7 @@ function ProjectPage() {
<SearchInput <SearchInput
value={search} value={search}
onChange={handleSearchChange} onChange={handleSearchChange}
placeholder="Search packages..." placeholder="Filter packages..."
className="list-controls__search" className="list-controls__search"
/> />
<select <select
@@ -246,7 +246,7 @@ function ProjectPage() {
{hasActiveFilters && ( {hasActiveFilters && (
<FilterChipGroup onClearAll={clearFilters}> <FilterChipGroup onClearAll={clearFilters}>
{search && <FilterChip label="Search" value={search} onRemove={() => handleSearchChange('')} />} {search && <FilterChip label="Filter" value={search} onRemove={() => handleSearchChange('')} />}
{format && <FilterChip label="Format" value={format} onRemove={() => handleFormatChange('')} />} {format && <FilterChip label="Format" value={format} onRemove={() => handleFormatChange('')} />}
</FilterChipGroup> </FilterChipGroup>
)} )}