diff options
133 files changed, 1050 insertions, 551 deletions
diff --git a/CHANGELOG b/CHANGELOG index 4e0e5d44be8..c78120275cd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,14 +1,16 @@ Please view this file on the master branch, on stable branches it's out of date. 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 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) - 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) - Fix bug where only the first 15 Bitbucket issues would be imported (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) - 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) @@ -30,31 +32,36 @@ v 8.0.0 (unreleased) - Fix 500 error when submit project snippet without body - Improve search page usability - 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) - Don't notify users without access to the project when they are (accidentally) mentioned in a note. - Retrieving oauth token with LDAP credentials - Load Application settings from running database unless env var USE_DB=false - 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) - 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 - Global Labels that are available to all projects - Fix highlighting of deleted lines in diffs. - 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 - Improve abuse reports management from admin area - Fix "Reload with full diff" URL button in compare branch view (Stan Hu) - 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) - Fix Error 500 in API when accessing a group that has an avatar (Stan Hu) - Ability to enable SSL verification for Webhooks - - Add FogBugz project import (Jared Szechy) v 7.14.0 - Fix bug where non-project members of the target project could set labels on new merge requests. diff --git a/Gemfile.lock b/Gemfile.lock index dce7e4964a6..f3091857b7e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -291,7 +291,7 @@ GEM github-markup (~> 1.3.1) gollum-grit_adapter (~> 0.1, >= 0.1.1) nokogiri (~> 1.6.4) - rouge (~> 1.9) + rouge (~> 1.10.1) sanitize (~> 2.1.0) stringex (~> 2.5.1) gon (5.0.1) @@ -544,7 +544,7 @@ GEM netrc (~> 0.7) rinku (1.7.3) rotp (1.6.1) - rouge (1.9.1) + rouge (1.10.1) rqrcode (0.4.2) rqrcode-rails3 (0.1.7) rqrcode (>= 0.4.2) diff --git a/app/assets/javascripts/dropzone_input.js.coffee b/app/assets/javascripts/dropzone_input.js.coffee index a0dcaa8c27a..6f789e668af 100644 --- a/app/assets/javascripts/dropzone_input.js.coffee +++ b/app/assets/javascripts/dropzone_input.js.coffee @@ -167,6 +167,7 @@ class @DropzoneInput dataType: "json" ).success (data) -> preview.html data.body + preview.syntaxHighlight() renderReferencedUsers data.references.users diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee index b7f2c63c5a7..ce638c2641b 100644 --- a/app/assets/javascripts/notes.js.coffee +++ b/app/assets/javascripts/notes.js.coffee @@ -122,8 +122,9 @@ class @Notes # or skip if rendered if @isNewNote(note) @note_ids.push(note.id) - $('ul.main-notes-list').append(note.html) - $('.js-syntax-highlight').syntaxHighlight() + $('ul.main-notes-list'). + append(note.html). + syntaxHighlight() @initTaskList() ### diff --git a/app/assets/javascripts/syntax_highlight.coffee b/app/assets/javascripts/syntax_highlight.coffee index 71295cd4b08..980f0232d10 100644 --- a/app/assets/javascripts/syntax_highlight.coffee +++ b/app/assets/javascripts/syntax_highlight.coffee @@ -1,3 +1,5 @@ +# Syntax Highlighter +# # Applies a syntax highlighting color scheme CSS class to any element with the # `js-syntax-highlight` class # @@ -6,7 +8,13 @@ # <div class="js-syntax-highlight"></div> # $.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', -> $('.js-syntax-highlight').syntaxHighlight() diff --git a/app/assets/stylesheets/base/gl_bootstrap.scss b/app/assets/stylesheets/base/gl_bootstrap.scss index ae72c5b8d97..eb8d23d6453 100644 --- a/app/assets/stylesheets/base/gl_bootstrap.scss +++ b/app/assets/stylesheets/base/gl_bootstrap.scss @@ -156,10 +156,16 @@ * Add some extra stuff to panels * */ + +.container-blank .panel .panel-heading { + font-size: 17px; + line-height: 38px; +} + .panel { - .panel-heading { - font-weight: bold; + box-shadow: none; + .panel-heading { .panel-head-actions { position: relative; top: -5px; @@ -182,6 +188,10 @@ .pagination { margin: 0; } + + .btn { + min-width: 124px; + } } &.panel-small { @@ -209,6 +219,12 @@ } } +.alert-help { + background-color: $background-color; + border: 1px solid $border-color; + color: $gl-gray; +} + // Typography ================================================================= .text-primary, diff --git a/app/assets/stylesheets/base/gl_variables.scss b/app/assets/stylesheets/base/gl_variables.scss index d18b48eaca9..bfef5f78f83 100644 --- a/app/assets/stylesheets/base/gl_variables.scss +++ b/app/assets/stylesheets/base/gl_variables.scss @@ -114,11 +114,12 @@ $alert-border-radius: 0; // //## -$panel-border-radius: 0; -$panel-default-text: $text-color; -$panel-default-border: #E7E9ED; -$panel-default-heading-bg: #F8FAFC; - +$panel-border-radius: 2px; +$panel-default-text: $text-color; +$panel-default-border: $border-color; +$panel-default-heading-bg: $background-color; +$panel-footer-bg: $background-color; +$panel-inner-border: $border-color; //== Wells // diff --git a/app/assets/stylesheets/base/mixins.scss b/app/assets/stylesheets/base/mixins.scss index 0f661d6b1b6..a2f6c3e21f4 100644 --- a/app/assets/stylesheets/base/mixins.scss +++ b/app/assets/stylesheets/base/mixins.scss @@ -55,10 +55,10 @@ } @mixin md-typography { - color: #444; + color: $md-text-color; a { - color: #3084bb; + color: $md-link-color; } img { diff --git a/app/assets/stylesheets/base/variables.scss b/app/assets/stylesheets/base/variables.scss index 21462b31127..2fc7bf1720a 100644 --- a/app/assets/stylesheets/base/variables.scss +++ b/app/assets/stylesheets/base/variables.scss @@ -2,6 +2,8 @@ $hover: #FFFAF1; $gl-text-color: #54565b; $gl-header-color: #4c4e54; $gl-link-color: #333c48; +$md-text-color: #444; +$md-link-color: #3084bb; $nprogress-color: #c0392b; $gl-font-size: 15px; $list-font-size: 15px; diff --git a/app/assets/stylesheets/generic/blocks.scss b/app/assets/stylesheets/generic/blocks.scss index 27a4c4db8c8..1bd016e0df2 100644 --- a/app/assets/stylesheets/generic/blocks.scss +++ b/app/assets/stylesheets/generic/blocks.scss @@ -27,6 +27,10 @@ border-bottom: 1px solid #e7e9ed; color: $gl-gray; + &.top-block { + border-top: none; + } + &.middle-block { margin-top: 0; margin-bottom: 0; @@ -47,6 +51,6 @@ } .oneline { - line-height: 44px; + line-height: 42px; } } diff --git a/app/assets/stylesheets/generic/buttons.scss b/app/assets/stylesheets/generic/buttons.scss index e8237509092..46ef595ddf0 100644 --- a/app/assets/stylesheets/generic/buttons.scss +++ b/app/assets/stylesheets/generic/buttons.scss @@ -10,7 +10,7 @@ } &.btn-save { - @extend .btn-primary; + @extend .btn-success; } &.btn-remove { diff --git a/app/assets/stylesheets/generic/files.scss b/app/assets/stylesheets/generic/files.scss index f845342c67b..9dd77747884 100644 --- a/app/assets/stylesheets/generic/files.scss +++ b/app/assets/stylesheets/generic/files.scss @@ -3,7 +3,11 @@ * */ .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; table { @@ -49,7 +53,7 @@ } &.wiki { - padding: 25px; + padding: $gl-padding; .highlight { margin-bottom: 9px; @@ -90,7 +94,7 @@ border-right: none; } background: #fff; - padding: 8px; + padding: 10px $gl-padding; } .lines { pre { @@ -100,6 +104,33 @@ 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 { diff --git a/app/assets/stylesheets/generic/sidebar.scss b/app/assets/stylesheets/generic/sidebar.scss index 22720c2e1d5..3d055f0e66f 100644 --- a/app/assets/stylesheets/generic/sidebar.scss +++ b/app/assets/stylesheets/generic/sidebar.scss @@ -28,12 +28,18 @@ padding: $gl-padding; border: 1px solid #e7e9ed; min-height: 90vh; + + &.container-blank { + background: none; + padding: 0; + border: none; + } } } .nav-sidebar { margin-top: 14 + $header-height; - margin-bottom: 50px; + margin-bottom: 100px; transition-duration: .3s; list-style: none; overflow: hidden; @@ -146,7 +152,6 @@ } .collapse-nav a { - left: 0px; width: $sidebar_collapsed_width; } @@ -165,6 +170,7 @@ width: $sidebar_width; position: fixed; bottom: 0; + left: 0; font-size: 13px; background: transparent; height: 40px; diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss index e0edfb80b42..5de589109bd 100644 --- a/app/assets/stylesheets/highlight/white.scss +++ b/app/assets/stylesheets/highlight/white.scss @@ -5,15 +5,19 @@ pre.code.highlight.white, background-color: #fff; color: #333; - pre.highlight, .line-numbers, .line-numbers a { + background-color: $background-color !important; + color: $gl-gray !important; + } + + pre.highlight { background-color: #fff !important; color: #333 !important; } pre.code { - border-left: 1px solid #bbb; + border-left: 1px solid $border-color; } // highlight line via anchor diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 487b600e31d..5e7e59a6af8 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -1,6 +1,6 @@ .diff-file { - margin-left: -16px; - margin-right: -16px; + margin-left: -$gl-padding; + margin-right: -$gl-padding; border: none; border-bottom: 1px solid #E7E9EE; @@ -8,7 +8,7 @@ position: relative; background: $background-color; border-bottom: 1px solid $border-color; - padding: 10px 15px; + padding: 10px 16px; color: #555; z-index: 10; diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 2544356a5f6..2a77f065aed 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -235,8 +235,6 @@ ul.notes { filter: alpha(opacity=0); &:hover { - width: 38px; - font-size: 20px; background: $gl-info; color: #FFF; @include show-add-diff-note; diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 8021b3bbffa..a986fafff07 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -48,7 +48,6 @@ p { color: #7f8fa4; - display: inline; } } @@ -204,26 +203,18 @@ ul.nav.nav-projects-tabs { } .fork-namespaces { - .thumbnail { + .fork-thumbnail { + text-align: center; + margin-bottom: $gl-padding; - &.fork-exists-thumbnail { - border-color: #EEE; - - .caption { - color: #999; - } - } - - &.fork-thumbnail { - border-color: #AAA; - - &:hover { - background-color: $hover; - } + .caption { + padding: $gl-padding 0; + min-height: 30px; } - a { - text-decoration: none; + img { + @include border-radius(50%); + max-width: 100px; } } } diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index 587d09a04a5..71ca37c0cd7 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -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 { @@ -132,17 +102,14 @@ list-style: none; margin: 0; padding: 0; - margin-bottom: 10px; + margin-bottom: 5px; .commit { - padding: 10px 15px; + padding: $gl-padding 0; .commit-row-title { - font-size: 13px; - .commit-row-message { font-weight: normal; - color: #555; } } } diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb index da96171e885..467d0f81aca 100644 --- a/app/controllers/dashboard/projects_controller.rb +++ b/app/controllers/dashboard/projects_controller.rb @@ -1,6 +1,21 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController 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 @projects = current_user.starred_projects @projects = @projects.includes(:namespace, :forked_from_project, :tags) diff --git a/app/controllers/dashboard/snippets_controller.rb b/app/controllers/dashboard/snippets_controller.rb new file mode 100644 index 00000000000..f4354c6d8ca --- /dev/null +++ b/app/controllers/dashboard/snippets_controller.rb @@ -0,0 +1,10 @@ +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 diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 2bc2e5e58f5..4ebb3d7276e 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -1,23 +1,8 @@ class DashboardController < Dashboard::ApplicationController - before_action :load_projects, except: :activity before_action :event_filter, only: :activity 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 @merge_requests = get_merge_requests_collection @merge_requests = @merge_requests.page(params[:page]).per(PER_PAGE) @@ -50,10 +35,6 @@ class DashboardController < Dashboard::ApplicationController protected - def load_projects - @projects = current_user.authorized_projects.sorted_by_activity.non_archived - end - def load_events project_ids = if params[:filter] == "starred" diff --git a/app/controllers/explore/application_controller.rb b/app/controllers/explore/application_controller.rb index 4b275033d26..461fc059a3c 100644 --- a/app/controllers/explore/application_controller.rb +++ b/app/controllers/explore/application_controller.rb @@ -1,3 +1,5 @@ class Explore::ApplicationController < ApplicationController + skip_before_action :authenticate_user!, :reject_blocked + layout 'explore' end diff --git a/app/controllers/explore/groups_controller.rb b/app/controllers/explore/groups_controller.rb index 55cda0cff17..9575a87ee41 100644 --- a/app/controllers/explore/groups_controller.rb +++ b/app/controllers/explore/groups_controller.rb @@ -1,7 +1,4 @@ class Explore::GroupsController < Explore::ApplicationController - skip_before_action :authenticate_user!, - :reject_blocked, :set_current_user_for_observers - def index @groups = GroupsFinder.new.execute(current_user) @groups = @groups.search(params[:search]) if params[:search].present? diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb index 6c733c1ae4d..a5aeaed66c5 100644 --- a/app/controllers/explore/projects_controller.rb +++ b/app/controllers/explore/projects_controller.rb @@ -1,7 +1,4 @@ class Explore::ProjectsController < Explore::ApplicationController - skip_before_action :authenticate_user!, - :reject_blocked - def index @projects = ProjectsFinder.new.execute(current_user) @tags = @projects.tags_on(:tags) diff --git a/app/controllers/explore/snippets_controller.rb b/app/controllers/explore/snippets_controller.rb new file mode 100644 index 00000000000..b70ac51d06e --- /dev/null +++ b/app/controllers/explore/snippets_controller.rb @@ -0,0 +1,6 @@ +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 diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 279c6ef0f4d..524218290c6 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -4,7 +4,7 @@ class GroupsController < Groups::ApplicationController before_action :group, except: [:new, :create] # 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_create_group!, only: [:new, :create] @@ -14,6 +14,10 @@ class GroupsController < Groups::ApplicationController layout :determine_layout + def index + redirect_to(current_user ? dashboard_groups_path : explore_groups_path) + end + def new @group = Group.new end diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb index 71831c5380d..ad00948da51 100644 --- a/app/controllers/help_controller.rb +++ b/app/controllers/help_controller.rb @@ -1,4 +1,6 @@ class HelpController < ApplicationController + skip_before_action :authenticate_user!, :reject_blocked + layout 'help' def index diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index eb3c8233530..8ef10a17f55 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -24,7 +24,7 @@ class InvitesController < ApplicationController path = if current_user - dashboard_path + dashboard_projects_path else new_user_session_path end @@ -73,7 +73,7 @@ class InvitesController < ApplicationController path = group_path(group) else label = "who knows what" - path = dashboard_path + path = dashboard_projects_path end [label, path] diff --git a/app/controllers/namespaces_controller.rb b/app/controllers/namespaces_controller.rb index 83eec1bf4a2..282012c60a1 100644 --- a/app/controllers/namespaces_controller.rb +++ b/app/controllers/namespaces_controller.rb @@ -14,7 +14,7 @@ class NamespacesController < ApplicationController if user redirect_to user_path(user) - elsif group && can?(current_user, :read_group, group) + elsif group redirect_to group_path(group) elsif current_user.nil? authenticate_user! diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index 9e72597ea87..8a785076bb7 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -13,10 +13,14 @@ class Projects::ForksController < Projects::ApplicationController @forked_project = ::Projects::ForkService.new(project, current_user, namespace: namespace).execute if @forked_project.saved? && @forked_project.forked? - redirect_to( - namespace_project_path(@forked_project.namespace, @forked_project), - notice: 'Project was successfully forked.' - ) + if @forked_project.import_in_progress? + redirect_to namespace_project_import_path(@forked_project.namespace, @forked_project) + else + redirect_to( + namespace_project_path(@forked_project.namespace, @forked_project), + notice: 'Project was successfully forked.' + ) + end else render :error end diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index b82b6f45d59..cf73bc01c8f 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -78,7 +78,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController @project.project_members.find_by(user_id: current_user).destroy respond_to do |format| - format.html { redirect_to dashboard_path } + format.html { redirect_to dashboard_projects_path } format.js { render nothing: true } end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 14c3a6028c9..009e856d93c 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -10,6 +10,10 @@ class ProjectsController < ApplicationController layout :determine_layout + def index + redirect_to(current_user ? root_path : explore_root_path) + end + def new @project = Project.new end @@ -108,7 +112,7 @@ class ProjectsController < ApplicationController if request.referer.include?('/admin') redirect_to admin_namespaces_projects_path else - redirect_to dashboard_path + redirect_to dashboard_projects_path end rescue Projects::DestroyService::DestroyError => ex redirect_to edit_project_path(@project), alert: ex.message diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb index fdfe00dc135..54171ff67c5 100644 --- a/app/controllers/root_controller.rb +++ b/app/controllers/root_controller.rb @@ -6,10 +6,10 @@ # # For users who haven't customized the setting, we simply delegate to # `DashboardController#show`, which is the default. -class RootController < DashboardController - before_action :redirect_to_custom_dashboard, only: [:show] +class RootController < Dashboard::ProjectsController + before_action :redirect_to_custom_dashboard, only: [:index] - def show + def index super end @@ -20,6 +20,7 @@ class RootController < DashboardController case current_user.dashboard when 'stars' + flash.keep redirect_to starred_dashboard_projects_path else return diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 8e7e45c781f..9f9f9a92f11 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -24,13 +24,9 @@ class SnippetsController < ApplicationController scope: params[:scope] }). page(params[:page]).per(PER_PAGE) - if @user == current_user - render 'current_user_index' - else - render 'user_index' - end + render 'index' 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 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a803b66c502..c3da54fd554 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -201,7 +201,7 @@ module ApplicationHelper class: "#{html_class} js-timeago", datetime: time.getutc.iso8601, 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 diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb index d0fae255a04..e0816f4e714 100644 --- a/app/helpers/gitlab_routing_helper.rb +++ b/app/helpers/gitlab_routing_helper.rb @@ -17,6 +17,14 @@ module GitlabRoutingHelper namespace_project_path(project.namespace, project, *args) 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) activity_namespace_project_path(project.namespace, project, *args) end diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb index 8473d6d75d0..df37be51ce9 100644 --- a/app/helpers/page_layout_helper.rb +++ b/app/helpers/page_layout_helper.rb @@ -31,4 +31,26 @@ module PageLayoutHelper @fluid_layout 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 diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index ab9b068de05..6a2de0de77c 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -43,24 +43,22 @@ module ProjectsHelper end end - def project_title(project) - if project.group - content_tag :span do - link_to( - simple_sanitize(project.group.name), group_path(project.group) - ) + ' / ' + - link_to(simple_sanitize(project.name), - 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)) + def project_title(project, name = nil, url = nil) + namespace_link = + if project.group + link_to(simple_sanitize(project.group.name), group_path(project.group)) + else + owner = project.namespace.owner + link_to(simple_sanitize(owner.name), user_path(owner)) end + + project_link = link_to(simple_sanitize(project.name), project_path(project)) + + full_title = namespace_link + ' / ' + project_link + full_title += ' · '.html_safe + link_to(simple_sanitize(name), url) if name + + content_tag :span do + full_title end end @@ -315,6 +313,45 @@ module ProjectsHelper 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 def filename_path(project, filename) diff --git a/app/models/project.rb b/app/models/project.rb index 072d7d73f41..49525eb9227 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -144,7 +144,7 @@ class Project < ActiveRecord::Base validates_uniqueness_of :path, scope: :namespace_id validates :import_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 } validate :check_limit, on: :create validate :avatar_type, @@ -275,7 +275,13 @@ class Project < ActiveRecord::Base end 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 def clear_import_data @@ -283,6 +289,10 @@ class Project < ActiveRecord::Base end def import? + external_import? || forked? + end + + def external_import? import_url.present? end @@ -702,14 +712,8 @@ class Project < ActiveRecord::Base end def create_repository - if forked? - if gitlab_shell.fork_repository(forked_from_project.path_with_namespace, self.namespace.path) - true - else - errors.add(:base, 'Failed to fork repository via gitlab-shell') - false - end - else + # Forked import is handled asynchronously + unless forked? if gitlab_shell.add_repository(path_with_namespace) true else diff --git a/app/services/files/create_service.rb b/app/services/files/create_service.rb index 91d715b2d63..c2da0c30bad 100644 --- a/app/services/files/create_service.rb +++ b/app/services/files/create_service.rb @@ -22,7 +22,7 @@ module Files blob = repository.blob_at_branch(@current_branch, @file_path) 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 diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 1bb2462565a..e54a13ed6c5 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -55,9 +55,7 @@ module Projects @project.save if @project.persisted? && !@project.import? - unless @project.create_repository - raise 'Failed to create repository' - end + raise 'Failed to create repository' unless @project.create_repository end end diff --git a/app/views/dashboard/_activities.html.haml b/app/views/dashboard/_activities.html.haml index 1db56542afd..19d919f9b6a 100644 --- a/app/views/dashboard/_activities.html.haml +++ b/app/views/dashboard/_activities.html.haml @@ -5,7 +5,7 @@ - if current_user %ul.nav.nav-pills.event_filter.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 = render 'shared/event_filter' diff --git a/app/views/dashboard/_groups_head.html.haml b/app/views/dashboard/_groups_head.html.haml index dcd6c97d44d..64bd356f546 100644 --- a/app/views/dashboard/_groups_head.html.haml +++ b/app/views/dashboard/_groups_head.html.haml @@ -1,7 +1,7 @@ %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 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 Explore Groups diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml index 13a5eae3cdc..ed480b8caf8 100644 --- a/app/views/dashboard/_projects_head.html.haml +++ b/app/views/dashboard/_projects_head.html.haml @@ -1,6 +1,6 @@ %ul.center-top-menu - = nav_link(path: ['dashboard#show', 'root#show']) do - = link_to dashboard_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do + = nav_link(path: ['projects#index', 'root#index']) do + = link_to dashboard_projects_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do Your Projects = nav_link(page: starred_dashboard_projects_path) do = link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do diff --git a/app/views/dashboard/_snippets_head.html.haml b/app/views/dashboard/_snippets_head.html.haml new file mode 100644 index 00000000000..0ae62d6f1b6 --- /dev/null +++ b/app/views/dashboard/_snippets_head.html.haml @@ -0,0 +1,7 @@ +%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 diff --git a/app/views/dashboard/activity.html.haml b/app/views/dashboard/activity.html.haml index 3e24338af64..aa57df14c23 100644 --- a/app/views/dashboard/activity.html.haml +++ b/app/views/dashboard/activity.html.haml @@ -1,8 +1,10 @@ = content_for :meta_tags do - 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 + = render 'dashboard/activity_head' %section.activities diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/projects/_projects.html.haml index ef9b9ce756a..ef9b9ce756a 100644 --- a/app/views/dashboard/_projects.html.haml +++ b/app/views/dashboard/projects/_projects.html.haml diff --git a/app/views/dashboard/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml index 4e7d6639727..4e7d6639727 100644 --- a/app/views/dashboard/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/projects/_zero_authorized_projects.html.haml diff --git a/app/views/dashboard/show.atom.builder b/app/views/dashboard/projects/index.atom.builder index e9a612231d5..d2c51486841 100644 --- a/app/views/dashboard/show.atom.builder +++ b/app/views/dashboard/projects/index.atom.builder @@ -1,9 +1,9 @@ xml.instruct! xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do 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_url, rel: "alternate", type: "text/html" - xml.id dashboard_url + 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_projects_url, rel: "alternate", type: "text/html" + xml.id dashboard_projects_url xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? @events.each do |event| diff --git a/app/views/dashboard/show.html.haml b/app/views/dashboard/projects/index.html.haml index 1d5324e0d72..7a16b811f6b 100644 --- a/app/views/dashboard/show.html.haml +++ b/app/views/dashboard/projects/index.html.haml @@ -1,8 +1,10 @@ = content_for :meta_tags do - 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' - if @last_push diff --git a/app/views/dashboard/projects/starred.html.haml b/app/views/dashboard/projects/starred.html.haml index 2fd7a1cf16c..339362701d4 100644 --- a/app/views/dashboard/projects/starred.html.haml +++ b/app/views/dashboard/projects/starred.html.haml @@ -1,9 +1,10 @@ - page_title "Starred Projects" -- header_title "Projects", (current_user ? root_path : explore_root_path) +- header_title "Projects", projects_path + = render 'dashboard/projects_head' - if @projects.any? - = render 'dashboard/projects' + = render 'projects' - else %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. diff --git a/app/views/dashboard/snippets/index.html.haml b/app/views/dashboard/snippets/index.html.haml new file mode 100644 index 00000000000..d3908062f43 --- /dev/null +++ b/app/views/dashboard/snippets/index.html.haml @@ -0,0 +1,38 @@ +- page_title "Snippets" +- header_title "Snippets", dashboard_snippets_path + += render 'dashboard/snippets_head' + +.gray-content-block + .pull-right + = link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do + Add new snippet + + .oneline + Share code pastes with others out of git repository + +%ul.nav.nav-tabs.prepend-top-20 + = nav_tab :scope, nil do + = link_to dashboard_snippets_path do + All + %span.badge + = current_user.snippets.count + = nav_tab :scope, 'are_private' do + = link_to dashboard_snippets_path(scope: 'are_private') do + Private + %span.badge + = current_user.snippets.are_private.count + = nav_tab :scope, 'are_internal' do + = link_to dashboard_snippets_path(scope: 'are_internal') do + Internal + %span.badge + = current_user.snippets.are_internal.count + = nav_tab :scope, 'are_public' do + = link_to dashboard_snippets_path(scope: 'are_public') do + Public + %span.badge + = current_user.snippets.are_public.count + +.my-snippets + = render 'snippets/snippets' + diff --git a/app/views/explore/_head.html.haml b/app/views/explore/_head.html.haml new file mode 100644 index 00000000000..d8a57560788 --- /dev/null +++ b/app/views/explore/_head.html.haml @@ -0,0 +1,6 @@ +.explore-title + %h3 + Explore GitLab + %p.lead + Discover projects, groups and snippets. Share your projects with others + %br diff --git a/app/views/explore/groups/index.html.haml b/app/views/explore/groups/index.html.haml index e8a6752de8c..83d4d321c83 100644 --- a/app/views/explore/groups/index.html.haml +++ b/app/views/explore/groups/index.html.haml @@ -1,7 +1,11 @@ -- page_title "Groups" -- header_title "Groups", (current_user ? dashboard_groups_path : explore_groups_path) +- page_title "Groups" +- header_title "Groups", dashboard_groups_path + - if current_user = render 'dashboard/groups_head' +- else + = render 'explore/head' + .gray-content-block.clearfix .pull-left = form_tag explore_groups_path, method: :get, class: 'form-inline form-tiny' do |f| diff --git a/app/views/explore/projects/index.html.haml b/app/views/explore/projects/index.html.haml index 9df5b3830a8..67e38ca3127 100644 --- a/app/views/explore/projects/index.html.haml +++ b/app/views/explore/projects/index.html.haml @@ -1,6 +1,11 @@ -- page_title "Projects" +- page_title "Projects" +- header_title "Projects", root_path + - if current_user = render 'dashboard/projects_head' +- else + = render 'explore/head' + .gray-content-block.clearfix = render 'filter' = render 'projects', projects: @projects diff --git a/app/views/explore/projects/starred.html.haml b/app/views/explore/projects/starred.html.haml index a9df32f3d7d..596cb0a96cd 100644 --- a/app/views/explore/projects/starred.html.haml +++ b/app/views/explore/projects/starred.html.haml @@ -1,6 +1,10 @@ -- page_title "Starred Projects" +- page_title "Projects" +- header_title "Projects", root_path + - if current_user = render 'dashboard/projects_head' +- else + = render 'explore/head' .explore-trending-block .gray-content-block diff --git a/app/views/explore/projects/trending.html.haml b/app/views/explore/projects/trending.html.haml index c1ef06f6cdb..5ea6d81c5b9 100644 --- a/app/views/explore/projects/trending.html.haml +++ b/app/views/explore/projects/trending.html.haml @@ -1,13 +1,11 @@ -- page_title "Trending Projects" +- page_title "Projects" +- header_title "Projects", root_path + - if current_user = render 'dashboard/projects_head' - else - .explore-title - %h3 - Explore GitLab - %p.lead - Discover projects and groups. Share your projects with others - %br + = render 'explore/head' + .explore-trending-block .gray-content-block .pull-right diff --git a/app/views/explore/snippets/index.html.haml b/app/views/explore/snippets/index.html.haml new file mode 100644 index 00000000000..7e4fa7d4873 --- /dev/null +++ b/app/views/explore/snippets/index.html.haml @@ -0,0 +1,18 @@ +- 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' diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 2ff4b7e23ea..ae8fc9f85f0 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -1,3 +1,6 @@ +- header_title group_title(@group, "Settings", edit_group_path(@group)) +- @blank_container = true + .panel.panel-default .panel-heading %strong= @group.name diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml index d06cfa7ff9f..f1d507a50c7 100644 --- a/app/views/groups/projects.html.haml +++ b/app/views/groups/projects.html.haml @@ -1,4 +1,6 @@ - page_title "Projects" +- header_title group_title(@group, "Projects", projects_group_path(@group)) + .panel.panel-default .panel-heading %strong= @group.name diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 0577f4ec142..a9ba9d2ba10 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,3 +1,6 @@ +- unless can?(current_user, :read_group, @group) + - @disable_search_panel = true + = content_for :meta_tags do - if current_user = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") @@ -16,22 +19,25 @@ = render 'shared/show_aside' - .row - %section.activities.col-md-7 - .hidden-xs - - if current_user - = render "events/event_last_push", event: @last_push - + - if can?(current_user, :read_group, @group) + .row + %section.activities.col-md-7 + .hidden-xs - if current_user + = render "events/event_last_push", event: @last_push + %ul.nav.nav-pills.event_filter.pull-right %li = link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'rss-btn' do %i.fa.fa-rss - = render 'shared/event_filter' - %hr + = render 'shared/event_filter' + %hr - .content_list - = spinner - %aside.side.col-md-5 - = render "projects", projects: @projects + .content_list + = spinner + %aside.side.col-md-5 + = render "projects", projects: @projects + - else + %p + This group does not have public projects diff --git a/app/views/help/show.html.haml b/app/views/help/show.html.haml index 8551496b98a..0398afb4c1d 100644 --- a/app/views/help/show.html.haml +++ b/app/views/help/show.html.haml @@ -1,3 +1,3 @@ - page_title @file.humanize, *@category.split("/").reverse.map(&:humanize) .documentation.wiki - = markdown @markdown.gsub('$your_email', current_user.email) + = markdown @markdown.gsub('$your_email', current_user.try(:email) || "email@example.com") diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index c1746676ae2..2468687b56d 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -6,10 +6,14 @@ = brand_header_logo .gitlab-text-container %h3 GitLab + - if defined?(sidebar) && sidebar = render "layouts/nav/#{sidebar}" - elsif current_user = render 'layouts/nav/dashboard' + - else + = render 'layouts/nav/explore' + .collapse-nav = render partial: 'layouts/collapse_button' - if current_user @@ -19,7 +23,7 @@ = current_user.username .content-wrapper = render "layouts/flash" - %div{ class: fluid_layout ? "container-fluid" : "container-fluid container-limited" } + %div{ class: container_class } .content .clearfix = yield diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml index 1987bf1592a..95e077c339f 100644 --- a/app/views/layouts/devise.html.haml +++ b/app/views/layouts/devise.html.haml @@ -31,5 +31,5 @@ .container .footer-links = 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/" diff --git a/app/views/layouts/explore.html.haml b/app/views/layouts/explore.html.haml index 9098554e6f0..df65792be73 100644 --- a/app/views/layouts/explore.html.haml +++ b/app/views/layouts/explore.html.haml @@ -1,9 +1,5 @@ - page_title "Explore" -- if current_user - - unless @header_title - - header_title "Projects", (current_user ? root_path : explore_root_path) -- else +- unless current_user - header_title "Explore GitLab", explore_root_path -- sidebar "dashboard" = render template: "layouts/application" diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 3892f71c0e3..c31b1cbe9a8 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -7,8 +7,9 @@ .navbar-collapse.collapse %ul.nav.navbar-nav.pull-right - %li.hidden-sm.hidden-xs - = render 'layouts/search' + - unless @disable_search_panel + %li.hidden-sm.hidden-xs + = render 'layouts/search' %li.visible-sm.visible-xs = link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom'} do = icon('search') diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml index 0cf1c3d5d27..c3b07200621 100644 --- a/app/views/layouts/nav/_dashboard.html.haml +++ b/app/views/layouts/nav/_dashboard.html.haml @@ -1,31 +1,30 @@ %ul.nav.nav-sidebar - = nav_link(path: ['dashboard#show', 'root#show', '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 + = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do + = link_to root_path, title: 'Projects', data: {placement: 'right'} do = icon('home fw') %span Projects = 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') %span Activity = 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') %span Groups - - if current_user - = nav_link(controller: :milestones) do - = link_to dashboard_milestones_path, title: 'Milestones', data: {placement: 'right'} do - = icon('clock-o fw') - %span - Milestones - = nav_link(path: 'dashboard#issues') do - = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues', data: {placement: 'right'} do - = icon('exclamation-circle fw') - %span - Issues - %span.count= current_user.assigned_issues.opened.count + = nav_link(controller: :milestones) do + = link_to dashboard_milestones_path, title: 'Milestones', data: {placement: 'right'} do + = icon('clock-o fw') + %span + Milestones + = nav_link(path: 'dashboard#issues') do + = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues', data: {placement: 'right'} do + = icon('exclamation-circle fw') + %span + Issues + %span.count= current_user.assigned_issues.opened.count = nav_link(path: 'dashboard#merge_requests') do = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'shortcuts-merge_requests', data: {placement: 'right'} do = icon('tasks fw') @@ -33,18 +32,17 @@ Merge Requests %span.count= current_user.assigned_merge_requests.opened.count = 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') %span 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 = link_to help_path, title: 'Help', data: {placement: 'right'} do = icon('question-circle fw') %span Help + = nav_link(controller: :profile) do + = link_to profile_path, title: 'Profile settings', data: {placement: 'bottom'} do + = icon('user fw') + %span + Profile Settings diff --git a/app/views/layouts/nav/_explore.html.haml b/app/views/layouts/nav/_explore.html.haml new file mode 100644 index 00000000000..21e565972a7 --- /dev/null +++ b/app/views/layouts/nav/_explore.html.haml @@ -0,0 +1,21 @@ +%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 diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml index 695ce68a201..eb35af22b93 100644 --- a/app/views/layouts/nav/_group.html.haml +++ b/app/views/layouts/nav/_group.html.haml @@ -3,7 +3,7 @@ = link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = icon('caret-square-o-left fw') %span - Back to Dashboard + Back to dashboard %li.separate-item @@ -12,34 +12,35 @@ = icon('dashboard fw') %span Group - - if current_user - = nav_link(controller: [:group, :milestones]) do - = link_to group_milestones_path(@group), title: 'Milestones', data: {placement: 'right'} do - = icon('clock-o fw') + - if can?(current_user, :read_group, @group) + - if current_user + = nav_link(controller: [:group, :milestones]) do + = 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 - Milestones - = nav_link(path: 'groups#issues') do - = link_to issues_group_path(@group), title: 'Issues', data: {placement: 'right'} do - = icon('exclamation-circle fw') - %span - Issues - - if current_user - %span.count= Issue.opened.of_group(@group).count - = nav_link(path: 'groups#merge_requests') do - = link_to merge_requests_group_path(@group), title: 'Merge Requests', data: {placement: 'right'} do - = icon('tasks fw') - %span - Merge Requests - - 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') + Issues + - if current_user + %span.count= Issue.opened.of_group(@group).count + = nav_link(path: 'groups#merge_requests') do + = link_to merge_requests_group_path(@group), title: 'Merge Requests', data: {placement: 'right'} do + = icon('tasks fw') + %span + Merge Requests + - 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 - 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 diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index 33fd5fcef6c..5a47b8e6db2 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -3,7 +3,7 @@ = link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = icon('caret-square-o-left fw') %span - Back to Dashboard + Back to dashboard %li.separate-item @@ -11,7 +11,7 @@ = link_to profile_path, title: 'Profile', data: {placement: 'right'} do = icon('user fw') %span - Profile + Profile Settings = nav_link(controller: [:accounts, :two_factor_auths]) do = link_to profile_account_path, title: 'Account', data: {placement: 'right'} do = icon('gear fw') diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 5e7b902622b..8ce46d4865b 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -4,13 +4,13 @@ = link_to group_path(@project.group), title: 'Back to group', data: {placement: 'right'}, class: 'back-link' do = icon('caret-square-o-left fw') %span - Back to Group + Back to group - else = nav_link do = link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = icon('caret-square-o-left fw') %span - Back to Dashboard + Back to dashboard %li.separate-item @@ -26,28 +26,28 @@ Activity - if project_nav_tab? :files = 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') %span Files - if project_nav_tab? :commits = 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') %span Commits - if project_nav_tab? :network = 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') %span Network - if project_nav_tab? :graphs = 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') %span Graphs diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml index 77d2ccbf762..b80ce0dfc75 100644 --- a/app/views/layouts/profile.html.haml +++ b/app/views/layouts/profile.html.haml @@ -1,5 +1,6 @@ - page_title "Profile Settings" -- header_title "Profile Settings", profile_path +- unless @header_title + - header_title "Profile Settings", profile_path - sidebar "profile" = render template: "layouts/application" diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml index 44afa33dfe5..5c4dd67f0ec 100644 --- a/app/views/layouts/project.html.haml +++ b/app/views/layouts/project.html.haml @@ -1,5 +1,5 @@ - page_title @project.name_with_namespace -- header_title project_title(@project) +- header_title detect_project_title(@project) - sidebar "project" unless sidebar - content_for :scripts_body_top do diff --git a/app/views/layouts/snippets.html.haml b/app/views/layouts/snippets.html.haml index d9c90d4fcef..02ca3ee7a28 100644 --- a/app/views/layouts/snippets.html.haml +++ b/app/views/layouts/snippets.html.haml @@ -1,8 +1,3 @@ -- page_title 'Snippets' -- if current_user - - header_title "Snippets", user_snippets_path(current_user) -- else - - header_title 'Snippets', snippets_path -- sidebar "dashboard" +- header_title "Snippets", snippets_path = render template: "layouts/application" diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index 767fe2e0e9a..cd7b1b0fe03 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -1,9 +1,7 @@ - page_title "Account" -%h3.page-title - = page_title -%p.light - Change your username and basic account settings. -%hr +- header_title page_title, profile_account_path +- @blank_container = true + - if current_user.ldap_user? .alert.alert-info Some options are unavailable for LDAP accounts @@ -69,7 +67,7 @@ - button_based_providers.each do |provider| .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" - + - if auth_active?(provider) = link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do = icon('close') diff --git a/app/views/profiles/applications.html.haml b/app/views/profiles/applications.html.haml index 3a3e6e1b1c4..2342936a5d5 100644 --- a/app/views/profiles/applications.html.haml +++ b/app/views/profiles/applications.html.haml @@ -1,13 +1,12 @@ - page_title "Applications" -%h3.page-title - = page_title -%p.light +- header_title page_title, applications_profile_path + +.gray-content-block.top-block - 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. - else Manage applications that you've authorized to use your account. -%hr - if user_oauth_applications? .oauth-applications diff --git a/app/views/profiles/audit_log.html.haml b/app/views/profiles/audit_log.html.haml index 698d6037428..8fdba45b193 100644 --- a/app/views/profiles/audit_log.html.haml +++ b/app/views/profiles/audit_log.html.haml @@ -1,5 +1,8 @@ - page_title "Audit Log" -%h3.page-title Audit Log -%p.light History of authentications +- header_title page_title, audit_log_profile_path -= render 'event_table', events: @events
\ No newline at end of file +.gray-content-block.top-block + History of authentications + +.prepend-top-default += render 'event_table', events: @events diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml index 66812872c41..1d140347a5f 100644 --- a/app/views/profiles/emails/index.html.haml +++ b/app/views/profiles/emails/index.html.haml @@ -1,12 +1,10 @@ - page_title "Emails" -%h3.page-title - = page_title -%p.light - Control emails linked to your account -%hr +- header_title page_title, profile_emails_path +.gray-content-block.top-block + Control emails linked to your account -%ul +%ul.prepend-top-default %li Your %b Primary Email diff --git a/app/views/profiles/keys/index.html.haml b/app/views/profiles/keys/index.html.haml index 06655f7ba3a..14adba1c797 100644 --- a/app/views/profiles/keys/index.html.haml +++ b/app/views/profiles/keys/index.html.haml @@ -1,11 +1,12 @@ - page_title "SSH Keys" -%h3.page-title - = page_title +- header_title page_title, profile_keys_path + +.gray-content-block.top-block .pull-right = link_to "Add SSH Key", new_profile_key_path, class: "btn btn-new" -%p.light - Before you can add an SSH key you need to - = link_to "generate it.", help_page_path("ssh", "README") -%hr + .oneline + Before you can add an SSH key you need to + = link_to "generate it.", help_page_path("ssh", "README") +.prepend-top-default = render 'key_table' diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml index db7fa2eabe3..ea4e5f3e182 100644 --- a/app/views/profiles/notifications/show.html.haml +++ b/app/views/profiles/notifications/show.html.haml @@ -1,10 +1,10 @@ - page_title "Notifications" -%h3.page-title - = page_title -%p.light +- header_title page_title, profile_notifications_path + +.gray-content-block.top-block 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| -if @user.errors.any? %div.alert.alert-danger diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml index 399ae98adf9..fab7c45c9b2 100644 --- a/app/views/profiles/passwords/edit.html.haml +++ b/app/views/profiles/passwords/edit.html.haml @@ -1,13 +1,13 @@ - page_title "Password" -%h3.page-title - = page_title -%p.light +- header_title page_title, edit_profile_password_path + +.gray-content-block.top-block - if @user.password_automatically_set? Set your password. - else 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| %div %p.slead diff --git a/app/views/profiles/passwords/new.html.haml b/app/views/profiles/passwords/new.html.haml index 9c6204963e0..d165f758c81 100644 --- a/app/views/profiles/passwords/new.html.haml +++ b/app/views/profiles/passwords/new.html.haml @@ -12,7 +12,7 @@ %ul - @user.errors.full_messages.each do |msg| %li= msg - + - unless @user.password_automatically_set? .form-group = f.label :current_password, class: 'control-label' diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index aa0361a0a1b..60289bfe7cd 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -1,11 +1,11 @@ - page_title 'Preferences' -%h3.page-title - = page_title -%p.light +- header_title page_title, profile_preferences_path +- @blank_container = true + +.alert.alert-help 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 access the site. -%hr = 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 diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index c519e52e596..47412e2ef0c 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -1,14 +1,9 @@ -- page_title "Profile" -%h3.page-title - = page_title -%p.light +.gray-content-block.top-block This information will appear on your profile. - if current_user.ldap_user? 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| -if @user.errors.any? %div.alert.alert-danger diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index 67a00b4ebef..6e53f55b0ab 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -7,6 +7,13 @@ - if @project.description.present? = 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 = render 'projects/buttons/star' @@ -14,12 +21,6 @@ - unless empty_repo = 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 = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: @ref, format: 'zip'), class: 'btn', rel: 'nofollow' do = icon('download fw') diff --git a/app/views/projects/activity.html.haml b/app/views/projects/activity.html.haml index 65674913bb0..5f6e5f3b644 100644 --- a/app/views/projects/activity.html.haml +++ b/app/views/projects/activity.html.haml @@ -1 +1,2 @@ +- page_title "Activity" = render 'projects/activity' diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml index 65c3ab10e02..b4c7d8b9b71 100644 --- a/app/views/projects/blob/_blob.html.haml +++ b/app/views/projects/blob/_blob.html.haml @@ -15,7 +15,7 @@ - else = 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) = render blob_commit, project: @project diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml index 50c0fd6803d..a849bf84698 100644 --- a/app/views/projects/commits/_head.html.haml +++ b/app/views/projects/commits/_head.html.haml @@ -1,10 +1,10 @@ %ul.center-top-menu = 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 %span.badge= number_with_delimiter(@repository.commit_count) = 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 = nav_link(html_options: {class: branches_tab_class}) do diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index e8e65d87f47..90dce739992 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -1,10 +1,11 @@ +- @blank_container = true + .project-edit-container .project-edit-errors .project-edit-content - %div - %h3.page-title + .panel.panel-default + .panel-heading Project settings - %hr .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| diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml index b7a2ed68e25..cd5f3a5d39e 100644 --- a/app/views/projects/forks/new.html.haml +++ b/app/views/projects/forks/new.html.haml @@ -10,21 +10,22 @@ - group.each do |namespace| .col-md-2.col-sm-3 - 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 - = image_tag namespace_icon(namespace, 200) + = image_tag namespace_icon(namespace, 100) .caption - %h4=namespace.human_name - %p - = namespace.path + %strong + = namespace.human_name + %div.text-primary + Already forked + - 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 - = image_tag namespace_icon(namespace, 200) + = image_tag namespace_icon(namespace, 100) .caption - %h4=namespace.human_name - %p - = namespace.path + %strong + = namespace.human_name %p.light Fork is a copy of a project repository. diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml index d44fe486212..284adb40e97 100644 --- a/app/views/projects/labels/index.html.haml +++ b/app/views/projects/labels/index.html.haml @@ -1,14 +1,15 @@ - 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 - New label -%h3.page-title - Labels -%hr + +.gray-content-block.top-block + - if can? current_user, :admin_label, @project + = link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do + New label + .oneline + Labels can be applied to issues and merge requests. .labels - if @labels.present? - %ul.bordered-list.manage-labels-list + %ul.content-list.manage-labels-list = render @labels = paginate @labels, theme: 'gitlab' - else diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml index 162583e4b1d..a40d1513671 100644 --- a/app/views/projects/project_members/index.html.haml +++ b/app/views/projects/project_members/index.html.haml @@ -1,30 +1,28 @@ - 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 %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 - if @group diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index d5c4ee71978..aa5914e3ed9 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -14,7 +14,7 @@ .project-stats.gray-content-block %ul.nav.nav-pills %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') %li = link_to namespace_project_branches_path(@project.namespace, @project) do diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 09327d645f3..1aa1e3c6c97 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -9,7 +9,7 @@ = f.label :title, class: 'control-label' do %strong= 'Title *' .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 - if issuable.is_a?(MergeRequest) diff --git a/app/views/snippets/_head.html.haml b/app/views/snippets/_head.html.haml deleted file mode 100644 index 0adf6b91f2c..00000000000 --- a/app/views/snippets/_head.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -%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 diff --git a/app/views/snippets/current_user_index.html.haml b/app/views/snippets/current_user_index.html.haml deleted file mode 100644 index d704407c4dd..00000000000 --- a/app/views/snippets/current_user_index.html.haml +++ /dev/null @@ -1,36 +0,0 @@ -- page_title "Your Snippets" -= render 'head' - -.gray-content-block - .pull-right - = link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do - Add new snippet - - .oneline - Share code pastes with others out of git repository - -%ul.nav.nav-tabs.prepend-top-20 - = nav_tab :scope, nil do - = link_to user_snippets_path(@user) do - All - %span.badge - = @user.snippets.count - = nav_tab :scope, 'are_private' do - = link_to user_snippets_path(@user, scope: 'are_private') do - Private - %span.badge - = @user.snippets.are_private.count - = nav_tab :scope, 'are_internal' do - = link_to user_snippets_path(@user, scope: 'are_internal') do - Internal - %span.badge - = @user.snippets.are_internal.count - = nav_tab :scope, 'are_public' do - = link_to user_snippets_path(@user, scope: 'are_public') do - Public - %span.badge - = @user.snippets.are_public.count - -.my-snippets - = render 'snippets' - diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml index 3b62dd2a6e1..7e4918a6085 100644 --- a/app/views/snippets/index.html.haml +++ b/app/views/snippets/index.html.haml @@ -1,15 +1,13 @@ -- page_title "Public Snippets" -- if current_user - = render '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 +- page_title "By #{@user.name}", "Snippets" + +%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' - diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index aed00f9caeb..97374e073dc 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -20,10 +20,10 @@ .back-link - if @snippet.author == current_user - = link_to user_snippets_path(current_user) do + = link_to dashboard_snippets_path do ← your snippets - else - = link_to snippets_path do + = link_to explore_snippets_path do ← explore snippets .file-holder diff --git a/app/views/snippets/user_index.html.haml b/app/views/snippets/user_index.html.haml deleted file mode 100644 index 7af5352da34..00000000000 --- a/app/views/snippets/user_index.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -- 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' diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb new file mode 100644 index 00000000000..acd1c43f06b --- /dev/null +++ b/app/workers/repository_fork_worker.rb @@ -0,0 +1,34 @@ +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 diff --git a/config/initializers/rouge_diff_lexer.rb b/config/initializers/rouge_diff_lexer.rb deleted file mode 100644 index fdb2d7b748e..00000000000 --- a/config/initializers/rouge_diff_lexer.rb +++ /dev/null @@ -1,24 +0,0 @@ -# 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 diff --git a/config/routes.rb b/config/routes.rb index 011af4825fa..fad6b3c569a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -143,6 +143,7 @@ Gitlab::Application.routes.draw do end resources :groups, only: [:index] + resources :snippets, only: [:index] root to: 'projects#trending' end @@ -263,24 +264,25 @@ Gitlab::Application.routes.draw do # # Dashboard Area # - resource :dashboard, controller: 'dashboard', only: [:show] do - member do - get :issues - get :merge_requests - get :activity - end + resource :dashboard, controller: 'dashboard', only: [] do + get :issues + get :merge_requests + get :activity scope module: :dashboard do resources :milestones, only: [:index, :show] resources :groups, only: [:index] + resources :snippets, only: [:index] - resources :projects, only: [] do + resources :projects, only: [:index] do collection do get :starred end end end + + root to: "dashboard/projects#index" end # @@ -304,7 +306,7 @@ Gitlab::Application.routes.draw do 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 } @@ -312,7 +314,7 @@ Gitlab::Application.routes.draw do get '/users/auth/:provider/omniauth_error' => 'omniauth_callbacks#omniauth_error', as: :omniauth_error end - root to: "root#show" + root to: "root#index" # # Project Area diff --git a/doc/api/services.md b/doc/api/services.md index bc5049dd302..7d45b2cf463 100644 --- a/doc/api/services.md +++ b/doc/api/services.md @@ -27,6 +27,14 @@ Delete Asana service for a project. DELETE /projects/:id/services/asana ``` +### Get Asana service settings + +Get Asana service settings for a project. + +``` +GET /projects/:id/services/asana +``` + ## Assembla Project Management Software (Source Commits Endpoint) @@ -52,6 +60,14 @@ Delete Assembla service for a project. DELETE /projects/:id/services/assembla ``` +### Get Assembla service settings + +Get Assembla service settings for a project. + +``` +GET /projects/:id/services/assembla +``` + ## Atlassian Bamboo CI A continuous integration and build server @@ -81,6 +97,14 @@ Delete Atlassian Bamboo CI service for a project. 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 Continuous integration and deployments @@ -107,6 +131,14 @@ Delete Buildkite service for a project. DELETE /projects/:id/services/buildkite ``` +### Get Buildkite service settings + +Get Buildkite service settings for a project. + +``` +GET /projects/:id/services/buildkite +``` + ## Campfire Simple web-based real-time group chat @@ -133,6 +165,14 @@ Delete Campfire service for a project. 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 @@ -161,6 +201,14 @@ Delete Custom Issue Tracker service for a project. 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 is a Continuous Integration platform built on Docker, written in Go @@ -187,6 +235,14 @@ Delete Drone CI service for a project. 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 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. 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 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. 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 is a collaboration web app for technical teams. @@ -261,6 +333,14 @@ Delete Flowdock service for a project. DELETE /projects/:id/services/flowdock ``` +### Get Flowdock service settings + +Get Flowdock service settings for a project. + +``` +GET /projects/:id/services/flowdock +``` + ## Gemnasium Gemnasium monitors your project dependencies and alerts you about updates and security vulnerabilities. @@ -286,6 +366,14 @@ Delete Gemnasium service for a project. DELETE /projects/:id/services/gemnasium ``` +### Get Gemnasium service settings + +Get Gemnasium service settings for a project. + +``` +GET /projects/:id/services/gemnasium +``` + ## GitLab CI Continuous integration server from GitLab @@ -312,6 +400,14 @@ Delete GitLab CI service for a project. 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 Private group chat and IM @@ -341,6 +437,14 @@ Delete HipChat service for a project. DELETE /projects/:id/services/hipchat ``` +### Get HipChat service settings + +Get HipChat service settings for a project. + +``` +GET /projects/:id/services/hipchat +``` + ## Irker (IRC 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. 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 issue tracker @@ -400,6 +512,14 @@ Delete JIRA service for a project. DELETE /projects/:id/services/jira ``` +### Get JIRA service settings + +Get JIRA service settings for a project. + +``` +GET /projects/:id/services/jira +``` + ## PivotalTracker Project Management Software (Source Commits Endpoint) @@ -424,6 +544,14 @@ Delete PivotalTracker service for a project. DELETE /projects/:id/services/pivotaltracker ``` +### Get PivotalTracker service settings + +Get PivotalTracker service settings for a project. + +``` +GET /projects/:id/services/pivotaltracker +``` + ## Pushover 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. DELETE /projects/:id/services/pushover ``` +### Get Pushover service settings + +Get Pushover service settings for a project. + +``` +GET /projects/:id/services/pushover +``` + ## Redmine Redmine issue tracker @@ -479,6 +615,14 @@ Delete Redmine service for a project. DELETE /projects/:id/services/redmine ``` +### Get Redmine service settings + +Get Redmine service settings for a project. + +``` +GET /projects/:id/services/redmine +``` + ## Slack A team communication tool for the 21st century @@ -505,6 +649,14 @@ Delete Slack service for a project. DELETE /projects/:id/services/slack ``` +### Get Slack service settings + +Get Slack service settings for a project. + +``` +GET /projects/:id/services/slack +``` + ## JetBrains TeamCity CI A continuous integration and build server @@ -534,3 +686,11 @@ Delete JetBrains TeamCity CI service for a project. 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 +``` + diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md index 6a68c8e8286..4ff5e74d438 100644 --- a/doc/raketasks/backup_restore.md +++ b/doc/raketasks/backup_restore.md @@ -369,4 +369,7 @@ For more information see similar questions on postgresql issue tracker[here](htt ## Note 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. diff --git a/doc/update/6.x-or-7.x-to-7.14.md b/doc/update/6.x-or-7.x-to-7.14.md index 5bc1f84270a..b34fb12da6f 100644 --- a/doc/update/6.x-or-7.x-to-7.14.md +++ b/doc/update/6.x-or-7.x-to-7.14.md @@ -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: ``` -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. diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md index 22b9be059d6..a66a863f6c4 100644 --- a/doc/update/patch_versions.md +++ b/doc/update/patch_versions.md @@ -1,7 +1,7 @@ # 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.* -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 @@ -23,17 +23,16 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production cd /home/git/gitlab sudo -u git -H git fetch --all 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 ```bash cd /home/git/gitlab-shell 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. diff --git a/features/explore/groups.feature b/features/explore/groups.feature index c11634bd74a..a42e59c98f2 100644 --- a/features/explore/groups.feature +++ b/features/explore/groups.feature @@ -3,20 +3,6 @@ Feature: Explore Groups Background: 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 Given group "TestGroup" has internal project "Internal" When I sign in as a user diff --git a/features/groups.feature b/features/groups.feature index d5272fdddcf..db37fa3b375 100644 --- a/features/groups.feature +++ b/features/groups.feature @@ -159,3 +159,14 @@ Feature: Groups When I visit group "Owned" projects page Then I should see group "Owned" projects list 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" + diff --git a/features/steps/admin/users.rb b/features/steps/admin/users.rb index 2e17d5c4c2e..4bc290b6bdf 100644 --- a/features/steps/admin/users.rb +++ b/features/steps/admin/users.rb @@ -4,11 +4,13 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps include SharedAdmin 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 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 step 'I should see all users' do diff --git a/features/steps/groups.rb b/features/steps/groups.rb index 18a1c4d32ce..95bc9baf8d8 100644 --- a/features/steps/groups.rb +++ b/features/steps/groups.rb @@ -6,7 +6,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps include Select2Helper 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 step 'gitlab user "Mike"' do @@ -17,6 +17,26 @@ class Spinach::Features::Groups < Spinach::FeatureSteps find(:css, 'button.btn-new').click 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 user = User.find_by(name: "Mike") diff --git a/features/steps/invites.rb b/features/steps/invites.rb index 5e8feff5095..dac972172aa 100644 --- a/features/steps/invites.rb +++ b/features/steps/invites.rb @@ -63,7 +63,7 @@ class Spinach::Features::Invites < Spinach::FeatureSteps end 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 step 'I should see a notice telling me I have declined' do diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb index 0e433781d7a..370960845cc 100644 --- a/features/steps/project/fork.rb +++ b/features/steps/project/fork.rb @@ -15,7 +15,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps end 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 step 'I already have a project named "Shop" in my namespace' do diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index 390a0ba9703..15f77734cb2 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -124,11 +124,11 @@ class Spinach::Features::Project < Spinach::FeatureSteps end 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 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 step 'I click notifications drop down button' do diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index b4deccb6520..eb978620da6 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -68,7 +68,7 @@ module SharedPaths # ---------------------------------------- step 'I visit dashboard page' do - visit dashboard_path + visit dashboard_projects_path end step 'I visit dashboard activity page' do @@ -460,7 +460,7 @@ module SharedPaths end step 'I visit snippets page' do - visit snippets_path + visit explore_snippets_path end step 'I visit new snippet page' do diff --git a/features/steps/snippets/user.rb b/features/steps/snippets/user.rb index 007fcb2893f..dea3256229f 100644 --- a/features/steps/snippets/user.rb +++ b/features/steps/snippets/user.rb @@ -4,7 +4,7 @@ class Spinach::Features::SnippetsUser < Spinach::FeatureSteps include SharedSnippet step 'I visit my snippets page' do - visit user_snippets_path(current_user) + visit dashboard_snippets_path end step 'I should see "Personal snippet one" in snippets' do diff --git a/lib/api/services.rb b/lib/api/services.rb index 73645cedea4..d170b3067ed 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -49,6 +49,16 @@ module API 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 diff --git a/lib/gitlab/markdown/sanitization_filter.rb b/lib/gitlab/markdown/sanitization_filter.rb index 68ed57f6257..e368de7d848 100644 --- a/lib/gitlab/markdown/sanitization_filter.rb +++ b/lib/gitlab/markdown/sanitization_filter.rb @@ -67,12 +67,16 @@ module Gitlab def clean_spans lambda do |env| - return unless env[:node_name] == 'span' - return unless env[:node].has_attribute?('class') + node = env[:node] - unless has_ancestor?(env[:node], 'pre') - env[:node].remove_attribute('class') + return unless node.name == 'span' + return unless node.has_attribute?('class') + + unless has_ancestor?(node, 'pre') + node.remove_attribute('class') end + + { node_whitelist: [node] } end end end diff --git a/lib/gitlab/markdown/syntax_highlight_filter.rb b/lib/gitlab/markdown/syntax_highlight_filter.rb index 86f4385753a..8597e02f0de 100644 --- a/lib/gitlab/markdown/syntax_highlight_filter.rb +++ b/lib/gitlab/markdown/syntax_highlight_filter.rb @@ -21,7 +21,13 @@ module Gitlab language = node.attr('class') 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 node.parent.replace(highlighted) diff --git a/lib/tasks/services.rake b/lib/tasks/services.rake index 3f276a5e12e..39541c0b9c6 100644 --- a/lib/tasks/services.rake +++ b/lib/tasks/services.rake @@ -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 %> ERB diff --git a/spec/controllers/namespaces_controller_spec.rb b/spec/controllers/namespaces_controller_spec.rb index 9c8619722cd..77436958711 100644 --- a/spec/controllers/namespaces_controller_spec.rb +++ b/spec/controllers/namespaces_controller_spec.rb @@ -46,13 +46,11 @@ describe NamespacesController 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 + it "does not redirect to the sign in page" do get :show, id: group.path - - expect(response).to redirect_to(new_user_session_path) + expect(response).not_to redirect_to(new_user_session_path) end end - context "when signed in" do before do sign_in(user) @@ -86,10 +84,10 @@ describe NamespacesController do end 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 - expect(response.status).to eq(404) + expect(response).to redirect_to(group_path(group)) end end end diff --git a/spec/controllers/root_controller_spec.rb b/spec/controllers/root_controller_spec.rb index abbbf6855fc..64dfe8f34e3 100644 --- a/spec/controllers/root_controller_spec.rb +++ b/spec/controllers/root_controller_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe RootController do - describe 'GET show' do + describe 'GET index' do context 'with a user' do let(:user) { create(:user) } @@ -16,15 +16,15 @@ describe RootController do end it 'redirects to their specified dashboard' do - get :show + get :index expect(response).to redirect_to starred_dashboard_projects_path end end context 'who uses the default dashboard setting' do it 'renders the default dashboard' do - get :show - expect(response).to render_template 'dashboard/show' + get :index + expect(response).to render_template 'dashboard/projects/index' end end end diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb index 0f9780356b1..af5d043cf02 100644 --- a/spec/controllers/uploads_controller_spec.rb +++ b/spec/controllers/uploads_controller_spec.rb @@ -156,14 +156,6 @@ describe UploadsController do end 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 before do sign_in(user) diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb index ad157d742ff..f81a3c117ff 100644 --- a/spec/features/atom/dashboard_spec.rb +++ b/spec/features/atom/dashboard_spec.rb @@ -6,7 +6,7 @@ describe "Dashboard Feed", feature: true do context "projects atom feed via private token" 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') end end @@ -20,7 +20,7 @@ describe "Dashboard Feed", feature: true do project.team << [user, :master] issue_event(issue, 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 it "should have issue opened event" do diff --git a/spec/features/profiles/preferences_spec.rb b/spec/features/profiles/preferences_spec.rb index 9bc6145dda4..8f645438cff 100644 --- a/spec/features/profiles/preferences_spec.rb +++ b/spec/features/profiles/preferences_spec.rb @@ -70,7 +70,7 @@ describe 'Profile > Preferences', feature: true do expect(page.current_path).to eq starred_dashboard_projects_path click_link 'Your Projects' - expect(page.current_path).to eq dashboard_path + expect(page.current_path).to eq dashboard_projects_path end end diff --git a/spec/features/security/dashboard_access_spec.rb b/spec/features/security/dashboard_access_spec.rb index c38cddbb904..788581a26cb 100644 --- a/spec/features/security/dashboard_access_spec.rb +++ b/spec/features/security/dashboard_access_spec.rb @@ -4,7 +4,7 @@ describe "Dashboard access", feature: true do include AccessMatchers 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 :user } @@ -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 :user } - it { is_expected.to be_denied_for :visitor } + it { is_expected.to be_allowed_for :visitor } end describe "GET /projects/new" do diff --git a/spec/features/security/group_access_spec.rb b/spec/features/security/group_access_spec.rb index 8ce15388605..4b78e3a61f0 100644 --- a/spec/features/security/group_access_spec.rb +++ b/spec/features/security/group_access_spec.rb @@ -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 :admin } 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 context 'with no projects' 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(:guest) } it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } + it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :visitor } end end diff --git a/spec/javascripts/syntax_highlight_spec.js.coffee b/spec/javascripts/syntax_highlight_spec.js.coffee new file mode 100644 index 00000000000..6a73b6bf32c --- /dev/null +++ b/spec/javascripts/syntax_highlight_spec.js.coffee @@ -0,0 +1,42 @@ +#= 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() diff --git a/spec/lib/gitlab/markdown/syntax_highlight_filter_spec.rb b/spec/lib/gitlab/markdown/syntax_highlight_filter_spec.rb new file mode 100644 index 00000000000..6a490673728 --- /dev/null +++ b/spec/lib/gitlab/markdown/syntax_highlight_filter_spec.rb @@ -0,0 +1,19 @@ +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 diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb index c297904614a..fb3b235446f 100644 --- a/spec/requests/api/services_spec.rb +++ b/spec/requests/api/services_spec.rb @@ -47,5 +47,15 @@ describe API::API, api: true do expect(project.send(service_method).activated?).to be_falsey 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 diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb index dd045826692..dfa18f69e05 100644 --- a/spec/routing/routing_spec.rb +++ b/spec/routing/routing_spec.rb @@ -206,7 +206,7 @@ end # dashboard_merge_requests GET /dashboard/merge_requests(.:format) dashboard#merge_requests describe DashboardController, "routing" do it "to #index" do - expect(get("/dashboard")).to route_to('dashboard#show') + expect(get("/dashboard")).to route_to('dashboard/projects#index') end it "to #issues" do @@ -220,8 +220,8 @@ end # root / root#show describe RootController, 'routing' do - it 'to #show' do - expect(get('/')).to route_to('root#show') + it 'to #index' do + expect(get('/')).to route_to('root#index') end end diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index ff4ed2dd484..25277f07482 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -96,6 +96,17 @@ describe Projects::CreateService do expect(project.saved?).to be(true) 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 def create_project(user, opts) diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb index c04e842c67e..7c4bb74b77f 100644 --- a/spec/services/projects/fork_service_spec.rb +++ b/spec/services/projects/fork_service_spec.rb @@ -28,8 +28,7 @@ describe Projects::ForkService do context 'fork project failure' do it "fails due to transaction failure" do @to_project = fork_project(@from_project, @to_user, false) - expect(@to_project.errors).not_to be_empty - expect(@to_project.errors[:base]).to include("Failed to fork repository via gitlab-shell") + expect(@to_project.import_failed?) end end @@ -100,7 +99,7 @@ describe Projects::ForkService do end 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 end end diff --git a/spec/workers/repository_fork_worker_spec.rb b/spec/workers/repository_fork_worker_spec.rb new file mode 100644 index 00000000000..aa031106968 --- /dev/null +++ b/spec/workers/repository_fork_worker_spec.rb @@ -0,0 +1,29 @@ +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 |