From db85d9d870d77c9ea7c2aa1aa843c2fc1062f9fc Mon Sep 17 00:00:00 2001 From: Justin Ho Tuan Duong <hduong@gitlab.com> Date: Fri, 10 May 2024 19:48:18 +0000 Subject: [PATCH] Add visual indicators for some items Issues, Epics, MRs. Verified that Notes and User activities work as expected. Changelog: changed --- .../graphql/fragments/design.fragment.graphql | 1 + app/assets/javascripts/issues/show/index.js | 2 ++ .../notes/components/note_header.vue | 2 +- .../queries/snippet/snippet.query.graphql | 1 + app/helpers/issuables_helper.rb | 1 + app/helpers/merge_requests_helper.rb | 23 ++++++++-------- app/views/events/_event.html.haml | 4 +-- .../import/shared/_imported_badge.html.haml | 7 +++++ .../import/shared/_imported_text.html.haml | 3 --- .../projects/merge_requests/_mr_box.html.haml | 2 +- .../projects/merge_requests/_page.html.haml | 2 +- app/views/shared/notes/_note.html.haml | 2 ++ doc/user/group/import/index.md | 3 +++ ee/spec/helpers/ee/issuables_helper_spec.rb | 1 + .../design/__snapshots__/index_spec.js.snap | 1 + spec/frontend/snippets/test_utils.js | 1 + spec/helpers/issuables_helper_spec.rb | 1 + spec/helpers/merge_requests_helper_spec.rb | 26 +++++++++++++++++++ 18 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 app/views/import/shared/_imported_badge.html.haml delete mode 100644 app/views/import/shared/_imported_text.html.haml diff --git a/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql b/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql index 4b1703e41c34c..47ea165470f3d 100644 --- a/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql +++ b/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql @@ -6,6 +6,7 @@ fragment DesignItem on Design { ...DesignListItem fullPath + imported diffRefs { ...DesignDiffRefs } diff --git a/app/assets/javascripts/issues/show/index.js b/app/assets/javascripts/issues/show/index.js index b1d8a245f5ef2..985f6fab7ed64 100644 --- a/app/assets/javascripts/issues/show/index.js +++ b/app/assets/javascripts/issues/show/index.js @@ -46,6 +46,7 @@ export function initIssuableApp(store) { issuableId, issueType, hasIterationsFeature, + imported, // for issue registerPath, signInPath, @@ -129,6 +130,7 @@ export function initIssuableApp(store) { descriptionComponent: issueType === TYPE_INCIDENT ? IncidentTabs : DescriptionComponent, isConfidential: this.getNoteableData?.confidential, isLocked: this.getNoteableData?.discussion_locked, + isImported: imported, issuableStatus: this.getNoteableData?.state, issuableType: issueType, issueId: this.getNoteableData?.id?.toString(), diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue index 15822be228990..bf420dc045709 100644 --- a/app/assets/javascripts/notes/components/note_header.vue +++ b/app/assets/javascripts/notes/components/note_header.vue @@ -247,7 +247,7 @@ export default { </template> <template v-if="isImported"> - <span>·</span> + <span v-if="isSystemNote">·</span> <imported-badge :text-only="isSystemNote" :importable-type="importableType" size="sm" /> </template> diff --git a/app/graphql/queries/snippet/snippet.query.graphql b/app/graphql/queries/snippet/snippet.query.graphql index 8a2b314b994be..2f4b89b339966 100644 --- a/app/graphql/queries/snippet/snippet.query.graphql +++ b/app/graphql/queries/snippet/snippet.query.graphql @@ -14,6 +14,7 @@ query GetSnippetQuery($ids: [SnippetID!]) { httpUrlToRepo sshUrlToRepo hidden + imported blobs { __typename hasUnretrievableBlobs diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index ccf208d5f3ea8..3c81142a88489 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -164,6 +164,7 @@ def issuable_initial_data(issuable) canUpdate: can?(current_user, :"update_#{issuable.to_ability_name}", issuable), canDestroy: can?(current_user, :"destroy_#{issuable.to_ability_name}", issuable), issuableRef: issuable.to_reference, + imported: issuable.imported?, markdownPreviewPath: preview_markdown_path(parent, target_type: issuable.model_name, target_id: issuable.iid), markdownDocsPath: help_page_path('user/markdown'), lockVersion: issuable.lock_version, diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index a3b2614a1a4e4..39211a518a184 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -311,23 +311,24 @@ def merge_request_header(project, merge_request) _('%{author} requested to merge %{source_branch} %{copy_button} into %{target_branch} %{created_at}').html_safe % { author: link_to_author.html_safe, source_branch: merge_request_source_branch(merge_request).html_safe, copy_button: copy_button.html_safe, target_branch: target_branch.html_safe, created_at: time_ago_with_tooltip(merge_request.created_at, html_class: 'gl-display-inline-block').html_safe } end - def sticky_header_data + def sticky_header_data(project, merge_request) data = { - iid: @merge_request.iid, - projectPath: @project.full_path, - sourceProjectPath: @merge_request.source_project_path, - title: markdown_field(@merge_request, :title), + iid: merge_request.iid, + projectPath: project.full_path, + sourceProjectPath: merge_request.source_project_path, + title: markdown_field(merge_request, :title), isFluidLayout: fluid_layout.to_s, - blocksMerge: @project.only_allow_merge_if_all_discussions_are_resolved?.to_s, + blocksMerge: project.only_allow_merge_if_all_discussions_are_resolved?.to_s, + imported: merge_request.imported?.to_s, tabs: [ - ['show', _('Overview'), project_merge_request_path(@project, @merge_request), @merge_request.related_notes.user.count], - ['commits', _('Commits'), commits_project_merge_request_path(@project, @merge_request), @commits_count], - ['diffs', _('Changes'), diffs_project_merge_request_path(@project, @merge_request), @diffs_count] + ['show', _('Overview'), project_merge_request_path(project, merge_request), merge_request.related_notes.user.count], + ['commits', _('Commits'), commits_project_merge_request_path(project, merge_request), @commits_count], + ['diffs', _('Changes'), diffs_project_merge_request_path(project, merge_request), @diffs_count] ] } - if @project.builds_enabled? - data[:tabs].insert(2, ['pipelines', _('Pipelines'), pipelines_project_merge_request_path(@project, @merge_request), @number_of_pipelines]) + if project.builds_enabled? + data[:tabs].insert(2, ['pipelines', _('Pipelines'), pipelines_project_merge_request_path(project, merge_request), @number_of_pipelines]) end data diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml index 432070ed28a15..3bb97720e845a 100644 --- a/app/views/events/_event.html.haml +++ b/app/views/events/_event.html.haml @@ -5,8 +5,8 @@ .event-item-timestamp.gl-font-sm #{time_ago_with_tooltip(event.created_at)} - if event.imported? - %span • - = render "import/shared/imported_text", importable: _('event') + %span · + = render "import/shared/imported_badge", text_only: true, importable: _('event') - if event.wiki_page? = render "events/event/wiki", event: event diff --git a/app/views/import/shared/_imported_badge.html.haml b/app/views/import/shared/_imported_badge.html.haml new file mode 100644 index 0000000000000..8da76d45019b9 --- /dev/null +++ b/app/views/import/shared/_imported_badge.html.haml @@ -0,0 +1,7 @@ +- tooltip_title = safe_format(s_('BulkImport|This %{importable} was imported from another instance.'), importable: local_assigns[:importable]) +- text_only = local_assigns.fetch(:text_only, false) + +- if text_only + %span.has-tooltip.gl-line-height-normal.gl-font-sm{ title: tooltip_title }= _('Imported') +- else + = render Pajamas::BadgeComponent.new(_('Imported'), size: :sm, title: tooltip_title, class: 'has-tooltip') diff --git a/app/views/import/shared/_imported_text.html.haml b/app/views/import/shared/_imported_text.html.haml deleted file mode 100644 index cac62c6fb4954..0000000000000 --- a/app/views/import/shared/_imported_text.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -- tooltip_title = safe_format(s_('BulkImport|This %{importable} was imported from another instance.'), importable: local_assigns[:importable]) - -%span.has-tooltip.gl-line-height-normal.gl-font-sm{ title: tooltip_title }= _('Imported') diff --git a/app/views/projects/merge_requests/_mr_box.html.haml b/app/views/projects/merge_requests/_mr_box.html.haml index c98252ef63ccb..6a6771497e63c 100644 --- a/app/views/projects/merge_requests/_mr_box.html.haml +++ b/app/views/projects/merge_requests/_mr_box.html.haml @@ -1,3 +1,3 @@ .detail-page-description.gl-pt-2.gl-pb-4.gl-display-flex.gl-align-items-baseline.gl-flex-wrap{ class: "#{'is-merge-request' if !fluid_layout}" } - .js-mr-header{ data: { project_path: @merge_request.project.path_with_namespace, hidden: @merge_request.hidden?.to_s, iid: @merge_request.iid, state: @merge_request.state } } + .js-mr-header{ data: { project_path: @merge_request.project.path_with_namespace, hidden: @merge_request.hidden?.to_s, imported: @merge_request.imported?.to_s, iid: @merge_request.iid, state: @merge_request.state } } = merge_request_header(@project, @merge_request) diff --git a/app/views/projects/merge_requests/_page.html.haml b/app/views/projects/merge_requests/_page.html.haml index e63ae75c1b82a..d7c0592b8353e 100644 --- a/app/views/projects/merge_requests/_page.html.haml +++ b/app/views/projects/merge_requests/_page.html.haml @@ -21,7 +21,7 @@ .merge-request{ data: { mr_action: mr_action, url: merge_request_path(@merge_request, format: :json), project_path: project_path(@merge_request.project), lock_version: @merge_request.lock_version, diffs_batch_cache_key: @diffs_batch_cache_key } } = render "projects/merge_requests/mr_title" - #js-merge-sticky-header{ data: { data: sticky_header_data.to_json } } + #js-merge-sticky-header{ data: { data: sticky_header_data(@project, @merge_request).to_json } } .merge-request-details.issuable-details{ data: { id: @merge_request.project.id } } = render "projects/merge_requests/mr_box" .gl-static.merge-request-tabs-holder{ class: "#{'js-tabs-affix' unless ENV['RAILS_ENV'] == 'test'}" } diff --git a/app/views/shared/notes/_note.html.haml b/app/views/shared/notes/_note.html.haml index ec304c58fcea4..32e7041c63f0e 100644 --- a/app/views/shared/notes/_note.html.haml +++ b/app/views/shared/notes/_note.html.haml @@ -45,6 +45,8 @@ %span.system-note-separator.gl-display-none.gl-sm-display-inline · %a.system-note-separator{ href: "##{dom_id(note)}" }= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago') + - if note.imported? + = render "import/shared/imported_badge", importable: note.system? ? _('activity') : _('comment') - unless note.system? .note-actions - if note.for_personal_snippet? diff --git a/doc/user/group/import/index.md b/doc/user/group/import/index.md index 93b3a38766c3a..a5ee516ed4df1 100644 --- a/doc/user/group/import/index.md +++ b/doc/user/group/import/index.md @@ -303,6 +303,7 @@ To view group import history: > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/429109) in GitLab 16.6 [with a flag](../../feature_flags.md) named `bulk_import_details_page`. Enabled by default. > - Feature flag `bulk_import_details_page` removed in GitLab 16.8. > - Details for partially completed and completed imports [added](https://gitlab.com/gitlab-org/gitlab/-/issues/437874) in GitLab 16.9. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/443492) in GitLab 17.0, an **Imported** badge to indicate that designs, epics, issues, merge requests, notes (system notes and comments), snippets, and user profile activity were imported. To review the results of an import: @@ -310,6 +311,8 @@ To review the results of an import: 1. To see the details of a failed import, select the **See failures** link on any import with a **Failed** or **Partially completed** status. 1. If the import has a **Partially completed** or **Complete** status, to see which items were and were not imported, select **Details**. +You can also see that an item was imported when you see an **Imported** badge on some items in the GitLab UI. + ## Cancel a running import To cancel a running import: diff --git a/ee/spec/helpers/ee/issuables_helper_spec.rb b/ee/spec/helpers/ee/issuables_helper_spec.rb index 06bae9c0725a2..2b763c5d60ce9 100644 --- a/ee/spec/helpers/ee/issuables_helper_spec.rb +++ b/ee/spec/helpers/ee/issuables_helper_spec.rb @@ -38,6 +38,7 @@ initialTitleHtml: epic.title, initialTitleText: epic.title, issuableRef: "&#{epic.iid}", + imported: epic.imported?, issuableTemplateNamesPath: '', issueLinksEndpoint: "/groups/#{@group.full_path}/-/epics/#{epic.iid}/issues", issuesWebUrl: "/groups/#{@group.full_path}/-/issues", diff --git a/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap b/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap index 7f2e45076e515..fe862eec78f02 100644 --- a/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap +++ b/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap @@ -21,6 +21,7 @@ exports[`Design management design index page when loaded renders design index 1` iid="1" image="test.jpg" imagev432x230="test.jpg" + imported="true" islatestversion="true" issidebaropen="true" issue="[object Object]" diff --git a/spec/frontend/snippets/test_utils.js b/spec/frontend/snippets/test_utils.js index 9d42e9fa26c53..dfa8d309ec0b3 100644 --- a/spec/frontend/snippets/test_utils.js +++ b/spec/frontend/snippets/test_utils.js @@ -46,6 +46,7 @@ export const createGQLSnippet = () => ({ }, }, hidden: false, + imported: false, }); export const createGQLSnippetsQueryResponse = (snippets) => ({ diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index cb6fcaa9d6506..c813bc98590a6 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -252,6 +252,7 @@ canUpdate: true, canDestroy: true, issuableRef: "##{issue.iid}", + imported: issue.imported?, markdownPreviewPath: "/#{@project.full_path}/preview_markdown?target_id=#{issue.iid}&target_type=Issue", markdownDocsPath: '/help/user/markdown', lockVersion: issue.lock_version, diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb index a2f2a1db113ac..2db156d273206 100644 --- a/spec/helpers/merge_requests_helper_spec.rb +++ b/spec/helpers/merge_requests_helper_spec.rb @@ -10,6 +10,7 @@ include ProjectForksHelper include IconsHelper include IssuablesHelper + include MarkupHelper let_it_be(:current_user) { create(:user) } @@ -218,6 +219,31 @@ end end + describe '#sticky_header_data' do + let_it_be(:project) { create(:project) } + let(:merge_request) do + create(:merge_request, source_project: project, target_project: project, imported_from: imported_from) + end + + subject { sticky_header_data(project, merge_request) } + + context 'when the merge request is not imported' do + let(:imported_from) { :none } + + it 'returns data with imported set as false' do + expect(subject[:imported]).to eq('false') + end + end + + context 'when the merge request is imported' do + let(:imported_from) { :gitlab_migration } + + it 'returns data with imported set as true' do + expect(subject[:imported]).to eq('true') + end + end + end + describe '#tab_count_display' do let(:merge_request) { create(:merge_request) } -- GitLab