From f1459245f7d33cacef224d14ffea52e9859dd256 Mon Sep 17 00:00:00 2001 From: Cindy Halim Date: Fri, 24 May 2024 16:20:15 -0400 Subject: [PATCH 1/9] Show alert on web IDE start error --- .../javascripts/ide/init_gitlab_web_ide.js | 109 ++++++++++-------- locale/gitlab.pot | 6 + spec/frontend/ide/init_gitlab_web_ide_spec.js | 24 ++++ 3 files changed, 92 insertions(+), 47 deletions(-) diff --git a/app/assets/javascripts/ide/init_gitlab_web_ide.js b/app/assets/javascripts/ide/init_gitlab_web_ide.js index 74fc00432d18d1..ba71331e9313a5 100644 --- a/app/assets/javascripts/ide/init_gitlab_web_ide.js +++ b/app/assets/javascripts/ide/init_gitlab_web_ide.js @@ -6,6 +6,7 @@ import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action'; import { createAndSubmitForm } from '~/lib/utils/create_and_submit_form'; import csrf from '~/lib/utils/csrf'; import Tracking from '~/tracking'; +import { createAlert } from '../alert'; import { getBaseConfig, getOAuthConfig, @@ -75,54 +76,68 @@ export const initGitlabWebIDE = async (el) => { 'X-Requested-With': 'XMLHttpRequest', }; - // See ClientOnlyConfig https://gitlab.com/gitlab-org/gitlab-web-ide/-/blob/main/packages/web-ide-types/src/config.ts#L17 - start(rootEl, { - ...getBaseConfig(), - nonce, - httpHeaders, - auth: oauthConfig, - projectPath, - ref, - filePath, - mrId, - mrTargetProject: getMRTargetProject(), - forkInfo, - username: gon.current_username, - links: { - feedbackIssue: GITLAB_WEB_IDE_FEEDBACK_ISSUE, - userPreferences: el.dataset.userPreferencesPath, - signIn: el.dataset.signInPath, - }, - featureFlags: { - settingsSync: true, - crossOriginExtensionHost: getCrossOriginExtensionHostFlagValue(extensionsGallerySettings), - }, - editorFont, - extensionsGallerySettings, - codeSuggestionsEnabled, - handleTracking, - // See https://gitlab.com/gitlab-org/gitlab-web-ide/-/blob/main/packages/web-ide-types/src/config.ts#L86 - telemetryEnabled: Tracking.enabled(), - async handleStartRemote({ remoteHost, remotePath, connectionToken }) { - const confirmed = await confirmAction( - __('Are you sure you want to leave the Web IDE? All unsaved changes will be lost.'), - { - primaryBtnText: __('Start remote connection'), - cancelBtnText: __('Continue editing'), - }, - ); + try { + // See ClientOnlyConfig https://gitlab.com/gitlab-org/gitlab-web-ide/-/blob/main/packages/web-ide-types/src/config.ts#L17 + await start(rootEl, { + ...getBaseConfig(), + nonce, + httpHeaders, + auth: oauthConfig, + projectPath, + ref, + filePath, + mrId, + mrTargetProject: getMRTargetProject(), + forkInfo, + username: gon.current_username, + links: { + feedbackIssue: GITLAB_WEB_IDE_FEEDBACK_ISSUE, + userPreferences: el.dataset.userPreferencesPath, + signIn: el.dataset.signInPath, + }, + featureFlags: { + settingsSync: true, + crossOriginExtensionHost: getCrossOriginExtensionHostFlagValue(extensionsGallerySettings), + }, + editorFont, + extensionsGallerySettings, + codeSuggestionsEnabled, + handleTracking, + // See https://gitlab.com/gitlab-org/gitlab-web-ide/-/blob/main/packages/web-ide-types/src/config.ts#L86 + telemetryEnabled: Tracking.enabled(), + async handleStartRemote({ remoteHost, remotePath, connectionToken }) { + const confirmed = await confirmAction( + __('Are you sure you want to leave the Web IDE? All unsaved changes will be lost.'), + { + primaryBtnText: __('Start remote connection'), + cancelBtnText: __('Continue editing'), + }, + ); - if (!confirmed) { - return; - } + if (!confirmed) { + return; + } - createAndSubmitForm({ - url: buildRemoteIdeURL(ideRemotePath, remoteHost, remotePath), - data: { - connection_token: connectionToken, - return_url: window.location.href, + createAndSubmitForm({ + url: buildRemoteIdeURL(ideRemotePath, remoteHost, remotePath), + data: { + connection_token: connectionToken, + return_url: window.location.href, + }, + }); + }, + }); + } catch (e) { + createAlert({ + message: __('Failed to load GitLab IDE. Please try again.'), + primaryButton: { + text: __('Reload'), + attributes: { + onClick: () => window.location.reload(), }, - }); - }, - }); + }, + captureError: true, + error: e, + }); + } }; diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a81ce9a2d59c00..4db59439f1c9ba 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -21796,6 +21796,9 @@ msgstr "" msgid "Failed to load" msgstr "" +msgid "Failed to load GitLab IDE. Please try again." +msgstr "" + msgid "Failed to load Roadmap" msgstr "" @@ -43420,6 +43423,9 @@ msgstr "" msgid "Release|You can edit the content later by editing the release. %{linkStart}How do I edit a release?%{linkEnd}" msgstr "" +msgid "Reload" +msgstr "" + msgid "Reload page" msgstr "" diff --git a/spec/frontend/ide/init_gitlab_web_ide_spec.js b/spec/frontend/ide/init_gitlab_web_ide_spec.js index 453bad21e4a28c..b067e69932aff9 100644 --- a/spec/frontend/ide/init_gitlab_web_ide_spec.js +++ b/spec/frontend/ide/init_gitlab_web_ide_spec.js @@ -1,4 +1,5 @@ import { start } from '@gitlab/web-ide'; +import { createAlert } from '~/alert'; import { GITLAB_WEB_IDE_FEEDBACK_ISSUE } from '~/ide/constants'; import { initGitlabWebIDE } from '~/ide/init_gitlab_web_ide'; import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action'; @@ -18,6 +19,7 @@ jest.mock('~/lib/utils/csrf', () => ({ headerKey: 'mock-csrf-header', })); jest.mock('~/tracking'); +jest.mock('~/alert'); const ROOT_ELEMENT_ID = 'ide'; const TEST_NONCE = 'test123nonce'; @@ -272,6 +274,28 @@ describe('ide/init_gitlab_web_ide', () => { }); }); + describe('on start error', () => { + const mockError = new Error('error'); + beforeEach(() => { + jest.mocked(start).mockImplementationOnce(() => { + throw mockError; + }); + + createSubject(); + }); + + it('shows alert', () => { + expect(start).toHaveBeenCalledTimes(1); + expect(createAlert).toHaveBeenCalledTimes(1); + expect(createAlert).toHaveBeenCalledWith( + expect.objectContaining({ + captureError: true, + error: mockError, + }), + ); + }); + }); + describe('when extensionsGallerySettings is in dataset', () => { function setMockExtensionGallerySettingsDataset( mockSettings = TEST_EXTENSIONS_GALLERY_SETTINGS, -- GitLab From 469c8a9014d32bbf467d6c4df01c1dca7832ef79 Mon Sep 17 00:00:00 2001 From: Cindy Halim Date: Tue, 28 May 2024 09:56:55 -0400 Subject: [PATCH 2/9] Log error to console --- app/assets/javascripts/ide/init_gitlab_web_ide.js | 2 ++ spec/frontend/ide/init_gitlab_web_ide_spec.js | 3 +++ 2 files changed, 5 insertions(+) diff --git a/app/assets/javascripts/ide/init_gitlab_web_ide.js b/app/assets/javascripts/ide/init_gitlab_web_ide.js index ba71331e9313a5..2c50ed466bd228 100644 --- a/app/assets/javascripts/ide/init_gitlab_web_ide.js +++ b/app/assets/javascripts/ide/init_gitlab_web_ide.js @@ -1,5 +1,6 @@ import { start } from '@gitlab/web-ide'; import { __ } from '~/locale'; +import { logError } from '~/lib/logger'; import { cleanLeadingSeparator } from '~/lib/utils/url_utility'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action'; @@ -128,6 +129,7 @@ export const initGitlabWebIDE = async (el) => { }, }); } catch (e) { + logError('Failed to load GitLab IDE', e); createAlert({ message: __('Failed to load GitLab IDE. Please try again.'), primaryButton: { diff --git a/spec/frontend/ide/init_gitlab_web_ide_spec.js b/spec/frontend/ide/init_gitlab_web_ide_spec.js index b067e69932aff9..99a091757bf3f7 100644 --- a/spec/frontend/ide/init_gitlab_web_ide_spec.js +++ b/spec/frontend/ide/init_gitlab_web_ide_spec.js @@ -1,5 +1,6 @@ import { start } from '@gitlab/web-ide'; import { createAlert } from '~/alert'; +import { logError } from '~/lib/logger'; import { GITLAB_WEB_IDE_FEEDBACK_ISSUE } from '~/ide/constants'; import { initGitlabWebIDE } from '~/ide/init_gitlab_web_ide'; import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action'; @@ -20,6 +21,7 @@ jest.mock('~/lib/utils/csrf', () => ({ })); jest.mock('~/tracking'); jest.mock('~/alert'); +jest.mock('~/lib/logger'); const ROOT_ELEMENT_ID = 'ide'; const TEST_NONCE = 'test123nonce'; @@ -286,6 +288,7 @@ describe('ide/init_gitlab_web_ide', () => { it('shows alert', () => { expect(start).toHaveBeenCalledTimes(1); + expect(logError).toHaveBeenCalledWith('Failed to load GitLab IDE', mockError); expect(createAlert).toHaveBeenCalledTimes(1); expect(createAlert).toHaveBeenCalledWith( expect.objectContaining({ -- GitLab From a7f6cf7c033434ac2344f59211a5647ab64e5f83 Mon Sep 17 00:00:00 2001 From: Cindy Halim Date: Wed, 29 May 2024 12:27:10 -0400 Subject: [PATCH 3/9] Add containerClasses option to createAlert --- app/assets/javascripts/alert.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/javascripts/alert.js b/app/assets/javascripts/alert.js index fd20d216385352..8d0c6e5837d29d 100644 --- a/app/assets/javascripts/alert.js +++ b/app/assets/javascripts/alert.js @@ -48,6 +48,7 @@ export const VARIANT_TIP = 'tip'; * @param {object} [options.parent] - Reference to parent element under which alert needs to appear. Defaults to `document`. * @param {Function} [options.onDismiss] - Handler to call when this alert is dismissed. * @param {string} [options.containerSelector] - Selector for the container of the alert + * @param {string} [options.containerClasses] - Array of classes to add to the container of the alert * @param {boolean} [options.preservePrevious] - Set to `true` to preserve previous alerts. Defaults to `false`. * @param {object} [options.primaryButton] - Object describing primary button of alert * @param {string} [options.primaryButton.link] - Href of primary button @@ -67,6 +68,7 @@ export const createAlert = ({ variant = VARIANT_DANGER, parent = document, containerSelector = '.flash-container', + containerClasses = [], preservePrevious = false, primaryButton = null, secondaryButton = null, @@ -80,6 +82,8 @@ export const createAlert = ({ const alertContainer = parent.querySelector(containerSelector); if (!alertContainer) return null; + alertContainer.classList.add(...containerClasses); + const el = document.createElement('div'); if (preservePrevious) { alertContainer.appendChild(el); -- GitLab From a1aec08982d73966ee4c579cb6c59f49fc4ebe58 Mon Sep 17 00:00:00 2001 From: Cindy Halim Date: Wed, 29 May 2024 12:29:38 -0400 Subject: [PATCH 4/9] Apply styling and copy suggestions --- app/assets/javascripts/ide/init_gitlab_web_ide.js | 5 ++++- locale/gitlab.pot | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/ide/init_gitlab_web_ide.js b/app/assets/javascripts/ide/init_gitlab_web_ide.js index 2c50ed466bd228..41df4cdd4a7539 100644 --- a/app/assets/javascripts/ide/init_gitlab_web_ide.js +++ b/app/assets/javascripts/ide/init_gitlab_web_ide.js @@ -131,7 +131,10 @@ export const initGitlabWebIDE = async (el) => { } catch (e) { logError('Failed to load GitLab IDE', e); createAlert({ - message: __('Failed to load GitLab IDE. Please try again.'), + containerClasses: ['gl-max-w-80', 'm-auto', 'gl-pt-6'], + message: __( + 'Failed to load GitLab IDE: see the developer console for more information. Reload the page or sign out to try again.', + ), primaryButton: { text: __('Reload'), attributes: { diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 4db59439f1c9ba..a2175e8ff8d82b 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -21796,7 +21796,7 @@ msgstr "" msgid "Failed to load" msgstr "" -msgid "Failed to load GitLab IDE. Please try again." +msgid "Failed to load GitLab IDE: see the developer console for more information. Reload the page or sign out to try again." msgstr "" msgid "Failed to load Roadmap" -- GitLab From c2c624e59c9c8e60b19c3108cd0f630af78fd457 Mon Sep 17 00:00:00 2001 From: Cindy Halim Date: Thu, 30 May 2024 09:42:34 -0400 Subject: [PATCH 5/9] Apply doc and copy suggestions Add report an issue topic in Web IDE docs. Apply copy suggestions --- app/assets/javascripts/ide/init_gitlab_web_ide.js | 13 ++++++++++--- doc/user/project/web_ide/index.md | 11 +++++++++++ locale/gitlab.pot | 7 +++++-- spec/frontend/ide/init_gitlab_web_ide_spec.js | 2 +- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/ide/init_gitlab_web_ide.js b/app/assets/javascripts/ide/init_gitlab_web_ide.js index 41df4cdd4a7539..4ec3a8adc6eabe 100644 --- a/app/assets/javascripts/ide/init_gitlab_web_ide.js +++ b/app/assets/javascripts/ide/init_gitlab_web_ide.js @@ -1,7 +1,7 @@ import { start } from '@gitlab/web-ide'; import { __ } from '~/locale'; import { logError } from '~/lib/logger'; -import { cleanLeadingSeparator } from '~/lib/utils/url_utility'; +import { cleanLeadingSeparator, DOCS_URL_IN_EE_DIR } from '~/lib/utils/url_utility'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action'; import { createAndSubmitForm } from '~/lib/utils/create_and_submit_form'; @@ -129,12 +129,19 @@ export const initGitlabWebIDE = async (el) => { }, }); } catch (e) { - logError('Failed to load GitLab IDE', e); + logError(__('Failed to load Web IDE'), e); createAlert({ containerClasses: ['gl-max-w-80', 'm-auto', 'gl-pt-6'], + title: __('Failed to load Web IDE'), message: __( - 'Failed to load GitLab IDE: see the developer console for more information. Reload the page or sign out to try again.', + 'See the developer console for more information. Reload the page, or sign out then in again, and try loading the Web IDE again. If the problem persists, %{issueLinkStart}report an issue%{issueLinkEnd}.', ), + messageLinks: { + issueLink: { + href: `${DOCS_URL_IN_EE_DIR}/user/project/web_ide/#report-an-issue`, + target: '_blank', + }, + }, primaryButton: { text: __('Reload'), attributes: { diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md index 489b8faea40066..5a26aa75a2e4c8 100644 --- a/doc/user/project/web_ide/index.md +++ b/doc/user/project/web_ide/index.md @@ -280,3 +280,14 @@ As a workaround: or modify the `"editor.fontFamily"` setting. For more information, see [VS Code issue 80170](https://github.com/microsoft/vscode/issues/80170). + +## Report an issue + +Open a new issue with the following information: + +1. The error message. +1. The expanded error details. +1. How often the problem occurs. +1. Steps to reproduce the problem. + +If you need additional help and you’re on a paid tier, you can [request support](https://about.gitlab.com/support). diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a2175e8ff8d82b..d09497e2d740c4 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -21796,10 +21796,10 @@ msgstr "" msgid "Failed to load" msgstr "" -msgid "Failed to load GitLab IDE: see the developer console for more information. Reload the page or sign out to try again." +msgid "Failed to load Roadmap" msgstr "" -msgid "Failed to load Roadmap" +msgid "Failed to load Web IDE" msgstr "" msgid "Failed to load assignees. Please try again." @@ -48503,6 +48503,9 @@ msgstr "" msgid "See the affected projects in the GitLab admin panel" msgstr "" +msgid "See the developer console for more information. Reload the page, or sign out then in again, and try loading the Web IDE again. If the problem persists, %{issueLinkStart}report an issue%{issueLinkEnd}." +msgstr "" + msgid "See vulnerability %{vulnerability_link} for any Remediation details." msgstr "" diff --git a/spec/frontend/ide/init_gitlab_web_ide_spec.js b/spec/frontend/ide/init_gitlab_web_ide_spec.js index 99a091757bf3f7..70fe016b0a8058 100644 --- a/spec/frontend/ide/init_gitlab_web_ide_spec.js +++ b/spec/frontend/ide/init_gitlab_web_ide_spec.js @@ -288,7 +288,7 @@ describe('ide/init_gitlab_web_ide', () => { it('shows alert', () => { expect(start).toHaveBeenCalledTimes(1); - expect(logError).toHaveBeenCalledWith('Failed to load GitLab IDE', mockError); + expect(logError).toHaveBeenCalledWith('Failed to load Web IDE', mockError); expect(createAlert).toHaveBeenCalledTimes(1); expect(createAlert).toHaveBeenCalledWith( expect.objectContaining({ -- GitLab From ae505a382c3c6d7a8b3b00467c14a803675304e1 Mon Sep 17 00:00:00 2001 From: Cindy Halim Date: Mon, 3 Jun 2024 09:26:04 -0400 Subject: [PATCH 6/9] New Web IDE error alert component New Web IDE error alert component based on UX feedback. --- .../ide/components/web_ide_error.vue | 54 +++++++++++++++++++ app/views/ide/_show.html.haml | 2 +- locale/gitlab.pot | 7 ++- .../ide/components/web_ide_error_spec.js | 39 ++++++++++++++ 4 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 app/assets/javascripts/ide/components/web_ide_error.vue create mode 100644 spec/frontend/ide/components/web_ide_error_spec.js diff --git a/app/assets/javascripts/ide/components/web_ide_error.vue b/app/assets/javascripts/ide/components/web_ide_error.vue new file mode 100644 index 00000000000000..87030d6be8ae34 --- /dev/null +++ b/app/assets/javascripts/ide/components/web_ide_error.vue @@ -0,0 +1,54 @@ + + diff --git a/app/views/ide/_show.html.haml b/app/views/ide/_show.html.haml index 7a14c270ae6698..310bbab1aec634 100644 --- a/app/views/ide/_show.html.haml +++ b/app/views/ide/_show.html.haml @@ -18,4 +18,4 @@ - data = ide_data(project: @project, fork_info: @fork_info, params: params) -= render partial: 'shared/ide_root', locals: { data: data, loading_text: _('Loading the GitLab IDE') } += render partial: 'shared/ide_root', locals: { data: data, loading_text: _('Loading the Web IDE') } diff --git a/locale/gitlab.pot b/locale/gitlab.pot index d09497e2d740c4..6d6650d8105c79 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -31066,7 +31066,7 @@ msgstr "" msgid "Loading snippet" msgstr "" -msgid "Loading the GitLab IDE" +msgid "Loading the Web IDE" msgstr "" msgid "Loading..." @@ -48503,7 +48503,7 @@ msgstr "" msgid "See the affected projects in the GitLab admin panel" msgstr "" -msgid "See the developer console for more information. Reload the page, or sign out then in again, and try loading the Web IDE again. If the problem persists, %{issueLinkStart}report an issue%{issueLinkEnd}." +msgid "See the developer console for more information. Reload the page, or sign out then in again, and try loading the Web IDE again. If the problem persists, %{reportIssue}." msgstr "" msgid "See vulnerability %{vulnerability_link} for any Remediation details." @@ -63320,6 +63320,9 @@ msgstr "" msgid "reply should have same confidentiality as top-level note" msgstr "" +msgid "report an issue" +msgstr "" + msgid "repositories" msgstr "" diff --git a/spec/frontend/ide/components/web_ide_error_spec.js b/spec/frontend/ide/components/web_ide_error_spec.js new file mode 100644 index 00000000000000..a95a4fb6eb721c --- /dev/null +++ b/spec/frontend/ide/components/web_ide_error_spec.js @@ -0,0 +1,39 @@ +import { GlAlert, GlButton } from '@gitlab/ui'; +import { mount } from '@vue/test-utils'; +import WebIdeError from '~/ide/components/web_ide_error.vue'; +import { useMockLocationHelper } from 'helpers/mock_window_location_helper'; + +const findButtons = (wrapper) => wrapper.findAllComponents(GlButton); + +describe('WebIdeError', () => { + let wrapper; + useMockLocationHelper(); + function createWrapper() { + wrapper = mount(WebIdeError); + } + + it('renders alert component', () => { + createWrapper(); + const alert = wrapper.findComponent(GlAlert); + + expect(alert.exists()).toBe(true); + expect(alert.props('title')).toContain('Failed to load Web IDE'); + }); + + it('renders reload page button', () => { + createWrapper(); + const reloadButton = findButtons(wrapper).at(0); + + expect(reloadButton.exists()).toBe(true); + + reloadButton.vm.$emit('click'); + expect(window.location.reload).toHaveBeenCalled(); + }); + + it('renders sign out button', () => { + createWrapper(); + const signOutButton = findButtons(wrapper).at(1); + + expect(signOutButton.exists()).toBe(true); + }); +}); -- GitLab From 82fea4d6c4055b62c51bf5e411d448c97a318da7 Mon Sep 17 00:00:00 2001 From: Cindy Halim Date: Mon, 3 Jun 2024 09:40:23 -0400 Subject: [PATCH 7/9] Use new Web IDE error component Use new Web IDE error component instead of createAlert. --- app/assets/javascripts/alert.js | 4 --- .../javascripts/ide/init_gitlab_web_ide.js | 28 ++--------------- .../javascripts/ide/render_web_ide_error.js | 23 ++++++++++++++ spec/frontend/ide/init_gitlab_web_ide_spec.js | 16 +++------- .../frontend/ide/render_web_ide_error_spec.js | 30 +++++++++++++++++++ 5 files changed, 60 insertions(+), 41 deletions(-) create mode 100644 app/assets/javascripts/ide/render_web_ide_error.js create mode 100644 spec/frontend/ide/render_web_ide_error_spec.js diff --git a/app/assets/javascripts/alert.js b/app/assets/javascripts/alert.js index 8d0c6e5837d29d..fd20d216385352 100644 --- a/app/assets/javascripts/alert.js +++ b/app/assets/javascripts/alert.js @@ -48,7 +48,6 @@ export const VARIANT_TIP = 'tip'; * @param {object} [options.parent] - Reference to parent element under which alert needs to appear. Defaults to `document`. * @param {Function} [options.onDismiss] - Handler to call when this alert is dismissed. * @param {string} [options.containerSelector] - Selector for the container of the alert - * @param {string} [options.containerClasses] - Array of classes to add to the container of the alert * @param {boolean} [options.preservePrevious] - Set to `true` to preserve previous alerts. Defaults to `false`. * @param {object} [options.primaryButton] - Object describing primary button of alert * @param {string} [options.primaryButton.link] - Href of primary button @@ -68,7 +67,6 @@ export const createAlert = ({ variant = VARIANT_DANGER, parent = document, containerSelector = '.flash-container', - containerClasses = [], preservePrevious = false, primaryButton = null, secondaryButton = null, @@ -82,8 +80,6 @@ export const createAlert = ({ const alertContainer = parent.querySelector(containerSelector); if (!alertContainer) return null; - alertContainer.classList.add(...containerClasses); - const el = document.createElement('div'); if (preservePrevious) { alertContainer.appendChild(el); diff --git a/app/assets/javascripts/ide/init_gitlab_web_ide.js b/app/assets/javascripts/ide/init_gitlab_web_ide.js index 4ec3a8adc6eabe..6e546c1faa2804 100644 --- a/app/assets/javascripts/ide/init_gitlab_web_ide.js +++ b/app/assets/javascripts/ide/init_gitlab_web_ide.js @@ -1,13 +1,11 @@ import { start } from '@gitlab/web-ide'; import { __ } from '~/locale'; -import { logError } from '~/lib/logger'; -import { cleanLeadingSeparator, DOCS_URL_IN_EE_DIR } from '~/lib/utils/url_utility'; +import { cleanLeadingSeparator } from '~/lib/utils/url_utility'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action'; import { createAndSubmitForm } from '~/lib/utils/create_and_submit_form'; import csrf from '~/lib/utils/csrf'; import Tracking from '~/tracking'; -import { createAlert } from '../alert'; import { getBaseConfig, getOAuthConfig, @@ -15,6 +13,7 @@ import { handleTracking, } from './lib/gitlab_web_ide'; import { GITLAB_WEB_IDE_FEEDBACK_ISSUE } from './constants'; +import { renderWebIdeError } from './render_web_ide_error'; const buildRemoteIdeURL = (ideRemotePath, remoteHost, remotePathArg) => { const remotePath = cleanLeadingSeparator(remotePathArg); @@ -129,27 +128,6 @@ export const initGitlabWebIDE = async (el) => { }, }); } catch (e) { - logError(__('Failed to load Web IDE'), e); - createAlert({ - containerClasses: ['gl-max-w-80', 'm-auto', 'gl-pt-6'], - title: __('Failed to load Web IDE'), - message: __( - 'See the developer console for more information. Reload the page, or sign out then in again, and try loading the Web IDE again. If the problem persists, %{issueLinkStart}report an issue%{issueLinkEnd}.', - ), - messageLinks: { - issueLink: { - href: `${DOCS_URL_IN_EE_DIR}/user/project/web_ide/#report-an-issue`, - target: '_blank', - }, - }, - primaryButton: { - text: __('Reload'), - attributes: { - onClick: () => window.location.reload(), - }, - }, - captureError: true, - error: e, - }); + renderWebIdeError(e); } }; diff --git a/app/assets/javascripts/ide/render_web_ide_error.js b/app/assets/javascripts/ide/render_web_ide_error.js new file mode 100644 index 00000000000000..6313684382c324 --- /dev/null +++ b/app/assets/javascripts/ide/render_web_ide_error.js @@ -0,0 +1,23 @@ +import Vue from 'vue'; +import { __ } from '~/locale'; +import { logError } from '~/lib/logger'; +import WebIdeError from '~/ide/components/web_ide_error.vue'; +import * as Sentry from '~/sentry/sentry_browser_wrapper'; + +export function renderWebIdeError(error) { + logError(__('Failed to load Web IDE'), error); + Sentry.captureException(error); + + const alertContainer = document.querySelector('.flash-container'); + if (!alertContainer) return null; + + const el = document.createElement('div'); + alertContainer.appendChild(el); + + return new Vue({ + el, + render(createElement) { + return createElement(WebIdeError); + }, + }); +} diff --git a/spec/frontend/ide/init_gitlab_web_ide_spec.js b/spec/frontend/ide/init_gitlab_web_ide_spec.js index 70fe016b0a8058..71680016337922 100644 --- a/spec/frontend/ide/init_gitlab_web_ide_spec.js +++ b/spec/frontend/ide/init_gitlab_web_ide_spec.js @@ -1,6 +1,4 @@ import { start } from '@gitlab/web-ide'; -import { createAlert } from '~/alert'; -import { logError } from '~/lib/logger'; import { GITLAB_WEB_IDE_FEEDBACK_ISSUE } from '~/ide/constants'; import { initGitlabWebIDE } from '~/ide/init_gitlab_web_ide'; import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action'; @@ -10,6 +8,7 @@ import Tracking from '~/tracking'; import { TEST_HOST } from 'helpers/test_constants'; import setWindowLocation from 'helpers/set_window_location_helper'; import waitForPromises from 'helpers/wait_for_promises'; +import { renderWebIdeError } from '~/ide/render_web_ide_error'; import { getMockCallbackUrl } from './helpers'; jest.mock('@gitlab/web-ide'); @@ -20,8 +19,7 @@ jest.mock('~/lib/utils/csrf', () => ({ headerKey: 'mock-csrf-header', })); jest.mock('~/tracking'); -jest.mock('~/alert'); -jest.mock('~/lib/logger'); +jest.mock('~/ide/render_web_ide_error'); const ROOT_ELEMENT_ID = 'ide'; const TEST_NONCE = 'test123nonce'; @@ -288,14 +286,8 @@ describe('ide/init_gitlab_web_ide', () => { it('shows alert', () => { expect(start).toHaveBeenCalledTimes(1); - expect(logError).toHaveBeenCalledWith('Failed to load Web IDE', mockError); - expect(createAlert).toHaveBeenCalledTimes(1); - expect(createAlert).toHaveBeenCalledWith( - expect.objectContaining({ - captureError: true, - error: mockError, - }), - ); + expect(renderWebIdeError).toHaveBeenCalledTimes(1); + expect(renderWebIdeError).toHaveBeenCalledWith(mockError); }); }); diff --git a/spec/frontend/ide/render_web_ide_error_spec.js b/spec/frontend/ide/render_web_ide_error_spec.js new file mode 100644 index 00000000000000..e74eee862f7994 --- /dev/null +++ b/spec/frontend/ide/render_web_ide_error_spec.js @@ -0,0 +1,30 @@ +import * as Sentry from '~/sentry/sentry_browser_wrapper'; +import { renderWebIdeError } from '~/ide/render_web_ide_error'; +import { logError } from '~/lib/logger'; + +jest.mock('~/sentry/sentry_browser_wrapper'); +jest.mock('~/sentry/sentry_browser_wrapper'); +jest.mock('~/lib/logger'); + +describe('render web IDE error', () => { + const MOCK_ERROR = new Error('error'); + let webIdeError; + + it('logs error to Sentry', () => { + webIdeError = renderWebIdeError(MOCK_ERROR); + expect(Sentry.captureException).toHaveBeenCalledWith(MOCK_ERROR); + }); + + it('logs error to console', () => { + webIdeError = renderWebIdeError(MOCK_ERROR); + expect(logError).toHaveBeenCalledWith('Failed to load Web IDE', MOCK_ERROR); + }); + + describe('no .flash-container', () => { + it('does not add to the DOM', () => { + webIdeError = renderWebIdeError(MOCK_ERROR); + + expect(webIdeError).toBeNull(); + }); + }); +}); -- GitLab From d5f51e1b6f7cb665614619187d60eb215459e354 Mon Sep 17 00:00:00 2001 From: Cindy Halim Date: Tue, 4 Jun 2024 14:16:07 +0000 Subject: [PATCH 8/9] Apply copy suggestions Apply copy suggestions based on technical writer feedback. --- .../javascripts/ide/components/web_ide_error.vue | 8 ++++---- doc/user/project/web_ide/index.md | 15 ++++++++------- locale/gitlab.pot | 11 +++++++---- .../frontend/ide/components/web_ide_error_spec.js | 1 - 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/ide/components/web_ide_error.vue b/app/assets/javascripts/ide/components/web_ide_error.vue index 87030d6be8ae34..a7ecf3e29a67df 100644 --- a/app/assets/javascripts/ide/components/web_ide_error.vue +++ b/app/assets/javascripts/ide/components/web_ide_error.vue @@ -15,15 +15,15 @@ export default { reload: () => window.location.reload(), }, i18n: { - title: __('Failed to load Web IDE'), + title: __('Failed to load the Web IDE'), message: __( - 'See the developer console for more information. Reload the page, or sign out then in again, and try loading the Web IDE again. If the problem persists, %{reportIssue}.', + 'For more information, see the developer console. Try to reload the page or sign out and in again. If the issue persists, %{reportIssue}.', ), - linkText: __('report an issue'), + linkText: __('report a problem'), primaryButtonText: __('Reload'), secondaryButtonText: __('Sign out'), }, - REPORT_ISSUE_URL: `${DOCS_URL_IN_EE_DIR}/user/project/web_ide/#report-an-issue`, + REPORT_ISSUE_URL: `${DOCS_URL_IN_EE_DIR}/user/project/web_ide/#report-a-problem`, SIGN_OUT_URL: '/users/sign_out', }; diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md index 5a26aa75a2e4c8..b0abe2bf12a4de 100644 --- a/doc/user/project/web_ide/index.md +++ b/doc/user/project/web_ide/index.md @@ -281,13 +281,14 @@ As a workaround: For more information, see [VS Code issue 80170](https://github.com/microsoft/vscode/issues/80170). -## Report an issue +### Report a problem -Open a new issue with the following information: +To report a problem, [create a new issue](https://gitlab.com/gitlab-org/gitlab-web-ide/-/issues/new) +with the following information: -1. The error message. -1. The expanded error details. -1. How often the problem occurs. -1. Steps to reproduce the problem. +- The error message +- The full error details +- How often the problem occurs +- Steps to reproduce the problem -If you need additional help and you’re on a paid tier, you can [request support](https://about.gitlab.com/support). +If you're on a paid tier, you can also [contact Support](https://about.gitlab.com/support/#contact-support) for help. diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 6d6650d8105c79..c458d5e771d7e9 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -21844,6 +21844,9 @@ msgstr "" msgid "Failed to load stacktrace." msgstr "" +msgid "Failed to load the Web IDE" +msgstr "" + msgid "Failed to make repository read-only: %{reason}" msgstr "" @@ -22553,6 +22556,9 @@ msgstr "" msgid "For more information, see the File Hooks documentation." msgstr "" +msgid "For more information, see the developer console. Try to reload the page or sign out and in again. If the issue persists, %{reportIssue}." +msgstr "" + msgid "For the GitLab Team to keep your subscription data up to date, this is a reminder to report your license usage on a monthly basis, or at the cadence set in your agreement with GitLab. This allows us to simplify the billing process for overages and renewals. To report your usage data, export your license usage file and email it to %{renewal_service_email}. If you need an updated license, GitLab will send the license to the email address registered in the %{customers_dot}, and you can upload this license to your instance." msgstr "" @@ -48503,9 +48509,6 @@ msgstr "" msgid "See the affected projects in the GitLab admin panel" msgstr "" -msgid "See the developer console for more information. Reload the page, or sign out then in again, and try loading the Web IDE again. If the problem persists, %{reportIssue}." -msgstr "" - msgid "See vulnerability %{vulnerability_link} for any Remediation details." msgstr "" @@ -63320,7 +63323,7 @@ msgstr "" msgid "reply should have same confidentiality as top-level note" msgstr "" -msgid "report an issue" +msgid "report a problem" msgstr "" msgid "repositories" diff --git a/spec/frontend/ide/components/web_ide_error_spec.js b/spec/frontend/ide/components/web_ide_error_spec.js index a95a4fb6eb721c..7fda6d7ebdae47 100644 --- a/spec/frontend/ide/components/web_ide_error_spec.js +++ b/spec/frontend/ide/components/web_ide_error_spec.js @@ -17,7 +17,6 @@ describe('WebIdeError', () => { const alert = wrapper.findComponent(GlAlert); expect(alert.exists()).toBe(true); - expect(alert.props('title')).toContain('Failed to load Web IDE'); }); it('renders reload page button', () => { -- GitLab From 9a4f2446ae9031ca43b7531f1dace28e8314a899 Mon Sep 17 00:00:00 2001 From: Cindy Halim Date: Fri, 7 Jun 2024 12:09:21 -0400 Subject: [PATCH 9/9] Update specs, pass sign out path from BE, use path helper --- .../ide/components/web_ide_error.vue | 30 ++++++------ .../javascripts/ide/init_gitlab_web_ide.js | 5 +- .../javascripts/ide/render_web_ide_error.js | 8 ++-- app/helpers/ide_helper.rb | 1 + locale/gitlab.pot | 8 +--- .../ide/components/web_ide_error_spec.js | 21 +++++++-- spec/frontend/ide/init_gitlab_web_ide_spec.js | 8 +++- .../frontend/ide/render_web_ide_error_spec.js | 47 ++++++++++++++----- 8 files changed, 83 insertions(+), 45 deletions(-) diff --git a/app/assets/javascripts/ide/components/web_ide_error.vue b/app/assets/javascripts/ide/components/web_ide_error.vue index a7ecf3e29a67df..9bb806ce365864 100644 --- a/app/assets/javascripts/ide/components/web_ide_error.vue +++ b/app/assets/javascripts/ide/components/web_ide_error.vue @@ -1,7 +1,7 @@