Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
c8a53a38
Commit
c8a53a38
authored
Sep 29, 2021
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab master
parents
6ab0d200
f54f18c0
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
288 additions
and
259 deletions
+288
-259
app/assets/javascripts/diffs/components/app.vue
app/assets/javascripts/diffs/components/app.vue
+15
-0
app/assets/javascripts/issuable_list/components/issuable_item.vue
...ts/javascripts/issuable_list/components/issuable_item.vue
+119
-120
app/assets/javascripts/issuable_list/components/issuable_list_root.vue
...vascripts/issuable_list/components/issuable_list_root.vue
+61
-63
app/assets/javascripts/issues_list/components/issue_card_time_info.vue
...vascripts/issues_list/components/issue_card_time_info.vue
+5
-12
app/assets/javascripts/vue_shared/components/issue/issue_assignees.vue
...vascripts/vue_shared/components/issue/issue_assignees.vue
+2
-3
app/assets/stylesheets/pages/issuable.scss
app/assets/stylesheets/pages/issuable.scss
+27
-27
app/controllers/projects/merge_requests_controller.rb
app/controllers/projects/merge_requests_controller.rb
+1
-0
config/feature_flags/development/mr_changes_fluid_layout.yml
config/feature_flags/development/mr_changes_fluid_layout.yml
+8
-0
config/initializers/backtrace_silencers.rb
config/initializers/backtrace_silencers.rb
+1
-1
doc/ci/chatops/index.md
doc/ci/chatops/index.md
+2
-0
doc/ci/variables/predefined_variables.md
doc/ci/variables/predefined_variables.md
+1
-0
ee/app/assets/javascripts/related_items_tree/components/issue_health_status.vue
...pts/related_items_tree/components/issue_health_status.vue
+2
-2
ee/spec/features/epics/epics_list_spec.rb
ee/spec/features/epics/epics_list_spec.rb
+9
-10
ee/spec/features/projects/quality/test_case_list_spec.rb
ee/spec/features/projects/quality/test_case_list_spec.rb
+5
-6
lib/gitlab/chat/command.rb
lib/gitlab/chat/command.rb
+2
-1
locale/gitlab.pot
locale/gitlab.pot
+3
-0
spec/frontend/diffs/components/app_spec.js
spec/frontend/diffs/components/app_spec.js
+19
-0
spec/frontend/issuable_list/components/issuable_item_spec.js
spec/frontend/issuable_list/components/issuable_item_spec.js
+5
-10
spec/frontend/vue_shared/components/issue/issue_assignees_spec.js
...ntend/vue_shared/components/issue/issue_assignees_spec.js
+0
-4
spec/lib/gitlab/chat/command_spec.rb
spec/lib/gitlab/chat/command_spec.rb
+1
-0
No files found.
app/assets/javascripts/diffs/components/app.vue
View file @
c8a53a38
...
...
@@ -19,6 +19,7 @@ import { updateHistory } from '~/lib/utils/url_utility';
import
{
__
}
from
'
~/locale
'
;
import
MrWidgetHowToMergeModal
from
'
~/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue
'
;
import
PanelResizer
from
'
~/vue_shared/components/panel_resizer.vue
'
;
import
glFeatureFlagsMixin
from
'
~/vue_shared/mixins/gl_feature_flags_mixin
'
;
import
notesEventHub
from
'
../../notes/event_hub
'
;
import
{
...
...
@@ -79,6 +80,7 @@ export default {
MrWidgetHowToMergeModal
,
GlAlert
,
},
mixins
:
[
glFeatureFlagsMixin
()],
alerts
:
{
ALERT_OVERFLOW_HIDDEN
,
ALERT_MERGE_CONFLICT
,
...
...
@@ -252,6 +254,10 @@ export default {
return
this
.
treeWidth
<=
TREE_HIDE_STATS_WIDTH
;
},
isLimitedContainer
()
{
if
(
this
.
glFeatures
.
mrChangesFluidLayout
)
{
return
false
;
}
return
!
this
.
renderFileTree
&&
!
this
.
isParallelView
&&
!
this
.
isFluidLayout
;
},
isFullChangeset
()
{
...
...
@@ -386,6 +392,8 @@ export default {
diffsApp
.
instrument
();
},
created
()
{
this
.
mergeRequestContainers
=
document
.
querySelectorAll
(
'
.merge-request-container
'
);
this
.
adjustView
();
this
.
subscribeToEvents
();
...
...
@@ -513,6 +521,13 @@ export default {
}
else
{
this
.
removeEventListeners
();
}
if
(
!
this
.
isFluidLayout
&&
this
.
glFeatures
.
mrChangesFluidLayout
)
{
this
.
mergeRequestContainers
.
forEach
((
el
)
=>
{
el
.
classList
.
toggle
(
'
limit-container-width
'
,
!
this
.
shouldShow
);
el
.
classList
.
toggle
(
'
container-limited
'
,
!
this
.
shouldShow
);
});
}
},
setEventListeners
()
{
Mousetrap
.
bind
(
keysFor
(
MR_PREVIOUS_FILE_IN_DIFF
),
()
=>
this
.
jumpToFile
(
-
1
));
...
...
app/assets/javascripts/issuable_list/components/issuable_item.vue
View file @
c8a53a38
<
script
>
import
{
GlLink
,
GlIcon
,
GlLabel
,
GlFormCheckbox
,
GlTooltipDirective
}
from
'
@gitlab/ui
'
;
import
{
GlLink
,
GlIcon
,
GlLabel
,
GlFormCheckbox
,
Gl
Sprintf
,
Gl
TooltipDirective
}
from
'
@gitlab/ui
'
;
import
{
getIdFromGraphQLId
}
from
'
~/graphql_shared/utils
'
;
import
{
isScopedLabel
}
from
'
~/lib/utils/common_utils
'
;
...
...
@@ -15,6 +15,7 @@ export default {
GlIcon
,
GlLabel
,
GlFormCheckbox
,
GlSprintf
,
IssuableAssignees
,
},
directives
:
{
...
...
@@ -82,9 +83,7 @@ export default {
return
this
.
issuable
.
assignees
?.
nodes
||
this
.
issuable
.
assignees
||
[];
},
createdAt
()
{
return
sprintf
(
__
(
'
created %{timeAgo}
'
),
{
timeAgo
:
getTimeago
().
format
(
this
.
issuable
.
createdAt
),
});
return
getTimeago
().
format
(
this
.
issuable
.
createdAt
);
},
updatedAt
()
{
return
sprintf
(
__
(
'
updated %{timeAgo}
'
),
{
...
...
@@ -164,132 +163,132 @@ export default {
<
template
>
<li
:id=
"`issuable_$
{issuableId}`"
class="issue gl-px-5!"
class="issue gl-
display-flex! gl-
px-5!"
:class="{ closed: issuable.closedAt, today: createdInPastDay }"
:data-labels="labelIdsString"
>
<div
class=
"issuable-info-container"
>
<div
v-if=
"showCheckbox"
class=
"issue-check"
>
<gl-form-checkbox
class=
"gl-mr-0"
:checked=
"checked"
:data-id=
"issuableId"
@
input=
"$emit('checked-input', $event)"
<gl-form-checkbox
v-if=
"showCheckbox"
class=
"issue-check gl-mr-0"
:checked=
"checked"
:data-id=
"issuableId"
@
input=
"$emit('checked-input', $event)"
>
<span
class=
"gl-sr-only"
>
{{
issuable
.
title
}}
</span>
</gl-form-checkbox>
<div
class=
"issuable-main-info"
>
<div
data-testid=
"issuable-title"
class=
"issue-title title"
>
<gl-icon
v-if=
"issuable.confidential"
v-gl-tooltip
name=
"eye-slash"
:title=
"__('Confidential')"
:aria-label=
"__('Confidential')"
/>
<gl-link
class=
"issue-title-text"
dir=
"auto"
:href=
"webUrl"
v-bind=
"issuableTitleProps"
>
{{
issuable
.
title
}}
<gl-icon
v-if=
"isIssuableUrlExternal"
name=
"external-link"
class=
"gl-ml-2"
/>
</gl-link>
<span
v-if=
"taskStatus"
class=
"task-status gl-display-none gl-sm-display-inline-block! gl-ml-3"
data-testid=
"task-status"
>
<span
class=
"gl-sr-only"
>
{{
issuable
.
title
}}
</span>
</
gl-form-checkbox
>
{{
taskStatus
}}
</
span
>
</div>
<div
class=
"issuable-main-info"
>
<div
data-testid=
"issuable-title"
class=
"issue-title title"
>
<span
class=
"issue-title-text"
dir=
"auto"
>
<gl-icon
v-if=
"issuable.confidential"
v-gl-tooltip
name=
"eye-slash"
:title=
"__('Confidential')"
:aria-label=
"__('Confidential')"
/>
<gl-link
:href=
"webUrl"
v-bind=
"issuableTitleProps"
>
{{
issuable
.
title
}}
<gl-icon
v-if=
"isIssuableUrlExternal"
name=
"external-link"
class=
"gl-ml-2"
/></gl-link>
</span>
<span
v-if=
"taskStatus"
class=
"task-status gl-display-none gl-sm-display-inline-block! gl-ml-3"
data-testid=
"task-status"
>
{{
taskStatus
}}
</span>
</div>
<div
class=
"issuable-info"
>
<slot
v-if=
"hasSlotContents('reference')"
name=
"reference"
></slot>
<span
v-else
data-testid=
"issuable-reference"
class=
"issuable-reference"
>
{{
reference
}}
</span>
<span
class=
"issuable-authored gl-display-none gl-sm-display-inline-block! gl-mr-3"
>
<span
aria-hidden=
"true"
>
·
</span>
<span
v-gl-tooltip:tooltipcontainer
.
bottom
data-testid=
"issuable-created-at"
:title=
"tooltipTitle(issuable.createdAt)"
>
{{
createdAt
}}
</span
>
{{
__
(
'
by
'
)
}}
<slot
v-if=
"hasSlotContents('author')"
name=
"author"
></slot>
<gl-link
v-else
:data-user-id=
"authorId"
:data-username=
"author.username"
:data-name=
"author.name"
:data-avatar-url=
"author.avatarUrl"
:href=
"author.webUrl"
data-testid=
"issuable-author"
class=
"author-link js-user-link"
>
<span
class=
"author"
>
{{
author
.
name
}}
</span>
</gl-link>
<div
class=
"issuable-info"
>
<slot
v-if=
"hasSlotContents('reference')"
name=
"reference"
></slot>
<span
v-else
data-testid=
"issuable-reference"
class=
"issuable-reference"
>
{{
reference
}}
</span>
<span
class=
"gl-display-none gl-sm-display-inline-block"
>
<span
aria-hidden=
"true"
>
·
</span>
<span
class=
"issuable-authored gl-mr-3"
>
<gl-sprintf
:message=
"__('created %
{timeAgo} by %{author}')">
<template
#timeAgo
>
<span
v-gl-tooltip
.
bottom
:title=
"tooltipTitle(issuable.createdAt)"
data-testid=
"issuable-created-at"
>
{{
createdAt
}}
</span>
</
template
>
<
template
#author
>
<slot
v-if=
"hasSlotContents('author')"
name=
"author"
></slot>
<gl-link
v-else
:data-user-id=
"authorId"
:data-username=
"author.username"
:data-name=
"author.name"
:data-avatar-url=
"author.avatarUrl"
:href=
"author.webUrl"
data-testid=
"issuable-author"
class=
"author-link js-user-link"
>
<span
class=
"author"
>
{{
author
.
name
}}
</span>
</gl-link>
</
template
>
</gl-sprintf>
</span>
<slot
name=
"timeframe"
></slot>
<span
v-if=
"labels.length"
role=
"group"
:aria-label=
"__('Labels')"
>
<gl-label
v-for=
"(label, index) in labels"
:key=
"index
"
:background-color=
"label.color
"
:title=
"labelTitle(label)
"
:description=
"label.description
"
:scoped=
"scopedLabel(label)
"
:target=
"labelTarget
(label)"
:class=
"
{ 'gl-ml-2': index }
"
size="sm
"
/>
</span
>
</
div
>
</span>
<span
v-if=
"labels.length"
role=
"group"
:aria-label=
"__('Labels')"
>
<gl-label
v-for=
"(label, index) in labels
"
:key=
"index
"
:background-color=
"label.color
"
:title=
"labelTitle(label)
"
:description=
"label.description
"
:scoped=
"scopedLabel
(label)"
:target=
"labelTarget(label)
"
:class=
"{ 'gl-ml-2': index }
"
size=
"sm"
/
>
</
span
>
</div>
<div
class=
"issuable-meta"
>
<ul
v-if=
"showIssuableMeta"
class=
"controls"
>
<li
v-if=
"hasSlotContents('status')"
class=
"issuable-status"
>
<slot
name=
"status"
></slot>
</li>
<li
v-if=
"assignees.length"
class=
"gl-display-flex"
>
<issuable-assignees
:assignees=
"assignees"
:icon-size=
"16"
:max-visible=
"4"
img-css-classes=
"gl-mr-2!"
class=
"gl-align-items-center gl-display-flex gl-ml-3"
/>
</li>
<slot
name=
"statistics"
></slot>
<li
v-if=
"showDiscussions"
data-testid=
"issuable-discussions"
class=
"issuable-comments gl-display-none gl-sm-display-block"
>
<gl-link
v-gl-tooltip:tooltipcontainer
.
top
:title=
"__('Comments')"
:href=
"issuableNotesLink"
:class=
"
{ 'no-comments': !notesCount }"
class="gl-reset-color!"
>
<gl-icon
name=
"comments"
/>
{{
notesCount
}}
</gl-link>
</li>
</ul>
<div
data-testid=
"issuable-updated-at"
class=
"float-right issuable-updated-at gl-display-none gl-sm-display-inline-block"
</div>
<div
class=
"issuable-meta"
>
<ul
v-if=
"showIssuableMeta"
class=
"controls"
>
<li
v-if=
"hasSlotContents('status')"
class=
"issuable-status"
>
<slot
name=
"status"
></slot>
</li>
<li
v-if=
"assignees.length"
>
<issuable-assignees
:assignees=
"assignees"
:icon-size=
"16"
:max-visible=
"4"
img-css-classes=
"gl-mr-2!"
class=
"gl-align-items-center gl-display-flex gl-ml-3"
/>
</li>
<slot
name=
"statistics"
></slot>
<li
v-if=
"showDiscussions"
data-testid=
"issuable-discussions"
class=
"issuable-comments gl-display-none gl-sm-display-block"
>
<span
v-gl-tooltip:tooltipcontainer
.
bottom
:title=
"tooltipTitle(issuable.updatedAt)"
class=
"issuable-updated-at"
>
{{
updatedAt
}}
</span
<gl-link
v-gl-tooltip
.
top
:title=
"__('Comments')"
:href=
"issuableNotesLink"
:class=
"{ 'no-comments': !notesCount }"
class=
"gl-reset-color!"
>
</div>
<gl-icon
name=
"comments"
/>
{{ notesCount }}
</gl-link>
</li>
</ul>
<div
v-gl-tooltip
.
bottom
class=
"gl-text-gray-500 gl-display-none gl-sm-display-inline-block"
:title=
"tooltipTitle(issuable.updatedAt)"
data-testid=
"issuable-updated-at"
>
{{ updatedAt }}
</div>
</div>
</li>
...
...
app/assets/javascripts/issuable_list/components/issuable_list_root.vue
View file @
c8a53a38
...
...
@@ -284,72 +284,70 @@ export default {
<slot
name=
"sidebar-items"
:checked-issuables=
"bulkEditIssuables"
></slot>
</
template
>
</issuable-bulk-edit-sidebar>
<div
class=
"issuables-holder"
>
<ul
v-if=
"issuablesLoading"
class=
"content-list"
>
<li
v-for=
"n in skeletonItemCount"
:key=
"n"
class=
"issue gl-px-5! gl-py-5!"
>
<gl-skeleton-loading
/>
</li>
</ul>
<
template
v-else
>
<component
:is=
"issuablesWrapper"
v-if=
"issuables.length > 0"
class=
"content-list issuable-list issues-list"
:class=
"
{ 'manual-ordering': isManualOrdering }"
v-bind="$options.vueDraggableAttributes"
@update="handleVueDraggableUpdate"
<ul
v-if=
"issuablesLoading"
class=
"content-list"
>
<li
v-for=
"n in skeletonItemCount"
:key=
"n"
class=
"issue gl-px-5! gl-py-5!"
>
<gl-skeleton-loading
/>
</li>
</ul>
<
template
v-else
>
<component
:is=
"issuablesWrapper"
v-if=
"issuables.length > 0"
class=
"content-list issuable-list issues-list"
:class=
"
{ 'manual-ordering': isManualOrdering }"
v-bind="$options.vueDraggableAttributes"
@update="handleVueDraggableUpdate"
>
<issuable-item
v-for=
"issuable in issuables"
:key=
"issuableId(issuable)"
:class=
"
{ 'gl-cursor-grab': isManualOrdering }"
:issuable-symbol="issuableSymbol"
:issuable="issuable"
:enable-label-permalinks="enableLabelPermalinks"
:label-filter-param="labelFilterParam"
:show-checkbox="showBulkEditSidebar"
:checked="issuableChecked(issuable)"
@checked-input="handleIssuableCheckedInput(issuable, $event)"
>
<issuable-item
v-for=
"issuable in issuables"
:key=
"issuableId(issuable)"
:class=
"
{ 'gl-cursor-grab': isManualOrdering }"
:issuable-symbol="issuableSymbol"
:issuable="issuable"
:enable-label-permalinks="enableLabelPermalinks"
:label-filter-param="labelFilterParam"
:show-checkbox="showBulkEditSidebar"
:checked="issuableChecked(issuable)"
@checked-input="handleIssuableCheckedInput(issuable, $event)"
>
<template
#reference
>
<slot
name=
"reference"
:issuable=
"issuable"
></slot>
</
template
>
<
template
#author
>
<slot
name=
"author"
:author=
"issuable.author"
></slot>
</
template
>
<
template
#timeframe
>
<slot
name=
"timeframe"
:issuable=
"issuable"
></slot>
</
template
>
<
template
#status
>
<slot
name=
"status"
:issuable=
"issuable"
></slot>
</
template
>
<
template
#statistics
>
<slot
name=
"statistics"
:issuable=
"issuable"
></slot>
</
template
>
</issuable-item>
</component>
<slot
v-else
name=
"empty-state"
></slot>
</template>
<template
#reference
>
<slot
name=
"reference"
:issuable=
"issuable"
></slot>
</
template
>
<
template
#author
>
<slot
name=
"author"
:author=
"issuable.author"
></slot>
</
template
>
<
template
#timeframe
>
<slot
name=
"timeframe"
:issuable=
"issuable"
></slot>
</
template
>
<
template
#status
>
<slot
name=
"status"
:issuable=
"issuable"
></slot>
</
template
>
<
template
#statistics
>
<slot
name=
"statistics"
:issuable=
"issuable"
></slot>
</
template
>
</issuable-item>
</component>
<slot
v-else
name=
"empty-state"
></slot>
</template>
<div
v-if=
"showPaginationControls && useKeysetPagination"
class=
"gl-text-center gl-mt-3"
>
<gl-keyset-pagination
:has-next-page=
"hasNextPage"
:has-previous-page=
"hasPreviousPage"
@
next=
"$emit('next-page')"
@
prev=
"$emit('previous-page')"
/>
</div>
<gl-pagination
v-else-if=
"showPaginationControls"
:per-page=
"defaultPageSize"
:total-items=
"totalItems"
:value=
"currentPage"
:prev-page=
"previousPage"
:next-page=
"nextPage"
align=
"center"
class=
"gl-pagination gl-mt-3"
@
input=
"$emit('page-change', $event)"
<div
v-if=
"showPaginationControls && useKeysetPagination"
class=
"gl-text-center gl-mt-3"
>
<gl-keyset-pagination
:has-next-page=
"hasNextPage"
:has-previous-page=
"hasPreviousPage"
@
next=
"$emit('next-page')"
@
prev=
"$emit('previous-page')"
/>
</div>
<gl-pagination
v-else-if=
"showPaginationControls"
:per-page=
"defaultPageSize"
:total-items=
"totalItems"
:value=
"currentPage"
:prev-page=
"previousPage"
:next-page=
"nextPage"
align=
"center"
class=
"gl-pagination gl-mt-3"
@
input=
"$emit('page-change', $event)"
/>
</div>
</template>
app/assets/javascripts/issues_list/components/issue_card_time_info.vue
View file @
c8a53a38
...
...
@@ -85,7 +85,7 @@ export default {
<span>
<span
v-if=
"issue.milestone"
class=
"issuable-milestone gl-
display-none gl-sm-display-inline-block! gl-
mr-3"
class=
"issuable-milestone gl-mr-3"
data-testid=
"issuable-milestone"
>
<gl-link
v-gl-tooltip
:href=
"milestoneLink"
:title=
"milestoneDate"
>
...
...
@@ -96,7 +96,7 @@ export default {
<span
v-if=
"issue.dueDate"
v-gl-tooltip
class=
"issuable-due-date gl-
display-none gl-sm-display-inline-block! gl-
mr-3"
class=
"issuable-due-date gl-mr-3"
:class=
"
{ 'gl-text-red-500': showDueDateInRed }"
:title="__('Due date')"
data-testid="issuable-due-date"
...
...
@@ -107,21 +107,14 @@ export default {
<span
v-if=
"timeEstimate"
v-gl-tooltip
class=
"gl-
display-none gl-sm-display-inline-block! gl-
mr-3"
class=
"gl-mr-3"
:title=
"__('Estimate')"
data-testid=
"time-estimate"
>
<gl-icon
name=
"timer"
/>
{{
timeEstimate
}}
</span>
<weight-count
class=
"issuable-weight gl-display-none gl-sm-display-inline-block gl-mr-3"
:weight=
"issue.weight"
/>
<issue-health-status
v-if=
"showHealthStatus"
class=
"gl-display-none gl-sm-display-inline-block"
:health-status=
"healthStatus"
/>
<weight-count
class=
"issuable-weight gl-mr-3"
:weight=
"issue.weight"
/>
<issue-health-status
v-if=
"showHealthStatus"
:health-status=
"healthStatus"
/>
</span>
</
template
>
app/assets/javascripts/vue_shared/components/issue/issue_assignees.vue
View file @
c8a53a38
...
...
@@ -77,7 +77,7 @@ export default {
};
</
script
>
<
template
>
<div
class=
"issue-assignees"
>
<div>
<user-avatar-link
v-for=
"assignee in assigneesToShow"
:key=
"assignee.id"
...
...
@@ -97,10 +97,9 @@ export default {
</user-avatar-link>
<span
v-if=
"numHiddenAssignees > 0"
v-gl-tooltip
v-gl-tooltip
.
bottom
:title=
"assigneesCounterTooltip"
class=
"avatar-counter"
data-placement=
"bottom"
data-qa-selector=
"avatar_counter_content"
>
{{
assigneeCounterLabel
}}
</span
>
...
...
app/assets/stylesheets/pages/issuable.scss
View file @
c8a53a38
...
...
@@ -673,40 +673,40 @@
.issuable-info-container
{
flex
:
1
;
display
:
flex
;
}
.issuable-main-info
{
flex
:
1
auto
;
margin-right
:
10px
;
min-width
:
0
;
.issuable-main-info
{
flex
:
1
auto
;
margin-right
:
10px
;
min-width
:
0
;
.issue-weight-icon
,
.issue-estimate-icon
{
vertical-align
:
sub
;
}
.issue-weight-icon
,
.issue-estimate-icon
{
vertical-align
:
sub
;
}
}
.issuable-meta
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
flex-end
;
flex
:
1
0
auto
;
.controls
{
margin-bottom
:
2px
;
line-height
:
20px
;
padding
:
0
;
}
.issuable-meta
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
flex-end
;
flex
:
1
0
auto
;
.issue-updated-at
{
line-height
:
20px
;
}
.controls
{
margin-bottom
:
2px
;
line-height
:
20px
;
padding
:
0
;
}
@include
media-breakpoint-down
(
xs
)
{
.issuable-meta
{
.controls
li
{
margin-right
:
0
;
}
.issue-updated-at
{
line-height
:
20px
;
}
}
@include
media-breakpoint-down
(
xs
)
{
.issuable-meta
{
.controls
li
{
margin-right
:
0
;
}
}
}
...
...
app/controllers/projects/merge_requests_controller.rb
View file @
c8a53a38
...
...
@@ -41,6 +41,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag
(
:improved_emoji_picker
,
project
,
default_enabled: :yaml
)
push_frontend_feature_flag
(
:diffs_virtual_scrolling
,
project
,
default_enabled: :yaml
)
push_frontend_feature_flag
(
:restructured_mr_widget
,
project
,
default_enabled: :yaml
)
push_frontend_feature_flag
(
:mr_changes_fluid_layout
,
project
,
default_enabled: :yaml
)
# Usage data feature flags
push_frontend_feature_flag
(
:users_expanding_widgets_usage_data
,
@project
,
default_enabled: :yaml
)
...
...
config/feature_flags/development/mr_changes_fluid_layout.yml
0 → 100644
View file @
c8a53a38
---
name
:
mr_changes_fluid_layout
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70815
rollout_issue_url
:
https://gitlab.com/gitlab-org/gitlab/-/issues/341809
milestone
:
'
14.4'
type
:
development
group
:
group::code review
default_enabled
:
false
config/initializers/backtrace_silencers.rb
View file @
c8a53a38
...
...
@@ -4,7 +4,7 @@ Rails.backtrace_cleaner.remove_silencers!
# This allows us to see the proper caller of SQL calls in {development,test}.log
if
(
Rails
.
env
.
development?
||
Rails
.
env
.
test?
)
&&
Gitlab
.
ee?
Rails
.
backtrace_cleaner
.
add_silencer
{
|
line
|
%r(^
ee/
lib/gitlab/database/load_balancing)
.
match?
(
line
)
}
Rails
.
backtrace_cleaner
.
add_silencer
{
|
line
|
%r(^lib/gitlab/database/load_balancing)
.
match?
(
line
)
}
end
Rails
.
backtrace_cleaner
.
add_silencer
{
|
line
|
!
Gitlab
::
APP_DIRS_PATTERN
.
match?
(
line
)
}
doc/ci/chatops/index.md
View file @
c8a53a38
...
...
@@ -9,6 +9,7 @@ type: index, concepts, howto
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4466) in GitLab Ultimate 10.6.
> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24780) to GitLab Free in 11.9.
> - `CHAT_USER_ID` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/341798) in GitLab 14.4.
GitLab ChatOps provides a method to interact with CI/CD jobs through chat services
like Slack. Many organizations' discussion, collaboration, and troubleshooting takes
...
...
@@ -30,6 +31,7 @@ to the job:
-
`CHAT_INPUT`
contains any additional arguments.
-
`CHAT_CHANNEL`
is set to the name of channel the action was triggered in.
-
`CHAT_USER_ID`
is set to the chat service's user ID of the user who triggered the slash command.
When executed, ChatOps looks up the specified job name and attempts to match it
to a corresponding job in
[
`.gitlab-ci.yml`
](
../yaml/index.md
)
. If a matching job
...
...
doc/ci/variables/predefined_variables.md
View file @
c8a53a38
...
...
@@ -20,6 +20,7 @@ There are also [Kubernetes-specific deployment variables](../../user/project/clu
|------------------------------------------|--------|--------|-------------|
|
`CHAT_CHANNEL`
| 10.6 | all | The Source chat channel that triggered the
[
ChatOps
](
../chatops/index.md
)
command. |
|
`CHAT_INPUT`
| 10.6 | all | The additional arguments passed with the
[
ChatOps
](
../chatops/index.md
)
command. |
|
`CHAT_USER_ID`
| 14.4 | all | The chat service's user ID of the user who triggered the
[
ChatOps
](
../chatops/index.md
)
command. |
|
`CI`
| all | 0.4 | Available for all jobs executed in CI/CD.
`true`
when available. |
|
`CI_API_V4_URL`
| 11.7 | all | The GitLab API v4 root URL. |
|
`CI_BUILDS_DIR`
| all | 11.10 | The top-level directory where builds are executed. |
...
...
ee/app/assets/javascripts/related_items_tree/components/issue_health_status.vue
View file @
c8a53a38
...
...
@@ -24,11 +24,11 @@ export default {
</
script
>
<
template
>
<
div
class=
"health-status"
>
<
span
class=
"health-status"
>
<span
class=
"gl-label gl-label-sm"
:class=
"statusClass"
>
<span
v-gl-tooltip
class=
"gl-label-text"
:title=
"__('Health status')"
>
{{
statusText
}}
</span>
</span>
</
div
>
</
span
>
</
template
>
ee/spec/features/epics/epics_list_spec.rb
View file @
c8a53a38
...
...
@@ -240,20 +240,19 @@ RSpec.describe 'epics list', :js do
end
it
'renders epics item with metadata'
,
:aggregate_failures
do
page
.
within
(
'.issuable-list-container .issuable-list'
)
do
expect
(
page
.
all
(
'.issuable-info-container'
)[
0
].
find
(
'.issue-title'
)).
to
have_content
(
epic2
.
title
)
expect
(
page
.
all
(
'.issuable-info-container'
)[
0
].
find
(
'.issuable-reference'
)).
to
have_content
(
"&
#{
epic2
.
iid
}
"
)
expect
(
page
.
all
(
'.issuable-info-container'
)[
0
].
find
(
'.issuable-authored'
)).
to
have_content
(
'created'
)
expect
(
page
.
all
(
'.issuable-info-container'
)[
0
].
find
(
'.issuable-authored'
)).
to
have_content
(
"by
#{
epic2
.
author
.
name
}
"
)
page
.
within
(
'.issuable-list .issue:first-of-type'
)
do
expect
(
page
).
to
have_link
(
epic2
.
title
)
expect
(
page
).
to
have_text
(
"&
#{
epic2
.
iid
}
"
)
expect
(
page
).
to
have_text
(
"created just now by
#{
epic2
.
author
.
name
}
"
)
end
end
it
'renders epic item timeframe'
,
:aggregate_failures
do
page
.
within
(
'.issuable-list-container .issuable-list'
)
do
expect
(
page
.
all
(
'.issuable-info-container'
)[
0
].
find
(
'.issuable-info'
)).
to
have_content
(
'Dec 15, 2020 – No due date'
)
expect
(
page
.
all
(
'.issuable-info-container'
)[
1
].
find
(
'.issuable-info'
)).
to
have_content
(
'Dec 15, 2020 – Jan 15, 2021
'
)
expect
(
page
.
all
(
'.issuable-info-container'
)[
2
].
find
(
'.issuable-info'
)).
to
have_content
(
'No start date
– Jan 15, 2021'
)
e
nd
issues
=
page
.
all
(
'.issue'
)
expect
(
issues
[
0
]).
to
have_text
(
'Dec 15, 2020 – No due date
'
)
expect
(
issues
[
1
]).
to
have_text
(
'Dec 15, 2020
– Jan 15, 2021'
)
e
xpect
(
issues
[
2
]).
to
have_text
(
'No start date – Jan 15, 2021'
)
end
end
...
...
ee/spec/features/projects/quality/test_case_list_spec.rb
View file @
c8a53a38
...
...
@@ -74,12 +74,11 @@ RSpec.describe 'Test Cases', :js do
it
'shows test cases title and metadata'
do
page
.
within
(
'.issuable-list-container .issuable-list li.issue'
,
match: :first
)
do
expect
(
page
.
find
(
'.issue-title'
)).
to
have_content
(
test_case1
.
title
)
expect
(
page
.
find
(
'.issuable-reference'
)).
to
have_content
(
"#
#{
test_case1
.
iid
}
"
)
expect
(
page
.
find
(
'.issuable-info'
)).
to
have_link
(
label
.
title
,
href:
"?label_name[]=
#{
label
.
title
}
"
)
expect
(
page
.
find
(
'.issuable-authored'
)).
to
have_content
(
'created 5 days ago by'
)
expect
(
page
.
find
(
'.author'
)).
to
have_content
(
user
.
name
)
expect
(
page
.
find
(
'div.issuable-updated-at'
)).
to
have_content
(
'updated 2 days ago'
)
expect
(
page
).
to
have_link
(
test_case1
.
title
)
expect
(
page
).
to
have_text
(
"#
#{
test_case1
.
iid
}
"
)
expect
(
page
).
to
have_link
(
label
.
title
,
href:
"?label_name[]=
#{
label
.
title
}
"
)
expect
(
page
).
to
have_text
(
"created 5 days ago by
#{
user
.
name
}
"
)
expect
(
page
).
to
have_text
(
'updated 2 days ago'
)
end
end
end
...
...
lib/gitlab/chat/command.rb
View file @
c8a53a38
...
...
@@ -66,7 +66,8 @@ module Gitlab
def
build_environment_variables
(
pipeline
)
pipeline
.
variables
.
build
(
[{
key:
'CHAT_INPUT'
,
value:
arguments
},
{
key:
'CHAT_CHANNEL'
,
value:
channel
}]
{
key:
'CHAT_CHANNEL'
,
value:
channel
},
{
key:
'CHAT_USER_ID'
,
value:
chat_name
.
chat_id
}]
)
end
...
...
locale/gitlab.pot
View file @
c8a53a38
...
...
@@ -39900,6 +39900,9 @@ msgstr ""
msgid "created %{timeAgo}"
msgstr ""
msgid "created %{timeAgo} by %{author}"
msgstr ""
msgid "created by"
msgstr ""
...
...
spec/frontend/diffs/components/app_spec.js
View file @
c8a53a38
...
...
@@ -702,4 +702,23 @@ describe('diffs/components/app', () => {
);
});
});
describe
(
'
fluid layout
'
,
()
=>
{
beforeEach
(()
=>
{
setFixtures
(
'
<div><div class="merge-request-container limit-container-width container-limited"></div></div>
'
,
);
});
it
(
'
removes limited container classes when on diffs tab
'
,
()
=>
{
createComponent
({
isFluidLayout
:
false
,
shouldShow
:
true
},
()
=>
{},
{
glFeatures
:
{
mrChangesFluidLayout
:
true
},
});
const
containerClassList
=
document
.
querySelector
(
'
.merge-request-container
'
).
classList
;
expect
(
containerClassList
).
not
.
toContain
(
'
container-limited
'
);
expect
(
containerClassList
).
not
.
toContain
(
'
limit-container-width
'
);
});
});
});
spec/frontend/issuable_list/components/issuable_item_spec.js
View file @
c8a53a38
import
{
GlLink
,
GlLabel
,
GlIcon
,
GlFormCheckbox
}
from
'
@gitlab/ui
'
;
import
{
GlLink
,
GlLabel
,
GlIcon
,
GlFormCheckbox
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
useFakeDate
}
from
'
helpers/fake_date
'
;
import
IssuableItem
from
'
~/issuable_list/components/issuable_item.vue
'
;
...
...
@@ -16,6 +16,9 @@ const createComponent = ({ issuableSymbol = '#', issuable = mockIssuable, slots
showCheckbox
:
false
,
},
slots
,
stubs
:
{
GlSprintf
,
},
});
const
MOCK_GITLAB_URL
=
'
http://0.0.0.0:3000
'
;
...
...
@@ -135,13 +138,6 @@ describe('IssuableItem', () => {
});
});
describe
(
'
createdAt
'
,
()
=>
{
it
(
'
returns string containing timeago string based on `issuable.createdAt`
'
,
()
=>
{
expect
(
wrapper
.
vm
.
createdAt
).
toContain
(
'
created
'
);
expect
(
wrapper
.
vm
.
createdAt
).
toContain
(
'
ago
'
);
});
});
describe
(
'
updatedAt
'
,
()
=>
{
it
(
'
returns string containing timeago string based on `issuable.updatedAt`
'
,
()
=>
{
expect
(
wrapper
.
vm
.
updatedAt
).
toContain
(
'
updated
'
);
...
...
@@ -449,8 +445,7 @@ describe('IssuableItem', () => {
it
(
'
renders issuable updatedAt info
'
,
()
=>
{
const
updatedAtEl
=
wrapper
.
find
(
'
[data-testid="issuable-updated-at"]
'
);
expect
(
updatedAtEl
.
exists
()).
toBe
(
true
);
expect
(
updatedAtEl
.
find
(
'
span
'
).
attributes
(
'
title
'
)).
toBe
(
'
Sep 10, 2020 11:41am UTC
'
);
expect
(
updatedAtEl
.
attributes
(
'
title
'
)).
toBe
(
'
Sep 10, 2020 11:41am UTC
'
);
expect
(
updatedAtEl
.
text
()).
toBe
(
wrapper
.
vm
.
updatedAt
);
});
...
...
spec/frontend/vue_shared/components/issue/issue_assignees_spec.js
View file @
c8a53a38
...
...
@@ -94,10 +94,6 @@ describe('IssueAssigneesComponent', () => {
expect
(
vm
.
avatarUrlTitle
(
mockAssigneesList
[
0
])).
toBe
(
'
Assigned to Terrell Graham
'
);
});
it
(
'
renders component root element with class `issue-assignees`
'
,
()
=>
{
expect
(
wrapper
.
element
.
classList
.
contains
(
'
issue-assignees
'
)).
toBe
(
true
);
});
it
(
'
renders assignee
'
,
()
=>
{
const
data
=
findAvatars
().
wrappers
.
map
((
x
)
=>
({
...
x
.
props
(),
...
...
spec/lib/gitlab/chat/command_spec.rb
View file @
c8a53a38
...
...
@@ -72,6 +72,7 @@ RSpec.describe Gitlab::Chat::Command do
expect
(
vars
[
'CHAT_INPUT'
]).
to
eq
(
'foo'
)
expect
(
vars
[
'CHAT_CHANNEL'
]).
to
eq
(
'123'
)
expect
(
vars
[
'CHAT_USER_ID'
]).
to
eq
(
chat_name
.
chat_id
)
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment