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
c763d98e
Commit
c763d98e
authored
Jun 03, 2019
by
Sam Bigelow
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Backport of EE Displaying Blocking MRs
This MR is a backport of an EE merge request
parent
e6a88b02
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
115 additions
and
15 deletions
+115
-15
app/assets/javascripts/reports/components/issues_list.vue
app/assets/javascripts/reports/components/issues_list.vue
+17
-3
app/assets/javascripts/reports/components/report_section.vue
app/assets/javascripts/reports/components/report_section.vue
+34
-8
app/assets/javascripts/reports/constants.js
app/assets/javascripts/reports/constants.js
+6
-0
app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue
...pts/vue_shared/components/issue/related_issuable_item.vue
+11
-1
app/controllers/projects/merge_requests/application_controller.rb
...rollers/projects/merge_requests/application_controller.rb
+7
-3
spec/frontend/reports/components/report_section_spec.js
spec/frontend/reports/components/report_section_spec.js
+40
-0
No files found.
app/assets/javascripts/reports/components/issues_list.vue
View file @
c763d98e
...
@@ -52,11 +52,21 @@ export default {
...
@@ -52,11 +52,21 @@ export default {
required
:
false
,
required
:
false
,
default
:
''
,
default
:
''
,
},
},
showReportSectionStatus
:
{
showReportSectionStatus
Icon
:
{
type
:
Boolean
,
type
:
Boolean
,
required
:
false
,
required
:
false
,
default
:
true
,
default
:
true
,
},
},
issuesUlElementClass
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
issueItemClass
:
{
type
:
String
,
required
:
false
,
default
:
null
,
},
},
},
computed
:
{
computed
:
{
issuesWithState
()
{
issuesWithState
()
{
...
@@ -67,6 +77,9 @@ export default {
...
@@ -67,6 +77,9 @@ export default {
...
this
.
resolvedIssues
.
map
(
wrapIssueWithState
(
STATUS_SUCCESS
)),
...
this
.
resolvedIssues
.
map
(
wrapIssueWithState
(
STATUS_SUCCESS
)),
];
];
},
},
wclass
()
{
return
`report-block-list
${
this
.
issuesUlElementClass
}
`
;
},
},
},
};
};
</
script
>
</
script
>
...
@@ -77,7 +90,7 @@ export default {
...
@@ -77,7 +90,7 @@ export default {
:size=
"$options.typicalReportItemHeight"
:size=
"$options.typicalReportItemHeight"
class=
"report-block-container"
class=
"report-block-container"
wtag=
"ul"
wtag=
"ul"
wclass=
"report-block-list
"
:wclass=
"wclass
"
>
>
<report-item
<report-item
v-for=
"(wrapped, index) in issuesWithState"
v-for=
"(wrapped, index) in issuesWithState"
...
@@ -86,7 +99,8 @@ export default {
...
@@ -86,7 +99,8 @@ export default {
:status=
"wrapped.status"
:status=
"wrapped.status"
:component=
"component"
:component=
"component"
:is-new=
"wrapped.isNew"
:is-new=
"wrapped.isNew"
:show-report-section-status=
"showReportSectionStatus"
:show-report-section-status-icon=
"showReportSectionStatusIcon"
:class=
"issueItemClass"
/>
/>
</smart-virtual-list>
</smart-virtual-list>
</
template
>
</
template
>
app/assets/javascripts/reports/components/report_section.vue
View file @
c763d98e
...
@@ -3,10 +3,7 @@ import { __ } from '~/locale';
...
@@ -3,10 +3,7 @@ import { __ } from '~/locale';
import
StatusIcon
from
'
~/vue_merge_request_widget/components/mr_widget_status_icon.vue
'
;
import
StatusIcon
from
'
~/vue_merge_request_widget/components/mr_widget_status_icon.vue
'
;
import
Popover
from
'
~/vue_shared/components/help_popover.vue
'
;
import
Popover
from
'
~/vue_shared/components/help_popover.vue
'
;
import
IssuesList
from
'
./issues_list.vue
'
;
import
IssuesList
from
'
./issues_list.vue
'
;
import
{
status
}
from
'
../constants
'
;
const
LOADING
=
'
LOADING
'
;
const
ERROR
=
'
ERROR
'
;
const
SUCCESS
=
'
SUCCESS
'
;
export
default
{
export
default
{
name
:
'
ReportSection
'
,
name
:
'
ReportSection
'
,
...
@@ -42,7 +39,8 @@ export default {
...
@@ -42,7 +39,8 @@ export default {
},
},
successText
:
{
successText
:
{
type
:
String
,
type
:
String
,
required
:
true
,
required
:
false
,
default
:
''
,
},
},
unresolvedIssues
:
{
unresolvedIssues
:
{
type
:
Array
,
type
:
Array
,
...
@@ -78,6 +76,21 @@ export default {
...
@@ -78,6 +76,21 @@ export default {
required
:
false
,
required
:
false
,
default
:
true
,
default
:
true
,
},
},
issuesUlElementClass
:
{
type
:
String
,
required
:
false
,
default
:
undefined
,
},
issuesListContainerClass
:
{
type
:
String
,
required
:
false
,
default
:
undefined
,
},
issueItemClass
:
{
type
:
String
,
required
:
false
,
default
:
undefined
,
},
},
},
data
()
{
data
()
{
...
@@ -91,13 +104,13 @@ export default {
...
@@ -91,13 +104,13 @@ export default {
return
this
.
isCollapsed
?
__
(
'
Expand
'
)
:
__
(
'
Collapse
'
);
return
this
.
isCollapsed
?
__
(
'
Expand
'
)
:
__
(
'
Collapse
'
);
},
},
isLoading
()
{
isLoading
()
{
return
this
.
status
===
LOADING
;
return
this
.
status
===
status
.
LOADING
;
},
},
loadingFailed
()
{
loadingFailed
()
{
return
this
.
status
===
ERROR
;
return
this
.
status
===
status
.
ERROR
;
},
},
isSuccess
()
{
isSuccess
()
{
return
this
.
status
===
SUCCESS
;
return
this
.
status
===
status
.
SUCCESS
;
},
},
isCollapsible
()
{
isCollapsible
()
{
return
!
this
.
alwaysOpen
&&
this
.
hasIssues
;
return
!
this
.
alwaysOpen
&&
this
.
hasIssues
;
...
@@ -132,6 +145,15 @@ export default {
...
@@ -132,6 +145,15 @@ export default {
hasPopover
()
{
hasPopover
()
{
return
Object
.
keys
(
this
.
popoverOptions
).
length
>
0
;
return
Object
.
keys
(
this
.
popoverOptions
).
length
>
0
;
},
},
slotName
()
{
if
(
this
.
isSuccess
)
{
return
'
success
'
;
}
else
if
(
this
.
isLoading
)
{
return
'
loading
'
;
}
return
'
error
'
;
},
},
},
methods
:
{
methods
:
{
toggleCollapsed
()
{
toggleCollapsed
()
{
...
@@ -147,6 +169,7 @@ export default {
...
@@ -147,6 +169,7 @@ export default {
<div
class=
"media-body d-flex flex-align-self-center"
>
<div
class=
"media-body d-flex flex-align-self-center"
>
<span
class=
"js-code-text code-text"
>
<span
class=
"js-code-text code-text"
>
{{
headerText
}}
{{
headerText
}}
<slot
:name=
"slotName"
></slot>
<popover
v-if=
"hasPopover"
:options=
"popoverOptions"
class=
"prepend-left-5"
/>
<popover
v-if=
"hasPopover"
:options=
"popoverOptions"
class=
"prepend-left-5"
/>
</span>
</span>
...
@@ -172,6 +195,9 @@ export default {
...
@@ -172,6 +195,9 @@ export default {
:neutral-issues=
"neutralIssues"
:neutral-issues=
"neutralIssues"
:component=
"component"
:component=
"component"
:show-report-section-status-icon=
"showReportSectionStatusIcon"
:show-report-section-status-icon=
"showReportSectionStatusIcon"
:issues-ul-element-class=
"issuesUlElementClass"
:class=
"issuesListContainerClass"
:issue-item-class=
"issueItemClass"
/>
/>
</slot>
</slot>
</div>
</div>
...
...
app/assets/javascripts/reports/constants.js
View file @
c763d98e
...
@@ -16,3 +16,9 @@ export const STATUS_NEUTRAL = 'neutral';
...
@@ -16,3 +16,9 @@ export const STATUS_NEUTRAL = 'neutral';
export
const
ICON_WARNING
=
'
warning
'
;
export
const
ICON_WARNING
=
'
warning
'
;
export
const
ICON_SUCCESS
=
'
success
'
;
export
const
ICON_SUCCESS
=
'
success
'
;
export
const
ICON_NOTFOUND
=
'
notfound
'
;
export
const
ICON_NOTFOUND
=
'
notfound
'
;
export
const
status
=
{
LOADING
:
'
LOADING
'
,
ERROR
:
'
ERROR
'
,
SUCCESS
:
'
SUCCESS
'
,
};
app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue
View file @
c763d98e
...
@@ -24,6 +24,11 @@ export default {
...
@@ -24,6 +24,11 @@ export default {
required
:
false
,
required
:
false
,
default
:
false
,
default
:
false
,
},
},
greyLinkWhenMerged
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
},
computed
:
{
computed
:
{
stateTitle
()
{
stateTitle
()
{
...
@@ -36,6 +41,11 @@ export default {
...
@@ -36,6 +41,11 @@ export default {
},
},
);
);
},
},
issueableLinkClass
()
{
return
this
.
greyLinkWhenMerged
?
`sortable-link
${
this
.
state
===
'
merged
'
?
'
text-secondary
'
:
''
}
`
:
'
sortable-link
'
;
},
},
},
};
};
</
script
>
</
script
>
...
@@ -69,7 +79,7 @@ export default {
...
@@ -69,7 +79,7 @@ export default {
class=
"confidential-icon append-right-4 align-self-baseline align-self-md-auto mt-xl-0"
class=
"confidential-icon append-right-4 align-self-baseline align-self-md-auto mt-xl-0"
:aria-label=
"__('Confidential')"
:aria-label=
"__('Confidential')"
/>
/>
<a
:href=
"computedPath"
class=
"sortable-link
"
>
{{
title
}}
</a>
<a
:href=
"computedPath"
:class=
"issueableLinkClass
"
>
{{
title
}}
</a>
</div>
</div>
<div
class=
"item-meta d-flex flex-wrap mt-xl-0 justify-content-xl-end flex-xl-nowrap"
>
<div
class=
"item-meta d-flex flex-wrap mt-xl-0 justify-content-xl-end flex-xl-nowrap"
>
<div
<div
...
...
app/controllers/projects/merge_requests/application_controller.rb
View file @
c763d98e
...
@@ -7,11 +7,15 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont
...
@@ -7,11 +7,15 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont
private
private
# rubocop: disable CodeReuse/ActiveRecord
def
merge_request
def
merge_request
@issuable
=
@merge_request
||=
@project
.
merge_requests
.
includes
(
author: :status
).
find_by!
(
iid:
params
[
:id
])
@issuable
=
@merge_request
||=
merge_request_includes
(
@project
.
merge_requests
).
find_by_iid!
(
params
[
:id
])
end
def
merge_request_includes
(
association
)
association
.
includes
(
:metrics
,
:assignees
,
author: :status
)
# rubocop:disable CodeReuse/ActiveRecord
end
end
# rubocop: enable CodeReuse/ActiveRecord
def
merge_request_params
def
merge_request_params
params
.
require
(
:merge_request
).
permit
(
merge_request_params_attributes
)
params
.
require
(
:merge_request
).
permit
(
merge_request_params_attributes
)
...
...
spec/frontend/reports/components/report_section_spec.js
View file @
c763d98e
...
@@ -197,4 +197,44 @@ describe('Report section', () => {
...
@@ -197,4 +197,44 @@ describe('Report section', () => {
expect
(
vm
.
$el
.
querySelector
(
'
.js-collapse-btn
'
).
textContent
.
trim
()).
toEqual
(
'
Expand
'
);
expect
(
vm
.
$el
.
querySelector
(
'
.js-collapse-btn
'
).
textContent
.
trim
()).
toEqual
(
'
Expand
'
);
});
});
});
});
describe
(
'
Success and Error slots
'
,
()
=>
{
const
createComponent
=
status
=>
{
vm
=
mountComponentWithSlots
(
ReportSection
,
{
props
:
{
status
,
hasIssues
:
true
,
},
slots
:
{
success
:
[
'
This is a success
'
],
loading
:
[
'
This is loading
'
],
error
:
[
'
This is an error
'
],
},
});
};
it
(
'
only renders success slot when status is "SUCCESS"
'
,
()
=>
{
createComponent
(
'
SUCCESS
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
This is a success
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
not
.
toContain
(
'
This is an error
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
not
.
toContain
(
'
This is loading
'
);
});
it
(
'
only renders error slot when status is "ERROR"
'
,
()
=>
{
createComponent
(
'
ERROR
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
This is an error
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
not
.
toContain
(
'
This is a success
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
not
.
toContain
(
'
This is loading
'
);
});
it
(
'
only renders loading slot when status is "LOADING"
'
,
()
=>
{
createComponent
(
'
LOADING
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
This is loading
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
not
.
toContain
(
'
This is an error
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
not
.
toContain
(
'
This is a success
'
);
});
});
});
});
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