Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-07 06:08:35 +00:00
parent 83cd5db435
commit bed53d96d2
27 changed files with 270 additions and 295 deletions

View File

@ -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')">

View File

@ -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>

View File

@ -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"

View File

@ -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"

View File

@ -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;

View File

@ -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 {

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
)

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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.

View File

@ -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**.

View File

@ -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

View File

@ -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',

View File

@ -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}

View File

@ -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