mirror of
https://github.com/siteboon/claudecodeui.git
synced 2025-12-09 10:59:47 +00:00
feat: Add project sorting by date option
feat: Add project sorting by date option
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user