diff options
Diffstat (limited to 'app/assets/javascripts/ide/init_gitlab_web_ide.js')
-rw-r--r-- | app/assets/javascripts/ide/init_gitlab_web_ide.js | 98 |
1 files changed, 79 insertions, 19 deletions
diff --git a/app/assets/javascripts/ide/init_gitlab_web_ide.js b/app/assets/javascripts/ide/init_gitlab_web_ide.js index 140f2895a29..d3c64754e8a 100644 --- a/app/assets/javascripts/ide/init_gitlab_web_ide.js +++ b/app/assets/javascripts/ide/init_gitlab_web_ide.js @@ -1,29 +1,89 @@ -import { cleanTrailingSlash } from './stores/utils'; +import { start } from '@gitlab/web-ide'; +import { __ } from '~/locale'; +import { cleanLeadingSeparator } from '~/lib/utils/url_utility'; +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 { getBaseConfig } from './lib/gitlab_web_ide/get_base_config'; +import { setupRootElement } from './lib/gitlab_web_ide/setup_root_element'; +import { GITLAB_WEB_IDE_FEEDBACK_ISSUE } from './constants'; -export const initGitlabWebIDE = async (el) => { - const { start } = await import('@gitlab/web-ide'); +const buildRemoteIdeURL = (ideRemotePath, remoteHost, remotePathArg) => { + const remotePath = cleanLeadingSeparator(remotePathArg); - const { gitlab_url: gitlabUrl } = window.gon; - const baseUrl = new URL(process.env.GITLAB_WEB_IDE_PUBLIC_PATH, window.location.origin); + const replacers = { + ':remote_host': encodeURIComponent(remoteHost), + ':remote_path': encodeURIComponent(remotePath).replaceAll('%2F', '/'), + }; - // what: Pull what we need from the element. We will replace it soon. - const { cspNonce: nonce, branchName: ref, projectPath } = el.dataset; + // why: Use the function callback of "replace" so we replace both keys at once + return ideRemotePath.replace(/(:remote_host|:remote_path)/g, (key) => { + return replacers[key]; + }); +}; + +const getMRTargetProject = () => { + const url = new URL(window.location.href); + + return url.searchParams.get('target_project') || ''; +}; - // what: Clean up the element, but preserve id. - // why: This way we don't inherit any `ide-loading` side-effects. This - // mirrors the behavior of Vue when it mounts to an element. - const newEl = document.createElement(el.tagName); - newEl.id = el.id; - newEl.classList.add('gl--flex-center', 'gl-relative', 'gl-h-full'); +export const initGitlabWebIDE = async (el) => { + // what: Pull what we need from the element. We will replace it soon. + const { + cspNonce: nonce, + branchName: ref, + projectPath, + ideRemotePath, + filePath, + mergeRequest: mrId, + forkInfo: forkInfoJSON, + } = el.dataset; - el.replaceWith(newEl); + const rootEl = setupRootElement(el); + const forkInfo = forkInfoJSON ? JSON.parse(forkInfoJSON) : null; - // what: Trigger start on our new mounting element - await start(newEl, { - baseUrl: cleanTrailingSlash(baseUrl.href), + // See ClientOnlyConfig https://gitlab.com/gitlab-org/gitlab-web-ide/-/blob/main/packages/web-ide-types/src/config.ts#L17 + start(rootEl, { + ...getBaseConfig(), + nonce, + // Use same headers as defined in axios_utils + httpHeaders: { + [csrf.headerKey]: csrf.token, + 'X-Requested-With': 'XMLHttpRequest', + }, projectPath, - gitlabUrl, ref, - nonce, + filePath, + mrId, + mrTargetProject: getMRTargetProject(), + // note: At the time of writing this, forkInfo isn't expected by `@gitlab/web-ide`, + // but it will be soon. + forkInfo, + links: { + feedbackIssue: GITLAB_WEB_IDE_FEEDBACK_ISSUE, + userPreferences: el.dataset.userPreferencesPath, + }, + 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; + } + + createAndSubmitForm({ + url: buildRemoteIdeURL(ideRemotePath, remoteHost, remotePath), + data: { + connection_token: connectionToken, + return_url: window.location.href, + }, + }); + }, }); }; |