Commit 1ef2ce95 authored by Patricio Cano's avatar Patricio Cano

Merge branch 'master' into notification-levels

parents 4c98357f c99473e5
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
v 8.0.0 (unreleased) v 8.0.0 (unreleased)
- Bump rouge to 1.10.1 to remove warning noise and fix other syntax highlighting bugs (Stan Hu)
- Gracefully handle errors in syntax highlighting by leaving the block unformatted (Stan Hu)
- Fix URL construction for merge requests, issues, notes, and commits for relative URL config (Stan Hu) - Fix URL construction for merge requests, issues, notes, and commits for relative URL config (Stan Hu)
- Fix emoji URLs in Markdown when relative_url_root is used (Stan Hu) - Fix emoji URLs in Markdown when relative_url_root is used (Stan Hu)
- Omit filename in Content-Disposition header in raw file download to avoid RFC 6266 encoding issues (Stan HU) - Omit filename in Content-Disposition header in raw file download to avoid RFC 6266 encoding issues (Stan HU)
- Fix broken Wiki Page History (Stan Hu) - Fix broken Wiki Page History (Stan Hu)
- Import forked repositories asynchronously to prevent large repositories from timing out (Stan Hu)
- Prevent anchors from being hidden by header (Stan Hu) - Prevent anchors from being hidden by header (Stan Hu)
- Fix bug where only the first 15 Bitbucket issues would be imported (Stan Hu) - Fix bug where only the first 15 Bitbucket issues would be imported (Stan Hu)
- Sort issues by creation date in Bitbucket importer (Stan Hu) - Sort issues by creation date in Bitbucket importer (Stan Hu)
- Upgrade gitlab_git to 7.2.15 to fix `git blame` errors with ISO-encoded files (Stan Hu)
- Prevent too many redirects upon login when home page URL is set to external_url (Stan Hu) - Prevent too many redirects upon login when home page URL is set to external_url (Stan Hu)
- Improve dropdown positioning on the project home page (Hannes Rosenögger) - Improve dropdown positioning on the project home page (Hannes Rosenögger)
- Upgrade browser gem to 1.0.0 to avoid warning in IE11 compatibilty mode (Stan Hu) - Upgrade browser gem to 1.0.0 to avoid warning in IE11 compatibilty mode (Stan Hu)
...@@ -30,31 +32,36 @@ v 8.0.0 (unreleased) ...@@ -30,31 +32,36 @@ v 8.0.0 (unreleased)
- Fix 500 error when submit project snippet without body - Fix 500 error when submit project snippet without body
- Improve search page usability - Improve search page usability
- Bring more UI consistency in way how projects, snippets and groups lists are rendered - Bring more UI consistency in way how projects, snippets and groups lists are rendered
- Make all profiles public - Make all profiles and group public
- Fixed login failure when extern_uid changes (Joel Koglin) - Fixed login failure when extern_uid changes (Joel Koglin)
- Don't notify users without access to the project when they are (accidentally) mentioned in a note. - Don't notify users without access to the project when they are (accidentally) mentioned in a note.
- Retrieving oauth token with LDAP credentials - Retrieving oauth token with LDAP credentials
- Load Application settings from running database unless env var USE_DB=false - Load Application settings from running database unless env var USE_DB=false
- Added Drone CI integration (Kirill Zaitsev) - Added Drone CI integration (Kirill Zaitsev)
- Refactored service API and added automatically service docs generator (Kirill Zaitsev) - Refactored service API and added automatically service docs generator (Kirill Zaitsev)
- Added web_url key project hook_attrs (Kirill Zaitsev) - Added web_url key project hook_attrs (Kirill Zaitsev)
- Add ability to get user information by ID of an SSH key via the API - Add ability to get user information by ID of an SSH key via the API
- Fix bug which IE cannot show image at markdown when the image is raw file of gitlab - Fix bug which IE cannot show image at markdown when the image is raw file of gitlab
- Add support for Crowd - Add support for Crowd
- Global Labels that are available to all projects - Global Labels that are available to all projects
- Fix highlighting of deleted lines in diffs. - Fix highlighting of deleted lines in diffs.
- Project notification level can be set on the project page itself - Project notification level can be set on the project page itself
- Added service API endpoint to retrieve service parameters (Petheő Bence)
- Add FogBugz project import (Jared Szechy)
v 7.14.3
- No changes
v 7.14.2
- Upgrade gitlab_git to 7.2.15 to fix `git blame` errors with ISO-encoded files (Stan Hu)
v 7.14.1 v 7.14.1
- Improve abuse reports management from admin area - Improve abuse reports management from admin area
- Fix "Reload with full diff" URL button in compare branch view (Stan Hu) - Fix "Reload with full diff" URL button in compare branch view (Stan Hu)
- Disabled DNS lookups for SSH in docker image (Rowan Wookey) - Disabled DNS lookups for SSH in docker image (Rowan Wookey)
v 7.14.1 (unreleased)
- Only include base URL in OmniAuth full_host parameter (Stan Hu) - Only include base URL in OmniAuth full_host parameter (Stan Hu)
- Fix Error 500 in API when accessing a group that has an avatar (Stan Hu) - Fix Error 500 in API when accessing a group that has an avatar (Stan Hu)
- Ability to enable SSL verification for Webhooks - Ability to enable SSL verification for Webhooks
- Add FogBugz project import (Jared Szechy)
v 7.14.0 v 7.14.0
- Fix bug where non-project members of the target project could set labels on new merge requests. - Fix bug where non-project members of the target project could set labels on new merge requests.
......
...@@ -291,7 +291,7 @@ GEM ...@@ -291,7 +291,7 @@ GEM
github-markup (~> 1.3.1) github-markup (~> 1.3.1)
gollum-grit_adapter (~> 0.1, >= 0.1.1) gollum-grit_adapter (~> 0.1, >= 0.1.1)
nokogiri (~> 1.6.4) nokogiri (~> 1.6.4)
rouge (~> 1.9) rouge (~> 1.10.1)
sanitize (~> 2.1.0) sanitize (~> 2.1.0)
stringex (~> 2.5.1) stringex (~> 2.5.1)
gon (5.0.1) gon (5.0.1)
...@@ -544,7 +544,7 @@ GEM ...@@ -544,7 +544,7 @@ GEM
netrc (~> 0.7) netrc (~> 0.7)
rinku (1.7.3) rinku (1.7.3)
rotp (1.6.1) rotp (1.6.1)
rouge (1.9.1) rouge (1.10.1)
rqrcode (0.4.2) rqrcode (0.4.2)
rqrcode-rails3 (0.1.7) rqrcode-rails3 (0.1.7)
rqrcode (>= 0.4.2) rqrcode (>= 0.4.2)
......
...@@ -167,6 +167,7 @@ class @DropzoneInput ...@@ -167,6 +167,7 @@ class @DropzoneInput
dataType: "json" dataType: "json"
).success (data) -> ).success (data) ->
preview.html data.body preview.html data.body
preview.syntaxHighlight()
renderReferencedUsers data.references.users renderReferencedUsers data.references.users
......
...@@ -122,8 +122,9 @@ class @Notes ...@@ -122,8 +122,9 @@ class @Notes
# or skip if rendered # or skip if rendered
if @isNewNote(note) if @isNewNote(note)
@note_ids.push(note.id) @note_ids.push(note.id)
$('ul.main-notes-list').append(note.html) $('ul.main-notes-list').
$('.js-syntax-highlight').syntaxHighlight() append(note.html).
syntaxHighlight()
@initTaskList() @initTaskList()
### ###
......
# Syntax Highlighter
#
# Applies a syntax highlighting color scheme CSS class to any element with the # Applies a syntax highlighting color scheme CSS class to any element with the
# `js-syntax-highlight` class # `js-syntax-highlight` class
# #
...@@ -6,7 +8,13 @@ ...@@ -6,7 +8,13 @@
# <div class="js-syntax-highlight"></div> # <div class="js-syntax-highlight"></div>
# #
$.fn.syntaxHighlight = -> $.fn.syntaxHighlight = ->
$(this).addClass(gon.user_color_scheme) if $(this).hasClass('js-syntax-highlight')
# Given the element itself, apply highlighting
$(this).addClass(gon.user_color_scheme)
else
# Given a parent element, recurse to any of its applicable children
$children = $(this).find('.js-syntax-highlight')
$children.syntaxHighlight() if $children.length
$(document).on 'ready page:load', -> $(document).on 'ready page:load', ->
$('.js-syntax-highlight').syntaxHighlight() $('.js-syntax-highlight').syntaxHighlight()
...@@ -156,10 +156,16 @@ ...@@ -156,10 +156,16 @@
* Add some extra stuff to panels * Add some extra stuff to panels
* *
*/ */
.container-blank .panel .panel-heading {
font-size: 17px;
line-height: 38px;
}
.panel { .panel {
.panel-heading { box-shadow: none;
font-weight: bold;
.panel-heading {
.panel-head-actions { .panel-head-actions {
position: relative; position: relative;
top: -5px; top: -5px;
...@@ -182,6 +188,10 @@ ...@@ -182,6 +188,10 @@
.pagination { .pagination {
margin: 0; margin: 0;
} }
.btn {
min-width: 124px;
}
} }
&.panel-small { &.panel-small {
...@@ -209,6 +219,12 @@ ...@@ -209,6 +219,12 @@
} }
} }
.alert-help {
background-color: $background-color;
border: 1px solid $border-color;
color: $gl-gray;
}
// Typography ================================================================= // Typography =================================================================
.text-primary, .text-primary,
......
...@@ -114,11 +114,12 @@ $alert-border-radius: 0; ...@@ -114,11 +114,12 @@ $alert-border-radius: 0;
// //
//## //##
$panel-border-radius: 0; $panel-border-radius: 2px;
$panel-default-text: $text-color; $panel-default-text: $text-color;
$panel-default-border: #E7E9ED; $panel-default-border: $border-color;
$panel-default-heading-bg: #F8FAFC; $panel-default-heading-bg: $background-color;
$panel-footer-bg: $background-color;
$panel-inner-border: $border-color;
//== Wells //== Wells
// //
......
...@@ -55,10 +55,10 @@ ...@@ -55,10 +55,10 @@
} }
@mixin md-typography { @mixin md-typography {
color: #444; color: $md-text-color;
a { a {
color: #3084bb; color: $md-link-color;
} }
img { img {
......
...@@ -2,6 +2,8 @@ $hover: #FFFAF1; ...@@ -2,6 +2,8 @@ $hover: #FFFAF1;
$gl-text-color: #54565b; $gl-text-color: #54565b;
$gl-header-color: #4c4e54; $gl-header-color: #4c4e54;
$gl-link-color: #333c48; $gl-link-color: #333c48;
$md-text-color: #444;
$md-link-color: #3084bb;
$nprogress-color: #c0392b; $nprogress-color: #c0392b;
$gl-font-size: 15px; $gl-font-size: 15px;
$list-font-size: 15px; $list-font-size: 15px;
......
...@@ -27,6 +27,10 @@ ...@@ -27,6 +27,10 @@
border-bottom: 1px solid #e7e9ed; border-bottom: 1px solid #e7e9ed;
color: $gl-gray; color: $gl-gray;
&.top-block {
border-top: none;
}
&.middle-block { &.middle-block {
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
...@@ -47,6 +51,6 @@ ...@@ -47,6 +51,6 @@
} }
.oneline { .oneline {
line-height: 44px; line-height: 42px;
} }
} }
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
} }
&.btn-save { &.btn-save {
@extend .btn-primary; @extend .btn-success;
} }
&.btn-remove { &.btn-remove {
......
...@@ -3,7 +3,11 @@ ...@@ -3,7 +3,11 @@
* *
*/ */
.file-holder { .file-holder {
border: 1px solid $border-color; margin-left: -$gl-padding;
margin-right: -$gl-padding;
border: none;
border-top: 1px solid #E7E9EE;
border-bottom: 1px solid #E7E9EE;
margin-bottom: 1em; margin-bottom: 1em;
table { table {
...@@ -49,7 +53,7 @@ ...@@ -49,7 +53,7 @@
} }
&.wiki { &.wiki {
padding: 25px; padding: $gl-padding;
.highlight { .highlight {
margin-bottom: 9px; margin-bottom: 9px;
...@@ -90,7 +94,7 @@ ...@@ -90,7 +94,7 @@
border-right: none; border-right: none;
} }
background: #fff; background: #fff;
padding: 8px; padding: 10px $gl-padding;
} }
.lines { .lines {
pre { pre {
...@@ -100,6 +104,33 @@ ...@@ -100,6 +104,33 @@
border: none; border: none;
} }
} }
img.avatar {
border: 0 none;
float: none;
margin: 0;
padding: 0;
}
td.blame-commit {
background: #f9f9f9;
min-width: 350px;
.commit-author-link {
color: #888;
}
}
td.blame-numbers {
pre {
color: #AAA;
white-space: pre;
}
background: #f1f1f1;
border-left: 1px solid #DDD;
}
td.lines {
code {
font-family: $monospace_font;
}
}
} }
&.logs { &.logs {
......
...@@ -28,12 +28,18 @@ ...@@ -28,12 +28,18 @@
padding: $gl-padding; padding: $gl-padding;
border: 1px solid #e7e9ed; border: 1px solid #e7e9ed;
min-height: 90vh; min-height: 90vh;
&.container-blank {
background: none;
padding: 0;
border: none;
}
} }
} }
.nav-sidebar { .nav-sidebar {
margin-top: 14 + $header-height; margin-top: 14 + $header-height;
margin-bottom: 50px; margin-bottom: 100px;
transition-duration: .3s; transition-duration: .3s;
list-style: none; list-style: none;
overflow: hidden; overflow: hidden;
...@@ -146,7 +152,6 @@ ...@@ -146,7 +152,6 @@
} }
.collapse-nav a { .collapse-nav a {
left: 0px;
width: $sidebar_collapsed_width; width: $sidebar_collapsed_width;
} }
...@@ -165,6 +170,7 @@ ...@@ -165,6 +170,7 @@
width: $sidebar_width; width: $sidebar_width;
position: fixed; position: fixed;
bottom: 0; bottom: 0;
left: 0;
font-size: 13px; font-size: 13px;
background: transparent; background: transparent;
height: 40px; height: 40px;
......
...@@ -5,15 +5,19 @@ pre.code.highlight.white, ...@@ -5,15 +5,19 @@ pre.code.highlight.white,
background-color: #fff; background-color: #fff;
color: #333; color: #333;
pre.highlight,
.line-numbers, .line-numbers,
.line-numbers a { .line-numbers a {
background-color: $background-color !important;
color: $gl-gray !important;
}
pre.highlight {
background-color: #fff !important; background-color: #fff !important;
color: #333 !important; color: #333 !important;
} }
pre.code { pre.code {
border-left: 1px solid #bbb; border-left: 1px solid $border-color;
} }
// highlight line via anchor // highlight line via anchor
......
.diff-file { .diff-file {
margin-left: -16px; margin-left: -$gl-padding;
margin-right: -16px; margin-right: -$gl-padding;
border: none; border: none;
border-bottom: 1px solid #E7E9EE; border-bottom: 1px solid #E7E9EE;
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
position: relative; position: relative;
background: $background-color; background: $background-color;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
padding: 10px 15px; padding: 10px 16px;
color: #555; color: #555;
z-index: 10; z-index: 10;
......
...@@ -235,8 +235,6 @@ ul.notes { ...@@ -235,8 +235,6 @@ ul.notes {
filter: alpha(opacity=0); filter: alpha(opacity=0);
&:hover { &:hover {
width: 38px;
font-size: 20px;
background: $gl-info; background: $gl-info;
color: #FFF; color: #FFF;
@include show-add-diff-note; @include show-add-diff-note;
......
...@@ -48,7 +48,6 @@ ...@@ -48,7 +48,6 @@
p { p {
color: #7f8fa4; color: #7f8fa4;
display: inline;
} }
} }
...@@ -204,26 +203,18 @@ ul.nav.nav-projects-tabs { ...@@ -204,26 +203,18 @@ ul.nav.nav-projects-tabs {
} }
.fork-namespaces { .fork-namespaces {
.thumbnail { .fork-thumbnail {
text-align: center;
margin-bottom: $gl-padding;
&.fork-exists-thumbnail { .caption {
border-color: #EEE; padding: $gl-padding 0;
min-height: 30px;
.caption {
color: #999;
}
}
&.fork-thumbnail {
border-color: #AAA;
&:hover {
background-color: $hover;
}
} }
a { img {
text-decoration: none; @include border-radius(50%);
max-width: 100px;
} }
} }
} }
......
...@@ -78,36 +78,6 @@ ...@@ -78,36 +78,6 @@
} }
} }
} }
.blame {
img.avatar {
border: 0 none;
float: none;
margin: 0;
padding: 0;
}
td.blame-commit {
background: #f9f9f9;
min-width: 350px;
.commit-author-link {
color: #888;
}
}
td.blame-numbers {
pre {
color: #AAA;
white-space: pre;
}
background: #f1f1f1;
border-left: 1px solid #DDD;
}
td.lines {
code {
font-family: $monospace_font;
}
}
}
} }
.tree-ref-holder { .tree-ref-holder {
...@@ -132,17 +102,14 @@ ...@@ -132,17 +102,14 @@
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
margin-bottom: 10px; margin-bottom: 5px;
.commit { .commit {
padding: 10px 15px; padding: $gl-padding 0;
.commit-row-title { .commit-row-title {
font-size: 13px;
.commit-row-message { .commit-row-message {
font-weight: normal; font-weight: normal;
color: #555;
} }
} }
} }
......
class Dashboard::ProjectsController < Dashboard::ApplicationController class Dashboard::ProjectsController < Dashboard::ApplicationController
before_action :event_filter before_action :event_filter
def index
@projects = current_user.authorized_projects.sorted_by_activity.non_archived
@projects = @projects.includes(:namespace)
@last_push = current_user.recent_push
respond_to do |format|
format.html
format.atom do
event_filter
load_events
render layout: false
end
end
end
def starred def starred
@projects = current_user.starred_projects @projects = current_user.starred_projects
@projects = @projects.includes(:namespace, :forked_from_project, :tags) @projects = @projects.includes(:namespace, :forked_from_project, :tags)
......
class Dashboard::SnippetsController < Dashboard::ApplicationController
def index
@snippets = SnippetsFinder.new.execute(current_user,
filter: :by_user,
user: current_user,
scope: params[:scope]
)
@snippets = @snippets.page(params[:page]).per(PER_PAGE)
end
end
class DashboardController < Dashboard::ApplicationController class DashboardController < Dashboard::ApplicationController
before_action :load_projects, except: :activity
before_action :event_filter, only: :activity before_action :event_filter, only: :activity
respond_to :html respond_to :html
def show
@projects = @projects.includes(:namespace)
@last_push = current_user.recent_push
respond_to do |format|
format.html
format.atom do
event_filter
load_events
render layout: false
end
end
end
def merge_requests def merge_requests
@merge_requests = get_merge_requests_collection @merge_requests = get_merge_requests_collection
@merge_requests = @merge_requests.page(params[:page]).per(PER_PAGE) @merge_requests = @merge_requests.page(params[:page]).per(PER_PAGE)
...@@ -50,10 +35,6 @@ class DashboardController < Dashboard::ApplicationController ...@@ -50,10 +35,6 @@ class DashboardController < Dashboard::ApplicationController
protected protected
def load_projects
@projects = current_user.authorized_projects.sorted_by_activity.non_archived
end
def load_events def load_events
project_ids = project_ids =
if params[:filter] == "starred" if params[:filter] == "starred"
......
class Explore::ApplicationController < ApplicationController class Explore::ApplicationController < ApplicationController
skip_before_action :authenticate_user!, :reject_blocked
layout 'explore' layout 'explore'
end end
class Explore::GroupsController < Explore::ApplicationController class Explore::GroupsController < Explore::ApplicationController
skip_before_action :authenticate_user!,
:reject_blocked, :set_current_user_for_observers
def index def index
@groups = GroupsFinder.new.execute(current_user) @groups = GroupsFinder.new.execute(current_user)
@groups = @groups.search(params[:search]) if params[:search].present? @groups = @groups.search(params[:search]) if params[:search].present?
......
class Explore::ProjectsController < Explore::ApplicationController class Explore::ProjectsController < Explore::ApplicationController
skip_before_action :authenticate_user!,
:reject_blocked
def index def index
@projects = ProjectsFinder.new.execute(current_user) @projects = ProjectsFinder.new.execute(current_user)
@tags = @projects.tags_on(:tags) @tags = @projects.tags_on(:tags)
......
class Explore::SnippetsController < Explore::ApplicationController
def index
@snippets = SnippetsFinder.new.execute(current_user, filter: :all)
@snippets = @snippets.page(params[:page]).per(PER_PAGE)
end
end
...@@ -4,7 +4,7 @@ class GroupsController < Groups::ApplicationController ...@@ -4,7 +4,7 @@ class GroupsController < Groups::ApplicationController
before_action :group, except: [:new, :create] before_action :group, except: [:new, :create]
# Authorize # Authorize
before_action :authorize_read_group!, except: [:new, :create] before_action :authorize_read_group!, except: [:show, :new, :create]
before_action :authorize_admin_group!, only: [:edit, :update, :destroy, :projects] before_action :authorize_admin_group!, only: [:edit, :update, :destroy, :projects]
before_action :authorize_create_group!, only: [:new, :create] before_action :authorize_create_group!, only: [:new, :create]
...@@ -14,6 +14,10 @@ class GroupsController < Groups::ApplicationController ...@@ -14,6 +14,10 @@ class GroupsController < Groups::ApplicationController
layout :determine_layout layout :determine_layout
def index
redirect_to(current_user ? dashboard_groups_path : explore_groups_path)
end
def new def new
@group = Group.new @group = Group.new
end end
......
class HelpController < ApplicationController class HelpController < ApplicationController
skip_before_action :authenticate_user!, :reject_blocked
layout 'help' layout 'help'
def index def index
......
...@@ -24,7 +24,7 @@ class InvitesController < ApplicationController ...@@ -24,7 +24,7 @@ class InvitesController < ApplicationController
path = path =
if current_user if current_user
dashboard_path dashboard_projects_path
else else
new_user_session_path new_user_session_path
end end
...@@ -73,7 +73,7 @@ class InvitesController < ApplicationController ...@@ -73,7 +73,7 @@ class InvitesController < ApplicationController
path = group_path(group) path = group_path(group)
else else
label = "who knows what" label = "who knows what"
path = dashboard_path path = dashboard_projects_path
end end
[label, path] [label, path]
......
...@@ -14,7 +14,7 @@ class NamespacesController < ApplicationController ...@@ -14,7 +14,7 @@ class NamespacesController < ApplicationController
if user if user
redirect_to user_path(user) redirect_to user_path(user)
elsif group && can?(current_user, :read_group, group) elsif group
redirect_to group_path(group) redirect_to group_path(group)
elsif current_user.nil? elsif current_user.nil?
authenticate_user! authenticate_user!
......
...@@ -13,10 +13,14 @@ class Projects::ForksController < Projects::ApplicationController ...@@ -13,10 +13,14 @@ class Projects::ForksController < Projects::ApplicationController
@forked_project = ::Projects::ForkService.new(project, current_user, namespace: namespace).execute @forked_project = ::Projects::ForkService.new(project, current_user, namespace: namespace).execute
if @forked_project.saved? && @forked_project.forked? if @forked_project.saved? && @forked_project.forked?
redirect_to( if @forked_project.import_in_progress?
namespace_project_path(@forked_project.namespace, @forked_project), redirect_to namespace_project_import_path(@forked_project.namespace, @forked_project)
notice: 'Project was successfully forked.' else
) redirect_to(
namespace_project_path(@forked_project.namespace, @forked_project),
notice: 'Project was successfully forked.'
)
end
else else
render :error render :error
end end
......
...@@ -78,7 +78,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController ...@@ -78,7 +78,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
@project.project_members.find_by(user_id: current_user).destroy @project.project_members.find_by(user_id: current_user).destroy
respond_to do |format| respond_to do |format|
format.html { redirect_to dashboard_path } format.html { redirect_to dashboard_projects_path }
format.js { render nothing: true } format.js { render nothing: true }
end end
end end
......
...@@ -10,6 +10,10 @@ class ProjectsController < ApplicationController ...@@ -10,6 +10,10 @@ class ProjectsController < ApplicationController
layout :determine_layout layout :determine_layout
def index
redirect_to(current_user ? root_path : explore_root_path)
end
def new def new
@project = Project.new @project = Project.new
end end
...@@ -108,7 +112,7 @@ class ProjectsController < ApplicationController ...@@ -108,7 +112,7 @@ class ProjectsController < ApplicationController
if request.referer.include?('/admin') if request.referer.include?('/admin')
redirect_to admin_namespaces_projects_path redirect_to admin_namespaces_projects_path
else else
redirect_to dashboard_path redirect_to dashboard_projects_path
end end
rescue Projects::DestroyService::DestroyError => ex rescue Projects::DestroyService::DestroyError => ex
redirect_to edit_project_path(@project), alert: ex.message redirect_to edit_project_path(@project), alert: ex.message
......
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
# #
# For users who haven't customized the setting, we simply delegate to # For users who haven't customized the setting, we simply delegate to
# `DashboardController#show`, which is the default. # `DashboardController#show`, which is the default.
class RootController < DashboardController class RootController < Dashboard::ProjectsController
before_action :redirect_to_custom_dashboard, only: [:show] before_action :redirect_to_custom_dashboard, only: [:index]
def show def index
super super
end end
...@@ -20,6 +20,7 @@ class RootController < DashboardController ...@@ -20,6 +20,7 @@ class RootController < DashboardController
case current_user.dashboard case current_user.dashboard
when 'stars' when 'stars'
flash.keep
redirect_to starred_dashboard_projects_path redirect_to starred_dashboard_projects_path
else else
return return
......
...@@ -24,13 +24,9 @@ class SnippetsController < ApplicationController ...@@ -24,13 +24,9 @@ class SnippetsController < ApplicationController
scope: params[:scope] }). scope: params[:scope] }).
page(params[:page]).per(PER_PAGE) page(params[:page]).per(PER_PAGE)
if @user == current_user render 'index'
render 'current_user_index'
else
render 'user_index'
end
else else
@snippets = SnippetsFinder.new.execute(current_user, filter: :all).page(params[:page]).per(PER_PAGE) redirect_to(current_user ? dashboard_snippets_path : explore_snippets_path)
end end
end end
......
...@@ -201,7 +201,7 @@ module ApplicationHelper ...@@ -201,7 +201,7 @@ module ApplicationHelper
class: "#{html_class} js-timeago", class: "#{html_class} js-timeago",
datetime: time.getutc.iso8601, datetime: time.getutc.iso8601,
title: time.in_time_zone.stamp('Aug 21, 2011 9:23pm'), title: time.in_time_zone.stamp('Aug 21, 2011 9:23pm'),
data: { toggle: 'tooltip', placement: placement } data: { toggle: 'tooltip', placement: placement, container: 'body' }
element += javascript_tag "$('.js-timeago').timeago()" unless skip_js element += javascript_tag "$('.js-timeago').timeago()" unless skip_js
......
...@@ -17,6 +17,14 @@ module GitlabRoutingHelper ...@@ -17,6 +17,14 @@ module GitlabRoutingHelper
namespace_project_path(project.namespace, project, *args) namespace_project_path(project.namespace, project, *args)
end end
def project_files_path(project, *args)
namespace_project_tree_path(project.namespace, project, @ref || project.repository.root_ref)
end
def project_commits_path(project, *args)
namespace_project_commits_path(project.namespace, project, @ref || project.repository.root_ref)
end
def activity_project_path(project, *args) def activity_project_path(project, *args)
activity_namespace_project_path(project.namespace, project, *args) activity_namespace_project_path(project.namespace, project, *args)
end end
......
...@@ -31,4 +31,26 @@ module PageLayoutHelper ...@@ -31,4 +31,26 @@ module PageLayoutHelper
@fluid_layout @fluid_layout
end end
end end
def blank_container(enabled = false)
if @blank_container.nil?
@blank_container = enabled
else
@blank_container
end
end
def container_class
css_class = "container-fluid"
unless fluid_layout
css_class += " container-limited"
end
if blank_container
css_class += " container-blank"
end
css_class
end
end end
...@@ -43,24 +43,22 @@ module ProjectsHelper ...@@ -43,24 +43,22 @@ module ProjectsHelper
end end
end end
def project_title(project) def project_title(project, name = nil, url = nil)
if project.group namespace_link =
content_tag :span do if project.group
link_to( link_to(simple_sanitize(project.group.name), group_path(project.group))
simple_sanitize(project.group.name), group_path(project.group) else
) + ' / ' + owner = project.namespace.owner
link_to(simple_sanitize(project.name), link_to(simple_sanitize(owner.name), user_path(owner))
project_path(project))
end
else
owner = project.namespace.owner
content_tag :span do
link_to(
simple_sanitize(owner.name), user_path(owner)
) + ' / ' +
link_to(simple_sanitize(project.name),
project_path(project))
end end
project_link = link_to(simple_sanitize(project.name), project_path(project))
full_title = namespace_link + ' / ' + project_link
full_title += ' &middot; '.html_safe + link_to(simple_sanitize(name), url) if name
content_tag :span do
full_title
end end
end end
...@@ -315,6 +313,45 @@ module ProjectsHelper ...@@ -315,6 +313,45 @@ module ProjectsHelper
end end
end end
def current_ref
@ref || @repository.try(:root_ref)
end
def detect_project_title(project)
name, url =
if current_controller? 'wikis'
['Wiki', get_project_wiki_path(project)]
elsif current_controller? 'project_members'
['Members', namespace_project_project_members_path(project.namespace, project)]
elsif current_controller? 'labels'
['Labels', namespace_project_labels_path(project.namespace, project)]
elsif current_controller? 'members'
['Members', project_files_path(project)]
elsif current_controller? 'commits'
['Commits', project_commits_path(project)]
elsif current_controller? 'graphs'
['Graphs', namespace_project_graph_path(project.namespace, project, current_ref)]
elsif current_controller? 'network'
['Network', namespace_project_network_path(project.namespace, project, current_ref)]
elsif current_controller? 'milestones'
['Milestones', namespace_project_milestones_path(project.namespace, project)]
elsif current_controller? 'snippets'
['Snippets', namespace_project_snippets_path(project.namespace, project)]
elsif current_controller? 'issues'
['Issues', namespace_project_issues_path(project.namespace, project)]
elsif current_controller? 'merge_requests'
['Merge Requests', namespace_project_merge_requests_path(project.namespace, project)]
elsif current_controller? 'tree', 'blob'
['Files', project_files_path(project)]
elsif current_path? 'projects#activity'
['Activity', activity_project_path(project)]
else
[nil, nil]
end
project_title(project, name, url)
end
private private
def filename_path(project, filename) def filename_path(project, filename)
......
...@@ -144,7 +144,7 @@ class Project < ActiveRecord::Base ...@@ -144,7 +144,7 @@ class Project < ActiveRecord::Base
validates_uniqueness_of :path, scope: :namespace_id validates_uniqueness_of :path, scope: :namespace_id
validates :import_url, validates :import_url,
format: { with: /\A#{URI.regexp(%w(ssh git http https))}\z/, message: 'should be a valid url' }, format: { with: /\A#{URI.regexp(%w(ssh git http https))}\z/, message: 'should be a valid url' },
if: :import? if: :external_import?
validates :star_count, numericality: { greater_than_or_equal_to: 0 } validates :star_count, numericality: { greater_than_or_equal_to: 0 }
validate :check_limit, on: :create validate :check_limit, on: :create
validate :avatar_type, validate :avatar_type,
...@@ -275,7 +275,13 @@ class Project < ActiveRecord::Base ...@@ -275,7 +275,13 @@ class Project < ActiveRecord::Base
end end
def add_import_job def add_import_job
RepositoryImportWorker.perform_in(2.seconds, id) if forked?
unless RepositoryForkWorker.perform_async(id, forked_from_project.path_with_namespace, self.namespace.path)
import_fail
end
else
RepositoryImportWorker.perform_in(2.seconds, id)
end
end end
def clear_import_data def clear_import_data
...@@ -283,6 +289,10 @@ class Project < ActiveRecord::Base ...@@ -283,6 +289,10 @@ class Project < ActiveRecord::Base
end end
def import? def import?
external_import? || forked?
end
def external_import?
import_url.present? import_url.present?
end end
...@@ -702,14 +712,8 @@ class Project < ActiveRecord::Base ...@@ -702,14 +712,8 @@ class Project < ActiveRecord::Base
end end
def create_repository def create_repository
if forked? # Forked import is handled asynchronously
if gitlab_shell.fork_repository(forked_from_project.path_with_namespace, self.namespace.path) unless forked?
true
else
errors.add(:base, 'Failed to fork repository via gitlab-shell')
false
end
else
if gitlab_shell.add_repository(path_with_namespace) if gitlab_shell.add_repository(path_with_namespace)
true true
else else
......
...@@ -22,7 +22,7 @@ module Files ...@@ -22,7 +22,7 @@ module Files
blob = repository.blob_at_branch(@current_branch, @file_path) blob = repository.blob_at_branch(@current_branch, @file_path)
if blob if blob
raise_error("Your changes could not be committed, because file with such name exists") raise_error("Your changes could not be committed because a file with the same name already exists")
end end
end end
end end
......
...@@ -55,9 +55,7 @@ module Projects ...@@ -55,9 +55,7 @@ module Projects
@project.save @project.save
if @project.persisted? && !@project.import? if @project.persisted? && !@project.import?
unless @project.create_repository raise 'Failed to create repository' unless @project.create_repository
raise 'Failed to create repository'
end
end end
end end
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
- if current_user - if current_user
%ul.nav.nav-pills.event_filter.pull-right %ul.nav.nav-pills.event_filter.pull-right
%li.pull-right %li.pull-right
= link_to dashboard_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do = link_to dashboard_projects_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do
%i.fa.fa-rss %i.fa.fa-rss
= render 'shared/event_filter' = render 'shared/event_filter'
......
%ul.center-top-menu %ul.center-top-menu
= nav_link(page: [dashboard_groups_path]) do = nav_link(page: dashboard_groups_path) do
= link_to dashboard_groups_path, title: 'Your groups', data: {placement: 'right'} do = link_to dashboard_groups_path, title: 'Your groups', data: {placement: 'right'} do
Your Groups Your Groups
= nav_link(page: [explore_groups_path]) do = nav_link(page: explore_groups_path) do
= link_to explore_groups_path, title: 'Explore groups', data: {placement: 'bottom'} do = link_to explore_groups_path, title: 'Explore groups', data: {placement: 'bottom'} do
Explore Groups Explore Groups
%ul.center-top-menu %ul.center-top-menu
= nav_link(path: ['dashboard#show', 'root#show']) do = nav_link(path: ['projects#index', 'root#index']) do
= link_to dashboard_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do = link_to dashboard_projects_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do
Your Projects Your Projects
= nav_link(page: starred_dashboard_projects_path) do = nav_link(page: starred_dashboard_projects_path) do
= link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do = link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do
......
%ul.center-top-menu
= nav_link(page: dashboard_snippets_path, html_options: {class: 'home'}) do
= link_to dashboard_snippets_path, title: 'Your snippets', data: {placement: 'right'} do
Your Snippets
= nav_link(page: explore_snippets_path) do
= link_to explore_snippets_path, title: 'Explore snippets', data: {placement: 'right'} do
Explore Snippets
= content_for :meta_tags do = content_for :meta_tags do
- if current_user - if current_user
= auto_discovery_link_tag(:atom, dashboard_url(format: :atom, private_token: current_user.private_token), title: "All activity") = auto_discovery_link_tag(:atom, dashboard_projects_url(format: :atom, private_token: current_user.private_token), title: "All activity")
- page_title "Activity"
- header_title "Activity", activity_dashboard_path - header_title "Activity", activity_dashboard_path
= render 'dashboard/activity_head' = render 'dashboard/activity_head'
%section.activities %section.activities
......
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "Activity" xml.title "Activity"
xml.link href: dashboard_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" xml.link href: dashboard_projects_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
xml.link href: dashboard_url, rel: "alternate", type: "text/html" xml.link href: dashboard_projects_url, rel: "alternate", type: "text/html"
xml.id dashboard_url xml.id dashboard_projects_url
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
@events.each do |event| @events.each do |event|
......
= content_for :meta_tags do = content_for :meta_tags do
- if current_user - if current_user
= auto_discovery_link_tag(:atom, dashboard_url(format: :atom, private_token: current_user.private_token), title: "All activity") = auto_discovery_link_tag(:atom, dashboard_projects_url(format: :atom, private_token: current_user.private_token), title: "All activity")
- page_title "Projects"
- header_title "Projects", root_path
- header_title "Projects", (current_user ? root_path : explore_root_path)
= render 'dashboard/projects_head' = render 'dashboard/projects_head'
- if @last_push - if @last_push
......
- page_title "Starred Projects" - page_title "Starred Projects"
- header_title "Projects", (current_user ? root_path : explore_root_path) - header_title "Projects", projects_path
= render 'dashboard/projects_head' = render 'dashboard/projects_head'
- if @projects.any? - if @projects.any?
= render 'dashboard/projects' = render 'projects'
- else - else
%h3 You don't have starred projects yet %h3 You don't have starred projects yet
%p.slead Visit project page and press on star icon and it will appear on this page. %p.slead Visit project page and press on star icon and it will appear on this page.
- page_title "Your Snippets" - page_title "Snippets"
= render 'head' - header_title "Snippets", dashboard_snippets_path
= render 'dashboard/snippets_head'
.gray-content-block .gray-content-block
.pull-right .pull-right
...@@ -11,26 +13,26 @@ ...@@ -11,26 +13,26 @@
%ul.nav.nav-tabs.prepend-top-20 %ul.nav.nav-tabs.prepend-top-20
= nav_tab :scope, nil do = nav_tab :scope, nil do
= link_to user_snippets_path(@user) do = link_to dashboard_snippets_path do
All All
%span.badge %span.badge
= @user.snippets.count = current_user.snippets.count
= nav_tab :scope, 'are_private' do = nav_tab :scope, 'are_private' do
= link_to user_snippets_path(@user, scope: 'are_private') do = link_to dashboard_snippets_path(scope: 'are_private') do
Private Private
%span.badge %span.badge
= @user.snippets.are_private.count = current_user.snippets.are_private.count
= nav_tab :scope, 'are_internal' do = nav_tab :scope, 'are_internal' do
= link_to user_snippets_path(@user, scope: 'are_internal') do = link_to dashboard_snippets_path(scope: 'are_internal') do
Internal Internal
%span.badge %span.badge
= @user.snippets.are_internal.count = current_user.snippets.are_internal.count
= nav_tab :scope, 'are_public' do = nav_tab :scope, 'are_public' do
= link_to user_snippets_path(@user, scope: 'are_public') do = link_to dashboard_snippets_path(scope: 'are_public') do
Public Public
%span.badge %span.badge
= @user.snippets.are_public.count = current_user.snippets.are_public.count
.my-snippets .my-snippets
= render 'snippets' = render 'snippets/snippets'
.explore-title
%h3
Explore GitLab
%p.lead
Discover projects, groups and snippets. Share your projects with others
%br
- page_title "Groups" - page_title "Groups"
- header_title "Groups", (current_user ? dashboard_groups_path : explore_groups_path) - header_title "Groups", dashboard_groups_path
- if current_user - if current_user
= render 'dashboard/groups_head' = render 'dashboard/groups_head'
- else
= render 'explore/head'
.gray-content-block.clearfix .gray-content-block.clearfix
.pull-left .pull-left
= form_tag explore_groups_path, method: :get, class: 'form-inline form-tiny' do |f| = form_tag explore_groups_path, method: :get, class: 'form-inline form-tiny' do |f|
......
- page_title "Projects" - page_title "Projects"
- header_title "Projects", root_path
- if current_user - if current_user
= render 'dashboard/projects_head' = render 'dashboard/projects_head'
- else
= render 'explore/head'
.gray-content-block.clearfix .gray-content-block.clearfix
= render 'filter' = render 'filter'
= render 'projects', projects: @projects = render 'projects', projects: @projects
......
- page_title "Starred Projects" - page_title "Projects"
- header_title "Projects", root_path
- if current_user - if current_user
= render 'dashboard/projects_head' = render 'dashboard/projects_head'
- else
= render 'explore/head'
.explore-trending-block .explore-trending-block
.gray-content-block .gray-content-block
......
- page_title "Trending Projects" - page_title "Projects"
- header_title "Projects", root_path
- if current_user - if current_user
= render 'dashboard/projects_head' = render 'dashboard/projects_head'
- else - else
.explore-title = render 'explore/head'
%h3
Explore GitLab
%p.lead
Discover projects and groups. Share your projects with others
%br
.explore-trending-block .explore-trending-block
.gray-content-block .gray-content-block
.pull-right .pull-right
......
- page_title "Snippets"
- header_title "Snippets", snippets_path
- if current_user
= render 'dashboard/snippets_head'
- else
= render 'explore/head'
.gray-content-block
- if current_user
.pull-right
= link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do
Add new snippet
.oneline
Public snippets created by you and other users are listed here
= render 'snippets/snippets'
- header_title group_title(@group, "Settings", edit_group_path(@group))
- @blank_container = true
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
%strong= @group.name %strong= @group.name
......
- page_title "Projects" - page_title "Projects"
- header_title group_title(@group, "Projects", projects_group_path(@group))
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
%strong= @group.name %strong= @group.name
......
- unless can?(current_user, :read_group, @group)
- @disable_search_panel = true
= content_for :meta_tags do = content_for :meta_tags do
- if current_user - if current_user
= auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
...@@ -16,22 +19,25 @@ ...@@ -16,22 +19,25 @@
= render 'shared/show_aside' = render 'shared/show_aside'
.row - if can?(current_user, :read_group, @group)
%section.activities.col-md-7 .row
.hidden-xs %section.activities.col-md-7
- if current_user .hidden-xs
= render "events/event_last_push", event: @last_push
- if current_user - if current_user
= render "events/event_last_push", event: @last_push
%ul.nav.nav-pills.event_filter.pull-right %ul.nav.nav-pills.event_filter.pull-right
%li %li
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'rss-btn' do = link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'rss-btn' do
%i.fa.fa-rss %i.fa.fa-rss
= render 'shared/event_filter' = render 'shared/event_filter'
%hr %hr
.content_list .content_list
= spinner = spinner
%aside.side.col-md-5 %aside.side.col-md-5
= render "projects", projects: @projects = render "projects", projects: @projects
- else
%p
This group does not have public projects
- page_title @file.humanize, *@category.split("/").reverse.map(&:humanize) - page_title @file.humanize, *@category.split("/").reverse.map(&:humanize)
.documentation.wiki .documentation.wiki
= markdown @markdown.gsub('$your_email', current_user.email) = markdown @markdown.gsub('$your_email', current_user.try(:email) || "email@example.com")
...@@ -6,10 +6,14 @@ ...@@ -6,10 +6,14 @@
= brand_header_logo = brand_header_logo
.gitlab-text-container .gitlab-text-container
%h3 GitLab %h3 GitLab
- if defined?(sidebar) && sidebar - if defined?(sidebar) && sidebar
= render "layouts/nav/#{sidebar}" = render "layouts/nav/#{sidebar}"
- elsif current_user - elsif current_user
= render 'layouts/nav/dashboard' = render 'layouts/nav/dashboard'
- else
= render 'layouts/nav/explore'
.collapse-nav .collapse-nav
= render partial: 'layouts/collapse_button' = render partial: 'layouts/collapse_button'
- if current_user - if current_user
...@@ -19,7 +23,7 @@ ...@@ -19,7 +23,7 @@
= current_user.username = current_user.username
.content-wrapper .content-wrapper
= render "layouts/flash" = render "layouts/flash"
%div{ class: fluid_layout ? "container-fluid" : "container-fluid container-limited" } %div{ class: container_class }
.content .content
.clearfix .clearfix
= yield = yield
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
.container .container
.footer-links .footer-links
= link_to "Explore", explore_root_path = link_to "Explore", explore_root_path
= link_to "Documentation", "http://doc.gitlab.com/" = link_to "Help", help_path
= link_to "About GitLab", "https://about.gitlab.com/" = link_to "About GitLab", "https://about.gitlab.com/"
- page_title "Explore" - page_title "Explore"
- if current_user - unless current_user
- unless @header_title
- header_title "Projects", (current_user ? root_path : explore_root_path)
- else
- header_title "Explore GitLab", explore_root_path - header_title "Explore GitLab", explore_root_path
- sidebar "dashboard"
= render template: "layouts/application" = render template: "layouts/application"
...@@ -7,8 +7,9 @@ ...@@ -7,8 +7,9 @@
.navbar-collapse.collapse .navbar-collapse.collapse
%ul.nav.navbar-nav.pull-right %ul.nav.navbar-nav.pull-right
%li.hidden-sm.hidden-xs - unless @disable_search_panel
= render 'layouts/search' %li.hidden-sm.hidden-xs
= render 'layouts/search'
%li.visible-sm.visible-xs %li.visible-sm.visible-xs
= link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom'} do = link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom'} do
= icon('search') = icon('search')
......
%ul.nav.nav-sidebar %ul.nav.nav-sidebar
= nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
= link_to (current_user ? root_path : explore_root_path), title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do = link_to root_path, title: 'Projects', data: {placement: 'right'} do
= icon('home fw') = icon('home fw')
%span %span
Projects Projects
= nav_link(path: 'dashboard#activity') do = nav_link(path: 'dashboard#activity') do
= link_to activity_dashboard_path, title: 'Activity', data: {placement: 'right'} do = link_to activity_dashboard_path, class: 'shortcuts-activity', title: 'Activity', data: {placement: 'right'} do
= icon('dashboard fw') = icon('dashboard fw')
%span %span
Activity Activity
= nav_link(controller: :groups) do = nav_link(controller: :groups) do
= link_to (current_user ? dashboard_groups_path : explore_groups_path), title: 'Groups', data: {placement: 'right'} do = link_to dashboard_groups_path, title: 'Groups', data: {placement: 'right'} do
= icon('group fw') = icon('group fw')
%span %span
Groups Groups
- if current_user = nav_link(controller: :milestones) do
= nav_link(controller: :milestones) do = link_to dashboard_milestones_path, title: 'Milestones', data: {placement: 'right'} do
= link_to dashboard_milestones_path, title: 'Milestones', data: {placement: 'right'} do = icon('clock-o fw')
= icon('clock-o fw') %span
%span Milestones
Milestones = nav_link(path: 'dashboard#issues') do
= nav_link(path: 'dashboard#issues') do = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues', data: {placement: 'right'} do
= link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues', data: {placement: 'right'} do = icon('exclamation-circle fw')
= icon('exclamation-circle fw') %span
%span Issues
Issues %span.count= current_user.assigned_issues.opened.count
%span.count= current_user.assigned_issues.opened.count
= nav_link(path: 'dashboard#merge_requests') do = nav_link(path: 'dashboard#merge_requests') do
= link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'shortcuts-merge_requests', data: {placement: 'right'} do = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'shortcuts-merge_requests', data: {placement: 'right'} do
= icon('tasks fw') = icon('tasks fw')
...@@ -33,18 +32,17 @@ ...@@ -33,18 +32,17 @@
Merge Requests Merge Requests
%span.count= current_user.assigned_merge_requests.opened.count %span.count= current_user.assigned_merge_requests.opened.count
= nav_link(controller: :snippets) do = nav_link(controller: :snippets) do
= link_to (current_user ? user_snippets_path(current_user) : snippets_path), title: 'Your snippets', data: {placement: 'right'} do = link_to dashboard_snippets_path, title: 'Your snippets', data: {placement: 'right'} do
= icon('clipboard fw') = icon('clipboard fw')
%span %span
Snippets Snippets
- if current_user
= nav_link(controller: :profile) do
= link_to profile_path, title: 'Profile settings', data: {toggle: 'tooltip', placement: 'bottom'} do
= icon('user fw')
%span
Profile Settings
= nav_link(controller: :help) do = nav_link(controller: :help) do
= link_to help_path, title: 'Help', data: {placement: 'right'} do = link_to help_path, title: 'Help', data: {placement: 'right'} do
= icon('question-circle fw') = icon('question-circle fw')
%span %span
Help Help
= nav_link(controller: :profile) do
= link_to profile_path, title: 'Profile settings', data: {placement: 'bottom'} do
= icon('user fw')
%span
Profile Settings
%ul.nav.nav-sidebar
= 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', data: {placement: 'right'} do
= icon('home fw')
%span
Projects
= nav_link(controller: :groups) do
= link_to explore_groups_path, title: 'Groups', data: {placement: 'right'} do
= icon('group fw')
%span
Groups
= nav_link(controller: :snippets) do
= link_to explore_snippets_path, title: 'Snippets', data: {placement: 'right'} do
= icon('clipboard fw')
%span
Snippets
= nav_link(controller: :help) do
= link_to help_path, title: 'Help', data: {placement: 'right'} do
= icon('question-circle fw')
%span
Help
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
= link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw') = icon('caret-square-o-left fw')
%span %span
Back to Dashboard Back to dashboard
%li.separate-item %li.separate-item
...@@ -12,34 +12,35 @@ ...@@ -12,34 +12,35 @@
= icon('dashboard fw') = icon('dashboard fw')
%span %span
Group Group
- if current_user - if can?(current_user, :read_group, @group)
= nav_link(controller: [:group, :milestones]) do - if current_user
= link_to group_milestones_path(@group), title: 'Milestones', data: {placement: 'right'} do = nav_link(controller: [:group, :milestones]) do
= icon('clock-o fw') = link_to group_milestones_path(@group), title: 'Milestones', data: {placement: 'right'} do
= icon('clock-o fw')
%span
Milestones
= nav_link(path: 'groups#issues') do
= link_to issues_group_path(@group), title: 'Issues', data: {placement: 'right'} do
= icon('exclamation-circle fw')
%span %span
Milestones Issues
= nav_link(path: 'groups#issues') do - if current_user
= link_to issues_group_path(@group), title: 'Issues', data: {placement: 'right'} do %span.count= Issue.opened.of_group(@group).count
= icon('exclamation-circle fw') = nav_link(path: 'groups#merge_requests') do
%span = link_to merge_requests_group_path(@group), title: 'Merge Requests', data: {placement: 'right'} do
Issues = icon('tasks fw')
- if current_user %span
%span.count= Issue.opened.of_group(@group).count Merge Requests
= nav_link(path: 'groups#merge_requests') do - if current_user
= link_to merge_requests_group_path(@group), title: 'Merge Requests', data: {placement: 'right'} do %span.count= MergeRequest.opened.of_group(@group).count
= icon('tasks fw') = nav_link(controller: [:group_members]) do
%span = link_to group_group_members_path(@group), title: 'Members', data: {placement: 'right'} do
Merge Requests = icon('users fw')
- if current_user
%span.count= MergeRequest.opened.of_group(@group).count
= nav_link(controller: [:group_members]) do
= link_to group_group_members_path(@group), title: 'Members', data: {placement: 'right'} do
= icon('users fw')
%span
Members
- if can?(current_user, :admin_group, @group)
= nav_link(html_options: { class: "separate-item" }) do
= link_to edit_group_path(@group), title: 'Settings', data: {placement: 'right'} do
= icon ('cogs fw')
%span %span
Settings Members
- if can?(current_user, :admin_group, @group)
= nav_link(html_options: { class: "separate-item" }) do
= link_to edit_group_path(@group), title: 'Settings', data: {placement: 'right'} do
= icon ('cogs fw')
%span
Settings
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
= link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw') = icon('caret-square-o-left fw')
%span %span
Back to Dashboard Back to dashboard
%li.separate-item %li.separate-item
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
= link_to profile_path, title: 'Profile', data: {placement: 'right'} do = link_to profile_path, title: 'Profile', data: {placement: 'right'} do
= icon('user fw') = icon('user fw')
%span %span
Profile Profile Settings
= nav_link(controller: [:accounts, :two_factor_auths]) do = nav_link(controller: [:accounts, :two_factor_auths]) do
= link_to profile_account_path, title: 'Account', data: {placement: 'right'} do = link_to profile_account_path, title: 'Account', data: {placement: 'right'} do
= icon('gear fw') = icon('gear fw')
......
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
= link_to group_path(@project.group), title: 'Back to group', data: {placement: 'right'}, class: 'back-link' do = link_to group_path(@project.group), title: 'Back to group', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw') = icon('caret-square-o-left fw')
%span %span
Back to Group Back to group
- else - else
= nav_link do = nav_link do
= link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw') = icon('caret-square-o-left fw')
%span %span
Back to Dashboard Back to dashboard
%li.separate-item %li.separate-item
...@@ -26,28 +26,28 @@ ...@@ -26,28 +26,28 @@
Activity Activity
- if project_nav_tab? :files - if project_nav_tab? :files
= nav_link(controller: %w(tree blob blame edit_tree new_tree)) do = nav_link(controller: %w(tree blob blame edit_tree new_tree)) do
= link_to namespace_project_tree_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Files', class: 'shortcuts-tree', data: {placement: 'right'} do = link_to project_files_path(@project), title: 'Files', class: 'shortcuts-tree', data: {placement: 'right'} do
= icon('files-o fw') = icon('files-o fw')
%span %span
Files Files
- if project_nav_tab? :commits - if project_nav_tab? :commits
= nav_link(controller: %w(commit commits compare repositories tags branches)) do = nav_link(controller: %w(commit commits compare repositories tags branches)) do
= link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Commits', class: 'shortcuts-commits', data: {placement: 'right'} do = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits', data: {placement: 'right'} do
= icon('history fw') = icon('history fw')
%span %span
Commits Commits
- if project_nav_tab? :network - if project_nav_tab? :network
= nav_link(controller: %w(network)) do = nav_link(controller: %w(network)) do
= link_to namespace_project_network_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Network', class: 'shortcuts-network', data: {placement: 'right'} do = link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network', data: {placement: 'right'} do
= icon('code-fork fw') = icon('code-fork fw')
%span %span
Network Network
- if project_nav_tab? :graphs - if project_nav_tab? :graphs
= nav_link(controller: %w(graphs)) do = nav_link(controller: %w(graphs)) do
= link_to namespace_project_graph_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Graphs', class: 'shortcuts-graphs', data: {placement: 'right'} do = link_to namespace_project_graph_path(@project.namespace, @project, current_ref), title: 'Graphs', class: 'shortcuts-graphs', data: {placement: 'right'} do
= icon('area-chart fw') = icon('area-chart fw')
%span %span
Graphs Graphs
......
- page_title "Profile Settings" - page_title "Profile Settings"
- header_title "Profile Settings", profile_path - unless @header_title
- header_title "Profile Settings", profile_path
- sidebar "profile" - sidebar "profile"
= render template: "layouts/application" = render template: "layouts/application"
- page_title @project.name_with_namespace - page_title @project.name_with_namespace
- header_title project_title(@project) - header_title detect_project_title(@project)
- sidebar "project" unless sidebar - sidebar "project" unless sidebar
- content_for :scripts_body_top do - content_for :scripts_body_top do
......
- page_title 'Snippets' - header_title "Snippets", snippets_path
- if current_user
- header_title "Snippets", user_snippets_path(current_user)
- else
- header_title 'Snippets', snippets_path
- sidebar "dashboard"
= render template: "layouts/application" = render template: "layouts/application"
- page_title "Account" - page_title "Account"
%h3.page-title - header_title page_title, profile_account_path
= page_title - @blank_container = true
%p.light
Change your username and basic account settings.
%hr
- if current_user.ldap_user? - if current_user.ldap_user?
.alert.alert-info .alert.alert-info
Some options are unavailable for LDAP accounts Some options are unavailable for LDAP accounts
...@@ -69,7 +67,7 @@ ...@@ -69,7 +67,7 @@
- button_based_providers.each do |provider| - button_based_providers.each do |provider|
.btn-group .btn-group
= link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: "btn btn-lg #{'active' if auth_active?(provider)}", "data-no-turbolink" => "true" = link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: "btn btn-lg #{'active' if auth_active?(provider)}", "data-no-turbolink" => "true"
- if auth_active?(provider) - if auth_active?(provider)
= link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do = link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do
= icon('close') = icon('close')
......
- page_title "Applications" - page_title "Applications"
%h3.page-title - header_title page_title, applications_profile_path
= page_title
%p.light .gray-content-block.top-block
- if user_oauth_applications? - if user_oauth_applications?
Manage applications that can use GitLab as an OAuth provider, Manage applications that can use GitLab as an OAuth provider,
and applications that you've authorized to use your account. and applications that you've authorized to use your account.
- else - else
Manage applications that you've authorized to use your account. Manage applications that you've authorized to use your account.
%hr
- if user_oauth_applications? - if user_oauth_applications?
.oauth-applications .oauth-applications
......
- page_title "Audit Log" - page_title "Audit Log"
%h3.page-title Audit Log - header_title page_title, audit_log_profile_path
%p.light History of authentications
= render 'event_table', events: @events .gray-content-block.top-block
\ No newline at end of file History of authentications
.prepend-top-default
= render 'event_table', events: @events
- page_title "Emails" - page_title "Emails"
%h3.page-title - header_title page_title, profile_emails_path
= page_title
%p.light
Control emails linked to your account
%hr
.gray-content-block.top-block
Control emails linked to your account
%ul %ul.prepend-top-default
%li %li
Your Your
%b Primary Email %b Primary Email
......
- page_title "SSH Keys" - page_title "SSH Keys"
%h3.page-title - header_title page_title, profile_keys_path
= page_title
.gray-content-block.top-block
.pull-right .pull-right
= link_to "Add SSH Key", new_profile_key_path, class: "btn btn-new" = link_to "Add SSH Key", new_profile_key_path, class: "btn btn-new"
%p.light .oneline
Before you can add an SSH key you need to Before you can add an SSH key you need to
= link_to "generate it.", help_page_path("ssh", "README") = link_to "generate it.", help_page_path("ssh", "README")
%hr
.prepend-top-default
= render 'key_table' = render 'key_table'
- page_title "Notifications" - page_title "Notifications"
%h3.page-title - header_title page_title, profile_notifications_path
= page_title
%p.light .gray-content-block.top-block
These are your global notification settings. These are your global notification settings.
%hr
.prepend-top-default
= form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications form-horizontal global-notifications-form' } do |f| = form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications form-horizontal global-notifications-form' } do |f|
-if @user.errors.any? -if @user.errors.any?
%div.alert.alert-danger %div.alert.alert-danger
......
- page_title "Password" - page_title "Password"
%h3.page-title - header_title page_title, edit_profile_password_path
= page_title
%p.light .gray-content-block.top-block
- if @user.password_automatically_set? - if @user.password_automatically_set?
Set your password. Set your password.
- else - else
Change your password or recover your current one. Change your password or recover your current one.
%hr
.update-password .update-password.prepend-top-default
= form_for @user, url: profile_password_path, method: :put, html: { class: 'form-horizontal' } do |f| = form_for @user, url: profile_password_path, method: :put, html: { class: 'form-horizontal' } do |f|
%div %div
%p.slead %p.slead
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
%ul %ul
- @user.errors.full_messages.each do |msg| - @user.errors.full_messages.each do |msg|
%li= msg %li= msg
- unless @user.password_automatically_set? - unless @user.password_automatically_set?
.form-group .form-group
= f.label :current_password, class: 'control-label' = f.label :current_password, class: 'control-label'
......
- page_title 'Preferences' - page_title 'Preferences'
%h3.page-title - header_title page_title, profile_preferences_path
= page_title - @blank_container = true
%p.light
.alert.alert-help
These settings allow you to customize the appearance and behavior of the site. These settings allow you to customize the appearance and behavior of the site.
They are saved with your account and will persist to any device you use to They are saved with your account and will persist to any device you use to
access the site. access the site.
%hr
= form_for @user, url: profile_preferences_path, remote: true, method: :put, html: {class: 'js-preferences-form form-horizontal'} do |f| = form_for @user, url: profile_preferences_path, remote: true, method: :put, html: {class: 'js-preferences-form form-horizontal'} do |f|
.panel.panel-default.application-theme .panel.panel-default.application-theme
......
- page_title "Profile" .gray-content-block.top-block
%h3.page-title
= page_title
%p.light
This information will appear on your profile. This information will appear on your profile.
- if current_user.ldap_user? - if current_user.ldap_user?
Some options are unavailable for LDAP accounts Some options are unavailable for LDAP accounts
%hr
.prepend-top-default
= form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit_user form-horizontal" }, authenticity_token: true do |f| = form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit_user form-horizontal" }, authenticity_token: true do |f|
-if @user.errors.any? -if @user.errors.any?
%div.alert.alert-danger %div.alert.alert-danger
......
...@@ -7,6 +7,13 @@ ...@@ -7,6 +7,13 @@
- if @project.description.present? - if @project.description.present?
= markdown(@project.description, pipeline: :description) = markdown(@project.description, pipeline: :description)
- if forked_from_project = @project.forked_from_project
%p
Forked from
= link_to project_path(forked_from_project) do
= forked_from_project.namespace.try(:name)
.project-repo-buttons .project-repo-buttons
= render 'projects/buttons/star' = render 'projects/buttons/star'
...@@ -14,12 +21,6 @@ ...@@ -14,12 +21,6 @@
- unless empty_repo - unless empty_repo
= render 'projects/buttons/fork' = render 'projects/buttons/fork'
- if forked_from_project = @project.forked_from_project
= link_to project_path(forked_from_project), class: 'btn' do
= icon("code-fork fw")
Forked from
= forked_from_project.namespace.try(:name)
- if can? current_user, :download_code, @project - if can? current_user, :download_code, @project
= link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: @ref, format: 'zip'), class: 'btn', rel: 'nofollow' do = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: @ref, format: 'zip'), class: 'btn', rel: 'nofollow' do
= icon('download fw') = icon('download fw')
......
- page_title "Activity"
= render 'projects/activity' = render 'projects/activity'
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
- else - else
= link_to title, '#' = link_to title, '#'
%ul.blob-commit-info.well.hidden-xs %ul.blob-commit-info.hidden-xs
- blob_commit = @repository.last_commit_for_path(@commit.id, blob.path) - blob_commit = @repository.last_commit_for_path(@commit.id, blob.path)
= render blob_commit, project: @project = render blob_commit, project: @project
......
%ul.center-top-menu %ul.center-top-menu
= nav_link(controller: [:commit, :commits]) do = nav_link(controller: [:commit, :commits]) do
= link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref) do = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do
Commits Commits
%span.badge= number_with_delimiter(@repository.commit_count) %span.badge= number_with_delimiter(@repository.commit_count)
= nav_link(controller: :compare) do = nav_link(controller: :compare) do
= link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: @ref || @repository.root_ref) do = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: current_ref) do
Compare Compare
= nav_link(html_options: {class: branches_tab_class}) do = nav_link(html_options: {class: branches_tab_class}) do
......
- @blank_container = true
.project-edit-container .project-edit-container
.project-edit-errors .project-edit-errors
.project-edit-content .project-edit-content
%div .panel.panel-default
%h3.page-title .panel-heading
Project settings Project settings
%hr
.panel-body .panel-body
= form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal fieldset-form" }, authenticity_token: true do |f| = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal fieldset-form" }, authenticity_token: true do |f|
......
...@@ -10,21 +10,22 @@ ...@@ -10,21 +10,22 @@
- group.each do |namespace| - group.each do |namespace|
.col-md-2.col-sm-3 .col-md-2.col-sm-3
- if fork = namespace.find_fork_of(@project) - if fork = namespace.find_fork_of(@project)
.thumbnail.fork-exists-thumbnail .fork-thumbnail
= link_to project_path(fork), title: "Visit project fork", class: 'has_tooltip' do = link_to project_path(fork), title: "Visit project fork", class: 'has_tooltip' do
= image_tag namespace_icon(namespace, 200) = image_tag namespace_icon(namespace, 100)
.caption .caption
%h4=namespace.human_name %strong
%p = namespace.human_name
= namespace.path %div.text-primary
Already forked
- else - else
.thumbnail.fork-thumbnail .fork-thumbnail
= link_to namespace_project_fork_path(@project.namespace, @project, namespace_key: namespace.id), title: "Fork here", method: "POST", class: 'has_tooltip' do = link_to namespace_project_fork_path(@project.namespace, @project, namespace_key: namespace.id), title: "Fork here", method: "POST", class: 'has_tooltip' do
= image_tag namespace_icon(namespace, 200) = image_tag namespace_icon(namespace, 100)
.caption .caption
%h4=namespace.human_name %strong
%p = namespace.human_name
= namespace.path
%p.light %p.light
Fork is a copy of a project repository. Fork is a copy of a project repository.
......
- page_title "Labels" - page_title "Labels"
- if can? current_user, :admin_label, @project
= link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do .gray-content-block.top-block
New label - if can? current_user, :admin_label, @project
%h3.page-title = link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do
Labels New label
%hr .oneline
Labels can be applied to issues and merge requests.
.labels .labels
- if @labels.present? - if @labels.present?
%ul.bordered-list.manage-labels-list %ul.content-list.manage-labels-list
= render @labels = render @labels
= paginate @labels, theme: 'gitlab' = paginate @labels, theme: 'gitlab'
- else - else
......
- page_title "Members" - page_title "Members"
%h3.page-title
Users with access to this project
%p.light .gray-content-block.top-block
.clearfix.js-toggle-container
= form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do
.form-group
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input' }
= button_tag 'Search', class: 'btn'
- if can?(current_user, :admin_project_member, @project)
%span.pull-right
= button_tag class: 'btn btn-new btn-grouped js-toggle-button', type: 'button' do
Add members
%i.fa.fa-chevron-down
= link_to import_namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-grouped", title: "Import members from another project" do
Import members
.js-toggle-content.hide.new-group-member-holder
= render "new_project_member"
%p.prepend-top-default.light
Users with access to this project are listed below.
Read more about project permissions Read more about project permissions
%strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
%hr
.clearfix.js-toggle-container
= form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do
.form-group
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input' }
= button_tag 'Search', class: 'btn'
- if can?(current_user, :admin_project_member, @project)
%span.pull-right
= button_tag class: 'btn btn-new btn-grouped js-toggle-button', type: 'button' do
Add members
%i.fa.fa-chevron-down
= link_to import_namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-grouped", title: "Import members from another project" do
Import members
.js-toggle-content.hide.new-group-member-holder
= render "new_project_member"
= render "team", members: @project_members = render "team", members: @project_members
- if @group - if @group
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
.project-stats.gray-content-block .project-stats.gray-content-block
%ul.nav.nav-pills %ul.nav.nav-pills
%li %li
= link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref) do = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do
= pluralize(number_with_delimiter(@project.commit_count), 'commit') = pluralize(number_with_delimiter(@project.commit_count), 'commit')
%li %li
= link_to namespace_project_branches_path(@project.namespace, @project) do = link_to namespace_project_branches_path(@project.namespace, @project) do
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
= f.label :title, class: 'control-label' do = f.label :title, class: 'control-label' do
%strong= 'Title *' %strong= 'Title *'
.col-sm-10 .col-sm-10
= f.text_field :title, maxlength: 255, autofocus: true, = f.text_field :title, maxlength: 255, autofocus: true, autocomplete: 'off',
class: 'form-control pad js-gfm-input', required: true class: 'form-control pad js-gfm-input', required: true
- if issuable.is_a?(MergeRequest) - if issuable.is_a?(MergeRequest)
......
%ul.center-top-menu
= nav_link(page: user_snippets_path(current_user), html_options: {class: 'home'}) do
= link_to user_snippets_path(current_user), title: 'Your snippets', data: {placement: 'right'} do
Your Snippets
= nav_link(page: snippets_path) do
= link_to snippets_path, title: 'Explore snippets', data: {placement: 'right'} do
Explore Snippets
- page_title "Public Snippets" - page_title "By #{@user.name}", "Snippets"
- if current_user
= render 'head' %ol.breadcrumb
%li
.gray-content-block = link_to snippets_path do
- if current_user Snippets
.pull-right %li
= link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do = @user.name
Add new snippet .pull-right.hidden-xs
= link_to user_path(@user) do
.oneline #{@user.name} profile page
Public snippets created by you and other users are listed here
= render 'snippets' = render 'snippets'
...@@ -20,10 +20,10 @@ ...@@ -20,10 +20,10 @@
.back-link .back-link
- if @snippet.author == current_user - if @snippet.author == current_user
= link_to user_snippets_path(current_user) do = link_to dashboard_snippets_path do
&larr; your snippets &larr; your snippets
- else - else
= link_to snippets_path do = link_to explore_snippets_path do
&larr; explore snippets &larr; explore snippets
.file-holder .file-holder
......
- page_title "Snippets", @user.name
%ol.breadcrumb
%li
= link_to snippets_path do
Snippets
%li
= @user.name
.pull-right.hidden-xs
= link_to user_path(@user) do
#{@user.name} profile page
= render 'snippets'
class RepositoryForkWorker
include Sidekiq::Worker
include Gitlab::ShellAdapter
sidekiq_options queue: :gitlab_shell
def perform(project_id, source_path, target_path)
project = Project.find_by_id(project_id)
unless project.present?
logger.error("Project #{project_id} no longer exists!")
return
end
result = gitlab_shell.fork_repository(source_path, target_path)
unless result
logger.error("Unable to fork project #{project_id} for repository #{source_path} -> #{target_path}")
project.import_fail
project.save
return
end
if project.valid_repo?
ProjectCacheWorker.perform_async(project.id)
project.import_finish
else
project.import_fail
logger.error("Project #{id} had an invalid repository after fork")
end
project.save
end
end
# Here until https://github.com/jneen/rouge/pull/297 is merged into Rouge and the gem is updated in GitLab.
module Rouge
module Lexers
class Diff
def self.analyze_text(text)
return 1 if text.start_with?('Index: ')
return 1 if text.start_with?('diff ')
return 0.9 if text.start_with?('--- ')
end
state :root do
rule(/^ .*\n/, Text)
rule(/^---\n/, Text)
rule(/^\+.*\n/, Generic::Inserted)
rule(/^-+.*\n/, Generic::Deleted)
rule(/^!.*\n/, Generic::Strong)
rule(/^@.*\n/, Generic::Subheading)
rule(/^([Ii]ndex|diff).*\n/, Generic::Heading)
rule(/^=.*\n/, Generic::Heading)
rule(/.*\n/, Text)
end
end
end
end
...@@ -143,6 +143,7 @@ Gitlab::Application.routes.draw do ...@@ -143,6 +143,7 @@ Gitlab::Application.routes.draw do
end end
resources :groups, only: [:index] resources :groups, only: [:index]
resources :snippets, only: [:index]
root to: 'projects#trending' root to: 'projects#trending'
end end
...@@ -263,24 +264,25 @@ Gitlab::Application.routes.draw do ...@@ -263,24 +264,25 @@ Gitlab::Application.routes.draw do
# #
# Dashboard Area # Dashboard Area
# #
resource :dashboard, controller: 'dashboard', only: [:show] do resource :dashboard, controller: 'dashboard', only: [] do
member do get :issues
get :issues get :merge_requests
get :merge_requests get :activity
get :activity
end
scope module: :dashboard do scope module: :dashboard do
resources :milestones, only: [:index, :show] resources :milestones, only: [:index, :show]
resources :groups, only: [:index] resources :groups, only: [:index]
resources :snippets, only: [:index]
resources :projects, only: [] do resources :projects, only: [:index] do
collection do collection do
get :starred get :starred
end end
end end
end end
root to: "dashboard/projects#index"
end end
# #
...@@ -304,7 +306,7 @@ Gitlab::Application.routes.draw do ...@@ -304,7 +306,7 @@ Gitlab::Application.routes.draw do
end end
end end
resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create] resources :projects, constraints: { id: /[^\/]+/ }, only: [:index, :new, :create]
devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords, sessions: :sessions, confirmations: :confirmations } devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords, sessions: :sessions, confirmations: :confirmations }
...@@ -312,7 +314,7 @@ Gitlab::Application.routes.draw do ...@@ -312,7 +314,7 @@ Gitlab::Application.routes.draw do
get '/users/auth/:provider/omniauth_error' => 'omniauth_callbacks#omniauth_error', as: :omniauth_error get '/users/auth/:provider/omniauth_error' => 'omniauth_callbacks#omniauth_error', as: :omniauth_error
end end
root to: "root#show" root to: "root#index"
# #
# Project Area # Project Area
......
...@@ -27,6 +27,14 @@ Delete Asana service for a project. ...@@ -27,6 +27,14 @@ Delete Asana service for a project.
DELETE /projects/:id/services/asana DELETE /projects/:id/services/asana
``` ```
### Get Asana service settings
Get Asana service settings for a project.
```
GET /projects/:id/services/asana
```
## Assembla ## Assembla
Project Management Software (Source Commits Endpoint) Project Management Software (Source Commits Endpoint)
...@@ -52,6 +60,14 @@ Delete Assembla service for a project. ...@@ -52,6 +60,14 @@ Delete Assembla service for a project.
DELETE /projects/:id/services/assembla DELETE /projects/:id/services/assembla
``` ```
### Get Assembla service settings
Get Assembla service settings for a project.
```
GET /projects/:id/services/assembla
```
## Atlassian Bamboo CI ## Atlassian Bamboo CI
A continuous integration and build server A continuous integration and build server
...@@ -81,6 +97,14 @@ Delete Atlassian Bamboo CI service for a project. ...@@ -81,6 +97,14 @@ Delete Atlassian Bamboo CI service for a project.
DELETE /projects/:id/services/bamboo DELETE /projects/:id/services/bamboo
``` ```
### Get Atlassian Bamboo CI service settings
Get Atlassian Bamboo CI service settings for a project.
```
GET /projects/:id/services/bamboo
```
## Buildkite ## Buildkite
Continuous integration and deployments Continuous integration and deployments
...@@ -107,6 +131,14 @@ Delete Buildkite service for a project. ...@@ -107,6 +131,14 @@ Delete Buildkite service for a project.
DELETE /projects/:id/services/buildkite DELETE /projects/:id/services/buildkite
``` ```
### Get Buildkite service settings
Get Buildkite service settings for a project.
```
GET /projects/:id/services/buildkite
```
## Campfire ## Campfire
Simple web-based real-time group chat Simple web-based real-time group chat
...@@ -133,6 +165,14 @@ Delete Campfire service for a project. ...@@ -133,6 +165,14 @@ Delete Campfire service for a project.
DELETE /projects/:id/services/campfire DELETE /projects/:id/services/campfire
``` ```
### Get Campfire service settings
Get Campfire service settings for a project.
```
GET /projects/:id/services/campfire
```
## Custom Issue Tracker ## Custom Issue Tracker
Custom issue tracker Custom issue tracker
...@@ -161,6 +201,14 @@ Delete Custom Issue Tracker service for a project. ...@@ -161,6 +201,14 @@ Delete Custom Issue Tracker service for a project.
DELETE /projects/:id/services/custom-issue-tracker DELETE /projects/:id/services/custom-issue-tracker
``` ```
### Get Custom Issue Tracker service settings
Get Custom Issue Tracker service settings for a project.
```
GET /projects/:id/services/custom-issue-tracker
```
## Drone CI ## Drone CI
Drone is a Continuous Integration platform built on Docker, written in Go Drone is a Continuous Integration platform built on Docker, written in Go
...@@ -187,6 +235,14 @@ Delete Drone CI service for a project. ...@@ -187,6 +235,14 @@ Delete Drone CI service for a project.
DELETE /projects/:id/services/drone-ci DELETE /projects/:id/services/drone-ci
``` ```
### Get Drone CI service settings
Get Drone CI service settings for a project.
```
GET /projects/:id/services/drone-ci
```
## Emails on push ## Emails on push
Email the commits and diff of each push to a list of recipients. Email the commits and diff of each push to a list of recipients.
...@@ -213,6 +269,14 @@ Delete Emails on push service for a project. ...@@ -213,6 +269,14 @@ Delete Emails on push service for a project.
DELETE /projects/:id/services/emails-on-push DELETE /projects/:id/services/emails-on-push
``` ```
### Get Emails on push service settings
Get Emails on push service settings for a project.
```
GET /projects/:id/services/emails-on-push
```
## External Wiki ## External Wiki
Replaces the link to the internal wiki with a link to an external wiki. Replaces the link to the internal wiki with a link to an external wiki.
...@@ -237,6 +301,14 @@ Delete External Wiki service for a project. ...@@ -237,6 +301,14 @@ Delete External Wiki service for a project.
DELETE /projects/:id/services/external-wiki DELETE /projects/:id/services/external-wiki
``` ```
### Get External Wiki service settings
Get External Wiki service settings for a project.
```
GET /projects/:id/services/external-wiki
```
## Flowdock ## Flowdock
Flowdock is a collaboration web app for technical teams. Flowdock is a collaboration web app for technical teams.
...@@ -261,6 +333,14 @@ Delete Flowdock service for a project. ...@@ -261,6 +333,14 @@ Delete Flowdock service for a project.
DELETE /projects/:id/services/flowdock DELETE /projects/:id/services/flowdock
``` ```
### Get Flowdock service settings
Get Flowdock service settings for a project.
```
GET /projects/:id/services/flowdock
```
## Gemnasium ## Gemnasium
Gemnasium monitors your project dependencies and alerts you about updates and security vulnerabilities. Gemnasium monitors your project dependencies and alerts you about updates and security vulnerabilities.
...@@ -286,6 +366,14 @@ Delete Gemnasium service for a project. ...@@ -286,6 +366,14 @@ Delete Gemnasium service for a project.
DELETE /projects/:id/services/gemnasium DELETE /projects/:id/services/gemnasium
``` ```
### Get Gemnasium service settings
Get Gemnasium service settings for a project.
```
GET /projects/:id/services/gemnasium
```
## GitLab CI ## GitLab CI
Continuous integration server from GitLab Continuous integration server from GitLab
...@@ -312,6 +400,14 @@ Delete GitLab CI service for a project. ...@@ -312,6 +400,14 @@ Delete GitLab CI service for a project.
DELETE /projects/:id/services/gitlab-ci DELETE /projects/:id/services/gitlab-ci
``` ```
### Get GitLab CI service settings
Get GitLab CI service settings for a project.
```
GET /projects/:id/services/gitlab-ci
```
## HipChat ## HipChat
Private group chat and IM Private group chat and IM
...@@ -341,6 +437,14 @@ Delete HipChat service for a project. ...@@ -341,6 +437,14 @@ Delete HipChat service for a project.
DELETE /projects/:id/services/hipchat DELETE /projects/:id/services/hipchat
``` ```
### Get HipChat service settings
Get HipChat service settings for a project.
```
GET /projects/:id/services/hipchat
```
## Irker (IRC gateway) ## Irker (IRC gateway)
Send IRC messages, on update, to a list of recipients through an Irker gateway. Send IRC messages, on update, to a list of recipients through an Irker gateway.
...@@ -371,6 +475,14 @@ Delete Irker (IRC gateway) service for a project. ...@@ -371,6 +475,14 @@ Delete Irker (IRC gateway) service for a project.
DELETE /projects/:id/services/irker DELETE /projects/:id/services/irker
``` ```
### Get Irker (IRC gateway) service settings
Get Irker (IRC gateway) service settings for a project.
```
GET /projects/:id/services/irker
```
## JIRA ## JIRA
Jira issue tracker Jira issue tracker
...@@ -400,6 +512,14 @@ Delete JIRA service for a project. ...@@ -400,6 +512,14 @@ Delete JIRA service for a project.
DELETE /projects/:id/services/jira DELETE /projects/:id/services/jira
``` ```
### Get JIRA service settings
Get JIRA service settings for a project.
```
GET /projects/:id/services/jira
```
## PivotalTracker ## PivotalTracker
Project Management Software (Source Commits Endpoint) Project Management Software (Source Commits Endpoint)
...@@ -424,6 +544,14 @@ Delete PivotalTracker service for a project. ...@@ -424,6 +544,14 @@ Delete PivotalTracker service for a project.
DELETE /projects/:id/services/pivotaltracker DELETE /projects/:id/services/pivotaltracker
``` ```
### Get PivotalTracker service settings
Get PivotalTracker service settings for a project.
```
GET /projects/:id/services/pivotaltracker
```
## Pushover ## Pushover
Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop. Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop.
...@@ -452,6 +580,14 @@ Delete Pushover service for a project. ...@@ -452,6 +580,14 @@ Delete Pushover service for a project.
DELETE /projects/:id/services/pushover DELETE /projects/:id/services/pushover
``` ```
### Get Pushover service settings
Get Pushover service settings for a project.
```
GET /projects/:id/services/pushover
```
## Redmine ## Redmine
Redmine issue tracker Redmine issue tracker
...@@ -479,6 +615,14 @@ Delete Redmine service for a project. ...@@ -479,6 +615,14 @@ Delete Redmine service for a project.
DELETE /projects/:id/services/redmine DELETE /projects/:id/services/redmine
``` ```
### Get Redmine service settings
Get Redmine service settings for a project.
```
GET /projects/:id/services/redmine
```
## Slack ## Slack
A team communication tool for the 21st century A team communication tool for the 21st century
...@@ -505,6 +649,14 @@ Delete Slack service for a project. ...@@ -505,6 +649,14 @@ Delete Slack service for a project.
DELETE /projects/:id/services/slack DELETE /projects/:id/services/slack
``` ```
### Get Slack service settings
Get Slack service settings for a project.
```
GET /projects/:id/services/slack
```
## JetBrains TeamCity CI ## JetBrains TeamCity CI
A continuous integration and build server A continuous integration and build server
...@@ -534,3 +686,11 @@ Delete JetBrains TeamCity CI service for a project. ...@@ -534,3 +686,11 @@ Delete JetBrains TeamCity CI service for a project.
DELETE /projects/:id/services/teamcity DELETE /projects/:id/services/teamcity
``` ```
### Get JetBrains TeamCity CI service settings
Get JetBrains TeamCity CI service settings for a project.
```
GET /projects/:id/services/teamcity
```
...@@ -369,4 +369,7 @@ For more information see similar questions on postgresql issue tracker[here](htt ...@@ -369,4 +369,7 @@ For more information see similar questions on postgresql issue tracker[here](htt
## Note ## Note
This documentation is for GitLab CE. This documentation is for GitLab CE.
We backup GitLab.com and make sure your data is secure, but you can't use these methods to export / backup your data yourself from GitLab.com. We backup GitLab.com and make sure your data is secure, but you can't use these methods
to export / backup your data yourself from GitLab.com.
Issues are stored in the database. They can't be stored in Git itself.
...@@ -162,7 +162,7 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab ...@@ -162,7 +162,7 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
TIP: to see what changed in `gitlab.yml.example` in this release use next command: TIP: to see what changed in `gitlab.yml.example` in this release use next command:
``` ```
git diff 6-0-stable:config/gitlab.yml.example 7.14-stable:config/gitlab.yml.example git diff 6-0-stable:config/gitlab.yml.example 7-14-stable:config/gitlab.yml.example
``` ```
* Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-14-stable/config/gitlab.yml.example but with your settings. * Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-14-stable/config/gitlab.yml.example but with your settings.
......
# Universal update guide for patch versions # Universal update guide for patch versions
*Make sure you view this [upgrade guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/patch_versions.md) from the `master` branch for the most up to date instructions.* *Make sure you view this [upgrade guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/patch_versions.md) from the `master` branch for the most up to date instructions.*
For example from 6.2.0 to 6.2.1, also see the [semantic versioning specification](http://semver.org/). For example from 7.14.0 to 7.14.3, also see the [semantic versioning specification](http://semver.org/).
### 0. Backup ### 0. Backup
...@@ -23,17 +23,16 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ...@@ -23,17 +23,16 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
cd /home/git/gitlab cd /home/git/gitlab
sudo -u git -H git fetch --all sudo -u git -H git fetch --all
sudo -u git -H git checkout -- Gemfile.lock db/schema.rb sudo -u git -H git checkout -- Gemfile.lock db/schema.rb
sudo -u git -H git checkout LATEST_TAG LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
sudo -u git -H git checkout $LATEST_TAG -b $LATEST_TAG
``` ```
Replace LATEST_TAG with the latest GitLab tag you want to upgrade to, for example `v6.6.3`.
### 3. Update gitlab-shell to the corresponding version ### 3. Update gitlab-shell to the corresponding version
```bash ```bash
cd /home/git/gitlab-shell cd /home/git/gitlab-shell
sudo -u git -H git fetch sudo -u git -H git fetch
sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION` sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION` -b v`cat /home/git/gitlab/GITLAB_SHELL_VERSION`
``` ```
### 4. Install libs, migrations, etc. ### 4. Install libs, migrations, etc.
......
...@@ -3,20 +3,6 @@ Feature: Explore Groups ...@@ -3,20 +3,6 @@ Feature: Explore Groups
Background: Background:
Given group "TestGroup" has private project "Enterprise" Given group "TestGroup" has private project "Enterprise"
Scenario: I should not see group with private projects as visitor
When I visit group "TestGroup" page
Then I should be redirected to sign in page
Scenario: I should not see group with private projects group as user
When I sign in as a user
And I visit group "TestGroup" page
Then page status code should be 404
Scenario: I should not see group with private and internal projects as visitor
Given group "TestGroup" has internal project "Internal"
When I visit group "TestGroup" page
Then I should be redirected to sign in page
Scenario: I should see group with private and internal projects as user Scenario: I should see group with private and internal projects as user
Given group "TestGroup" has internal project "Internal" Given group "TestGroup" has internal project "Internal"
When I sign in as a user When I sign in as a user
......
...@@ -159,3 +159,14 @@ Feature: Groups ...@@ -159,3 +159,14 @@ Feature: Groups
When I visit group "Owned" projects page When I visit group "Owned" projects page
Then I should see group "Owned" projects list Then I should see group "Owned" projects list
And I should see "archived" label And I should see "archived" label
# Public group
@javascript
Scenario: Signed out user should see group
Given "Mary Jane" is owner of group "Owned"
And I am a signed out user
And Group "Owned" has a public project "Public-project"
When I visit group "Owned" page
Then I should see group "Owned"
Then I should see project "Public-project"
...@@ -4,11 +4,13 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps ...@@ -4,11 +4,13 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps
include SharedAdmin include SharedAdmin
before do before do
allow(Devise).to receive(:omniauth_providers).and_return([:twitter, :twitter_updated]) allow(Gitlab::OAuth::Provider).to receive(:providers).and_return([:twitter, :twitter_updated])
allow_any_instance_of(ApplicationHelper).to receive(:user_omniauth_authorize_path).and_return(root_path)
end end
after do after do
allow(Devise).to receive(:omniauth_providers).and_call_original allow(Gitlab::OAuth::Provider).to receive(:providers).and_call_original
allow_any_instance_of(ApplicationHelper).to receive(:user_omniauth_authorize_path).and_call_original
end end
step 'I should see all users' do step 'I should see all users' do
......
...@@ -6,7 +6,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps ...@@ -6,7 +6,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
include Select2Helper include Select2Helper
step 'I should see back to dashboard button' do step 'I should see back to dashboard button' do
expect(page).to have_content 'Back to Dashboard' expect(page).to have_content 'Back to dashboard'
end end
step 'gitlab user "Mike"' do step 'gitlab user "Mike"' do
...@@ -17,6 +17,26 @@ class Spinach::Features::Groups < Spinach::FeatureSteps ...@@ -17,6 +17,26 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
find(:css, 'button.btn-new').click find(:css, 'button.btn-new').click
end end
step 'I should see group "Owned"' do
expect(page).to have_content '@owned'
end
step 'I am a signed out user' do
logout
end
step 'Group "Owned" has a public project "Public-project"' do
group = Group.find_by(name: "Owned")
@project = create :empty_project, :public,
group: group,
name: "Public-project"
end
step 'I should see project "Public-project"' do
expect(page).to have_content 'Public-project'
end
step 'I select "Mike" as "Reporter"' do step 'I select "Mike" as "Reporter"' do
user = User.find_by(name: "Mike") user = User.find_by(name: "Mike")
......
...@@ -63,7 +63,7 @@ class Spinach::Features::Invites < Spinach::FeatureSteps ...@@ -63,7 +63,7 @@ class Spinach::Features::Invites < Spinach::FeatureSteps
end end
step 'I should be redirected to the dashboard' do step 'I should be redirected to the dashboard' do
expect(current_path).to eq(dashboard_path) expect(current_path).to eq(dashboard_projects_path)
end end
step 'I should see a notice telling me I have declined' do step 'I should see a notice telling me I have declined' do
......
...@@ -15,7 +15,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps ...@@ -15,7 +15,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps
end end
step 'I should see the forked project page' do step 'I should see the forked project page' do
expect(page).to have_content "Project was successfully forked." expect(page).to have_content "Forked from"
end end
step 'I already have a project named "Shop" in my namespace' do step 'I already have a project named "Shop" in my namespace' do
......
...@@ -124,11 +124,11 @@ class Spinach::Features::Project < Spinach::FeatureSteps ...@@ -124,11 +124,11 @@ class Spinach::Features::Project < Spinach::FeatureSteps
end end
step 'I should see back to dashboard button' do step 'I should see back to dashboard button' do
expect(page).to have_content 'Back to Dashboard' expect(page).to have_content 'Back to dashboard'
end end
step 'I should see back to group button' do step 'I should see back to group button' do
expect(page).to have_content 'Back to Group' expect(page).to have_content 'Back to group'
end end
step 'I click notifications drop down button' do step 'I click notifications drop down button' do
......
...@@ -68,7 +68,7 @@ module SharedPaths ...@@ -68,7 +68,7 @@ module SharedPaths
# ---------------------------------------- # ----------------------------------------
step 'I visit dashboard page' do step 'I visit dashboard page' do
visit dashboard_path visit dashboard_projects_path
end end
step 'I visit dashboard activity page' do step 'I visit dashboard activity page' do
...@@ -460,7 +460,7 @@ module SharedPaths ...@@ -460,7 +460,7 @@ module SharedPaths
end end
step 'I visit snippets page' do step 'I visit snippets page' do
visit snippets_path visit explore_snippets_path
end end
step 'I visit new snippet page' do step 'I visit new snippet page' do
......
...@@ -4,7 +4,7 @@ class Spinach::Features::SnippetsUser < Spinach::FeatureSteps ...@@ -4,7 +4,7 @@ class Spinach::Features::SnippetsUser < Spinach::FeatureSteps
include SharedSnippet include SharedSnippet
step 'I visit my snippets page' do step 'I visit my snippets page' do
visit user_snippets_path(current_user) visit dashboard_snippets_path
end end
step 'I should see "Personal snippet one" in snippets' do step 'I should see "Personal snippet one" in snippets' do
......
...@@ -49,6 +49,16 @@ module API ...@@ -49,6 +49,16 @@ module API
end end
end end
end end
# Get <service_slug> service settings for project
#
# Example Request:
#
# GET /project/:id/services/gitlab-ci
#
get ':id/services/:service_slug' do
present project_service
end
end end
end end
end end
...@@ -67,12 +67,16 @@ module Gitlab ...@@ -67,12 +67,16 @@ module Gitlab
def clean_spans def clean_spans
lambda do |env| lambda do |env|
return unless env[:node_name] == 'span' node = env[:node]
return unless env[:node].has_attribute?('class')
unless has_ancestor?(env[:node], 'pre') return unless node.name == 'span'
env[:node].remove_attribute('class') return unless node.has_attribute?('class')
unless has_ancestor?(node, 'pre')
node.remove_attribute('class')
end end
{ node_whitelist: [node] }
end end
end end
end end
......
...@@ -21,7 +21,13 @@ module Gitlab ...@@ -21,7 +21,13 @@ module Gitlab
language = node.attr('class') language = node.attr('class')
code = node.text code = node.text
highlighted = block_code(code, language) begin
highlighted = block_code(code, language)
rescue
# Gracefully handle syntax highlighter bugs/errors to ensure
# users can still access an issue/comment/etc.
highlighted = "<pre>#{code}</pre>"
end
# Replace the parent `pre` element with the entire highlighted block # Replace the parent `pre` element with the entire highlighted block
node.parent.replace(highlighted) node.parent.replace(highlighted)
......
...@@ -40,6 +40,15 @@ DELETE /projects/:id/services/<%= service[:dashed_name] %> ...@@ -40,6 +40,15 @@ DELETE /projects/:id/services/<%= service[:dashed_name] %>
``` ```
### Get <%= service[:title] %> service settings
Get <%= service[:title] %> service settings for a project.
```
GET /projects/:id/services/<%= service[:dashed_name] %>
```
<% end %> <% end %>
ERB ERB
......
...@@ -46,13 +46,11 @@ describe NamespacesController do ...@@ -46,13 +46,11 @@ describe NamespacesController do
context "when the project doesn't have public projects" do context "when the project doesn't have public projects" do
context "when not signed in" do context "when not signed in" do
it "redirects to the sign in page" do it "does not redirect to the sign in page" do
get :show, id: group.path get :show, id: group.path
expect(response).not_to redirect_to(new_user_session_path)
expect(response).to redirect_to(new_user_session_path)
end end
end end
context "when signed in" do context "when signed in" do
before do before do
sign_in(user) sign_in(user)
...@@ -86,10 +84,10 @@ describe NamespacesController do ...@@ -86,10 +84,10 @@ describe NamespacesController do
end end
context "when the user doesn't have access to the project" do context "when the user doesn't have access to the project" do
it "responds with status 404" do it "redirects to the group's page" do
get :show, id: group.path get :show, id: group.path
expect(response.status).to eq(404) expect(response).to redirect_to(group_path(group))
end end
end end
end end
......
require 'spec_helper' require 'spec_helper'
describe RootController do describe RootController do
describe 'GET show' do describe 'GET index' do
context 'with a user' do context 'with a user' do
let(:user) { create(:user) } let(:user) { create(:user) }
...@@ -16,15 +16,15 @@ describe RootController do ...@@ -16,15 +16,15 @@ describe RootController do
end end
it 'redirects to their specified dashboard' do it 'redirects to their specified dashboard' do
get :show get :index
expect(response).to redirect_to starred_dashboard_projects_path expect(response).to redirect_to starred_dashboard_projects_path
end end
end end
context 'who uses the default dashboard setting' do context 'who uses the default dashboard setting' do
it 'renders the default dashboard' do it 'renders the default dashboard' do
get :show get :index
expect(response).to render_template 'dashboard/show' expect(response).to render_template 'dashboard/projects/index'
end end
end end
end end
......
...@@ -156,14 +156,6 @@ describe UploadsController do ...@@ -156,14 +156,6 @@ describe UploadsController do
end end
context "when the project doesn't have public projects" do context "when the project doesn't have public projects" do
context "when not signed in" do
it "redirects to the sign in page" do
get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png"
expect(response).to redirect_to(new_user_session_path)
end
end
context "when signed in" do context "when signed in" do
before do before do
sign_in(user) sign_in(user)
......
...@@ -6,7 +6,7 @@ describe "Dashboard Feed", feature: true do ...@@ -6,7 +6,7 @@ describe "Dashboard Feed", feature: true do
context "projects atom feed via private token" do context "projects atom feed via private token" do
it "should render projects atom feed" do it "should render projects atom feed" do
visit dashboard_path(:atom, private_token: user.private_token) visit dashboard_projects_path(:atom, private_token: user.private_token)
expect(body).to have_selector('feed title') expect(body).to have_selector('feed title')
end end
end end
...@@ -20,7 +20,7 @@ describe "Dashboard Feed", feature: true do ...@@ -20,7 +20,7 @@ describe "Dashboard Feed", feature: true do
project.team << [user, :master] project.team << [user, :master]
issue_event(issue, user) issue_event(issue, user)
note_event(note, user) note_event(note, user)
visit dashboard_path(:atom, private_token: user.private_token) visit dashboard_projects_path(:atom, private_token: user.private_token)
end end
it "should have issue opened event" do it "should have issue opened event" do
......
...@@ -70,7 +70,7 @@ describe 'Profile > Preferences', feature: true do ...@@ -70,7 +70,7 @@ describe 'Profile > Preferences', feature: true do
expect(page.current_path).to eq starred_dashboard_projects_path expect(page.current_path).to eq starred_dashboard_projects_path
click_link 'Your Projects' click_link 'Your Projects'
expect(page.current_path).to eq dashboard_path expect(page.current_path).to eq dashboard_projects_path
end end
end end
......
...@@ -4,7 +4,7 @@ describe "Dashboard access", feature: true do ...@@ -4,7 +4,7 @@ describe "Dashboard access", feature: true do
include AccessMatchers include AccessMatchers
describe "GET /dashboard" do describe "GET /dashboard" do
subject { dashboard_path } subject { dashboard_projects_path }
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
...@@ -40,7 +40,7 @@ describe "Dashboard access", feature: true do ...@@ -40,7 +40,7 @@ describe "Dashboard access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
describe "GET /projects/new" do describe "GET /projects/new" do
......
...@@ -68,7 +68,7 @@ describe 'Group access', feature: true do ...@@ -68,7 +68,7 @@ describe 'Group access', feature: true do
it { is_expected.to be_allowed_for group_member(:guest) } it { is_expected.to be_allowed_for group_member(:guest) }
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
context 'with no projects' do context 'with no projects' do
...@@ -77,8 +77,8 @@ describe 'Group access', feature: true do ...@@ -77,8 +77,8 @@ describe 'Group access', feature: true do
it { is_expected.to be_allowed_for group_member(:reporter) } it { is_expected.to be_allowed_for group_member(:reporter) }
it { is_expected.to be_allowed_for group_member(:guest) } it { is_expected.to be_allowed_for group_member(:guest) }
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
end end
......
#= require syntax_highlight
describe 'Syntax Highlighter', ->
stubUserColorScheme = (value) ->
window.gon ?= {}
window.gon.user_color_scheme = value
describe 'on a js-syntax-highlight element', ->
beforeEach ->
fixture.set('<div class="js-syntax-highlight"></div>')
it 'applies syntax highlighting', ->
stubUserColorScheme('monokai')
$('.js-syntax-highlight').syntaxHighlight()
expect($('.js-syntax-highlight')).toHaveClass('monokai')
describe 'on a parent element', ->
beforeEach ->
fixture.set """
<div class="parent">
<div class="js-syntax-highlight"></div>
<div class="foo"></div>
<div class="js-syntax-highlight"></div>
</div>
"""
it 'applies highlighting to all applicable children', ->
stubUserColorScheme('monokai')
$('.parent').syntaxHighlight()
expect($('.parent, .foo')).not.toHaveClass('monokai')
expect($('.monokai').length).toBe(2)
it 'prevents an infinite loop when no matches exist', ->
fixture.set('<div></div>')
highlight = -> $('div').syntaxHighlight()
expect(highlight).not.toThrow()
require 'spec_helper'
module Gitlab::Markdown
describe SyntaxHighlightFilter do
include FilterSpecHelper
it 'highlights valid code blocks' do
result = filter('<pre><code>def fun end</code>')
expect(result.to_html).to eq("<pre class=\"code highlight js-syntax-highlight plaintext\"><code>def fun end</code></pre>\n")
end
it 'passes through invalid code blocks' do
allow_any_instance_of(SyntaxHighlightFilter).to receive(:block_code).and_raise(StandardError)
result = filter('<pre><code>This is a test</code></pre>')
expect(result.to_html).to eq('<pre>This is a test</pre>')
end
end
end
...@@ -47,5 +47,15 @@ describe API::API, api: true do ...@@ -47,5 +47,15 @@ describe API::API, api: true do
expect(project.send(service_method).activated?).to be_falsey expect(project.send(service_method).activated?).to be_falsey
end end
end end
describe "GET /projects/:id/services/#{service.dasherize}" do
include_context service
it "should get #{service} settings" do
get api("/projects/#{project.id}/services/#{dashed_service}", user)
expect(response.status).to eq(200)
end
end
end end
end end
...@@ -206,7 +206,7 @@ end ...@@ -206,7 +206,7 @@ end
# dashboard_merge_requests GET /dashboard/merge_requests(.:format) dashboard#merge_requests # dashboard_merge_requests GET /dashboard/merge_requests(.:format) dashboard#merge_requests
describe DashboardController, "routing" do describe DashboardController, "routing" do
it "to #index" do it "to #index" do
expect(get("/dashboard")).to route_to('dashboard#show') expect(get("/dashboard")).to route_to('dashboard/projects#index')
end end
it "to #issues" do it "to #issues" do
...@@ -220,8 +220,8 @@ end ...@@ -220,8 +220,8 @@ end
# root / root#show # root / root#show
describe RootController, 'routing' do describe RootController, 'routing' do
it 'to #show' do it 'to #index' do
expect(get('/')).to route_to('root#show') expect(get('/')).to route_to('root#index')
end end
end end
......
...@@ -96,6 +96,17 @@ describe Projects::CreateService do ...@@ -96,6 +96,17 @@ describe Projects::CreateService do
expect(project.saved?).to be(true) expect(project.saved?).to be(true)
end end
end end
context 'repository creation' do
it 'should synchronously create the repository' do
expect_any_instance_of(Project).to receive(:create_repository)
project = create_project(@user, @opts)
expect(project).to be_valid
expect(project.owner).to eq(@user)
expect(project.namespace).to eq(@user.namespace)
end
end
end end
def create_project(user, opts) def create_project(user, opts)
......
...@@ -28,8 +28,7 @@ describe Projects::ForkService do ...@@ -28,8 +28,7 @@ describe Projects::ForkService do
context 'fork project failure' do context 'fork project failure' do
it "fails due to transaction failure" do it "fails due to transaction failure" do
@to_project = fork_project(@from_project, @to_user, false) @to_project = fork_project(@from_project, @to_user, false)
expect(@to_project.errors).not_to be_empty expect(@to_project.import_failed?)
expect(@to_project.errors[:base]).to include("Failed to fork repository via gitlab-shell")
end end
end end
...@@ -100,7 +99,7 @@ describe Projects::ForkService do ...@@ -100,7 +99,7 @@ describe Projects::ForkService do
end end
def fork_project(from_project, user, fork_success = true, params = {}) def fork_project(from_project, user, fork_success = true, params = {})
allow_any_instance_of(Gitlab::Shell).to receive(:fork_repository).and_return(fork_success) allow(RepositoryForkWorker).to receive(:perform_async).and_return(fork_success)
Projects::ForkService.new(from_project, user, params).execute Projects::ForkService.new(from_project, user, params).execute
end end
end end
require 'spec_helper'
describe RepositoryForkWorker do
let(:project) { create(:project) }
let(:fork_project) { create(:project, forked_from_project: project) }
subject { RepositoryForkWorker.new }
describe "#perform" do
it "creates a new repository from a fork" do
expect_any_instance_of(Gitlab::Shell).to receive(:fork_repository).with(
project.path_with_namespace,
fork_project.namespace.path).
and_return(true)
expect(ProjectCacheWorker).to receive(:perform_async)
subject.perform(project.id,
project.path_with_namespace,
fork_project.namespace.path)
end
it "handles bad fork" do
expect_any_instance_of(Gitlab::Shell).to receive(:fork_repository).and_return(false)
subject.perform(project.id,
project.path_with_namespace,
fork_project.namespace.path)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment