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
0
Merge Requests
0
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
Tatuya Kamada
gitlab-ce
Commits
17ab3730
Commit
17ab3730
authored
Jun 12, 2016
by
Robert Speicher
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into 8-9-stable
parents
6c23107d
8d243f9b
Changes
52
Show whitespace changes
Inline
Side-by-side
Showing
52 changed files
with
473 additions
and
372 deletions
+473
-372
CHANGELOG
CHANGELOG
+4
-1
app/assets/javascripts/application.js.coffee
app/assets/javascripts/application.js.coffee
+1
-18
app/assets/javascripts/logo.js.coffee
app/assets/javascripts/logo.js.coffee
+1
-1
app/assets/javascripts/sidebar.js.coffee
app/assets/javascripts/sidebar.js.coffee
+0
-9
app/assets/stylesheets/framework/gitlab-theme.scss
app/assets/stylesheets/framework/gitlab-theme.scss
+4
-22
app/assets/stylesheets/framework/header.scss
app/assets/stylesheets/framework/header.scss
+40
-11
app/assets/stylesheets/framework/nav.scss
app/assets/stylesheets/framework/nav.scss
+4
-2
app/assets/stylesheets/framework/sidebar.scss
app/assets/stylesheets/framework/sidebar.scss
+23
-58
app/assets/stylesheets/framework/variables.scss
app/assets/stylesheets/framework/variables.scss
+1
-1
app/controllers/application_controller.rb
app/controllers/application_controller.rb
+1
-0
app/controllers/projects/avatars_controller.rb
app/controllers/projects/avatars_controller.rb
+1
-4
app/controllers/projects/merge_requests_controller.rb
app/controllers/projects/merge_requests_controller.rb
+2
-5
app/controllers/projects/raw_controller.rb
app/controllers/projects/raw_controller.rb
+1
-4
app/controllers/projects/repositories_controller.rb
app/controllers/projects/repositories_controller.rb
+1
-2
app/helpers/nav_helper.rb
app/helpers/nav_helper.rb
+1
-7
app/helpers/workhorse_helper.rb
app/helpers/workhorse_helper.rb
+24
-0
app/models/merge_request.rb
app/models/merge_request.rb
+0
-8
app/models/project.rb
app/models/project.rb
+60
-11
app/views/layouts/_collapse_button.html.haml
app/views/layouts/_collapse_button.html.haml
+1
-4
app/views/layouts/_page.html.haml
app/views/layouts/_page.html.haml
+4
-6
app/views/layouts/ci/_page.html.haml
app/views/layouts/ci/_page.html.haml
+0
-6
app/views/layouts/header/_default.html.haml
app/views/layouts/header/_default.html.haml
+5
-1
app/views/layouts/nav/_admin.html.haml
app/views/layouts/nav/_admin.html.haml
+23
-19
app/views/layouts/nav/_dashboard.html.haml
app/views/layouts/nav/_dashboard.html.haml
+13
-10
app/views/layouts/nav/_explore.html.haml
app/views/layouts/nav/_explore.html.haml
+4
-4
app/views/layouts/nav/_group.html.haml
app/views/layouts/nav/_group.html.haml
+0
-6
app/views/layouts/nav/_profile.html.haml
app/views/layouts/nav/_profile.html.haml
+0
-10
app/views/layouts/nav/_project.html.haml
app/views/layouts/nav/_project.html.haml
+2
-26
app/views/projects/issues/_head.html.haml
app/views/projects/issues/_head.html.haml
+25
-0
app/views/projects/issues/index.html.haml
app/views/projects/issues/index.html.haml
+18
-15
app/views/projects/labels/index.html.haml
app/views/projects/labels/index.html.haml
+33
-30
app/views/projects/merge_requests/_head.html.haml
app/views/projects/merge_requests/_head.html.haml
+0
-5
app/views/projects/merge_requests/index.html.haml
app/views/projects/merge_requests/index.html.haml
+14
-12
app/views/projects/milestones/index.html.haml
app/views/projects/milestones/index.html.haml
+16
-13
doc/api/merge_requests.md
doc/api/merge_requests.md
+12
-1
features/project/active_tab.feature
features/project/active_tab.feature
+8
-4
features/steps/profile/profile.rb
features/steps/profile/profile.rb
+1
-0
features/steps/project/active_tab.rb
features/steps/project/active_tab.rb
+8
-8
features/steps/shared/active_tab.rb
features/steps/shared/active_tab.rb
+2
-2
lib/api/entities.rb
lib/api/entities.rb
+5
-0
lib/api/helpers.rb
lib/api/helpers.rb
+18
-0
lib/api/merge_requests.rb
lib/api/merge_requests.rb
+1
-1
lib/api/repositories.rb
lib/api/repositories.rb
+3
-7
lib/backup/manager.rb
lib/backup/manager.rb
+18
-3
lib/gitlab/workhorse.rb
lib/gitlab/workhorse.rb
+10
-8
spec/controllers/projects/merge_requests_controller_spec.rb
spec/controllers/projects/merge_requests_controller_spec.rb
+1
-1
spec/controllers/projects/raw_controller_spec.rb
spec/controllers/projects/raw_controller_spec.rb
+2
-0
spec/controllers/projects/repositories_controller_spec.rb
spec/controllers/projects/repositories_controller_spec.rb
+3
-2
spec/features/profiles/preferences_spec.rb
spec/features/profiles/preferences_spec.rb
+5
-3
spec/lib/gitlab/workhorse_spec.rb
spec/lib/gitlab/workhorse_spec.rb
+1
-1
spec/models/project_spec.rb
spec/models/project_spec.rb
+33
-0
spec/requests/api/merge_requests_spec.rb
spec/requests/api/merge_requests_spec.rb
+15
-0
No files found.
CHANGELOG
View file @
17ab3730
Please view this file on the master branch, on stable branches it's out of date.
v 8.9.0 (unreleased)
- Fix Error 500 when using closes_issues API with an external issue tracker
- Bulk assign/unassign labels to issues.
- Ability to prioritize labels !4009 / !3205 (Thijs Wouters)
- Fix endless redirections when accessing user OAuth applications when they are disabled
- Allow enabling wiki page events from Webhook management UI
- Bump rouge to 1.11.0
- Fix issue with arrow keys not working in search autocomplete dropdown
- Make EmailsOnPushWorker use Sidekiq mailers queue
- Fix wiki page events' webhook to point to the wiki repository
- Fix issue todo not remove when leave project !4150 (Long Nguyen)
...
...
@@ -55,6 +57,7 @@ v 8.9.0 (unreleased)
- Remove duplicated notification settings
- Put project Files and Commits tabs under Code tab
- Replace Colorize with Rainbow for coloring console output in Rake tasks.
- Add workhorse controller and API helpers
- An indicator is now displayed at the top of the comment field for confidential issues.
- RepositoryCheck::SingleRepositoryWorker public and private methods are now instrumented
- Improve issuables APIs performance when accessing notes !4471
...
...
@@ -63,10 +66,10 @@ v 8.9.0 (unreleased)
- Toggling a task list item in a issue/mr description does not creates a Todo for mentions
- Improved UX of date pickers on issue & milestone forms
- Cache on the database if a project has an active external issue tracker.
- Put project Labels and Milestones pages links under Issues and Merge Requests tabs as subnav
v 8.8.5 (unreleased)
- Ensure branch cleanup regardless of whether the GitHub import process succeeds
- Fix issue with arrow keys not working in search autocomplete dropdown
- Fix todos page throwing errors when you have a project pending deletion
- Reduce number of SQL queries when rendering user references
- Import GitHub repositories respecting the API rate limit
...
...
app/assets/javascripts/application.js.coffee
View file @
17ab3730
...
...
@@ -162,19 +162,6 @@ $ ->
$el
.
data
(
'placement'
)
||
'bottom'
)
$
(
'.header-logo .home'
).
tooltip
(
placement
:
(
_
,
el
)
->
$el
=
$
(
el
)
if
$
(
'.page-with-sidebar'
).
hasClass
(
'page-sidebar-collapsed'
)
then
'right'
else
'bottom'
container
:
'body'
)
$
(
'.page-with-sidebar'
).
tooltip
(
selector
:
'.sidebar-collapsed .nav-sidebar a, .sidebar-collapsed a.sidebar-user'
placement
:
'right'
container
:
'body'
)
# Form submitter
$
(
'.trigger-submit'
).
on
'change'
,
->
$
(
@
).
parents
(
'form'
).
submit
()
...
...
@@ -207,6 +194,7 @@ $ ->
$
(
'.navbar-toggle'
).
on
'click'
,
->
$
(
'.header-content .title'
).
toggle
()
$
(
'.header-content .header-logo'
).
toggle
()
$
(
'.header-content .navbar-collapse'
).
toggle
()
$
(
'.navbar-toggle'
).
toggleClass
(
'active'
)
$
(
'.navbar-toggle i'
).
toggleClass
(
"fa-angle-right fa-angle-left"
)
...
...
@@ -241,7 +229,6 @@ $ ->
$this
.
attr
'value'
,
$this
.
val
()
$sidebarGutterToggle
=
$
(
'.js-sidebar-toggle'
)
$navIconToggle
=
$
(
'.toggle-nav-collapse'
)
$
(
document
)
.
off
'breakpoint:change'
...
...
@@ -251,10 +238,6 @@ $ ->
if
$gutterIcon
.
hasClass
(
'fa-angle-double-right'
)
$sidebarGutterToggle
.
trigger
(
'click'
)
$navIcon
=
$navIconToggle
.
find
(
'.fa'
)
if
$navIcon
.
hasClass
(
'fa-angle-left'
)
$navIconToggle
.
trigger
(
'click'
)
fitSidebarForSize
=
->
oldBootstrapBreakpoint
=
bootstrapBreakpoint
bootstrapBreakpoint
=
bp
.
getBreakpointSize
()
...
...
app/assets/javascripts/logo.js.coffee
View file @
17ab3730
...
...
@@ -47,4 +47,4 @@ $ ->
# Make logo clickable as part of a workaround for Safari visited
# link behaviour (See !2690).
$
(
'#logo'
).
on
'click'
,
->
$
(
'#js-shortcuts-home'
).
get
(
0
).
click
(
)
Turbolinks
.
visit
(
'/'
)
app/assets/javascripts/sidebar.js.coffee
View file @
17ab3730
...
...
@@ -4,8 +4,6 @@ expanded = 'page-sidebar-expanded'
toggleSidebar
=
->
$
(
'.page-with-sidebar'
).
toggleClass
(
"
#{
collapsed
}
#{
expanded
}
"
)
$
(
'header'
).
toggleClass
(
"header-collapsed header-expanded"
)
$
(
'.toggle-nav-collapse i'
).
toggleClass
(
"fa-angle-right fa-angle-left"
)
$
.
cookie
(
"collapsed_nav"
,
$
(
'.page-with-sidebar'
).
hasClass
(
collapsed
),
{
path
:
'/'
})
setTimeout
(
->
niceScrollBars
=
$
(
'.nicescroll'
).
niceScroll
();
...
...
@@ -17,10 +15,3 @@ $(document).on("click", '.toggle-nav-collapse, .side-nav-toggle', (e) ->
toggleSidebar
()
)
$
->
size
=
bp
.
getBreakpointSize
()
if
size
is
"xs"
or
size
is
"sm"
if
$
(
'.page-with-sidebar'
).
hasClass
(
expanded
)
toggleSidebar
()
app/assets/stylesheets/framework/gitlab-theme.scss
View file @
17ab3730
...
...
@@ -8,32 +8,14 @@
*/
@mixin
gitlab-theme
(
$color-light
,
$color
,
$color-darker
,
$color-dark
)
{
.page-with-sidebar
{
.header-logo
{
background
:
$color-darker
;
a
{
color
:
$color-light
;
h3
{
.collapse-nav
a
{
color
:
$color-light
;
}
}
background
:
$color
;
&
:hover
{
background-color
:
$color-dark
;
a
{
color
:
$white-light
;
h3
{
color
:
$white-light
;
}
}
}
}
.collapse-nav
a
{
color
:
$white-light
;
background
:
$color
;
}
.sidebar-wrapper
{
...
...
app/assets/stylesheets/framework/header.scss
View file @
17ab3730
...
...
@@ -109,10 +109,8 @@ header {
position
:
relative
;
height
:
$header-height
;
padding-right
:
40px
;
@media
(
max-width
:
$screen-xs-min
)
{
padding-left
:
40px
;
}
padding-left
:
30px
;
transition-duration
:
.3s
;
@media
(
min-width
:
$screen-sm-min
)
{
padding-right
:
0
;
...
...
@@ -122,9 +120,29 @@ header {
margin-top
:
-5px
;
}
.header-logo
{
position
:
absolute
;
left
:
50%
;
margin-left
:
-18px
;
top
:
7px
;
transition-duration
:
.3s
;
z-index
:
999
;
&
:hover
{
cursor
:
pointer
;
}
@media
(
max-width
:
$screen-xs-max
)
{
right
:
25px
;
left
:
auto
;
}
}
.title
{
margin
:
0
;
font-size
:
19px
;
max-width
:
400px
;
display
:
inline-block
;
line-height
:
$header-height
;
font-weight
:
normal
;
color
:
$gl-text-color
;
...
...
@@ -133,6 +151,10 @@ header {
vertical-align
:
top
;
white-space
:
nowrap
;
@media
(
max-width
:
$screen-sm-max
)
{
max-width
:
190px
;
}
a
{
color
:
$gl-text-color
;
&
:hover
{
...
...
@@ -160,6 +182,10 @@ header {
.navbar-collapse
{
float
:
right
;
border-top
:
none
;
@media
(
max-width
:
$screen-xs-max
)
{
float
:
none
;
}
}
}
...
...
@@ -176,17 +202,20 @@ header {
margin-left
:
0
;
.header-content
{
@media
(
min-width
:
$screen-sm-max
)
{
padding-left
:
30px
;
transition-duration
:
.3s
;
}
}
}
.
header-expanded
{
margin-left
:
0
;
.
tanuki-shape
{
transition
:
all
0
.8s
;
.header-conten
t
{
margin-left
:
$sidebar_width
;
transition
-duration
:
.3
s
;
&
:hover
,
&
.highligh
t
{
fill
:
rgb
(
255
,
255
,
255
)
;
transition
:
all
0
.1
s
;
}
}
...
...
app/assets/stylesheets/framework/nav.scss
View file @
17ab3730
@mixin
fade
(
$gradient-direction
,
$rgba
,
$gradient-color
)
{
visibility
:
visible
;
opacity
:
1
;
z-index
:
2
;
position
:
absolute
;
bottom
:
12px
;
width
:
43px
;
...
...
@@ -68,6 +69,7 @@
}
&
.sub-nav
{
text-align
:
center
;
background-color
:
$background-color
;
.container-fluid
{
...
...
@@ -171,7 +173,6 @@
>
form
{
display
:
inline-block
;
margin-top
:
-1px
;
margin-bottom
:
12px
;
}
.icon-label
{
...
...
@@ -250,6 +251,7 @@
background
:
$background-color
;
border-bottom
:
1px
solid
$border-color
;
transition-duration
:
.3s
;
text-align
:
center
;
.container-fluid
{
position
:
relative
;
...
...
@@ -352,7 +354,7 @@
.fade-right
{
@media
(
min-width
:
$screen-xs-max
)
{
right
:
6
7
px
;
right
:
6
8
px
;
}
@media
(
max-width
:
$screen-xs-min
)
{
right
:
0
;
...
...
app/assets/stylesheets/framework/sidebar.scss
View file @
17ab3730
...
...
@@ -35,24 +35,11 @@
}
.sidebar-wrapper
{
.header-logo
{
height
:
$header-height
;
padding
:
8px
26px
;
width
:
$sidebar_width
;
position
:
fixed
;
z-index
:
999
;
overflow
:
hidden
;
transition-duration
:
.3s
;
&
:hover
{
background-color
:
#eee
;
}
}
.sidebar-user
{
padding
:
15px
22px
;
position
:
fixed
;
bottom
:
40px
;
bottom
:
0
;
width
:
$sidebar_width
;
overflow
:
hidden
;
transition-duration
:
.3s
;
...
...
@@ -97,10 +84,10 @@
}
a
{
text-align
:
center
;
padding
:
8
px
;
width
:
$sidebar_width
;
padding
:
7px
15px
7px
23
px
;
font-size
:
$gl-font-size
;
color
:
$gray
;
line-height
:
24px
;
display
:
block
;
text-decoration
:
none
;
font-weight
:
normal
;
...
...
@@ -118,10 +105,9 @@
font-size
:
16px
;
}
.nav-link-text
{
margin-top
:
3px
;
font-size
:
13px
;
line-height
:
18px
;
i
,
svg
{
margin-right
:
13px
;
}
&
.back-link
i
{
...
...
@@ -129,6 +115,12 @@
}
}
}
.count
{
float
:
right
;
padding
:
0
8px
;
@include
border-radius
(
6px
);
}
}
.sidebar-subnav
{
...
...
@@ -143,11 +135,12 @@
.collapse-nav
a
{
width
:
$sidebar_width
;
position
:
fixed
;
bottom
:
0
;
top
:
0
;
left
:
0
;
font-size
:
13px
;
padding
:
5px
0
;
font-size
:
18px
;
background
:
transparent
;
height
:
4
0px
;
height
:
5
0px
;
text-align
:
center
;
line-height
:
40px
;
transition-duration
:
.3s
;
...
...
@@ -170,25 +163,8 @@
.sidebar-wrapper
{
width
:
0
;
.header-logo
{
width
:
0
;
padding
:
8px
0
;
a
{
padding-left
:
(
$sidebar_collapsed_width
-
36
)
/
2
;
.gitlab-text-container
{
display
:
none
;
}
}
}
#logo
{
display
:
none
;
}
.nav-sidebar
{
width
:
$sidebar_collapsed_width
;
width
:
0
;
li
{
width
:
auto
;
...
...
@@ -203,6 +179,10 @@
.collapse-nav
a
{
width
:
0
;
i
{
display
:
none
;
}
}
.sidebar-user
{
...
...
@@ -218,9 +198,8 @@
}
.page-sidebar-expanded
{
padding-left
:
$sidebar_width
;
@media
(
max-width
:
$screen-
xs-min
)
{
@media
(
max-width
:
$screen-
sm-max
)
{
padding-left
:
0
;
}
...
...
@@ -241,20 +220,6 @@
}
}
}
.layout-nav
{
@media
(
max-width
:
$screen-xs-min
)
{
padding-right
:
0
;
}
@media
(
min-width
:
$screen-xs-min
)
and
(
max-width
:
$screen-md-min
)
{
padding-right
:
90px
;
}
@media
(
min-width
:
$screen-md-min
)
{
padding-right
:
$sidebar_width
;
}
}
}
.right-sidebar-collapsed
{
...
...
app/assets/stylesheets/framework/variables.scss
View file @
17ab3730
...
...
@@ -2,7 +2,7 @@
* Layout
*/
$sidebar_collapsed_width
:
62px
;
$sidebar_width
:
9
0px
;
$sidebar_width
:
22
0px
;
$gutter_collapsed_width
:
62px
;
$gutter_width
:
290px
;
$gutter_inner_width
:
258px
;
...
...
app/controllers/application_controller.rb
View file @
17ab3730
...
...
@@ -6,6 +6,7 @@ class ApplicationController < ActionController::Base
include
Gitlab
::
GonHelper
include
GitlabRoutingHelper
include
PageLayoutHelper
include
WorkhorseHelper
before_action
:authenticate_user_from_token!
before_action
:authenticate_user!
...
...
app/controllers/projects/avatars_controller.rb
View file @
17ab3730
...
...
@@ -10,10 +10,7 @@ class Projects::AvatarsController < Projects::ApplicationController
return
if
cached_blob?
headers
.
store
(
*
Gitlab
::
Workhorse
.
send_git_blob
(
@repository
,
@blob
))
headers
[
'Content-Disposition'
]
=
'inline'
headers
[
'Content-Type'
]
=
safe_content_type
(
@blob
)
head
:ok
# 'render nothing: true' messes up the Content-Type
send_git_blob
@repository
,
@blob
else
render_404
end
...
...
app/controllers/projects/merge_requests_controller.rb
View file @
17ab3730
...
...
@@ -61,12 +61,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController
format
.
json
{
render
json:
@merge_request
}
format
.
patch
{
render
text:
@merge_request
.
to_patch
}
format
.
diff
do
headers
.
store
(
*
Gitlab
::
Workhorse
.
send_git_diff
(
@project
.
repository
,
@merge_request
.
diff_base_commit
.
id
,
@merge_request
.
last_commit
.
id
))
headers
[
'Content-Disposition'
]
=
'inline'
return
render_404
unless
@merge_request
.
diff_refs
head
:ok
send_git_diff
@project
.
repository
,
@merge_request
.
diff_refs
end
end
end
...
...
app/controllers/projects/raw_controller.rb
View file @
17ab3730
...
...
@@ -18,10 +18,7 @@ class Projects::RawController < Projects::ApplicationController
if
@blob
.
lfs_pointer?
send_lfs_object
else
headers
.
store
(
*
Gitlab
::
Workhorse
.
send_git_blob
(
@repository
,
@blob
))
headers
[
'Content-Disposition'
]
=
'inline'
headers
[
'Content-Type'
]
=
safe_content_type
(
@blob
)
head
:ok
# 'render nothing: true' messes up the Content-Type
send_git_blob
@repository
,
@blob
end
else
render_404
...
...
app/controllers/projects/repositories_controller.rb
View file @
17ab3730
...
...
@@ -11,8 +11,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
end
def
archive
headers
.
store
(
*
Gitlab
::
Workhorse
.
send_git_archive
(
@project
,
params
[
:ref
],
params
[
:format
]))
head
:ok
send_git_archive
@repository
,
ref:
params
[
:ref
],
format:
params
[
:format
]
rescue
=>
ex
logger
.
error
(
"
#{
self
.
class
.
name
}
:
#{
ex
}
"
)
return
git_not_found!
...
...
app/helpers/nav_helper.rb
View file @
17ab3730
...
...
@@ -36,13 +36,7 @@ module NavHelper
end
def
nav_header_class
class_name
=
if
nav_menu_collapsed?
"header-collapsed"
else
"header-expanded"
end
class_name
+=
" with-horizontal-nav"
if
defined?
(
nav
)
&&
nav
class_name
=
" with-horizontal-nav"
if
defined?
(
nav
)
&&
nav
class_name
end
...
...
app/helpers/workhorse_helper.rb
0 → 100644
View file @
17ab3730
# Helpers to send Git blobs, diffs or archives through Workhorse.
# Workhorse will also serve files when using `send_file`.
module
WorkhorseHelper
# Send a Git blob through Workhorse
def
send_git_blob
(
repository
,
blob
)
headers
.
store
(
*
Gitlab
::
Workhorse
.
send_git_blob
(
repository
,
blob
))
headers
[
'Content-Disposition'
]
=
'inline'
headers
[
'Content-Type'
]
=
safe_content_type
(
blob
)
head
:ok
# 'render nothing: true' messes up the Content-Type
end
# Send a Git diff through Workhorse
def
send_git_diff
(
repository
,
diff_refs
)
headers
.
store
(
*
Gitlab
::
Workhorse
.
send_git_diff
(
repository
,
diff_refs
))
headers
[
'Content-Disposition'
]
=
'inline'
head
:ok
end
# Archive a Git repository and send it through Workhorse
def
send_git_archive
(
repository
,
ref
:,
format
:)
headers
.
store
(
*
Gitlab
::
Workhorse
.
send_git_archive
(
repository
,
ref:
ref
,
format:
format
))
head
:ok
end
end
app/models/merge_request.rb
View file @
17ab3730
...
...
@@ -276,14 +276,6 @@ class MergeRequest < ActiveRecord::Base
true
end
def
gitlab_merge_status
if
work_in_progress?
"work_in_progress"
else
merge_status_name
end
end
def
can_cancel_merge_when_build_succeeds?
(
current_user
)
can_be_merged_by?
(
current_user
)
||
self
.
author
==
current_user
end
...
...
app/models/project.rb
View file @
17ab3730
...
...
@@ -253,20 +253,69 @@ class Project < ActiveRecord::Base
non_archived
.
where
(
table
[
:name
].
matches
(
pattern
))
end
def
find_with_namespace
(
id
)
namespace_path
,
project_path
=
id
.
split
(
'/'
,
2
)
# Finds a single project for the given path.
#
# path - The full project path (including namespace path).
#
# Returns a Project, or nil if no project could be found.
def
find_with_namespace
(
path
)
where_paths_in
([
path
]).
reorder
(
nil
).
take
end
return
nil
if
!
namespace_path
||
!
project_path
# Builds a relation to find multiple projects by their full paths.
#
# Each path must be in the following format:
#
# namespace_path/project_path
#
# For example:
#
# gitlab-org/gitlab-ce
#
# Usage:
#
# Project.where_paths_in(%w{gitlab-org/gitlab-ce gitlab-org/gitlab-ee})
#
# This would return the projects with the full paths matching the values
# given.
#
# paths - An Array of full paths (namespace path + project path) for which
# to find the projects.
#
# Returns an ActiveRecord::Relation.
def
where_paths_in
(
paths
)
wheres
=
[]
cast_lower
=
Gitlab
::
Database
.
postgresql?
# Use of unscoped ensures we're not secretly adding any ORDER BYs, which
# have a negative impact on performance (and aren't needed for this
# query).
projects
=
unscoped
.
joins
(
:namespace
).
iwhere
(
'namespaces.path'
=>
namespace_path
)
paths
.
each
do
|
path
|
namespace_path
,
project_path
=
path
.
split
(
'/'
,
2
)
next
unless
namespace_path
&&
project_path
namespace_path
=
connection
.
quote
(
namespace_path
)
project_path
=
connection
.
quote
(
project_path
)
projects
.
find_by
(
'projects.path'
=>
project_path
)
||
projects
.
iwhere
(
'projects.path'
=>
project_path
).
take
where
=
"(namespaces.path =
#{
namespace_path
}
AND projects.path =
#{
project_path
}
)"
if
cast_lower
where
=
"(
#{
where
}
OR (
LOWER(namespaces.path) = LOWER(
#{
namespace_path
}
)
AND LOWER(projects.path) = LOWER(
#{
project_path
}
)
)
)"
end
wheres
<<
where
end
if
wheres
.
empty?
none
else
joins
(
:namespace
).
where
(
wheres
.
join
(
' OR '
))
end
end
def
visibility_levels
...
...
app/views/layouts/_collapse_button.html.haml
View file @
17ab3730
-
if
nav_menu_collapsed?
=
link_to
icon
(
'angle-right'
),
'#'
,
class:
'toggle-nav-collapse'
,
title:
"Open/Close"
-
else
=
link_to
icon
(
'angle-left'
),
'#'
,
class:
'toggle-nav-collapse'
,
title:
"Open/Close"
=
link_to
icon
(
'bars'
),
'#'
,
class:
'toggle-nav-collapse'
,
title:
"Open/Close"
app/views/layouts/_page.html.haml
View file @
17ab3730
.page-with-sidebar
{
class:
"#{page_sidebar_class}
#{page_gutter_class}"
}
.page-with-sidebar
.page-sidebar-collapsed
{
class:
"
#{page_gutter_class}"
}
.sidebar-wrapper.nicescroll
{
class:
nav_sidebar_class
}
=
link_to
root_path
,
class:
'gitlab-text-container-link'
,
title:
'Dashboard'
,
id:
'js-shortcuts-home'
do
.header-logo
#logo
=
brand_header_logo
-
if
defined?
(
sidebar
)
&&
sidebar
=
render
"layouts/nav/
#{
sidebar
}
"
...
...
@@ -16,7 +12,9 @@
=
render
partial:
'layouts/collapse_button'
-
if
current_user
=
link_to
current_user
,
class:
'sidebar-user'
,
title:
"Profile"
,
data:
{
user:
current_user
.
username
}
do
=
image_tag
avatar_icon
(
current_user
,
60
),
alt:
'Profile'
,
class:
'avatar avatar s46'
=
image_tag
avatar_icon
(
current_user
,
60
),
alt:
'Profile'
,
class:
'avatar avatar s36'
.username
=
current_user
.
username
-
if
defined?
(
nav
)
&&
nav
.layout-nav
.container-fluid
...
...
app/views/layouts/ci/_page.html.haml
View file @
17ab3730
.page-with-sidebar
{
class:
page_sidebar_class
}
=
render
"layouts/broadcast"
.sidebar-wrapper.nicescroll
{
class:
nav_sidebar_class
}
.header-logo
%a
#logo
=
brand_header_logo
=
link_to
root_path
,
class:
'gitlab-text-container-link'
,
title:
'Dashboard'
,
id:
'js-shortcuts-home'
do
.gitlab-text-container
%h3
GitLab
-
if
defined?
(
sidebar
)
&&
sidebar
=
render
"layouts/ci/
#{
sidebar
}
"
...
...
app/views/layouts/header/_default.html.haml
View file @
17ab3730
%header
.navbar.navbar-fixed-top.navbar-gitlab
{
class:
nav_header_class
}
%header
.navbar.navbar-fixed-top.navbar-gitlab
.header-collapsed
{
class:
nav_header_class
}
%div
{
class:
fluid_layout
?
"container-fluid"
:
"container-fluid"
}
.header-content
%button
.side-nav-toggle
{
type:
'button'
}
...
...
@@ -50,6 +50,10 @@
%h1
.title
=
title
.header-logo
#logo
=
brand_header_logo
=
yield
:header_content
=
render
'shared/outdated_browser'
...
...
app/views/layouts/nav/_admin.html.haml
View file @
17ab3730
...
...
@@ -2,102 +2,106 @@
=
nav_link
(
controller: :dashboard
,
html_options:
{
class:
'home'
})
do
=
link_to
admin_root_path
,
title:
'Overview'
do
=
icon
(
'dashboard fw'
)
.nav-link-text
%span
Overview
=
nav_link
(
controller:
[
:admin
,
:projects
])
do
=
link_to
admin_namespaces_projects_path
,
title:
'Projects'
do
=
icon
(
'cube fw'
)
.nav-link-text
%span
Projects
=
nav_link
(
controller: :users
)
do
=
link_to
admin_users_path
,
title:
'Users'
do
=
icon
(
'user fw'
)
.nav-link-text
%span
Users
=
nav_link
(
controller: :groups
)
do
=
link_to
admin_groups_path
,
title:
'Groups'
do
=
icon
(
'group fw'
)
.nav-link-text
%span
Groups
=
nav_link
(
controller: :deploy_keys
)
do
=
link_to
admin_deploy_keys_path
,
title:
'Deploy Keys'
do
=
icon
(
'key fw'
)
.nav-link-text
%span
Deploy Keys
=
nav_link
path:
[
'runners#index'
,
'runners#show'
]
do
=
link_to
admin_runners_path
,
title:
'Runners'
do
=
icon
(
'cog fw'
)
.nav-link-text
%span
Runners
%span
.count
=
number_with_delimiter
(
Ci
::
Runner
.
count
(
:all
))
=
nav_link
path:
'builds#index'
do
=
link_to
admin_builds_path
,
title:
'Builds'
do
=
icon
(
'link fw'
)
.nav-link-text
%span
Builds
%span
.count
=
number_with_delimiter
(
Ci
::
Build
.
count
(
:all
))
=
nav_link
(
controller: :logs
)
do
=
link_to
admin_logs_path
,
title:
'Logs'
do
=
icon
(
'file-text fw'
)
.nav-link-text
%span
Logs
=
nav_link
(
controller: :health_check
)
do
=
link_to
admin_health_check_path
,
title:
'Health Check'
do
=
icon
(
'medkit fw'
)
.nav-link-text
%span
Health Check
=
nav_link
(
controller: :broadcast_messages
)
do
=
link_to
admin_broadcast_messages_path
,
title:
'Messages'
do
=
icon
(
'bullhorn fw'
)
.nav-link-text
%span
Messages
=
nav_link
(
controller: :hooks
)
do
=
link_to
admin_hooks_path
,
title:
'Hooks'
do
=
icon
(
'external-link fw'
)
.nav-link-text
%span
Hooks
=
nav_link
(
controller: :background_jobs
)
do
=
link_to
admin_background_jobs_path
,
title:
'Background Jobs'
do
=
icon
(
'cog fw'
)
.nav-link-text
%span
Background Jobs
=
nav_link
(
controller: :appearances
)
do
=
link_to
admin_appearances_path
,
title:
'Appearances'
do
=
icon
(
'image'
)
.nav-link-text
%span
Appearance
=
nav_link
(
controller: :applications
)
do
=
link_to
admin_applications_path
,
title:
'Applications'
do
=
icon
(
'cloud fw'
)
.nav-link-text
%span
Applications
=
nav_link
(
controller: :services
)
do
=
link_to
admin_application_settings_services_path
,
title:
'Service Templates'
do
=
icon
(
'copy fw'
)
.nav-link-text
%span
Service Templates
=
nav_link
(
controller: :labels
)
do
=
link_to
admin_labels_path
,
title:
'Labels'
do
=
icon
(
'tags fw'
)
.nav-link-text
%span
Labels
=
nav_link
(
controller: :abuse_reports
)
do
=
link_to
admin_abuse_reports_path
,
title:
"Abuse Reports"
do
=
icon
(
'exclamation-circle fw'
)
.nav-link-text
%span
Abuse Reports
%span
.count
=
number_with_delimiter
(
AbuseReport
.
count
(
:all
))
-
if
askimet_enabled?
=
nav_link
(
controller: :spam_logs
)
do
=
link_to
admin_spam_logs_path
,
title:
"Spam Logs"
do
=
icon
(
'exclamation-triangle fw'
)
.nav-link-text
%span
Spam Logs
%span
.count
=
number_with_delimiter
(
SpamLog
.
count
(
:all
))
=
nav_link
(
controller: :application_settings
,
html_options:
{
class:
'separate-item'
})
do
=
link_to
admin_application_settings_path
,
title:
'Settings'
do
=
icon
(
'cogs fw'
)
.nav-link-text
%span
Settings
app/views/layouts/nav/_dashboard.html.haml
View file @
17ab3730
...
...
@@ -2,50 +2,53 @@
=
nav_link
(
path:
[
'root#index'
,
'projects#trending'
,
'projects#starred'
,
'dashboard/projects#index'
],
html_options:
{
class:
"
#{
project_tab_class
}
home"
})
do
=
link_to
dashboard_projects_path
,
title:
'Projects'
,
class:
'dashboard-shortcuts-projects'
do
=
navbar_icon
(
'project'
)
.nav-link-text
%span
Projects
=
nav_link
(
controller: :todos
)
do
=
link_to
dashboard_todos_path
,
title:
'Todos'
do
=
icon
(
'bell fw'
)
.nav-link-text
%span
Todos
%span
.count
=
number_with_delimiter
(
todos_pending_count
)
=
nav_link
(
path:
'dashboard#activity'
)
do
=
link_to
activity_dashboard_path
,
class:
'dashboard-shortcuts-activity'
,
title:
'Activity'
do
=
navbar_icon
(
'activity'
)
.nav-link-text
%span
Activity
=
nav_link
(
controller:
[
:groups
,
'groups/milestones'
,
'groups/group_members'
])
do
=
link_to
dashboard_groups_path
,
title:
'Groups'
do
=
navbar_icon
(
'group'
)
.nav-link-text
%span
Groups
=
nav_link
(
controller:
'dashboard/milestones'
)
do
=
link_to
dashboard_milestones_path
,
title:
'Milestones'
do
=
navbar_icon
(
'milestones'
)
.nav-link-text
%span
Milestones
=
nav_link
(
path:
'dashboard#issues'
)
do
=
link_to
assigned_issues_dashboard_path
,
title:
'Issues'
,
class:
'dashboard-shortcuts-issues'
do
=
navbar_icon
(
'issues'
)
.nav-link-text
%span
Issues
%span
.count
=
number_with_delimiter
(
current_user
.
assigned_issues
.
opened
.
count
)
=
nav_link
(
path:
'dashboard#merge_requests'
)
do
=
link_to
assigned_mrs_dashboard_path
,
title:
'Merge Requests'
,
class:
'dashboard-shortcuts-merge_requests'
do
=
navbar_icon
(
'mr'
)
.nav-link-text
%span
Merge Requests
%span
.count
=
number_with_delimiter
(
current_user
.
assigned_merge_requests
.
opened
.
count
)
=
nav_link
(
controller: :snippets
)
do
=
link_to
dashboard_snippets_path
,
title:
'Snippets'
do
=
icon
(
'clipboard fw'
)
.nav-link-text
%span
Snippets
=
nav_link
(
controller: :help
)
do
=
link_to
help_path
,
title:
'Help'
do
=
icon
(
'question-circle fw'
)
.nav-link-text
%span
Help
=
nav_link
(
html_options:
{
class:
profile_tab_class
})
do
=
link_to
profile_path
,
title:
'Profile Settings'
,
data:
{
placement:
'bottom'
}
do
=
icon
(
'user fw'
)
.nav-link-text
%span
Profile Settings
app/views/layouts/nav/_explore.html.haml
View file @
17ab3730
...
...
@@ -2,20 +2,20 @@
=
nav_link
(
path:
[
'dashboard#show'
,
'root#show'
,
'projects#trending'
,
'projects#starred'
,
'projects#index'
],
html_options:
{
class:
'home'
})
do
=
link_to
explore_root_path
,
title:
'Projects'
do
=
icon
(
'bookmark fw'
)
.nav-link-text
%span
Projects
=
nav_link
(
controller:
[
:groups
,
'groups/milestones'
,
'groups/group_members'
])
do
=
link_to
explore_groups_path
,
title:
'Groups'
do
=
icon
(
'group fw'
)
.nav-link-text
%span
Groups
=
nav_link
(
controller: :snippets
)
do
=
link_to
explore_snippets_path
,
title:
'Snippets'
do
=
icon
(
'clipboard fw'
)
.nav-link-text
%span
Snippets
=
nav_link
(
controller: :help
)
do
=
link_to
help_path
,
title:
'Help'
do
=
icon
(
'question-circle fw'
)
.nav-link-text
%span
Help
app/views/layouts/nav/_group.html.haml
View file @
17ab3730
...
...
@@ -5,36 +5,30 @@
.fade-left
=
nav_link
(
path:
'groups#show'
,
html_options:
{
class:
'home'
})
do
=
link_to
group_path
(
@group
),
title:
'Home'
do
=
navbar_icon
(
'group'
)
%span
Group
=
nav_link
(
path:
'groups#activity'
)
do
=
link_to
activity_group_path
(
@group
),
title:
'Activity'
do
=
navbar_icon
(
'activity'
)
%span
Activity
=
nav_link
(
controller:
[
:group
,
:milestones
])
do
=
link_to
group_milestones_path
(
@group
),
title:
'Milestones'
do
=
navbar_icon
(
'milestones'
)
%span
Milestones
=
nav_link
(
path:
'groups#issues'
)
do
=
link_to
issues_group_path
(
@group
),
title:
'Issues'
do
=
navbar_icon
(
'issues'
)
%span
Issues
-
issues
=
IssuesFinder
.
new
(
current_user
,
group_id:
@group
.
id
,
state:
'opened'
).
execute
%span
.badge.count
=
number_with_delimiter
(
issues
.
count
)
=
nav_link
(
path:
'groups#merge_requests'
)
do
=
link_to
merge_requests_group_path
(
@group
),
title:
'Merge Requests'
do
=
navbar_icon
(
'mr'
)
%span
Merge Requests
-
merge_requests
=
MergeRequestsFinder
.
new
(
current_user
,
group_id:
@group
.
id
,
state:
'opened'
).
execute
%span
.badge.count
=
number_with_delimiter
(
merge_requests
.
count
)
=
nav_link
(
controller:
[
:group_members
])
do
=
link_to
group_group_members_path
(
@group
),
title:
'Members'
do
=
navbar_icon
(
'members'
)
%span
Members
.fade-right
app/views/layouts/nav/_profile.html.haml
View file @
17ab3730
...
...
@@ -2,51 +2,41 @@
.fade-left
=
nav_link
(
path:
'profiles#show'
,
html_options:
{
class:
'home'
})
do
=
link_to
profile_path
,
title:
'Profile Settings'
do
=
icon
(
'user fw'
)
%span
Profile
=
nav_link
(
controller:
[
:accounts
,
:two_factor_auths
])
do
=
link_to
profile_account_path
,
title:
'Account'
do
=
icon
(
'gear fw'
)
%span
Account
-
if
current_application_settings
.
user_oauth_applications?
=
nav_link
(
controller:
'oauth/applications'
)
do
=
link_to
applications_profile_path
,
title:
'Applications'
do
=
icon
(
'cloud fw'
)
%span
Applications
=
nav_link
(
controller: :emails
)
do
=
link_to
profile_emails_path
,
title:
'Emails'
do
=
icon
(
'envelope-o fw'
)
%span
Emails
-
unless
current_user
.
ldap_user?
=
nav_link
(
controller: :passwords
)
do
=
link_to
edit_profile_password_path
,
title:
'Password'
do
=
icon
(
'lock fw'
)
%span
Password
=
nav_link
(
controller: :notifications
)
do
=
link_to
profile_notifications_path
,
title:
'Notifications'
do
=
icon
(
'inbox fw'
)
%span
Notifications
=
nav_link
(
controller: :keys
)
do
=
link_to
profile_keys_path
,
title:
'SSH Keys'
do
=
icon
(
'key fw'
)
%span
SSH Keys
=
nav_link
(
controller: :preferences
)
do
=
link_to
profile_preferences_path
,
title:
'Preferences'
do
-# TODO (rspeicher): Better icon?
=
icon
(
'image fw'
)
%span
Preferences
=
nav_link
(
path:
'profiles#audit_log'
)
do
=
link_to
audit_log_profile_path
,
title:
'Audit Log'
do
=
icon
(
'history fw'
)
%span
Audit Log
.fade-right
app/views/layouts/nav/_project.html.haml
View file @
17ab3730
...
...
@@ -24,55 +24,41 @@
.fade-left
=
nav_link
(
path:
'projects#show'
,
html_options:
{
class:
'home'
})
do
=
link_to
project_path
(
@project
),
title:
'Project'
,
class:
'shortcuts-project'
do
=
navbar_icon
(
'project'
)
%span
Project
=
nav_link
(
path:
'projects#activity'
)
do
=
link_to
activity_project_path
(
@project
),
title:
'Activity'
,
class:
'shortcuts-project-activity'
do
=
navbar_icon
(
'activity'
)
%span
Activity
-
if
project_nav_tab?
:files
=
nav_link
(
controller:
%w(tree blob blame edit_tree new_tree find_file commit commits compare repositories tags branches releases network)
)
do
=
link_to
project_files_path
(
@project
),
title:
'Code'
,
class:
'shortcuts-tree'
do
=
icon
(
'code fw'
)
%span
Code
-
if
project_nav_tab?
:pipelines
=
nav_link
(
controller: :pipelines
)
do
=
link_to
project_pipelines_path
(
@project
),
title:
'Pipelines'
,
class:
'shortcuts-pipelines'
do
=
navbar_icon
(
'pipelines'
)
%span
Pipelines
-
if
project_nav_tab?
:container_registry
=
nav_link
(
controller:
%w(container_registry)
)
do
=
link_to
project_container_registry_path
(
@project
),
title:
'Container Registry'
,
class:
'shortcuts-container-registry'
do
=
icon
(
'hdd-o fw'
)
%span
Registry
-
if
project_nav_tab?
:graphs
=
nav_link
(
controller:
%w(graphs)
)
do
=
link_to
namespace_project_graph_path
(
@project
.
namespace
,
@project
,
current_ref
),
title:
'Graphs'
,
class:
'shortcuts-graphs'
do
=
icon
(
'area-chart fw'
)
%span
Graphs
-
if
project_nav_tab?
:milestones
=
nav_link
(
controller: :milestones
)
do
=
link_to
namespace_project_milestones_path
(
@project
.
namespace
,
@project
),
title:
'Milestones'
do
=
navbar_icon
(
'milestones'
)
%span
Milestones
-
if
project_nav_tab?
:issues
=
nav_link
(
controller:
:issues
)
do
=
nav_link
(
controller:
[
:issues
,
:labels
,
:milestones
]
)
do
=
link_to
url_for_project_issues
(
@project
,
only_path:
true
),
title:
'Issues'
,
class:
'shortcuts-issues'
do
=
navbar_icon
(
'issues'
)
%span
Issues
-
if
@project
.
default_issues_tracker?
...
...
@@ -81,29 +67,19 @@
-
if
project_nav_tab?
:merge_requests
=
nav_link
(
controller: :merge_requests
)
do
=
link_to
namespace_project_merge_requests_path
(
@project
.
namespace
,
@project
),
title:
'Merge Requests'
,
class:
'shortcuts-merge_requests'
do
=
navbar_icon
(
'mr'
)
%span
Merge Requests
%span
.badge.count.merge_counter
=
number_with_delimiter
(
@project
.
merge_requests
.
opened
.
count
)
-
if
project_nav_tab?
:labels
=
nav_link
(
controller: :labels
)
do
=
link_to
namespace_project_labels_path
(
@project
.
namespace
,
@project
),
title:
'Labels'
do
=
icon
(
'tags fw'
)
%span
Labels
-
if
project_nav_tab?
:wiki
=
nav_link
(
controller: :wikis
)
do
=
link_to
get_project_wiki_path
(
@project
),
title:
'Wiki'
,
class:
'shortcuts-wiki'
do
=
navbar_icon
(
'wiki'
)
%span
Wiki
-
if
project_nav_tab?
:snippets
=
nav_link
(
controller: :snippets
)
do
=
link_to
namespace_project_snippets_path
(
@project
.
namespace
,
@project
),
title:
'Snippets'
,
class:
'shortcuts-snippets'
do
=
icon
(
'clipboard fw'
)
%span
Snippets
...
...
app/views/projects/issues/_head.html.haml
0 → 100644
View file @
17ab3730
%ul
.nav-links.sub-nav
%div
{
class:
(
container_class
)
}
-
if
project_nav_tab?
(
:issues
)
&&
!
current_controller?
(
:merge_requests
)
=
nav_link
(
controller: :issues
)
do
=
link_to
url_for_project_issues
(
@project
,
only_path:
true
),
title:
'Issues'
do
%span
Issues
-
if
project_nav_tab?
(
:merge_requests
)
&&
current_controller?
(
:merge_requests
)
=
nav_link
(
controller: :merge_requests
)
do
=
link_to
namespace_project_merge_requests_path
(
@project
.
namespace
,
@project
),
title:
'Merge Requests'
do
%span
Merge Requests
-
if
project_nav_tab?
:labels
=
nav_link
(
controller: :labels
)
do
=
link_to
namespace_project_labels_path
(
@project
.
namespace
,
@project
),
title:
'Labels'
do
%span
Labels
-
if
project_nav_tab?
:milestones
=
nav_link
(
controller: :milestones
)
do
=
link_to
namespace_project_milestones_path
(
@project
.
namespace
,
@project
),
title:
'Milestones'
do
%span
Milestones
app/views/projects/issues/index.html.haml
View file @
17ab3730
-
@no_container
=
true
-
page_title
"Issues"
=
render
"projects/issues/head"
=
content_for
:meta_tags
do
-
if
current_user
=
auto_discovery_link_tag
(
:atom
,
namespace_project_issues_url
(
@project
.
namespace
,
@project
,
:atom
,
private_token:
current_user
.
private_token
),
title:
"
#{
@project
.
name
}
issues"
)
.top-area
%div
{
class:
(
container_class
)
}
.top-area
=
render
'shared/issuable/nav'
,
type: :issues
.nav-controls
-
if
current_user
...
...
@@ -17,7 +20,7 @@
=
link_to
new_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
issue:
{
assignee_id:
@issuable_finder
.
assignee
.
try
(
:id
),
milestone_id:
@issuable_finder
.
milestones
.
try
(
:first
).
try
(
:id
)
}),
class:
"btn btn-new"
,
title:
"New Issue"
,
id:
"new_issue_link"
do
New Issue
=
render
'shared/issuable/filter'
,
type: :issues
=
render
'shared/issuable/filter'
,
type: :issues
.issues-holder
.issues-holder
=
render
"issues"
app/views/projects/labels/index.html.haml
View file @
17ab3730
-
@no_container
=
true
-
page_title
"Labels"
-
hide_class
=
''
=
render
"projects/issues/head"
.top-area
%div
{
class:
(
container_class
)
}
.top-area
.nav-text
Labels can be applied to issues and merge requests.
.nav-controls
...
...
@@ -9,7 +12,7 @@
=
link_to
new_namespace_project_label_path
(
@project
.
namespace
,
@project
),
class:
"btn btn-new"
do
New label
.labels
.labels
-
if
can?
(
current_user
,
:admin_label
,
@project
)
-# Only show it in the first page
-
hide
=
@project
.
labels
.
empty?
||
(
params
[
:page
].
present?
&&
params
[
:page
]
!=
'1'
)
...
...
app/views/projects/merge_requests/_head.html.haml
deleted
100644 → 0
View file @
6c23107d
.top-tabs
=
link_to
namespace_project_merge_requests_path
(
@project
.
namespace
,
@project
),
class:
"tab
#{
'active'
if
current_page?
(
namespace_project_merge_requests_path
(
@project
.
namespace
,
@project
))
}
"
do
%span
Merge Requests
app/views/projects/merge_requests/index.html.haml
View file @
17ab3730
-
@no_container
=
true
-
page_title
"Merge Requests"
=
render
"projects/issues/head"
=
render
'projects/last_push'
.top-area
%div
{
class:
(
container_class
)
}
.top-area
=
render
'shared/issuable/nav'
,
type: :merge_requests
.nav-controls
=
render
'shared/issuable/search_form'
,
path:
namespace_project_merge_requests_path
(
@project
.
namespace
,
@project
)
...
...
@@ -12,7 +14,7 @@
=
link_to
new_namespace_project_merge_request_path
(
merge_project
.
namespace
,
merge_project
),
class:
"btn btn-new"
,
title:
"New Merge Request"
do
New Merge Request
=
render
'shared/issuable/filter'
,
type: :merge_requests
=
render
'shared/issuable/filter'
,
type: :merge_requests
.merge-requests-holder
.merge-requests-holder
=
render
'merge_requests'
app/views/projects/milestones/index.html.haml
View file @
17ab3730
-
@no_container
=
true
-
page_title
"Milestones"
=
render
"projects/issues/head"
.top-area
%div
{
class:
(
container_class
)
}
.top-area
=
render
'shared/milestones_filter'
.nav-controls
...
...
@@ -8,7 +11,7 @@
=
link_to
new_namespace_project_milestone_path
(
@project
.
namespace
,
@project
),
class:
"btn btn-new"
,
title:
"New Milestone"
do
New Milestone
.milestones
.milestones
%ul
.content-list
=
render
@milestones
...
...
doc/api/merge_requests.md
View file @
17ab3730
...
...
@@ -572,7 +572,7 @@ GET /projects/:id/merge_requests/:merge_request_id/closes_issues
curl
-H
"PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK"
https://gitlab.example.com/api/v3/projects/76/merge_requests/1/closes_issues
```
Example response:
Example response
when the GitLab issue tracker is used
:
```
json
[
...
...
@@ -618,6 +618,17 @@ Example response:
]
```
Example response when an external issue tracker (e.g. JIRA) is used:
```
json
[
{
"id"
:
"PROJECT-123"
,
"title"
:
"Title of this issue"
}
]
```
## Subscribe to a merge request
Subscribes the authenticated user to a merge request to receive notification. If
...
...
features/project/active_tab.feature
View file @
17ab3730
...
...
@@ -107,12 +107,16 @@ Feature: Project Active Tab
Scenario
:
On Project Issues/Milestones
Given
I visit my project's issues page
And
I click the
"Milestones"
tab
Then
the active main tab should be Milestones
And
I click the
"Milestones"
sub tab
Then
the active main tab should be Issues
Then
the active sub tab should be Milestones
And
no other main tabs should be active
And
no other sub tabs should be active
Scenario
:
On Project Issues/Labels
Given
I visit my project's issues page
And
I click the
"Labels"
tab
Then
the active main tab should be Labels
And
I click the
"Labels"
sub tab
Then
the active main tab should be Issues
Then
the active sub tab should be Labels
And
no other main tabs should be active
And
no other sub tabs should be active
features/steps/profile/profile.rb
View file @
17ab3730
...
...
@@ -155,6 +155,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps
end
step
'I click on my profile picture'
do
find
(
:css
,
'.side-nav-toggle'
).
click
find
(
:css
,
'.sidebar-user'
).
click
end
...
...
features/steps/project/active_tab.rb
View file @
17ab3730
...
...
@@ -77,14 +77,14 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps
# Sub Tabs: Issues
step
'I click the "Milestones" tab'
do
page
.
within
(
'.
layout
-nav'
)
do
step
'I click the "Milestones"
sub
tab'
do
page
.
within
(
'.
sub
-nav'
)
do
click_link
(
'Milestones'
)
end
end
step
'I click the "Labels" tab'
do
page
.
within
(
'.
layout
-nav'
)
do
step
'I click the "Labels"
sub
tab'
do
page
.
within
(
'.
sub
-nav'
)
do
click_link
(
'Labels'
)
end
end
...
...
@@ -93,11 +93,11 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps
ensure_active_sub_tab
(
'Issues'
)
end
step
'the active
main
tab should be Milestones'
do
ensure_active_
main
_tab
(
'Milestones'
)
step
'the active
sub
tab should be Milestones'
do
ensure_active_
sub
_tab
(
'Milestones'
)
end
step
'the active
main
tab should be Labels'
do
ensure_active_
main
_tab
(
'Labels'
)
step
'the active
sub
tab should be Labels'
do
ensure_active_
sub
_tab
(
'Labels'
)
end
end
features/steps/shared/active_tab.rb
View file @
17ab3730
...
...
@@ -6,7 +6,7 @@ module SharedActiveTab
end
def
ensure_active_sub_tab
(
content
)
expect
(
find
(
'
div.content ul.nav-links
li.active'
)).
to
have_content
(
content
)
expect
(
find
(
'
.sub-nav
li.active'
)).
to
have_content
(
content
)
end
def
ensure_active_sub_nav
(
content
)
...
...
@@ -18,7 +18,7 @@ module SharedActiveTab
end
step
'no other sub tabs should be active'
do
expect
(
page
).
to
have_selector
(
'
div.content ul.nav-links
li.active'
,
count:
1
)
expect
(
page
).
to
have_selector
(
'
.sub-nav
li.active'
,
count:
1
)
end
step
'no other sub navs should be active'
do
...
...
lib/api/entities.rb
View file @
17ab3730
...
...
@@ -179,6 +179,11 @@ module API
expose
:upvotes
,
:downvotes
end
class
ExternalIssue
<
Grape
::
Entity
expose
:title
expose
:id
end
class
MergeRequest
<
ProjectEntity
expose
:target_branch
,
:source_branch
expose
:upvotes
,
:downvotes
...
...
lib/api/helpers.rb
View file @
17ab3730
...
...
@@ -408,5 +408,23 @@ module API
error!
(
errors
[
:access_level
],
422
)
if
errors
[
:access_level
].
any?
not_found!
(
errors
)
end
def
send_git_blob
(
repository
,
blob
)
env
[
'api.format'
]
=
:txt
content_type
'text/plain'
header
(
*
Gitlab
::
Workhorse
.
send_git_blob
(
repository
,
blob
))
end
def
send_git_archive
(
repository
,
ref
:,
format
:)
header
(
*
Gitlab
::
Workhorse
.
send_git_archive
(
repository
,
ref:
ref
,
format:
format
))
end
def
issue_entity
(
project
)
if
project
.
has_external_issue_tracker?
Entities
::
ExternalIssue
else
Entities
::
Issue
end
end
end
end
lib/api/merge_requests.rb
View file @
17ab3730
...
...
@@ -329,7 +329,7 @@ module API
get
"
#{
path
}
/closes_issues"
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
issues
=
::
Kaminari
.
paginate_array
(
merge_request
.
closes_issues
(
current_user
))
present
paginate
(
issues
),
with:
Entities
::
Issue
,
current_user:
current_user
present
paginate
(
issues
),
with:
issue_entity
(
user_project
)
,
current_user:
current_user
end
end
end
...
...
lib/api/repositories.rb
View file @
17ab3730
...
...
@@ -56,8 +56,7 @@ module API
blob
=
Gitlab
::
Git
::
Blob
.
find
(
repo
,
commit
.
id
,
params
[
:filepath
])
not_found!
"File"
unless
blob
content_type
'text/plain'
header
(
*
Gitlab
::
Workhorse
.
send_git_blob
(
repo
,
blob
))
send_git_blob
repo
,
blob
end
# Get a raw blob contents by blob sha
...
...
@@ -80,10 +79,7 @@ module API
not_found!
'Blob'
unless
blob
env
[
'api.format'
]
=
:txt
content_type
blob
.
mime_type
header
(
*
Gitlab
::
Workhorse
.
send_git_blob
(
repo
,
blob
))
send_git_blob
repo
,
blob
end
# Get a an archive of the repository
...
...
@@ -98,7 +94,7 @@ module API
authorize!
:download_code
,
user_project
begin
header
(
*
Gitlab
::
Workhorse
.
send_git_archive
(
user_project
,
params
[
:sha
],
params
[
:format
]))
send_git_archive
user_project
.
repository
,
ref:
params
[
:sha
],
format:
params
[
:format
]
rescue
not_found!
(
'File'
)
end
...
...
lib/backup/manager.rb
View file @
17ab3730
...
...
@@ -38,7 +38,6 @@ module Backup
end
def
upload
(
tar_file
)
remote_directory
=
Gitlab
.
config
.
backup
.
upload
.
remote_directory
$progress
.
print
"Uploading backup archive to remote storage
#{
remote_directory
}
... "
connection_settings
=
Gitlab
.
config
.
backup
.
upload
.
connection
...
...
@@ -47,8 +46,7 @@ module Backup
return
end
connection
=
::
Fog
::
Storage
.
new
(
connection_settings
)
directory
=
connection
.
directories
.
create
(
key:
remote_directory
)
directory
=
connect_to_remote_directory
(
connection_settings
)
if
directory
.
files
.
create
(
key:
tar_file
,
body:
File
.
open
(
tar_file
),
public:
false
,
multipart_chunk_size:
Gitlab
.
config
.
backup
.
upload
.
multipart_chunk_size
,
...
...
@@ -155,6 +153,23 @@ module Backup
private
def
connect_to_remote_directory
(
connection_settings
)
connection
=
::
Fog
::
Storage
.
new
(
connection_settings
)
# We only attempt to create the directory for local backups. For AWS
# and other cloud providers, we cannot guarantee the user will have
# permission to create the bucket.
if
connection
.
service
==
::
Fog
::
Storage
::
Local
connection
.
directories
.
create
(
key:
remote_directory
)
else
connection
.
directories
.
get
(
remote_directory
)
end
end
def
remote_directory
Gitlab
.
config
.
backup
.
upload
.
remote_directory
end
def
backup_contents
folders_to_backup
+
archives_to_backup
+
[
"backup_information.yml"
]
end
...
...
lib/gitlab/workhorse.rb
View file @
17ab3730
...
...
@@ -21,27 +21,29 @@ module Gitlab
[
SEND_DATA_HEADER
,
"git-blob:
#{
encode
(
params
)
}
"
,
"git-blob:
#{
encode
(
params
)
}
"
]
end
def
send_git_archive
(
project
,
ref
,
format
)
def
send_git_archive
(
repository
,
ref
:,
format
:
)
format
||=
'tar.gz'
format
.
downcase!
params
=
project
.
repository
.
archive_metadata
(
ref
,
Gitlab
.
config
.
gitlab
.
repository_downloads_path
,
format
)
params
=
repository
.
archive_metadata
(
ref
,
Gitlab
.
config
.
gitlab
.
repository_downloads_path
,
format
)
raise
"Repository or ref not found"
if
params
.
empty?
[
SEND_DATA_HEADER
,
"git-archive:
#{
encode
(
params
)
}
"
,
"git-archive:
#{
encode
(
params
)
}
"
]
end
def
send_git_diff
(
repository
,
from
,
to
)
def
send_git_diff
(
repository
,
diff_refs
)
from
,
to
=
diff_refs
params
=
{
'RepoPath'
=>
repository
.
path_to_repo
,
'ShaFrom'
=>
from
,
'ShaTo'
=>
to
'ShaFrom'
=>
from
.
sha
,
'ShaTo'
=>
to
.
sha
}
[
...
...
spec/controllers/projects/merge_requests_controller_spec.rb
View file @
17ab3730
...
...
@@ -91,7 +91,7 @@ describe Projects::MergeRequestsController do
id:
merge_request
.
iid
,
format: :diff
)
expect
(
response
.
headers
[
'Gitlab-Workhorse-Send-Data'
]).
to
start_with
(
"git-diff:"
)
expect
(
response
.
headers
[
Gitlab
::
Workhorse
::
SEND_DATA_HEADER
]).
to
start_with
(
"git-diff:"
)
end
end
...
...
spec/controllers/projects/raw_controller_spec.rb
View file @
17ab3730
...
...
@@ -17,6 +17,7 @@ describe Projects::RawController do
expect
(
response
.
header
[
'Content-Type'
]).
to
eq
(
'text/plain; charset=utf-8'
)
expect
(
response
.
header
[
'Content-Disposition'
]).
to
eq
(
"inline"
)
expect
(
response
.
header
[
Gitlab
::
Workhorse
::
SEND_DATA_HEADER
]).
to
start_with
(
"git-blob:"
)
end
end
...
...
@@ -31,6 +32,7 @@ describe Projects::RawController do
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
response
.
header
[
'Content-Type'
]).
to
eq
(
'image/jpeg'
)
expect
(
response
.
header
[
Gitlab
::
Workhorse
::
SEND_DATA_HEADER
]).
to
start_with
(
"git-blob:"
)
end
end
...
...
spec/controllers/projects/repositories_controller_spec.rb
View file @
17ab3730
...
...
@@ -20,10 +20,11 @@ describe Projects::RepositoriesController do
project
.
team
<<
[
user
,
:developer
]
sign_in
(
user
)
end
it
"uses Gitlab::Workhorse"
do
expect
(
Gitlab
::
Workhorse
).
to
receive
(
:send_git_archive
).
with
(
project
,
"master"
,
"zip"
)
it
"uses Gitlab::Workhorse"
do
get
:archive
,
namespace_id:
project
.
namespace
.
path
,
project_id:
project
.
path
,
ref:
"master"
,
format:
"zip"
expect
(
response
.
header
[
Gitlab
::
Workhorse
::
SEND_DATA_HEADER
]).
to
start_with
(
"git-archive:"
)
end
context
"when the service raises an error"
do
...
...
spec/features/profiles/preferences_spec.rb
View file @
17ab3730
...
...
@@ -54,7 +54,7 @@ describe 'Profile > Preferences', feature: true do
end
end
describe
'User changes their default dashboard'
do
describe
'User changes their default dashboard'
,
js:
true
do
it
'creates a flash message'
do
select
'Starred Projects'
,
from:
'user_dashboard'
click_button
'Save'
...
...
@@ -66,8 +66,10 @@ describe 'Profile > Preferences', feature: true do
select
'Starred Projects'
,
from:
'user_dashboard'
click_button
'Save'
click_link
'Dashboard'
allowing_for_delay
do
find
(
'#logo'
).
click
expect
(
page
.
current_path
).
to
eq
starred_dashboard_projects_path
end
click_link
'Your Projects'
expect
(
page
.
current_path
).
to
eq
dashboard_projects_path
...
...
spec/lib/gitlab/workhorse_spec.rb
View file @
17ab3730
...
...
@@ -11,7 +11,7 @@ describe Gitlab::Workhorse, lib: true do
end
it
"raises an error"
do
expect
{
subject
.
send_git_archive
(
project
,
"master"
,
"zip"
)
}.
to
raise_error
(
RuntimeError
)
expect
{
subject
.
send_git_archive
(
project
.
repository
,
ref:
"master"
,
format:
"zip"
)
}.
to
raise_error
(
RuntimeError
)
end
end
end
...
...
spec/models/project_spec.rb
View file @
17ab3730
...
...
@@ -922,4 +922,37 @@ describe Project, models: true do
it
{
is_expected
.
to
be_falsey
}
end
end
describe
'.where_paths_in'
do
context
'without any paths'
do
it
'returns an empty relation'
do
expect
(
Project
.
where_paths_in
([])).
to
eq
([])
end
end
context
'without any valid paths'
do
it
'returns an empty relation'
do
expect
(
Project
.
where_paths_in
(
%w[foo]
)).
to
eq
([])
end
end
context
'with valid paths'
do
let!
(
:project1
)
{
create
(
:project
)
}
let!
(
:project2
)
{
create
(
:project
)
}
it
'returns the projects matching the paths'
do
projects
=
Project
.
where_paths_in
([
project1
.
path_with_namespace
,
project2
.
path_with_namespace
])
expect
(
projects
).
to
contain_exactly
(
project1
,
project2
)
end
it
'returns projects regardless of the casing of paths'
do
projects
=
Project
.
where_paths_in
([
project1
.
path_with_namespace
.
upcase
,
project2
.
path_with_namespace
.
upcase
])
expect
(
projects
).
to
contain_exactly
(
project1
,
project2
)
end
end
end
end
spec/requests/api/merge_requests_spec.rb
View file @
17ab3730
...
...
@@ -563,6 +563,21 @@ describe API::API, api: true do
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
.
length
).
to
eq
(
0
)
end
it
'handles external issues'
do
jira_project
=
create
(
:jira_project
,
:public
,
name:
'JIR_EXT1'
)
issue
=
ExternalIssue
.
new
(
"
#{
jira_project
.
name
}
-123"
,
jira_project
)
merge_request
=
create
(
:merge_request
,
:simple
,
author:
user
,
assignee:
user
,
source_project:
jira_project
)
merge_request
.
update_attribute
(
:description
,
"Closes
#{
issue
.
to_reference
(
jira_project
)
}
"
)
get
api
(
"/projects/
#{
jira_project
.
id
}
/merge_requests/
#{
merge_request
.
id
}
/closes_issues"
,
user
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
.
length
).
to
eq
(
1
)
expect
(
json_response
.
first
[
'title'
]).
to
eq
(
issue
.
title
)
expect
(
json_response
.
first
[
'id'
]).
to
eq
(
issue
.
id
)
end
end
describe
'POST :id/merge_requests/:merge_request_id/subscription'
do
...
...
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