feat: Add project sorting by date option

feat: Add project sorting by date option
This commit is contained in:
viper151
2025-07-12 13:35:04 +02:00
committed by GitHub
2 changed files with 98 additions and 2 deletions

View File

@@ -61,6 +61,7 @@ function Sidebar({
const [additionalSessions, setAdditionalSessions] = useState({}); const [additionalSessions, setAdditionalSessions] = useState({});
const [initialSessionsLoaded, setInitialSessionsLoaded] = useState(new Set()); const [initialSessionsLoaded, setInitialSessionsLoaded] = useState(new Set());
const [currentTime, setCurrentTime] = useState(new Date()); const [currentTime, setCurrentTime] = useState(new Date());
const [projectSortOrder, setProjectSortOrder] = useState('name');
const [isRefreshing, setIsRefreshing] = useState(false); const [isRefreshing, setIsRefreshing] = useState(false);
const [editingSession, setEditingSession] = useState(null); const [editingSession, setEditingSession] = useState(null);
const [editingSessionName, setEditingSessionName] = useState(''); const [editingSessionName, setEditingSessionName] = useState('');
@@ -114,6 +115,45 @@ function Sidebar({
} }
}, [projects, isLoading]); }, [projects, isLoading]);
// Load project sort order from settings
useEffect(() => {
const loadSortOrder = () => {
try {
const savedSettings = localStorage.getItem('claude-tools-settings');
if (savedSettings) {
const settings = JSON.parse(savedSettings);
setProjectSortOrder(settings.projectSortOrder || 'name');
}
} catch (error) {
console.error('Error loading sort order:', error);
}
};
// Load initially
loadSortOrder();
// Listen for storage changes
const handleStorageChange = (e) => {
if (e.key === 'claude-tools-settings') {
loadSortOrder();
}
};
window.addEventListener('storage', handleStorageChange);
// Also check periodically when component is focused (for same-tab changes)
const checkInterval = setInterval(() => {
if (document.hasFocus()) {
loadSortOrder();
}
}, 1000);
return () => {
window.removeEventListener('storage', handleStorageChange);
clearInterval(checkInterval);
};
}, []);
const toggleProject = (projectName) => { const toggleProject = (projectName) => {
const newExpanded = new Set(expandedProjects); const newExpanded = new Set(expandedProjects);
if (newExpanded.has(projectName)) { if (newExpanded.has(projectName)) {
@@ -291,6 +331,35 @@ function Sidebar({
return [...initialSessions, ...additional]; return [...initialSessions, ...additional];
}; };
// Helper function to get the last activity date for a project
const getProjectLastActivity = (project) => {
const allSessions = getAllSessions(project);
if (allSessions.length === 0) {
return new Date(0); // Return epoch date for projects with no sessions
}
// Find the most recent session activity
const mostRecentDate = allSessions.reduce((latest, session) => {
const sessionDate = new Date(session.lastActivity);
return sessionDate > latest ? sessionDate : latest;
}, new Date(0));
return mostRecentDate;
};
// Sort projects based on selected order
const sortedProjects = [...projects].sort((a, b) => {
if (projectSortOrder === 'date') {
// Sort by most recent activity (descending)
return getProjectLastActivity(b) - getProjectLastActivity(a);
} else {
// Sort by display name (user-defined) or fallback to name (ascending)
const nameA = a.displayName || a.name;
const nameB = b.displayName || b.name;
return nameA.localeCompare(nameB);
}
});
return ( return (
<div className="h-full flex flex-col bg-card md:select-none"> <div className="h-full flex flex-col bg-card md:select-none">
{/* Header */} {/* Header */}
@@ -499,7 +568,7 @@ function Sidebar({
</p> </p>
</div> </div>
) : ( ) : (
projects.map((project) => { sortedProjects.map((project) => {
const isExpanded = expandedProjects.has(project.name); const isExpanded = expandedProjects.has(project.name);
const isSelected = selectedProject?.name === project.name; const isSelected = selectedProject?.name === project.name;

View File

@@ -15,6 +15,7 @@ function ToolsSettings({ isOpen, onClose }) {
const [skipPermissions, setSkipPermissions] = useState(false); const [skipPermissions, setSkipPermissions] = useState(false);
const [isSaving, setIsSaving] = useState(false); const [isSaving, setIsSaving] = useState(false);
const [saveStatus, setSaveStatus] = useState(null); const [saveStatus, setSaveStatus] = useState(null);
const [projectSortOrder, setProjectSortOrder] = useState('name');
// Common tool patterns // Common tool patterns
const commonTools = [ const commonTools = [
@@ -51,11 +52,13 @@ function ToolsSettings({ isOpen, onClose }) {
setAllowedTools(settings.allowedTools || []); setAllowedTools(settings.allowedTools || []);
setDisallowedTools(settings.disallowedTools || []); setDisallowedTools(settings.disallowedTools || []);
setSkipPermissions(settings.skipPermissions || false); setSkipPermissions(settings.skipPermissions || false);
setProjectSortOrder(settings.projectSortOrder || 'name');
} else { } else {
// Set defaults // Set defaults
setAllowedTools([]); setAllowedTools([]);
setDisallowedTools([]); setDisallowedTools([]);
setSkipPermissions(false); setSkipPermissions(false);
setProjectSortOrder('name');
} }
} catch (error) { } catch (error) {
console.error('Error loading tool settings:', error); console.error('Error loading tool settings:', error);
@@ -63,6 +66,7 @@ function ToolsSettings({ isOpen, onClose }) {
setAllowedTools([]); setAllowedTools([]);
setDisallowedTools([]); setDisallowedTools([]);
setSkipPermissions(false); setSkipPermissions(false);
setProjectSortOrder('name');
} }
}; };
@@ -75,6 +79,7 @@ function ToolsSettings({ isOpen, onClose }) {
allowedTools, allowedTools,
disallowedTools, disallowedTools,
skipPermissions, skipPermissions,
projectSortOrder,
lastUpdated: new Date().toISOString() lastUpdated: new Date().toISOString()
}; };
@@ -181,6 +186,28 @@ function ToolsSettings({ isOpen, onClose }) {
</span> </span>
</button> </button>
</div> </div>
{/* Project Sorting - Moved under Appearance */}
<div className="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between">
<div>
<div className="font-medium text-foreground">
Project Sorting
</div>
<div className="text-sm text-muted-foreground">
How projects are ordered in the sidebar
</div>
</div>
<select
value={projectSortOrder}
onChange={(e) => setProjectSortOrder(e.target.value)}
className="text-sm bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 rounded-lg focus:ring-blue-500 focus:border-blue-500 p-2 w-32"
>
<option value="name">Alphabetical</option>
<option value="date">Recent Activity</option>
</select>
</div>
</div>
</div> </div>
</div> </div>
@@ -418,4 +445,4 @@ function ToolsSettings({ isOpen, onClose }) {
); );
} }
export default ToolsSettings; export default ToolsSettings;