Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
83cd5db435
commit
bed53d96d2
|
@ -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')">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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**.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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 '~/flash';',
|
||||
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}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue