mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 23:19:43 +02:00
feat: add settings gear icon with app settings modal
- Add gear icon button in header-right for app settings - Create App Settings modal with fields for: - Default CLAUDE.md template path - Default working directory - Settings persist to ~/.claudeman/settings.json - Add GET/PUT /api/settings endpoints - Keep "+" tab for creating new sessions (useful UX) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+70
-1
@@ -477,7 +477,7 @@ class ClaudemanApp {
|
||||
`;
|
||||
}
|
||||
|
||||
// Add the "+" button
|
||||
// Add the "+" button at the end of session tabs
|
||||
html += `
|
||||
<div class="session-tab new-tab" onclick="app.createNewSession()" title="New Session (Ctrl+N)">
|
||||
<span>+</span>
|
||||
@@ -1298,6 +1298,74 @@ class ClaudemanApp {
|
||||
});
|
||||
}
|
||||
|
||||
// ========== App Settings Modal ==========
|
||||
|
||||
openAppSettings() {
|
||||
// Load current settings
|
||||
const settings = this.loadAppSettingsFromStorage();
|
||||
document.getElementById('appSettingsClaudeMdPath').value = settings.defaultClaudeMdPath || '';
|
||||
document.getElementById('appSettingsDefaultDir').value = settings.defaultWorkingDir || '';
|
||||
document.getElementById('appSettingsModal').classList.add('active');
|
||||
}
|
||||
|
||||
closeAppSettings() {
|
||||
document.getElementById('appSettingsModal').classList.remove('active');
|
||||
}
|
||||
|
||||
async saveAppSettings() {
|
||||
const settings = {
|
||||
defaultClaudeMdPath: document.getElementById('appSettingsClaudeMdPath').value.trim(),
|
||||
defaultWorkingDir: document.getElementById('appSettingsDefaultDir').value.trim(),
|
||||
};
|
||||
|
||||
// Save to localStorage
|
||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(settings));
|
||||
|
||||
// Also save to server
|
||||
try {
|
||||
await fetch('/api/settings', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(settings)
|
||||
});
|
||||
this.showToast('Settings saved', 'success');
|
||||
} catch (err) {
|
||||
// Server save failed but localStorage succeeded
|
||||
this.showToast('Settings saved locally', 'warning');
|
||||
}
|
||||
|
||||
this.closeAppSettings();
|
||||
}
|
||||
|
||||
loadAppSettingsFromStorage() {
|
||||
try {
|
||||
const saved = localStorage.getItem('claudeman-app-settings');
|
||||
if (saved) {
|
||||
return JSON.parse(saved);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to load app settings:', err);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
async loadAppSettingsFromServer() {
|
||||
try {
|
||||
const res = await fetch('/api/settings');
|
||||
if (res.ok) {
|
||||
const settings = await res.json();
|
||||
// Merge with localStorage (server takes precedence)
|
||||
const localSettings = this.loadAppSettingsFromStorage();
|
||||
const merged = { ...localSettings, ...settings };
|
||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(merged));
|
||||
return merged;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to load settings from server:', err);
|
||||
}
|
||||
return this.loadAppSettingsFromStorage();
|
||||
}
|
||||
|
||||
// ========== Help Modal ==========
|
||||
|
||||
showHelp() {
|
||||
@@ -1310,6 +1378,7 @@ class ClaudemanApp {
|
||||
|
||||
closeAllPanels() {
|
||||
this.closeSessionOptions();
|
||||
this.closeAppSettings();
|
||||
document.getElementById('respawnPanel').classList.remove('open');
|
||||
document.getElementById('newSessionPanel').classList.remove('open');
|
||||
document.getElementById('taskPanel').classList.remove('open');
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<span class="status-text">Connecting</span>
|
||||
</div>
|
||||
<div class="header-tokens" id="headerTokens" title="Total tokens across all sessions">0 tokens</div>
|
||||
<button class="btn-icon-header" onclick="app.openAppSettings()" title="App Settings">⚙</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -272,6 +273,33 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- App Settings Modal -->
|
||||
<div class="modal" id="appSettingsModal">
|
||||
<div class="modal-backdrop" onclick="app.closeAppSettings()"></div>
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3>App Settings</h3>
|
||||
<button class="modal-close" onclick="app.closeAppSettings()">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-row">
|
||||
<label>Default CLAUDE.md Template Path</label>
|
||||
<input type="text" id="appSettingsClaudeMdPath" placeholder="/path/to/CLAUDE.md template">
|
||||
<span class="form-hint">Used when creating new cases. Leave empty for built-in template.</span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Default Working Directory</label>
|
||||
<input type="text" id="appSettingsDefaultDir" placeholder="~/projects">
|
||||
<span class="form-hint">Default directory for new sessions.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button class="btn-toolbar" onclick="app.closeAppSettings()">Cancel</button>
|
||||
<button class="btn-toolbar btn-primary" onclick="app.saveAppSettings()">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Help Button -->
|
||||
<button class="help-btn" onclick="app.showHelp()" title="Keyboard shortcuts (Ctrl+?)">?</button>
|
||||
</div>
|
||||
|
||||
@@ -187,6 +187,27 @@ body {
|
||||
font-family: 'SF Mono', Monaco, monospace;
|
||||
}
|
||||
|
||||
.btn-icon-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text-dim);
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.btn-icon-header:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--text);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
/* Session tab gear icon */
|
||||
.session-tab .tab-gear {
|
||||
opacity: 0;
|
||||
|
||||
Reference in New Issue
Block a user