diff --git a/app/assets/javascripts/merge_request_dashboard/components/app.vue b/app/assets/javascripts/merge_request_dashboard/components/app.vue new file mode 100644 index 0000000000000000000000000000000000000000..2d95c1fd126140bd28ce06e933760305ee6c714f --- /dev/null +++ b/app/assets/javascripts/merge_request_dashboard/components/app.vue @@ -0,0 +1,18 @@ +<script> +import { GlLoadingIcon } from '@gitlab/ui'; + +export default { + components: { + GlLoadingIcon, + }, +}; +</script> + +<template> + <div> + <div class="page-title-holder"> + <h1 class="page-title gl-font-size-h-display">{{ __('Merge Requests') }}</h1> + </div> + <gl-loading-icon size="lg" /> + </div> +</template> diff --git a/app/assets/javascripts/merge_request_dashboard/index.js b/app/assets/javascripts/merge_request_dashboard/index.js new file mode 100644 index 0000000000000000000000000000000000000000..799462844e618ae2c704a53336c75118a63e4d8c --- /dev/null +++ b/app/assets/javascripts/merge_request_dashboard/index.js @@ -0,0 +1,18 @@ +import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; +import App from './components/app.vue'; + +export function initMergeRequestDashboard(el) { + Vue.use(VueApollo); + + return new Vue({ + el, + apolloProvider: new VueApollo({ + defaultClient: createDefaultClient(), + }), + render(createElement) { + return createElement(App); + }, + }); +} diff --git a/app/assets/javascripts/pages/dashboard/merge_requests/index.js b/app/assets/javascripts/pages/dashboard/merge_requests/index.js index 774e234a358cf9c7ad91ae83fbe6a2ca29d8e5c7..9f785d561742c6f315378fd0e95dfb363d3c95af 100644 --- a/app/assets/javascripts/pages/dashboard/merge_requests/index.js +++ b/app/assets/javascripts/pages/dashboard/merge_requests/index.js @@ -6,23 +6,33 @@ import { initNewResourceDropdown } from '~/vue_shared/components/new_resource_dr import { RESOURCE_TYPE_MERGE_REQUEST } from '~/vue_shared/components/new_resource_dropdown/constants'; import searchUserProjectsWithMergeRequestsEnabled from '~/vue_shared/components/new_resource_dropdown/graphql/search_user_projects_with_merge_requests_enabled.query.graphql'; -const IssuableFilteredSearchTokenKeys = createFilteredSearchTokenKeys({ - disableReleaseFilter: true, -}); +const el = document.getElementById('js-merge-request-dashboard'); -addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys, { - disableBranchFilter: true, - disableReleaseFilter: true, - disableEnvironmentFilter: true, -}); +if (el) { + requestIdleCallback(async () => { + const { initMergeRequestDashboard } = await import('~/merge_request_dashboard'); -initFilteredSearch({ - page: FILTERED_SEARCH.MERGE_REQUESTS, - filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys, - useDefaultState: true, -}); + initMergeRequestDashboard(el); + }); +} else { + const IssuableFilteredSearchTokenKeys = createFilteredSearchTokenKeys({ + disableReleaseFilter: true, + }); -initNewResourceDropdown({ - resourceType: RESOURCE_TYPE_MERGE_REQUEST, - query: searchUserProjectsWithMergeRequestsEnabled, -}); + addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys, { + disableBranchFilter: true, + disableReleaseFilter: true, + disableEnvironmentFilter: true, + }); + + initFilteredSearch({ + page: FILTERED_SEARCH.MERGE_REQUESTS, + filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys, + useDefaultState: true, + }); + + initNewResourceDropdown({ + resourceType: RESOURCE_TYPE_MERGE_REQUEST, + query: searchUserProjectsWithMergeRequestsEnabled, + }); +} diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index ef160fdc36b9d2bb80f97f28a898881a2b346216..0ed504ed61aee096d43acf4906e283df8ae1aa7c 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -328,6 +328,10 @@ def project_merge_requests_list_data(project, current_user) is_signed_in: current_user.present?.to_s } end + + def merge_request_dashboard_enabled?(current_user) + Feature.enabled?(:merge_request_dashboard, current_user, type: :wip) + end end MergeRequestsHelper.prepend_mod_with('MergeRequestsHelper') diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index d29cb56db0718f51750195902a7f9ad28520aa19..5d5ba8ac605380c6f124538aca939edf24ed9232 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -1,5 +1,7 @@ :ruby - title = if params[:reviewer_username] == current_user.username + title = if merge_request_dashboard_enabled?(current_user) + _('Merge Requests') + elsif params[:reviewer_username] == current_user.username _("Review requests") elsif params[:assignee_username] == current_user.username _("Assigned merge requests") @@ -14,25 +16,31 @@ = render_if_exists 'shared/dashboard/saml_reauth_notice', groups_requiring_saml_reauth: user_groups_requiring_reauth -.page-title-holder.d-flex.align-items-start.flex-column.flex-sm-row.align-items-sm-center - %h1.page-title.gl-font-size-h-display= title +- if merge_request_dashboard_enabled?(current_user) + #js-merge-request-dashboard + .page-title-holder + %h1.page-title.gl-font-size-h-display= _('Merge Requests') + = gl_loading_icon(size: 'lg') +- else + .page-title-holder.d-flex.align-items-start.flex-column.flex-sm-row.align-items-sm-center + %h1.page-title.gl-font-size-h-display= title - - if current_user - .page-title-controls.ml-0.mb-3.ml-sm-auto.mb-sm-0 - = render 'shared/new_project_item_vue_select' + - if current_user + .page-title-controls.ml-0.mb-3.ml-sm-auto.mb-sm-0 + = render 'shared/new_project_item_vue_select' -.top-area - = render 'shared/issuable/nav', type: :merge_requests, display_count: !(@no_filters_set || @search_timeout_occurred) + .top-area + = render 'shared/issuable/nav', type: :merge_requests, display_count: !(@no_filters_set || @search_timeout_occurred) -= render 'shared/issuable/search_bar', - type: :merge_requests, - disable_target_branch: true, - disable_releases: true, - disable_environments: true + = render 'shared/issuable/search_bar', + type: :merge_requests, + disable_target_branch: true, + disable_releases: true, + disable_environments: true -- if current_user && @no_filters_set - = render 'no_filter_selected' -- elsif @search_timeout_occurred - = render 'shared/dashboard/search_timeout_occurred' -- else - = render 'shared/merge_requests' + - if current_user && @no_filters_set + = render 'no_filter_selected' + - elsif @search_timeout_occurred + = render 'shared/dashboard/search_timeout_occurred' + - else + = render 'shared/merge_requests' diff --git a/config/feature_flags/wip/merge_request_dashboard.yml b/config/feature_flags/wip/merge_request_dashboard.yml new file mode 100644 index 0000000000000000000000000000000000000000..cea0775417e4e317cf59ad6b2b33ea47f5fa8a75 --- /dev/null +++ b/config/feature_flags/wip/merge_request_dashboard.yml @@ -0,0 +1,9 @@ +--- +name: merge_request_dashboard +feature_issue_url: https://gitlab.com/groups/gitlab-org/-/epics/13448 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150661 +rollout_issue_url: +milestone: '17.0' +group: group::code review +type: wip +default_enabled: false diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 77b95044318b631e5b90702acf4cc48544ac273d..1e47810846810be8544996ec1db69737cf8371c4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -336,6 +336,9 @@ # Disable license requirement for duo chat (self managed), which is subject to change. # See https://gitlab.com/gitlab-org/gitlab/-/issues/457283 stub_feature_flags(duo_chat_requires_licensed_seat_sm: false) + + # Experimental merge request dashboard + stub_feature_flags(merge_request_dashboard: false) else unstub_all_feature_flags end