Commit 4537623d authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' into karlhungus-mr-on-fork

Conflicts:
	app/contexts/filter_context.rb
	app/contexts/search_context.rb
	app/models/merge_request.rb
	app/models/note.rb
	app/views/shared/_merge_requests.html.haml
	spec/controllers/commit_controller_spec.rb
	spec/services/notification_service_spec.rb
parents c7e490eb 1a83fea7
...@@ -30,3 +30,5 @@ vendor/bundle/* ...@@ -30,3 +30,5 @@ vendor/bundle/*
rails_best_practices_output.html rails_best_practices_output.html
doc/code/* doc/code/*
.secret .secret
*.log
public/uploads.*
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
This guide details how to use issues and pull requests to improve GitLab. This guide details how to use issues and pull requests to improve GitLab.
- [Closing policy for issues and pull requests](#closing-policy-for-issues-and-pull-requests)
- [Issue tracker](#issue-tracker)
- [Pull requests](#pull-requests)
If you want to know how the GitLab team handles contributions have a look at [the GitLab contributing process](PROCESS.md).
## Closing policy for issues and pull requests ## Closing policy for issues and pull requests
GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. Out of respect for our volunteers, issues and pull requests not in line with the guidelines listed in this document may be closed without notice. GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. Out of respect for our volunteers, issues and pull requests not in line with the guidelines listed in this document may be closed without notice.
......
...@@ -23,7 +23,7 @@ gem 'omniauth-github' ...@@ -23,7 +23,7 @@ gem 'omniauth-github'
# 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', '~> 1.4.1' gem "gitlab_git", "~> 2.0.0.pre"
# Ruby/Rack Git Smart-HTTP Server Handler # Ruby/Rack Git Smart-HTTP Server Handler
gem 'gitlab-grack', '~> 1.0.1', require: 'grack' gem 'gitlab-grack', '~> 1.0.1', require: 'grack'
......
...@@ -176,7 +176,7 @@ GEM ...@@ -176,7 +176,7 @@ GEM
gitlab-pygments.rb (0.3.2) gitlab-pygments.rb (0.3.2)
posix-spawn (~> 0.3.6) posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0) yajl-ruby (~> 1.1.0)
gitlab_git (1.4.1) gitlab_git (2.0.0.pre)
activesupport (~> 3.2.13) activesupport (~> 3.2.13)
github-linguist (~> 2.3.4) github-linguist (~> 2.3.4)
gitlab-grit (~> 2.6.0) gitlab-grit (~> 2.6.0)
...@@ -275,7 +275,7 @@ GEM ...@@ -275,7 +275,7 @@ GEM
minitest (4.7.4) minitest (4.7.4)
modernizr (2.6.2) modernizr (2.6.2)
sprockets (~> 2.0) sprockets (~> 2.0)
multi_json (1.7.7) multi_json (1.7.8)
multi_xml (0.5.4) multi_xml (0.5.4)
multipart-post (1.2.0) multipart-post (1.2.0)
mysql2 (0.3.11) mysql2 (0.3.11)
...@@ -568,7 +568,7 @@ DEPENDENCIES ...@@ -568,7 +568,7 @@ DEPENDENCIES
gitlab-gollum-lib (~> 1.0.1) gitlab-gollum-lib (~> 1.0.1)
gitlab-grack (~> 1.0.1) gitlab-grack (~> 1.0.1)
gitlab-pygments.rb (~> 0.3.2) gitlab-pygments.rb (~> 0.3.2)
gitlab_git (~> 1.4.1) gitlab_git (~> 2.0.0.pre)
gitlab_meta (= 6.0) gitlab_meta (= 6.0)
gitlab_omniauth-ldap (= 1.0.3) gitlab_omniauth-ldap (= 1.0.3)
gon gon
......
# GitLab Contributing Process
## Purpose of describing the contributing process
Below we describe the contributing process for two reasons. Contributors know what to expect from maintainers (initial, response within xx days, friendly treatment, etc). And maintainers know what to expect from contributors (use latest version, confirm the issue is addressed, friendly treatment, etc).
## How we handle issues
The priority should be mentioning people that can help and assigning workflow labels. Workflow labels are purposely not very detailed since that would be hard to keep updated as you would need to reevaluate them after every comment. We optionally use functional labels on demand when want to group related issues to get an overview (for example all issues related to RVM, to tackle them in one go) and to add details to the issue.
If an issue is complex and needs the attention of a specific person, assignment is a good option but assigning issues might discourage other people from contributing to that issue. We need all the contributions we can get so this should never be discouraged. Also, an assigned person might not have time for a few weeks, so others should feel free to takeover.
Priority (from high to low):
1. Mentioning people (very important)
2. Workflow labels
3. Functional labels (less important)
4. Assigning issues (optional)
## Workflow labels
- _Awaiting feedback_: Feedback pending from the reporter
- _Awaiting confirmation of fix_: The issue should already be solved in **master** (generally you can avoid this workflow item and just close the issue right away)
- _Attached PR_: There is a PR attached and the discussion should happen there
- We need to let issues stay in sync with the PR's. We can do this with a "Closing #XXXX" or "Fixes #XXXX" comment in the PR. We can't close the issue when there is a pull request because sometimes a PR is not good and we just close the PR, then the issue must stay.
- _Awaiting developer action/feedback_: Issue needs to be fixed or clarified by a developer
## Functional labels
These labels describe what development specialities are involved such as: PostgreSQL, UX, LDAP.
## Label colors
- Light orange `#fef2c0`: workflow labels for issue team members (awaiting feedback, awaiting confirmation of fix)
- Bright orange `#eb6420`: workflow labels for core team members (attached PR, awaiting developer action/feedback)
- Light blue `#82C5FF`: functional labels
- Green labels `#009800`: issues that can generally be ignored. For example, issues given the following labels normally can be closed immediately:
- Feature request (see copy & paste response: [Feature requests](#feature-requests))
- Support (see copy & paste response: [Support requests and configuration questions](#support-requests-and-configuration-questions)
## Common actions
### Issue team
- Looks for issues without workflow labels and triages issue
- Monitors pull requests
- Closes invalid issues and pull requests with a comment (duplicates, [feature requests](#feature-requests), [fixed in newer version](#issue-fixed-in-newer-version), [issue report for old version](#issue-report-for-old-version), not a problem in GitLab, etc.)
- Assigns appropriate [labels](#how-we-handle-issues)
- Asks for feedback from issue reporter/pull request initiator ([invalid issue reports](#improperly-formatted-issue), [format code](#code-format), etc.)
- Asks for feedback from the relevant developer(s) based on the [list of members and their specialities](http://gitlab.org/team/)
- Monitors all issues/pull requests for feedback (but especially ones commented on since automatically watching them):
- Assigns issues to developers if they indicate they are fixing it
- Assigns pull requests to developers if they indicate they will take care of merge
- Closes issues with no feedback from the reporter for two weeks
- Closes stale pull requests
### Development team
- Responds to issues and pull requests the issue team mentions them in
- Monitors for new issues in _Awaiting developer action/feedback_ with no developer activity (once a week)
- Monitors for new pull requests (at least once a week)
- Manages their work queue by looking at issues and pull requests assigned to them
- Close fixed issues (via commit messages or manually)
- Codes [new features](http://feedback.gitlab.com/forums/176466-general/filters/top)!
- Response guidelines
- Be kind to people trying to contribute. Be aware that people can be a non-native or a native English speaker, they might not understand thing or they might be very sensitive to how your word things. Use emoji to express your feelings (hearth, star, smile, etc.). Some good tips about giving feedback to pull requests is in the [Thoughtbot code review guide](https://github.com/thoughtbot/guides/tree/master/code-review).
## Copy & paste responses
### Improperly formatted issue
Thanks for the issue report. Please reformat your issue to conform to the issue tracker guidelines found in our \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#issue-tracker-guidelines).
### Feature requests
Thanks for your interest in GitLab. We don't use the GitHub issue tracker for feature requests. Please use http://feedback.gitlab.com/ for this purpose or create a pull request implementing this feature. Have a look at the \[contribution guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) for more information.
### Issue report for old version
Thanks for the issue report but we only support issues for the latest stable version of GitLab. I'm closing this issue but if you still experience this problem in the latest stable version, please open a new issue (but also reference the old issue(s)). Make sure to also include the necessary debugging information conforming to the issue tracker guidelines found in our \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#issue-tracker-guidelines).
### Support requests and configuration questions
Thanks for your interest in GitLab. We don't use the GitHub issue tracker for support requests and configuration questions. Please use the \[support forum\]\(https://groups.google.com/forum/#!forum/gitlabhq), \[Stack Overflow\]\(http://stackoverflow.com/questions/tagged/gitlab), the unofficial #gitlab IRC channel on Freenode or the http://www.gitlab.com paid services for this purpose. Have a look at the \[contribution guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) for more information.
### Code format
Please use ``` to format console output, logs, and code as it's very hard to read otherwise.
### Issue fixed in newer version
Thanks for the issue report. This issue has already been fixed in newer versions of GitLab. Due to the size of this project and our limited resources we are only able to support the latest stable release as outlined in our \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#issue-tracker). In order to get this bug fix and enjoy many new features please \[upgrade\]\(http://blog.gitlab.org/). If you still experience issues at that time please open a new issue following our issue tracker guidelines found in the \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#issue-tracker-guidelines).
### Improperly formatted pull request
Thanks for your interest in improving the GitLab codebase! Please update your pull request according to the \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#pull-request-guidelines).
### Inactivity close of an issue
It's been at least 2 weeks (and a new release) since we heard from you. I'm closing this issue but if you still experience this problem, please open a new issue (but also reference the old issue(s)). Make sure to also include the necessary debugging information conforming to the issue tracker guidelines found in our \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#issue-tracker-guidelines).
### Inactivity close of a pull request
This pull request has been closed because a request for more information has not been reacted to for more than 2 weeks. If you respond and conform to the pull request guidelines in our \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#pull-requests) we will reopen this pull request.
...@@ -147,6 +147,8 @@ or start each component separately ...@@ -147,6 +147,8 @@ or start each component separately
* [Mailing list](https://groups.google.com/forum/#!forum/gitlabhq) and [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) are the best places to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and has resolved it. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix. * [Mailing list](https://groups.google.com/forum/#!forum/gitlabhq) and [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) are the best places to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and has resolved it. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix.
* [Unofficial #gitlab IRC on Freenode](http://www.freenode.net/) is another way to get in touch with other GitLab users who may be able to help you.
* [Feedback and suggestions forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab. * [Feedback and suggestions forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab.
* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) describes how to submit pull requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed. * [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) describes how to submit pull requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed.
......
...@@ -11,3 +11,7 @@ $ -> ...@@ -11,3 +11,7 @@ $ ->
container = $(".js-toggle-visibility-container") container = $(".js-toggle-visibility-container")
container.toggleClass("hide") container.toggleClass("hide")
e.preventDefault() e.preventDefault()
$("body").on "click", ".js-toggle-button", (e) ->
$(@).closest(".js-toggle-container").find(".js-toggle-content").toggle()
e.preventDefault()
...@@ -62,22 +62,22 @@ class BranchGraph ...@@ -62,22 +62,22 @@ class BranchGraph
cuday = 0 cuday = 0
cumonth = "" cumonth = ""
r.rect(0, 0, 26, @barHeight).attr fill: "#222" r.rect(0, 0, 40, @barHeight).attr fill: "#222"
r.rect(26, 0, 20, @barHeight).attr fill: "#444" r.rect(40, 0, 30, @barHeight).attr fill: "#444"
for day, mm in @days for day, mm in @days
if cuday isnt day[0] if cuday isnt day[0]
# Dates # Dates
r.text(36, @offsetY + @unitTime * mm, day[0]) r.text(55, @offsetY + @unitTime * mm, day[0])
.attr( .attr(
font: "12px Monaco, monospace" font: "12px Monaco, monospace"
fill: "#DDD" fill: "#BBB"
) )
cuday = day[0] cuday = day[0]
if cumonth isnt day[1] if cumonth isnt day[1]
# Months # Months
r.text(13, @offsetY + @unitTime * mm, day[1]) r.text(20, @offsetY + @unitTime * mm, day[1])
.attr( .attr(
font: "12px Monaco, monospace" font: "12px Monaco, monospace"
fill: "#EEE" fill: "#EEE"
......
...@@ -39,7 +39,9 @@ class Dispatcher ...@@ -39,7 +39,9 @@ class Dispatcher
switch path.first() switch path.first()
when 'admin' then new Admin() when 'admin' then new Admin()
when 'wikis' then new Wikis() when 'projects'
new Wikis() if path[1] == 'wikis'
initSearch: -> initSearch: ->
autocomplete_json = $('.search-autocomplete-json').data('autocomplete-opts') autocomplete_json = $('.search-autocomplete-json').data('autocomplete-opts')
......
...@@ -7,3 +7,7 @@ $.fn.enableButton = -> ...@@ -7,3 +7,7 @@ $.fn.enableButton = ->
$(@).removeAttr('disabled'). $(@).removeAttr('disabled').
removeClass('disabled') removeClass('disabled')
$.fn.disableButton = ->
$(@).attr('disabled', 'disabled').
addClass('disabled')
...@@ -44,7 +44,7 @@ GitLab.GfmAutoComplete = ...@@ -44,7 +44,7 @@ GitLab.GfmAutoComplete =
tpl: @Issues.template tpl: @Issues.template
callbacks: callbacks:
before_save: (issues) -> before_save: (issues) ->
$.map issues, (i) -> id: i.id, title: i.title, search: "#{i.id} #{i.title}" $.map issues, (i) -> id: i.id, title: sanitize(i.title), search: "#{i.id} #{i.title}"
input.one "focus", => input.one "focus", =>
$.getJSON(@dataSource).done (data) -> $.getJSON(@dataSource).done (data) ->
......
...@@ -119,7 +119,7 @@ $ -> ...@@ -119,7 +119,7 @@ $ ->
# Commit show suppressed diff # Commit show suppressed diff
$(".supp_diff_link").bind "click", -> $(".content").on "click", ".supp_diff_link", ->
$(@).next('table').show() $(@).next('table').show()
$(@).remove() $(@).remove()
......
...@@ -22,12 +22,7 @@ class MergeRequest ...@@ -22,12 +22,7 @@ class MergeRequest
this.$('.show-all-commits').on 'click', => this.$('.show-all-commits').on 'click', =>
this.showAllCommits() this.showAllCommits()
modal = $('#modal_merge_info').modal modal: true, show:false modal = $('#modal_merge_info').modal(show: false)
$('.how_to_merge_link').bind "click", ->
modal.show()
$('.modal-header .close').bind "click", ->
modal.hide()
# Local jQuery finder # Local jQuery finder
$: (selector) -> $: (selector) ->
......
...@@ -227,10 +227,11 @@ var NoteList = { ...@@ -227,10 +227,11 @@ var NoteList = {
// Show the attachment delete link // Show the attachment delete link
note.find(".js-note-attachment-delete").show(); note.find(".js-note-attachment-delete").show();
GitLab.GfmAutoComplete.setup();
var form = note.find(".note-edit-form"); var form = note.find(".note-edit-form");
form.show(); form.show();
var textarea = form.find("textarea"); var textarea = form.find("textarea");
var p = $("<p></p>").text(textarea.val()); var p = $("<p></p>").text(textarea.val());
var hidden_div = $('<div class="note-original-content"></div>').append(p); var hidden_div = $('<div class="note-original-content"></div>').append(p);
......
class Wikis class Wikis
constructor: -> constructor: ->
modal = $('#modal-new-wiki').modal({modal: true, show:false})
$('.add-new-wiki').bind "click", ->
modal.show()
$('.build-new-wiki').bind "click", -> $('.build-new-wiki').bind "click", ->
field = $('#new_wiki_path') field = $('#new_wiki_path')
slug = field.val() slug = field.val()
...@@ -13,7 +8,5 @@ class Wikis ...@@ -13,7 +8,5 @@ class Wikis
if(slug.length > 0) if(slug.length > 0)
location.href = path + "/" + slug location.href = path + "/" + slug
$('.modal-header .close').bind "click", ->
modal.hide()
@Wikis = Wikis @Wikis = Wikis
...@@ -81,33 +81,6 @@ span.update-author { ...@@ -81,33 +81,6 @@ span.update-author {
font-weight: normal; font-weight: normal;
} }
form {
@extend .form-horizontal;
.actions {
@extend .form-actions;
}
.clearfix {
@extend .control-group;
}
.input {
@extend .controls;
}
label {
@extend .control-label;
}
.xlarge {
@extend .input-xlarge;
}
.xxlarge {
@extend .input-xxlarge;
}
}
.field_with_errors { .field_with_errors {
display: inline; display: inline;
} }
...@@ -121,15 +94,6 @@ ul.breadcrumb { ...@@ -121,15 +94,6 @@ ul.breadcrumb {
} }
a { a {
color: #474D57;
font-weight: bold;
font-size: 14px;
}
}
input[type=text] {
&.large_text {
padding: 6px;
font-size: 16px; font-size: 16px;
} }
} }
......
...@@ -2,11 +2,49 @@ ...@@ -2,11 +2,49 @@
$baseFontSize: 13px !default; $baseFontSize: 13px !default;
$baseLineHeight: 18px !default; $baseLineHeight: 18px !default;
// BOOTSTRAP /**
@import "bootstrap"; * BOOTSTRAP
*/
@import "bootstrap/variables";
@import "bootstrap/mixins";
@import "bootstrap/reset";
@import "bootstrap/scaffolding";
@import "bootstrap/grid";
@import "bootstrap/layouts";
@import "bootstrap/type";
@import "bootstrap/code";
@import "bootstrap/forms";
@import "bootstrap/tables";
@import "bootstrap/sprites";
@import "bootstrap/dropdowns";
@import "bootstrap/wells";
@import "bootstrap/component-animations";
@import "bootstrap/close";
@import "bootstrap/button-groups";
@import "bootstrap/alerts";
@import "bootstrap/navs";
@import "bootstrap/navbar";
@import "bootstrap/breadcrumbs";
@import "bootstrap/pagination";
@import "bootstrap/pager";
@import "bootstrap/modals";
@import "bootstrap/tooltip";
@import "bootstrap/popovers";
@import "bootstrap/thumbnails";
@import "bootstrap/media";
@import "bootstrap/labels-badges";
@import "bootstrap/progress-bars";
@import "bootstrap/accordion";
@import "bootstrap/carousel";
@import "bootstrap/hero-unit";
@import "bootstrap/utilities";
@import "bootstrap/responsive-utilities"; @import "bootstrap/responsive-utilities";
@import "bootstrap/responsive-1200px-min"; @import "bootstrap/responsive-1200px-min";
/**
* Font icons
*
*/
@import "font-awesome"; @import "font-awesome";
/** /**
...@@ -26,3 +64,4 @@ $baseLineHeight: 18px !default; ...@@ -26,3 +64,4 @@ $baseLineHeight: 18px !default;
@import "gitlab_bootstrap/files.scss"; @import "gitlab_bootstrap/files.scss";
@import "gitlab_bootstrap/tables.scss"; @import "gitlab_bootstrap/tables.scss";
@import "gitlab_bootstrap/lists.scss"; @import "gitlab_bootstrap/lists.scss";
@import "gitlab_bootstrap/forms.scss";
...@@ -10,15 +10,34 @@ ...@@ -10,15 +10,34 @@
* *
*/ */
.ui-box { .ui-box {
background: #F9F9F9; background: #FFF;
margin-bottom: 20px; margin-bottom: 20px;
border: 1px solid #CCC; border: 1px solid #CCC;
word-wrap: break-word; word-wrap: break-word;
@include solid-shade;
&.small-box {
margin-bottom: 10px;
.title {
font-size: 13px;
line-height: 30px;
a {
color: #666;
&:hover {
text-decoration: underline;
}
}
}
}
&.ui-box-show { &.ui-box-show {
margin:20px 0; margin:20px 0;
background: #FFF; background: #FFF;
.control-group {
margin-bottom: 0;
}
} }
&.ui-box-danger { &.ui-box-danger {
...@@ -71,10 +90,6 @@ ...@@ -71,10 +90,6 @@
border-top: 1px solid #eee; border-top: 1px solid #eee;
} }
&.white {
background: #fff;
}
ul { ul {
margin: 0; margin: 0;
} }
...@@ -102,6 +117,8 @@ ...@@ -102,6 +117,8 @@
.btn { .btn {
vertical-align: middle; vertical-align: middle;
padding: 4px 12px;
@include box-shadow(0 0px 1px 1px #f2f2f2);
} }
.nav-pills { .nav-pills {
......
.btn { .btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 13px;
line-height: $baseLineHeight;
text-align: center;
vertical-align: middle;
cursor: pointer;
border: 1px solid #BBB;
color: $style_color;
@include border-radius($baseBorderRadius);
@include box-shadow(inset 0 1px 0 rgba(255,255,255,.2));
@include linear-gradient(#f1f1f1, #e1e1e1); @include linear-gradient(#f1f1f1, #e1e1e1);
text-shadow: 0 1px 1px #FFF; text-shadow: 0 1px 1px #FFF;
border-color: #BBB; text-decoration: none;
&.hover,
&:hover { &:hover {
color: $style_color;
background: #f1f1f1; background: #f1f1f1;
@include linear-gradient(#fAfAfA, #f1f1f1);
border-color: #AAA; border-color: #AAA;
color: #333; text-decoration: none;
@include linear-gradient(#fAfAfA, #f1f1f1);
} }
&.btn-primary { &.focus,
background: #2a79A3; &:focus {
@include linear-gradient(#47A7b7, #2585b5); text-decoration: none;
border-color: #2A79A3; @include box-shadow(inset 0 2px 4px rgba(0,0,0,.15));
color: #fff;
text-shadow: 0 1px 1px #268;
&:hover {
background: $primary_color;
color: #fff;
} }
&.disabled { &.active,
color: #fff; &:active {
background: $primary_color; background-image: none;
} outline: 0;
text-decoration: none;
@include box-shadow(inset 0 2px 4px rgba(0,0,0,.15));
} }
&.btn-info { &.disabled,
background: #5aB9C3; &[disabled] {
border-color: $primary_color; cursor: default;
color: #fff; background-image: none;
text-shadow: 0 1px 1px #268; @include opacity(65);
&:hover { @include box-shadow(none);
background: $primary_color;
color: #fff;
} }
&.disabled { &.btn-primary {
color: #fff; color: #FFF;
background: $primary_color; border-color: #189;
text-shadow: 0 1px 1px #189;
@include linear-gradient(#4AC, #289);
&.hover,
&:hover,
&.disabled,
&[disabled] {
color: #FFF;
background: #389;
} }
} }
&.btn-success { &.btn-success {
&:hover { color: #FFF;
background: #51a351; border-color: #1A1;
text-shadow: 0 1px 1px #FFF;
text-shadow: 0 1px 1px #181;
@include linear-gradient(#62C452, #51a351);
&.hover,
&:hover,
&.disabled,
&[disabled] {
color: #FFF;
background: #2A2;
}
} }
&.disabled { &.btn-danger {
color: #fff; color: #FFF;
background: #2b2; text-shadow: 0 1px 1px #811;
border-color: #BD362F;
@include linear-gradient(#EE5F5B, #BD362F);
&.hover,
&:hover,
&.disabled,
&[disabled] {
color: #FFF;
background: #A22;
} }
} }
&.btn-new {
@extend .btn-success;
}
&.btn-create { &.btn-create {
@extend .wide; @extend .wide;
@extend .btn-success; @extend .btn-success;
...@@ -67,12 +111,6 @@ ...@@ -67,12 +111,6 @@
&.btn-close, &.btn-close,
&.btn-remove { &.btn-remove {
@extend .btn-danger; @extend .btn-danger;
border-color: #BD362F;
&:hover {
color: #fff;
background: #EE4E49;
}
} }
&.btn-cancel { &.btn-cancel {
...@@ -84,13 +122,9 @@ ...@@ -84,13 +122,9 @@
padding-right: 20px; padding-right: 20px;
} }
&.small { &.btn-small {
@extend .btn-small; padding: 2px 10px;
} font-size: 12px;
&.active {
border-color: #aaa;
background-color: #ccc;
} }
&.btn-tiny { &.btn-tiny {
...@@ -104,9 +138,4 @@ ...@@ -104,9 +138,4 @@
margin-right: 7px; margin-right: 7px;
float: left; float: left;
} }
&.padded {
margin-right: 3px;
padding: 4px 10px 4px;
}
} }
...@@ -48,7 +48,13 @@ ...@@ -48,7 +48,13 @@
line-height: 36px; line-height: 36px;
} }
p.slead { color: #456; font-size: 16px; margin-bottom: 12px; font-weight: 200; line-height: 24px; } .slead {
color: #666;
font-size: 14px;
margin-bottom: 12px;
font-weight: normal;
line-height: 24px;
}
/** FORMS **/ /** FORMS **/
input[type='search'].search-text-input { input[type='search'].search-text-input {
...@@ -66,7 +72,7 @@ input[type='text'].danger { ...@@ -66,7 +72,7 @@ input[type='text'].danger {
text-shadow: 0 1px 1px #fff text-shadow: 0 1px 1px #fff
} }
fieldset legend { font-size: 17px; } fieldset legend { font-size: 15px; }
.tab-content { .tab-content {
overflow: visible; overflow: visible;
...@@ -90,3 +96,11 @@ pre.well-pre { ...@@ -90,3 +96,11 @@ pre.well-pre {
border-radius: 0; border-radius: 0;
color: #555; color: #555;
} }
.input-append .btn.active, .input-prepend .btn.active {
background: #CCC;
border-color: #BBB;
text-shadow: 0 1px 1px #fff;
font-weight: bold;
@include box-shadow(inset 0 2px 4px rgba(0,0,0,.15));
}
...@@ -3,18 +3,18 @@ ...@@ -3,18 +3,18 @@
* *
*/ */
.file-holder { .file-holder {
border: 1px solid #BBB; border: 1px solid #CCC;
margin-bottom: 1em; margin-bottom: 1em;
@include solid-shade;
.file-title { .file-title {
border-bottom: 1px solid #bbb; border-bottom: 1px solid #bbb;
@include bg-dark-gray-gradient; @include bg-dark-gray-gradient;
text-shadow: 0 1px 1px #fff;
margin: 0; margin: 0;
font-weight: normal; font-weight: normal;
font-weight: bold; font-weight: bold;
text-align: left; text-align: left;
color: #666; color: $style_color;
padding: 9px 10px; padding: 9px 10px;
height: 18px; height: 18px;
......
form {
@extend .form-horizontal;
label {
@extend .control-label;
}
}
input {
&.input-xpadding {
padding: 6px 10px;
}
}
.control-group {
.control-label {
padding-top: 6px;
}
.controls {
input, textarea {
padding: 6px 10px;
}
input[type="radio"], input[type="checkbox"] {
margin-top: 6px;
}
}
}
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
margin: 0; margin: 0;
list-style: none; list-style: none;
li { li {
background-color: #FFF;
padding: 10px; padding: 10px;
min-height: 20px; min-height: 20px;
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
...@@ -84,4 +83,13 @@ ul.bordered-list { ...@@ -84,4 +83,13 @@ ul.bordered-list {
a { color: #777; } a { color: #777; }
} }
} }
&.top-list {
li:first-child {
padding-top: 0;
h4, h5 {
margin-top: 0;
}
}
}
} }
...@@ -90,7 +90,6 @@ ...@@ -90,7 +90,6 @@
@mixin page-title { @mixin page-title {
color: $style_color; color: $style_color;
font-size: 20px; font-size: 20px;
font-weight: normal;
line-height: 1.5; line-height: 1.5;
margin-top: 0px; margin-top: 0px;
margin-bottom: 15px; margin-bottom: 15px;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
> li > a { > li > a {
@include border-radius(0); @include border-radius(0);
} }
&.nav-stacked { &.nav-stacked {
> li > a { > li > a {
border-left: 4px solid #EEE; border-left: 4px solid #EEE;
...@@ -30,6 +31,12 @@ ...@@ -30,6 +31,12 @@
} }
} }
} }
&.nav-pills-small {
> li > a {
padding: 8px 12px;
}
}
} }
.nav-pills > .active > a > i[class^="icon-"] { background: inherit; } .nav-pills > .active > a > i[class^="icon-"] { background: inherit; }
......
table { table {
@extend .table; @extend .table;
@extend .table-striped; @extend .table-striped;
@include solid-shade; border: 1px solid #CCC;
border: 1px solid #bbb;
width: 100%; width: 100%;
&.low { &.low {
...@@ -20,7 +19,7 @@ table { ...@@ -20,7 +19,7 @@ table {
th { th {
font-weight: bold; font-weight: bold;
vertical-align: middle; vertical-align: middle;
border-bottom: 1px solid #bbb; border-bottom: 1px solid #CCC;
text-shadow: 0 1px 1px #fff; text-shadow: 0 1px 1px #fff;
@include bg-dark-gray-gradient; @include bg-dark-gray-gradient;
...@@ -46,11 +45,11 @@ table { ...@@ -46,11 +45,11 @@ table {
} }
&:first-child { &:first-child {
border-left: 1px solid #bbb; border-left: 1px solid #CCC;
} }
&:last-child { &:last-child {
border-right: 1px solid #bbb; border-right: 1px solid #CCC;
} }
} }
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
* Headers * Headers
* *
*/ */
h1, h2, h3, h4, h5, h6 {
font-weight: 500;
line-height: 1.1;
}
h1.page-title { h1.page-title {
@include page-title; @include page-title;
...@@ -48,13 +52,6 @@ a { ...@@ -48,13 +52,6 @@ a {
text-decoration: underline; text-decoration: underline;
} }
&.btn {
color: $style_color;
&:hover {
color: $style_color;
}
}
&.dark { &.dark {
color: $style_color; color: $style_color;
} }
......
...@@ -421,8 +421,8 @@ ...@@ -421,8 +421,8 @@
.commits-compare-switch{ .commits-compare-switch{
background: url("switch_icon.png") no-repeat center center; background: url("switch_icon.png") no-repeat center center;
width: 16px; width: 22px;
height: 18px; height: 22px;
text-indent: -9999px; text-indent: -9999px;
float: left; float: left;
margin-right: 9px; margin-right: 9px;
...@@ -471,3 +471,7 @@ li.commit { ...@@ -471,3 +471,7 @@ li.commit {
} }
} }
} }
.commit-breadcrumb {
padding: 0;
}
...@@ -44,7 +44,7 @@ input.check_all_issues { ...@@ -44,7 +44,7 @@ input.check_all_issues {
margin: 0; margin: 0;
margin-right: 10px; margin-right: 10px;
position: relative; position: relative;
top: 8px; top: 10px;
height: 22px; height: 22px;
} }
...@@ -52,6 +52,10 @@ input.check_all_issues { ...@@ -52,6 +52,10 @@ input.check_all_issues {
.title { .title {
height: 40px; height: 40px;
} }
form {
margin: 0;
}
} }
.btn.close_issue { .btn.close_issue {
...@@ -88,14 +92,11 @@ input.check_all_issues { ...@@ -88,14 +92,11 @@ input.check_all_issues {
} }
.update_selected_issues { .update_selected_issues {
position: relative;
top:5px;
margin-left: 4px; margin-left: 4px;
float: left;
} }
.update_issues_text { .update_issues_text {
padding: 3px; padding: 5px;
line-height: 28px; line-height: 28px;
float: left; float: left;
color: #479; color: #479;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
ul { ul {
margin: auto; margin: auto;
height: 42px; height: 40px;
overflow: hidden; overflow: hidden;
.count { .count {
font-weight: normal; font-weight: normal;
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
text-align: center; text-align: center;
font-weight: normal; font-weight: normal;
height: 38px; height: 38px;
line-height: 36px; line-height: 34px;
color: #777; color: #777;
text-shadow: 0 1px 1px white; text-shadow: 0 1px 1px white;
padding: 0 10px; padding: 0 10px;
......
.new_project, .new_project,
.edit_project { .edit_project {
.project_name_holder {
input,
label {
font-size: 16px;
line-height: 20px;
padding: 8px;
}
.btn {
padding: 6px 10px;
margin-left: 10px;
margin-bottom: 8px;
}
}
.adv_settings {
h6 { margin-left: 40px; }
}
fieldset.features { fieldset.features {
.control-label { .control-label {
font-weight: bold; font-weight: bold;
...@@ -30,6 +13,10 @@ ...@@ -30,6 +13,10 @@
padding: 4px 7px; padding: 4px 7px;
border: 1px solid #CCC; border: 1px solid #CCC;
margin-bottom: 20px; margin-bottom: 20px;
.btn {
padding: 4px 12px;
}
} }
.project_clone_holder { .project_clone_holder {
...@@ -114,7 +101,7 @@ ul.nav.nav-projects-tabs { ...@@ -114,7 +101,7 @@ ul.nav.nav-projects-tabs {
.public-clone { .public-clone {
background: #333; background: #333;
color: #f5f5f5; color: #f5f5f5;
padding: 5px 10px; padding: 6px 10px;
margin: 1px; margin: 1px;
font-weight: normal; font-weight: normal;
} }
......
...@@ -104,6 +104,8 @@ ...@@ -104,6 +104,8 @@
} }
.tree-btn-group { .tree-btn-group {
top: 2px;
.btn { .btn {
margin-right: 0px; margin-right: 0px;
padding: 2px 10px; padding: 2px 10px;
......
...@@ -31,8 +31,4 @@ ...@@ -31,8 +31,4 @@
border-left: 1px solid #666; border-left: 1px solid #666;
} }
} }
.main-nav {
box-shadow: 0 -1px 0 white inset;
}
} }
...@@ -11,8 +11,8 @@ class FilterContext ...@@ -11,8 +11,8 @@ class FilterContext
end end
def apply_filter items def apply_filter items
if params[:project_id] if params[:project_id].present?
items = items.by_project(params[:project_id]) items = items.where(project_id: params[:project_id])
end end
if params[:search].present? if params[:search].present?
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# based on filtering passed via params for @project # based on filtering passed via params for @project
class MergeRequestsLoadContext < BaseContext class MergeRequestsLoadContext < BaseContext
def execute def execute
type = params[:f] type = params[:status]
merge_requests = project.merge_requests merge_requests = project.merge_requests
......
...@@ -11,7 +11,7 @@ class SearchContext ...@@ -11,7 +11,7 @@ class SearchContext
return result unless query.present? return result unless query.present?
projects = Project.where(id: project_ids) projects = Project.where(id: project_ids)
result[:projects] = projects.search(query).limit(10) result[:projects] = projects.search(query).limit(20)
# Search inside singe project # Search inside singe project
project = projects.first if projects.length == 1 project = projects.first if projects.length == 1
...@@ -19,8 +19,8 @@ class SearchContext ...@@ -19,8 +19,8 @@ class SearchContext
if params[:search_code].present? if params[:search_code].present?
result[:blobs] = project.repository.search_files(query, params[:repository_ref]) unless project.empty_repo? result[:blobs] = project.repository.search_files(query, params[:repository_ref]) unless project.empty_repo?
else else
result[:merge_requests] = MergeRequest.in_projects(project_ids).search(query).limit(10) result[:merge_requests] = MergeRequest.in_projects(project_ids).search(query).limit(20)
result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10) result[:issues] = Issue.where(project_id: project_ids).search(query).limit(20)
result[:wiki_pages] = [] result[:wiki_pages] = []
end end
result result
......
...@@ -2,7 +2,7 @@ class Profiles::GroupsController < ApplicationController ...@@ -2,7 +2,7 @@ class Profiles::GroupsController < ApplicationController
layout "profile" layout "profile"
def index def index
@groups = current_user.authorized_groups.page(params[:page]).per(20) @user_groups = current_user.users_groups.page(params[:page]).per(20)
end end
def leave def leave
......
...@@ -11,6 +11,10 @@ class Projects::BranchesController < Projects::ApplicationController ...@@ -11,6 +11,10 @@ class Projects::BranchesController < Projects::ApplicationController
@branches = Kaminari.paginate_array(@repository.branches).page(params[:page]).per(30) @branches = Kaminari.paginate_array(@repository.branches).page(params[:page]).per(30)
end end
def recent
@branches = @repository.recent_branches
end
def create def create
@repository.add_branch(params[:branch_name], params[:ref]) @repository.add_branch(params[:branch_name], params[:ref])
......
...@@ -10,7 +10,7 @@ class Projects::EditTreeController < Projects::ApplicationController ...@@ -10,7 +10,7 @@ class Projects::EditTreeController < Projects::ApplicationController
before_filter :edit_requirements, only: [:show, :update] before_filter :edit_requirements, only: [:show, :update]
def show def show
@last_commit = @project.repository.last_commit_for(@ref, @path).sha @last_commit = Gitlab::Git::Commit.last_for_path(@project.repository, @ref, @path).sha
end end
def update def update
......
...@@ -4,10 +4,6 @@ class Projects::RepositoriesController < Projects::ApplicationController ...@@ -4,10 +4,6 @@ class Projects::RepositoriesController < Projects::ApplicationController
before_filter :authorize_code_access! before_filter :authorize_code_access!
before_filter :require_non_empty_project before_filter :require_non_empty_project
def show
@activities = @repository.commits_with_refs(20)
end
def stats def stats
@stats = Gitlab::Git::Stats.new(@repository.raw, @repository.root_ref) @stats = Gitlab::Git::Stats.new(@repository.raw, @repository.root_ref)
@graph = @stats.graph @graph = @stats.graph
......
...@@ -13,7 +13,8 @@ class UsersGroupsController < ApplicationController ...@@ -13,7 +13,8 @@ class UsersGroupsController < ApplicationController
end end
def update def update
# TODO: implement @member = @group.users_groups.find(params[:id])
@member.update_attributes(params[:users_group])
end end
def destroy def destroy
......
...@@ -15,62 +15,10 @@ module CommitsHelper ...@@ -15,62 +15,10 @@ module CommitsHelper
commit_person_link(commit, options.merge(source: :committer)) commit_person_link(commit, options.merge(source: :committer))
end end
def identification_type(line)
if line[0] == "+"
"new"
elsif line[0] == "-"
"old"
else
nil
end
end
def build_line_anchor(diff, line_new, line_old)
"#{hexdigest(diff.new_path)}_#{line_old}_#{line_new}"
end
def each_diff_line(diff, index) def each_diff_line(diff, index)
diff_arr = diff.diff.lines.to_a Gitlab::DiffParser.new(diff).each do |full_line, type, line_code, line_new, line_old|
line_old = 1
line_new = 1
type = nil
lines_arr = ::Gitlab::InlineDiff.processing diff_arr
lines_arr.each do |line|
next if line.match(/^\-\-\- \/dev\/null/)
next if line.match(/^\+\+\+ \/dev\/null/)
next if line.match(/^\-\-\- a/)
next if line.match(/^\+\+\+ b/)
full_line = html_escape(line.gsub(/\n/, ''))
full_line = ::Gitlab::InlineDiff.replace_markers full_line
if line.match(/^@@ -/)
type = "match"
line_old = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0
line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0
next if line_old == 1 && line_new == 1 #top of file
yield(full_line, type, nil, nil, nil)
next
else
type = identification_type(line)
line_code = build_line_anchor(diff, line_new, line_old)
yield(full_line, type, line_code, line_new, line_old) yield(full_line, type, line_code, line_new, line_old)
end end
if line[0] == "+"
line_new += 1
elsif line[0] == "-"
line_old += 1
else
line_new += 1
line_old += 1
end
end
end end
def each_diff_line_near(diff, index, expected_line_code) def each_diff_line_near(diff, index, expected_line_code)
......
module DashboardHelper module DashboardHelper
def dashboard_filter_path(entity, options={}) def filter_path(entity, options={})
exist_opts = { exist_opts = {
status: params[:status], status: params[:status],
project_id: params[:project_id], project_id: params[:project_id],
...@@ -7,12 +7,9 @@ module DashboardHelper ...@@ -7,12 +7,9 @@ module DashboardHelper
options = exist_opts.merge(options) options = exist_opts.merge(options)
case entity path = request.path
when 'issue' then path << "?#{options.to_param}"
issues_dashboard_path(options) path
when 'merge_request'
merge_requests_dashboard_path(options)
end
end end
def entities_per_project project, entity def entities_per_project project, entity
......
module GroupsHelper module GroupsHelper
def group_filter_path(entity, options={})
exist_opts = {
status: params[:status],
project_id: params[:project_id],
}
options = exist_opts.merge(options)
case entity
when 'issue' then
issues_group_path(@group, options)
when 'merge_request'
merge_requests_group_path(@group, options)
end
end
def remove_user_from_group_message(group, user) def remove_user_from_group_message(group, user)
"You are going to remove #{user.name} from #{group.name} Group. Are you sure?" "You are going to remove #{user.name} from #{group.name} Group. Are you sure?"
end end
......
module NotificationsHelper module NotificationsHelper
def notification_icon(notification)
if notification.disabled?
content_tag :i, nil, class: 'icon-circle cred'
elsif notification.participating?
content_tag :i, nil, class: 'icon-circle cblue'
elsif notification.watch?
content_tag :i, nil, class: 'icon-circle cgreen'
else
content_tag :i, nil, class: 'icon-circle-blank cblue'
end
end
end end
...@@ -39,12 +39,12 @@ module TreeHelper ...@@ -39,12 +39,12 @@ module TreeHelper
# #
# Returns boolean # Returns boolean
def markup?(filename) def markup?(filename)
filename.end_with?(*%w(.textile .rdoc .org .creole filename.downcase.end_with?(*%w(.textile .rdoc .org .creole
.mediawiki .rst .asciidoc .pod)) .mediawiki .rst .asciidoc .pod))
end end
def gitlab_markdown?(filename) def gitlab_markdown?(filename)
filename.end_with?(*%w(.mdown .md .markdown)) filename.downcase.end_with?(*%w(.mdown .md .markdown))
end end
def plain_text_readme? filename def plain_text_readme? filename
...@@ -57,6 +57,8 @@ module TreeHelper ...@@ -57,6 +57,8 @@ module TreeHelper
end end
def allowed_tree_edit? def allowed_tree_edit?
return false unless @repository.branch_names.include?(@ref)
if @project.protected_branch? @ref if @project.protected_branch? @ref
can?(current_user, :push_code_to_protected_branches, @project) can?(current_user, :push_code_to_protected_branches, @project)
else else
......
# Will be removed in 6.1 with tables
#
# == Schema Information # == Schema Information
# #
# Table name: user_teams # Table name: user_teams
......
# Will be removed in 6.1 with tables
#
# == Schema Information # == Schema Information
# #
# Table name: user_team_project_relationships # Table name: user_team_project_relationships
......
# Will be removed in 6.1 with tables
#
# == Schema Information # == Schema Information
# #
# Table name: user_team_user_relationships # Table name: user_team_user_relationships
......
...@@ -149,11 +149,12 @@ class MergeRequest < ActiveRecord::Base ...@@ -149,11 +149,12 @@ class MergeRequest < ActiveRecord::Base
end end
def unmerged_diffs def unmerged_diffs
if for_fork? diffs = if for_fork?
diffs = Gitlab::Satellite::MergeAction.new(author, self).diffs_between_satellite Gitlab::Satellite::MergeAction.new(author, self).diffs_between_satellite
else else
diffs = target_project.repository.diffs_between(source_branch, target_branch) Gitlab::Git::Diff.between(project.repository, source_branch, target_branch)
end end
diffs ||= [] diffs ||= []
diffs diffs
end end
......
...@@ -50,6 +50,9 @@ class Note < ActiveRecord::Base ...@@ -50,6 +50,9 @@ class Note < ActiveRecord::Base
scope :inc_author_project, ->{ includes(:project, :author) } scope :inc_author_project, ->{ includes(:project, :author) }
scope :inc_author, ->{ includes(:author) } scope :inc_author, ->{ includes(:author) }
serialize :st_diff
before_create :set_diff, if: ->(n) { n.line_code.present? }
def self.create_status_change_note(noteable, project, author, status) def self.create_status_change_note(noteable, project, author, status)
create({ create({
noteable: noteable, noteable: noteable,
...@@ -67,14 +70,31 @@ class Note < ActiveRecord::Base ...@@ -67,14 +70,31 @@ class Note < ActiveRecord::Base
nil nil
end end
def diff def find_diff
if noteable.diffs.present? return nil unless noteable && noteable.diffs.present?
noteable.diffs.select do |d|
if d.new_path @diff ||= noteable.diffs.find do |d|
Digest::SHA1.hexdigest(d.new_path) == diff_file_index Digest::SHA1.hexdigest(d.new_path) == diff_file_index if d.new_path
end end
end.first
end end
def set_diff
# First lets find notes with same diff
# before iterating over all mr diffs
diff = Note.where(noteable_id: self.noteable_id, noteable_type: self.noteable_type, line_code: self.line_code).last.try(:diff)
diff ||= find_diff
self.st_diff = diff.to_hash if diff
end
def diff
@diff ||= Gitlab::Git::Diff.new(st_diff) if st_diff.respond_to?(:map)
end
def active?
# TODO: determine if discussion is outdated
# according to recent MR diff or not
true
end end
def diff_file_index def diff_file_index
...@@ -82,13 +102,29 @@ class Note < ActiveRecord::Base ...@@ -82,13 +102,29 @@ class Note < ActiveRecord::Base
end end
def diff_file_name def diff_file_name
diff.new_path diff.new_path if diff
end
def diff_old_line
line_code.split('_')[1].to_i
end end
def diff_new_line def diff_new_line
line_code.split('_')[2].to_i line_code.split('_')[2].to_i
end end
def diff_line
return @diff_line if @diff_line
if diff
Gitlab::DiffParser.new(diff).each do |full_line, type, line_code, line_new, line_old|
@diff_line = full_line if line_code == self.line_code
end
end
@diff_line
end
def discussion_id def discussion_id
@discussion_id ||= [:discussion, noteable_type.try(:underscore), noteable_id || commit_id, line_code].join("-").to_sym @discussion_id ||= [:discussion, noteable_type.try(:underscore), noteable_id || commit_id, line_code].join("-").to_sym
end end
......
...@@ -18,19 +18,25 @@ class Repository ...@@ -18,19 +18,25 @@ class Repository
end end
def commit(id = nil) def commit(id = nil)
commit = raw_repository.commit(id) commit = Gitlab::Git::Commit.find(raw_repository, id)
commit = Commit.new(commit) if commit commit = Commit.new(commit) if commit
commit commit
end end
def commits(ref, path = nil, limit = nil, offset = nil) def commits(ref, path = nil, limit = nil, offset = nil)
commits = raw_repository.commits(ref, path, limit, offset) commits = Gitlab::Git::Commit.where(
repo: raw_repository,
ref: ref,
path: path,
limit: limit,
offset: offset,
)
commits = Commit.decorate(commits) if commits.present? commits = Commit.decorate(commits) if commits.present?
commits commits
end end
def commits_between(target, source) def commits_between(from, to)
commits = raw_repository.commits_between(target, source) commits = Gitlab::Git::Commit.between(raw_repository, from, to)
commits = Commit.decorate(commits) if commits.present? commits = Commit.decorate(commits) if commits.present?
commits commits
end end
...@@ -43,6 +49,12 @@ class Repository ...@@ -43,6 +49,12 @@ class Repository
tags.find { |tag| tag.name == name } tags.find { |tag| tag.name == name }
end end
def recent_branches(limit = 20)
branches.sort do |a, b|
a.commit.committed_date <=> b.commit.committed_date
end[0..limit]
end
def add_branch(branch_name, ref) def add_branch(branch_name, ref)
Rails.cache.delete(cache_key(:branch_names)) Rails.cache.delete(cache_key(:branch_names))
......
...@@ -102,19 +102,22 @@ class NotificationService ...@@ -102,19 +102,22 @@ class NotificationService
# ignore wall messages # ignore wall messages
return true unless note.noteable_type.present? return true unless note.noteable_type.present?
# ignore gitlab service messages
return true if note.note =~ /\A_Status changed to closed_/
opts = { noteable_type: note.noteable_type, project_id: note.project_id } opts = { noteable_type: note.noteable_type, project_id: note.project_id }
if note.commit_id.present? if note.commit_id.present?
opts.merge!(commit_id: note.commit_id) opts.merge!(commit_id: note.commit_id)
recipients = [note.commit_author]
else else
opts.merge!(noteable_id: note.noteable_id) opts.merge!(noteable_id: note.noteable_id)
end
target = note.noteable target = note.noteable
if target.respond_to?(:participants) if target.respond_to?(:participants)
recipients = target.participants recipients = target.participants
else else
recipients = [] recipients = note.mentioned_users
end
end end
# Get users who left comment in thread # Get users who left comment in thread
......
...@@ -4,22 +4,22 @@ ...@@ -4,22 +4,22 @@
- if @group.errors.any? - if @group.errors.any?
.alert.alert-error .alert.alert-error
%span= @group.errors.full_messages.first %span= @group.errors.full_messages.first
.clearfix.group_name_holder .control-group.group_name_holder
= f.label :name do = f.label :name do
Group name is Group name is
.input .controls
= f.text_field :name, placeholder: "Example Group", class: "xxlarge" = f.text_field :name, placeholder: "Example Group", class: "input-xxlarge"
.clearfix.group-description-holder .control-group.group-description-holder
= f.label :description, "Details" = f.label :description, "Details"
.input .controls
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4 = f.text_area :description, maxlength: 250, class: "input-xxlarge js-gfm-input", rows: 4
.clearfix.group_name_holder .control-group.group_name_holder
= f.label :path do = f.label :path do
%span.cred Group path is %span.cred Group path is
.input .controls
= f.text_field :path, placeholder: "example-group", class: "xxlarge danger" = f.text_field :path, placeholder: "example-group", class: "input-xxlarge danger"
%ul.cred %ul.cred
%li Changing group path can have unintended side effects. %li Changing group path can have unintended side effects.
%li Renaming group path will rename directory for all related projects %li Renaming group path will rename directory for all related projects
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
allows you to keep projects organized. allows you to keep projects organized.
Use groups for uniting related projects. Use groups for uniting related projects.
= link_to 'New Group', new_admin_group_path, class: "btn btn-small pull-right" = link_to 'New Group', new_admin_group_path, class: "btn btn-new pull-right"
%br %br
= form_tag admin_groups_path, method: :get, class: 'form-inline' do = form_tag admin_groups_path, method: :get, class: 'form-inline' do
= text_field_tag :name, params[:name], class: "span6" = text_field_tag :name, params[:name], class: "span6"
......
...@@ -4,15 +4,15 @@ ...@@ -4,15 +4,15 @@
- if @group.errors.any? - if @group.errors.any?
.alert.alert-error .alert.alert-error
%span= @group.errors.full_messages.first %span= @group.errors.full_messages.first
.clearfix .control-group
= f.label :name do = f.label :name do
Group name is Group name is
.input .controls
= f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left" = f.text_field :name, placeholder: "Ex. OpenSource", class: "input-xxlarge left"
.clearfix.group-description-holder .control-group.group-description-holder
= f.label :description, "Details" = f.label :description, "Details"
.input .controls
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4 = f.text_area :description, maxlength: 250, class: "input-xxlarge js-gfm-input", rows: 4
.form-actions .form-actions
= f.submit 'Create group', class: "btn btn-create" = f.submit 'Create group', class: "btn btn-create"
......
...@@ -10,10 +10,10 @@ ...@@ -10,10 +10,10 @@
.alert.alert-error .alert.alert-error
- @hook.errors.full_messages.each do |msg| - @hook.errors.full_messages.each do |msg|
%p= msg %p= msg
.clearfix .control-group
= f.label :url, "URL:" = f.label :url, "URL:"
.input .controls
= f.text_field :url, class: "text_field xxlarge" = f.text_field :url, class: "text_field input-xxlarge input-xpadding"
&nbsp; &nbsp;
= f.submit "Add System Hook", class: "btn btn-create" = f.submit "Add System Hook", class: "btn btn-create"
%hr %hr
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
.title .title
Projects (#{@projects.total_count}) Projects (#{@projects.total_count})
.pull-right .pull-right
= link_to 'New Project', new_project_path, class: "btn btn-small btn-primary wide" = link_to 'New Project', new_project_path, class: "btn btn-new"
%ul.well-list %ul.well-list
- @projects.each do |project| - @projects.each do |project|
%li %li
......
...@@ -8,28 +8,28 @@ ...@@ -8,28 +8,28 @@
%fieldset %fieldset
%legend Account %legend Account
.clearfix .control-group
= f.label :name = f.label :name
.input .controls
= f.text_field :name, required: true, autocomplete: "off" = f.text_field :name, required: true, autocomplete: "off"
%span.help-inline * required %span.help-inline * required
.clearfix .control-group
= f.label :username = f.label :username
.input .controls
= f.text_field :username, required: true, autocomplete: "off" = f.text_field :username, required: true, autocomplete: "off"
%span.help-inline * required %span.help-inline * required
.clearfix .control-group
= f.label :email = f.label :email
.input .controls
= f.text_field :email, required: true, autocomplete: "off" = f.text_field :email, required: true, autocomplete: "off"
%span.help-inline * required %span.help-inline * required
- if @user.new_record? - if @user.new_record?
%fieldset %fieldset
%legend Password %legend Password
.clearfix .control-group
= f.label :password = f.label :password
.input .controls
%strong %strong
A temporary password will be generated and sent to user. A temporary password will be generated and sent to user.
%br %br
...@@ -37,33 +37,33 @@ ...@@ -37,33 +37,33 @@
- else - else
%fieldset %fieldset
%legend Password %legend Password
.clearfix .control-group
= f.label :password = f.label :password
.input= f.password_field :password, disabled: f.object.force_random_password .controls= f.password_field :password, disabled: f.object.force_random_password
.clearfix .control-group
= f.label :password_confirmation = f.label :password_confirmation
.input= f.password_field :password_confirmation, disabled: f.object.force_random_password .controls= f.password_field :password_confirmation, disabled: f.object.force_random_password
%fieldset %fieldset
%legend Access %legend Access
.row .row
.span8 .span8
.clearfix .control-group
= f.label :projects_limit = f.label :projects_limit
.input= f.number_field :projects_limit .controls= f.number_field :projects_limit
.clearfix .control-group
= f.label :can_create_group = f.label :can_create_group
.input= f.check_box :can_create_group .controls= f.check_box :can_create_group
.clearfix .control-group
= f.label :can_create_team = f.label :can_create_team
.input= f.check_box :can_create_team .controls= f.check_box :can_create_team
.clearfix .control-group
= f.label :admin do = f.label :admin do
%strong.cred Administrator %strong.cred Administrator
.input= f.check_box :admin .controls= f.check_box :admin
.span4 .span4
- unless @user.new_record? - unless @user.new_record?
.alert.alert-error .alert.alert-error
...@@ -75,17 +75,17 @@ ...@@ -75,17 +75,17 @@
= link_to 'Block User', block_admin_user_path(@user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn btn-small btn-remove" = link_to 'Block User', block_admin_user_path(@user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn btn-small btn-remove"
%fieldset %fieldset
%legend Profile %legend Profile
.clearfix .control-group
= f.label :skype = f.label :skype
.input= f.text_field :skype .controls= f.text_field :skype
.clearfix .control-group
= f.label :linkedin = f.label :linkedin
.input= f.text_field :linkedin .controls= f.text_field :linkedin
.clearfix .control-group
= f.label :twitter = f.label :twitter
.input= f.text_field :twitter .controls= f.text_field :twitter
.actions .form-actions
- if @user.new_record? - if @user.new_record?
= f.submit 'Create user', class: "btn btn-create" = f.submit 'Create user', class: "btn btn-create"
= link_to 'Cancel', admin_users_path, class: "btn btn-cancel" = link_to 'Cancel', admin_users_path, class: "btn btn-cancel"
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
.title .title
Users (#{@users.total_count}) Users (#{@users.total_count})
.pull-right .pull-right
= link_to 'New User', new_admin_user_path, class: "btn btn-small wide btn-primary" = link_to 'New User', new_admin_user_path, class: "btn btn-new"
%ul.well-list %ul.well-list
- @users.each do |user| - @users.each do |user|
%li %li
......
%h3.page-title %h3.page-title
Issues Issues assigned to me
%span.light
&ndash;
Assigned to you
%span.pull-right #{@issues.total_count} issues %span.pull-right #{@issues.total_count} issues
%p.light
For all issues you should visit project issues page. Or you can use search panel to find specific issue
%hr
.row .row
.span3 .span3
= render 'filter', entity: 'issue' = render 'shared/filter', entity: 'issue'
.span9 .span9
- if @issues.any? = render 'shared/issues'
- @issues.group_by(&:project).each do |group|
%div.ui-box
- project = group[0]
.title
= link_to_project project
&nbsp;
%i.icon-angle-right
&nbsp;
= link_to 'issues', project_issues_path(project)
%ul.well-list.issues-list
- group[1].each do |issue|
= render 'projects/issues/issue', issue: issue
%hr
= paginate @issues, theme: "gitlab"
- else
%p.nothing_here_message Nothing to show here
%h3.page-title %h3.page-title
Merge Requests Merge Requests
%span.light
&ndash;
Authored by or assigned to you
%span.pull-right #{@merge_requests.total_count} merge requests %span.pull-right #{@merge_requests.total_count} merge requests
%p.light
Only merge requests authored or assigned to you are listed here.
%hr
.row .row
.span3 .span3
= render 'filter', entity: 'merge_request' = render 'shared/filter', entity: 'merge_request'
.span9 .span9
= render 'shared/merge_requests' = render 'shared/merge_requests'
%h3.page-title My Projects
%p.light
All projects you have access to are listed here. Public projects are not included here unless you have membership in it
%hr
.row .row
.span3 .span3
%ul.nav.nav-pills.nav-stacked %ul.nav.nav-pills.nav-stacked
...@@ -32,7 +36,7 @@ ...@@ -32,7 +36,7 @@
= label.name = label.name
.span9 .span9
%ul.bordered-list.my-projects %ul.bordered-list.my-projects.top-list
- @projects.each do |project| - @projects.each do |project|
%li %li
%h4.project-title %h4.project-title
......
= form_for @users_group, url: group_users_groups_path(@group) do |f| = form_for @users_group, url: group_users_groups_path(@group) do |f|
%fieldset %fieldset
%legend= "New Group member(s) for #{@group.name}" %legend
New member(s) for
%strong #{@group.name}
group
%h6 1. Choose users you want in the group %p 1. Choose users you want in the group
.clearfix .control-group
= f.label :user_ids, "People" = f.label :user_ids, "People"
.input= users_select_tag(:user_ids, multiple: true, class: 'input-large') .controls= users_select_tag(:user_ids, multiple: true, class: 'input-large')
%h6 2. Set access level for them %p 2. Set access level for them
.clearfix .control-group
= f.label :group_access, "Group Access" = f.label :group_access, "Group Access"
.input= select_tag :group_access, options_for_select(UsersGroup.group_access_roles, @users_group.group_access), class: "project-access-select chosen" .controls= select_tag :group_access, options_for_select(UsersGroup.group_access_roles, @users_group.group_access), class: "project-access-select chosen"
.form-actions .form-actions
= f.submit 'Add users into group', class: "btn btn-create" = f.submit 'Add users into group', class: "btn btn-create"
......
...@@ -20,22 +20,22 @@ ...@@ -20,22 +20,22 @@
.ui-box .ui-box
.title .title
%strong= @group.name %strong= @group.name
Group Settings: group settings:
%div.form-holder %div.form-holder
= form_for @group do |f| = form_for @group do |f|
- if @group.errors.any? - if @group.errors.any?
.alert.alert-error .alert.alert-error
%span= @group.errors.full_messages.first %span= @group.errors.full_messages.first
.clearfix .control-group
= f.label :name do = f.label :name do
Group name is Group name is
.input .controls
= f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left" = f.text_field :name, placeholder: "Ex. OpenSource", class: "input-xxlarge left"
.clearfix.group-description-holder .control-group.group-description-holder
= f.label :description, "Details" = f.label :description, "Details"
.input .controls
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4 = f.text_area :description, maxlength: 250, class: "input-xxlarge js-gfm-input", rows: 4
.form-actions .form-actions
= f.submit 'Save group', class: "btn btn-save" = f.submit 'Save group', class: "btn btn-save"
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
.ui-box .ui-box
.title .title
%strong= @group.name %strong= @group.name
Projects: projects:
- if can? current_user, :manage_group, @group - if can? current_user, :manage_group, @group
%span.pull-right %span.pull-right
= link_to new_project_path(namespace_id: @group.id), class: "btn btn-tiny" do = link_to new_project_path(namespace_id: @group.id), class: "btn btn-tiny" do
...@@ -85,4 +85,4 @@ ...@@ -85,4 +85,4 @@
%p %p
%strong Removed group can not be restored! %strong Removed group can not be restored!
= link_to 'Remove Group', @group, confirm: 'Removed group can not be restored! Are you sure?', method: :delete, class: "btn btn-remove btn-small" = link_to 'Remove Group', @group, confirm: 'Removed group can not be restored! Are you sure?', method: :delete, class: "btn btn-remove"
...@@ -6,18 +6,6 @@ ...@@ -6,18 +6,6 @@
%hr %hr
.row .row
.span3 .span3
= render 'filter', entity: 'issue' = render 'shared/filter', entity: 'issue'
.span9 .span9
- if @issues.any? = render 'shared/issues'
- @issues.group_by(&:project).each do |group|
%div.ui-box
- project = group[0]
.title
= link_to_project project
%ul.well-list.issues-list
- group[1].each do |issue|
= render 'projects/issues/issue', issue: issue
%hr
= paginate @issues, theme: "gitlab"
- else
%p.nothing_here_message Nothing to show here
%h3.page-title
Group members
%p.light
Members of group have access to all group projects.
%hr
- can_manage_group = current_user.can? :manage_group, @group - can_manage_group = current_user.can? :manage_group, @group
.row .ui-box
.span6
- if can_manage_group
= render "new_group_member"
- else
.light-well
%h4.nothing_here_message
Only group owners can manage group members
.span6
.ui-box
.title .title
%strong #{@group.name} %strong #{@group.name}
Group Members group members
%small %small
(#{@members.count}) (#{@members.count})
%ul.well-list %ul.well-list
- @members.each do |member| - @members.each do |member|
= render 'users_groups/users_group', member: member, show_controls: can_manage_group = render 'users_groups/users_group', member: member, show_controls: can_manage_group
%p.light - if can_manage_group
Group members get access to all projects in this group = render "new_group_member"
...@@ -6,6 +6,6 @@ ...@@ -6,6 +6,6 @@
%hr %hr
.row .row
.span3 .span3
= render 'filter', entity: 'merge_request' = render 'shared/filter', entity: 'merge_request'
.span9 .span9
= render 'shared/merge_requests' = render 'shared/merge_requests'
...@@ -2,19 +2,19 @@ ...@@ -2,19 +2,19 @@
- if @group.errors.any? - if @group.errors.any?
.alert.alert-error .alert.alert-error
%span= @group.errors.full_messages.first %span= @group.errors.full_messages.first
.clearfix .control-group
= f.label :name do = f.label :name do
Group name is Group name is
.input .controls
= f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left" = f.text_field :name, placeholder: "Ex. OpenSource", class: "input-xxlarge left"
.clearfix.group-description-holder .control-group.group-description-holder
= f.label :description, "Details" = f.label :description, "Details"
.input .controls
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4 = f.text_area :description, maxlength: 250, class: "input-xxlarge js-gfm-input", rows: 4
.clearfix .control-group
.input .controls
%ul %ul
%li Group is kind of directory for several projects %li Group is kind of directory for several projects
%li All created groups are private %li All created groups are private
......
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
%br %br
Fast, secure and stable solution based on Ruby on Rails. Fast, secure and stable solution based on Ruby on Rails.
%br
.row .row
.span4 .span4
.ui-box .ui-box
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
- if Gitlab.config.gitlab.signup_enabled - if Gitlab.config.gitlab.signup_enabled
Your account has been created successfully. Your account has been created successfully.
- else - else
The Administrator created an account for you. Now you are a member of company GitLab application. The Administrator created an account for you. Now you are a member of the company GitLab application.
%p %p
login.......................................... login..........................................
%code= @user['email'] %code= @user['email']
......
Hi <%= @user.name %>! Hi <%= @user.name %>!
The Administrator created an account for you. Now you are a member of company GitLab application. The Administrator created an account for you. Now you are a member of the company GitLab application.
login.................. <%= @user.email %> login.................. <%= @user.email %>
<% if @user.created_by_id %> <% if @user.created_by_id %>
......
%h3.page-title
Account settings
%p.light
You can change password, username, private token here.
- if current_user.ldap_user?
Some options are unavailable for LDAP accounts
%hr
- unless current_user.ldap_user? - unless current_user.ldap_user?
- if Gitlab.config.omniauth.enabled - if Gitlab.config.omniauth.enabled
%fieldset %fieldset
...@@ -20,15 +27,15 @@ ...@@ -20,15 +27,15 @@
- @user.errors.full_messages.each do |msg| - @user.errors.full_messages.each do |msg|
%li= msg %li= msg
.clearfix .control-group
= f.label :password = f.label :password
.input= f.password_field :password, required: true .controls= f.password_field :password, required: true
.clearfix .control-group
= f.label :password_confirmation = f.label :password_confirmation
.input .controls
= f.password_field :password_confirmation, required: true = f.password_field :password_confirmation, required: true
.clearfix .control-group
.input .controls
= f.submit 'Save password', class: "btn btn-save" = f.submit 'Save password', class: "btn btn-save"
...@@ -47,7 +54,7 @@ ...@@ -47,7 +54,7 @@
It can be used for atom feed or API It can be used for atom feed or API
%p.cgray %p.cgray
- if current_user.private_token - if current_user.private_token
= text_field_tag "token", current_user.private_token, class: "xxlarge large_text" = text_field_tag "token", current_user.private_token, class: "input-xxlarge large_text input-xpadding"
= f.submit 'Reset', confirm: "Are you sure?", class: "btn btn-primary btn-build-token" = f.submit 'Reset', confirm: "Are you sure?", class: "btn btn-primary btn-build-token"
- else - else
%span You don`t have one yet. Click generate to fix it. %span You don`t have one yet. Click generate to fix it.
...@@ -63,7 +70,7 @@ ...@@ -63,7 +70,7 @@
= form_for @user, url: update_username_profile_path, method: :put, remote: true do |f| = form_for @user, url: update_username_profile_path, method: :put, remote: true do |f|
.padded .padded
= f.label :username = f.label :username
.input .controls
= f.text_field :username, required: true = f.text_field :username, required: true
&nbsp; &nbsp;
%span.loading-gif.hide= image_tag "ajax_loader.gif" %span.loading-gif.hide= image_tag "ajax_loader.gif"
...@@ -76,7 +83,7 @@ ...@@ -76,7 +83,7 @@
%ul.cred %ul.cred
%li It will change web url for personal projects. %li It will change web url for personal projects.
%li It will change the git path to repositories for personal projects. %li It will change the git path to repositories for personal projects.
.input .controls
= f.submit 'Save username', class: "btn btn-save" = f.submit 'Save username', class: "btn btn-save"
- if gitlab_config.signup_enabled - if gitlab_config.signup_enabled
......
%h3.page-title
My appearance settings
%p.light
Appearance settings saved to your profile and available across all devices
%hr
= form_for @user, url: profile_path, remote: true, method: :put do |f| = form_for @user, url: profile_path, remote: true, method: :put do |f|
%fieldset.application-theme %fieldset.application-theme
%legend %legend
......
.ui-box %h3.page-title
.title Group membership
%strong Groups
(#{@groups.count})
- if current_user.can_create_group? - if current_user.can_create_group?
%span.pull-right %span.pull-right
= link_to new_group_path, class: "btn btn-small btn-primary" do = link_to new_group_path, class: "btn btn-new" do
%i.icon-plus %i.icon-plus
New Group New Group
%p.light
Members of group have access to all group projects.
%hr
.ui-box
.title
%strong Groups
(#{@user_groups.count})
%ul.well-list %ul.well-list
- @groups.each do |group| - @user_groups.each do |user_group|
- group = user_group.group
%li %li
.pull-right .pull-right
- if can?(current_user, :manage_group, group) - if can?(current_user, :manage_group, group)
...@@ -23,4 +29,7 @@ ...@@ -23,4 +29,7 @@
= link_to group, class: 'group-name' do = link_to group, class: 'group-name' do
= group.name = group.name
= paginate @groups as #{user_group.human_access}
= paginate @user_groups
%h3.page-title
Account history
%p.light
You can see all events authored by your account here
%hr
.profile_history .profile_history
= render @events = render @events
%hr %hr
......
...@@ -6,18 +6,18 @@ ...@@ -6,18 +6,18 @@
- @key.errors.full_messages.each do |msg| - @key.errors.full_messages.each do |msg|
%li= msg %li= msg
.clearfix .control-group
= f.label :title = f.label :title
.input= f.text_field :title .controls= f.text_field :title, class: "input-xlarge"
.clearfix .control-group
= f.label :key = f.label :key
.input .controls
%p.light %p.light
Paste your public key here. Read more about how generate it #{link_to "here", help_ssh_path} Paste your public key here. Read more about how generate it #{link_to "here", help_ssh_path}
= f.text_area :key, class: [:xxlarge, :thin_area] = f.text_area :key, class: "input-xxlarge thin_area"
.actions .form-actions
= f.submit 'Add key', class: "btn btn-create" = f.submit 'Add key', class: "btn btn-create"
= link_to "Cancel", profile_keys_path, class: "btn btn-cancel" = link_to "Cancel", profile_keys_path, class: "btn btn-cancel"
%h3.page-title
My SSH keys
.pull-right
= link_to "Add SSH Key", new_profile_key_path, class: "btn btn-new"
%p.light %p.light
SSH key allows you to establish a secure connection between your computer and GitLab SSH key allows you to establish a secure connection between your computer and GitLab
%p.light %br
Before you can add ssh key you need to Before you can add ssh key you need to
= link_to "generate it", help_ssh_path = link_to "generate it", help_ssh_path
%hr
.ui-box .ui-box
.title .title
SSH Keys (#{@keys.count}) SSH Keys (#{@keys.count})
.pull-right
= link_to "Add SSH Key", new_profile_key_path, class: "btn btn-small btn-primary"
%ul.well-list#keys-table %ul.well-list#keys-table
= render @keys = render @keys
- if @keys.blank? - if @keys.blank?
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
.row .row
.span4 .span4
%span %span
= notification_icon(notification)
- if membership.kind_of? UsersGroup - if membership.kind_of? UsersGroup
= link_to membership.group.name, membership.group = link_to membership.group.name, membership.group
- else - else
......
%h3.page-title Setup your notification level %h3.page-title
Notifications settings
%p.light %p.light
Application use email specified in your profile for notifications
%hr
.alert.alert-info
%p
%i.icon-circle.cred
%strong Disabled %strong Disabled
&ndash; You will not get any notifications via email &ndash; You will not get any notifications via email
%p.light %p
%i.icon-circle.cblue
%strong Participating %strong Participating
&ndash; You will receive only notifications from related resources(ex. from assigned issue or your commit) &ndash; You will receive only notifications from related resources(ex. from assigned issue or your commit)
%p.light %p
%i.icon-circle.cgreen
%strong Watch %strong Watch
&ndash; You will receive all notifications from projects in which you participate &ndash; You will receive all notifications from projects in which you participate
%hr
.row .row
.span4 .span4
%h5 Global setting %h4
= notification_icon(@notification)
Global setting
.span7 .span7
= form_tag profile_notifications_path, method: :put, remote: true, class: 'update-notifications' do = form_tag profile_notifications_path, method: :put, remote: true, class: 'update-notifications' do
= hidden_field_tag :notification_type, 'global' = hidden_field_tag :notification_type, 'global'
...@@ -30,20 +38,21 @@ ...@@ -30,20 +38,21 @@
= radio_button_tag :notification_level, Notification::N_WATCH, @notification.watch?, class: 'trigger-submit' = radio_button_tag :notification_level, Notification::N_WATCH, @notification.watch?, class: 'trigger-submit'
%span Watch %span Watch
%hr %br
= link_to '#', class: 'js-toggle-visibility-link' do = link_to '#', class: 'js-toggle-visibility-link' do
%h6.btn.btn-tiny %span.btn.btn-tiny
%i.icon-chevron-down %i.icon-chevron-down
%span Advanced notifications settings %span Advanced notifications settings
.js-toggle-visibility-container.hide .js-toggle-visibility-container.hide
%h5 Groups: %hr
%ul.well-list %h4 Groups:
%ul.bordered-list
- @users_groups.each do |users_group| - @users_groups.each do |users_group|
- notification = Notification.new(users_group) - notification = Notification.new(users_group)
= render 'settings', type: 'group', membership: users_group, notification: notification = render 'settings', type: 'group', membership: users_group, notification: notification
%h5 Projects: %h4 Projects:
%ul.well-list %ul.bordered-list
- @users_projects.each do |users_project| - @users_projects.each do |users_project|
- notification = Notification.new(users_project) - notification = Notification.new(users_project)
= render 'settings', type: 'project', membership: users_project, notification: notification = render 'settings', type: 'project', membership: users_project, notification: notification
......
...@@ -10,13 +10,13 @@ ...@@ -10,13 +10,13 @@
- @user.errors.full_messages.each do |msg| - @user.errors.full_messages.each do |msg|
%li= msg %li= msg
.clearfix .control-group
= f.label :password = f.label :password
.input= f.password_field :password, required: true .controls= f.password_field :password, required: true
.clearfix .control-group
= f.label :password_confirmation = f.label :password_confirmation
.input .controls
= f.password_field :password_confirmation, required: true = f.password_field :password_confirmation, required: true
.clearfix .control-group
.input .controls
= f.submit 'Set new password', class: "btn btn-create" = f.submit 'Set new password', class: "btn btn-create"
...@@ -87,4 +87,4 @@ ...@@ -87,4 +87,4 @@
= link_to "Add Public Key", new_profile_key_path, class: "btn btn-small" = link_to "Add Public Key", new_profile_key_path, class: "btn btn-small"
.form-actions .form-actions
= f.submit 'Save', class: "btn btn-save" = f.submit 'Save changes', class: "btn btn-save"
%div.tree-ref-holder
= render 'shared/ref_switcher', destination: 'tree', path: params[:path]
= render "head" %h3.page-title Blame view
#tree-holder.tree-holder #tree-holder.tree-holder
%ul.breadcrumb
%li
%i.icon-angle-right
= link_to project_tree_path(@project, @ref) do
= @project.name
- tree_breadcrumbs(@tree, 6) do |link|
\/
%li= link
.clear
.file-holder .file-holder
.file-title .file-title
%i.icon-file %i.icon-file
%span.file_name %span.file_name
= @blob.name = @path
%small= number_to_human_size @blob.size %small= number_to_human_size @blob.size
%span.options= render "projects/blob/actions" %span.options= render "projects/blob/actions"
.file-content.blame .file-content.blame
......
.btn-group.tree-btn-group .btn-group.tree-btn-group
-# only show edit link for text files -# only show edit link for text files
- if @blob.text? - if @blob.text?
= link_to "edit", project_edit_tree_path(@project, @id), class: "btn btn-tiny", disabled: !allowed_tree_edit? = link_to "edit", project_edit_tree_path(@project, @id), class: "btn btn-small", disabled: !allowed_tree_edit?
= link_to "raw", project_raw_path(@project, @id), class: "btn btn-tiny", target: "_blank" = link_to "raw", project_raw_path(@project, @id), class: "btn btn-small", target: "_blank"
-# only show normal/blame view links for text files -# only show normal/blame view links for text files
- if @blob.text? - if @blob.text?
- if current_page? project_blame_path(@project, @id) - if current_page? project_blame_path(@project, @id)
= link_to "normal view", project_blob_path(@project, @id), class: "btn btn-tiny" = link_to "normal view", project_blob_path(@project, @id), class: "btn btn-small"
- else - else
= link_to "blame", project_blame_path(@project, @id), class: "btn btn-tiny" unless @blob.empty? = link_to "blame", project_blame_path(@project, @id), class: "btn btn-small" unless @blob.empty?
= link_to "history", project_commits_path(@project, @id), class: "btn btn-tiny" = link_to "history", project_commits_path(@project, @id), class: "btn btn-small"
%ul.nav.nav-pills.nav-stacked %ul.nav.nav-pills.nav-stacked
= nav_link(path: 'repositories#show') do = nav_link(path: 'branches#recent') do
= link_to 'Recent', project_repository_path(@project) = link_to 'Recent', recent_project_branches_path(@project)
= nav_link(path: 'protected_branches#index') do = nav_link(path: 'protected_branches#index') do
= link_to project_protected_branches_path(@project) do = link_to project_protected_branches_path(@project) do
Protected Protected
......
= render "projects/commits/head" = render "projects/commits/head"
.row .row
.span3 .span3
= render "projects/repositories/filter" = render "filter"
.span9 .span9
- unless @branches.empty? - unless @branches.empty?
%ul.bordered-list %ul.bordered-list
......
...@@ -4,6 +4,5 @@ ...@@ -4,6 +4,5 @@
= render "filter" = render "filter"
.span9 .span9
%ul.bordered-list %ul.bordered-list
- @activities.each do |update| - @branches.each do |branch|
= render "projects/branches/branch", branch: update.head = render "projects/branches/branch", branch: branch
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
= link_to 'Compare', project_compare_index_path(@project) = link_to 'Compare', project_compare_index_path(@project)
= nav_link(html_options: {class: branches_tab_class}) do = nav_link(html_options: {class: branches_tab_class}) do
= link_to project_repository_path(@project) do = link_to recent_project_branches_path(@project) do
Branches Branches
%span.badge= @repository.branches.length %span.badge= @repository.branches.length
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
%a.supp_diff_link Diff suppressed. Click to show %a.supp_diff_link Diff suppressed. Click to show
%table.text-file{class: "#{'hide' if too_big}"} %table.text-file{class: "#{'hide' if too_big}"}
- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old| - each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line|
%tr.line_holder{ id: line_code, class: "#{type}" } %tr.line_holder{ id: line_code, class: "#{type}" }
- if type == "match" - if type == "match"
%td.old_line= "..." %td.old_line= "..."
...@@ -20,4 +20,4 @@ ...@@ -20,4 +20,4 @@
- if @reply_allowed - if @reply_allowed
- comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at) - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at)
- unless comments.empty? - unless comments.empty?
= render "projects/notes/diff_notes_with_reply", notes: comments = render "projects/notes/diff_notes_with_reply", notes: comments, line: line
= render "head" = render "head"
- if @path.present? - if @path.present?
%ul.breadcrumb %ul.breadcrumb.commit-breadcrumb
%li.light %li.light
History for History for
= commits_breadcrumbs = commits_breadcrumbs
......
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
.pull-left .pull-left
- if params[:to] && params[:from] - if params[:to] && params[:from]
= link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has_tooltip', title: 'Switch base of comparison'} = link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has_tooltip', title: 'Switch base of comparison'}
= text_field_tag :from, params[:from], placeholder: "master", class: "xlarge" = text_field_tag :from, params[:from], placeholder: "master", class: "input-xlarge input-xpadding"
= "..." = "..."
= text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge" = text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "input-xlarge input-xpadding"
.pull-left .pull-left
&nbsp; &nbsp;
= submit_tag "Compare", class: "btn btn-create commits-compare-btn" = submit_tag "Compare", class: "btn btn-create commits-compare-btn"
......
...@@ -4,5 +4,6 @@ ...@@ -4,5 +4,6 @@
- else - else
:plain :plain
$(".project-edit-errors").html("#{escape_javascript(render('errors'))}"); $(".project-edit-errors").html("#{escape_javascript(render('errors'))}");
$('.project-submit').enable();
$('.save-project-loader').hide(); $('.save-project-loader').hide();
$('.project-edit-container').show(); $('.project-edit-container').show();
...@@ -6,18 +6,18 @@ ...@@ -6,18 +6,18 @@
- @key.errors.full_messages.each do |msg| - @key.errors.full_messages.each do |msg|
%li= msg %li= msg
.clearfix .control-group
= f.label :title = f.label :title
.input= f.text_field :title .controls= f.text_field :title, class: 'input-xlarge'
.clearfix .control-group
= f.label :key = f.label :key
.input .controls
= f.text_area :key, class: [:xxlarge, :thin_area] %p.light
%p.hint
Paste a machine public key here. Read more about how generate it Paste a machine public key here. Read more about how generate it
= link_to "here", help_ssh_path = link_to "here", help_ssh_path
= f.text_area :key, class: "input-xxlarge thin_area"
.actions .form-actions
= f.submit 'Create', class: "btn-create btn" = f.submit 'Create', class: "btn-create btn"
= link_to "Cancel", project_deploy_keys_path(@project), class: "btn btn-cancel" = link_to "Cancel", project_deploy_keys_path(@project), class: "btn btn-cancel"
%p.slead %h3.page-title
Deploy keys allow read-only access to repository. They can be used for CI, staging or production servers Deploy keys allow read-only access to repository
%p = link_to new_project_deploy_key_path(@project), class: "btn btn-new pull-right", title: "New Deploy Key" do
You can create a deploy key or add existing one
= link_to new_project_deploy_key_path(@project), class: "btn btn-primary pull-right", title: "New Deploy Key" do
%i.icon-plus %i.icon-plus
New Deploy Key New Deploy Key
%p.light
They can be used for CI, staging or production servers.
You can create a deploy key or add existing one
%hr.clearfix %hr.clearfix
.row .row
.span5.enabled-keys .span5.enabled-keys
%h5.cgreen %h5
Enabled deploy keys %strong.cgreen Enabled deploy keys
%small for this project for this project
%ul.bordered-list %ul.bordered-list
= render @enabled_keys = render @enabled_keys
- if @enabled_keys.blank? - if @enabled_keys.blank?
...@@ -21,10 +23,10 @@ ...@@ -21,10 +23,10 @@
%p.nothing_here_message Create #{link_to 'new deploy key', new_project_deploy_key_path(@project)} or add existing one %p.nothing_here_message Create #{link_to 'new deploy key', new_project_deploy_key_path(@project)} or add existing one
.span5.available-keys .span5.available-keys
%h5 %h5
Available deploy keys %strong Deploy keys
%small from projects you are able to manage from projects available for you
%ul.bordered-list %ul.bordered-list
= render @available_keys = render @available_keys
- if @available_keys.blank? - if @available_keys.blank?
.light-well .light-well
%p.nothing_here_message All deploy keys created in projects you own will be displayed here %p.nothing_here_message All deploy keys created in projects you participate will be displayed here
...@@ -4,28 +4,28 @@ ...@@ -4,28 +4,28 @@
.ui-box.white .ui-box.white
.title .title
%strong= @project.name %strong= @project.name
Project Settings: project settings:
.form-holder .form-holder
= form_for(@project, remote: true) do |f| = form_for(@project, remote: true) do |f|
%fieldset %fieldset
.clearfix.project_name_holder .control-group.project_name_holder
= f.label :name do = f.label :name do
Project name is Project name is
.input .controls
= f.text_field :name, placeholder: "Example Project", class: "span5" = f.text_field :name, placeholder: "Example Project", class: "span5"
.clearfix .control-group
= f.label :description do = f.label :description do
Project description Project description
%span.light (optional) %span.light (optional)
.input .controls
= f.text_area :description, placeholder: "awesome project", class: "span5", rows: 3, maxlength: 250 = f.text_area :description, placeholder: "awesome project", class: "span5", rows: 3, maxlength: 250
- unless @project.empty_repo? - if @project.repository.exists? && @project.repository.branch_names.any?
.clearfix .control-group
= f.label :default_branch, "Default Branch" = f.label :default_branch, "Default Branch"
.input= f.select(:default_branch, @repository.branch_names, {}, {class: 'chosen'}) .controls= f.select(:default_branch, @repository.branch_names, {}, {class: 'chosen'})
- if can?(current_user, :change_public_mode, @project) - if can?(current_user, :change_public_mode, @project)
...@@ -66,11 +66,11 @@ ...@@ -66,11 +66,11 @@
- if Project.issues_tracker.values.count > 1 - if Project.issues_tracker.values.count > 1
.control-group .control-group
= f.label :issues_tracker, "Issues tracker", class: 'control-label' = f.label :issues_tracker, "Issues tracker", class: 'control-label'
.input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) .controls= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled })
.clearfix .control-group
= f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label' = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label'
.input= f.text_field :issues_tracker_id, disabled: !@project.can_have_issues_tracker_id? .controls= f.text_field :issues_tracker_id, disabled: !@project.can_have_issues_tracker_id?
.control-group .control-group
= f.label :merge_requests_enabled, "Merge Requests", class: 'control-label' = f.label :merge_requests_enabled, "Merge Requests", class: 'control-label'
...@@ -98,7 +98,7 @@ ...@@ -98,7 +98,7 @@
.form-actions .form-actions
= f.submit 'Save', class: "btn btn-save" = f.submit 'Save changes', class: "btn btn-save"
- if can?(current_user, :change_namespace, @project) - if can?(current_user, :change_namespace, @project)
.ui-box.ui-box-danger .ui-box.ui-box-danger
...@@ -110,7 +110,7 @@ ...@@ -110,7 +110,7 @@
= f.label :namespace_id do = f.label :namespace_id do
%span Namespace %span Namespace
.controls .controls
.clearfix .control-group
= f.select :namespace_id, namespaces_options(@project.namespace_id), {prompt: 'Choose a project namespace'}, {class: 'chosen'} = f.select :namespace_id, namespaces_options(@project.namespace_id), {prompt: 'Choose a project namespace'}, {class: 'chosen'}
%ul %ul
%li Be careful. Changing project namespace can have unintended side effects %li Be careful. Changing project namespace can have unintended side effects
...@@ -130,7 +130,7 @@ ...@@ -130,7 +130,7 @@
= f.label :path do = f.label :path do
%span Path %span Path
.controls .controls
.clearfix .control-group
= f.text_field :path = f.text_field :path
%ul %ul
%li Be careful. Rename of project repo can have unintended side effects %li Be careful. Rename of project repo can have unintended side effects
......
%h3.page-title Edit mode
.file-editor .file-editor
= form_tag(project_edit_tree_path(@project, @id), method: :put, class: "form-horizontal") do = form_tag(project_edit_tree_path(@project, @id), method: :put, class: "form-horizontal") do
.file-holder .file-holder
......
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
.alert.alert-error .alert.alert-error
- @hook.errors.full_messages.each do |msg| - @hook.errors.full_messages.each do |msg|
%p= msg %p= msg
.clearfix .control-group
= f.label :url, "URL:" = f.label :url, "URL:"
.input .controls
= f.text_field :url, class: "text_field xxlarge" = f.text_field :url, class: "text_field input-xxlarge input-xpadding", placeholder: 'http://example.com/trigger-ci.json'
&nbsp; &nbsp;
= f.submit "Add Web Hook", class: "btn btn-create" = f.submit "Add Web Hook", class: "btn btn-create"
%hr %hr
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
All All
%fieldset %fieldset
%hr - if %w(status milestone_id assignee_id label_name).select { |k| params[k].present? }.any?
= link_to "Reset", project_issues_path(@project), class: 'btn pull-right' = link_to project_issues_path(@project), class: 'cgray pull-right' do
%i.icon-remove
Clear filter
...@@ -8,18 +8,18 @@ ...@@ -8,18 +8,18 @@
%br %br
.ui-box.ui-box-show .ui-box.ui-box-show
.ui-box-head .ui-box-head
.clearfix .control-group
= f.label :title do = f.label :title do
%strong= "Subject *" %strong= "Subject *"
.input .controls
= f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input", autofocus: true, required: true = f.text_field :title, maxlength: 255, class: "input-xxlarge js-gfm-input", autofocus: true, required: true
.ui-box-body .ui-box-body
.clearfix .control-group
.issue_assignee.pull-left .issue_assignee.pull-left
= f.label :assignee_id do = f.label :assignee_id do
%i.icon-user %i.icon-user
Assign to Assign to
.input .controls
.pull-left .pull-left
= f.select(:assignee_id, @project.team.members.sort_by(&:name).map {|p| [ p.name, p.id ] }, { include_blank: "Select a user" }, {class: 'chosen'}) = f.select(:assignee_id, @project.team.members.sort_by(&:name).map {|p| [ p.name, p.id ] }, { include_blank: "Select a user" }, {class: 'chosen'})
.pull-right .pull-right
...@@ -29,25 +29,25 @@ ...@@ -29,25 +29,25 @@
= f.label :milestone_id do = f.label :milestone_id do
%i.icon-time %i.icon-time
Milestone Milestone
.input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'}) .controls= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
.ui-box-bottom .ui-box-bottom
.clearfix .control-group
= f.label :label_list do = f.label :label_list do
%i.icon-tag %i.icon-tag
Labels Labels
.input .controls
= f.text_field :label_list, maxlength: 2000, class: "xxlarge" = f.text_field :label_list, maxlength: 2000, class: "input-xxlarge"
%p.hint Separate labels with commas. %p.hint Separate labels with commas.
.clearfix .control-group
= f.label :description, "Details" = f.label :description, "Details"
.input .controls
= f.text_area :description, class: "xxlarge js-gfm-input", rows: 14 = f.text_area :description, class: "input-xxlarge js-gfm-input", rows: 14
%p.hint Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. %p.hint Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
.actions .form-actions
- if @issue.new_record? - if @issue.new_record?
= f.submit 'Submit new issue', class: "btn btn-create" = f.submit 'Submit new issue', class: "btn btn-create"
-else -else
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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