Overview
Remember recent searches, save complex filter combinations for reuse, and provide search templates for common patterns.
Current State
- ✅ Advanced search filters work
- ❌ No search history
- ❌ No saved searches
- ❌ Must re-enter filters every time
UX Score Impact
Current: UX A (94/100)
With #75 + #76 + this: UX A+ (99/100)
1. Search History
Concept: Automatically remember last 50 searches for quick recall.
Storage Format (JSON):
{
"history": [
{
"timestamp": "2026-05-28T10:30:00Z",
"repository": "maven-releases",
"criteria": {
"regexFilter": ".*SNAPSHOT.*",
"minSize": 1000000,
"createdBefore": "2025-01-01T00:00:00Z"
},
"resultsCount": 150
}
]
}
Location:
Max Size: 50 searches (configurable)
Auto-Cleanup: Remove entries older than 90 days
GUI Implementation (Swing)
Search History Dropdown:
JComboBox<SearchHistoryEntry> historyCombo = new JComboBox<>();
historyCombo.setRenderer(new SearchHistoryRenderer());
// Populate from history
searchHistory.getRecent(10).forEach(historyCombo::addItem);
// On selection
historyCombo.addActionListener(e -> {
SearchHistoryEntry entry = (SearchHistoryEntry) historyCombo.getSelectedItem();
if (entry != null) {
applySearchCriteria(entry.criteria());
}
});
Renderer:
class SearchHistoryRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(...) {
SearchHistoryEntry entry = (SearchHistoryEntry) value;
setText(entry.describe()); // "maven-releases: *.SNAPSHOT.* (150 results) - 2h ago"
return this;
}
}
CLI Implementation
# View history
jnexus search --history
# Output:
# Recent searches:
# 1. maven-releases: .*SNAPSHOT.* (150 results) - 2 hours ago
# 2. npm-public: created before 2025-01-01 (45 results) - 1 day ago
# 3. maven-releases: >10MB (1234 results) - 3 days ago
# Repeat search #2
jnexus search --history-index 2
# Clear history
jnexus search --clear-history
2. Saved Searches
Concept: Name and save complex searches for easy reuse.
Storage Format (JSON):
{
"savedSearches": [
{
"name": "Large SNAPSHOTs",
"description": "SNAPSHOT JARs over 10 MB",
"category": "cleanup",
"repository": "maven-releases",
"criteria": {
"regexFilter": ".*SNAPSHOT.*\.jar",
"minSize": 10485760
},
"createdAt": "2026-05-01T10:00:00Z",
"lastUsed": "2026-05-28T10:30:00Z",
"useCount": 15
},
{
"name": "Old Dependencies",
"description": "Dependencies older than 1 year",
"category": "audit",
"repository": "maven-releases",
"criteria": {
"createdBefore": "relative:-365d" // Special: relative to now
},
"createdAt": "2026-05-01T10:00:00Z",
"lastUsed": "2026-05-28T09:00:00Z",
"useCount": 8
}
]
}
Location:
GUI Implementation (Swing)
Saved Searches Menu:
JMenu searchMenu = new JMenu("Search");
JMenuItem saveSearchItem = new JMenuItem("Save Current Search...");
saveSearchItem.addActionListener(e -> saveCurrentSearch());
JMenu savedSearchesMenu = new JMenu("Saved Searches");
// Dynamically populate
savedSearchManager.getAll().forEach(search -> {
JMenuItem item = new JMenuItem(search.name());
item.setToolTipText(search.description());
item.addActionListener(e -> applySearch(search));
savedSearchesMenu.add(item);
});
JMenuItem manageSearchesItem = new JMenuItem("Manage Saved Searches...");
manageSearchesItem.addActionListener(e -> showManageSearchesDialog());
Save Search Dialog:
┌─ Save Search ──────────────────────────────────┐
│ │
│ Name: [Large SNAPSHOTs ] │
│ │
│ Description: │
│ [SNAPSHOT JARs over 10 MB ] │
│ │
│ Category: │
│ ( ) Cleanup ( ) Audit ( ) Analysis │
│ ( ) Other: [_____________] │
│ │
│ Current Filters: │
│ Repository: maven-releases │
│ Regex: .*SNAPSHOT.*\.jar │
│ Min Size: 10 MB │
│ │
│ [Cancel] [Save] │
└─────────────────────────────────────────────────┘
Manage Searches Dialog:
┌─ Manage Saved Searches ────────────────────────┐
│ │
│ ┌───────────────────────────────────────────┐ │
│ │ Name Category Last Used │ │
│ ├───────────────────────────────────────────┤ │
│ │ Large SNAPSHOTs Cleanup 2 hours ago │ │
│ │ Old Dependencies Audit Yesterday │ │
│ │ Security JARs Analysis 1 week ago │ │
│ │ ... │ │
│ └───────────────────────────────────────────┘ │
│ │
│ [Edit] [Delete] [Export] [Import] [Close] │
└─────────────────────────────────────────────────┘
CLI Implementation
# List saved searches
jnexus search --saved
# Output:
# Saved searches:
# 1. Large SNAPSHOTs (cleanup) - Used 15 times
# 2. Old Dependencies (audit) - Used 8 times
# Run saved search
jnexus search --saved "Large SNAPSHOTs"
# or
jnexus search --saved-index 1
# Save current search
jnexus list maven-releases --regex '.*SNAPSHOT.*' --min-size 10485760 \
--save-search "Large SNAPSHOTs" \
--search-description "SNAPSHOT JARs over 10 MB" \
--search-category cleanup
# Export/import
jnexus search --export-saved saved-searches.json
jnexus search --import-saved saved-searches.json
3. Search Templates
Built-In Templates for Common Patterns:
public enum SearchTemplate {
LARGE_FILES("Large Files", "Files over 100 MB",
criteria -> criteria.minSize(100_000_000L)),
SMALL_FILES("Small Files", "Files under 1 MB",
criteria -> criteria.maxSize(1_000_000L)),
OLD_SNAPSHOTS("Old SNAPSHOTs", "SNAPSHOTs older than 90 days",
criteria -> criteria
.regexFilter(".*SNAPSHOT.*")
.createdBefore(Instant.now().minus(Duration.ofDays(90)))),
RECENT_UPLOADS("Recent Uploads", "Uploaded in last 7 days",
criteria -> criteria.createdAfter(Instant.now().minus(Duration.ofDays(7)))),
JAR_FILES("JAR Files", "All JAR files",
criteria -> criteria.fileExtension(".jar")),
WAR_FILES("WAR Files", "All WAR files",
criteria -> criteria.fileExtension(".war")),
POM_FILES("POM Files", "All POM files",
criteria -> criteria.fileExtension(".pom")),
DOCKER_IMAGES("Docker Images", "Docker format repositories",
criteria -> criteria.format("docker")),
NPM_PACKAGES("NPM Packages", "NPM format repositories",
criteria -> criteria.format("npm"));
private final String name;
private final String description;
private final Function<SearchCriteria.Builder, SearchCriteria.Builder> configurator;
public SearchCriteria apply(String repository) {
SearchCriteria.Builder builder = SearchCriteria.builder().repository(repository);
return configurator.apply(builder).build();
}
}
GUI Usage:
Search → Templates → Old SNAPSHOTs
# Auto-fills filters
CLI Usage:
jnexus search maven-releases --template old-snapshots
jnexus search maven-releases --template large-files
4. Search Sharing/Export
Export Search to File:
# Export single search
jnexus search --export-search my-search.json
# Import and run
jnexus search --import-search my-search.json
Share via URL (Future Enhancement):
jnexus://search?repo=maven-releases®ex=.*SNAPSHOT.*&minSize=10485760
# Copy to clipboard, share with team
5. Search Statistics
Track Search Effectiveness:
public record SearchStats(
int totalSearches,
int avgResultsPerSearch,
Map<String, Integer> popularFilters, // "regex" → 45, "minSize" → 30
List<String> mostUsedSavedSearches
) {}
View Stats:
jnexus search --stats
# Output:
# Search Statistics:
# - Total searches: 150
# - Average results: 87 components
# - Most used filter: regex (45 times)
# - Most popular saved search: "Large SNAPSHOTs" (15 times)
Configuration
# Search history size (default: 50)
nexus.search.history.max=50
# Search history retention (days, default: 90)
nexus.search.history.retention.days=90
# Enable search statistics (default: true)
nexus.search.stats.enabled=true
Testing
@Test
void testSearchHistoryLimited() {
SearchHistory history = new SearchHistory(3); // Max 3
history.add(search1);
history.add(search2);
history.add(search3);
history.add(search4); // Should evict search1
List<SearchHistoryEntry> recent = history.getRecent(10);
assertEquals(3, recent.size());
assertEquals(search4, recent.get(0)); // Most recent first
}
@Test
void testSavedSearchUsageTracking() {
SavedSearchManager manager = new SavedSearchManager();
SavedSearch search = new SavedSearch("test", "Test", "category", criteria);
manager.save(search);
manager.use("test");
manager.use("test");
SavedSearch loaded = manager.get("test");
assertEquals(2, loaded.useCount());
assertNotNull(loaded.lastUsed());
}
Acceptance Criteria
Priority
Low - Quality of life feature, not essential
Related
Overview
Remember recent searches, save complex filter combinations for reuse, and provide search templates for common patterns.
Current State
UX Score Impact
Current: UX A (94/100)
With #75 + #76 + this: UX A+ (99/100)
1. Search History
Concept: Automatically remember last 50 searches for quick recall.
Storage Format (JSON):
{ "history": [ { "timestamp": "2026-05-28T10:30:00Z", "repository": "maven-releases", "criteria": { "regexFilter": ".*SNAPSHOT.*", "minSize": 1000000, "createdBefore": "2025-01-01T00:00:00Z" }, "resultsCount": 150 } ] }Location:
Max Size: 50 searches (configurable)
Auto-Cleanup: Remove entries older than 90 days
GUI Implementation (Swing)
Search History Dropdown:
Renderer:
CLI Implementation
2. Saved Searches
Concept: Name and save complex searches for easy reuse.
Storage Format (JSON):
{ "savedSearches": [ { "name": "Large SNAPSHOTs", "description": "SNAPSHOT JARs over 10 MB", "category": "cleanup", "repository": "maven-releases", "criteria": { "regexFilter": ".*SNAPSHOT.*\.jar", "minSize": 10485760 }, "createdAt": "2026-05-01T10:00:00Z", "lastUsed": "2026-05-28T10:30:00Z", "useCount": 15 }, { "name": "Old Dependencies", "description": "Dependencies older than 1 year", "category": "audit", "repository": "maven-releases", "criteria": { "createdBefore": "relative:-365d" // Special: relative to now }, "createdAt": "2026-05-01T10:00:00Z", "lastUsed": "2026-05-28T09:00:00Z", "useCount": 8 } ] }Location:
GUI Implementation (Swing)
Saved Searches Menu:
Save Search Dialog:
Manage Searches Dialog:
CLI Implementation
3. Search Templates
Built-In Templates for Common Patterns:
GUI Usage:
CLI Usage:
4. Search Sharing/Export
Export Search to File:
Share via URL (Future Enhancement):
5. Search Statistics
Track Search Effectiveness:
View Stats:
Configuration
Testing
Acceptance Criteria
Priority
Low - Quality of life feature, not essential
Related