diff --git a/src/serena/resources/dashboard/dashboard.css b/src/serena/resources/dashboard/dashboard.css index d320f24c..b97e02df 100644 --- a/src/serena/resources/dashboard/dashboard.css +++ b/src/serena/resources/dashboard/dashboard.css @@ -711,3 +711,43 @@ body { background: rgba(255, 68, 68, 0.2); transform: scale(1.1); } + +.language-add-btn { + padding: 6px 12px; + font-size: 13px; + font-weight: 500; + border-radius: 6px; + border: 1px dashed var(--border-color); + background: var(--bg-secondary); + color: var(--text-primary); + cursor: pointer; + transition: all 0.2s; +} + +.language-add-btn:hover { + background: var(--bg-tertiary); + border-color: var(--btn-primary); + color: var(--btn-primary); +} + +.language-spinner { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 6px 12px; +} + +.spinner { + width: 16px; + height: 16px; + border: 2px solid var(--border-color); + border-top-color: var(--btn-primary); + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} diff --git a/src/serena/resources/dashboard/dashboard.js b/src/serena/resources/dashboard/dashboard.js index fbb306b7..24eb8f93 100644 --- a/src/serena/resources/dashboard/dashboard.js +++ b/src/serena/resources/dashboard/dashboard.js @@ -83,7 +83,6 @@ class Dashboard { this.$availableToolsDisplay = $('#available-tools-display'); this.$availableModesDisplay = $('#available-modes-display'); this.$availableContextsDisplay = $('#available-contexts-display'); - this.$addLanguageBtn = $('#add-language-btn'); this.$addLanguageModal = $('#add-language-modal'); this.$modalLanguageSelect = $('#modal-language-select'); this.$modalProjectName = $('#modal-project-name'); @@ -112,7 +111,6 @@ class Dashboard { this.$themeToggle.click(this.toggleTheme.bind(this)); this.$refreshStats.click(this.loadStats.bind(this)); this.$clearStats.click(this.clearStats.bind(this)); - this.$addLanguageBtn.click(this.openLanguageModal.bind(this)); this.$modalAddBtn.click(this.addLanguageFromModal.bind(this)); this.$modalCancelBtn.click(this.closeLanguageModal.bind(this)); this.$modalClose.click(this.closeLanguageModal.bind(this)); @@ -302,6 +300,13 @@ class Dashboard { } html += ''; }); + // Add the "Add Language" button inline with language badges (only if active project exists) + if (config.active_project && config.active_project.name) { + html += ''; + html += ''; + } html += ''; } else { html += 'N/A'; @@ -328,12 +333,6 @@ class Dashboard { html += ''; - // Configuration help link - html += '
'; - html += '📖'; - html += 'View Configuration Guide'; - html += '
'; - // Active tools - collapsible html += '
'; html += '

'; @@ -362,14 +361,16 @@ class Dashboard { html += '

'; } + // Configuration help link + html += '
'; + html += '📖'; + html += 'View Configuration Guide'; + html += '
'; + this.$configDisplay.html(html); - // Show/hide add language button based on jetbrains mode - if (this.jetbrainsMode) { - this.$addLanguageBtn.hide(); - } else { - this.$addLanguageBtn.show(); - } + // Attach event handlers for the dynamically created add language button + $('#add-language-btn').click(this.openLanguageModal.bind(this)); // Attach event handlers for language remove buttons const self = this; @@ -1145,8 +1146,13 @@ class Dashboard { } const self = this; - // Disable button during request - self.$modalAddBtn.prop('disabled', true).text('Adding...'); + + // Close modal immediately + self.closeLanguageModal(); + + // Hide the inline add language button and show spinner + $('#add-language-btn').hide(); + $('#add-language-spinner').show(); $.ajax({ url: '/add_language', @@ -1157,21 +1163,21 @@ class Dashboard { }), success: function(response) { if (response.status === 'success') { - // Close modal - self.closeLanguageModal(); - // Reload config to show updated language + // Reload config to show updated language (this will restore the button) self.loadConfigOverview(); } else { alert('Error: ' + response.message); + // Restore button visibility on error + $('#add-language-btn').show(); + $('#add-language-spinner').hide(); } }, error: function(xhr, status, error) { console.error('Error adding language:', error); alert('Error adding language: ' + (xhr.responseJSON ? xhr.responseJSON.message : error)); - }, - complete: function() { - // Re-enable button - self.$modalAddBtn.prop('disabled', false).text('Add Language'); + // Restore button visibility on error + $('#add-language-btn').show(); + $('#add-language-spinner').hide(); } }); } diff --git a/src/serena/resources/dashboard/index.html b/src/serena/resources/dashboard/index.html index ccbf972d..9f4ecf8c 100644 --- a/src/serena/resources/dashboard/index.html +++ b/src/serena/resources/dashboard/index.html @@ -46,7 +46,6 @@

Current Configuration

-
Loading configuration...