From c964374fc2e1eb474451abc129bf43d4290cbf93 Mon Sep 17 00:00:00 2001 From: aregnery Date: Wed, 3 Sep 2025 13:58:00 -0400 Subject: [PATCH 1/4] Add bootup modal [skip ci] --- .../components/duo_agent_onboarding_modal.vue | 355 ++++++++++++++++++ .../ai/components/duo_onboarding_checker.vue | 41 ++ .../javascripts/ai/duo_onboarding_init.js | 18 + app/assets/javascripts/main.js | 10 +- .../user_menu_project_studio_section.vue | 4 + 5 files changed, 427 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/ai/components/duo_agent_onboarding_modal.vue create mode 100644 app/assets/javascripts/ai/components/duo_onboarding_checker.vue create mode 100644 app/assets/javascripts/ai/duo_onboarding_init.js diff --git a/app/assets/javascripts/ai/components/duo_agent_onboarding_modal.vue b/app/assets/javascripts/ai/components/duo_agent_onboarding_modal.vue new file mode 100644 index 00000000000000..185ee2e8eb23c9 --- /dev/null +++ b/app/assets/javascripts/ai/components/duo_agent_onboarding_modal.vue @@ -0,0 +1,355 @@ + + + + + diff --git a/app/assets/javascripts/ai/components/duo_onboarding_checker.vue b/app/assets/javascripts/ai/components/duo_onboarding_checker.vue new file mode 100644 index 00000000000000..66ae0906f244f7 --- /dev/null +++ b/app/assets/javascripts/ai/components/duo_onboarding_checker.vue @@ -0,0 +1,41 @@ + + + diff --git a/app/assets/javascripts/ai/duo_onboarding_init.js b/app/assets/javascripts/ai/duo_onboarding_init.js new file mode 100644 index 00000000000000..54eeb3a7aa745e --- /dev/null +++ b/app/assets/javascripts/ai/duo_onboarding_init.js @@ -0,0 +1,18 @@ +import Vue from 'vue'; +import DuoOnboardingChecker from './components/duo_onboarding_checker.vue'; + +export function initDuoOnboarding() { + // Only initialize if localStorage flag exists + if (localStorage.getItem('showDuoAgentOnboarding') === 'true') { + // Create a mount point for the modal + const mountPoint = document.createElement('div'); + mountPoint.id = 'duo-onboarding-modal-mount'; + document.body.appendChild(mountPoint); + + // Mount the Vue component + new Vue({ + el: '#duo-onboarding-modal-mount', + render: (h) => h(DuoOnboardingChecker), + }); + } +} diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index ee4a9fc74e596d..b94465a990c76f 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -17,7 +17,11 @@ import { initPrefetchLinks } from '~/lib/utils/navigation_utility'; import { logHelloDeferred } from 'jh_else_ce/lib/logger/hello_deferred'; import initAlertHandler from './alert_handler'; import initLayoutNav from './layout_nav'; -import { handleLocationHash, addSelectOnFocusBehaviour } from './lib/utils/common_utils'; +import { + handleLocationHash, + addSelectOnFocusBehaviour, + parseBoolean, +} from './lib/utils/common_utils'; import { localTimeAgo } from './lib/utils/datetime/timeago_utility'; import { getLocationHash, visitUrl, mergeUrlParams } from './lib/utils/url_utility'; @@ -34,6 +38,7 @@ import initBroadcastNotifications from './broadcast_notification'; import { initCopyCodeButton } from './behaviors/copy_code'; import initGitlabVersionCheck from './gitlab_version_check'; import { initExpireSessionModal } from './authentication/sessions'; +import { initDuoOnboarding } from './ai/duo_onboarding_init'; import initPanelHeightCalc from './panel_height_calc'; import 'ee_else_ce/main_ee'; import 'jh_else_ce/main_jh'; @@ -98,6 +103,9 @@ function deferredInitialisation() { initCopyCodeButton(); initGitlabVersionCheck(); initExpireSessionModal(); + + // Initialize Duo Agent onboarding modal if needed + initDuoOnboarding(); initPanelHeightCalc(); addSelectOnFocusBehaviour('.js-select-on-focus'); diff --git a/app/assets/javascripts/super_sidebar/components/user_menu_project_studio_section.vue b/app/assets/javascripts/super_sidebar/components/user_menu_project_studio_section.vue index 78ac7f95b17733..b551cdcda0ffb1 100644 --- a/app/assets/javascripts/super_sidebar/components/user_menu_project_studio_section.vue +++ b/app/assets/javascripts/super_sidebar/components/user_menu_project_studio_section.vue @@ -58,6 +58,10 @@ export default { projectStudioEnabled: val, }, update: () => { + // If user is enabling the New UI (val=true and currently disabled), flag for onboarding + if (val === true && this.projectStudioEnabled === false) { + localStorage.setItem('showDuoAgentOnboarding', 'true'); + } window.location.reload(); }, }) -- GitLab From ae5bf43e3daaf42529213e2289d276f680c86c35 Mon Sep 17 00:00:00 2001 From: Julia Miocene Date: Wed, 22 Oct 2025 13:05:58 +0200 Subject: [PATCH 2/4] Resolve conflicts --- .../ai/components/duo_agent_onboarding_modal.vue | 12 +++++++----- app/assets/javascripts/ai/duo_onboarding_init.js | 2 +- app/assets/javascripts/main.js | 6 +----- locale/gitlab.pot | 12 ++++++++++++ 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/ai/components/duo_agent_onboarding_modal.vue b/app/assets/javascripts/ai/components/duo_agent_onboarding_modal.vue index 185ee2e8eb23c9..76cf9ecda74a8d 100644 --- a/app/assets/javascripts/ai/components/duo_agent_onboarding_modal.vue +++ b/app/assets/javascripts/ai/components/duo_agent_onboarding_modal.vue @@ -1,7 +1,7 @@ - - - - diff --git a/app/assets/javascripts/ai/components/duo_onboarding_checker.vue b/app/assets/javascripts/ai/components/duo_onboarding_checker.vue deleted file mode 100644 index 66ae0906f244f7..00000000000000 --- a/app/assets/javascripts/ai/components/duo_onboarding_checker.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/app/assets/javascripts/ai/duo_onboarding_init.js b/app/assets/javascripts/ai/duo_onboarding_init.js deleted file mode 100644 index 7f3fa7de9a1633..00000000000000 --- a/app/assets/javascripts/ai/duo_onboarding_init.js +++ /dev/null @@ -1,18 +0,0 @@ -import Vue from 'vue'; -import DuoOnboardingChecker from './components/duo_onboarding_checker.vue'; - -export function initDuoOnboarding() { - // Only initialize if localStorage flag exists - if (localStorage.getItem('showDuoAgentOnboarding') === 'true') { - // Create a mount point for the modal - const mountPoint = document.createElement('div'); - mountPoint.id = 'duo-onboarding-modal-mount'; - document.body.appendChild(mountPoint); - - // Mount the Vue component - Vue({ - el: '#duo-onboarding-modal-mount', - render: (h) => h(DuoOnboardingChecker), - }); - } -} diff --git a/app/assets/javascripts/ai/editor_actions/generate_description.js b/app/assets/javascripts/ai/editor_actions/generate_description.js deleted file mode 100644 index d850d13da3ff73..00000000000000 --- a/app/assets/javascripts/ai/editor_actions/generate_description.js +++ /dev/null @@ -1,3 +0,0 @@ -// Placeholder for GitLab FOSS -// Actual implementation: ee/app/assets/javascripts/ai/editor_actions/generate_description.js -export const generateDescriptionAction = () => {}; diff --git a/app/assets/javascripts/dap_welcome_modal/components/app.vue b/app/assets/javascripts/dap_welcome_modal/components/app.vue new file mode 100644 index 00000000000000..d0c5360e8780e8 --- /dev/null +++ b/app/assets/javascripts/dap_welcome_modal/components/app.vue @@ -0,0 +1,258 @@ + + + + + diff --git a/app/assets/javascripts/dap_welcome_modal/index.js b/app/assets/javascripts/dap_welcome_modal/index.js new file mode 100644 index 00000000000000..ac5cf0e61738a9 --- /dev/null +++ b/app/assets/javascripts/dap_welcome_modal/index.js @@ -0,0 +1,15 @@ +import Vue from 'vue'; +import DapWelcomeModalApp from './components/app.vue'; + +export const initDapWelcomeModal = () => { + const el = document.querySelector('.js-dap-welcome-modal'); + + if (!el) { + return null; + } + + return new Vue({ + el, + render: (createElement) => createElement(DapWelcomeModalApp), + }); +}; diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 9d762a08e0d26f..cc705b79b93830 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -34,7 +34,7 @@ import initBroadcastNotifications from './broadcast_notification'; import { initCopyCodeButton } from './behaviors/copy_code'; import initGitlabVersionCheck from './gitlab_version_check'; import { initExpireSessionModal } from './authentication/sessions'; -import { initDuoOnboarding } from './ai/duo_onboarding_init'; +import { initDapWelcomeModal } from './dap_welcome_modal/index'; import initPanelHeightCalc from './panel_height_calc'; import 'ee_else_ce/main_ee'; import 'jh_else_ce/main_jh'; @@ -99,9 +99,7 @@ function deferredInitialisation() { initCopyCodeButton(); initGitlabVersionCheck(); initExpireSessionModal(); - - // Initialize Duo Agent onboarding modal if needed - initDuoOnboarding(); + initDapWelcomeModal(); initPanelHeightCalc(); addSelectOnFocusBehaviour('.js-select-on-focus'); diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index 3457102cfe1d06..276d3eb20fff3d 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -27,6 +27,8 @@ = render_if_exists "layouts/session_expire_modal" - if project_studio_enabled? + .js-dap-welcome-modal + .panels-container.gl-flex.gl-gap-3 .content-panels.gl-flex-1.gl-w-full.gl-flex.gl-gap-3.gl-relative.js-content-panels{ class: 'gl-@container/content-panels' } #static-panel-portal.js-static-panel.static-panel.content-wrapper.gl-relative.paneled-view.gl-flex-1.gl-overflow-y-auto.gl-bg-default{ class: "#{@content_wrapper_class}" } diff --git a/locale/gitlab.pot b/locale/gitlab.pot index ece3b12279b391..55ca324bb10238 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -30105,9 +30105,6 @@ msgstr "" msgid "Get free trial" msgstr "" -msgid "Get instant AI assistance anywhere in GitLab with Duo's new persistent right panel" -msgstr "" - msgid "Get more information about troubleshooting pipelines" msgstr "" @@ -30288,9 +30285,6 @@ msgstr "" msgid "GitLab Duo" msgstr "" -msgid "GitLab Duo AI" -msgstr "" - msgid "GitLab Duo Agentic Chat" msgstr "" @@ -35613,6 +35607,9 @@ msgstr "" msgid "Interval" msgstr "" +msgid "Introducing a GitLab Duo sidebar on the right. Access Duo Agent Platform tools and get instant AI assistance anywhere in GitLab or collapse the sidebar so it gets out of the way." +msgstr "" + msgid "Introducing embedded views" msgstr "" @@ -74039,10 +74036,10 @@ msgstr "" msgid "Welcome to GitLab,%{br_tag}%{name}!" msgstr "" -msgid "Welcome to the GitLab Duo Agent Platform" +msgid "Welcome to the new merge request homepage! This page gives you a centralized view of all the merge requests you're working on. Know at a glance what merge requests need your attention first so you can spend less time checking in, and more time reviewing and responding to feedback." msgstr "" -msgid "Welcome to the new merge request homepage! This page gives you a centralized view of all the merge requests you're working on. Know at a glance what merge requests need your attention first so you can spend less time checking in, and more time reviewing and responding to feedback." +msgid "Welcome to the redesigned GitLab UI" msgstr "" msgid "Welcome, %{name}!" -- GitLab From 1ceb9ac3bf032a0f81fc7e579220c225c541b4aa Mon Sep 17 00:00:00 2001 From: Julia Miocene Date: Thu, 23 Oct 2025 12:58:02 +0200 Subject: [PATCH 4/4] Add steps --- .../ai/editor_actions/generate_description.js | 3 + .../dap_welcome_modal/components/app.vue | 115 +++++++++++++----- .../components/explainer_ai.vue | 14 +++ .../components/explainer_feedback.vue | 14 +++ .../components/explainer_panels.vue | 105 ++++++++++++++++ .../components/explainer_search.vue | 14 +++ .../components/explainer_sidebar.vue | 96 +++++++++++++++ .../components/explainer_ui.vue | 109 +++++++++++++++++ locale/gitlab.pot | 27 +++- 9 files changed, 465 insertions(+), 32 deletions(-) create mode 100644 app/assets/javascripts/ai/editor_actions/generate_description.js create mode 100644 app/assets/javascripts/dap_welcome_modal/components/explainer_ai.vue create mode 100644 app/assets/javascripts/dap_welcome_modal/components/explainer_feedback.vue create mode 100644 app/assets/javascripts/dap_welcome_modal/components/explainer_panels.vue create mode 100644 app/assets/javascripts/dap_welcome_modal/components/explainer_search.vue create mode 100644 app/assets/javascripts/dap_welcome_modal/components/explainer_sidebar.vue create mode 100644 app/assets/javascripts/dap_welcome_modal/components/explainer_ui.vue diff --git a/app/assets/javascripts/ai/editor_actions/generate_description.js b/app/assets/javascripts/ai/editor_actions/generate_description.js new file mode 100644 index 00000000000000..d850d13da3ff73 --- /dev/null +++ b/app/assets/javascripts/ai/editor_actions/generate_description.js @@ -0,0 +1,3 @@ +// Placeholder for GitLab FOSS +// Actual implementation: ee/app/assets/javascripts/ai/editor_actions/generate_description.js +export const generateDescriptionAction = () => {}; diff --git a/app/assets/javascripts/dap_welcome_modal/components/app.vue b/app/assets/javascripts/dap_welcome_modal/components/app.vue index d0c5360e8780e8..dce5e8cb6a5cf8 100644 --- a/app/assets/javascripts/dap_welcome_modal/components/app.vue +++ b/app/assets/javascripts/dap_welcome_modal/components/app.vue @@ -1,23 +1,34 @@ @@ -38,16 +55,17 @@ export default { - -

{{ $options.i18n.title }}

-

{{ $options.i18n.description }}

+ + + + + +
+ +
@@ -99,13 +136,35 @@ export default { initial-value: 0%; } -#dap_welcome_modal { - --tw-shadow: var(--gl-shadow-sm); - --tw-shadow-colored: var(--gl-shadow-sm); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), - var(--tw-shadow); +.gl-light #dap_welcome_modal { + --gl-button-confirm-primary-background-color-default: var(--gl-color-neutral-950); + --gl-button-confirm-primary-border-color-default: var(--gl-color-neutral-950); + --_svg-color: color-mix(in srgb, var(--gl-color-neutral-950), var(--theme-color)); + background-color: rgba(from var(--gl-background-color-overlay) r g b / 90%); + .modal-content { + background: rgba(from var(--gl-color-neutral-0) r g b / 90%); + } +} + +.gl-dark #dap_welcome_modal { + --gl-button-confirm-primary-background-color-default: var(--gl-color-neutral-10); + --gl-button-confirm-primary-border-color-default: var(--gl-color-neutral-10); + --_svg-color: color-mix(in srgb, var(--gl-color-neutral-10), var(--theme-color)); + + background-color: rgba(from var(--gl-background-color-overlay) r g b / 70%); + + .modal-content { + background: rgba(from var(--gl-color-neutral-950) r g b / 80%); + } +} + +#dap_welcome_modal { + --_flashlight-main-color: hsla(from var(--theme-color) h calc(s + 20) calc(l + 35) / 30%); + --_flashlight-complimentary-color: hsla( + from var(--theme-color) calc(h + 30) calc(s + 20) calc(l + 35) / 15% + ); backdrop-filter: blur(0.25rem); .modal-body { @@ -127,12 +186,10 @@ export default { background-image: conic-gradient( from -90deg at 50% 120%, transparent var(--_flashlight-start), - hsla(from var(--theme-color) calc(h + 30) calc(s + 20) calc(l + 10) / 25%) - var(--_flashlight-step-1), - hsla(from var(--theme-color) h calc(s + 20) calc(l + 10) / 50%) var(--_flashlight-step-2), - hsla(from var(--theme-color) h calc(s + 20) calc(l + 10) / 50%) var(--_flashlight-step-3), - hsla(from var(--theme-color) calc(h + 30) calc(s + 20) calc(l + 10) / 25%) - var(--_flashlight-step-4), + var(--_flashlight-complimentary-color) var(--_flashlight-step-1), + var(--_flashlight-main-color) var(--_flashlight-step-2), + var(--_flashlight-main-color) var(--_flashlight-step-3), + var(--_flashlight-complimentary-color) var(--_flashlight-step-4), transparent var(--_flashlight-end) ); animation: @@ -163,7 +220,7 @@ export default { 1 100% ) both, - breath 5s 1s ease-in-out infinite; + breath 10s 1s ease-in-out infinite; } } @@ -215,7 +272,7 @@ export default { padding: 0 10vw; top: 0; left: 0; - z-index: -1; + z-index: -2; display: flex; justify-content: space-around; mask: radial-gradient(circle at 50% 100%, black 50%, transparent 75%); @@ -233,7 +290,7 @@ export default { animation-iteration-count: infinite; width: calc(0.5rem * var(--size)); - animation-delay: calc(10s * var(--delay) - 1s); + animation-delay: calc(10s * var(--delay) - 5s); animation-duration: calc(20s * var(--duration) + 5s), 5s; filter: blur(calc(0.1rem * var(--blur))); } diff --git a/app/assets/javascripts/dap_welcome_modal/components/explainer_ai.vue b/app/assets/javascripts/dap_welcome_modal/components/explainer_ai.vue new file mode 100644 index 00000000000000..8e359e92e5804c --- /dev/null +++ b/app/assets/javascripts/dap_welcome_modal/components/explainer_ai.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/assets/javascripts/dap_welcome_modal/components/explainer_feedback.vue b/app/assets/javascripts/dap_welcome_modal/components/explainer_feedback.vue new file mode 100644 index 00000000000000..628ff7fd5b3d58 --- /dev/null +++ b/app/assets/javascripts/dap_welcome_modal/components/explainer_feedback.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/assets/javascripts/dap_welcome_modal/components/explainer_panels.vue b/app/assets/javascripts/dap_welcome_modal/components/explainer_panels.vue new file mode 100644 index 00000000000000..d32c20cbfd145e --- /dev/null +++ b/app/assets/javascripts/dap_welcome_modal/components/explainer_panels.vue @@ -0,0 +1,105 @@ + + + diff --git a/app/assets/javascripts/dap_welcome_modal/components/explainer_search.vue b/app/assets/javascripts/dap_welcome_modal/components/explainer_search.vue new file mode 100644 index 00000000000000..541e34c94b4aa0 --- /dev/null +++ b/app/assets/javascripts/dap_welcome_modal/components/explainer_search.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/assets/javascripts/dap_welcome_modal/components/explainer_sidebar.vue b/app/assets/javascripts/dap_welcome_modal/components/explainer_sidebar.vue new file mode 100644 index 00000000000000..71b7a42a322953 --- /dev/null +++ b/app/assets/javascripts/dap_welcome_modal/components/explainer_sidebar.vue @@ -0,0 +1,96 @@ + + + diff --git a/app/assets/javascripts/dap_welcome_modal/components/explainer_ui.vue b/app/assets/javascripts/dap_welcome_modal/components/explainer_ui.vue new file mode 100644 index 00000000000000..6416d6082bda55 --- /dev/null +++ b/app/assets/javascripts/dap_welcome_modal/components/explainer_ui.vue @@ -0,0 +1,109 @@ + + + diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 55ca324bb10238..33165fcc541bb8 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -30261,6 +30261,9 @@ msgstr "" msgid "GitLab / Unsubscribe" msgstr "" +msgid "GitLab 18.5 improves the GitLab user experience with a more usable, intuitive interface driven by a new panel-based layout." +msgstr "" + msgid "GitLab API" msgstr "" @@ -31261,6 +31264,9 @@ msgstr "" msgid "Go Micro is a framework for micro service development" msgstr "" +msgid "Go Next" +msgstr "" + msgid "Go back" msgstr "" @@ -34092,6 +34098,9 @@ msgstr "" msgid "If you don't renew by %{strong}%{downgrades_on}%{strong_close} your instance will become read-only, and you won't be able to create issues or merge requests. You will also lose access to your paid features and support entitlement. %{learn_more_link}" msgstr "" +msgid "If you enabled Duo. You can then open the GitLab Duo Chat panel on the right side of the interface as an on-demand assistant, allowing you to engage your agents with contextual questions and instructions from anywhere in the GitLab experience." +msgstr "" + msgid "If you get a lot of false alarms from repository checks, you can clear all repository check information from the database." msgstr "" @@ -35607,9 +35616,6 @@ msgstr "" msgid "Interval" msgstr "" -msgid "Introducing a GitLab Duo sidebar on the right. Access Duo Agent Platform tools and get instant AI assistance anywhere in GitLab or collapse the sidebar so it gets out of the way." -msgstr "" - msgid "Introducing embedded views" msgstr "" @@ -46342,6 +46348,9 @@ msgstr "" msgid "Other merge requests block this MR" msgstr "" +msgid "Other subtle, but usability-driven improvements include the move of the global search box to the top center for improved accessibility, while global navigation elements — including My Issues, Merge Requests, To-Dos, and the user icon — relocate to the top right." +msgstr "" + msgid "Other updates" msgstr "" @@ -47426,6 +47435,9 @@ msgstr "" msgid "Pagination|« First" msgstr "" +msgid "Panels present information side by side, allowing you to work more contextually. When you click on an issue in the issues list, you will see the details in its side panel." +msgstr "" + msgid "Parameter" msgstr "" @@ -49402,6 +49414,9 @@ msgstr "" msgid "Please set the admin account password." msgstr "" +msgid "Please share your feedback and file bugs on anything you don’t love! Our engineers are listening. Assuming you love the experience as much as our own team, this toggle is expected to be removed in 18.6, making the panel UI standard across all user experiences." +msgstr "" + msgid "Please solve the captcha" msgstr "" @@ -65180,6 +65195,9 @@ msgstr "" msgid "System started" msgstr "" +msgid "TITLE" +msgstr "" + msgid "TXT" msgstr "" @@ -66307,6 +66325,9 @@ msgstr "" msgid "The latest pipeline for this merge request has failed." msgstr "" +msgid "The left navigation menu now collapses and expands to provide flexible sidebar management." +msgstr "" + msgid "The license key is invalid." msgstr "" -- GitLab