diff --git a/extension.js b/extension.js index 69caa9d..1bd192c 100644 --- a/extension.js +++ b/extension.js @@ -348,6 +348,8 @@ class GitLabIssuesIndicator extends PanelMenu.Button { try { if (message.status_code === 201 || message.status_code === 200) { Main.notify(this._('GitLab Issues Timer'), `${this._('Time sent')}: ${duration} ${this._('on issue')} #${this._selectedIssue.iid}`); + } else if (message.status_code === 401 || message.status_code === 403) { + Main.notify(this._('Error'), this._('Please configure the server URL and token in preferences')); } else { Main.notify(this._('Error'), `${this._('Unable to send time')}: ${message.status_code}`); } @@ -365,6 +367,33 @@ class GitLabIssuesIndicator extends PanelMenu.Button { return; } + try { + // Pass the currently selected project if available + let dialog = new ReportDialog(this._settings, this._, this._selectedProject); + dialog.open(); + console.debug('GitLab Timer: Report dialog opened successfully'); + } catch (e) { + console.debug('GitLab Timer: Error opening report dialog: ' + e.message); + console.debug('Stack trace: ' + e.stack); + Main.notify(this._('Error'), this._('Unable to open report') + ': ' + e.message); + } + } + + _openPreferences() { + try { + const extensionManager = Main.extensionManager; + const extension = extensionManager.lookup('gitlab-time-tracker@gecka.nc'); + if (extension) { + extensionManager.openExtensionPrefs(extension.uuid, '', {}); + } else { + Main.notify(this._('Error'), this._('Extension not found')); + console.debug('GitLab Timer: Extension not found'); + } + } catch (e) { + Main.notify(this._('Error'), this._('Unable to open preferences') + ': ' + e.message); + console.debug('GitLab Timer: Error opening preferences:', e.message); + console.debug('GitLab Timer: Stack:', e.stack); + } // Pass the currently selected project if available let dialog = new ReportDialog(this._settings, this._, this._selectedProject); dialog.open(); diff --git a/issueSelector.js b/issueSelector.js index e3ccc06..29ca7c3 100644 --- a/issueSelector.js +++ b/issueSelector.js @@ -152,36 +152,51 @@ class IssueSelectorDialog extends ModalDialog.ModalDialog { _loadProjects() { this._showLoading(this._('Loading projects...')); - const url = this._settings.get_string('gitlab-url'); - const token = this._settings.get_string('gitlab-token'); - - const apiUrl = `${url}/api/v4/projects?membership=true&per_page=100&order_by=last_activity_at`; - - const message = Soup.Message.new('GET', apiUrl); - message.request_headers.append('PRIVATE-TOKEN', token); - - this._httpSession.send_and_read_async( - message, - GLib.PRIORITY_DEFAULT, - null, - (session, result) => { - try { - const bytes = session.send_and_read_finish(result); - const decoder = new TextDecoder('utf-8'); - const response = decoder.decode(bytes.get_data()); - - if (message.status_code === 200) { - this._projects = JSON.parse(response); - this._updateProjectList(); - this._hideLoading(); - } else { - this._showLoading(`${this._('Error')}: ${message.status_code}`); + try { + const url = this._settings.get_string('gitlab-url'); + const token = this._settings.get_string('gitlab-token'); + const apiUrl = `${url}/api/v4/projects?membership=true&per_page=100&order_by=last_activity_at`; + + console.debug('GitLab Issue Selector: Fetching projects'); + + const message = Soup.Message.new('GET', apiUrl); + message.request_headers.append('PRIVATE-TOKEN', token); + + this._httpSession.send_and_read_async( + message, + GLib.PRIORITY_DEFAULT, + null, + (session, result) => { + let response = ''; + try { + const bytes = session.send_and_read_finish(result); + const decoder = new TextDecoder('utf-8'); + response = decoder.decode(bytes.get_data()); + + if (message.status_code === 200) { + this._projects = JSON.parse(response); + this._updateProjectList(); + this._hideLoading(); + } else if (message.status_code === 401 || message.status_code === 403) { + const authMessage = this._('Please configure the server URL and token in preferences'); + this._projects = []; + this._updateProjectList(); + this._showLoading(authMessage); + Main.notify(this._('Error'), authMessage); + } else { + console.debug(`GitLab Issue Selector: Error fetching projects: ${message.status_code}`); + this._showLoading(`${this._('Error')}: ${message.status_code}`); + } + } catch (e) { + console.debug(`GitLab Issue Selector: Error parsing projects: ${e.message}`); + this._showLoading(`${this._('Error')}: ${e.message}`); } - } catch (e) { - this._showLoading(`${this._('Error')}: ${e.message}`); } - } - ); + ); + } catch (e) { + console.debug(`GitLab Issue Selector: Error loading projects: ${e.message}`); + this._showLoading(`${this._('Error')}: ${e.message}`); + } } _updateProjectList() { @@ -284,6 +299,12 @@ class IssueSelectorDialog extends ModalDialog.ModalDialog { this._allIssues = JSON.parse(response); this._updateIssueList(); this._hideLoading(); + } else if (message.status_code === 401 || message.status_code === 403) { + const authMessage = this._('Please configure the server URL and token in preferences'); + this._allIssues = []; + this._updateIssueList(); + this._showLoading(authMessage); + Main.notify(this._('Error'), authMessage); } else { this._showLoading(`${this._('Error')}: ${message.status_code}`); } diff --git a/reportDialog.js b/reportDialog.js index 3bfe57e..a4f5f6c 100644 --- a/reportDialog.js +++ b/reportDialog.js @@ -299,6 +299,10 @@ class ReportDialog extends ModalDialog.ModalDialog { this._selectProject(project, null); } } + } else if (message.status_code === 401 || message.status_code === 403) { + const authMessage = this._('Please configure the server URL and token in preferences'); + this._projects = []; + Main.notify(this._('Error'), authMessage); } else { Main.notify(this._('Error'), `${this._('Unable to load projects')}: ${message.status_code}`); } @@ -448,6 +452,9 @@ class ReportDialog extends ModalDialog.ModalDialog { if (message.status_code === 200) { const issues = JSON.parse(response); this._processReportData(issues); + } else if (message.status_code === 401 || message.status_code === 403) { + this._hideLoading(); + Main.notify(this._('Error'), this._('Please configure the server URL and token in preferences')); } else { this._hideLoading(); Main.notify(this._('Error'), `${this._('Unable to load report')}: ${message.status_code}`);