From 1146f15203f7e80d9ff9b480f52dc9801955e628 Mon Sep 17 00:00:00 2001
From: Marcel van Remmerden <mvanremmerden@gitlab.com>
Date: Thu, 31 Oct 2024 15:11:56 +0000
Subject: [PATCH] Add "Open in Web IDE" button to empty repositories

---
 .../pages/projects/shared/web_ide_link/index.js      | 12 ++++++++++--
 app/assets/javascripts/pages/projects/show/index.js  |  2 ++
 .../vue_shared/components/web_ide_link.vue           |  2 +-
 app/helpers/web_ide_button_helper.rb                 |  2 +-
 app/views/projects/empty.html.haml                   |  3 ++-
 app/views/shared/_web_ide_button.html.haml           |  4 +++-
 6 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/app/assets/javascripts/pages/projects/shared/web_ide_link/index.js b/app/assets/javascripts/pages/projects/shared/web_ide_link/index.js
index e4a4e2c00eb2d..275a9cf76d10a 100644
--- a/app/assets/javascripts/pages/projects/shared/web_ide_link/index.js
+++ b/app/assets/javascripts/pages/projects/shared/web_ide_link/index.js
@@ -18,7 +18,7 @@ export default ({ el, router }) => {
   const { projectPath, ref, isBlob, webIdeUrl, ...options } = convertObjectPropsToCamelCase(
     JSON.parse(el.dataset.options),
   );
-  const { webIdePromoPopoverImg, cssClasses } = el.dataset;
+  const { webIdePromoPopoverImg, cssClasses, defaultBranch } = el.dataset;
 
   // eslint-disable-next-line no-new
   new Vue({
@@ -37,7 +37,15 @@ export default ({ el, router }) => {
           webIdeUrl: isBlob
             ? webIdeUrl
             : webIDEUrl(
-                joinPaths('/', projectPath, 'edit', ref, '-', this.$route?.params.path || '', '/'),
+                joinPaths(
+                  '/',
+                  projectPath,
+                  'edit',
+                  ref || defaultBranch,
+                  '-',
+                  this.$route?.params.path || '',
+                  '/',
+                ),
               ),
           projectPath,
           cssClasses,
diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js
index 11d3c4ad2cc28..eb6cb11832cf3 100644
--- a/app/assets/javascripts/pages/projects/show/index.js
+++ b/app/assets/javascripts/pages/projects/show/index.js
@@ -11,6 +11,7 @@ import initAmbiguousRefModal from '~/ref/init_ambiguous_ref_modal';
 import CodeDropdown from '~/vue_shared/components/code_dropdown/code_dropdown.vue';
 import initSourceCodeDropdowns from '~/vue_shared/components/download_dropdown/init_download_dropdowns';
 import EmptyProject from '~/pages/projects/show/empty_project';
+import initWebIdeLink from '~/pages/projects/shared/web_ide_link';
 import { initHomePanel } from '../home_panel';
 
 // Project show page loads different overview content based on user preferences
@@ -94,3 +95,4 @@ initCodeDropdown();
 initSourceCodeDropdowns();
 initFindFileShortcut();
 initEmptyProjectTabs();
+initWebIdeLink({ el: document.getElementById('js-tree-web-ide-link') });
diff --git a/app/assets/javascripts/vue_shared/components/web_ide_link.vue b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
index 9a83afae60fdd..383aa8a516c88 100644
--- a/app/assets/javascripts/vue_shared/components/web_ide_link.vue
+++ b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
@@ -238,7 +238,7 @@ export default {
       return this.gitpodText || __('Gitpod');
     },
     computedShowGitpodButton() {
-      return this.showGitpodButton && this.gitpodEnabled;
+      return this.showGitpodButton && this.gitpodEnabled && this.gitpodUrl;
     },
     pipelineEditorAction() {
       if (!this.showPipelineEditorButton) {
diff --git a/app/helpers/web_ide_button_helper.rb b/app/helpers/web_ide_button_helper.rb
index 185e1b8e0a8d9..2f654056382bb 100644
--- a/app/helpers/web_ide_button_helper.rb
+++ b/app/helpers/web_ide_button_helper.rb
@@ -54,7 +54,7 @@ def edit_url(options = {})
   end
 
   def gitpod_url
-    return "" unless Gitlab::CurrentSettings.gitpod_enabled
+    return "" unless Gitlab::CurrentSettings.gitpod_enabled && @ref
 
     "#{Gitlab::CurrentSettings.gitpod_url}##{project_tree_url(@project, tree_join(@ref, @path || ''))}"
   end
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index e892c1d9ab1b7..8a0b6715e129c 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -17,7 +17,8 @@
       .project-clone-holder.gl-block.sm:gl-hidden
         = render "shared/mobile_clone_panel"
 
-      .project-clone-holder.gl-hidden.sm:gl-flex.gl-justify-end.gl-w-full
+      .project-clone-holder.gl-hidden.sm:gl-flex.gl-justify-end.gl-w-full.gl-gap-3
+        = render 'shared/web_ide_button', blob: nil
         = render "projects/buttons/code", ref: @ref
 
     = render Pajamas::CardComponent.new(card_options: { class: 'gl-mb-5' }, body_options: { class: 'gl-bg-gray-10 gl-p-5 gl-rounded-base' }) do |c|
diff --git a/app/views/shared/_web_ide_button.html.haml b/app/views/shared/_web_ide_button.html.haml
index c06571d14b2d8..a625234d7f3e4 100644
--- a/app/views/shared/_web_ide_button.html.haml
+++ b/app/views/shared/_web_ide_button.html.haml
@@ -1,6 +1,8 @@
+- return unless current_user && current_user.namespace
+
 - type = blob ? 'blob' : 'tree'
 - button_data = web_ide_button_data({ blob: blob })
 - fork_options = fork_modal_options(@project, blob)
 - css_classes = false unless local_assigns[:css_classes]
 
-.gl-inline-block{ data: { options: button_data.merge(fork_options).to_json, web_ide_promo_popover_img: image_path('web-ide-promo-popover.svg'), css_classes: css_classes }, id: "js-#{type}-web-ide-link" }
+.gl-inline-block{ data: { options: button_data.merge(fork_options).to_json, web_ide_promo_popover_img: image_path('web-ide-promo-popover.svg'), css_classes: css_classes, default_branch: @project.default_branch_or_main }, id: "js-#{type}-web-ide-link" }
-- 
GitLab