Commit 2c8d5aea authored by Douwe Maan's avatar Douwe Maan

Merge branch 'master' into reply-by-email-docs

parents 58c487e2 e0da2c35
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
v 8.0.0 (unreleased) v 8.0.0 (unreleased)
- Fix Error 500 in API when accessing a group that has an avatar (Stan Hu) - Fix URL construction for merge requests, issues, notes, and commits for relative URL config (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)
- 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)
- Remove user OAuth tokens from the database and request new tokens each session (Stan Hu) - Remove user OAuth tokens from the database and request new tokens each session (Stan Hu)
- Only show recent push event if the branch still exists or a recent merge request has not been created (Stan Hu) - Only show recent push event if the branch still exists or a recent merge request has not been created (Stan Hu)
- Remove satellites - Remove satellites
...@@ -13,6 +22,31 @@ v 8.0.0 (unreleased) ...@@ -13,6 +22,31 @@ v 8.0.0 (unreleased)
- Search for comments should be case insensetive - Search for comments should be case insensetive
- Create cross-reference for closing references on commits pushed to non-default branches (Maël Valais) - Create cross-reference for closing references on commits pushed to non-default branches (Maël Valais)
- Ability to search milestones - Ability to search milestones
- Gracefully handle SMTP user input errors (e.g. incorrect email addresses) to prevent Sidekiq retries (Stan Hu)
- Move dashboard activity to separate page (for your projects and starred projects)
- Improve performance of git blame
- Limit content width to 1200px for most of pages to improve readability on big screens
- 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
- 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)
- 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
- Add support for Crowd
v 7.14.1
- Improve abuse reports management from admin area
- Fix "Reload with full diff" URL button in compare branch view (Stan Hu)
- Only include base URL in OmniAuth full_host parameter (Stan Hu)
- Fix Error 500 in API when accessing a group that has an avatar (Stan Hu)
- Ability to enable SSL verification for Webhooks
v 7.14.0 v 7.14.0
- Fix bug where non-project members of the target project could set labels on new merge requests. - Fix bug where non-project members of the target project could set labels on new merge requests.
...@@ -298,6 +332,7 @@ v 7.11.0 ...@@ -298,6 +332,7 @@ v 7.11.0
- Protect OmniAuth request phase against CSRF. - Protect OmniAuth request phase against CSRF.
- Don't send notifications to mentioned users that don't have access to the project in question. - Don't send notifications to mentioned users that don't have access to the project in question.
- Add search issues/MR by number - Add search issues/MR by number
- Change plots to bar graphs in commit statistics screen
- Move snippets UI to fluid layout - Move snippets UI to fluid layout
- Improve UI for sidebar. Increase separation between navigation and content - Improve UI for sidebar. Increase separation between navigation and content
- Improve new project command options (Ben Bodenmiller) - Improve new project command options (Ben Bodenmiller)
......
...@@ -25,6 +25,7 @@ gem 'omniauth-kerberos', group: :kerberos ...@@ -25,6 +25,7 @@ gem 'omniauth-kerberos', group: :kerberos
gem 'omniauth-gitlab' gem 'omniauth-gitlab'
gem 'omniauth-bitbucket' gem 'omniauth-bitbucket'
gem 'omniauth-saml', '~> 1.4.0' gem 'omniauth-saml', '~> 1.4.0'
gem 'omniauth_crowd'
gem 'doorkeeper', '2.1.3' gem 'doorkeeper', '2.1.3'
gem "rack-oauth2", "~> 1.0.5" gem "rack-oauth2", "~> 1.0.5"
...@@ -34,16 +35,11 @@ gem 'rqrcode-rails3' ...@@ -34,16 +35,11 @@ gem 'rqrcode-rails3'
gem 'attr_encrypted', '1.3.4' gem 'attr_encrypted', '1.3.4'
# Browser detection # Browser detection
gem "browser", '~> 0.8.0' gem "browser", '~> 1.0.0'
# Extracting information from a git repository # Extracting information from a git repository
# Provide access to Gitlab::Git library # Provide access to Gitlab::Git library
gem "gitlab_git", '~> 7.2.14' gem "gitlab_git", '~> 7.2.15'
# Ruby/Rack Git Smart-HTTP Server Handler
# GitLab fork with a lot of changes (improved thread-safety, better memory usage etc)
# For full list of changes see https://github.com/SaitoWu/grack/compare/master...gitlabhq:master
gem 'gitlab-grack', '~> 2.0.2', require: 'grack'
# LDAP Auth # LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes # GitLab fork with several improvements to original library. For full list of changes
...@@ -273,6 +269,6 @@ gem "newrelic_rpm" ...@@ -273,6 +269,6 @@ gem "newrelic_rpm"
gem 'octokit', '3.7.0' gem 'octokit', '3.7.0'
gem "mail_room", "~> 0.4.0" gem "mail_room", "~> 0.4.2"
gem 'email_reply_parser' gem 'email_reply_parser'
...@@ -76,7 +76,7 @@ GEM ...@@ -76,7 +76,7 @@ GEM
ruby_parser (~> 3.5.0) ruby_parser (~> 3.5.0)
sass (~> 3.0) sass (~> 3.0)
terminal-table (~> 1.4) terminal-table (~> 1.4)
browser (0.8.0) browser (1.0.0)
builder (3.2.2) builder (3.2.2)
byebug (3.2.0) byebug (3.2.0)
columnize (~> 0.8) columnize (~> 0.8)
...@@ -263,8 +263,6 @@ GEM ...@@ -263,8 +263,6 @@ GEM
flowdock (~> 0.7) flowdock (~> 0.7)
gitlab-grit (>= 2.4.1) gitlab-grit (>= 2.4.1)
multi_json multi_json
gitlab-grack (2.0.2)
rack (~> 1.5.1)
gitlab-grit (2.7.2) gitlab-grit (2.7.2)
charlock_holmes (~> 0.6) charlock_holmes (~> 0.6)
diff-lcs (~> 1.1) diff-lcs (~> 1.1)
...@@ -276,7 +274,7 @@ GEM ...@@ -276,7 +274,7 @@ GEM
mime-types (~> 1.19) mime-types (~> 1.19)
gitlab_emoji (0.1.0) gitlab_emoji (0.1.0)
gemojione (~> 2.0) gemojione (~> 2.0)
gitlab_git (7.2.14) gitlab_git (7.2.15)
activesupport (~> 4.0) activesupport (~> 4.0)
charlock_holmes (~> 0.6) charlock_holmes (~> 0.6)
gitlab-linguist (~> 3.0) gitlab-linguist (~> 3.0)
...@@ -372,7 +370,7 @@ GEM ...@@ -372,7 +370,7 @@ GEM
systemu (~> 2.6.2) systemu (~> 2.6.2)
mail (2.6.3) mail (2.6.3)
mime-types (>= 1.16, < 3) mime-types (>= 1.16, < 3)
mail_room (0.4.0) mail_room (0.4.2)
method_source (0.8.2) method_source (0.8.2)
mime-types (1.25.1) mime-types (1.25.1)
mimemagic (0.3.0) mimemagic (0.3.0)
...@@ -436,6 +434,10 @@ GEM ...@@ -436,6 +434,10 @@ GEM
omniauth-twitter (1.0.1) omniauth-twitter (1.0.1)
multi_json (~> 1.3) multi_json (~> 1.3)
omniauth-oauth (~> 1.0) omniauth-oauth (~> 1.0)
omniauth_crowd (2.2.3)
activesupport
nokogiri (>= 1.4.4)
omniauth (~> 1.0)
opennebula (4.12.1) opennebula (4.12.1)
json json
nokogiri nokogiri
...@@ -462,7 +464,7 @@ GEM ...@@ -462,7 +464,7 @@ GEM
pyu-ruby-sasl (0.0.3.3) pyu-ruby-sasl (0.0.3.3)
quiet_assets (1.0.2) quiet_assets (1.0.2)
railties (>= 3.1, < 5.0) railties (>= 3.1, < 5.0)
racc (1.4.10) racc (1.4.12)
rack (1.5.5) rack (1.5.5)
rack-accept (0.4.5) rack-accept (0.4.5)
rack (>= 0.4) rack (>= 0.4)
...@@ -755,7 +757,7 @@ DEPENDENCIES ...@@ -755,7 +757,7 @@ DEPENDENCIES
binding_of_caller binding_of_caller
bootstrap-sass (~> 3.0) bootstrap-sass (~> 3.0)
brakeman brakeman
browser (~> 0.8.0) browser (~> 1.0.0)
byebug byebug
cal-heatmap-rails (~> 0.0.1) cal-heatmap-rails (~> 0.0.1)
capybara (~> 2.4.0) capybara (~> 2.4.0)
...@@ -787,10 +789,9 @@ DEPENDENCIES ...@@ -787,10 +789,9 @@ DEPENDENCIES
gemnasium-gitlab-service (~> 0.2) gemnasium-gitlab-service (~> 0.2)
github-markup github-markup
gitlab-flowdock-git-hook (~> 1.0.1) gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-grack (~> 2.0.2)
gitlab-linguist (~> 3.0.1) gitlab-linguist (~> 3.0.1)
gitlab_emoji (~> 0.1) gitlab_emoji (~> 0.1)
gitlab_git (~> 7.2.14) gitlab_git (~> 7.2.15)
gitlab_meta (= 7.0) gitlab_meta (= 7.0)
gitlab_omniauth-ldap (= 1.2.1) gitlab_omniauth-ldap (= 1.2.1)
gollum-lib (~> 4.0.2) gollum-lib (~> 4.0.2)
...@@ -808,7 +809,7 @@ DEPENDENCIES ...@@ -808,7 +809,7 @@ DEPENDENCIES
jquery-ui-rails jquery-ui-rails
kaminari (~> 0.15.1) kaminari (~> 0.15.1)
letter_opener letter_opener
mail_room (~> 0.4.0) mail_room (~> 0.4.2)
minitest (~> 5.3.0) minitest (~> 5.3.0)
mousetrap-rails mousetrap-rails
mysql2 mysql2
...@@ -824,6 +825,7 @@ DEPENDENCIES ...@@ -824,6 +825,7 @@ DEPENDENCIES
omniauth-saml (~> 1.4.0) omniauth-saml (~> 1.4.0)
omniauth-shibboleth omniauth-shibboleth
omniauth-twitter omniauth-twitter
omniauth_crowd
org-ruby (= 0.9.12) org-ruby (= 0.9.12)
pg pg
poltergeist (~> 1.6.0) poltergeist (~> 1.6.0)
...@@ -883,4 +885,4 @@ DEPENDENCIES ...@@ -883,4 +885,4 @@ DEPENDENCIES
wikicloth (= 0.8.1) wikicloth (= 0.8.1)
BUNDLED WITH BUNDLED WITH
1.10.6 1.10.5
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
class @Activities class @Activities
constructor: -> constructor: ->
Pager.init 20, true Pager.init 20, true
$(".event_filter_link").bind "click", (event) => $(".event-filter .btn").bind "click", (event) =>
event.preventDefault() event.preventDefault()
@toggleFilter($(event.currentTarget)) @toggleFilter($(event.currentTarget))
@reloadActivities() @reloadActivities()
...@@ -12,7 +12,7 @@ class @Activities ...@@ -12,7 +12,7 @@ class @Activities
toggleFilter: (sender) -> toggleFilter: (sender) ->
sender.parent().toggleClass "active" sender.toggleClass "active"
event_filters = $.cookie("event_filter") event_filters = $.cookie("event_filter")
filter = sender.attr("id").split("_")[0] filter = sender.attr("id").split("_")[0]
if event_filters if event_filters
......
...@@ -94,16 +94,18 @@ window.unbindEvents = -> ...@@ -94,16 +94,18 @@ window.unbindEvents = ->
$(document).off('scroll') $(document).off('scroll')
window.shiftWindow = -> window.shiftWindow = ->
scrollBy 0, -50 scrollBy 0, -100
document.addEventListener("page:fetch", unbindEvents) document.addEventListener("page:fetch", unbindEvents)
# Scroll the window to avoid the topnav bar
# https://github.com/twitter/bootstrap/issues/1768
if location.hash
setTimeout shiftWindow, 1
window.addEventListener "hashchange", shiftWindow window.addEventListener "hashchange", shiftWindow
window.onload = ->
# Scroll the window to avoid the topnav bar
# https://github.com/twitter/bootstrap/issues/1768
if location.hash
setTimeout shiftWindow, 100
$ -> $ ->
$(".nicescroll").niceScroll(cursoropacitymax: '0.4', cursorcolor: '#FFF', cursorborder: "1px solid #FFF") $(".nicescroll").niceScroll(cursoropacitymax: '0.4', cursorcolor: '#FFF', cursorborder: "1px solid #FFF")
...@@ -116,6 +118,12 @@ $ -> ...@@ -116,6 +118,12 @@ $ ->
$('.remove-row').bind 'ajax:success', -> $('.remove-row').bind 'ajax:success', ->
$(this).closest('li').fadeOut() $(this).closest('li').fadeOut()
$('.js-remove-tr').bind 'ajax:before', ->
$(this).hide()
$('.js-remove-tr').bind 'ajax:success', ->
$(this).closest('tr').fadeOut()
# Initialize select2 selects # Initialize select2 selects
$('select.select2').select2(width: 'resolve', dropdownAutoWidth: true) $('select.select2').select2(width: 'resolve', dropdownAutoWidth: true)
......
...@@ -51,10 +51,10 @@ class Dispatcher ...@@ -51,10 +51,10 @@ class Dispatcher
MergeRequests.init() MergeRequests.init()
when 'dashboard:show', 'root:show' when 'dashboard:show', 'root:show'
new Dashboard() new Dashboard()
when 'dashboard:activity'
new Activities() new Activities()
when 'dashboard:projects:starred' when 'dashboard:projects:starred'
new Activities() new Activities()
new ProjectsList()
when 'projects:commit:show' when 'projects:commit:show'
new Commit() new Commit()
new Diff() new Diff()
...@@ -69,7 +69,6 @@ class Dispatcher ...@@ -69,7 +69,6 @@ class Dispatcher
when 'groups:show' when 'groups:show'
new Activities() new Activities()
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
new ProjectsList()
when 'groups:group_members:index' when 'groups:group_members:index'
new GroupMembers() new GroupMembers()
new UsersSelect() new UsersSelect()
...@@ -95,8 +94,6 @@ class Dispatcher ...@@ -95,8 +94,6 @@ class Dispatcher
when 'users:show' when 'users:show'
new User() new User()
new Activities() new Activities()
when 'admin:users:show'
new ProjectsList()
switch path.first() switch path.first()
when 'admin' when 'admin'
......
...@@ -123,6 +123,7 @@ class @Notes ...@@ -123,6 +123,7 @@ class @Notes
if @isNewNote(note) if @isNewNote(note)
@note_ids.push(note.id) @note_ids.push(note.id)
$('ul.main-notes-list').append(note.html) $('ul.main-notes-list').append(note.html)
$('.js-syntax-highlight').syntaxHighlight()
@initTaskList() @initTaskList()
### ###
......
...@@ -8,7 +8,7 @@ class @ProjectsList ...@@ -8,7 +8,7 @@ class @ProjectsList
$(".projects-list-filter").keyup -> $(".projects-list-filter").keyup ->
terms = $(this).val() terms = $(this).val()
uiBox = $(this).closest('.panel') uiBox = $(this).closest('.projects-list-holder')
if terms == "" || terms == undefined if terms == "" || terms == undefined
uiBox.find(".projects-list li").show() uiBox.find(".projects-list li").show()
else else
......
# Applies a syntax highlighting color scheme CSS class to any element with the
# `js-syntax-highlight` class
#
# ### Example Markup
#
# <div class="js-syntax-highlight"></div>
#
$.fn.syntaxHighlight = ->
$(this).addClass(gon.user_color_scheme)
$(document).on 'ready page:load', ->
$('.js-syntax-highlight').syntaxHighlight()
...@@ -38,6 +38,8 @@ class @ZenMode ...@@ -38,6 +38,8 @@ class @ZenMode
@active_checkbox = $(checkbox) @active_checkbox = $(checkbox)
@active_checkbox.prop('checked', true) @active_checkbox.prop('checked', true)
@active_zen_area = @active_checkbox.parent().find('textarea') @active_zen_area = @active_checkbox.parent().find('textarea')
# Prevent a user-resized textarea from persisting to fullscreen
@active_zen_area.removeAttr('style')
@active_zen_area.focus() @active_zen_area.focus()
exitZenMode: => exitZenMode: =>
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
*/ */
@import "base/fonts";
@import "base/variables"; @import "base/variables";
@import "base/mixins"; @import "base/mixins";
@import "base/layout"; @import "base/layout";
......
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 300;
src: local('Source Sans Pro Light'), local('SourceSansPro-Light'), font-url('SourceSansPro-Light.ttf');
}
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro'), local('SourceSansPro-Regular'), font-url('SourceSansPro-Regular.ttf');
}
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), font-url('SourceSansPro-Semibold.ttf');
}
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), font-url('SourceSansPro-Bold.ttf');
}
...@@ -42,17 +42,18 @@ $font-size-base: $gl-font-size; ...@@ -42,17 +42,18 @@ $font-size-base: $gl-font-size;
// //
//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start). //## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
$padding-base-vertical: 6px; $padding-base-vertical: 9px;
$padding-base-horizontal: 14px; $padding-base-horizontal: $gl-padding;
$component-active-color: #fff;
$component-active-bg: $brand-info;
//== Forms //== Forms
// //
//## //##
$input-color: $text-color; $input-color: $text-color;
$input-border: #DDD; $input-border: #e7e9ed;
$input-border-focus: $brand-info; $input-border-focus: #7F8FA4;
$legend-color: $text-color; $legend-color: $text-color;
...@@ -111,8 +112,8 @@ $alert-border-radius: 0; ...@@ -111,8 +112,8 @@ $alert-border-radius: 0;
$panel-border-radius: 0; $panel-border-radius: 0;
$panel-default-text: $text-color; $panel-default-text: $text-color;
$panel-default-border: $border-color; $panel-default-border: #E7E9ED;
$panel-default-heading-bg: $background-color; $panel-default-heading-bg: #F8FAFC;
//== Wells //== Wells
...@@ -131,3 +132,15 @@ $code-bg: #f9f2f4; ...@@ -131,3 +132,15 @@ $code-bg: #f9f2f4;
$kbd-color: #fff; $kbd-color: #fff;
$kbd-bg: #333; $kbd-bg: #333;
//== Buttons
//
//##
$btn-default-color: $gl-text-color;
$btn-default-bg: #fff;
$btn-default-border: #e7e9ed;
//== Nav
//
//##
$nav-link-padding: 13px $gl-padding;
...@@ -20,3 +20,7 @@ html { ...@@ -20,3 +20,7 @@ html {
.navless-container { .navless-container {
margin-top: 30px; margin-top: 30px;
} }
.container-limited {
max-width: $fixed-layout-width;
}
...@@ -55,8 +55,11 @@ ...@@ -55,8 +55,11 @@
} }
@mixin md-typography { @mixin md-typography {
font-size: 15px; color: #444;
line-height: 1.5;
a {
color: #3084bb;
}
img { img {
max-width: 100%; max-width: 100%;
...@@ -157,3 +160,58 @@ ...@@ -157,3 +160,58 @@
white-space: nowrap; white-space: nowrap;
max-width: $max_width; max-width: $max_width;
} }
/*
* Base mixin for lists in GitLab
*/
@mixin basic-list {
margin: 5px 0px;
padding: 0px;
list-style: none;
> li {
padding: 10px 0;
border-bottom: 1px solid #EEE;
overflow: hidden;
display: block;
margin: 0px;
&:last-child {
border:none
}
&.active {
background: #f9f9f9;
a {
font-weight: bold;
}
}
&.hide {
display: none;
}
&.light {
a {
color: $gl-gray;
}
}
}
}
@mixin input-big {
height: 36px;
padding: 5px 10px;
font-size: 16px;
line-height: 24px;
color: #7f8fa4;
background-color: #fff;
border-color: #e7e9ed;
}
@mixin btn-big {
height: 36px;
padding: 5px 10px;
font-size: 16px;
line-height: 24px;
}
$style_color: #474D57;
$hover: #FFFAF1; $hover: #FFFAF1;
$gl-text-color: #222222; $gl-text-color: #54565b;
$gl-link-color: #446e9b; $gl-header-color: #4c4e54;
$gl-link-color: #333c48;
$nprogress-color: #c0392b; $nprogress-color: #c0392b;
$gl-font-size: 14px; $gl-font-size: 15px;
$list-font-size: 15px; $list-font-size: 15px;
$sidebar_collapsed_width: 52px; $sidebar_collapsed_width: 62px;
$sidebar_width: 230px; $sidebar_width: 230px;
$avatar_radius: 50%; $avatar_radius: 50%;
$code_font_size: 13px; $code_font_size: 13px;
$code_line_height: 1.5; $code_line_height: 1.5;
$border-color: #E5E5E5; $border-color: #E7E9ED;
$background-color: #f5f5f5; $background-color: #F8FAFC;
$header-height: 50px; $header-height: 58px;
$readable-width: 1100px; $fixed-layout-width: 1200px;
$gl-gray: #7f8fa4;
$gl-padding: 16px;
$gl-avatar-size: 46px;
/* /*
* State colors: * State colors:
*/ */
$gl-primary: #446e9b; $gl-primary: #446e9b;
$gl-success: #019875; $gl-success: #44c679;
$gl-info: #029ACF; $gl-info: #00aaff;
$gl-warning: #EB9532; $gl-warning: #EB9532;
$gl-danger: #d9534f; $gl-danger: #d9534f;
...@@ -35,4 +38,4 @@ $deleted: #f77; ...@@ -35,4 +38,4 @@ $deleted: #f77;
* Fonts * Fonts
*/ */
$monospace_font: 'Menlo', 'Liberation Mono', 'Consolas', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Courier New', 'andale mono', 'lucida console', monospace; $monospace_font: 'Menlo', 'Liberation Mono', 'Consolas', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Courier New', 'andale mono', 'lucida console', monospace;
$regular_font: "Helvetica Neue", Helvetica, Arial, sans-serif; $regular_font: 'Source Sans Pro', "Helvetica Neue", Helvetica, Arial, sans-serif;
...@@ -23,8 +23,12 @@ ...@@ -23,8 +23,12 @@
&.s24 { width: 24px; height: 24px; margin-right: 8px; } &.s24 { width: 24px; height: 24px; margin-right: 8px; }
&.s26 { width: 26px; height: 26px; margin-right: 8px; } &.s26 { width: 26px; height: 26px; margin-right: 8px; }
&.s32 { width: 32px; height: 32px; margin-right: 10px; } &.s32 { width: 32px; height: 32px; margin-right: 10px; }
&.s36 { width: 36px; height: 36px; margin-right: 10px; }
&.s46 { width: 46px; height: 46px; margin-right: 15px; }
&.s48 { width: 48px; height: 48px; margin-right: 10px; }
&.s60 { width: 60px; height: 60px; margin-right: 12px; } &.s60 { width: 60px; height: 60px; margin-right: 12px; }
&.s90 { width: 90px; height: 90px; margin-right: 15px; } &.s90 { width: 90px; height: 90px; margin-right: 15px; }
&.s140 { width: 140px; height: 140px; margin-right: 20px; }
&.s160 { width: 160px; height: 160px; margin-right: 20px; } &.s160 { width: 160px; height: 160px; margin-right: 20px; }
} }
...@@ -38,5 +42,6 @@ ...@@ -38,5 +42,6 @@
&.s32 { font-size: 22px; line-height: 32px; } &.s32 { font-size: 22px; line-height: 32px; }
&.s60 { font-size: 32px; line-height: 60px; } &.s60 { font-size: 32px; line-height: 60px; }
&.s90 { font-size: 36px; line-height: 90px; } &.s90 { font-size: 36px; line-height: 90px; }
&.s160 { font-size: 96px; line-height: 1.33; } &.s140 { font-size: 72px; line-height: 140px; }
&.s160 { font-size: 96px; line-height: 160px; }
} }
.light-well { .light-well {
background: #f9f9f9; background-color: #f8fafc;
padding: 15px; padding: 15px;
} }
.centered-light-block { .centered-light-block {
text-align: center; text-align: center;
color: #888; color: $gl-gray;
margin: 20px; margin: 20px;
} }
.nothing-here-block { .nothing-here-block {
text-align: center; text-align: center;
padding: 20px; padding: 20px;
color: #666; color: $gl-gray;
font-weight: normal; font-weight: normal;
font-size: 16px; font-size: 16px;
line-height: 36px; line-height: 36px;
} }
.gray-content-block {
margin: -$gl-padding;
background-color: #f8fafc;
padding: $gl-padding;
margin-bottom: 0px;
border-top: 1px solid #e7e9ed;
border-bottom: 1px solid #e7e9ed;
color: $gl-gray;
&.second-block {
margin-top: -1px;
margin-bottom: 0;
}
&.footer-block {
margin-top: 0;
margin-bottom: -$gl-padding;
}
.title {
color: $gl-text-color;
}
.oneline {
line-height: 44px;
}
}
...@@ -72,3 +72,19 @@ ...@@ -72,3 +72,19 @@
} }
} }
} }
.btn-group-next {
.btn {
padding: 9px 0px;
font-size: 15px;
color: #7f8fa4;
border-color: #e7e9ed;
width: 140px;
&.active {
border-color: $gl-info;
background: $gl-info;
color: #fff;
}
}
}
/** COLORS **/ /** COLORS **/
.cgray { color: gray } .cgray { color: $gl-gray; }
.clgray { color: #BBB } .clgray { color: #BBB }
.cred { color: #D12F19 } .cred { color: #D12F19 }
.cgreen { color: #4a2 } .cgreen { color: #4a2 }
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
/** COMMON CLASSES **/ /** COMMON CLASSES **/
.prepend-top-10 { margin-top:10px } .prepend-top-10 { margin-top:10px }
.prepend-top-default { margin-top: $gl-padding; }
.prepend-top-20 { margin-top:20px } .prepend-top-20 { margin-top:20px }
.prepend-left-10 { margin-left:10px } .prepend-left-10 { margin-left:10px }
.prepend-left-20 { margin-left:20px } .prepend-left-20 { margin-left:20px }
...@@ -20,10 +21,10 @@ ...@@ -20,10 +21,10 @@
.underlined-link { text-decoration: underline; } .underlined-link { text-decoration: underline; }
.hint { font-style: italic; color: #999; } .hint { font-style: italic; color: #999; }
.light { color: #888 } .light { color: $gl-gray; }
.slead { .slead {
color: #666; color: $gl-gray;
font-size: 15px; font-size: 15px;
margin-bottom: 12px; margin-bottom: 12px;
font-weight: normal; font-weight: normal;
...@@ -74,8 +75,6 @@ pre { ...@@ -74,8 +75,6 @@ pre {
color: $gl-link-color; color: $gl-link-color;
} }
.help li { color:$style_color; }
.back-link { .back-link {
font-size: 14px; font-size: 14px;
} }
...@@ -132,10 +131,6 @@ p.time { ...@@ -132,10 +131,6 @@ p.time {
text-shadow: none; text-shadow: none;
} }
.highlight_word {
background: #fafe3d;
}
.thin_area{ .thin_area{
height: 150px; height: 150px;
} }
...@@ -307,7 +302,7 @@ table { ...@@ -307,7 +302,7 @@ table {
} }
.btn-sign-in { .btn-sign-in {
margin-top: 7px; margin-top: 15px;
text-shadow: none; text-shadow: none;
} }
...@@ -359,14 +354,14 @@ table { ...@@ -359,14 +354,14 @@ table {
} }
.description { .description {
font-size: 16px; font-size: $gl-font-size;
color: #666; color: #666;
margin-top: 8px; margin-top: 8px;
} }
} }
.profiler-results { .profiler-results {
top: 50px !important; top: 73px !important;
.profiler-button, .profiler-button,
.profiler-controls { .profiler-controls {
...@@ -375,21 +370,41 @@ table { ...@@ -375,21 +370,41 @@ table {
} }
.center-top-menu { .center-top-menu {
border-bottom: 1px solid #EEE; padding: 0;
margin: 0;
list-style: none; list-style: none;
text-align: center; text-align: center;
padding-bottom: 15px; margin-top: 5px;
margin-bottom: 15px; margin-bottom: $gl-padding;
height: 56px;
margin-top: -$gl-padding;
padding-top: $gl-padding;
li { li {
display: inline-block; display: inline-block;
a { a {
padding: 10px; padding: 14px;
font-size: 17px;
line-height: 28px;
color: #7f8fa4;
border-bottom: 2px solid transparent;
&:hover, &:active, &:focus {
text-decoration: none;
}
} }
&.active a { &.active a {
color: #666; color: #4c4e54;
border-bottom: 2px solid #1cacfc;
}
.badge {
font-weight: normal;
background-color: #fff;
background-color: #eee;
color: #78a;
} }
} }
} }
...@@ -2,31 +2,6 @@ ...@@ -2,31 +2,6 @@
margin-right: 15px; margin-right: 15px;
} }
.issues-state-filters {
li.active a {
border-color: #DDD !important;
&, &:hover, &:active, &.active {
background: #f5f5f5 !important;
border-bottom: 1px solid #f5f5f5 !important;
}
}
}
.issues-details-filters {
font-size: 13px;
background: #f5f5f5;
margin: -10px 0;
padding: 10px 15px;
margin-top: -15px;
border-left: 1px solid #DDD;
border-right: 1px solid #DDD;
.btn {
font-size: 13px;
}
}
@media (min-width: 800px) { @media (min-width: 800px) {
.issues-filters, .issues-filters,
.issues_bulk_update { .issues_bulk_update {
......
...@@ -20,33 +20,32 @@ header { ...@@ -20,33 +20,32 @@ header {
} }
&.navbar-gitlab { &.navbar-gitlab {
padding: 0 20px;
z-index: 100; z-index: 100;
margin-bottom: 0; margin-bottom: 0;
min-height: $header-height; min-height: $header-height;
background-color: #fff;
border: none; border: none;
width: 100%; border-bottom: 1px solid #EEE;
.container { .container-fluid {
background: #FFF;
width: 100% !important; width: 100% !important;
padding: 0;
filter: none; filter: none;
padding: 0;
.nav > li > a { .nav > li > a {
color: #888; color: #7f8fa4;
font-size: 14px; font-size: 18px;
padding: 0; padding: 0;
background-color: #f5f5f5;
margin: ($header-height - 28) / 2 0; margin: ($header-height - 28) / 2 0;
margin-left: 10px; margin-left: 10px;
border-radius: 40px;
height: 28px; height: 28px;
width: 28px; width: 28px;
line-height: 28px; line-height: 28px;
text-align: center; text-align: center;
&:hover, &:focus, &:active { &:hover, &:focus, &:active {
background-color: #EEE; background-color: #FFF;
} }
} }
...@@ -56,6 +55,7 @@ header { ...@@ -56,6 +55,7 @@ header {
border-radius: 0; border-radius: 0;
position: absolute; position: absolute;
right: 2px; right: 2px;
top: 15px;
&:hover { &:hover {
background-color: #EEE; background-color: #EEE;
...@@ -64,66 +64,22 @@ header { ...@@ -64,66 +64,22 @@ header {
} }
} }
.header-logo {
border-bottom: 1px solid transparent;
float: left;
height: $header-height;
width: $sidebar_width;
overflow: hidden;
transition-duration: .3s;
a {
float: left;
height: $header-height;
width: 100%;
padding: ($header-height - 36 ) / 2 8px;
overflow: hidden;
img {
width: 36px;
height: 36px;
float: left;
}
.gitlab-text-container {
width: 230px;
h3 {
width: 158px;
float: left;
margin: 0;
margin-left: 14px;
font-size: 18px;
line-height: $header-height - 14;
font-weight: normal;
}
}
}
&:hover {
background-color: #EEE;
}
}
.header-content { .header-content {
border-bottom: 1px solid #EEE;
padding-right: 35px;
height: $header-height; height: $header-height;
.title { .title {
margin: 0; margin: 0;
padding: 0 15px 0 35px;
overflow: hidden; overflow: hidden;
font-size: 18px; font-size: 19px;
line-height: $header-height; line-height: $header-height;
font-weight: bold; font-weight: normal;
color: #444; color: #4c4e54;
text-overflow: ellipsis; text-overflow: ellipsis;
vertical-align: top; vertical-align: top;
white-space: nowrap; white-space: nowrap;
a { a {
color: #444; color: #4c4e54;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
...@@ -138,7 +94,7 @@ header { ...@@ -138,7 +94,7 @@ header {
.search { .search {
margin-right: 10px; margin-right: 10px;
margin-left: 10px; margin-left: 10px;
margin-top: ($header-height - 28) / 2; margin-top: ($header-height - 36) / 2;
form { form {
margin: 0; margin: 0;
...@@ -149,13 +105,8 @@ header { ...@@ -149,13 +105,8 @@ header {
width: 220px; width: 220px;
background-image: image-url("icon-search.png"); background-image: image-url("icon-search.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 10px; background-position: 195px;
height: inherit; @include input-big;
padding: 4px 6px;
padding-left: 25px;
font-size: 13px;
background-color: #f5f5f5;
border-color: #f5f5f5;
&:focus { &:focus {
@include box-shadow(none); @include box-shadow(none);
...@@ -168,15 +119,7 @@ header { ...@@ -168,15 +119,7 @@ header {
} }
@mixin collapsed-header { @mixin collapsed-header {
.header-logo { margin-left: $sidebar_collapsed_width;
width: $sidebar_collapsed_width;
}
.header-content {
.title {
margin-left: 30px;
}
}
} }
@media (max-width: $screen-md-max) { @media (max-width: $screen-md-max) {
...@@ -191,16 +134,14 @@ header { ...@@ -191,16 +134,14 @@ header {
} }
.header-expanded { .header-expanded {
margin-left: $sidebar_width;
} }
} }
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
header .container { header .container-fluid {
font-size: 18px; font-size: 18px;
.title {
}
.navbar-nav { .navbar-nav {
margin: 0px; margin: 0px;
float: none !important; float: none !important;
......
...@@ -49,8 +49,6 @@ ...@@ -49,8 +49,6 @@
} }
} }
.author { color: #999; }
.list-item-name { .list-item-name {
float: left; float: left;
position: relative; position: relative;
...@@ -71,15 +69,6 @@ ...@@ -71,15 +69,6 @@
font-size: $list-font-size; font-size: $list-font-size;
line-height: 18px; line-height: 18px;
} }
.row_title {
color: $gray-dark;
&:hover {
color: $text-color;
text-decoration: underline;
}
}
} }
} }
...@@ -93,28 +82,12 @@ ol, ul { ...@@ -93,28 +82,12 @@ ol, ul {
/** light list with border-bottom between li **/ /** light list with border-bottom between li **/
ul.bordered-list { ul.bordered-list {
margin: 5px 0px; @include basic-list;
padding: 0px;
li {
padding: 5px 0;
border-bottom: 1px solid #EEE;
overflow: hidden;
display: block;
margin: 0px;
&:last-child { border:none }
&.active {
background: #f9f9f9;
a { font-weight: bold; }
}
&.light {
a { color: #777; }
}
}
&.top-list { &.top-list {
li:first-child { li:first-child {
padding-top: 0; padding-top: 0;
h4, h5 { h4, h5 {
margin-top: 0; margin-top: 0;
} }
...@@ -125,3 +98,28 @@ ul.bordered-list { ...@@ -125,3 +98,28 @@ ul.bordered-list {
li.task-list-item { li.task-list-item {
list-style-type: none; list-style-type: none;
} }
ul.content-list {
@include basic-list;
margin: 0;
padding: 0;
> li {
padding: $gl-padding;
border-color: #f1f2f4;
margin-left: -$gl-padding;
margin-right: -$gl-padding;
color: $gl-gray;
.avatar {
margin-right: 15px;
}
.controls {
padding-top: 10px;
float: right;
}
}
}
...@@ -80,6 +80,23 @@ ...@@ -80,6 +80,23 @@
%ul.notes .note-role, .note-actions { %ul.notes .note-role, .note-actions {
display: none; display: none;
} }
.center-top-menu {
height: 45px;
li a {
font-size: 14px;
padding: 19px 10px;
}
}
.projects-search-form {
margin: 0 -5px !important;
.btn {
display: none;
}
}
} }
@media (max-width: $screen-sm-max) { @media (max-width: $screen-sm-max) {
......
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
.select2-choice { .select2-choice {
background: #FFF; background: #FFF;
border-color: #DDD; border-color: #DDD;
height: 34px; height: 42px;
padding: 6px 14px; padding: 8px $gl-padding;
font-size: 14px; font-size: $gl-font-size;
line-height: 1.42857143; line-height: 1.42857143;
@include border-radius(4px); @include border-radius(4px);
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
.select2-arrow { .select2-arrow {
background: #FFF; background: #FFF;
border-left: none; border-left: none;
padding-top: 3px; padding-top: 5px;
} }
} }
} }
......
...@@ -18,13 +18,21 @@ ...@@ -18,13 +18,21 @@
} }
.content-wrapper { .content-wrapper {
min-height: 100vh;
width: 100%; width: 100%;
padding: 20px; padding: 20px;
background: #f1f4f8;
.container-fluid {
background: #FFF; background: #FFF;
padding: $gl-padding;
border: 1px solid #e7e9ed;
min-height: 90vh;
}
} }
.nav-sidebar { .nav-sidebar {
margin-top: 29 + $header-height; margin-top: 14 + $header-height;
margin-bottom: 50px; margin-bottom: 50px;
transition-duration: .3s; transition-duration: .3s;
list-style: none; list-style: none;
...@@ -43,13 +51,14 @@ ...@@ -43,13 +51,14 @@
} }
a { a {
padding: 8px 15px; padding: 7px 15px;
font-size: 13px; font-size: $gl-font-size;
line-height: 18px; line-height: 24px;
color: $gray; color: $gray;
display: block; display: block;
text-decoration: none; text-decoration: none;
padding-left: 16px; padding-left: 22px;
font-weight: normal;
&:hover { &:hover {
text-decoration: none; text-decoration: none;
...@@ -60,9 +69,9 @@ ...@@ -60,9 +69,9 @@
} }
i { i {
width: 20px; width: 16px;
color: $gray-light; color: $gray-light;
margin-right: 23px; margin-right: 13px;
} }
.count { .count {
...@@ -108,17 +117,31 @@ ...@@ -108,17 +117,31 @@
} }
@mixin folded-sidebar { @mixin folded-sidebar {
padding-left: 50px; padding-left: 60px;
transition-duration: .3s; transition-duration: .3s;
.sidebar-wrapper { .sidebar-wrapper {
width: $sidebar_collapsed_width; width: $sidebar_collapsed_width;
.header-logo {
width: $sidebar_collapsed_width;
a {
padding-left: 12px;
.gitlab-text-container {
display: none;
}
}
}
.nav-sidebar { .nav-sidebar {
width: $sidebar_collapsed_width; width: $sidebar_collapsed_width;
li a { li a {
padding-left: 16px; span {
display: none;
}
} }
} }
...@@ -128,21 +151,25 @@ ...@@ -128,21 +151,25 @@
} }
.sidebar-user { .sidebar-user {
padding-left: 12px;
width: $sidebar_collapsed_width; width: $sidebar_collapsed_width;
.username {
display: none;
}
} }
} }
} }
.collapse-nav a { .collapse-nav a {
width: $sidebar_width;
position: fixed; position: fixed;
top: $header-height; bottom: 0;
left: 198px;
font-size: 13px; font-size: 13px;
background: transparent; background: transparent;
width: 32px; height: 40px;
height: 28px;
text-align: center; text-align: center;
line-height: 28px; line-height: 40px;
transition-duration: .3s; transition-duration: .3s;
} }
...@@ -176,15 +203,60 @@ ...@@ -176,15 +203,60 @@
} }
.sidebar-user { .sidebar-user {
padding: 9px 22px;
position: fixed; position: fixed;
bottom: 0; bottom: 40px;
width: $sidebar_width; width: $sidebar_width;
padding: 10px;
overflow: hidden; overflow: hidden;
transition-duration: .3s; transition-duration: .3s;
.username { .username {
margin-top: 5px; margin-left: 10px;
width: $sidebar_width - 2 * 10px; width: $sidebar_width - 2 * 10px;
font-size: 16px;
line-height: 34px;
}
}
.sidebar-wrapper {
.header-logo {
border-bottom: 1px solid transparent;
float: left;
height: $header-height;
width: $sidebar_width;
overflow: hidden;
transition-duration: .3s;
a {
float: left;
height: $header-height;
width: 100%;
padding: 10px 22px;
overflow: hidden;
img {
width: 36px;
height: 36px;
float: left;
}
.gitlab-text-container {
width: 230px;
h3 {
width: 158px;
float: left;
margin: 0;
margin-left: 14px;
font-size: 19px;
line-height: 41px;
font-weight: normal;
}
}
}
&:hover {
background-color: #EEE;
}
} }
} }
...@@ -9,6 +9,11 @@ ...@@ -9,6 +9,11 @@
margin-bottom: 5px; margin-bottom: 5px;
} }
h1, h2, h3, h4, h5, h6 {
color: $gl-header-color;
font-weight: 500;
}
/** CODE **/ /** CODE **/
pre { pre {
font-family: $monospace_font; font-family: $monospace_font;
......
...@@ -21,6 +21,12 @@ pre.code.highlight.dark, ...@@ -21,6 +21,12 @@ pre.code.highlight.dark,
background-color: #557 !important; background-color: #557 !important;
} }
// Search result highlight
span.highlight_word {
background: #ffe792;
color: #000000;
}
.hll { background-color: #373b41 } .hll { background-color: #373b41 }
.c { color: #969896 } /* Comment */ .c { color: #969896 } /* Comment */
.err { color: #cc6666 } /* Error */ .err { color: #cc6666 } /* Error */
......
...@@ -21,6 +21,12 @@ pre.code.monokai, ...@@ -21,6 +21,12 @@ pre.code.monokai,
background-color: #49483e !important; background-color: #49483e !important;
} }
// Search result highlight
span.highlight_word {
background: #ffe792;
color: #000000;
}
.hll { background-color: #49483e } .hll { background-color: #49483e }
.c { color: #75715e } /* Comment */ .c { color: #75715e } /* Comment */
.err { color: #960050; background-color: #1e0010 } /* Error */ .err { color: #960050; background-color: #1e0010 } /* Error */
......
...@@ -21,6 +21,11 @@ pre.code.highlight.solarized-dark, ...@@ -21,6 +21,11 @@ pre.code.highlight.solarized-dark,
background-color: #174652 !important; background-color: #174652 !important;
} }
// Search result highlight
span.highlight_word {
background: #094554;
}
/* Solarized Dark /* Solarized Dark
For use with Jekyll and Pygments For use with Jekyll and Pygments
......
...@@ -21,6 +21,11 @@ pre.code.highlight.solarized-light, ...@@ -21,6 +21,11 @@ pre.code.highlight.solarized-light,
background-color: #ddd8c5 !important; background-color: #ddd8c5 !important;
} }
// Search result highlight
span.highlight_word {
background: #eee8d5;
}
/* Solarized Light /* Solarized Light
For use with Jekyll and Pygments For use with Jekyll and Pygments
......
...@@ -21,6 +21,11 @@ pre.code.highlight.white, ...@@ -21,6 +21,11 @@ pre.code.highlight.white,
background-color: #f8eec7 !important; background-color: #f8eec7 !important;
} }
// Search result highlight
span.highlight_word {
background: #fafe3d;
}
.hll { background-color: #f8f8f8 } .hll { background-color: #f8f8f8 }
.c { color: #999988; font-style: italic; } .c { color: #999988; font-style: italic; }
.err { color: #a61717; background-color: #e3d2d2; } .err { color: #a61717; background-color: #e3d2d2; }
......
...@@ -61,10 +61,6 @@ ...@@ -61,10 +61,6 @@
} }
} }
.file-stats a {
color: $style_color;
}
.file-stats { .file-stats {
.new-file { .new-file {
a { a {
......
...@@ -52,7 +52,7 @@ li.commit { ...@@ -52,7 +52,7 @@ li.commit {
} }
.commit-row-message { .commit-row-message {
color: #444; color: $gl-link-color;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
...@@ -88,12 +88,12 @@ li.commit { ...@@ -88,12 +88,12 @@ li.commit {
} }
.commit-row-info { .commit-row-info {
color: #777; color: $gl-gray;
line-height: 24px; line-height: 24px;
font-size: 13px; font-size: 13px;
a { a {
color: #777; color: $gl-gray;
} }
.committed_ago { .committed_ago {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.side { .side {
.panel { .panel {
.panel-heading { .panel-heading {
background: #EEE; background: $background-color;
border-top-left-radius: 0; border-top-left-radius: 0;
} }
border-top-left-radius: 0; border-top-left-radius: 0;
...@@ -23,41 +23,6 @@ ...@@ -23,41 +23,6 @@
} }
} }
.project-row, .group-row {
padding: 0 !important;
font-size: 14px;
line-height: 24px;
a {
display: block;
padding: 8px 15px;
}
.project-name, .group-name {
font-weight: 500;
}
.arrow {
float: right;
margin: 0;
font-size: 20px;
}
.last-activity {
float: right;
font-size: 12px;
color: #AAA;
display: block;
.date {
color: #777;
}
}
}
.project-description {
overflow: hidden;
}
.project-access-icon { .project-access-icon {
margin-left: 10px; margin-left: 10px;
float: left; float: left;
...@@ -73,12 +38,11 @@ ...@@ -73,12 +38,11 @@
float: left; float: left;
.avatar { .avatar {
margin-top: -8px; @include border-radius(50%);
margin-left: -15px;
@include border-radius(0px);
} }
.identicon { .identicon {
line-height: 40px; line-height: 46px;
} }
} }
......
/** /**
* Events labels * Dashboard events feed
* *
*/ */
.event_label { .event-item {
&.pushed { font-size: $gl-font-size;
padding: 0 2px; padding: $gl-padding;
} margin-left: -$gl-padding;
margin-right: -$gl-padding;
border-bottom: 1px solid #f1f2f4;
color: #7f8fa4;
&.opened { &.event-inline {
padding: 0 2px; .avatar {
position: relative;
top: -2px;
} }
&.closed { .event-title {
padding: 0 2px; line-height: 44px;
} }
&.merged { .event-item-timestamp {
padding: 0 2px; line-height: 44px;
} }
&.left,
&.joined {
padding: 0 2px;
float: none;
} }
}
/** a {
* Dashboard events feed color: #4c4e54;
*
*/
.event-item {
&:first-child {
padding-top: 0;
} }
&.event-inline {
.avatar { .avatar {
position: relative; margin-right: 15px;
top: -2px;
}
} }
padding: 12px 0px;
border-bottom: 1px solid #eee;
.event-title { .event-title {
max-width: 70%;
@include str-truncated(calc(100% - 174px)); @include str-truncated(calc(100% - 174px));
font-weight: 500; font-weight: 600;
font-size: 14px;
.author_name { .author_name {
color: #333; color: #333;
} }
} }
.event-body { .event-body {
font-size: 13px; margin-left: 63px;
margin-left: 35px;
margin-right: 80px; margin-right: 80px;
color: #777;
.event-note { .event-note {
margin-top: 5px; margin-top: 5px;
word-wrap: break-word; word-wrap: break-word;
.md { .md {
font-size: 13px; color: #7f8fa4;
font-size: $gl-font-size;
iframe.twitter-share-button { iframe.twitter-share-button {
vertical-align: bottom; vertical-align: bottom;
...@@ -94,7 +82,7 @@ ...@@ -94,7 +82,7 @@
.event-note-icon { .event-note-icon {
color: #777; color: #777;
float: left; float: left;
font-size: 16px; font-size: $gl-font-size;
line-height: 16px; line-height: 16px;
margin-right: 5px; margin-right: 5px;
} }
...@@ -116,7 +104,7 @@ ...@@ -116,7 +104,7 @@
&:last-child { border:none } &:last-child { border:none }
.event_commits { .event_commits {
margin-top: 5px; margin-top: 9px;
li { li {
&.commit { &.commit {
...@@ -125,10 +113,12 @@ ...@@ -125,10 +113,12 @@
padding-left: 0; padding-left: 0;
border: none; border: none;
.commit-row-title { .commit-row-title {
font-size: 12px; font-size: $gl-font-size;
} }
} }
&.commits-stat { &.commits-stat {
margin-top: 3px;
display: block; display: block;
padding: 3px; padding: 3px;
padding-left: 0; padding-left: 0;
...@@ -142,7 +132,6 @@ ...@@ -142,7 +132,6 @@
.event-item-timestamp { .event-item-timestamp {
float: right; float: right;
color: #999;
line-height: 22px; line-height: 22px;
} }
} }
...@@ -186,12 +175,3 @@ ...@@ -186,12 +175,3 @@
} }
} }
} }
.event_filter {
li a {
font-size: 13px;
padding: 5px 10px;
background: $background-color;
margin-left: 4px;
}
}
...@@ -46,8 +46,13 @@ ...@@ -46,8 +46,13 @@
.btn { font-size: 13px; } .btn { font-size: 13px; }
} }
.issuable-details { .project-issuable-filter {
.description { .controls {
max-width: $readable-width; float: right;
margin-top: 7px;
}
.center-top-menu {
text-align: left;
} }
} }
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
} }
.issue-info { .issue-info {
color: #999; color: $gl-gray;
font-size: 13px; font-size: 13px;
} }
......
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
} }
.merge-request-info { .merge-request-info {
color: #999; color: $gl-gray;
font-size: 13px; font-size: 13px;
} }
......
...@@ -16,6 +16,10 @@ ...@@ -16,6 +16,10 @@
.project-home-panel { .project-home-panel {
text-align: center; text-align: center;
background: #f7f8fa;
margin: -$gl-padding;
padding: $gl-padding;
padding-top: 40px;
.project-identicon-holder { .project-identicon-holder {
margin-bottom: 15px; margin-bottom: 15px;
...@@ -30,14 +34,20 @@ ...@@ -30,14 +34,20 @@
} }
} }
.project-home-dropdown {
margin: 11px 3px 0;
}
.project-home-desc { .project-home-desc {
h1 { h1 {
margin: 0; margin: 0;
margin-bottom: 10px; margin-bottom: 10px;
font-size: 26px; font-size: 23px;
font-weight: normal;
} }
p { p {
color: #7f8fa4;
display: inline; display: inline;
} }
} }
...@@ -45,6 +55,10 @@ ...@@ -45,6 +55,10 @@
.git-clone-holder { .git-clone-holder {
max-width: 600px; max-width: 600px;
margin: 20px auto; margin: 20px auto;
.form-control {
background: #FFF;
}
} }
.visibility-level-label { .visibility-level-label {
...@@ -55,17 +69,18 @@ ...@@ -55,17 +69,18 @@
} }
.project-repo-buttons { .project-repo-buttons {
margin-top: 25px; margin-top: $gl-padding;
margin-bottom: 25px; margin-bottom: 25px;
.btn { .btn {
@extend .btn-info; @extend .btn-info;
text-transform: uppercase;
font-size: 15px;
line-height: 20px;
padding: 8px 14px;
border-radius: 3px;
margin-left: 10px; margin-left: 10px;
font-weight: bold;
font-size: 14px;
line-height: 16px;
padding: 8px 12px;
.count { .count {
padding-left: 7px; padding-left: 7px;
...@@ -155,78 +170,6 @@ ul.nav.nav-projects-tabs { ...@@ -155,78 +170,6 @@ ul.nav.nav-projects-tabs {
margin: 0px; margin: 0px;
} }
.my-projects,
.public-projects {
li {
.project-info {
margin-bottom: 10px;
overflow: hidden;
}
.access-icon {
color: #AAA;
margin-left: 10px;
i {
color: #AAA;
}
}
}
}
.public-clone {
background: #EEE;
color: #777;
padding: 6px 10px;
margin: 1px;
font-weight: normal;
}
.public-projects .repo-info {
color: #777;
a {
color: #777;
}
}
.project-side {
.project-fork-icon {
float: left;
font-size: 26px;
margin-right: 10px;
line-height: 1.5;
}
.panel {
@include border-radius(3px);
.panel-heading, .panel-footer {
font-weight: normal;
background-color: transparent;
color: #666;
border-color: #EEE;
}
.actions {
margin-top: 10px;
}
.nav-pills a {
padding: 10px;
font-weight: bold;
color: $gl-link-color;
}
.nav {
margin-bottom: 15px;
}
}
.ci-status-image {
max-height: 22px;
}
}
.transfer-project .select2-container { .transfer-project .select2-container {
min-width: 200px; min-width: 200px;
} }
...@@ -249,10 +192,10 @@ ul.nav.nav-projects-tabs { ...@@ -249,10 +192,10 @@ ul.nav.nav-projects-tabs {
.breadcrumb.repo-breadcrumb { .breadcrumb.repo-breadcrumb {
padding: 0; padding: 0;
line-height: 34px; line-height: 42px;
background: white; background: transparent;
border: none; border: none;
font-size: 16px; margin: 0;
> li + li:before { > li + li:before {
padding: 0 3px; padding: 0 3px;
...@@ -298,10 +241,23 @@ table.table.protected-branches-list tr.no-border { ...@@ -298,10 +241,23 @@ table.table.protected-branches-list tr.no-border {
.project-stats { .project-stats {
text-align: center; text-align: center;
margin-top: 0;
margin-bottom: 0;
padding-top: 5px;
padding-bottom: 0;
ul.nav-pills { display:inline-block; } ul.nav-pills {
li { display:inline; } display:inline-block;
a { float:left; } }
li {
display:inline;
}
a {
float:left;
font-size: 17px;
}
li.missing a { li.missing a {
color: #bbb; color: #bbb;
...@@ -316,3 +272,69 @@ table.table.protected-branches-list tr.no-border { ...@@ -316,3 +272,69 @@ table.table.protected-branches-list tr.no-border {
pre.light-well { pre.light-well {
border-color: #f1f1f1; border-color: #f1f1f1;
} }
.projects-search-form {
margin: -$gl-padding;
background-color: #f8fafc;
padding: $gl-padding;
margin-bottom: 0px;
border-top: 1px solid #e7e9ed;
border-bottom: 1px solid #e7e9ed;
}
/*
* Projects list rendered on dashboard and user page
*/
.projects-list {
@include basic-list;
.project-row {
padding: $gl-padding;
border-color: #f1f2f4;
margin-left: -$gl-padding;
margin-right: -$gl-padding;
&.no-description {
.project {
line-height: 44px;
}
}
.project-full-name {
@include str-truncated;
font-weight: 600;
color: #4c4e54;
}
.pull-right.light {
line-height: 45px;
color: #7f8fa4;
}
.project-description {
color: #7f8fa4;
p {
@include str-truncated;
margin-bottom: 0;
color: #7f8fa4;
}
}
}
.bottom {
padding-top: $gl-padding;
padding-bottom: 0;
}
}
.panel .projects-list li {
padding: 10px 15px;
margin: 0;
}
.project-show-activity {
.activity-filter-block {
margin-top: -1px;
}
}
.search-results { .search-results {
.search-result-row { .search-result-row {
border-bottom: 1px solid #EEE; border-bottom: 1px solid #DDD;
padding-bottom: 10px; padding-bottom: 15px;
margin-bottom: 10px; margin-bottom: 15px;
} }
} }
.search-holder {
max-width: 600px;
margin: 0 auto;
margin-bottom: 20px;
input {
border-color: #BBB;
font-weight: bold;
}
}
...@@ -6,3 +6,27 @@ ...@@ -6,3 +6,27 @@
.snippet-form-holder .file-holder .file-title { .snippet-form-holder .file-holder .file-title {
padding: 2px; padding: 2px;
} }
.snippet-row {
.snippet-title {
font-size: 15px;
font-weight: bold;
line-height: 20px;
margin-bottom: 2px;
.monospace {
font-weight: normal;
}
}
.snippet-info {
color: #888;
font-size: 13px;
line-height: 24px;
a {
color: #888;
}
}
}
...@@ -63,15 +63,15 @@ ...@@ -63,15 +63,15 @@
padding-right: 8px; padding-right: 8px;
.commit-author-name { .commit-author-name {
color: gray; color: $gl-gray;
} }
} }
.tree_commit { .tree_commit {
color: gray; color: $gl-gray;
.tree-commit-link { .tree-commit-link {
color: gray; color: $gl-gray;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
...@@ -117,7 +117,6 @@ ...@@ -117,7 +117,6 @@
.readme-holder { .readme-holder {
margin: 0 auto; margin: 0 auto;
max-width: $readable-width;
.readme-file-title { .readme-file-title {
font-size: 14px; font-size: 14px;
......
...@@ -7,27 +7,27 @@ ...@@ -7,27 +7,27 @@
* $color-dark - * $color-dark -
*/ */
@mixin gitlab-theme($color-light, $color, $color-darker, $color-dark) { @mixin gitlab-theme($color-light, $color, $color-darker, $color-dark) {
header { .page-with-sidebar {
&.navbar-gitlab {
.header-logo { .header-logo {
background-color: $color-darker; background-color: $color;
border-color: $color-darker; border-color: $color;
a { a {
color: $color-light; color: $color-light;
h3 {
color: $color-light;
}
} }
&:hover { &:hover {
background-color: $color-dark; background-color: $color-darker;
a { a {
color: #FFF; color: #FFF;
} }
} }
} }
}
}
.page-with-sidebar {
.collapse-nav a { .collapse-nav a {
color: #FFF; color: #FFF;
background: $color; background: $color;
...@@ -87,7 +87,7 @@ ...@@ -87,7 +87,7 @@
} }
$theme-blue: #2980B9; $theme-blue: #2980B9;
$theme-charcoal: #474D57; $theme-charcoal: #333c47;
$theme-graphite: #888888; $theme-graphite: #888888;
$theme-gray: #373737; $theme-gray: #373737;
$theme-green: #019875; $theme-green: #019875;
...@@ -99,7 +99,7 @@ body { ...@@ -99,7 +99,7 @@ body {
} }
&.ui_charcoal { &.ui_charcoal {
@include gitlab-theme(#979DA7, $theme-charcoal, #373D47, #24272D); @include gitlab-theme(#c5d0de, $theme-charcoal, #2b333d, #24272D);
} }
&.ui_graphite { &.ui_graphite {
......
...@@ -4,8 +4,13 @@ class Admin::AbuseReportsController < Admin::ApplicationController ...@@ -4,8 +4,13 @@ class Admin::AbuseReportsController < Admin::ApplicationController
end end
def destroy def destroy
AbuseReport.find(params[:id]).destroy abuse_report = AbuseReport.find(params[:id])
redirect_to admin_abuse_reports_path, notice: 'Report was removed' if params[:remove_user]
abuse_report.user.destroy
end
abuse_report.destroy
render nothing: true
end end
end end
...@@ -39,6 +39,6 @@ class Admin::HooksController < Admin::ApplicationController ...@@ -39,6 +39,6 @@ class Admin::HooksController < Admin::ApplicationController
end end
def hook_params def hook_params
params.require(:hook).permit(:url) params.require(:hook).permit(:url, :enable_ssl_verification)
end end
end end
...@@ -55,7 +55,9 @@ class ApplicationController < ActionController::Base ...@@ -55,7 +55,9 @@ class ApplicationController < ActionController::Base
def authenticate_user!(*args) def authenticate_user!(*args)
# If user is not signed-in and tries to access root_path - redirect him to landing page # If user is not signed-in and tries to access root_path - redirect him to landing page
if current_application_settings.home_page_url.present? # Don't redirect to the default URL to prevent endless redirections
if current_application_settings.home_page_url.present? &&
current_application_settings.home_page_url.chomp('/') != Gitlab.config.gitlab['url'].chomp('/')
if current_user.nil? && root_path == request.path if current_user.nil? && root_path == request.path
redirect_to current_application_settings.home_page_url and return redirect_to current_application_settings.home_page_url and return
end end
...@@ -190,11 +192,12 @@ class ApplicationController < ActionController::Base ...@@ -190,11 +192,12 @@ class ApplicationController < ActionController::Base
end end
def add_gon_variables def add_gon_variables
gon.default_issues_tracker = Project.new.default_issue_tracker.to_param
gon.api_version = API::API.version gon.api_version = API::API.version
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s
gon.max_file_size = current_application_settings.max_attachment_size; gon.default_issues_tracker = Project.new.default_issue_tracker.to_param
gon.max_file_size = current_application_settings.max_attachment_size
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
gon.user_color_scheme = Gitlab::ColorSchemes.for_user(current_user).css_class
if current_user if current_user
gon.current_user_id = current_user.id gon.current_user_id = current_user.id
......
class DashboardController < Dashboard::ApplicationController class DashboardController < Dashboard::ApplicationController
before_action :load_projects before_action :load_projects, except: :activity
before_action :event_filter, only: :show before_action :event_filter, only: :activity
respond_to :html respond_to :html
...@@ -10,13 +10,8 @@ class DashboardController < Dashboard::ApplicationController ...@@ -10,13 +10,8 @@ class DashboardController < Dashboard::ApplicationController
respond_to do |format| respond_to do |format|
format.html format.html
format.json do
load_events
pager_json("events/_events", @events.count)
end
format.atom do format.atom do
event_filter
load_events load_events
render layout: false render layout: false
end end
...@@ -40,6 +35,19 @@ class DashboardController < Dashboard::ApplicationController ...@@ -40,6 +35,19 @@ class DashboardController < Dashboard::ApplicationController
end end
end end
def activity
@last_push = current_user.recent_push
respond_to do |format|
format.html
format.json do
load_events
pager_json("events/_events", @events.count)
end
end
end
protected protected
def load_projects def load_projects
...@@ -47,7 +55,14 @@ class DashboardController < Dashboard::ApplicationController ...@@ -47,7 +55,14 @@ class DashboardController < Dashboard::ApplicationController
end end
def load_events def load_events
@events = Event.in_projects(current_user.authorized_projects.pluck(:id)) project_ids =
if params[:filter] == "starred"
current_user.starred_projects
else
current_user.authorized_projects
end.pluck(:id)
@events = Event.in_projects(project_ids)
@events = @event_filter.apply_filter(@events).with_associations @events = @event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0) @events = @events.limit(20).offset(params[:offset] || 0)
end end
......
...@@ -53,6 +53,7 @@ class Projects::HooksController < Projects::ApplicationController ...@@ -53,6 +53,7 @@ class Projects::HooksController < Projects::ApplicationController
end end
def hook_params def hook_params
params.require(:hook).permit(:url, :push_events, :issues_events, :merge_requests_events, :tag_push_events, :note_events) params.require(:hook).permit(:url, :push_events, :issues_events,
:merge_requests_events, :tag_push_events, :note_events, :enable_ssl_verification)
end end
end end
...@@ -17,8 +17,7 @@ class Projects::RawController < Projects::ApplicationController ...@@ -17,8 +17,7 @@ class Projects::RawController < Projects::ApplicationController
send_data( send_data(
@blob.data, @blob.data,
type: type, type: type,
disposition: 'inline', disposition: 'inline'
filename: @blob.name
) )
else else
not_found! not_found!
...@@ -30,6 +29,8 @@ class Projects::RawController < Projects::ApplicationController ...@@ -30,6 +29,8 @@ class Projects::RawController < Projects::ApplicationController
def get_blob_type def get_blob_type
if @blob.text? if @blob.text?
'text/plain; charset=utf-8' 'text/plain; charset=utf-8'
elsif @blob.image?
@blob.content_type
else else
'application/octet-stream' 'application/octet-stream'
end end
......
...@@ -2,13 +2,13 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -2,13 +2,13 @@ class Projects::ServicesController < Projects::ApplicationController
ALLOWED_PARAMS = [:title, :token, :type, :active, :api_key, :api_version, :subdomain, ALLOWED_PARAMS = [:title, :token, :type, :active, :api_key, :api_version, :subdomain,
:room, :recipients, :project_url, :webhook, :room, :recipients, :project_url, :webhook,
:user_key, :device, :priority, :sound, :bamboo_url, :username, :password, :user_key, :device, :priority, :sound, :bamboo_url, :username, :password,
:build_key, :server, :teamcity_url, :build_type, :build_key, :server, :teamcity_url, :drone_url, :build_type,
:description, :issues_url, :new_issue_url, :restrict_to_branch, :channel, :description, :issues_url, :new_issue_url, :restrict_to_branch, :channel,
:colorize_messages, :channels, :colorize_messages, :channels,
:push_events, :issues_events, :merge_requests_events, :tag_push_events, :push_events, :issues_events, :merge_requests_events, :tag_push_events,
:note_events, :send_from_committer_email, :disable_diffs, :external_wiki_url, :note_events, :send_from_committer_email, :disable_diffs, :external_wiki_url,
:notify, :color, :notify, :color,
:server_host, :server_port, :default_irc_uri] :server_host, :server_port, :default_irc_uri, :enable_ssl_verification]
# Authorize # Authorize
before_action :authorize_admin_project! before_action :authorize_admin_project!
before_action :service, only: [:edit, :update, :test] before_action :service, only: [:edit, :update, :test]
......
...@@ -30,9 +30,14 @@ class Projects::SnippetsController < Projects::ApplicationController ...@@ -30,9 +30,14 @@ class Projects::SnippetsController < Projects::ApplicationController
def create def create
@snippet = CreateSnippetService.new(@project, current_user, @snippet = CreateSnippetService.new(@project, current_user,
snippet_params).execute snippet_params).execute
if @snippet.valid?
respond_with(@snippet, respond_with(@snippet,
location: namespace_project_snippet_path(@project.namespace, location: namespace_project_snippet_path(@project.namespace,
@project, @snippet)) @project, @snippet))
else
render :new
end
end end
def edit def edit
......
...@@ -5,7 +5,6 @@ class Projects::WikisController < Projects::ApplicationController ...@@ -5,7 +5,6 @@ class Projects::WikisController < Projects::ApplicationController
before_action :authorize_create_wiki!, only: [:edit, :create, :history] before_action :authorize_create_wiki!, only: [:edit, :create, :history]
before_action :authorize_admin_wiki!, only: :destroy before_action :authorize_admin_wiki!, only: :destroy
before_action :load_project_wiki before_action :load_project_wiki
include WikiHelper
def pages def pages
@wiki_pages = Kaminari.paginate_array(@project_wiki.pages).page(params[:page]).per(PER_PAGE) @wiki_pages = Kaminari.paginate_array(@project_wiki.pages).page(params[:page]).per(PER_PAGE)
......
...@@ -8,6 +8,8 @@ class SessionsController < Devise::SessionsController ...@@ -8,6 +8,8 @@ class SessionsController < Devise::SessionsController
def new def new
if Gitlab.config.ldap.enabled if Gitlab.config.ldap.enabled
@ldap_servers = Gitlab::LDAP::Config.servers @ldap_servers = Gitlab::LDAP::Config.servers
else
@ldap_servers = []
end end
super super
......
...@@ -51,10 +51,6 @@ class UsersController < ApplicationController ...@@ -51,10 +51,6 @@ class UsersController < ApplicationController
def set_user def set_user
@user = User.find_by_username!(params[:username]) @user = User.find_by_username!(params[:username])
unless current_user || @user.public_profile?
return authenticate_user!
end
end end
def authorized_projects_ids def authorized_projects_ids
......
...@@ -2,13 +2,21 @@ class TrendingProjectsFinder ...@@ -2,13 +2,21 @@ class TrendingProjectsFinder
def execute(current_user, start_date = nil) def execute(current_user, start_date = nil)
start_date ||= Date.today - 1.month start_date ||= Date.today - 1.month
projects = projects_for(current_user)
# Determine trending projects based on comments count # Determine trending projects based on comments count
# for period of time - ex. month # for period of time - ex. month
projects.joins(:notes).where('notes.created_at > ?', start_date). trending_project_ids = Note.
select("projects.*, count(notes.id) as ncount"). select("notes.project_id, count(notes.project_id) as pcount").
group("projects.id").reorder("ncount DESC") where('notes.created_at > ?', start_date).
group("project_id").
reorder("pcount DESC").
map(&:project_id)
sql_order_ids = trending_project_ids.reverse.
map { |project_id| "id = #{project_id}" }.join(", ")
# Get list of projects that user allowed to see
projects = projects_for(current_user)
projects.where(id: trending_project_ids).reorder(sql_order_ids)
end end
private private
......
module AuthHelper module AuthHelper
PROVIDERS_WITH_ICONS = %w(twitter github gitlab bitbucket google_oauth2).freeze PROVIDERS_WITH_ICONS = %w(twitter github gitlab bitbucket google_oauth2).freeze
FORM_BASED_PROVIDERS = [/\Aldap/, 'kerberos'].freeze FORM_BASED_PROVIDERS = [/\Aldap/, 'kerberos', 'crowd'].freeze
def ldap_enabled? def ldap_enabled?
Gitlab.config.ldap.enabled Gitlab.config.ldap.enabled
...@@ -26,6 +26,10 @@ module AuthHelper ...@@ -26,6 +26,10 @@ module AuthHelper
auth_providers.select { |provider| form_based_provider?(provider) } auth_providers.select { |provider| form_based_provider?(provider) }
end end
def crowd_enabled?
auth_providers.include? :crowd
end
def button_based_providers def button_based_providers
auth_providers.reject { |provider| form_based_provider?(provider) } auth_providers.reject { |provider| form_based_provider?(provider) }
end end
......
...@@ -137,7 +137,7 @@ module DiffHelper ...@@ -137,7 +137,7 @@ module DiffHelper
# Always use HTML to handle case where JSON diff rendered this button # Always use HTML to handle case where JSON diff rendered this button
params_copy.delete(:format) params_copy.delete(:format)
link_to url_for(params_copy), id: "commit-diff-viewtype", class: (params[:view] != 'parallel' ? 'btn btn-sm active' : 'btn btn-sm') do link_to url_for(params_copy), id: "inline-diff-btn", class: (params[:view] != 'parallel' ? 'btn btn-sm active' : 'btn btn-sm') do
'Inline' 'Inline'
end end
end end
...@@ -148,7 +148,7 @@ module DiffHelper ...@@ -148,7 +148,7 @@ module DiffHelper
# Always use HTML to handle case where JSON diff rendered this button # Always use HTML to handle case where JSON diff rendered this button
params_copy.delete(:format) params_copy.delete(:format)
link_to url_for(params_copy), id: "commit-diff-viewtype", class: (params[:view] == 'parallel' ? 'btn active btn-sm' : 'btn btn-sm') do link_to url_for(params_copy), id: "parallel-diff-btn", class: (params[:view] == 'parallel' ? 'btn active btn-sm' : 'btn btn-sm') do
'Side-by-side' 'Side-by-side'
end end
end end
......
...@@ -27,16 +27,13 @@ module EventsHelper ...@@ -27,16 +27,13 @@ module EventsHelper
key = key.to_s key = key.to_s
active = 'active' if @event_filter.active?(key) active = 'active' if @event_filter.active?(key)
link_opts = { link_opts = {
class: 'event_filter_link', class: "event-filter-link btn btn-default #{active}",
id: "#{key}_event_filter", id: "#{key}_event_filter",
title: "Filter by #{tooltip.downcase}", title: "Filter by #{tooltip.downcase}",
data: { toggle: 'tooltip', placement: 'top' }
} }
content_tag :li, class: "filter_icon #{active}" do
link_to request.path, link_opts do link_to request.path, link_opts do
icon(icon_for_event[key]) + content_tag(:span, ' ' + tooltip) content_tag(:span, ' ' + tooltip)
end
end end
end end
......
require 'nokogiri' require 'nokogiri'
module GitlabMarkdownHelper module GitlabMarkdownHelper
include Gitlab::Markdown
include PreferencesHelper
# Use this in places where you would normally use link_to(gfm(...), ...). # Use this in places where you would normally use link_to(gfm(...), ...).
# #
# It solves a problem occurring with nested links (i.e. # It solves a problem occurring with nested links (i.e.
...@@ -22,7 +19,7 @@ module GitlabMarkdownHelper ...@@ -22,7 +19,7 @@ module GitlabMarkdownHelper
escape_once(body) escape_once(body)
end end
gfm_body = gfm(escaped_body, {}, html_options) gfm_body = Gitlab::Markdown.gfm(escaped_body, project: @project, current_user: current_user)
fragment = Nokogiri::XML::DocumentFragment.parse(gfm_body) fragment = Nokogiri::XML::DocumentFragment.parse(gfm_body)
if fragment.children.size == 1 && fragment.children[0].name == 'a' if fragment.children.size == 1 && fragment.children[0].name == 'a'
...@@ -39,32 +36,38 @@ module GitlabMarkdownHelper ...@@ -39,32 +36,38 @@ module GitlabMarkdownHelper
end end
end end
fragment.to_html.html_safe # Add any custom CSS classes to the GFM-generated reference links
if html_options[:class]
fragment.css('a.gfm').add_class(html_options[:class])
end end
MARKDOWN_OPTIONS = { fragment.to_html.html_safe
no_intra_emphasis: true, end
tables: true,
fenced_code_blocks: true,
strikethrough: true,
lax_spacing: true,
space_after_headers: true,
superscript: true,
footnotes: true
}.freeze
def markdown(text, options={})
unless @markdown && options == @options
@options = options
# see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch def markdown(text, context = {})
rend = Redcarpet::Render::GitlabHTML.new(self, user_color_scheme_class, options) context.merge!(
current_user: current_user,
path: @path,
project: @project,
project_wiki: @project_wiki,
ref: @ref
)
# see https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use Gitlab::Markdown.render(text, context)
@markdown = Redcarpet::Markdown.new(rend, MARKDOWN_OPTIONS)
end end
@markdown.render(text).html_safe # TODO (rspeicher): Remove all usages of this helper and just call `markdown`
# with a custom pipeline depending on the content being rendered
def gfm(text, options = {})
options.merge!(
current_user: current_user,
path: @path,
project: @project,
project_wiki: @project_wiki,
ref: @ref
)
Gitlab::Markdown.gfm(text, options)
end end
def asciidoc(text) def asciidoc(text)
......
...@@ -30,4 +30,13 @@ module GroupsHelper ...@@ -30,4 +30,13 @@ module GroupsHelper
image_path('no_group_avatar.png') image_path('no_group_avatar.png')
end end
end end
def group_title(group, name, url)
content_tag :span do
link_to(
simple_sanitize(group.name), group_path(group)
) + ' &middot; '.html_safe +
link_to(simple_sanitize(name), url)
end
end
end end
...@@ -23,4 +23,12 @@ module PageLayoutHelper ...@@ -23,4 +23,12 @@ module PageLayoutHelper
@sidebar @sidebar
end end
end end
def fluid_layout(enabled = false)
if @fluid_layout.nil?
@fluid_layout = enabled
else
@fluid_layout
end
end
end end
# Helper methods for per-User preferences # Helper methods for per-User preferences
module PreferencesHelper module PreferencesHelper
COLOR_SCHEMES = {
1 => 'white',
2 => 'dark',
3 => 'solarized-light',
4 => 'solarized-dark',
5 => 'monokai',
}
COLOR_SCHEMES.default = 'white'
# Helper method to access the COLOR_SCHEMES
#
# The keys are the `color_scheme_ids`
# The values are the `name` of the scheme.
#
# The preview images are `name-scheme-preview.png`
# The stylesheets should use the css class `.name`
def color_schemes
COLOR_SCHEMES.freeze
end
# Maps `dashboard` values to more user-friendly option text # Maps `dashboard` values to more user-friendly option text
DASHBOARD_CHOICES = { DASHBOARD_CHOICES = {
projects: 'Your Projects (default)', projects: 'Your Projects (default)',
...@@ -50,12 +30,11 @@ module PreferencesHelper ...@@ -50,12 +30,11 @@ module PreferencesHelper
end end
def user_application_theme def user_application_theme
theme = Gitlab::Themes.by_id(current_user.try(:theme_id)) Gitlab::Themes.for_user(current_user).css_class
theme.css_class
end end
def user_color_scheme_class def user_color_scheme
COLOR_SCHEMES[current_user.try(:color_scheme_id)] if defined?(current_user) Gitlab::ColorSchemes.for_user(current_user).css_class
end end
def prefer_readme? def prefer_readme?
......
module WikiHelper
# Rails v4.1.9+ escapes all model IDs, converting slashes into %2F. The
# only way around this is to implement our own path generators.
def namespace_project_wiki_path(namespace, project, wiki_page, *args)
slug =
case wiki_page
when Symbol
wiki_page
when String
wiki_page
else
wiki_page.slug
end
namespace_project_path(namespace, project) + "/wikis/#{slug}"
end
def edit_namespace_project_wiki_path(namespace, project, wiki_page, *args)
namespace_project_wiki_path(namespace, project, wiki_page) + '/edit'
end
def history_namespace_project_wiki_path(namespace, project, wiki_page, *args)
namespace_project_wiki_path(namespace, project, wiki_page) + '/history'
end
end
...@@ -3,6 +3,8 @@ class EmailRejectionMailer < BaseMailer ...@@ -3,6 +3,8 @@ class EmailRejectionMailer < BaseMailer
@reason = reason @reason = reason
@original_message = Mail::Message.new(original_raw) @original_message = Mail::Message.new(original_raw)
return unless @original_message.from
headers = { headers = {
to: @original_message.from, to: @original_message.from,
subject: "[Rejected] #{@original_message.subject}" subject: "[Rejected] #{@original_message.subject}"
......
# == Schema Information
#
# Table name: abuse_reports
#
# id :integer not null, primary key
# reporter_id :integer
# user_id :integer
# message :text
# created_at :datetime
# updated_at :datetime
#
class AbuseReport < ActiveRecord::Base class AbuseReport < ActiveRecord::Base
belongs_to :reporter, class_name: "User" belongs_to :reporter, class_name: "User"
belongs_to :user belongs_to :user
......
...@@ -25,6 +25,7 @@ class WebHook < ActiveRecord::Base ...@@ -25,6 +25,7 @@ class WebHook < ActiveRecord::Base
default_value_for :note_events, false default_value_for :note_events, false
default_value_for :merge_requests_events, false default_value_for :merge_requests_events, false
default_value_for :tag_push_events, false default_value_for :tag_push_events, false
default_value_for :enable_ssl_verification, false
# HTTParty timeout # HTTParty timeout
default_timeout Gitlab.config.gitlab.webhook_timeout default_timeout Gitlab.config.gitlab.webhook_timeout
...@@ -41,7 +42,7 @@ class WebHook < ActiveRecord::Base ...@@ -41,7 +42,7 @@ class WebHook < ActiveRecord::Base
"Content-Type" => "application/json", "Content-Type" => "application/json",
"X-Gitlab-Event" => hook_name.singularize.titleize "X-Gitlab-Event" => hook_name.singularize.titleize
}, },
verify: false) verify: enable_ssl_verification)
else else
post_url = url.gsub("#{parsed_url.userinfo}@", "") post_url = url.gsub("#{parsed_url.userinfo}@", "")
auth = { auth = {
...@@ -54,7 +55,7 @@ class WebHook < ActiveRecord::Base ...@@ -54,7 +55,7 @@ class WebHook < ActiveRecord::Base
"Content-Type" => "application/json", "Content-Type" => "application/json",
"X-Gitlab-Event" => hook_name.singularize.titleize "X-Gitlab-Event" => hook_name.singularize.titleize
}, },
verify: false, verify: enable_ssl_verification,
basic_auth: auth) basic_auth: auth)
end end
rescue SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e rescue SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
# milestone_id :integer # milestone_id :integer
# state :string(255) # state :string(255)
# iid :integer # iid :integer
# updated_by_id :integer
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
# description :text # description :text
# position :integer default(0) # position :integer default(0)
# locked_at :datetime # locked_at :datetime
# updated_by_id :integer
# #
require Rails.root.join("app/models/commit") require Rails.root.join("app/models/commit")
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
# noteable_id :integer # noteable_id :integer
# system :boolean default(FALSE), not null # system :boolean default(FALSE), not null
# st_diff :text # st_diff :text
# updated_by_id :integer
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
......
...@@ -73,6 +73,7 @@ class Project < ActiveRecord::Base ...@@ -73,6 +73,7 @@ class Project < ActiveRecord::Base
has_many :services has_many :services
has_one :gitlab_ci_service, dependent: :destroy has_one :gitlab_ci_service, dependent: :destroy
has_one :campfire_service, dependent: :destroy has_one :campfire_service, dependent: :destroy
has_one :drone_ci_service, dependent: :destroy
has_one :emails_on_push_service, dependent: :destroy has_one :emails_on_push_service, dependent: :destroy
has_one :irker_service, dependent: :destroy has_one :irker_service, dependent: :destroy
has_one :pivotaltracker_service, dependent: :destroy has_one :pivotaltracker_service, dependent: :destroy
...@@ -613,6 +614,7 @@ class Project < ActiveRecord::Base ...@@ -613,6 +614,7 @@ class Project < ActiveRecord::Base
name: name, name: name,
ssh_url: ssh_url_to_repo, ssh_url: ssh_url_to_repo,
http_url: http_url_to_repo, http_url: http_url_to_repo,
web_url: web_url,
namespace: namespace.name, namespace: namespace.name,
visibility_level: visibility_level visibility_level: visibility_level
} }
......
...@@ -23,7 +23,7 @@ require "addressable/uri" ...@@ -23,7 +23,7 @@ require "addressable/uri"
class BuildkiteService < CiService class BuildkiteService < CiService
ENDPOINT = "https://buildkite.com" ENDPOINT = "https://buildkite.com"
prop_accessor :project_url, :token prop_accessor :project_url, :token, :enable_ssl_verification
validates :project_url, presence: true, if: :activated? validates :project_url, presence: true, if: :activated?
validates :token, presence: true, if: :activated? validates :token, presence: true, if: :activated?
...@@ -37,6 +37,7 @@ class BuildkiteService < CiService ...@@ -37,6 +37,7 @@ class BuildkiteService < CiService
def compose_service_hook def compose_service_hook
hook = service_hook || build_service_hook hook = service_hook || build_service_hook
hook.url = webhook_url hook.url = webhook_url
hook.enable_ssl_verification = enable_ssl_verification
hook.save hook.save
end end
...@@ -96,7 +97,11 @@ class BuildkiteService < CiService ...@@ -96,7 +97,11 @@ class BuildkiteService < CiService
{ type: 'text', { type: 'text',
name: 'project_url', name: 'project_url',
placeholder: "#{ENDPOINT}/example/project" } placeholder: "#{ENDPOINT}/example/project" },
{ type: 'checkbox',
name: 'enable_ssl_verification',
title: "Enable SSL verification" }
] ]
end end
......
...@@ -26,11 +26,23 @@ class CiService < Service ...@@ -26,11 +26,23 @@ class CiService < Service
:ci :ci
end end
def valid_token?(token)
self.respond_to?(:token) && self.token.present? && self.token == token
end
def supported_events def supported_events
%w(push) %w(push)
end end
# Return complete url to build page def merge_request_page(iid, sha, ref)
commit_page(sha, ref)
end
def commit_page(sha, ref)
build_page(sha, ref)
end
# Return complete url to merge_request page
# #
# Ex. # Ex.
# http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c # http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c
...@@ -45,10 +57,27 @@ class CiService < Service ...@@ -45,10 +57,27 @@ class CiService < Service
# #
# #
# Ex. # Ex.
# @service.commit_status('13be4ac') # @service.merge_request_status(9, '13be4ac', 'dev')
# # => 'success'
#
# @service.merge_request_status(10, '2abe4ac', 'dev)
# # => 'running'
#
#
def merge_request_status(iid, sha, ref)
commit_status(sha, ref)
end
# Return string with build status or :error symbol
#
# Allowed states: 'success', 'failed', 'running', 'pending', 'skipped'
#
#
# Ex.
# @service.commit_status('13be4ac', 'master')
# # => 'success' # # => 'success'
# #
# @service.commit_status('2abe4ac') # @service.commit_status('2abe4ac', 'dev')
# # => 'running' # # => 'running'
# #
# #
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
# push_events :boolean default(TRUE)
# issues_events :boolean default(TRUE)
# merge_requests_events :boolean default(TRUE)
# tag_push_events :boolean default(TRUE)
# note_events :boolean default(TRUE), not null
#
class DroneCiService < CiService
prop_accessor :drone_url, :token, :enable_ssl_verification
validates :drone_url,
presence: true,
format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated?
validates :token,
presence: true,
format: { with: /\A([A-Za-z0-9]+)\z/ }, if: :activated?
after_save :compose_service_hook, if: :activated?
def compose_service_hook
hook = service_hook || build_service_hook
hook.url = [drone_url, "/api/hook", "?owner=#{project.namespace.path}", "&name=#{project.path}", "&access_token=#{token}"].join
hook.enable_ssl_verification = enable_ssl_verification
hook.save
end
def execute(data)
case data[:object_kind]
when 'push'
service_hook.execute(data) if push_valid?(data)
when 'merge_request'
service_hook.execute(data) if merge_request_valid?(data)
when 'tag_push'
service_hook.execute(data) if tag_push_valid?(data)
end
end
def allow_target_ci?
true
end
def supported_events
%w(push merge_request tag_push)
end
def merge_request_status_path(iid, sha = nil, ref = nil)
url = [drone_url,
"gitlab/#{project.namespace.path}/#{project.path}/pulls/#{iid}",
"?access_token=#{token}"]
URI.join(*url).to_s
end
def commit_status_path(sha, ref)
url = [drone_url,
"gitlab/#{project.namespace.path}/#{project.path}/commits/#{sha}",
"?branch=#{URI::encode(ref.to_s)}&access_token=#{token}"]
URI.join(*url).to_s
end
def merge_request_status(iid, sha, ref)
response = HTTParty.get(merge_request_status_path(iid), verify: enable_ssl_verification)
if response.code == 200 and response['status']
case response['status']
when 'killed'
:canceled
when 'failure', 'error'
# Because drone return error if some test env failed
:failed
else
response["status"]
end
else
:error
end
rescue Errno::ECONNREFUSED
:error
end
def commit_status(sha, ref)
response = HTTParty.get(commit_status_path(sha, ref), verify: enable_ssl_verification)
if response.code == 200 and response['status']
case response['status']
when 'killed'
:canceled
when 'failure', 'error'
# Because drone return error if some test env failed
:failed
else
response["status"]
end
else
:error
end
rescue Errno::ECONNREFUSED
:error
end
def merge_request_page(iid, sha, ref)
url = [drone_url,
"gitlab/#{project.namespace.path}/#{project.path}/redirect/pulls/#{iid}"]
URI.join(*url).to_s
end
def commit_page(sha, ref)
url = [drone_url,
"gitlab/#{project.namespace.path}/#{project.path}/redirect/commits/#{sha}",
"?branch=#{URI::encode(ref.to_s)}"]
URI.join(*url).to_s
end
def commit_coverage(sha, ref)
nil
end
def build_page(sha, ref)
commit_page(sha, ref)
end
def builds_path
url = [drone_url, "#{project.namespace.path}/#{project.path}"]
URI.join(*url).to_s
end
def status_img_path
url = [drone_url,
"api/badges/#{project.namespace.path}/#{project.path}/status.svg",
"?branch=#{URI::encode(project.default_branch)}"]
URI.join(*url).to_s
end
def title
'Drone CI'
end
def description
'Drone is a Continuous Integration platform built on Docker, written in Go'
end
def to_param
'drone_ci'
end
def fields
[
{ type: 'text', name: 'token', placeholder: 'Drone CI project specific token' },
{ type: 'text', name: 'drone_url', placeholder: 'http://drone.example.com' },
{ type: 'checkbox', name: 'enable_ssl_verification', title: "Enable SSL verification" }
]
end
private
def tag_push_valid?(data)
data[:total_commits_count] > 0 && !Gitlab::Git.blank_ref?(data[:after])
end
def push_valid?(data)
opened_merge_requests = project.merge_requests.opened.where(source_project_id: project.id,
source_branch: Gitlab::Git.ref_name(data[:ref]))
opened_merge_requests.empty? && data[:total_commits_count] > 0 &&
!Gitlab::Git.blank_ref?(data[:after])
end
def merge_request_valid?(data)
['opened', 'reopened'].include?(data[:object_attributes][:state]) &&
data[:object_attributes][:merge_status] == 'unchecked'
end
end
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
class GitlabCiService < CiService class GitlabCiService < CiService
API_PREFIX = "api/v1" API_PREFIX = "api/v1"
prop_accessor :project_url, :token prop_accessor :project_url, :token, :enable_ssl_verification
validates :project_url, validates :project_url,
presence: true, presence: true,
format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated? format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated?
...@@ -34,6 +34,7 @@ class GitlabCiService < CiService ...@@ -34,6 +34,7 @@ class GitlabCiService < CiService
def compose_service_hook def compose_service_hook
hook = service_hook || build_service_hook hook = service_hook || build_service_hook
hook.url = [project_url, "/build", "?token=#{token}"].join("") hook.url = [project_url, "/build", "?token=#{token}"].join("")
hook.enable_ssl_verification = enable_ssl_verification
hook.save hook.save
end end
...@@ -136,7 +137,8 @@ class GitlabCiService < CiService ...@@ -136,7 +137,8 @@ class GitlabCiService < CiService
def fields def fields
[ [
{ type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' }, { type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' },
{ type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' } { type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' },
{ type: 'checkbox', name: 'enable_ssl_verification', title: "Enable SSL verification" }
] ]
end end
......
# == Schema Information
#
# Table name: sent_notifications
#
# id :integer not null, primary key
# project_id :integer
# noteable_id :integer
# noteable_type :string(255)
# recipient_id :integer
# commit_id :string(255)
# reply_key :string(255) not null
#
class SentNotification < ActiveRecord::Base class SentNotification < ActiveRecord::Base
belongs_to :project belongs_to :project
belongs_to :noteable, polymorphic: true belongs_to :noteable, polymorphic: true
......
...@@ -135,6 +135,7 @@ class Service < ActiveRecord::Base ...@@ -135,6 +135,7 @@ class Service < ActiveRecord::Base
buildkite buildkite
campfire campfire
custom_issue_tracker custom_issue_tracker
drone_ci
emails_on_push emails_on_push
external_wiki external_wiki
flowdock flowdock
......
...@@ -42,13 +42,9 @@ ...@@ -42,13 +42,9 @@
# unconfirmed_email :string(255) # unconfirmed_email :string(255)
# hide_no_ssh_key :boolean default(FALSE) # hide_no_ssh_key :boolean default(FALSE)
# website_url :string(255) default(""), not null # website_url :string(255) default(""), not null
# github_access_token :string(255)
# gitlab_access_token :string(255)
# notification_email :string(255) # notification_email :string(255)
# hide_no_password :boolean default(FALSE) # hide_no_password :boolean default(FALSE)
# password_automatically_set :boolean default(FALSE) # password_automatically_set :boolean default(FALSE)
# bitbucket_access_token :string(255)
# bitbucket_access_token_secret :string(255)
# location :string(255) # location :string(255)
# encrypted_otp_secret :string(255) # encrypted_otp_secret :string(255)
# encrypted_otp_secret_iv :string(255) # encrypted_otp_secret_iv :string(255)
...@@ -104,7 +100,7 @@ class User < ActiveRecord::Base ...@@ -104,7 +100,7 @@ class User < ActiveRecord::Base
# Profile # Profile
has_many :keys, dependent: :destroy has_many :keys, dependent: :destroy
has_many :emails, dependent: :destroy has_many :emails, dependent: :destroy
has_many :identities, dependent: :destroy has_many :identities, dependent: :destroy, autosave: true
# Groups # Groups
has_many :members, dependent: :destroy has_many :members, dependent: :destroy
...@@ -637,10 +633,6 @@ class User < ActiveRecord::Base ...@@ -637,10 +633,6 @@ class User < ActiveRecord::Base
email.start_with?('temp-email-for-oauth') email.start_with?('temp-email-for-oauth')
end end
def public_profile?
authorized_projects.public_only.any?
end
def avatar_url(size = nil) def avatar_url(size = nil)
if avatar.present? if avatar.present?
[gitlab_config.url, avatar.url].join [gitlab_config.url, avatar.url].join
......
...@@ -107,12 +107,17 @@ class NotificationService ...@@ -107,12 +107,17 @@ class NotificationService
recipients = [] recipients = []
mentioned_users = note.mentioned_users
mentioned_users.select! do |user|
user.can?(:read_project, note.project)
end
# Add all users participating in the thread (author, assignee, comment authors) # Add all users participating in the thread (author, assignee, comment authors)
participants = participants =
if target.respond_to?(:participants) if target.respond_to?(:participants)
target.participants(note.author) target.participants(note.author)
else else
note.mentioned_users mentioned_users
end end
recipients = recipients.concat(participants) recipients = recipients.concat(participants)
...@@ -120,8 +125,8 @@ class NotificationService ...@@ -120,8 +125,8 @@ class NotificationService
recipients = add_project_watchers(recipients, note.project) recipients = add_project_watchers(recipients, note.project)
# Reject users with Mention notification level, except those mentioned in _this_ note. # Reject users with Mention notification level, except those mentioned in _this_ note.
recipients = reject_mention_users(recipients - note.mentioned_users, note.project) recipients = reject_mention_users(recipients - mentioned_users, note.project)
recipients = recipients + note.mentioned_users recipients = recipients + mentioned_users
recipients = reject_muted_users(recipients, note.project) recipients = reject_muted_users(recipients, note.project)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
%tr %tr
%td %td
- if reporter - if reporter
= link_to reporter.name, [:admin, reporter] = link_to reporter.name, reporter
- else - else
(removed) (removed)
%td %td
...@@ -12,12 +12,15 @@ ...@@ -12,12 +12,15 @@
= abuse_report.message = abuse_report.message
%td %td
- if user - if user
= link_to user.name, [:admin, user] = link_to user.name, user
- else - else
(removed) (removed)
%td %td
- if user - if user
= link_to 'Block', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs btn-warning" = link_to 'Remove user & report', admin_abuse_report_path(abuse_report, remove_user: true),
= link_to 'Remove user', [:admin, user], data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, method: :delete, class: "btn btn-xs btn-remove" data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, remote: true, method: :delete, class: "btn btn-xs btn-remove js-remove-tr"
%td %td
= link_to 'Remove report', [:admin, abuse_report], method: :delete, class: "btn btn-xs btn-close" - if user
= link_to 'Block user', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs"
= link_to 'Remove report', [:admin, abuse_report], remote: true, method: :delete, class: "btn btn-xs btn-close js-remove-tr"
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
%th Reported at %th Reported at
%th Message %th Message
%th User %th User
%th %th Primary action
%th %th
= render @abuse_reports = render @abuse_reports
= paginate @abuse_reports = paginate @abuse_reports
......
...@@ -18,6 +18,13 @@ ...@@ -18,6 +18,13 @@
= f.label :url, "URL:", class: 'control-label' = f.label :url, "URL:", class: 'control-label'
.col-sm-10 .col-sm-10
= f.text_field :url, class: "form-control" = f.text_field :url, class: "form-control"
.form-group
= f.label :enable_ssl_verification, "SSL verification", class: 'control-label checkbox'
.col-sm-10
.checkbox
= f.label :enable_ssl_verification do
= f.check_box :enable_ssl_verification
%strong Enable SSL verification
.form-actions .form-actions
= f.submit "Add System Hook", class: "btn btn-create" = f.submit "Add System Hook", class: "btn btn-create"
%hr %hr
...@@ -32,6 +39,7 @@ ...@@ -32,6 +39,7 @@
.list-item-name .list-item-name
= link_to admin_hook_path(hook) do = link_to admin_hook_path(hook) do
%strong= hook.url %strong= hook.url
%p SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"}
.pull-right .pull-right
= link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-sm" = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-sm"
......
.hidden-xs .hidden-xs
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
.gray-content-block
- if current_user - if current_user
%ul.nav.nav-pills.event_filter.pull-right %ul.nav.nav-pills.event_filter.pull-right
%li.pull-right %li.pull-right
= link_to dashboard_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do = link_to dashboard_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do
%i.fa.fa-rss %i.fa.fa-rss
= render 'shared/event_filter' = render 'shared/event_filter'
%hr
.content_list .content_list
= spinner = spinner
%ul.center-top-menu
%li{ class: ("active" unless params[:filter]) }
= link_to activity_dashboard_path, class: 'shortcuts-activity', data: {placement: 'right'} do
Your Projects
%li{ class: ("active" if params[:filter] == 'starred') }
= link_to activity_dashboard_path(filter: 'starred'), data: {placement: 'right'} do
Starred Projects
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
= link_to dashboard_groups_path, title: 'Your groups', data: {placement: 'right'} do = link_to dashboard_groups_path, title: 'Your groups', data: {placement: 'right'} do
Your Groups Your Groups
= nav_link(page: [explore_groups_path]) do = nav_link(page: [explore_groups_path]) do
= link_to explore_groups_path, title: 'Explore groups', data: {toggle: 'tooltip', placement: 'bottom'} do = link_to explore_groups_path, title: 'Explore groups', data: {placement: 'bottom'} do
Explore Groups Explore Groups
.panel.panel-default .projects-list-holder
.panel-heading.clearfix .projects-search-form
.input-group .input-group
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control' = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
- if current_user.can_create_project? - if current_user.can_create_project?
...@@ -7,4 +7,4 @@ ...@@ -7,4 +7,4 @@
= link_to new_project_path, class: 'btn btn-success' do = link_to new_project_path, class: 'btn btn-success' do
New project New project
= render 'shared/projects_list', projects: @projects, projects_limit: 20 = render 'shared/projects/list', projects: @projects
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
= nav_link(page: starred_dashboard_projects_path) do = nav_link(page: starred_dashboard_projects_path) do
= link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do = link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do
Starred Projects Starred Projects
= nav_link(page: [explore_root_path, trending_explore_projects_path, starred_explore_projects_path, explore_projects_path]) do = nav_link(page: [explore_root_path, trending_explore_projects_path, starred_explore_projects_path, explore_projects_path], html_options: { class: 'hidden-xs' }) do
= link_to explore_root_path, title: 'Explore', data: {toggle: 'tooltip', placement: 'bottom'} do = link_to explore_root_path, title: 'Explore', data: {placement: 'right'} do
Explore Projects Explore Projects
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment