Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-07 09:08:35 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-07 09:08:35 +0300
commitbed53d96d214fd96ea688d3e86e53457ce50043e (patch)
tree8196df5e612e847c3da3e8f50a0d45d7ae9ea6e0
parent83cd5db43517cfd977b0d288b179f794677ba1a7 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue7
-rw-r--r--app/assets/javascripts/diffs/components/diff_expansion_cell.vue47
-rw-r--r--app/assets/javascripts/diffs/components/diff_view.vue43
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue7
-rw-r--r--app/assets/stylesheets/framework/diffs.scss21
-rw-r--r--app/assets/stylesheets/highlight/common.scss30
-rw-r--r--app/assets/stylesheets/highlight/themes/dark.scss4
-rw-r--r--app/assets/stylesheets/highlight/themes/monokai.scss4
-rw-r--r--app/assets/stylesheets/highlight/themes/none.scss4
-rw-r--r--app/assets/stylesheets/highlight/themes/solarized-dark.scss4
-rw-r--r--app/assets/stylesheets/highlight/themes/solarized-light.scss4
-rw-r--r--app/assets/stylesheets/highlight/white_base.scss13
-rw-r--r--app/controllers/projects/merge_requests_controller.rb1
-rw-r--r--config/feature_flags/development/updated_diff_expansion_buttons.yml8
-rw-r--r--doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md12
-rw-r--r--doc/api/issue_links.md100
-rw-r--r--doc/development/database/background_migrations.md2
-rw-r--r--doc/user/group/epics/img/epics_filter_v14_7.png (renamed from doc/user/group/epics/img/epics_search_v14_7.png)bin40250 -> 40250 bytes
-rw-r--r--doc/user/group/epics/manage_epics.md20
-rw-r--r--doc/user/project/issues/index.md2
-rw-r--r--doc/user/project/issues/managing_issues.md24
-rw-r--r--doc/user/project/merge_requests/index.md18
-rw-r--r--doc/user/search/index.md66
-rw-r--r--lib/api/issue_links.rb16
-rw-r--r--spec/frontend/diffs/components/diff_expansion_cell_spec.js11
-rw-r--r--spec/frontend/diffs/components/diff_view_spec.js16
-rw-r--r--spec/requests/api/issue_links_spec.rb81
27 files changed, 270 insertions, 295 deletions
diff --git a/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue b/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue
index 209e4629830..c0d6e32a739 100644
--- a/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue
+++ b/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue
@@ -101,6 +101,9 @@ export default {
deleteTable: __('Delete table'),
editTableActions: __('Edit table'),
},
+ dropdownPopperOpts: {
+ positionFixed: true,
+ },
};
</script>
<template>
@@ -124,9 +127,7 @@ export default {
no-caret
text-sr-only
:text="$options.i18n.editTableActions"
- :popper-opts="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ {
- positionFixed: true,
- } /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */"
+ :popper-opts="$options.dropdownPopperOpts"
@hide="handleHide($event)"
>
<gl-dropdown-item @click="runCommand('addColumnBefore')">
diff --git a/app/assets/javascripts/diffs/components/diff_expansion_cell.vue b/app/assets/javascripts/diffs/components/diff_expansion_cell.vue
index 4e7dc578193..fc5766a23ef 100644
--- a/app/assets/javascripts/diffs/components/diff_expansion_cell.vue
+++ b/app/assets/javascripts/diffs/components/diff_expansion_cell.vue
@@ -3,7 +3,6 @@ import { GlTooltipDirective, GlSafeHtmlDirective, GlIcon, GlLoadingIcon } from '
import { mapActions } from 'vuex';
import createFlash from '~/flash';
import { s__, sprintf } from '~/locale';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { UNFOLD_COUNT, INLINE_DIFF_LINES_KEY } from '../constants';
import * as utils from '../store/utils';
@@ -24,7 +23,6 @@ export default {
GlTooltip: GlTooltipDirective,
SafeHtml: GlSafeHtmlDirective,
},
- mixins: [glFeatureFlagsMixin()],
props: {
file: {
type: Object,
@@ -93,25 +91,16 @@ export default {
nextLineNumbers = {},
) {
this.loadMoreLines({ endpoint, params, lineNumbers, fileHash, isExpandDown, nextLineNumbers })
- .then(() => {
- this.isRequesting = false;
- })
.catch(() => {
createFlash({
message: s__('Diffs|Something went wrong while fetching diff lines.'),
});
- this.isRequesting = false;
})
.finally(() => {
this.loading = { up: false, down: false, all: false };
});
},
handleExpandLines(type = EXPAND_ALL) {
- if (this.isRequesting) {
- return;
- }
-
- this.isRequesting = true;
const endpoint = this.file.context_lines_path;
const oldLineNumber = this.line.meta_data.old_pos || 0;
const newLineNumber = this.line.meta_data.new_pos || 0;
@@ -228,10 +217,7 @@ export default {
</script>
<template>
- <div
- v-if="glFeatures.updatedDiffExpansionButtons"
- class="diff-grid-row diff-grid-row-full diff-tr line_holder match expansion"
- >
+ <div class="diff-grid-row diff-grid-row-full diff-tr line_holder match expansion">
<div :class="{ parallel: !inline }" class="diff-grid-left diff-grid-2-col left-side">
<div
class="diff-td diff-line-num gl-text-center! gl-p-0! gl-w-full! gl-display-flex gl-flex-direction-column"
@@ -240,6 +226,7 @@ export default {
v-if="showExpandDown"
v-gl-tooltip.left
:title="s__('Diffs|Next 20 lines')"
+ :disabled="loading.down"
type="button"
class="js-unfold-down gl-rounded-0 gl-border-0 diff-line-expand-button"
@click="handleExpandLines($options.EXPAND_DOWN)"
@@ -251,6 +238,7 @@ export default {
v-if="lineCountBetween !== -1 && lineCountBetween < 20"
v-gl-tooltip.left
:title="s__('Diffs|Expand all lines')"
+ :disabled="loading.all"
type="button"
class="js-unfold-all gl-rounded-0 gl-border-0 diff-line-expand-button"
@click="handleExpandLines()"
@@ -262,6 +250,7 @@ export default {
v-if="showExpandUp"
v-gl-tooltip.left
:title="s__('Diffs|Previous 20 lines')"
+ :disabled="loading.up"
type="button"
class="js-unfold gl-rounded-0 gl-border-0 diff-line-expand-button"
@click="handleExpandLines($options.EXPAND_UP)"
@@ -276,32 +265,4 @@ export default {
></div>
</div>
</div>
- <div v-else class="content js-line-expansion-content">
- <button
- type="button"
- :disabled="!canExpandDown"
- class="js-unfold-down gl-mx-2 gl-py-4 gl-cursor-pointer"
- @click="handleExpandLines($options.EXPAND_DOWN)"
- >
- <gl-icon :size="12" name="expand-down" />
- <span>{{ $options.i18n.showMore }}</span>
- </button>
- <button
- type="button"
- class="js-unfold-all gl-mx-2 gl-py-4 gl-cursor-pointer"
- @click="handleExpandLines()"
- >
- <gl-icon :size="12" name="expand" />
- <span>{{ $options.i18n.showAll }}</span>
- </button>
- <button
- type="button"
- :disabled="!canExpandUp"
- class="js-unfold gl-mx-2 gl-py-4 gl-cursor-pointer"
- @click="handleExpandLines($options.EXPAND_UP)"
- >
- <gl-icon :size="12" name="expand-up" />
- <span>{{ $options.i18n.showMore }}</span>
- </button>
- </div>
</template>
diff --git a/app/assets/javascripts/diffs/components/diff_view.vue b/app/assets/javascripts/diffs/components/diff_view.vue
index 529f8e0a2f9..d740d5adcb6 100644
--- a/app/assets/javascripts/diffs/components/diff_view.vue
+++ b/app/assets/javascripts/diffs/components/diff_view.vue
@@ -6,7 +6,6 @@ import DraftNote from '~/batch_comments/components/draft_note.vue';
import draftCommentsMixin from '~/diffs/mixins/draft_comments';
import { getCommentedLines } from '~/notes/components/multiline_comment_utils';
import { hide } from '~/tooltips';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { pickDirection } from '../utils/diff_line';
import DiffCommentCell from './diff_comment_cell.vue';
import DiffExpansionCell from './diff_expansion_cell.vue';
@@ -23,11 +22,7 @@ export default {
directives: {
SafeHtml,
},
- mixins: [
- draftCommentsMixin,
- glFeatureFlagsMixin(),
- IdState({ idProp: (vm) => vm.diffFile.file_hash }),
- ],
+ mixins: [draftCommentsMixin, IdState({ idProp: (vm) => vm.diffFile.file_hash })],
props: {
diffFile: {
type: Object,
@@ -171,7 +166,6 @@ export default {
<template v-for="(line, index) in diffLines">
<template v-if="line.isMatchLineLeft || line.isMatchLineRight">
<diff-expansion-cell
- v-if="glFeatures.updatedDiffExpansionButtons"
:key="`expand-${index}`"
:file="diffFile"
:line="line.left"
@@ -180,41 +174,6 @@ export default {
:inline="inline"
:line-count-between="getCountBetweenIndex(index)"
/>
- <template v-else>
- <div :key="`expand-${index}`" class="diff-tr line_expansion old-line_expansion match">
- <div class="diff-td text-center gl-font-regular">
- <diff-expansion-cell
- :file="diffFile"
- :context-lines-path="diffFile.context_lines_path"
- :line="line.left"
- :is-top="index === 0"
- :is-bottom="index + 1 === diffLinesLength"
- :inline="inline"
- />
- </div>
- </div>
- <div
- v-if="line.left.rich_text"
- :key="`expand-definition-${index}`"
- class="diff-grid-row diff-tr line_holder match"
- >
- <div class="diff-grid-left diff-grid-3-col left-side">
- <div class="diff-td diff-line-num"></div>
- <div v-if="inline" class="diff-td diff-line-num"></div>
- <div
- v-safe-html="line.left.rich_text"
- class="diff-td line_content left-side gl-white-space-normal!"
- ></div>
- </div>
- <div v-if="!inline" class="diff-grid-right diff-grid-3-col right-side">
- <div class="diff-td diff-line-num"></div>
- <div
- v-safe-html="line.left.rich_text"
- class="diff-td line_content right-side gl-white-space-normal!"
- ></div>
- </div>
- </div>
- </template>
</template>
<diff-row
v-if="!line.isMatchLineLeft && !line.isMatchLineRight"
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue
index 008b5780ecd..f83d8e644cb 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue
@@ -24,6 +24,9 @@ export default {
i18n: {
stage: __('Stage:'),
},
+ dropdownPopperOpts: {
+ placement: 'bottom',
+ },
components: {
CiIcon,
GlLoadingIcon,
@@ -114,9 +117,7 @@ export default {
variant="link"
:aria-label="stageAriaLabel(stage.title)"
:lazy="true"
- :popper-opts="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ {
- placement: 'bottom',
- } /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */"
+ :popper-opts="$options.dropdownPopperOpts"
:toggle-class="['gl-rounded-full!']"
menu-class="mini-pipeline-graph-dropdown-menu"
@hide="onHideDropdown"
diff --git a/app/assets/stylesheets/framework/diffs.scss b/app/assets/stylesheets/framework/diffs.scss
index 760fd6ccbd3..5e3fc5be317 100644
--- a/app/assets/stylesheets/framework/diffs.scss
+++ b/app/assets/stylesheets/framework/diffs.scss
@@ -456,19 +456,6 @@ table.code {
table-layout: fixed;
border-radius: 0 0 $border-radius-default $border-radius-default;
- .diff-tr:first-of-type.line_expansion > .diff-td,
- tr:first-of-type.line_expansion > td {
- border-top: 0;
- }
-
- .diff-tr:nth-last-of-type(2).line_expansion > .diff-td,
- tr:nth-last-of-type(2).line_expansion,
- tr:last-of-type.line_expansion {
- > td {
- border-bottom: 0;
- }
- }
-
.diff-tr.line_holder .diff-td,
tr.line_holder td {
line-height: $code-line-height;
@@ -611,10 +598,6 @@ table.code {
grid-template-columns: 50px 8px 0 1fr;
}
- .diff-grid-3-col {
- grid-template-columns: 50px 1fr !important;
- }
-
.diff-grid-2-col {
grid-template-columns: 100px 1fr !important;
@@ -623,10 +606,6 @@ table.code {
}
}
- &.inline-diff-view .diff-grid-3-col {
- grid-template-columns: 50px 50px 1fr !important;
- }
-
.diff-grid-comments {
display: grid;
grid-template-columns: 1fr 1fr;
diff --git a/app/assets/stylesheets/highlight/common.scss b/app/assets/stylesheets/highlight/common.scss
index 433141ae690..5c58d220075 100644
--- a/app/assets/stylesheets/highlight/common.scss
+++ b/app/assets/stylesheets/highlight/common.scss
@@ -29,36 +29,6 @@
}
}
-@mixin old-diff-expansion($background, $border, $link) {
- background-color: $background;
-
- .diff-td,
- td {
- border-top: 1px solid $border;
- border-bottom: 1px solid $border;
- }
-
- button {
- color: $link;
- border: 0;
- background: transparent;
-
- &[disabled] {
- color: desaturate($link, 100%);
- opacity: 0.5;
- cursor: default;
- }
-
- &:hover:not([disabled]) {
- text-decoration: underline;
- }
-
- &:not(:focus-visible) {
- outline: 0;
- }
- }
-}
-
@mixin dark-diff-expansion-line {
&.expansion .diff-td {
diff --git a/app/assets/stylesheets/highlight/themes/dark.scss b/app/assets/stylesheets/highlight/themes/dark.scss
index 0eeebdb2e7a..f4d9909d81f 100644
--- a/app/assets/stylesheets/highlight/themes/dark.scss
+++ b/app/assets/stylesheets/highlight/themes/dark.scss
@@ -154,10 +154,6 @@ $dark-il: #de935f;
color: $dark-line-color;
}
- .old-line_expansion {
- @include old-diff-expansion($dark-main-bg, $dark-border, $dark-na);
- }
-
.diff-line-expand-button {
@include diff-expansion($gray-600, $gray-200, $gray-300, $white);
}
diff --git a/app/assets/stylesheets/highlight/themes/monokai.scss b/app/assets/stylesheets/highlight/themes/monokai.scss
index b8cd97d6504..4a6d06a6444 100644
--- a/app/assets/stylesheets/highlight/themes/monokai.scss
+++ b/app/assets/stylesheets/highlight/themes/monokai.scss
@@ -125,10 +125,6 @@ $monokai-gh: #75715e;
color: $monokai-text-color;
}
- .old-line_expansion {
- @include old-diff-expansion($monokai-bg, $monokai-border, $monokai-k);
- }
-
.diff-line-expand-button {
@include diff-expansion($gray-600, $gray-200, $gray-300, $white);
}
diff --git a/app/assets/stylesheets/highlight/themes/none.scss b/app/assets/stylesheets/highlight/themes/none.scss
index 99a3de23c26..2f35126dd3b 100644
--- a/app/assets/stylesheets/highlight/themes/none.scss
+++ b/app/assets/stylesheets/highlight/themes/none.scss
@@ -44,10 +44,6 @@
color: $gl-text-color;
}
- .old-line_expansion {
- @include old-diff-expansion($gray-light, $white-normal, $gl-text-color);
- }
-
.diff-line-expand-button {
@include diff-expansion($gray-100, $gray-700, $gray-200, $gray-800);
}
diff --git a/app/assets/stylesheets/highlight/themes/solarized-dark.scss b/app/assets/stylesheets/highlight/themes/solarized-dark.scss
index 55d17b8f1d2..acfc98c13ab 100644
--- a/app/assets/stylesheets/highlight/themes/solarized-dark.scss
+++ b/app/assets/stylesheets/highlight/themes/solarized-dark.scss
@@ -128,10 +128,6 @@ $solarized-dark-il: #2aa198;
color: $solarized-dark-pre-color;
}
- .old-line_expansion {
- @include old-diff-expansion($solarized-dark-line-bg, $solarized-dark-border, $solarized-dark-kd);
- }
-
.diff-line-expand-button {
@include diff-expansion(lighten($solarized-dark-pre-bg, 10%), $gray-200, lighten($solarized-dark-pre-bg, 20%), $white);
}
diff --git a/app/assets/stylesheets/highlight/themes/solarized-light.scss b/app/assets/stylesheets/highlight/themes/solarized-light.scss
index 72b961097e4..74448317270 100644
--- a/app/assets/stylesheets/highlight/themes/solarized-light.scss
+++ b/app/assets/stylesheets/highlight/themes/solarized-light.scss
@@ -134,10 +134,6 @@ $solarized-light-il: #2aa198;
background-color: $solarized-light-pre-bg;
color: $solarized-light-pre-color;
}
-
- .old-line_expansion {
- @include old-diff-expansion($solarized-light-line-bg, $solarized-light-border, $solarized-light-kd);
- }
.diff-line-expand-button {
@include diff-expansion($gray-100, $gray-700, $gray-200, $gray-800);
diff --git a/app/assets/stylesheets/highlight/white_base.scss b/app/assets/stylesheets/highlight/white_base.scss
index b984c194033..aac8ccde96e 100644
--- a/app/assets/stylesheets/highlight/white_base.scss
+++ b/app/assets/stylesheets/highlight/white_base.scss
@@ -133,19 +133,6 @@ pre.code,
color: $white-code-color;
}
-.old-line_expansion {
- @include old-diff-expansion($gray-light, $border-color, $blue-600);
-
- &.diff-tr:last-child {
- border-bottom-right-radius: 4px;
- border-bottom-left-radius: 4px;
-
- .diff-td {
- border-bottom: 0;
- }
- }
-}
-
.diff-line-expand-button {
@include diff-expansion($gray-100, $gray-700, $gray-200, $gray-800);
}
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 79289fe1c2e..176adaf094e 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -44,7 +44,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:rebase_without_ci_ui, project)
push_frontend_feature_flag(:issue_assignees_widget, @project)
push_frontend_feature_flag(:realtime_labels, project)
- push_frontend_feature_flag(:updated_diff_expansion_buttons, project)
push_frontend_feature_flag(:refactor_security_extension, @project)
push_frontend_feature_flag(:mr_attention_requests, current_user)
push_frontend_feature_flag(:remove_diff_header_icons, project)
diff --git a/config/feature_flags/development/updated_diff_expansion_buttons.yml b/config/feature_flags/development/updated_diff_expansion_buttons.yml
deleted file mode 100644
index a566eab6047..00000000000
--- a/config/feature_flags/development/updated_diff_expansion_buttons.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: updated_diff_expansion_buttons
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80890
-rollout_issue_url:
-milestone: '14.10'
-type: development
-group: group::code review
-default_enabled: true
diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
index 831015b3e59..64c51ead46d 100644
--- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
+++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
@@ -296,18 +296,6 @@ namespace = Namespace.find_by_full_path("<new_namespace>")
::Projects::TransferService.new(p, current_user).execute(namespace)
```
-### For Removing webhooks that is getting timeout due to large webhook logs
-
-```ruby
-# ID is the webhook_id
-hook=WebHook.find(ID)
-
-WebHooks::DestroyService.new(current_user).execute(hook)
-
-#In case the service gets timeout consider removing webhook_logs
-hook.web_hook_logs.limit(BATCH_SIZE).delete_all
-```
-
### Bulk update service integration password for _all_ projects
For example, change the Jira user's password for all projects that have the Jira
diff --git a/doc/api/issue_links.md b/doc/api/issue_links.md
index ac26d2a3d17..eb9e8e8adc0 100644
--- a/doc/api/issue_links.md
+++ b/doc/api/issue_links.md
@@ -63,6 +63,106 @@ Parameters:
]
```
+## Get an issue link
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/88228) in GitLab 15.1.
+
+Gets details about an issue link.
+
+```plaintext
+GET /projects/:id/issues/:issue_iid/links/:issue_link_id
+```
+
+Supported attributes:
+
+| Attribute | Type | Required | Description |
+|-----------------|----------------|------------------------|-----------------------------------------------------------------------------|
+| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding). |
+| `issue_iid` | integer | **{check-circle}** Yes | Internal ID of a project's issue. |
+| `issue_link_id` | integer/string | **{check-circle}** Yes | ID of an issue relationship. |
+
+Response body attributes:
+
+| Attribute | Type | Description |
+|:---------------|:-------|:------------------------------------------------------------------------------------------|
+| `source_issue` | object | Details of the source issue of the relationship. |
+| `target_issue` | object | Details of the target issue of the relationship. |
+| `link_type` | string | Type of the relationship. Possible values are `relates_to`, `blocks` and `is_blocked_by`. |
+
+Example request:
+
+```shell
+curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/84/issues/14/links/1"
+```
+
+Example response:
+
+```json
+{
+ "source_issue" : {
+ "id" : 83,
+ "iid" : 11,
+ "project_id" : 4,
+ "created_at" : "2016-01-07T12:44:33.959Z",
+ "title" : "Issues with auth",
+ "state" : "opened",
+ "assignees" : [],
+ "assignee" : null,
+ "labels" : [
+ "bug"
+ ],
+ "author" : {
+ "name" : "Alexandra Bashirian",
+ "avatar_url" : null,
+ "state" : "active",
+ "web_url" : "https://gitlab.example.com/eileen.lowe",
+ "id" : 18,
+ "username" : "eileen.lowe"
+ },
+ "description" : null,
+ "updated_at" : "2016-01-07T12:44:33.959Z",
+ "milestone" : null,
+ "subscribed" : true,
+ "user_notes_count": 0,
+ "due_date": null,
+ "web_url": "http://example.com/example/example/issues/11",
+ "confidential": false,
+ "weight": null
+ },
+ "target_issue" : {
+ "id" : 84,
+ "iid" : 14,
+ "project_id" : 4,
+ "created_at" : "2016-01-07T12:44:33.959Z",
+ "title" : "Issues with auth",
+ "state" : "opened",
+ "assignees" : [],
+ "assignee" : null,
+ "labels" : [
+ "bug"
+ ],
+ "author" : {
+ "name" : "Alexandra Bashirian",
+ "avatar_url" : null,
+ "state" : "active",
+ "web_url" : "https://gitlab.example.com/eileen.lowe",
+ "id" : 18,
+ "username" : "eileen.lowe"
+ },
+ "description" : null,
+ "updated_at" : "2016-01-07T12:44:33.959Z",
+ "milestone" : null,
+ "subscribed" : true,
+ "user_notes_count": 0,
+ "due_date": null,
+ "web_url": "http://example.com/example/example/issues/14",
+ "confidential": false,
+ "weight": null
+ },
+ "link_type": "relates_to"
+}
+```
+
## Create an issue link
Creates a two-way relation between two issues. The user must be allowed to
diff --git a/doc/development/database/background_migrations.md b/doc/development/database/background_migrations.md
index ab52dfad018..4d20d85fce2 100644
--- a/doc/development/database/background_migrations.md
+++ b/doc/development/database/background_migrations.md
@@ -100,7 +100,7 @@ to automatically split the job into batches:
```ruby
queue_background_migration_jobs_by_range_at_intervals(
ClassName,
- BackgroundMigrationClassName,
+ 'BackgroundMigrationClassName',
2.minutes,
batch_size: 10_000
)
diff --git a/doc/user/group/epics/img/epics_search_v14_7.png b/doc/user/group/epics/img/epics_filter_v14_7.png
index baed532c736..baed532c736 100644
--- a/doc/user/group/epics/img/epics_search_v14_7.png
+++ b/doc/user/group/epics/img/epics_filter_v14_7.png
Binary files differ
diff --git a/doc/user/group/epics/manage_epics.md b/doc/user/group/epics/manage_epics.md
index e8f720238ed..cead676f136 100644
--- a/doc/user/group/epics/manage_epics.md
+++ b/doc/user/group/epics/manage_epics.md
@@ -187,17 +187,17 @@ To view epics in a group:
The total count of open epics displayed in the sidebar is cached if higher
than 1000. The cached value is rounded to thousands or millions and updated every 24 hours.
-## Search for an epic from epics list page
+## Filter the list of epics
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/37081) from GitLab Ultimate to GitLab Premium in 12.8.
-> - Searching by the user's reaction emoji [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/325630) in GitLab 13.11.
+> - Filtering by epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/195704) in GitLab 12.9.
+> - Filtering by child epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9029) in GitLab 13.0.
+> - Filtering by the user's reaction emoji [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/325630) in GitLab 13.11.
> - Sorting by epic titles [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/331625) in GitLab 14.1.
-> - Searching by milestone and confidentiality [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/268372) in GitLab 14.2 [with a flag](../../../administration/feature_flags.md) named `vue_epics_list`. Disabled by default.
+> - Filtering by milestone and confidentiality [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/268372) in GitLab 14.2 [with a flag](../../../administration/feature_flags.md) named `vue_epics_list`. Disabled by default.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/276189) in GitLab 14.7.
> - [Feature flag `vue_epics_list`](https://gitlab.com/gitlab-org/gitlab/-/issues/327320) removed in GitLab 14.8.
-You can search for an epic from the list of epics using filtered search bar based on following
-parameters:
+You can filter the list of epics by:
- Title or description
- Author name / username
@@ -206,9 +206,9 @@ parameters:
- Confidentiality
- Reaction emoji
-![epics search](img/epics_search_v14_7.png)
+![epics filter](img/epics_filter_v14_7.png)
-To search:
+To filter:
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Epics**.
@@ -216,7 +216,9 @@ To search:
1. From the dropdown menu, select the scope or enter plain text to search by epic title or description.
1. Press <kbd>Enter</kbd> on your keyboard. The list is filtered.
-You can also sort epics list by:
+## Sort the list of epics
+
+You can sort the epics list by:
- Start date
- Due date
diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md
index bd0cf92e320..a2dbc8581d9 100644
--- a/doc/user/project/issues/index.md
+++ b/doc/user/project/issues/index.md
@@ -45,7 +45,7 @@ To learn how the GitLab Strategic Marketing department uses GitLab issues with [
- [Health status](managing_issues.md#health-status)
- [Cross-link issues](crosslinking_issues.md)
- [Sort issue lists](sorting_issue_lists.md)
-- [Search for issues](../../search/index.md#filter-issue-and-merge-request-lists)
+- [Search for issues](managing_issues.md#filter-the-list-of-issues)
- [Epics](../../group/epics/index.md)
- [Issue boards](../issue_board.md)
- [Issues API](../../../api/issues.md)
diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md
index ca151e1a28e..fbdce211295 100644
--- a/doc/user/project/issues/managing_issues.md
+++ b/doc/user/project/issues/managing_issues.md
@@ -576,6 +576,30 @@ Or:
- To use a [keyboard shortcut](../../shortcuts.md), press <kbd>Shift</kbd> + <kbd>i</kbd>.
- On the top bar, on the top right, select **{issues}** **Issues**.
+## Filter the list of issues
+
+> - Filtering by iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6.
+> - Filtering by iterations was moved from GitLab Ultimate to GitLab Premium in 13.9.
+> - Filtering by type was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322755) in GitLab 13.10 [with a flag](../../../administration/feature_flags.md) named `vue_issues_list`. Disabled by default.
+> - Filtering by type was [enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/322755) in GitLab 14.10.
+> - Filtering by type is generally available in GitLab 15.1. [Feature flag `vue_issues_list`](https://gitlab.com/gitlab-org/gitlab/-/issues/359966) removed.
+
+To filter the list of issues:
+
+1. Above the list of issues, select **Search or filter results...**.
+1. In the dropdown list that appears, select the attribute you want to filter by.
+1. Select or type the operator to use for filtering the attribute. The following operators are
+ available:
+ - `=`: Is
+ - `!=`: Is not ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18059) in GitLab 12.7)
+1. Enter the text to filter the attribute by.
+ You can filter some attributes by **None** or **Any**.
+1. Repeat this process to filter by multiple attributes. Multiple attributes are joined by a logical
+ `AND`.
+
+GitLab displays the results on-screen, but you can also
+[retrieve them as an RSS feed](../../search/index.md#retrieve-search-results-as-feed).
+
### Filter issues by ID
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39908) in GitLab 12.1.
diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md
index c2f0eacebd4..30b69c2fff5 100644
--- a/doc/user/project/merge_requests/index.md
+++ b/doc/user/project/merge_requests/index.md
@@ -60,6 +60,24 @@ Or:
- [Review requests](reviews/index.md).
- Merge requests assigned.
+## Filter the list of merge requests
+
+To filter the list of merge requests:
+
+1. Above the list of merge requests, select **Search or filter results...**.
+1. In the dropdown list that appears, select the attribute you wish to filter by.
+1. Select or type the operator to use for filtering the attribute. The following operators are
+ available:
+ - `=`: Is
+ - `!=`: Is not ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18059) in GitLab 12.7)
+1. Enter the text to filter the attribute by.
+ You can filter some attributes by **None** or **Any**.
+1. Repeat this process to filter by multiple attributes. Multiple attributes are joined by a logical
+ `AND`.
+
+GitLab displays the results on-screen, but you can also
+[retrieve them as an RSS feed](../../search/index.md#retrieve-search-results-as-feed).
+
### Filter merge requests by ID
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39908) in GitLab 12.1.
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index b70f060091f..28d4bf22689 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -31,6 +31,7 @@ Use basic search to find:
## Perform a search
To start a search, type your search query in the search bar on the top-right of the screen.
+You must type at least two characters.
![basic search](img/basic_search_v15_1.png)
@@ -75,47 +76,6 @@ and gives you the option to return to the search results page.
![project SHA search redirect](img/project_search_sha_redirect.png)
-## Filter issue and merge request lists
-
-> - Filtering by epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/195704) in GitLab 12.9.
-> - Filtering by child epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9029) in GitLab 13.0.
-> - Filtering by iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6.
-> - Filtering by iterations was moved from GitLab Ultimate to GitLab Premium in 13.9.
-> - Filtering by type was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322755) in GitLab 13.10 [with a flag](../../administration/feature_flags.md) named `vue_issues_list`. Disabled by default.
-> - Filtering by type was [enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/322755) in GitLab 14.10.
-> - Filtering by type is generally available in GitLab 15.1. [Feature flag `vue_issues_list`](https://gitlab.com/gitlab-org/gitlab/-/issues/359966) removed.
-> - Filtering by attention request was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/343528) in GitLab 14.10 [with a flag](../../administration/feature_flags.md) named `mr_attention_requests`. Disabled by default.
-
-Follow these steps to filter the **Issues** and **Merge requests** list pages in projects and
-groups:
-
-1. Select **Search or filter results...**.
-1. In the dropdown list that appears, select the attribute you wish to filter by:
- - Assignee
- - [Attention requests](../project/merge_requests/index.md#request-attention-to-a-merge-request)
- - Author
- - Confidential
- - [Epic and child Epic](../group/epics/index.md) (available only for the group the Epic was created, not for [higher group levels](https://gitlab.com/gitlab-org/gitlab/-/issues/233729)).
- - [Iteration](../group/iterations/index.md)
- - [Label](../project/labels.md)
- - [Milestone](../project/milestones/index.md)
- - My-reaction
- - Release
- - Type
- - Weight
- - Search for this text
-1. Select or type the operator to use for filtering the attribute. The following operators are
- available:
- - `=`: Is
- - `!=`: Is not ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18059) in GitLab 12.7)
-1. Enter the text to [filter the attribute by](#filters-autocomplete).
- You can filter some attributes by **None** or **Any**.
-1. Repeat this process to filter by multiple attributes. Multiple attributes are joined by a logical
- `AND`.
-
-GitLab displays the results on-screen, but you can also
-[retrieve them as an RSS feed](#retrieve-search-results-as-feed).
-
## Searching for specific terms
You can filter issues and merge requests by specific terms included in titles or descriptions.
@@ -138,23 +98,12 @@ RSS feed of search results:
1. Go to your project's page.
1. On the left sidebar, select **Issues** or **Merge requests**.
-1. Build your search query as described in [Filter issue and merge request lists](#filter-issue-and-merge-request-lists).
+1. Perform a search.
1. Select the feed symbol **{rss}** to display the results as an RSS feed in Atom format.
The URL of the result contains both a feed token, and your search query.
You can add this URL to your feed reader.
-## Filters autocomplete
-
-GitLab provides many filters across many pages (issues, merge requests, epics,
-and pipelines among others) which you can use to narrow down your search. When
-using the filter functionality, you can start typing characters to bring up
-relevant users or other attributes.
-
-For performance optimization, there is a requirement of a minimum of three
-characters to begin your search. To search for issues with the assignee `Simone Presley`,
-you must type at least `Sim` before autocomplete displays results.
-
## Search history
Search history is available for issues and merge requests, and is stored locally
@@ -175,17 +124,6 @@ Some filters can be added multiple times. These include but are not limited to a
![multiple assignees filtering](img/multiple_assignees.png)
-## Groups
-
-You can search through your groups from
-the left menu, by clicking the menu bar, then **Groups**.
-
-On the field **Filter by name**, type the group name you want to find, and GitLab
-filters them for you as you type.
-
-You can also **Explore** all public and internal groups available in GitLab.com,
-and sort them by **Name**, **Last created**, **Oldest created**, or **Updated date**.
-
## Issue boards
From an [issue board](../../user/project/issue_board.md), you can filter issues by **Author**, **Assignee**, **Milestone**, and **Labels**.
diff --git a/lib/api/issue_links.rb b/lib/api/issue_links.rb
index cf075af8373..c07c2c1994e 100644
--- a/lib/api/issue_links.rb
+++ b/lib/api/issue_links.rb
@@ -61,6 +61,22 @@ module API
end
# rubocop: enable CodeReuse/ActiveRecord
+ desc 'Get issues relation' do
+ detail 'This feature was introduced in GitLab 15.1.'
+ success Entities::IssueLink
+ end
+ params do
+ requires :issue_link_id, type: Integer, desc: 'The ID of an issue link'
+ end
+ get ':id/issues/:issue_iid/links/:issue_link_id' do
+ issue = find_project_issue(params[:issue_iid])
+ issue_link = IssueLink.for_source_or_target(issue).find(declared_params[:issue_link_id])
+
+ find_project_issue(issue_link.target.iid.to_s, issue_link.target.project_id.to_s)
+
+ present issue_link, with: Entities::IssueLink
+ end
+
desc 'Remove issues relation' do
success Entities::IssueLink
end
diff --git a/spec/frontend/diffs/components/diff_expansion_cell_spec.js b/spec/frontend/diffs/components/diff_expansion_cell_spec.js
index bd538996349..5ff0728b358 100644
--- a/spec/frontend/diffs/components/diff_expansion_cell_spec.js
+++ b/spec/frontend/diffs/components/diff_expansion_cell_spec.js
@@ -1,4 +1,3 @@
-import { getByText } from '@testing-library/dom';
import { mount } from '@vue/test-utils';
import { cloneDeep } from 'lodash';
import DiffExpansionCell from '~/diffs/components/diff_expansion_cell.vue';
@@ -81,7 +80,7 @@ describe('DiffExpansionCell', () => {
const findExpandUp = (wrapper) => wrapper.find(EXPAND_UP_CLASS);
const findExpandDown = (wrapper) => wrapper.find(EXPAND_DOWN_CLASS);
- const findExpandAll = ({ element }) => getByText(element, 'Show all unchanged lines');
+ const findExpandAll = (wrapper) => wrapper.find('.js-unfold-all');
describe('top row', () => {
it('should have "expand up" and "show all" option', () => {
@@ -90,9 +89,7 @@ describe('DiffExpansionCell', () => {
});
expect(findExpandUp(wrapper).exists()).toBe(true);
- expect(findExpandDown(wrapper).exists()).toBe(true);
expect(findExpandUp(wrapper).attributes('disabled')).not.toBeDefined();
- expect(findExpandDown(wrapper).attributes('disabled')).toBeDefined();
expect(findExpandAll(wrapper)).not.toBe(null);
});
});
@@ -114,9 +111,7 @@ describe('DiffExpansionCell', () => {
});
expect(findExpandDown(wrapper).exists()).toBe(true);
- expect(findExpandUp(wrapper).exists()).toBe(true);
expect(findExpandDown(wrapper).attributes('disabled')).not.toBeDefined();
- expect(findExpandUp(wrapper).attributes('disabled')).toBeDefined();
expect(findExpandAll(wrapper)).not.toBe(null);
});
});
@@ -144,9 +139,9 @@ describe('DiffExpansionCell', () => {
newLineNumber,
});
- const wrapper = createComponent({ file });
+ const wrapper = createComponent({ file, lineCountBetween: 10 });
- findExpandAll(wrapper).click();
+ findExpandAll(wrapper).trigger('click');
expect(store.dispatch).toHaveBeenCalledWith(
'diffs/loadMoreLines',
diff --git a/spec/frontend/diffs/components/diff_view_spec.js b/spec/frontend/diffs/components/diff_view_spec.js
index f982749d1de..dfbe30e460b 100644
--- a/spec/frontend/diffs/components/diff_view_spec.js
+++ b/spec/frontend/diffs/components/diff_view_spec.js
@@ -49,22 +49,6 @@ describe('DiffView', () => {
return shallowMount(DiffView, { propsData, store, stubs });
};
- it('renders a match line', () => {
- const wrapper = createWrapper({
- diffLines: [
- {
- isMatchLineLeft: true,
- left: {
- rich_text: '@@ -4,12 +4,12 @@ import createFlash from &#39;~/flash&#39;;',
- lineDraft: {},
- },
- },
- ],
- });
- expect(wrapper.find(DiffExpansionCell).exists()).toBe(true);
- expect(wrapper.text()).toContain("@@ -4,12 +4,12 @@ import createFlash from '~/flash';");
- });
-
it.each`
type | side | container | sides | total
${'parallel'} | ${'left'} | ${'.old'} | ${{ left: { lineDraft: {}, renderDiscussion: true }, right: { lineDraft: {}, renderDiscussion: true } }} | ${2}
diff --git a/spec/requests/api/issue_links_spec.rb b/spec/requests/api/issue_links_spec.rb
index 81dd4c3dfa0..90238c8bf76 100644
--- a/spec/requests/api/issue_links_spec.rb
+++ b/spec/requests/api/issue_links_spec.rb
@@ -156,6 +156,87 @@ RSpec.describe API::IssueLinks do
end
end
+ describe 'GET /links/:issue_link_id' do
+ def perform_request(issue_link_id, user = nil, params = {})
+ get api("/projects/#{project.id}/issues/#{issue.iid}/links/#{issue_link_id}", user), params: params
+ end
+
+ context 'when unauthenticated' do
+ it 'returns 401' do
+ issue_link = create(:issue_link)
+
+ perform_request(issue_link.id)
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ context 'when authenticated' do
+ context 'when issue link does not exist' do
+ it 'returns 404' do
+ perform_request(non_existing_record_id, user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ let_it_be(:target_issue) { create(:issue, project: project) }
+
+ context 'when issue link does not belong to the specified issue' do
+ it 'returns 404' do
+ other_issue = create(:issue, project: project)
+ # source is different than the given API route issue
+ issue_link = create(:issue_link, source: other_issue, target: target_issue)
+
+ perform_request(issue_link.id, user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when user has ability to read the issue link' do
+ it 'returns 200' do
+ issue_link = create(:issue_link, source: issue, target: target_issue)
+
+ perform_request(issue_link.id, user)
+
+ aggregate_failures "testing response" do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to match_response_schema('public_api/v4/issue_link')
+ end
+ end
+ end
+
+ context 'when user cannot read issue link' do
+ let(:private_project) { create(:project) }
+ let(:public_project) { create(:project, :public) }
+ let(:public_issue) { create(:issue, project: public_project) }
+
+ context 'when the issue link targets an issue in a non-accessible project' do
+ it 'returns 404' do
+ private_issue = create(:issue, project: private_project)
+ issue_link = create(:issue_link, source: public_issue, target: private_issue)
+
+ perform_request(issue_link.id, user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when issue link targets a non-accessible issue' do
+ it 'returns 404' do
+ confidential_issue = create(:issue, :confidential, project: public_project)
+ issue_link = create(:issue_link, source: public_issue, target: confidential_issue)
+
+ perform_request(issue_link.id, user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+ end
+ end
+
describe 'DELETE /links/:issue_link_id' do
context 'when unauthenticated' do
it 'returns 401' do