Commit be4d3403 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' of dev.gitlab.org:gitlab/gitlabhq into ce-to-ee

Conflicts:
	Gemfile.lock
	app/controllers/uploads_controller.rb
	app/models/application_setting.rb
	app/models/project_services/issue_tracker_service.rb
	app/views/projects/services/_form.html.haml
	db/schema.rb
	doc/integration/README.md
	features/steps/groups.rb
parents c5f7714d f186b20c
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 7.9.0 (unreleased) v 7.9.0 (unreleased)
- Fix mass SQL statements on initial push (Hannes Rosenögger)
- Add tag push notifications and normalize HipChat and Slack messages to be consistent (Stan Hu)
- Add comment notification events to HipChat and Slack services (Stan Hu)
- Add issue and merge request events to HipChat and Slack services (Stan Hu)
- Fix merge request URL passed to Webhooks. (Stan Hu) - Fix merge request URL passed to Webhooks. (Stan Hu)
- Fix bug that caused a server error when editing a comment to "+1" or "-1" (Stan Hu) - Fix bug that caused a server error when editing a comment to "+1" or "-1" (Stan Hu)
- Fix code preview theme setting for comments, issues, merge requests, and snippets (Stan Hu)
- Move labels/milestones tabs to sidebar - Move labels/milestones tabs to sidebar
- Upgrade Rails gem to version 4.1.9. - Upgrade Rails gem to version 4.1.9.
- Improve error messages for file edit failures - Improve error messages for file edit failures
...@@ -13,6 +18,7 @@ v 7.9.0 (unreleased) ...@@ -13,6 +18,7 @@ v 7.9.0 (unreleased)
- Fix ordering of imported but unchanged projects (Marco Wessel) - Fix ordering of imported but unchanged projects (Marco Wessel)
- Mobile UI improvements: make aside content expandable - Mobile UI improvements: make aside content expandable
- Expose avatar_url in projects API - Expose avatar_url in projects API
- Fix checkbox alignment on the application settings page.
- Generalize image upload in drag and drop in markdown to all files (Hannes Rosenögger) - Generalize image upload in drag and drop in markdown to all files (Hannes Rosenögger)
- Fix mass-unassignment of issues (Robert Speicher) - Fix mass-unassignment of issues (Robert Speicher)
- Allow user confirmation to be skipped for new users via API - Allow user confirmation to be skipped for new users via API
...@@ -20,6 +26,50 @@ v 7.9.0 (unreleased) ...@@ -20,6 +26,50 @@ v 7.9.0 (unreleased)
- Ignore case of LDAP user DN when checking group membership. - Ignore case of LDAP user DN when checking group membership.
- Add brakeman (security scanner for Ruby on Rails) - Add brakeman (security scanner for Ruby on Rails)
- Slack username and channel options - Slack username and channel options
- Add grouped milestones from all projects to dashboard.
- Web hook sends pusher email as well as commiter
- Add Bitbucket omniauth provider.
- Add Bitbucket importer.
- Support referencing issues to a project whose name starts with a digit
- Condense commits already in target branch when updating merge request source branch.
- Send notifications and leave system comments when bulk updating issues.
- Automatically link commit ranges to compare page: sha1...sha4 or sha1..sha4 (includes sha1 in comparison)
- Move groups page from profile to dashboard
- Starred projects page at dashboard
- Blocking user does not remove him/her from project/groups but show blocked label
- Change subject of EmailsOnPush emails to include namespace, project and branch.
- Change subject of EmailsOnPush emails to include first commit message when multiple were pushed.
- Remove confusing footer from EmailsOnPush mail body.
- Add list of changed files to EmailsOnPush emails.
- Add option to send EmailsOnPush emails from committer email if domain matches.
- Add option to disable code diffs in EmailOnPush emails.
- Wrap commit message in EmailsOnPush email.
- Send EmailsOnPush emails when deleting commits using force push.
- Fix EmailsOnPush email comparison link to include first commit.
- Fix highliht of selected lines in file
- Reject access to group/project avatar if the user doesn't have access.
- Add database migration to clean group duplicates with same path and name (Make sure you have a backup before update)
- Add GitLab active users count to rake gitlab:check
- Starred projects page at dashboard
- Make email display name configurable
- Improve json validation in hook data
v 7.8.4
- Fix issue_tracker_id substitution in custom issue trackers
- Fix path and name duplication in namespaces
v 7.8.3
- Bump version of gitlab_git fixing annotated tags without message
v 7.8.2
- Fix service migration issue when upgrading from versions prior to 7.3
- Fix setting of the default use project limit via admin UI
- Fix showing of already imported projects for GitLab and Gitorious importers
- Fix response of push to repository to return "Not found" if user doesn't have access
- Fix check if user is allowed to view the file attachment
- Fix import check for case sensetive namespaces
- Increase timeout for Git-over-HTTP requests to 1 hour since large pulls/pushes can take a long time.
- Properly handle autosave local storage exceptions.
- Escape wildcards when searching LDAP by username.
v 7.8.1 v 7.8.1
- Fix run of custom post receive hooks - Fix run of custom post receive hooks
...@@ -27,9 +77,6 @@ v 7.8.1 ...@@ -27,9 +77,6 @@ v 7.8.1
- Fix the warning for LDAP users about need to set password - Fix the warning for LDAP users about need to set password
- Fix avatars which were not shown for non logged in users - Fix avatars which were not shown for non logged in users
- Fix urls for the issues when relative url was enabled - Fix urls for the issues when relative url was enabled
- Add Bitbucket omniauth provider.
- Add Bitbucket importer.
- Support referencing issues to a project whose name starts with a digit
v 7.8.0 v 7.8.0
- Fix access control and protection against XSS for note attachments and other uploads. - Fix access control and protection against XSS for note attachments and other uploads.
...@@ -48,7 +95,8 @@ v 7.8.0 ...@@ -48,7 +95,8 @@ v 7.8.0
- Add notes for label changes in issue and merge requests - Add notes for label changes in issue and merge requests
- Show tags in commit view (Hannes Rosenögger) - Show tags in commit view (Hannes Rosenögger)
- Only count a user's vote once on a merge request or issue (Michael Clarke) - Only count a user's vote once on a merge request or issue (Michael Clarke)
- Increate font size when browse source files and diffs - Increase font size when browse source files and diffs
- Service Templates now let you set default values for all services
- Create new file in empty repository using GitLab UI - Create new file in empty repository using GitLab UI
- Ability to clone project using oauth2 token - Ability to clone project using oauth2 token
- Upgrade Sidekiq gem to version 3.3.0 - Upgrade Sidekiq gem to version 3.3.0
......
...@@ -20,6 +20,13 @@ Please treat our volunteers with courtesy and respect, it will go a long way tow ...@@ -20,6 +20,13 @@ Please treat our volunteers with courtesy and respect, it will go a long way tow
Issues and merge requests should be in English and contain appropriate language for audiences of all ages. Issues and merge requests should be in English and contain appropriate language for audiences of all ages.
## Helping others
Please help other GitLab users when you can.
The channnels people will reach out on can be found on the [getting help page](https://about.gitlab.com/getting-help/).
Sign up for the mailinglist, answer GitLab questions on StackOverflow or respond in the irc channel.
You can also sign up on [CodeTriage](http://www.codetriage.com/gitlabhq/gitlabhq) to help with one issue every day.
## Issue tracker ## Issue tracker
To get support for your particular problem please use the channels as detailed in the [getting help section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#getting-help). Professional [support subscriptions](http://about.gitlab.com/subscription/) and [consulting services](http://about.gitlab.com/consultancy/) are available from [GitLab.com](http://about.gitlab.com/). To get support for your particular problem please use the channels as detailed in the [getting help section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#getting-help). Professional [support subscriptions](http://about.gitlab.com/subscription/) and [consulting services](http://about.gitlab.com/consultancy/) are available from [GitLab.com](http://about.gitlab.com/).
...@@ -56,6 +63,8 @@ Merge requests can be filed either at [gitlab.com](https://gitlab.com/gitlab-org ...@@ -56,6 +63,8 @@ Merge requests can be filed either at [gitlab.com](https://gitlab.com/gitlab-org
If you are new to GitLab development (or web development in general), search for the label `easyfix` ([gitlab.com](https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name=easyfix), [github](https://github.com/gitlabhq/gitlabhq/labels/easyfix)). Those are issues easy to fix, marked by the GitLab core-team. If you are unsure how to proceed but want to help, mention one of the core-team members to give you a hint. If you are new to GitLab development (or web development in general), search for the label `easyfix` ([gitlab.com](https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name=easyfix), [github](https://github.com/gitlabhq/gitlabhq/labels/easyfix)). Those are issues easy to fix, marked by the GitLab core-team. If you are unsure how to proceed but want to help, mention one of the core-team members to give you a hint.
To start with GitLab download the [GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit) and see [Development section](doc/development/README.md) in the help file.
### Merge request guidelines ### Merge request guidelines
If you can, please submit a merge request with the fix or improvements including tests. If you don't know how to fix the issue but can write a test that exposes the issue we will accept that as well. In general bug fixes that include a regression test are merged quickly while new features without proper tests are least likely to receive timely feedback. The workflow to make a merge request is as follows: If you can, please submit a merge request with the fix or improvements including tests. If you don't know how to fix the issue but can write a test that exposes the issue we will accept that as well. In general bug fixes that include a regression test are merged quickly while new features without proper tests are least likely to receive timely feedback. The workflow to make a merge request is as follows:
......
...@@ -39,7 +39,7 @@ gem "browser" ...@@ -39,7 +39,7 @@ gem "browser"
# 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.0.0.rc14' gem "gitlab_git", '7.1.0'
# Ruby/Rack Git Smart-HTTP Server Handler # Ruby/Rack Git Smart-HTTP Server Handler
gem 'gitlab-grack', '~> 2.0.0.rc2', require: 'grack' gem 'gitlab-grack', '~> 2.0.0.rc2', require: 'grack'
...@@ -179,6 +179,9 @@ gem 'ace-rails-ap' ...@@ -179,6 +179,9 @@ gem 'ace-rails-ap'
# Keyboard shortcuts # Keyboard shortcuts
gem 'mousetrap-rails' gem 'mousetrap-rails'
# Shutting down requests that take too long
gem "slowpoke"
gem "sass-rails", '~> 4.0.2' gem "sass-rails", '~> 4.0.2'
gem "coffee-rails" gem "coffee-rails"
gem "uglifier" gem "uglifier"
...@@ -252,7 +255,7 @@ group :development, :test do ...@@ -252,7 +255,7 @@ group :development, :test do
gem 'jasmine', '2.0.2' gem 'jasmine', '2.0.2'
gem "spring", '1.3.1' gem "spring", '~> 1.3.1'
gem "spring-commands-rspec", '1.0.4' gem "spring-commands-rspec", '1.0.4'
gem "spring-commands-spinach", '1.0.0' gem "spring-commands-spinach", '1.0.0'
end end
......
...@@ -149,6 +149,7 @@ GEM ...@@ -149,6 +149,7 @@ GEM
enumerize (0.7.0) enumerize (0.7.0)
activesupport (>= 3.2) activesupport (>= 3.2)
equalizer (0.0.8) equalizer (0.0.8)
errbase (0.0.2)
erubis (2.7.0) erubis (2.7.0)
escape_utils (0.2.4) escape_utils (0.2.4)
eventmachine (1.0.4) eventmachine (1.0.4)
...@@ -212,7 +213,7 @@ GEM ...@@ -212,7 +213,7 @@ GEM
mime-types (~> 1.19) mime-types (~> 1.19)
gitlab_emoji (0.0.1.1) gitlab_emoji (0.0.1.1)
emoji (~> 1.0.1) emoji (~> 1.0.1)
gitlab_git (7.0.0.rc14) gitlab_git (7.1.0)
activesupport (~> 4.0) activesupport (~> 4.0)
charlock_holmes (~> 0.6) charlock_holmes (~> 0.6)
gitlab-linguist (~> 3.0) gitlab-linguist (~> 3.0)
...@@ -429,6 +430,7 @@ GEM ...@@ -429,6 +430,7 @@ GEM
rack rack
rack-test (0.6.3) rack-test (0.6.3)
rack (>= 1.0) rack (>= 1.0)
rack-timeout (0.2.0)
rails (4.1.9) rails (4.1.9)
actionmailer (= 4.1.9) actionmailer (= 4.1.9)
actionpack (= 4.1.9) actionpack (= 4.1.9)
...@@ -482,6 +484,8 @@ GEM ...@@ -482,6 +484,8 @@ GEM
rest-client (1.6.7) rest-client (1.6.7)
mime-types (>= 1.16) mime-types (>= 1.16)
rinku (1.7.3) rinku (1.7.3)
robustly (0.0.3)
errbase
rouge (1.7.4) rouge (1.7.4)
rspec (2.99.0) rspec (2.99.0)
rspec-core (~> 2.99.0) rspec-core (~> 2.99.0)
...@@ -568,6 +572,9 @@ GEM ...@@ -568,6 +572,9 @@ GEM
temple (~> 0.6.6) temple (~> 0.6.6)
tilt (>= 1.3.3, < 2.1) tilt (>= 1.3.3, < 2.1)
slop (3.4.7) slop (3.4.7)
slowpoke (0.0.5)
rack-timeout (>= 0.1.0)
robustly
spinach (0.8.7) spinach (0.8.7)
colorize (= 0.5.8) colorize (= 0.5.8)
gherkin-ruby (>= 0.3.1) gherkin-ruby (>= 0.3.1)
...@@ -706,7 +713,7 @@ DEPENDENCIES ...@@ -706,7 +713,7 @@ DEPENDENCIES
gitlab-grack (~> 2.0.0.rc2) gitlab-grack (~> 2.0.0.rc2)
gitlab-linguist (~> 3.0.1) gitlab-linguist (~> 3.0.1)
gitlab_emoji (~> 0.0.1.1) gitlab_emoji (~> 0.0.1.1)
gitlab_git (= 7.0.0.rc14) gitlab_git (= 7.1.0)
gitlab_meta (= 7.0) gitlab_meta (= 7.0)
gitlab_omniauth-ldap (= 1.2.0) gitlab_omniauth-ldap (= 1.2.0)
gollum-lib (~> 4.0.0) gollum-lib (~> 4.0.0)
...@@ -779,8 +786,9 @@ DEPENDENCIES ...@@ -779,8 +786,9 @@ DEPENDENCIES
six six
slack-notifier (~> 1.0.0) slack-notifier (~> 1.0.0)
slim slim
slowpoke
spinach-rails spinach-rails
spring (= 1.3.1) spring (~> 1.3.1)
spring-commands-rspec (= 1.0.4) spring-commands-rspec (= 1.0.4)
spring-commands-spinach (= 1.0.0) spring-commands-spinach (= 1.0.0)
stamp stamp
......
...@@ -57,8 +57,6 @@ To get access to the EE and support please [become a subscriber](https://about.g ...@@ -57,8 +57,6 @@ To get access to the EE and support please [become a subscriber](https://about.g
- [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master) - [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master)
- [![PullReview stats](https://www.pullreview.com/gitlab/gitlab-org/gitlab-ce/badges/master.svg?)](https://www.pullreview.com/gitlab.gitlab.com/gitlab-org/gitlab-ce/reviews/master)
## Website ## Website
On [about.gitlab.com](https://about.gitlab.com/) you can find more information about: On [about.gitlab.com](https://about.gitlab.com/) you can find more information about:
......
...@@ -14,7 +14,11 @@ class @Autosave ...@@ -14,7 +14,11 @@ class @Autosave
restore: -> restore: ->
return unless window.localStorage? return unless window.localStorage?
text = window.localStorage.getItem @key try
text = window.localStorage.getItem @key
catch
return
@field.val text if text?.length > 0 @field.val text if text?.length > 0
@field.trigger "input" @field.trigger "input"
...@@ -23,11 +27,13 @@ class @Autosave ...@@ -23,11 +27,13 @@ class @Autosave
text = @field.val() text = @field.val()
if text?.length > 0 if text?.length > 0
window.localStorage.setItem @key, text try
window.localStorage.setItem @key, text
else else
@reset() @reset()
reset: -> reset: ->
return unless window.localStorage? return unless window.localStorage?
window.localStorage.removeItem @key try
\ No newline at end of file window.localStorage.removeItem @key
...@@ -26,7 +26,7 @@ class @BlobView ...@@ -26,7 +26,7 @@ class @BlobView
unless isNaN first_line unless isNaN first_line
$("#tree-content-holder .highlight .line").removeClass("hll") $("#tree-content-holder .highlight .line").removeClass("hll")
$("#LC#{line}").addClass("hll") for line in [first_line..last_line] $("#LC#{line}").addClass("hll") for line in [first_line..last_line]
$.scrollTo("#L#{first_line}") unless e? $.scrollTo("#L#{first_line}", offset: -50) unless e?
# parse selected lines from hash # parse selected lines from hash
# always return first and last line (initialized to NaN) # always return first and last line (initialized to NaN)
......
...@@ -15,7 +15,7 @@ class @EditBlob ...@@ -15,7 +15,7 @@ class @EditBlob
$(".js-commit-button").click -> $(".js-commit-button").click ->
$("#file-content").val editor.getValue() $("#file-content").val editor.getValue()
$(".file-editor form").submit() $(".file-editor form").submit()
return return false
editModePanes = $(".js-edit-mode-pane") editModePanes = $(".js-edit-mode-pane")
editModeLinks = $(".js-edit-mode a") editModeLinks = $(".js-edit-mode a")
......
...@@ -15,7 +15,7 @@ class @NewBlob ...@@ -15,7 +15,7 @@ class @NewBlob
$(".js-commit-button").click -> $(".js-commit-button").click ->
$("#file-content").val editor.getValue() $("#file-content").val editor.getValue()
$(".file-editor form").submit() $(".file-editor form").submit()
return return false
editor: -> editor: ->
return @editor return @editor
class @Dashboard class @Dashboard
constructor: -> constructor: ->
@initSidebarTab() new ProjectsList()
$(".dash-filter").keyup ->
terms = $(this).val()
uiBox = $(this).parents('.panel').first()
if terms == "" || terms == undefined
uiBox.find(".dash-list li").show()
else
uiBox.find(".dash-list li").each (index) ->
name = $(this).find(".filter-title").text()
if name.toLowerCase().search(terms.toLowerCase()) == -1
$(this).hide()
else
$(this).show()
initSidebarTab: ->
key = "dashboard_sidebar_filter"
# store selection in cookie
$('.dash-sidebar-tabs a').on 'click', (e) ->
$.cookie(key, $(e.target).attr('id'))
# show tab from cookie
sidebar_filter = $.cookie(key)
$("#" + sidebar_filter).tab('show') if sidebar_filter
...@@ -33,12 +33,16 @@ class Dispatcher ...@@ -33,12 +33,16 @@ class Dispatcher
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
new ZenMode() new ZenMode()
new DropzoneInput($('.issue-form')) new DropzoneInput($('.issue-form'))
if page == 'projects:issues:new'
new IssuableForm($('.issue-form'))
when 'projects:merge_requests:new', 'projects:merge_requests:edit' when 'projects:merge_requests:new', 'projects:merge_requests:edit'
GitLab.GfmAutoComplete.setup() GitLab.GfmAutoComplete.setup()
new Diff() new Diff()
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
new ZenMode() new ZenMode()
new DropzoneInput($('.merge-request-form')) new DropzoneInput($('.merge-request-form'))
if page == 'projects:merge_requests:new'
new IssuableForm($('.merge-request-form'))
when 'projects:merge_requests:show' when 'projects:merge_requests:show'
new Diff() new Diff()
shortcut_handler = new ShortcutsIssueable() shortcut_handler = new ShortcutsIssueable()
...@@ -51,6 +55,9 @@ class Dispatcher ...@@ -51,6 +55,9 @@ class Dispatcher
when 'dashboard:show' when 'dashboard:show'
new Dashboard() new Dashboard()
new Activities() new Activities()
when 'dashboard:projects:starred'
new Activities()
new ProjectsList()
when 'projects:commit:show' when 'projects:commit:show'
new Commit() new Commit()
new Diff() new Diff()
...@@ -58,9 +65,13 @@ class Dispatcher ...@@ -58,9 +65,13 @@ class Dispatcher
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
when 'projects:commits:show' when 'projects:commits:show'
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
when 'groups:show', 'projects:show' when 'projects:show'
new Activities()
shortcut_handler = new ShortcutsNavigation()
when 'groups:show'
new Activities() new Activities()
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
new ProjectsList()
when 'groups:members' when 'groups:members'
new GroupMembers() new GroupMembers()
new UsersSelect() new UsersSelect()
......
class @IssuableForm
constructor: (@form) ->
@titleField = @form.find("input[name*='[title]']")
@descriptionField = @form.find("textarea[name*='[description]']")
return unless @titleField.length && @descriptionField.length
@initAutosave()
@form.on "submit", @resetAutosave
@form.on "click", ".btn-cancel", @resetAutosave
initAutosave: ->
new Autosave @titleField, [
document.location.pathname,
document.location.search,
"title"
]
new Autosave @descriptionField, [
document.location.pathname,
document.location.search,
"description"
]
resetAutosave: =>
@titleField.data("autosave").reset()
@descriptionField.data("autosave").reset()
...@@ -49,6 +49,13 @@ class @Milestone ...@@ -49,6 +49,13 @@ class @Milestone
data: data data: data
success: (data) -> success: (data) ->
if data.saved == true if data.saved == true
if data.assignee_avatar_url
img_tag = $('<img/>')
img_tag.attr('src', data.assignee_avatar_url)
img_tag.addClass('avatar s16')
$(li).find('.assignee-icon').html(img_tag)
else
$(li).find('.assignee-icon').html('')
$(li).effect 'highlight' $(li).effect 'highlight'
else else
new Flash("Issue update failed", 'alert') new Flash("Issue update failed", 'alert')
......
...@@ -6,7 +6,7 @@ class @ProjectShow ...@@ -6,7 +6,7 @@ class @ProjectShow
new Flash('Star toggle failed. Try again later.', 'alert') new Flash('Star toggle failed. Try again later.', 'alert')
$("a[data-toggle='tab']").on "shown.bs.tab", (e) -> $("a[data-toggle='tab']").on "shown.bs.tab", (e) ->
$.cookie "default_view", $(e.target).attr("href"), { expires: 30 } $.cookie "default_view", $(e.target).attr("href"), { expires: 30, path: '/' }
defaultView = $.cookie("default_view") defaultView = $.cookie("default_view")
if defaultView if defaultView
......
class @ProjectsList
constructor: ->
$(".projects-list .js-expand").on 'click', (e) ->
e.preventDefault()
list = $(this).closest('.projects-list')
list.find("li").show()
list.find("li.bottom").hide()
$(".projects-list-filter").keyup ->
terms = $(this).val()
uiBox = $(this).closest('.panel')
if terms == "" || terms == undefined
uiBox.find(".projects-list li").show()
else
uiBox.find(".projects-list li").each (index) ->
name = $(this).find(".filter-title").text()
if name.toLowerCase().search(terms.toLowerCase()) == -1
$(this).hide()
else
$(this).show()
uiBox.find(".projects-list li.bottom").hide()
class @User class @User
constructor: -> constructor: ->
$('.profile-groups-avatars').tooltip("placement": "top") $('.profile-groups-avatars').tooltip("placement": "top")
new ProjectsList()
...@@ -11,12 +11,17 @@ ...@@ -11,12 +11,17 @@
*= require cal-heatmap *= require cal-heatmap
*/ */
@import "main/*";
@import "base/variables";
@import "base/mixins";
@import "base/layout";
/** /**
* Customized Twitter bootstrap * Customized Twitter bootstrap
*/ */
@import 'gl_bootstrap'; @import 'base/gl_variables';
@import 'base/gl_bootstrap';
/** /**
* NProgress load bar css * NProgress load bar css
...@@ -39,7 +44,7 @@ ...@@ -39,7 +44,7 @@
* Page specific styles (issues, projects etc): * Page specific styles (issues, projects etc):
*/ */
@import "sections/*"; @import "pages/*";
/** /**
* Code highlight * Code highlight
......
...@@ -3,11 +3,6 @@ ...@@ -3,11 +3,6 @@
* *
*/ */
$font-size-base: 13px !default;
$nav-pills-active-link-hover-bg: $bg_primary;
$pagination-active-bg: $bg_primary;
$list-group-active-bg: $bg_primary;
// Core variables and mixins // Core variables and mixins
@import "bootstrap/variables"; @import "bootstrap/variables";
@import "bootstrap/mixins"; @import "bootstrap/mixins";
...@@ -23,6 +18,7 @@ $list-group-active-bg: $bg_primary; ...@@ -23,6 +18,7 @@ $list-group-active-bg: $bg_primary;
@import "bootstrap/grid"; @import "bootstrap/grid";
@import "bootstrap/tables"; @import "bootstrap/tables";
@import "bootstrap/forms"; @import "bootstrap/forms";
@import "bootstrap/buttons";
// Components // Components
@import "bootstrap/component-animations"; @import "bootstrap/component-animations";
...@@ -134,10 +130,6 @@ $list-group-active-bg: $bg_primary; ...@@ -134,10 +130,6 @@ $list-group-active-bg: $bg_primary;
} }
} }
} }
&.nav-small-tabs > li > a {
padding: 6px 9px;
}
} }
.nav-tabs > li > a, .nav-tabs > li > a,
...@@ -145,61 +137,6 @@ $list-group-active-bg: $bg_primary; ...@@ -145,61 +137,6 @@ $list-group-active-bg: $bg_primary;
color: #666; color: #666;
} }
.nav-compact > li > a {
padding: 6px 12px;
}
.nav-small > li > a {
padding: 3px 5px;
font-size: 12px;
}
/*
* Callouts from Bootstrap3 docs
*
* Not quite alerts, but custom and helpful notes for folks reading the docs.
* Requires a base and modifier class.
*/
/* Common styles for all types */
.bs-callout {
margin: 20px 0;
padding: 20px;
border-left: 3px solid #eee;
color: #666;
background: #f9f9f9;
}
.bs-callout h4 {
margin-top: 0;
margin-bottom: 5px;
}
.bs-callout p:last-child {
margin-bottom: 0;
}
/* Variations */
.bs-callout-danger {
background-color: #fdf7f7;
border-color: #eed3d7;
color: #b94a48;
}
.bs-callout-warning {
background-color: #faf8f0;
border-color: #faebcc;
color: #8a6d3b;
}
.bs-callout-info {
background-color: #f4f8fa;
border-color: #bce8f1;
color: #34789a;
}
.bs-callout-success {
background-color: #dff0d8;
border-color: #5cA64d;
color: #3c763d;
}
/** /**
* fix to keep tooltips position in top navigation bar * fix to keep tooltips position in top navigation bar
* *
...@@ -214,16 +151,13 @@ $list-group-active-bg: $bg_primary; ...@@ -214,16 +151,13 @@ $list-group-active-bg: $bg_primary;
* *
*/ */
.panel { .panel {
@include border-radius(0px);
.panel-heading { .panel-heading {
@include border-radius(0px);
font-size: 14px; font-size: 14px;
line-height: 18px; line-height: 18px;
.panel-head-actions { .panel-head-actions {
position: relative; position: relative;
top: -7px; top: -6px;
float: right; float: right;
} }
} }
...@@ -256,40 +190,10 @@ $list-group-active-bg: $bg_primary; ...@@ -256,40 +190,10 @@ $list-group-active-bg: $bg_primary;
} }
} }
.panel-default { .alert {
.panel-heading { a {
background-color: #EEE; @extend .alert-link;
} color: #fff;
} text-decoration: underline;
.panel-danger {
@include panel-colored;
.panel-heading {
color: $border_danger;
border-color: $border_danger;
}
}
.panel-success {
@include panel-colored;
.panel-heading {
color: $border_success;
border-color: $border_success;
}
}
.panel-primary {
@include panel-colored;
.panel-heading {
color: $border_primary;
border-color: $border_primary;
}
}
.panel-warning {
@include panel-colored;
.panel-heading {
color: $border_warning;
border-color: $border_warning;
} }
} }
This diff is collapsed.
...@@ -4,7 +4,7 @@ html { ...@@ -4,7 +4,7 @@ html {
&.touch .tooltip { display: none !important; } &.touch .tooltip { display: none !important; }
body { body {
padding-top: 47px; padding-top: 46px;
} }
} }
......
...@@ -121,14 +121,6 @@ ...@@ -121,14 +121,6 @@
} }
} }
@mixin page-title {
color: #333;
line-height: 1.5;
font-weight: normal;
margin-top: 0px;
margin-bottom: 10px;
}
@mixin str-truncated($max_width: 82%) { @mixin str-truncated($max_width: 82%) {
display: inline-block; display: inline-block;
overflow: hidden; overflow: hidden;
...@@ -137,14 +129,3 @@ ...@@ -137,14 +129,3 @@
white-space: nowrap; white-space: nowrap;
max-width: $max_width; max-width: $max_width;
} }
@mixin panel-colored {
border: 1px solid #EEE;
background: $box_bg;
@include box-shadow(0 1px 1px rgba(0, 0, 0, 0.09));
.panel-heading {
font-weight: bold;
background-color: $box_bg;
}
}
/*
* General Colors
*/
$style_color: #474D57; $style_color: #474D57;
$hover: #FFF3EB; $hover: #FFF3EB;
$box_bg: #F9F9F9; $box_bg: #F9F9F9;
$gl-link-color: #446e9b;
$nprogress-color: #c0392b;
$gl-font-size: 14px;
$list-font-size: 15px;
$sidebar_width: 230px;
$avatar_radius: 50%;
$code_font_size: 13px;
$code_line_height: 1.5;
/* /*
* Link colors * State colors:
*/ */
$link_color: #446e9b; $gl-success: #019875;
$link_hover_color: darken($link-color, 10%); $gl-danger: #d9534f;
$gl-primary: #446e9b;
$btn-border: 1px solid #ccc; $gl-info: #029ACF;
$gl-warning: #EB9532;
/*
* Success colors (green) $gl-primary: #2C3E50;
*/ $gl-success: #18BC9C;
$border_success: #019875; $gl-info: #3498DB;
$bg_success: #019875; $gl-warning: #F39C12;
$gl-danger: #E74C3C;
/*
* Danger colors (red)
*/
$border_danger: #d43f3a;
$bg_danger: #d9534f;
/*
* Primary colors (blue)
*/
$border_primary: #446e9b;
$bg_primary: #446e9b;
/* /*
* Warning colors (yellow)
*/
$bg_warning: #EB9532;
$border_warning: #EB9532;
/**
* Commit Diff Colors * Commit Diff Colors
*/ */
$added: #63c363; $added: #63c363;
$deleted: #f77; $deleted: #f77;
/** /*
* NProgress customize * Fonts
*/
$nprogress-color: #c0392b;
/**
* Font sizes
*/
$list-font-size: 15px;
/**
* Sidebar navigation width
*/ */
$sidebar_width: 230px; $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;
$avatar_radius: 50%;
$code_font_size: 13px;
$code_line_height: 1.5;
.btn { .btn {
display: inline-block; @extend .btn-default;
margin-bottom: 0;
font-weight: normal;
text-align: center;
vertical-align: middle;
cursor: pointer;
background-image: none;
border: $btn-border;
white-space: nowrap;
padding: 6px 12px;
font-size: 13px;
line-height: 18px;
border-radius: 4px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
color: #444444;
background-color: #fff;
text-shadow: none;
&.hover,
&:hover {
color: #444444;
text-decoration: none;
background-color: #ebebeb;
border-color: #adadad;
}
&.focus,
&:focus {
color: #444444;
text-decoration: none;
outline: thin dotted #333;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
&.active,
&:active {
outline: 0;
background-image: none;
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
&.disabled,
&[disabled] {
cursor: not-allowed;
pointer-events: none;
opacity: 0.65;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
box-shadow: none;
}
&.btn-primary {
color: #ffffff;
background-color: $bg_primary;
border-color: $border_primary;
&.hover,
&:hover,
&.disabled,
&[disabled] {
color: #ffffff;
}
}
&.btn-success {
color: #ffffff;
background-color: $bg_success;
border-color: $border_success;
&.hover,
&:hover,
&.disabled,
&[disabled] {
color: #ffffff;
}
}
&.btn-danger {
color: #ffffff;
background-color: $bg_danger;
border-color: $border_danger;
&.hover,
&:hover,
&.disabled,
&[disabled] {
color: #ffffff;
}
}
&.btn-warning {
color: #ffffff;
background-color: $bg_warning;
border-color: $border_warning;
&.hover,
&:hover,
&.disabled,
&[disabled] {
color: #ffffff;
}
}
&.btn-new { &.btn-new {
@extend .btn-success; @extend .btn-success;
} }
&.btn-create { &.btn-create {
@extend .wide;
@extend .btn-success; @extend .btn-success;
} }
&.btn-save { &.btn-save {
@extend .wide;
@extend .btn-primary; @extend .btn-primary;
} }
...@@ -133,11 +21,6 @@ ...@@ -133,11 +21,6 @@
float: right; float: right;
} }
&.wide {
padding-left: 20px;
padding-right: 20px;
}
&.btn-small { &.btn-small {
padding: 2px 10px; padding: 2px 10px;
font-size: 12px; font-size: 12px;
...@@ -151,16 +34,16 @@ ...@@ -151,16 +34,16 @@
} }
&.btn-close { &.btn-close {
color: $bg_danger; color: $gl-danger;
border-color: $border_danger; border-color: $gl-danger;
&:hover { &:hover {
color: #B94A48; color: #B94A48;
} }
} }
&.btn-reopen { &.btn-reopen {
color: $bg_success; color: $gl-success;
border-color: $border_success; border-color: $gl-success;
&:hover { &:hover {
color: #468847; color: #468847;
} }
...@@ -174,9 +57,12 @@ ...@@ -174,9 +57,12 @@
} }
} }
&.btn-lg { &.btn-save {
font-size: 15px; @extend .btn-primary;
line-height: 1.4; }
&.btn-new, &.btn-create {
@extend .btn-success;
} }
} }
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
.slead { .slead {
color: #666; color: #666;
font-size: 14px; font-size: 15px;
margin-bottom: 12px; margin-bottom: 12px;
font-weight: normal; font-weight: normal;
line-height: 24px; line-height: 24px;
...@@ -61,7 +61,7 @@ pre { ...@@ -61,7 +61,7 @@ pre {
.dropdown-menu > li > a:hover, .dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus { .dropdown-menu > li > a:focus {
background: $bg_primary; background: $gl-primary;
color: #FFF color: #FFF
} }
...@@ -71,7 +71,7 @@ pre { ...@@ -71,7 +71,7 @@ pre {
/** FLASH message **/ /** FLASH message **/
.author_link { .author_link {
color: $link_color; color: $gl-link-color;
} }
.help li { color:$style_color; } .help li { color:$style_color; }
...@@ -315,20 +315,8 @@ table { ...@@ -315,20 +315,8 @@ table {
width: 100%; width: 100%;
} }
.broadcast-message {
padding: 10px;
text-align: center;
background: #555;
color: #BBB;
}
.broadcast-message-preview {
@extend .broadcast-message;
margin-bottom: 20px;
}
.btn-sign-in { .btn-sign-in {
margin-top: 7px; margin-top: 5px;
text-shadow: none; text-shadow: none;
} }
...@@ -346,8 +334,11 @@ table { ...@@ -346,8 +334,11 @@ table {
overflow-x: auto; overflow-x: auto;
} }
.footer-links a { .footer-links {
margin-right: 15px; margin-bottom: 20px;
a {
margin-right: 15px;
}
} }
.search_box { .search_box {
......
...@@ -29,7 +29,7 @@ fieldset legend { ...@@ -29,7 +29,7 @@ fieldset legend {
padding: 17px 20px 18px; padding: 17px 20px 18px;
margin-top: 18px; margin-top: 18px;
margin-bottom: 18px; margin-bottom: 18px;
background-color: whitesmoke; background-color: #ecf0f1;
border-top: 1px solid #e5e5e5; border-top: 1px solid #e5e5e5;
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
*/ */
.issue-form, .merge-request-form, .wiki-form { .issue-form, .merge-request-form, .wiki-form {
.description { .description {
height: 20em; height: 16em;
border-top-left-radius: 0; border-top-left-radius: 0;
} }
} }
......
...@@ -11,17 +11,17 @@ ...@@ -11,17 +11,17 @@
margin-right: 5px; margin-right: 5px;
&.issue-box-closed { &.issue-box-closed {
background-color: $bg_danger; background-color: $gl-danger;
color: #FFF; color: #FFF;
} }
&.issue-box-merged { &.issue-box-merged {
background-color: $bg_primary; background-color: $gl-primary;
color: #FFF; color: #FFF;
} }
&.issue-box-open { &.issue-box-open {
background-color: $bg_success; background-color: $gl-success;
color: #FFF; color: #FFF;
} }
......
...@@ -41,8 +41,8 @@ ...@@ -41,8 +41,8 @@
} }
.ui-state-active { .ui-state-active {
border: 1px solid $bg_primary; border: 1px solid $gl-primary;
background: $bg_primary; background: $gl-primary;
color: #FFF; color: #FFF;
} }
......
...@@ -57,7 +57,6 @@ ...@@ -57,7 +57,6 @@
border: 1px solid #ddd; border: 1px solid #ddd;
min-height: 100px; min-height: 100px;
padding: 5px; padding: 5px;
font-size: 14px;
box-shadow: none; box-shadow: none;
} }
...@@ -77,3 +76,12 @@ ...@@ -77,3 +76,12 @@
} }
} }
} }
.markdown-area {
background: #FFF;
border: 1px solid #ddd;
min-height: 100px;
padding: 5px;
box-shadow: none;
width: 100%;
}
...@@ -43,8 +43,10 @@ ...@@ -43,8 +43,10 @@
} }
} }
.page-title .new-issue-link { .page-title {
display: none; .note_created_ago, .new-issue-link {
display: none;
}
} }
.issue_edited_ago, .note_edited_ago { .issue_edited_ago, .note_edited_ago {
......
...@@ -154,9 +154,10 @@ ...@@ -154,9 +154,10 @@
.collapse-nav a { .collapse-nav a {
position: fixed; position: fixed;
top: 47px; top: 46px;
padding: 5px 13px 3px 13px; padding: 5px 13px 3px 13px;
left: 197px; left: 197px;
font-size: 13px;
background: #EEE; background: #EEE;
color: black; color: black;
border: 1px solid rgba(0,0,0,0.035); border: 1px solid rgba(0,0,0,0.035);
......
...@@ -3,9 +3,8 @@ ...@@ -3,9 +3,8 @@
.select2-choice { .select2-choice {
background: #FFF; background: #FFF;
border-color: #BBB; border-color: #BBB;
padding: 6px 12px; padding: 6px 14px;
font-size: 13px; line-height: 1.42857143;
line-height: 18px;
height: auto; height: auto;
.select2-arrow { .select2-arrow {
...@@ -20,7 +19,7 @@ ...@@ -20,7 +19,7 @@
} }
.select2-container-multi .select2-choices .select2-search-field input { .select2-container-multi .select2-choices .select2-search-field input {
padding: 6px 12px; padding: 8px 14px;
font-size: 13px; font-size: 13px;
line-height: 18px; line-height: 18px;
height: auto; height: auto;
...@@ -42,7 +41,7 @@ ...@@ -42,7 +41,7 @@
.select2-results { .select2-results {
max-height: 350px; max-height: 350px;
.select2-highlighted { .select2-highlighted {
background: $bg_primary; background: $gl-primary;
} }
} }
} }
......
...@@ -2,28 +2,12 @@ ...@@ -2,28 +2,12 @@
* Headers * Headers
* *
*/ */
h1.page-title { .page-title {
@include page-title;
font-size: 28px;
}
h2.page-title {
@include page-title;
font-size: 24px;
}
h3.page-title {
@include page-title;
font-size: 22px;
}
h4.page-title {
margin-top: 0px; margin-top: 0px;
} color: #333;
line-height: 1.5;
h6 { font-weight: normal;
color: #888; margin-bottom: 5px;
text-transform: uppercase;
} }
/** CODE **/ /** CODE **/
...@@ -36,52 +20,6 @@ pre { ...@@ -36,52 +20,6 @@ pre {
} }
} }
/**
* Links
*
*/
a {
outline: none;
color: $link_color;
&:hover {
text-decoration: underline;
color: $link_hover_color;
}
&:focus {
text-decoration: underline;
}
&.darken {
color: $style_color;
}
&.lined {
text-decoration: underline;
&:hover { text-decoration: underline; }
}
&.gray {
color: gray;
}
&.supp_diff_link {
text-align: center;
padding: 20px 0;
background: #f1f1f1;
width: 100%;
float: left;
}
&.neib {
margin-right: 15px;
}
}
a:focus {
outline: none;
}
.monospace { .monospace {
font-family: $monospace_font; font-family: $monospace_font;
} }
......
/* https://github.com/MozMorris/tomorrow-pygments */ /* https://github.com/MozMorris/tomorrow-pygments */
pre.code.highlight.dark,
.code.dark { .code.dark {
background-color: #1d1f21;
color: #c5c8c6;
pre.code, pre.code,
.line-numbers, .line-numbers,
.line-numbers a { .line-numbers a {
...@@ -13,8 +17,8 @@ ...@@ -13,8 +17,8 @@
} }
// highlight line via anchor // highlight line via anchor
pre.hll { pre .hll {
background-color: #fff !important; background-color: #557 !important;
} }
.hll { background-color: #373b41 } .hll { background-color: #373b41 }
......
/* https://github.com/richleland/pygments-css/blob/master/monokai.css */ /* https://github.com/richleland/pygments-css/blob/master/monokai.css */
pre.code.monokai,
.code.monokai { .code.monokai {
background: #272822;
color: #f8f8f2;
pre.highlight, pre.highlight,
.line-numbers, .line-numbers,
.line-numbers a { .line-numbers a {
...@@ -13,7 +17,7 @@ ...@@ -13,7 +17,7 @@
} }
// highlight line via anchor // highlight line via anchor
pre.hll { pre .hll {
background-color: #49483e !important; background-color: #49483e !important;
} }
......
/* https://gist.github.com/qguv/7936275 */ /* https://gist.github.com/qguv/7936275 */
pre.code.highlight.solarized-dark,
.code.solarized-dark { .code.solarized-dark {
background-color: #002b36;
color: #93a1a1;
pre.code, pre.code,
.line-numbers, .line-numbers,
.line-numbers a { .line-numbers a {
...@@ -13,8 +17,8 @@ ...@@ -13,8 +17,8 @@
} }
// highlight line via anchor // highlight line via anchor
pre.hll { pre .hll {
background-color: #073642 !important; background-color: #174652 !important;
} }
/* Solarized Dark /* Solarized Dark
......
/* https://gist.github.com/qguv/7936275 */ /* https://gist.github.com/qguv/7936275 */
pre.code.highlight.solarized-light,
.code.solarized-light { .code.solarized-light {
background-color: #fdf6e3;
color: #586e75;
pre.code, pre.code,
.line-numbers, .line-numbers,
.line-numbers a { .line-numbers a {
...@@ -13,8 +17,8 @@ ...@@ -13,8 +17,8 @@
} }
// highlight line via anchor // highlight line via anchor
pre.hll { pre .hll {
background-color: #eee8d5 !important; background-color: #ddd8c5 !important;
} }
/* Solarized Light /* Solarized Light
......
/* https://github.com/aahan/pygments-github-style */ /* https://github.com/aahan/pygments-github-style */
pre.code.highlight.white,
.code.white { .code.white {
background-color: #fff;
color: #333;
pre.highlight, pre.highlight,
.line-numbers, .line-numbers,
.line-numbers a { .line-numbers a {
...@@ -13,7 +17,7 @@ ...@@ -13,7 +17,7 @@
} }
// highlight line via anchor // highlight line via anchor
pre.hll { pre .hll {
background-color: #f8eec7 !important; background-color: #f8eec7 !important;
} }
......
/** Typo **/
$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;
...@@ -50,3 +50,14 @@ ...@@ -50,3 +50,14 @@
line-height: 2; line-height: 2;
} }
} }
.broadcast-message {
@extend .alert-warning;
padding: 10px;
text-align: center;
}
.broadcast-message-preview {
@extend .broadcast-message;
margin-bottom: 20px;
}
...@@ -45,15 +45,6 @@ ...@@ -45,15 +45,6 @@
} }
} }
.commit-committer-link,
.commit-author-link {
font-size: 13px;
color: #555;
&:hover {
color: #999;
}
}
.commit-box { .commit-box {
margin: 10px 0; margin: 10px 0;
border-top: 1px solid #ddd; border-top: 1px solid #ddd;
......
...@@ -100,6 +100,7 @@ li.commit { ...@@ -100,6 +100,7 @@ li.commit {
.commit-row-info { .commit-row-info {
color: #777; color: #777;
line-height: 24px; line-height: 24px;
font-size: 13px;
a { a {
color: #777; color: #777;
......
...@@ -23,28 +23,6 @@ ...@@ -23,28 +23,6 @@
} }
} }
.dash-sidebar-tabs {
margin-bottom: 2px;
border: none;
margin: 0 !important;
li {
&.active {
a {
background-color: #EEE;
border-bottom: 1px solid #EEE !important;
&:hover {
background: #eee;
}
}
}
a {
border-color: #DDD !important;
}
}
}
.project-row, .group-row { .project-row, .group-row {
padding: 0 !important; padding: 0 !important;
font-size: 14px; font-size: 14px;
...@@ -111,17 +89,8 @@ ...@@ -111,17 +89,8 @@
} }
.dash-new-project { .dash-new-project {
background: $bg_success; background: $gl-success;
border: 1px solid $border_success; border: 1px solid $gl-success;
a {
color: #FFF;
}
}
.dash-new-group {
background: $bg_success;
border: 1px solid $border_success;
a { a {
color: #FFF; color: #FFF;
......
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
.event-title { .event-title {
@include str-truncated(72%); @include str-truncated(72%);
color: #333;
font-weight: 500; font-weight: 500;
font-size: 14px; font-size: 14px;
.author_name { .author_name {
...@@ -54,6 +53,7 @@ ...@@ -54,6 +53,7 @@
} }
} }
.event-body { .event-body {
font-size: 13px;
margin-left: 35px; margin-left: 35px;
margin-right: 80px; margin-right: 80px;
color: #777; color: #777;
...@@ -185,11 +185,10 @@ ...@@ -185,11 +185,10 @@
} }
.event_filter { .event_filter {
li a { li a {
font-size: 13px;
padding: 5px 10px; padding: 5px 10px;
background: rgba(0,0,0,0.045); background: rgba(0,0,0,0.045);
margin-left: 4px; margin-left: 4px;
} }
} }
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
color: #888; color: #888;
a { a {
font-size: 14px;
margin-right: 3px; margin-right: 3px;
} }
} }
...@@ -29,7 +28,6 @@ ...@@ -29,7 +28,6 @@
th { th {
padding-top: 15px; padding-top: 15px;
font-size: 14px;
line-height: 1.5; line-height: 1.5;
color: #333; color: #333;
text-align: left text-align: left
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
.issue-info { .issue-info {
color: #999; color: #999;
font-size: 13px;
} }
.issue-check { .issue-check {
...@@ -40,7 +41,7 @@ ...@@ -40,7 +41,7 @@
} }
.check-all-holder { .check-all-holder {
height: 32px; height: 36px;
float: left; float: left;
margin-right: 12px; margin-right: 12px;
padding: 6px 15px; padding: 6px 15px;
......
...@@ -96,6 +96,7 @@ ...@@ -96,6 +96,7 @@
.merge-request-info { .merge-request-info {
color: #999; color: #999;
font-size: 13px;
.merge-request-labels { .merge-request-labels {
display: inline-block; display: inline-block;
...@@ -136,8 +137,8 @@ ...@@ -136,8 +137,8 @@
background-color: #F5F5F5; background-color: #F5F5F5;
&.ci-success { &.ci-success {
color: $bg_success; color: $gl-success;
border-color: $border_success; border-color: $gl-success;
background-color: #F1FAF1; background-color: #F1FAF1;
} }
...@@ -148,20 +149,20 @@ ...@@ -148,20 +149,20 @@
} }
&.ci-running { &.ci-running {
color: $bg_warning; color: $gl-warning;
border-color: $border_warning; border-color: $gl-warning;
background-color: #FAF5F1; background-color: #FAF5F1;
} }
&.ci-failed { &.ci-failed {
color: $bg_danger; color: $gl-danger;
border-color: $border_danger; border-color: $gl-danger;
background-color: #FAF1F1; background-color: #FAF1F1;
} }
&.ci-error { &.ci-error {
color: $bg_danger; color: $gl-danger;
border-color: $border_danger; border-color: $gl-danger;
background-color: #FAF1F1; background-color: #FAF1F1;
} }
} }
......
.issues-sortable-list .str-truncated { .issues-sortable-list .str-truncated {
max-width: 70%; max-width: 90%;
}
li.milestone {
h4 {
font-weight: bold;
}
} }
...@@ -38,13 +38,11 @@ ul.notes { ...@@ -38,13 +38,11 @@ ul.notes {
.author { .author {
color: #333; color: #333;
font-weight: bold; font-weight: bold;
font-size: 14px;
&:hover { &:hover {
color: $link_color; color: $gl-link-color;
} }
} }
.author-username { .author-username {
font-size: 14px;
} }
} }
...@@ -57,9 +55,6 @@ ul.notes { ...@@ -57,9 +55,6 @@ ul.notes {
.note { .note {
display: block; display: block;
position:relative; position:relative;
.attachment {
font-size: 14px;
}
.note-body { .note-body {
overflow: auto; overflow: auto;
.note-text { .note-text {
...@@ -70,7 +65,7 @@ ul.notes { ...@@ -70,7 +65,7 @@ ul.notes {
a[href*="/uploads/"] { a[href*="/uploads/"] {
&:before { &:before {
margin-right: 4px; margin-right: 4px;
font: normal normal normal 14px/1 FontAwesome; font: normal normal normal 14px/1 FontAwesome;
font-size: inherit; font-size: inherit;
text-rendering: auto; text-rendering: auto;
...@@ -153,7 +148,6 @@ ul.notes { ...@@ -153,7 +148,6 @@ ul.notes {
@extend .cgray; @extend .cgray;
&:hover { &:hover {
color: $link_hover_color;
&.danger { @extend .cred; } &.danger { @extend .cred; }
} }
} }
...@@ -181,10 +175,11 @@ ul.notes { ...@@ -181,10 +175,11 @@ ul.notes {
background: #FFF; background: #FFF;
padding: 4px; padding: 4px;
font-size: 16px; font-size: 16px;
color: $link_color; color: $gl-link-color;
margin-left: -60px; margin-left: -60px;
position: absolute; position: absolute;
z-index: 10; z-index: 10;
width: 32px;
transition: all 0.2s ease; transition: all 0.2s ease;
...@@ -193,8 +188,9 @@ ul.notes { ...@@ -193,8 +188,9 @@ ul.notes {
filter: alpha(opacity=0); filter: alpha(opacity=0);
&:hover { &:hover {
font-size: 24px; width: 38px;
background: $bg_primary; font-size: 20px;
background: $gl-info;
color: #FFF; color: #FFF;
@include show-add-diff-note; @include show-add-diff-note;
} }
......
...@@ -10,13 +10,13 @@ ...@@ -10,13 +10,13 @@
} }
.ns-part { .ns-part {
color: $bg_primary; color: $gl-primary;
} }
.ns-watch { .ns-watch {
color: $bg_success; color: $gl-success;
} }
.ns-mute { .ns-mute {
color: $bg_danger; color: $gl-danger;
} }
...@@ -99,25 +99,6 @@ ...@@ -99,25 +99,6 @@
margin-right: 45px; margin-right: 45px;
} }
.btn,
.form-control {
border: 1px solid #E1E1E1;
box-shadow: none;
padding: 6px 9px;
}
.btn {
background: none;
color: $link_color;
&.active {
background-color: #f5f5f5;
border: 1px solid rgba(0,0,0,0.195);
color: #333;
font-weight: bold;
}
}
.form-control { .form-control {
cursor: auto; cursor: auto;
@extend .monospace; @extend .monospace;
...@@ -267,15 +248,15 @@ ul.nav.nav-projects-tabs { ...@@ -267,15 +248,15 @@ ul.nav.nav-projects-tabs {
} }
.vs-public { .vs-public {
color: $bg_primary; color: $gl-primary;
} }
.vs-internal { .vs-internal {
color: $bg_warning; color: $gl-warning;
} }
.vs-private { .vs-private {
color: $bg_success; color: $gl-success;
} }
.breadcrumb.repo-breadcrumb { .breadcrumb.repo-breadcrumb {
......
...@@ -39,14 +39,9 @@ ...@@ -39,14 +39,9 @@
.tree-item-file-name { .tree-item-file-name {
max-width: 320px; max-width: 320px;
vertical-align: middle; vertical-align: middle;
a {
&:hover {
color: $link_hover_color;
}
}
i { i, a {
color: $bg_primary; color: $gl-link-color;
} }
img { img {
...@@ -66,13 +61,18 @@ ...@@ -66,13 +61,18 @@
.tree_author { .tree_author {
padding-right: 8px; padding-right: 8px;
.commit-author-name {
color: gray;
}
} }
.tree_commit { .tree_commit {
color: gray; color: gray;
.tree-commit-link { .tree-commit-link {
color: #444; color: gray;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
......
.gitlab-ui-dev-kit {
> h2 {
font-size: 27px;
border-bottom: 1px solid #CCC;
color: #666;
margin: 30px 0;
font-weight: bold;
}
}
.markdown-area {
background: #FFF;
border: 1px solid #ddd;
min-height: 100px;
padding: 5px;
font-size: 14px;
box-shadow: none;
width: 100%;
}
...@@ -45,7 +45,8 @@ class Admin::ServicesController < Admin::ApplicationController ...@@ -45,7 +45,8 @@ class Admin::ServicesController < Admin::ApplicationController
: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, :build_type,
:description, :issues_url, :new_issue_url, :restrict_to_branch :description, :issues_url, :new_issue_url, :restrict_to_branch,
:send_from_committer_email, :disable_diffs
]) ])
end end
end end
...@@ -24,7 +24,7 @@ class Admin::UsersController < Admin::ApplicationController ...@@ -24,7 +24,7 @@ class Admin::UsersController < Admin::ApplicationController
def block def block
if user.block if user.block
redirect_to :back, alert: "Successfully blocked" redirect_to :back, notice: "Successfully blocked"
else else
redirect_to :back, alert: "Error occurred. User was not blocked" redirect_to :back, alert: "Error occurred. User was not blocked"
end end
...@@ -32,7 +32,7 @@ class Admin::UsersController < Admin::ApplicationController ...@@ -32,7 +32,7 @@ class Admin::UsersController < Admin::ApplicationController
def unblock def unblock
if user.activate if user.activate
redirect_to :back, alert: "Successfully unblocked" redirect_to :back, notice: "Successfully unblocked"
else else
redirect_to :back, alert: "Error occurred. User was not unblocked" redirect_to :back, alert: "Error occurred. User was not unblocked"
end end
......
class Profiles::GroupsController < ApplicationController class Dashboard::GroupsController < ApplicationController
layout "profile"
def index def index
@user_groups = current_user.group_members.page(params[:page]).per(20) @user_groups = current_user.group_members.page(params[:page]).per(20)
end end
...@@ -9,7 +7,7 @@ class Profiles::GroupsController < ApplicationController ...@@ -9,7 +7,7 @@ class Profiles::GroupsController < ApplicationController
@users_group = group.group_members.where(user_id: current_user.id).first @users_group = group.group_members.where(user_id: current_user.id).first
if can?(current_user, :destroy, @users_group) if can?(current_user, :destroy, @users_group)
@users_group.destroy @users_group.destroy
redirect_to(profile_groups_path, info: "You left #{group.name} group.") redirect_to(dashboard_groups_path, info: "You left #{group.name} group.")
else else
return render_403 return render_403
end end
......
class Dashboard::MilestonesController < ApplicationController
before_filter :load_projects
def index
project_milestones = case params[:state]
when 'all'; state
when 'closed'; state('closed')
else state('active')
end
@dashboard_milestones = Milestones::GroupService.new(project_milestones).execute
@dashboard_milestones = Kaminari.paginate_array(@dashboard_milestones).page(params[:page]).per(30)
end
def show
project_milestones = Milestone.where(project_id: @projects).order("due_date ASC")
@dashboard_milestone = Milestones::GroupService.new(project_milestones).milestone(title)
end
private
def load_projects
@projects = current_user.authorized_projects.sorted_by_activity.non_archived
end
def title
params[:title]
end
def state(state = nil)
conditions = { project_id: @projects }
conditions.reverse_merge!(state: state) if state
Milestone.where(conditions).order("title ASC")
end
end
class Dashboard::ProjectsController < ApplicationController
before_filter :event_filter
def starred
@projects = current_user.starred_projects
@projects = @projects.includes(:namespace, :forked_from_project, :tags)
@projects = @projects.sort(@sort = params[:sort])
@groups = []
respond_to do |format|
format.html
format.json do
load_events
pager_json("events/_events", @events.count)
end
end
end
private
def load_events
@events = Event.in_projects(@projects.pluck(:id))
@events = @event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0)
end
end
...@@ -5,19 +5,9 @@ class DashboardController < ApplicationController ...@@ -5,19 +5,9 @@ class DashboardController < ApplicationController
before_filter :event_filter, only: :show before_filter :event_filter, only: :show
def show def show
# Fetch only 30 projects. @projects = @projects.includes(:namespace)
# If user needs more - point to Dashboard#projects page
@projects_limit = 30
@groups = current_user.authorized_groups.order_name_asc
@has_authorized_projects = @projects.count > 0
@projects_count = @projects.count
@projects = @projects.includes(:namespace).limit(@projects_limit)
@last_push = current_user.recent_push @last_push = current_user.recent_push
@publicish_project_count = Project.publicish(current_user).count
respond_to do |format| respond_to do |format|
format.html format.html
...@@ -33,29 +23,6 @@ class DashboardController < ApplicationController ...@@ -33,29 +23,6 @@ class DashboardController < ApplicationController
end end
end end
def projects
@projects = case params[:scope]
when 'personal' then
current_user.namespace.projects
when 'joined' then
current_user.authorized_projects.joined(current_user)
when 'owned' then
current_user.owned_projects
else
current_user.authorized_projects
end
@projects = @projects.where(namespace_id: Group.find_by(name: params[:group])) if params[:group].present?
@projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present?
@projects = @projects.includes(:namespace, :forked_from_project, :tags)
@projects = @projects.tagged_with(params[:tag]) if params[:tag].present?
@projects = @projects.sort(@sort = params[:sort])
@projects = @projects.page(params[:page]).per(30)
@tags = current_user.authorized_projects.tags_on(:tags)
@groups = current_user.authorized_groups
end
def merge_requests def merge_requests
@merge_requests = get_merge_requests_collection @merge_requests = get_merge_requests_collection
@merge_requests = @merge_requests.page(params[:page]).per(20) @merge_requests = @merge_requests.page(params[:page]).per(20)
......
...@@ -6,6 +6,9 @@ class Explore::ProjectsController < ApplicationController ...@@ -6,6 +6,9 @@ class Explore::ProjectsController < ApplicationController
def index def index
@projects = ProjectsFinder.new.execute(current_user) @projects = ProjectsFinder.new.execute(current_user)
@tags = @projects.tags_on(:tags)
@projects = @projects.tagged_with(params[:tag]) if params[:tag].present?
@projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present?
@projects = @projects.search(params[:search]) if params[:search].present? @projects = @projects.search(params[:search]) if params[:search].present?
@projects = @projects.sort(@sort = params[:sort]) @projects = @projects.sort(@sort = params[:sort])
@projects = @projects.includes(:namespace).page(params[:page]).per(20) @projects = @projects.includes(:namespace).page(params[:page]).per(20)
......
...@@ -4,10 +4,10 @@ class Groups::MilestonesController < ApplicationController ...@@ -4,10 +4,10 @@ class Groups::MilestonesController < ApplicationController
before_filter :authorize_group_milestone!, only: :update before_filter :authorize_group_milestone!, only: :update
def index def index
project_milestones = case params[:status] project_milestones = case params[:state]
when 'all'; status when 'all'; state
when 'closed'; status('closed') when 'closed'; state('closed')
else status('active') else state('active')
end end
@group_milestones = Milestones::GroupService.new(project_milestones).execute @group_milestones = Milestones::GroupService.new(project_milestones).execute
@group_milestones = Kaminari.paginate_array(@group_milestones).page(params[:page]).per(30) @group_milestones = Kaminari.paginate_array(@group_milestones).page(params[:page]).per(30)
...@@ -44,7 +44,7 @@ class Groups::MilestonesController < ApplicationController ...@@ -44,7 +44,7 @@ class Groups::MilestonesController < ApplicationController
params[:title] params[:title]
end end
def status(state = nil) def state(state = nil)
conditions = { project_id: group.projects } conditions = { project_id: group.projects }
conditions.reverse_merge!(state: state) if state conditions.reverse_merge!(state: state) if state
Milestone.where(conditions).order("title ASC") Milestone.where(conditions).order("title ASC")
......
...@@ -19,4 +19,7 @@ class HelpController < ApplicationController ...@@ -19,4 +19,7 @@ class HelpController < ApplicationController
def shortcuts def shortcuts
end end
def ui
end
end end
...@@ -3,19 +3,17 @@ class Import::BaseController < ApplicationController ...@@ -3,19 +3,17 @@ class Import::BaseController < ApplicationController
private private
def get_or_create_namespace def get_or_create_namespace
existing_namespace = Namespace.find_by_path_or_name(@target_namespace) begin
namespace = Group.create!(name: @target_namespace, path: @target_namespace, owner: current_user)
if existing_namespace namespace.add_owner(current_user)
if existing_namespace.owner == current_user rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid
namespace = existing_namespace namespace = Namespace.find_by_path_or_name(@target_namespace)
else unless namespace.owner == current_user
@already_been_taken = true @already_been_taken = true
return false return false
end end
else
namespace = Group.create(name: @target_namespace, path: @target_namespace, owner: current_user)
namespace.add_owner(current_user)
namespace
end end
namespace
end end
end end
...@@ -37,7 +37,7 @@ class Projects::ImportsController < Projects::ApplicationController ...@@ -37,7 +37,7 @@ class Projects::ImportsController < Projects::ApplicationController
private private
def require_no_repo def require_no_repo
if @project.repository_exists? if @project.repository_exists? && !@project.import_in_progress?
redirect_to(namespace_project_path(@project.namespace, @project)) and return redirect_to(namespace_project_path(@project.namespace, @project)) and return
end end
end end
......
...@@ -93,7 +93,7 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -93,7 +93,7 @@ class Projects::IssuesController < Projects::ApplicationController
end end
def bulk_update def bulk_update
result = Issues::BulkUpdateService.new(project, current_user, params).execute result = Issues::BulkUpdateService.new(project, current_user, bulk_update_params).execute
redirect_to :back, notice: "#{result[:count]} issues updated" redirect_to :back, notice: "#{result[:count]} issues updated"
end end
...@@ -141,4 +141,13 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -141,4 +141,13 @@ class Projects::IssuesController < Projects::ApplicationController
:milestone_id, :state_event, :task_num, label_ids: [] :milestone_id, :state_event, :task_num, label_ids: []
) )
end end
def bulk_update_params
params.require(:update).permit(
:issues_ids,
:assignee_id,
:milestone_id,
:state_event
)
end
end end
...@@ -78,10 +78,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -78,10 +78,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@merge_request = MergeRequests::CreateService.new(project, current_user, merge_request_params).execute @merge_request = MergeRequests::CreateService.new(project, current_user, merge_request_params).execute
if @merge_request.valid? if @merge_request.valid?
redirect_to( redirect_to(merge_request_path(@merge_request))
merge_request_path(@merge_request),
notice: 'Merge request was successfully created.'
)
else else
@source_project = @merge_request.source_project @source_project = @merge_request.source_project
@target_project = @merge_request.target_project @target_project = @merge_request.target_project
...@@ -97,8 +94,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -97,8 +94,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController
format.js format.js
format.html do format.html do
redirect_to([@merge_request.target_project.namespace.becomes(Namespace), redirect_to([@merge_request.target_project.namespace.becomes(Namespace),
@merge_request.target_project, @merge_request], @merge_request.target_project, @merge_request])
notice: 'Merge request was successfully updated.') end
format.json do
render json: {
saved: @merge_request.valid?,
assignee_avatar_url: @merge_request.assignee.try(:avatar_url)
}
end end
end end
else else
......
...@@ -51,7 +51,9 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -51,7 +51,9 @@ class Projects::ServicesController < Projects::ApplicationController
: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, :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,
:note_events, :send_from_committer_email, :disable_diffs
) )
end end
end end
...@@ -27,7 +27,7 @@ class Projects::TagsController < Projects::ApplicationController ...@@ -27,7 +27,7 @@ class Projects::TagsController < Projects::ApplicationController
tag = @repository.find_tag(params[:id]) tag = @repository.find_tag(params[:id])
if tag && @repository.rm_tag(tag.name) if tag && @repository.rm_tag(tag.name)
EventCreateService.new.push_ref(@project, current_user, tag, 'rm', 'refs/tags') EventCreateService.new.push_ref(@project, current_user, tag, 'rm', Gitlab::Git::TAG_REF_PREFIX)
end end
respond_to do |format| respond_to do |format|
......
...@@ -105,7 +105,7 @@ class ProjectsController < ApplicationController ...@@ -105,7 +105,7 @@ class ProjectsController < ApplicationController
if request.referer.include?('/admin') if request.referer.include?('/admin')
redirect_to admin_namespaces_projects_path redirect_to admin_namespaces_projects_path
else else
redirect_to projects_dashboard_path redirect_to dashboard_path
end end
end end
end end
......
class UploadsController < ApplicationController class UploadsController < ApplicationController
skip_before_filter :authenticate_user!, :reject_blocked! skip_before_filter :authenticate_user!
before_filter :authorize_access before_filter :find_model, :authorize_access!
def show def show
unless upload_model && upload_mount uploader = @model.send(upload_mount)
return not_found!
end
model = upload_model.find(params[:id])
uploader = model.send(upload_mount)
if model.respond_to?(:project) && !can?(current_user, :read_project, model.project)
return not_found!
end
unless uploader.file_storage? unless uploader.file_storage?
return redirect_to uploader.url return redirect_to uploader.url
end end
unless uploader.file.exists? unless uploader.file && uploader.file.exists?
return not_found! return not_found!
end end
...@@ -28,9 +19,34 @@ class UploadsController < ApplicationController ...@@ -28,9 +19,34 @@ class UploadsController < ApplicationController
private private
def authorize_access def find_model
unless %w(avatar logo light_logo).include?(params[:mounted_as]) unless upload_model && upload_mount
authenticate_user! && reject_blocked! return not_found!
end
@model = upload_model.find(params[:id])
end
def authorize_access!
authorized =
case @model
when Project
can?(current_user, :read_project, @model)
when Group
can?(current_user, :read_group, @model)
when Note
can?(current_user, :read_project, @model.project)
else
# No authentication required for user avatars.
true
end
return if authorized
if current_user
not_found!
else
authenticate_user!
end end
end end
......
module DashboardHelper module DashboardHelper
def projects_dashboard_filter_path(options={})
exist_opts = {
sort: params[:sort],
scope: params[:scope],
group: params[:group],
tag: params[:tag],
visibility_level: params[:visibility_level],
}
options = exist_opts.merge(options)
path = request.path
path << "?#{options.to_param}"
path
end
def assigned_issues_dashboard_path def assigned_issues_dashboard_path
issues_dashboard_path(assignee_id: current_user.id) issues_dashboard_path(assignee_id: current_user.id)
end end
......
...@@ -166,7 +166,7 @@ module EventsHelper ...@@ -166,7 +166,7 @@ module EventsHelper
def event_note(text) def event_note(text)
text = first_line_in_markdown(text, 150) text = first_line_in_markdown(text, 150)
sanitize(text, tags: %w(a img b pre code p)) sanitize(text, tags: %w(a img b pre code p span))
end end
def event_commit_title(message) def event_commit_title(message)
......
module ExploreHelper
def explore_projects_filter_path(options={})
exist_opts = {
sort: params[:sort],
scope: params[:scope],
group: params[:group],
tag: params[:tag],
visibility_level: params[:visibility_level],
}
options = exist_opts.merge(options)
path = request.path
path << "?#{options.to_param}"
path
end
end
...@@ -31,7 +31,9 @@ module GitlabMarkdownHelper ...@@ -31,7 +31,9 @@ module GitlabMarkdownHelper
def markdown(text, options={}) def markdown(text, options={})
unless (@markdown and options == @options) unless (@markdown and options == @options)
@options = options @options = options
gitlab_renderer = Redcarpet::Render::GitlabHTML.new(self, { gitlab_renderer = Redcarpet::Render::GitlabHTML.new(self,
user_color_scheme_class,
{
# see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch- # see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch-
filter_html: true, filter_html: true,
with_toc_data: true, with_toc_data: true,
......
...@@ -44,4 +44,8 @@ module GitlabRoutingHelper ...@@ -44,4 +44,8 @@ module GitlabRoutingHelper
def merge_request_url(entity, *args) def merge_request_url(entity, *args)
namespace_project_merge_request_url(entity.project.namespace, entity.project, entity, *args) namespace_project_merge_request_url(entity.project.namespace, entity.project, entity, *args)
end end
def snippet_url(entity, *args)
namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args)
end
end end
...@@ -4,6 +4,19 @@ module MilestonesHelper ...@@ -4,6 +4,19 @@ module MilestonesHelper
namespace_project_milestones_path(@project.namespace, @project, opts) namespace_project_milestones_path(@project.namespace, @project, opts)
elsif @group elsif @group
group_milestones_path(@group, opts) group_milestones_path(@group, opts)
else
dashboard_milestones_path(opts)
end
end
def milestone_progress_bar(milestone)
options = {
class: 'progress-bar progress-bar-success',
style: "width: #{milestone.percent_complete}%;"
}
content_tag :div, class: 'progress' do
content_tag :div, nil, options
end end
end end
end end
...@@ -16,28 +16,38 @@ module Emails ...@@ -16,28 +16,38 @@ module Emails
subject: subject("Project was moved")) subject: subject("Project was moved"))
end end
def repository_push_email(project_id, recipient, author_id, branch, compare) def repository_push_email(project_id, recipient, author_id, branch, compare, reverse_compare = false, send_from_committer_email = false, disable_diffs = false)
@project = Project.find(project_id) @project = Project.find(project_id)
@author = User.find(author_id) @author = User.find(author_id)
@reverse_compare = reverse_compare
@compare = compare @compare = compare
@commits = Commit.decorate(compare.commits) @commits = Commit.decorate(compare.commits)
@diffs = compare.diffs @diffs = compare.diffs
@branch = branch @branch = Gitlab::Git.ref_name(branch)
@disable_diffs = disable_diffs
@subject = "[#{@project.path_with_namespace}][#{@branch}] "
if @commits.length > 1 if @commits.length > 1
@target_url = namespace_project_compare_url(@project.namespace, @target_url = namespace_project_compare_url(@project.namespace,
@project, @project,
from: @commits.first, from: Commit.new(@compare.base),
to: @commits.last) to: Commit.new(@compare.head))
@subject = "#{@commits.length} new commits pushed to repository" @subject << "Deleted " if @reverse_compare
@subject << "#{@commits.length} commits: #{@commits.first.title}"
else else
@target_url = namespace_project_commit_url(@project.namespace, @target_url = namespace_project_commit_url(@project.namespace,
@project, @commits.first) @project, @commits.first)
@subject = @commits.first.title
@subject << "Deleted 1 commit: " if @reverse_compare
@subject << @commits.first.title
end end
mail(from: sender(author_id), @disable_footer = true
mail(from: sender(author_id, send_from_committer_email),
to: recipient, to: recipient,
subject: subject(@subject)) subject: @subject)
end end
end end
end end
...@@ -35,21 +35,41 @@ class Notify < ActionMailer::Base ...@@ -35,21 +35,41 @@ class Notify < ActionMailer::Base
) )
end end
# Splits "gitlab.corp.company.com" up into "gitlab.corp.company.com",
# "corp.company.com" and "company.com".
# Respects set tld length so "company.co.uk" won't match "somethingelse.uk"
def self.allowed_email_domains
domain_parts = Gitlab.config.gitlab.host.split(".")
allowed_domains = []
begin
allowed_domains << domain_parts.join(".")
domain_parts.shift
end while domain_parts.length > ActionDispatch::Http::URL.tld_length
allowed_domains
end
private private
# The default email address to send emails from # The default email address to send emails from
def default_sender_address def default_sender_address
address = Mail::Address.new(Gitlab.config.gitlab.email_from) address = Mail::Address.new(Gitlab.config.gitlab.email_from)
address.display_name = "GitLab" address.display_name = Gitlab.config.gitlab.email_display_name
address address
end end
# Return an email address that displays the name of the sender. # Return an email address that displays the name of the sender.
# Only the displayed name changes; the actual email address is always the same. # Only the displayed name changes; the actual email address is always the same.
def sender(sender_id) def sender(sender_id, send_from_user_email = false)
if sender = User.find(sender_id) if sender = User.find(sender_id)
address = default_sender_address address = default_sender_address
address.display_name = sender.name address.display_name = sender.name
sender_domain = sender.email.split("@").last
if send_from_user_email && self.class.allowed_email_domains.include?(sender_domain)
address.address = sender.email
end
address.format address.format
end end
end end
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# home_page_url :string(255) # home_page_url :string(255)
# default_branch_protection :integer default(2)
# twitter_sharing_enabled :boolean default(TRUE)
# help_text :text # help_text :text
# #
......
...@@ -100,5 +100,4 @@ module Mentionable ...@@ -100,5 +100,4 @@ module Mentionable
preexisting = references(p, original) preexisting = references(p, original)
create_cross_references!(p, a, preexisting) create_cross_references!(p, a, preexisting)
end end
end end
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