Commit 9e9ce95d authored by Vinnie Okada's avatar Vinnie Okada

Merge branch 'master' into rails-4.1.9

Conflicts:
	app/views/dashboard/_project.html.haml
	app/views/events/event/_common.html.haml
	app/views/explore/projects/_project.html.haml
	app/views/groups/_projects.html.haml
	app/views/projects/_home_panel.html.haml
	app/views/projects/_issues_nav.html.haml
	app/views/projects/issues/_discussion.html.haml
	app/views/projects/issues/_issues.html.haml
	app/views/projects/issues/show.html.haml
	app/views/projects/merge_requests/_discussion.html.haml
	app/views/projects/merge_requests/_show.html.haml
	app/views/projects/milestones/index.html.haml
	app/views/projects/notes/_edit_form.html.haml
	app/views/shared/_issuable_filter.html.haml
parents 76aad9b7 de040ffa
v 7.9.0 (unreleased)
- Fix broken access control for note attachments (Hannes Rosenögger)
v 7.8.0 (unreleased) v 7.8.0 (unreleased)
- Replace highlight.js with rouge-fork rugments (Stefan Tatschner) - Replace highlight.js with rouge-fork rugments (Stefan Tatschner)
- Make project search case insensitive (Hannes Rosenögger) - Make project search case insensitive (Hannes Rosenögger)
...@@ -10,7 +13,7 @@ v 7.8.0 (unreleased) ...@@ -10,7 +13,7 @@ v 7.8.0 (unreleased)
- View note image attachments in new tab when clicked instead of downloading them - View note image attachments in new tab when clicked instead of downloading them
- Improve sorting logic in UI and API. Explicitly define what sorting method is used by default - Improve sorting logic in UI and API. Explicitly define what sorting method is used by default
- Allow more variations for commit messages closing issues (Julien Bianchi and Hannes Rosenögger) - Allow more variations for commit messages closing issues (Julien Bianchi and Hannes Rosenögger)
- Fix overflow at sidebar when have several itens - Fix overflow at sidebar when have several items
- 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)
...@@ -54,6 +57,13 @@ v 7.8.0 (unreleased) ...@@ -54,6 +57,13 @@ v 7.8.0 (unreleased)
- Link head panel titles to relevant root page. - Link head panel titles to relevant root page.
- Allow users that signed up via OAuth to set their password in order to use Git over HTTP(S). - Allow users that signed up via OAuth to set their password in order to use Git over HTTP(S).
- Upgrade Rails gem to version 4.1.9. - Upgrade Rails gem to version 4.1.9.
- Show users button to share their newly created public or internal projects on twitter
- Add quick help links to the GitLab pricing and feature comparison pages.
- Fix duplicate authorized applications in user profile and incorrect application client count in admin area.
- Make sure Markdown previews always use the same styling as the eventual destination.
- Remove deprecated Group#owner_id from API
- Show projects user contributed to on user page. Show stars near project on user page.
- Improve database performance for GitLab
v 7.7.2 v 7.7.2
- Update GitLab Shell to version 2.4.2 that fixes a bug when developers can push to protected branch - Update GitLab Shell to version 2.4.2 that fixes a bug when developers can push to protected branch
......
...@@ -47,6 +47,9 @@ GEM ...@@ -47,6 +47,9 @@ GEM
astrolabe (1.3.0) astrolabe (1.3.0)
parser (>= 2.2.0.pre.3, < 3.0) parser (>= 2.2.0.pre.3, < 3.0)
attr_required (1.0.0) attr_required (1.0.0)
autoprefixer-rails (5.1.6)
execjs
json
awesome_print (1.2.0) awesome_print (1.2.0)
axiom-types (0.0.5) axiom-types (0.0.5)
descendants_tracker (~> 0.0.1) descendants_tracker (~> 0.0.1)
...@@ -57,8 +60,9 @@ GEM ...@@ -57,8 +60,9 @@ GEM
erubis (>= 2.6.6) erubis (>= 2.6.6)
binding_of_caller (0.7.2) binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1) debug_inspector (>= 0.0.1)
bootstrap-sass (3.0.3.0) bootstrap-sass (3.3.3)
sass (~> 3.2) autoprefixer-rails (>= 5.0.0.1)
sass (>= 3.2.19)
browser (0.7.2) browser (0.7.2)
builder (3.2.2) builder (3.2.2)
cal-heatmap-rails (0.0.1) cal-heatmap-rails (0.0.1)
......
...@@ -71,7 +71,7 @@ Thanks for the issue report. Please reformat your issue to conform to the issue ...@@ -71,7 +71,7 @@ Thanks for the issue report. Please reformat your issue to conform to the issue
### Feature requests ### Feature requests
Thank you for your interest in improving GitLab. We don't use the issue tracker for feature requests. Things that are wrong but are not a regression compared to older versions of GitLab are considered feature requests and not issues. Please use the [feature request forum](http://feedback.gitlab.com/) for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. Thank you for your interest in improving GitLab. We don't use the issue tracker for feature requests. Things that are wrong but are not a regression compared to older versions of GitLab are considered feature requests and not issues. Please use the \[feature request forum\]\(http://feedback.gitlab.com/) for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information.
### Issue report for old version ### Issue report for old version
......
...@@ -60,7 +60,7 @@ Please see the [requirements documentation](doc/install/requirements.md) for sys ...@@ -60,7 +60,7 @@ Please see the [requirements documentation](doc/install/requirements.md) for sys
## Installation ## Installation
The recommended way to install GitLab is using the provided [Omnibus packages](https://about.gitlab.com/downloads/). Compared to a manual installation, this is faster and less error prone. Just select your operating system, download the respective package (Debian or RPM) and install it using the system's package manager. The recommended way to install GitLab is using the provided [Omnibus packages](https://about.gitlab.com/downloads/). Compared to an installation from source, this is faster and less error prone. Just select your operating system, download the respective package (Debian or RPM) and install it using the system's package manager.
There are various other options to install GitLab, please refer to the [installation page on the GitLab website](https://about.gitlab.com/installation/) for more information. There are various other options to install GitLab, please refer to the [installation page on the GitLab website](https://about.gitlab.com/installation/) for more information.
...@@ -76,7 +76,7 @@ Since 2011 a minor or major version of GitLab is released on the 22nd of every m ...@@ -76,7 +76,7 @@ Since 2011 a minor or major version of GitLab is released on the 22nd of every m
## Upgrading ## Upgrading
For updating the Omnibus installation please see the [update documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/update.md). For manual installations there is an [upgrader script](doc/update/upgrader.md) and there are [upgrade guides](doc/update) detailing all necessary commands to migrate to the next version. For updating the Omnibus installation please see the [update documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/update.md). For installations from source there is an [upgrader script](doc/update/upgrader.md) and there are [upgrade guides](doc/update) detailing all necessary commands to migrate to the next version.
## Install a development environment ## Install a development environment
......
7.8.0.pre 7.9.0.pre
...@@ -15,3 +15,9 @@ class @Issue ...@@ -15,3 +15,9 @@ class @Issue
"issue" "issue"
updateTaskState updateTaskState
) )
$('.issuable-affix').affix offset:
top: ->
@top = $('.issue-details').outerHeight(true) + 25
bottom: ->
@bottom = $('.footer').outerHeight(true)
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
$(this).html totalIssues + 1 $(this).html totalIssues + 1
else else
$(this).html totalIssues - 1 $(this).html totalIssues - 1
$("body").on "click", ".issues-filters .dropdown-menu a", -> $("body").on "click", ".issues-other-filters .dropdown-menu a", ->
$('.issues-list').block( $('.issues-list').block(
message: null, message: null,
overlayCSS: overlayCSS:
...@@ -77,9 +77,9 @@ ...@@ -77,9 +77,9 @@
ids.push $(value).attr("data-id") ids.push $(value).attr("data-id")
$("#update_issues_ids").val ids $("#update_issues_ids").val ids
$(".issues-filters").hide() $(".issues-other-filters").hide()
$(".issues_bulk_update").show() $(".issues_bulk_update").show()
else else
$("#update_issues_ids").val [] $("#update_issues_ids").val []
$(".issues_bulk_update").hide() $(".issues_bulk_update").hide()
$(".issues-filters").show() $(".issues-other-filters").show()
...@@ -20,6 +20,12 @@ class @MergeRequest ...@@ -20,6 +20,12 @@ class @MergeRequest
if $("a.btn-close").length if $("a.btn-close").length
$("li.task-list-item input:checkbox").prop("disabled", false) $("li.task-list-item input:checkbox").prop("disabled", false)
$('.issuable-affix').affix offset:
top: ->
@top = $('.merge-request-details').outerHeight(true) + 70
bottom: ->
@bottom = $('.footer').outerHeight(true)
# Local jQuery finder # Local jQuery finder
$: (selector) -> $: (selector) ->
this.$el.find(selector) this.$el.find(selector)
......
...@@ -77,7 +77,7 @@ class @Notes ...@@ -77,7 +77,7 @@ class @Notes
$(document).off "click", ".js-discussion-reply-button" $(document).off "click", ".js-discussion-reply-button"
$(document).off "click", ".js-add-diff-note-button" $(document).off "click", ".js-add-diff-note-button"
$(document).off "visibilitychange" $(document).off "visibilitychange"
$(document).off "keypress", @notes_forms $(document).off "keydown", @notes_forms
$(document).off "keyup", ".js-note-text" $(document).off "keyup", ".js-note-text"
$(document).off "click", ".js-note-target-reopen" $(document).off "click", ".js-note-target-reopen"
$(document).off "click", ".js-note-target-close" $(document).off "click", ".js-note-target-close"
...@@ -272,7 +272,7 @@ class @Notes ...@@ -272,7 +272,7 @@ class @Notes
note_li = $(".note-row-" + note.id) note_li = $(".note-row-" + note.id)
note_li.replaceWith(note.html) note_li.replaceWith(note.html)
note_li.find('.note-edit-form').hide() note_li.find('.note-edit-form').hide()
note_li.find('.note-text').show() note_li.find('.note-body > .note-text').show()
### ###
Called in response to clicking the edit note link Called in response to clicking the edit note link
...@@ -284,7 +284,7 @@ class @Notes ...@@ -284,7 +284,7 @@ class @Notes
showEditForm: (e) -> showEditForm: (e) ->
e.preventDefault() e.preventDefault()
note = $(this).closest(".note") note = $(this).closest(".note")
note.find(".note-text").hide() note.find(".note-body > .note-text").hide()
note.find(".note-header").hide() note.find(".note-header").hide()
base_form = note.find(".note-edit-form") base_form = note.find(".note-edit-form")
form = base_form.clone().insertAfter(base_form) form = base_form.clone().insertAfter(base_form)
...@@ -311,7 +311,7 @@ class @Notes ...@@ -311,7 +311,7 @@ class @Notes
cancelEdit: (e) -> cancelEdit: (e) ->
e.preventDefault() e.preventDefault()
note = $(this).closest(".note") note = $(this).closest(".note")
note.find(".note-text").show() note.find(".note-body > .note-text").show()
note.find(".note-header").show() note.find(".note-header").show()
note.find(".current-note-edit-form").remove() note.find(".current-note-edit-form").remove()
...@@ -345,7 +345,7 @@ class @Notes ...@@ -345,7 +345,7 @@ class @Notes
removeAttachment: -> removeAttachment: ->
note = $(this).closest(".note") note = $(this).closest(".note")
note.find(".note-attachment").remove() note.find(".note-attachment").remove()
note.find(".note-text").show() note.find(".note-body > .note-text").show()
note.find(".js-note-attachment-delete").hide() note.find(".js-note-attachment-delete").hide()
note.find(".note-edit-form").hide() note.find(".note-edit-form").hide()
......
...@@ -17,6 +17,10 @@ h3.page-title { ...@@ -17,6 +17,10 @@ h3.page-title {
font-size: 22px; font-size: 22px;
} }
h4.page-title {
margin-top: 0px;
}
h6 { h6 {
color: #888; color: #888;
text-transform: uppercase; text-transform: uppercase;
...@@ -131,4 +135,4 @@ textarea.js-gfm-input { ...@@ -131,4 +135,4 @@ textarea.js-gfm-input {
.strikethrough { .strikethrough {
text-decoration: line-through; text-decoration: line-through;
} }
\ No newline at end of file
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
border-left: 1px solid #666; border-left: 1px solid #666;
} }
// highlight line via anchor
pre.hll { pre.hll {
background-color: #fff !important; background-color: #fff !important;
} }
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
border-left: 1px solid #555; border-left: 1px solid #555;
} }
// highlight line via anchor
pre.hll {
background-color: #49483e !important;
}
.hll { background-color: #49483e } .hll { background-color: #49483e }
.c { color: #75715e } /* Comment */ .c { color: #75715e } /* Comment */
.err { color: #960050; background-color: #1e0010 } /* Error */ .err { color: #960050; background-color: #1e0010 } /* Error */
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
border-left: 1px solid #113b46; border-left: 1px solid #113b46;
} }
// highlight line via anchor
pre.hll {
background-color: #073642 !important;
}
/* Solarized Dark /* Solarized Dark
For use with Jekyll and Pygments For use with Jekyll and Pygments
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
border-left: 1px solid #c5d0d4; border-left: 1px solid #c5d0d4;
} }
// highlight line via anchor
pre.hll {
background-color: #eee8d5 !important;
}
/* Solarized Light /* Solarized Light
For use with Jekyll and Pygments For use with Jekyll and Pygments
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
border-left: 1px solid #bbb; border-left: 1px solid #bbb;
} }
// highlight line via anchor
pre.hll {
background-color: #f8eec7 !important;
}
.hll { background-color: #f8f8f8 } .hll { background-color: #f8f8f8 }
.c { color: #999988; font-style: italic; } .c { color: #999988; font-style: italic; }
.err { color: #a61717; background-color: #e3d2d2; } .err { color: #a61717; background-color: #e3d2d2; }
......
...@@ -120,6 +120,15 @@ ...@@ -120,6 +120,15 @@
} }
} }
.dash-new-group {
background: $bg_success;
border: 1px solid $border_success;
a {
color: #FFF;
}
}
.dash-list .str-truncated { .dash-list .str-truncated {
max-width: 72%; max-width: 72%;
} }
...@@ -64,6 +64,10 @@ ...@@ -64,6 +64,10 @@
.md { .md {
font-size: 13px; font-size: 13px;
iframe.twitter-share-button {
vertical-align: bottom;
}
} }
pre { pre {
......
@media (max-width: $screen-sm-max) {
.issuable-affix {
margin-top: 20px;
}
}
@media (max-width: $screen-md-max) {
.issuable-affix {
position: static;
}
}
@media (min-width: $screen-md-max) {
.issuable-affix {
&.affix-top {
position: static;
}
&.affix {
position: fixed;
top: 70px;
width: 220px;
}
}
}
...@@ -94,8 +94,15 @@ ...@@ -94,8 +94,15 @@
} }
} }
.issue-show-labels .color-label { .issue-show-labels {
padding: 6px 10px; a {
margin-right: 5px;
margin-bottom: 5px;
display: inline-block;
.color-label {
padding: 6px 10px;
}
}
} }
form.edit-issue { form.edit-issue {
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
.accept-control { .accept-control {
display: inline-block; display: inline-block;
margin: 0;
margin-left: 20px; margin-left: 20px;
padding: 10px 0; padding: 10px 0;
line-height: 20px; line-height: 20px;
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
.remove_source_checkbox { .remove_source_checkbox {
margin: 0; margin: 0;
font-weight: bold;
} }
} }
} }
...@@ -185,6 +187,13 @@ ...@@ -185,6 +187,13 @@
} }
} }
.merge-request-show-labels .label { .merge-request-show-labels {
padding: 6px 10px; a {
margin-right: 5px;
margin-bottom: 5px;
display: inline-block;
.color-label {
padding: 6px 10px;
}
}
} }
...@@ -40,12 +40,16 @@ ...@@ -40,12 +40,16 @@
.nav-sidebar li { .nav-sidebar li {
&.active a { &.active a {
color: #111; color: #333;
background: #EEE; background: #FFF;
font-weight: bold; font-weight: bold;
border: 1px solid #EEE;
border-right: 1px solid transparent;
border-left: 3px solid $style_color;
&.no-highlight { &.no-highlight {
background: none; background: none;
border: none;
} }
i { i {
...@@ -65,7 +69,7 @@ ...@@ -65,7 +69,7 @@
color: #555; color: #555;
display: block; display: block;
text-decoration: none; text-decoration: none;
padding: 6px 15px; padding: 8px 15px;
font-size: 13px; font-size: 13px;
line-height: 20px; line-height: 20px;
text-shadow: 0 1px 2px #FFF; text-shadow: 0 1px 2px #FFF;
...@@ -133,7 +137,7 @@ ...@@ -133,7 +137,7 @@
li a { li a {
padding-left: 18px; padding-left: 18px;
font-size: 14px; font-size: 14px;
padding: 10px 15px; padding: 8px 15px;
text-align: center; text-align: center;
& > span { & > span {
......
...@@ -26,6 +26,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -26,6 +26,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:signup_enabled, :signup_enabled,
:signin_enabled, :signin_enabled,
:gravatar_enabled, :gravatar_enabled,
:twitter_sharing_enabled,
:sign_in_text, :sign_in_text,
:home_page_url :home_page_url
) )
......
...@@ -12,11 +12,7 @@ class DashboardController < ApplicationController ...@@ -12,11 +12,7 @@ class DashboardController < ApplicationController
@groups = current_user.authorized_groups.order_name_asc @groups = current_user.authorized_groups.order_name_asc
@has_authorized_projects = @projects.count > 0 @has_authorized_projects = @projects.count > 0
@projects_count = @projects.count @projects_count = @projects.count
@projects = @projects.limit(@projects_limit) @projects = @projects.includes(:namespace).limit(@projects_limit)
@events = Event.in_projects(current_user.authorized_projects.pluck(:id))
@events = @event_filter.apply_filter(@events)
@events = @events.limit(20).offset(params[:offset] || 0)
@last_push = current_user.recent_push @last_push = current_user.recent_push
...@@ -24,8 +20,16 @@ class DashboardController < ApplicationController ...@@ -24,8 +20,16 @@ class DashboardController < ApplicationController
respond_to do |format| respond_to do |format|
format.html format.html
format.json { pager_json("events/_events", @events.count) }
format.atom { render layout: false } format.json do
load_events
pager_json("events/_events", @events.count)
end
format.atom do
load_events
render layout: false
end
end end
end end
...@@ -74,4 +78,10 @@ class DashboardController < ApplicationController ...@@ -74,4 +78,10 @@ class DashboardController < ApplicationController
def load_projects def load_projects
@projects = current_user.authorized_projects.sorted_by_activity.non_archived @projects = current_user.authorized_projects.sorted_by_activity.non_archived
end end
def load_events
@events = Event.in_projects(current_user.authorized_projects.pluck(:id))
@events = @event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0)
end
end end
...@@ -18,7 +18,7 @@ class Explore::ProjectsController < ApplicationController ...@@ -18,7 +18,7 @@ class Explore::ProjectsController < ApplicationController
def starred def starred
@starred_projects = ProjectsFinder.new.execute(current_user) @starred_projects = ProjectsFinder.new.execute(current_user)
@starred_projects = @starred_projects.order('star_count DESC') @starred_projects = @starred_projects.reorder('star_count DESC')
@starred_projects = @starred_projects.page(params[:page]).per(10) @starred_projects = @starred_projects.page(params[:page]).per(10)
end end
end end
...@@ -10,11 +10,11 @@ class GroupsController < ApplicationController ...@@ -10,11 +10,11 @@ class GroupsController < ApplicationController
# Load group projects # Load group projects
before_filter :load_projects, except: [:new, :create, :projects, :edit, :update] before_filter :load_projects, except: [:new, :create, :projects, :edit, :update]
before_filter :event_filter, only: :show
before_filter :set_title, only: [:new, :create]
layout :determine_layout layout :determine_layout
before_filter :set_title, only: [:new, :create]
def new def new
@group = Group.new @group = Group.new
end end
...@@ -32,15 +32,21 @@ class GroupsController < ApplicationController ...@@ -32,15 +32,21 @@ class GroupsController < ApplicationController
end end
def show def show
@events = Event.in_projects(project_ids)
@events = event_filter.apply_filter(@events)
@events = @events.limit(20).offset(params[:offset] || 0)
@last_push = current_user.recent_push if current_user @last_push = current_user.recent_push if current_user
@projects = @projects.includes(:namespace)
respond_to do |format| respond_to do |format|
format.html format.html
format.json { pager_json("events/_events", @events.count) }
format.atom { render layout: false } format.json do
load_events
pager_json("events/_events", @events.count)
end
format.atom do
load_events
render layout: false
end
end end
end end
...@@ -149,4 +155,10 @@ class GroupsController < ApplicationController ...@@ -149,4 +155,10 @@ class GroupsController < ApplicationController
def group_params def group_params
params.require(:group).permit(:name, :description, :path, :avatar) params.require(:group).permit(:name, :description, :path, :avatar)
end end
def load_events
@events = Event.in_projects(project_ids)
@events = event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0)
end
end end
...@@ -16,6 +16,7 @@ class ProfilesController < ApplicationController ...@@ -16,6 +16,7 @@ class ProfilesController < ApplicationController
def applications def applications
@applications = current_user.oauth_applications @applications = current_user.oauth_applications
@authorized_tokens = current_user.oauth_authorized_tokens @authorized_tokens = current_user.oauth_authorized_tokens
@authorized_apps = @authorized_tokens.map(&:application).uniq
end end
def update def update
......
...@@ -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)
Event.create_ref_event(@project, current_user, tag, 'rm', 'refs/tags') EventCreateService.new.push_ref(@project, current_user, tag, 'rm', 'refs/tags')
end end
respond_to do |format| respond_to do |format|
......
...@@ -5,9 +5,10 @@ class ProjectsController < ApplicationController ...@@ -5,9 +5,10 @@ class ProjectsController < ApplicationController
# Authorize # Authorize
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive] before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive]
before_filter :set_title, only: [:new, :create]
before_filter :event_filter, only: :show
layout 'navless', only: [:new, :create, :fork] layout 'navless', only: [:new, :create, :fork]
before_filter :set_title, only: [:new, :create]
def new def new
@project = Project.new @project = Project.new
...@@ -65,9 +66,6 @@ class ProjectsController < ApplicationController ...@@ -65,9 +66,6 @@ class ProjectsController < ApplicationController
end end
limit = (params[:limit] || 20).to_i limit = (params[:limit] || 20).to_i
@events = @project.events.recent
@events = event_filter.apply_filter(@events)
@events = @events.limit(limit).offset(params[:offset] || 0)
@show_star = !(current_user && current_user.starred?(@project)) @show_star = !(current_user && current_user.starred?(@project))
...@@ -85,7 +83,12 @@ class ProjectsController < ApplicationController ...@@ -85,7 +83,12 @@ class ProjectsController < ApplicationController
end end
end end
format.json { pager_json('events/_events', @events.count) } format.json do
@events = @project.events.recent
@events = event_filter.apply_filter(@events).with_associations
@events = @events.limit(limit).offset(params[:offset] || 0)
pager_json('events/_events', @events.count)
end
end end
end end
......
...@@ -4,19 +4,20 @@ class UsersController < ApplicationController ...@@ -4,19 +4,20 @@ class UsersController < ApplicationController
layout :determine_layout layout :determine_layout
def show def show
# Projects user can view @contributed_projects = Project.
visible_projects = ProjectsFinder.new.execute(current_user) where(id: authorized_projects_ids & @user.contributed_projects_ids).
authorized_projects_ids = visible_projects.pluck(:id) in_group_namespace.includes(:namespace)
@projects = @user.personal_projects. @projects = @user.personal_projects.
where(id: authorized_projects_ids) where(id: authorized_projects_ids).includes(:namespace)
# Collect only groups common for both users # Collect only groups common for both users
@groups = @user.groups & GroupsFinder.new.execute(current_user) @groups = @user.groups & GroupsFinder.new.execute(current_user)
# Get user activity feed for projects common for both users # Get user activity feed for projects common for both users
@events = @user.recent_events. @events = @user.recent_events.
where(project_id: authorized_projects_ids).limit(30) where(project_id: authorized_projects_ids).
with_associations.limit(30)
@title = @user.name @title = @user.name
@title_url = user_path(@user) @title_url = user_path(@user)
...@@ -28,8 +29,8 @@ class UsersController < ApplicationController ...@@ -28,8 +29,8 @@ class UsersController < ApplicationController
end end
def calendar def calendar
visible_projects = ProjectsFinder.new.execute(current_user) projects = Project.where(id: authorized_projects_ids & @user.contributed_projects_ids)
calendar = Gitlab::CommitsCalendar.new(visible_projects, @user) calendar = Gitlab::CommitsCalendar.new(projects, @user)
@timestamps = calendar.timestamps @timestamps = calendar.timestamps
@starting_year = calendar.starting_year @starting_year = calendar.starting_year
@starting_month = calendar.starting_month @starting_month = calendar.starting_month
...@@ -54,4 +55,10 @@ class UsersController < ApplicationController ...@@ -54,4 +55,10 @@ class UsersController < ApplicationController
return authenticate_user! return authenticate_user!
end end
end end
def authorized_projects_ids
# Projects user can view
@authorized_projects_ids ||=
ProjectsFinder.new.execute(current_user).pluck(:id)
end
end end
...@@ -8,7 +8,7 @@ class TrendingProjectsFinder ...@@ -8,7 +8,7 @@ class TrendingProjectsFinder
# for period of time - ex. month # for period of time - ex. month
projects.joins(:notes).where('notes.created_at > ?', start_date). projects.joins(:notes).where('notes.created_at > ?', start_date).
select("projects.*, count(notes.id) as ncount"). select("projects.*, count(notes.id) as ncount").
group("projects.id").order("ncount DESC") group("projects.id").reorder("ncount DESC")
end end
private private
......
...@@ -51,7 +51,13 @@ module ApplicationHelper ...@@ -51,7 +51,13 @@ module ApplicationHelper
end end
def project_icon(project_id, options = {}) def project_icon(project_id, options = {})
project = Project.find_with_namespace(project_id) project =
if project_id.is_a?(Project)
project = project_id
else
Project.find_with_namespace(project_id)
end
if project.avatar.present? if project.avatar.present?
image_tag project.avatar.url, options image_tag project.avatar.url, options
elsif project.avatar_in_git elsif project.avatar_in_git
......
...@@ -3,6 +3,10 @@ module ApplicationSettingsHelper ...@@ -3,6 +3,10 @@ module ApplicationSettingsHelper
current_application_settings.gravatar_enabled? current_application_settings.gravatar_enabled?
end end
def twitter_sharing_enabled?
current_application_settings.twitter_sharing_enabled?
end
def signup_enabled? def signup_enabled?
current_application_settings.signup_enabled? current_application_settings.signup_enabled?
end end
......
...@@ -17,7 +17,7 @@ module BlobHelper ...@@ -17,7 +17,7 @@ module BlobHelper
end end
def no_highlight_files def no_highlight_files
%w(credits changelog copying copyright license authors) %w(credits changelog news copying copyright license authors)
end end
def edit_blob_link(project, ref, path, options = {}) def edit_blob_link(project, ref, path, options = {})
......
...@@ -10,11 +10,15 @@ module EventsHelper ...@@ -10,11 +10,15 @@ module EventsHelper
end end
def event_action_name(event) def event_action_name(event)
target = if event.target_type target = if event.target_type
event.target_type.titleize.downcase if event.note?
else event.note_target_type
'project' else
end event.target_type.titleize.downcase
end
else
'project'
end
[event.action_name, target].join(" ") [event.action_name, target].join(" ")
end end
...@@ -42,21 +46,30 @@ module EventsHelper ...@@ -42,21 +46,30 @@ module EventsHelper
end end
def event_feed_title(event) def event_feed_title(event)
if event.issue? words = []
"#{event.author_name} #{event.action_name} issue ##{event.target_iid}: #{event.issue_title} at #{event.project_name}" words << event.author_name
elsif event.merge_request? words << event_action_name(event)
"#{event.author_name} #{event.action_name} MR ##{event.target_iid}: #{event.merge_request_title} at #{event.project_name}"
elsif event.push? if event.push?
"#{event.author_name} #{event.push_action_name} #{event.ref_type} #{event.ref_name} at #{event.project_name}" words << event.ref_type
elsif event.membership_changed? words << event.ref_name
"#{event.author_name} #{event.action_name} #{event.project_name}" words << "at"
elsif event.note? && event.note_commit? elsif event.commented?
"#{event.author_name} commented on #{event.note_target_type} #{event.note_short_commit_id} at #{event.project_name}" if event.note_commit?
elsif event.note? words << event.note_short_commit_id
"#{event.author_name} commented on #{event.note_target_type} ##{truncate event.note_target_iid} at #{event.project_name}" else
else words << "##{truncate event.note_target_iid}"
"" end
words << "at"
elsif event.target
words << "##{event.target_iid}:"
words << event.target.title if event.target.respond_to?(:title)
words << "at"
end end
words << event.project_name
words.join(" ")
end end
def event_feed_url(event) def event_feed_url(event)
...@@ -106,8 +119,6 @@ module EventsHelper ...@@ -106,8 +119,6 @@ module EventsHelper
render "events/event_push", event: event render "events/event_push", event: event
elsif event.merge_request? elsif event.merge_request?
render "events/event_merge_request", merge_request: event.merge_request render "events/event_merge_request", merge_request: event.merge_request
elsif event.push?
render "events/event_push", event: event
elsif event.note? elsif event.note?
render "events/event_note", note: event.note render "events/event_note", note: event.note
end end
......
...@@ -110,7 +110,7 @@ module GitlabMarkdownHelper ...@@ -110,7 +110,7 @@ module GitlabMarkdownHelper
end end
def link_to_ignore?(link) def link_to_ignore?(link)
if link =~ /\#\w+/ if link =~ /\A\#\w+/
# ignore anchors like <a href="#my-header"> # ignore anchors like <a href="#my-header">
true true
else else
...@@ -122,10 +122,11 @@ module GitlabMarkdownHelper ...@@ -122,10 +122,11 @@ module GitlabMarkdownHelper
["http://","https://", "ftp://", "mailto:"] ["http://","https://", "ftp://", "mailto:"]
end end
def rebuild_path(path) def rebuild_path(file_path)
path.gsub!(/(#.*)/, "") file_path = file_path.dup
file_path.gsub!(/(#.*)/, "")
id = $1 || "" id = $1 || ""
file_path = relative_file_path(path) file_path = relative_file_path(file_path)
file_path = sanitize_slashes(file_path) file_path = sanitize_slashes(file_path)
[ [
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
# signup_enabled :boolean # signup_enabled :boolean
# signin_enabled :boolean # signin_enabled :boolean
# gravatar_enabled :boolean # gravatar_enabled :boolean
# twitter_sharing_enabled :boolean
# sign_in_text :text # sign_in_text :text
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
...@@ -30,6 +31,7 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -30,6 +31,7 @@ class ApplicationSetting < ActiveRecord::Base
default_branch_protection: Settings.gitlab['default_branch_protection'], default_branch_protection: Settings.gitlab['default_branch_protection'],
signup_enabled: Settings.gitlab['signup_enabled'], signup_enabled: Settings.gitlab['signup_enabled'],
signin_enabled: Settings.gitlab['signin_enabled'], signin_enabled: Settings.gitlab['signin_enabled'],
twitter_sharing_enabled: Settings.gitlab['twitter_sharing_enabled'],
gravatar_enabled: Settings.gravatar['enabled'], gravatar_enabled: Settings.gravatar['enabled'],
sign_in_text: Settings.extra['sign_in_text'], sign_in_text: Settings.extra['sign_in_text'],
) )
......
...@@ -47,31 +47,9 @@ class Event < ActiveRecord::Base ...@@ -47,31 +47,9 @@ class Event < ActiveRecord::Base
scope :recent, -> { order("created_at DESC") } scope :recent, -> { order("created_at DESC") }
scope :code_push, -> { where(action: PUSHED) } scope :code_push, -> { where(action: PUSHED) }
scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent } scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent }
scope :with_associations, -> { includes(project: :namespace) }
class << self class << self
def create_ref_event(project, user, ref, action = 'add', prefix = 'refs/heads')
commit = project.repository.commit(ref.target)
if action.to_s == 'add'
before = '00000000'
after = commit.id
else
before = commit.id
after = '00000000'
end
Event.create(
project: project,
action: Event::PUSHED,
data: {
ref: "#{prefix}/#{ref.name}",
before: before,
after: after
},
author_id: user.id
)
end
def reset_event_cache_for(target) def reset_event_cache_for(target)
Event.where(target_id: target.id, target_type: target.class.to_s). Event.where(target_id: target.id, target_type: target.class.to_s).
order('id DESC').limit(100). order('id DESC').limit(100).
...@@ -84,6 +62,8 @@ class Event < ActiveRecord::Base ...@@ -84,6 +62,8 @@ class Event < ActiveRecord::Base
true true
elsif membership_changed? elsif membership_changed?
true true
elsif created_project?
true
else else
(issue? || merge_request? || note? || milestone?) && target (issue? || merge_request? || note? || milestone?) && target
end end
...@@ -98,25 +78,51 @@ class Event < ActiveRecord::Base ...@@ -98,25 +78,51 @@ class Event < ActiveRecord::Base
end end
def target_title def target_title
if target && target.respond_to?(:title) target.title if target && target.respond_to?(:title)
target.title end
end
def created?
action == CREATED
end end
def push? def push?
action == self.class::PUSHED && valid_push? action == PUSHED && valid_push?
end end
def merged? def merged?
action == self.class::MERGED action == MERGED
end end
def closed? def closed?
action == self.class::CLOSED action == CLOSED
end end
def reopened? def reopened?
action == self.class::REOPENED action == REOPENED
end
def joined?
action == JOINED
end
def left?
action == LEFT
end
def commented?
action == COMMENTED
end
def membership_changed?
joined? || left?
end
def created_project?
created? && !target
end
def created_target?
created? && target
end end
def milestone? def milestone?
...@@ -135,32 +141,32 @@ class Event < ActiveRecord::Base ...@@ -135,32 +141,32 @@ class Event < ActiveRecord::Base
target_type == "MergeRequest" target_type == "MergeRequest"
end end
def joined? def milestone
action == JOINED target if milestone?
end
def left?
action == LEFT
end
def membership_changed?
joined? || left?
end end
def issue def issue
target if target_type == "Issue" target if issue?
end end
def merge_request def merge_request
target if target_type == "MergeRequest" target if merge_request?
end end
def note def note
target if target_type == "Note" target if note?
end end
def action_name def action_name
if closed? if push?
if new_ref?
"pushed new"
elsif rm_ref?
"deleted"
else
"pushed to"
end
elsif closed?
"closed" "closed"
elsif merged? elsif merged?
"accepted" "accepted"
...@@ -168,6 +174,10 @@ class Event < ActiveRecord::Base ...@@ -168,6 +174,10 @@ class Event < ActiveRecord::Base
'joined' 'joined'
elsif left? elsif left?
'left' 'left'
elsif commented?
"commented on"
elsif created_project?
"created"
else else
"opened" "opened"
end end
...@@ -236,16 +246,6 @@ class Event < ActiveRecord::Base ...@@ -236,16 +246,6 @@ class Event < ActiveRecord::Base
tag? ? "tag" : "branch" tag? ? "tag" : "branch"
end end
def push_action_name
if new_ref?
"pushed new"
elsif rm_ref?
"deleted"
else
"pushed to"
end
end
def push_with_commits? def push_with_commits?
md_ref? && commits.any? && commit_from && commit_to md_ref? && commits.any? && commit_from && commit_to
end end
......
...@@ -114,13 +114,11 @@ class ProjectMember < Member ...@@ -114,13 +114,11 @@ class ProjectMember < Member
end end
def post_create_hook def post_create_hook
Event.create( unless owner?
project_id: self.project.id, event_service.join_project(self.project, self.user)
action: Event::JOINED, notification_service.new_team_member(self)
author_id: self.user.id end
)
notification_service.new_team_member(self) unless owner?
system_hook_service.execute_hooks_for(self, :create) system_hook_service.execute_hooks_for(self, :create)
end end
...@@ -129,15 +127,14 @@ class ProjectMember < Member ...@@ -129,15 +127,14 @@ class ProjectMember < Member
end end
def post_destroy_hook def post_destroy_hook
Event.create( event_service.leave_project(self.project, self.user)
project_id: self.project.id,
action: Event::LEFT,
author_id: self.user.id
)
system_hook_service.execute_hooks_for(self, :destroy) system_hook_service.execute_hooks_for(self, :destroy)
end end
def event_service
EventCreateService.new
end
def notification_service def notification_service
NotificationService.new NotificationService.new
end end
......
...@@ -55,14 +55,13 @@ class User < ActiveRecord::Base ...@@ -55,14 +55,13 @@ class User < ActiveRecord::Base
include Gitlab::ConfigHelper include Gitlab::ConfigHelper
include TokenAuthenticatable include TokenAuthenticatable
extend Gitlab::ConfigHelper extend Gitlab::ConfigHelper
extend Gitlab::CurrentSettings include Gitlab::CurrentSettings
default_value_for :admin, false default_value_for :admin, false
default_value_for :can_create_group, gitlab_config.default_can_create_group default_value_for :can_create_group, gitlab_config.default_can_create_group
default_value_for :can_create_team, false default_value_for :can_create_team, false
default_value_for :hide_no_ssh_key, false default_value_for :hide_no_ssh_key, false
default_value_for :hide_no_password, false default_value_for :hide_no_password, false
default_value_for :projects_limit, current_application_settings.default_projects_limit
default_value_for :theme_id, gitlab_config.default_theme default_value_for :theme_id, gitlab_config.default_theme
devise :database_authenticatable, :lockable, :async, devise :database_authenticatable, :lockable, :async,
...@@ -141,6 +140,7 @@ class User < ActiveRecord::Base ...@@ -141,6 +140,7 @@ class User < ActiveRecord::Base
before_save :ensure_authentication_token before_save :ensure_authentication_token
after_save :ensure_namespace_correct after_save :ensure_namespace_correct
after_initialize :set_projects_limit
after_create :post_create_hook after_create :post_create_hook
after_destroy :post_destroy_hook after_destroy :post_destroy_hook
...@@ -255,7 +255,7 @@ class User < ActiveRecord::Base ...@@ -255,7 +255,7 @@ class User < ActiveRecord::Base
counter = 0 counter = 0
base = username base = username
while User.by_login(username).present? || Namespace.by_path(username).present? while User.by_login(username).present? || Namespace.by_path(username).present?
counter += 1 counter += 1
username = "#{base}#{counter}" username = "#{base}#{counter}"
end end
...@@ -459,10 +459,17 @@ class User < ActiveRecord::Base ...@@ -459,10 +459,17 @@ class User < ActiveRecord::Base
def set_notification_email def set_notification_email
if self.notification_email.blank? || !self.all_emails.include?(self.notification_email) if self.notification_email.blank? || !self.all_emails.include?(self.notification_email)
self.notification_email = self.email self.notification_email = self.email
end end
end end
def set_projects_limit
connection_default_value_defined = new_record? && !projects_limit_changed?
return unless self.projects_limit.nil? || connection_default_value_defined
self.projects_limit = current_application_settings.default_projects_limit
end
def requires_ldap_check? def requires_ldap_check?
if !Gitlab.config.ldap.enabled if !Gitlab.config.ldap.enabled
false false
...@@ -559,7 +566,7 @@ class User < ActiveRecord::Base ...@@ -559,7 +566,7 @@ class User < ActiveRecord::Base
def post_create_hook def post_create_hook
log_info("User \"#{self.name}\" (#{self.email}) was created") log_info("User \"#{self.name}\" (#{self.email}) was created")
notification_service.new_user(self, @reset_token) notification_service.new_user(self, @reset_token) if self.created_by_id
system_hook_service.execute_hooks_for(self, :create) system_hook_service.execute_hooks_for(self, :create)
end end
...@@ -607,4 +614,13 @@ class User < ActiveRecord::Base ...@@ -607,4 +614,13 @@ class User < ActiveRecord::Base
def oauth_authorized_tokens def oauth_authorized_tokens
Doorkeeper::AccessToken.where(resource_owner_id: self.id, revoked_at: nil) Doorkeeper::AccessToken.where(resource_owner_id: self.id, revoked_at: nil)
end end
def contributed_projects_ids
Event.where(author_id: self).
where("created_at > ?", Time.now - 1.year).
code_push.
reorder(project_id: :desc).
select('DISTINCT(project_id)').
map(&:project_id)
end
end end
...@@ -17,7 +17,7 @@ class CreateBranchService < BaseService ...@@ -17,7 +17,7 @@ class CreateBranchService < BaseService
new_branch = repository.find_branch(branch_name) new_branch = repository.find_branch(branch_name)
if new_branch if new_branch
Event.create_ref_event(project, current_user, new_branch, 'add') EventCreateService.new.push_ref(project, current_user, new_branch, 'add')
return success(new_branch) return success(new_branch)
else else
return error('Invalid reference name') return error('Invalid reference name')
......
...@@ -26,7 +26,7 @@ class CreateTagService < BaseService ...@@ -26,7 +26,7 @@ class CreateTagService < BaseService
project.gitlab_ci_service.async_execute(push_data) project.gitlab_ci_service.async_execute(push_data)
end end
Event.create_ref_event(project, current_user, new_tag, 'add', 'refs/tags') EventCreateService.new.push_ref(project, current_user, new_tag, 'add', 'refs/tags')
success(new_tag) success(new_tag)
else else
error('Invalid reference name') error('Invalid reference name')
......
...@@ -25,7 +25,7 @@ class DeleteBranchService < BaseService ...@@ -25,7 +25,7 @@ class DeleteBranchService < BaseService
end end
if repository.rm_branch(branch_name) if repository.rm_branch(branch_name)
Event.create_ref_event(project, current_user, branch, 'rm') EventCreateService.new.push_ref(project, current_user, branch, 'rm')
success('Branch was removed') success('Branch was removed')
else else
return error('Failed to remove branch') return error('Failed to remove branch')
......
...@@ -7,58 +7,98 @@ ...@@ -7,58 +7,98 @@
# #
class EventCreateService class EventCreateService
def open_issue(issue, current_user) def open_issue(issue, current_user)
create_event(issue, current_user, Event::CREATED) create_record_event(issue, current_user, Event::CREATED)
end end
def close_issue(issue, current_user) def close_issue(issue, current_user)
create_event(issue, current_user, Event::CLOSED) create_record_event(issue, current_user, Event::CLOSED)
end end
def reopen_issue(issue, current_user) def reopen_issue(issue, current_user)
create_event(issue, current_user, Event::REOPENED) create_record_event(issue, current_user, Event::REOPENED)
end end
def open_mr(merge_request, current_user) def open_mr(merge_request, current_user)
create_event(merge_request, current_user, Event::CREATED) create_record_event(merge_request, current_user, Event::CREATED)
end end
def close_mr(merge_request, current_user) def close_mr(merge_request, current_user)
create_event(merge_request, current_user, Event::CLOSED) create_record_event(merge_request, current_user, Event::CLOSED)
end end
def reopen_mr(merge_request, current_user) def reopen_mr(merge_request, current_user)
create_event(merge_request, current_user, Event::REOPENED) create_record_event(merge_request, current_user, Event::REOPENED)
end end
def merge_mr(merge_request, current_user) def merge_mr(merge_request, current_user)
create_event(merge_request, current_user, Event::MERGED) create_record_event(merge_request, current_user, Event::MERGED)
end end
def open_milestone(milestone, current_user) def open_milestone(milestone, current_user)
create_event(milestone, current_user, Event::CREATED) create_record_event(milestone, current_user, Event::CREATED)
end end
def close_milestone(milestone, current_user) def close_milestone(milestone, current_user)
create_event(milestone, current_user, Event::CLOSED) create_record_event(milestone, current_user, Event::CLOSED)
end end
def reopen_milestone(milestone, current_user) def reopen_milestone(milestone, current_user)
create_event(milestone, current_user, Event::REOPENED) create_record_event(milestone, current_user, Event::REOPENED)
end end
def leave_note(note, current_user) def leave_note(note, current_user)
create_event(note, current_user, Event::COMMENTED) create_record_event(note, current_user, Event::COMMENTED)
end
def join_project(project, current_user)
create_event(project, current_user, Event::JOINED)
end
def leave_project(project, current_user)
create_event(project, current_user, Event::LEFT)
end
def create_project(project, current_user)
create_event(project, current_user, Event::CREATED)
end
def push_ref(project, current_user, ref, action = 'add', prefix = 'refs/heads')
commit = project.repository.commit(ref.target)
if action.to_s == 'add'
before = '00000000'
after = commit.id
else
before = commit.id
after = '00000000'
end
data = {
ref: "#{prefix}/#{ref.name}",
before: before,
after: after
}
push(project, current_user, data)
end
def push(project, current_user, push_data)
create_event(project, current_user, Event::PUSHED, data: push_data)
end end
private private
def create_event(record, current_user, status) def create_record_event(record, current_user, status)
Event.create( create_event(record.project, current_user, status, target_id: record.id, target_type: record.class.name)
project: record.project, end
target_id: record.id,
target_type: record.class.name, def create_event(project, current_user, status, attributes = {})
attributes.reverse_merge!(
project: project,
action: status, action: status,
author_id: current_user.id author_id: current_user.id
) )
Event.create(attributes)
end end
end end
...@@ -52,7 +52,7 @@ class GitPushService ...@@ -52,7 +52,7 @@ class GitPushService
end end
@push_data = post_receive_data(oldrev, newrev, ref) @push_data = post_receive_data(oldrev, newrev, ref)
create_push_event(@push_data) EventCreateService.new.push(project, user, @push_data)
project.execute_hooks(@push_data.dup, :push_hooks) project.execute_hooks(@push_data.dup, :push_hooks)
project.execute_services(@push_data.dup) project.execute_services(@push_data.dup)
end end
...@@ -60,15 +60,6 @@ class GitPushService ...@@ -60,15 +60,6 @@ class GitPushService
protected protected
def create_push_event(push_data)
Event.create!(
project: project,
action: Event::PUSHED,
data: push_data,
author_id: push_data[:user_id]
)
end
# Extract any GFM references from the pushed commit messages. If the configured issue-closing regex is matched, # Extract any GFM references from the pushed commit messages. If the configured issue-closing regex is matched,
# close the referenced Issue. Create cross-reference Notes corresponding to any other referenced Mentionables. # close the referenced Issue. Create cross-reference Notes corresponding to any other referenced Mentionables.
def process_commit_messages(ref) def process_commit_messages(ref)
......
...@@ -5,7 +5,7 @@ class GitTagPushService ...@@ -5,7 +5,7 @@ class GitTagPushService
@project, @user = project, user @project, @user = project, user
@push_data = create_push_data(oldrev, newrev, ref) @push_data = create_push_data(oldrev, newrev, ref)
create_push_event EventCreateService.new.push(project, user, @push_data)
project.repository.expire_cache project.repository.expire_cache
project.execute_hooks(@push_data.dup, :tag_push_hooks) project.execute_hooks(@push_data.dup, :tag_push_hooks)
...@@ -22,13 +22,4 @@ class GitTagPushService ...@@ -22,13 +22,4 @@ class GitTagPushService
Gitlab::PushDataBuilder. Gitlab::PushDataBuilder.
build(project, user, oldrev, newrev, ref, []) build(project, user, oldrev, newrev, ref, [])
end end
def create_push_event
Event.create!(
project: project,
action: Event::PUSHED,
data: push_data,
author_id: push_data[:user_id]
)
end
end end
...@@ -52,13 +52,7 @@ module Projects ...@@ -52,13 +52,7 @@ module Projects
end end
end end
if @project.persisted? after_create_actions if @project.persisted?
if @project.wiki_enabled?
@project.create_wiki
end
after_create_actions
end
@project @project
rescue => ex rescue => ex
...@@ -79,6 +73,10 @@ module Projects ...@@ -79,6 +73,10 @@ module Projects
def after_create_actions def after_create_actions
log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"") log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"")
@project.create_wiki if @project.wiki_enabled?
event_service.create_project(@project, current_user)
system_hook_service.execute_hooks_for(@project, :create) system_hook_service.execute_hooks_for(@project, :create)
unless @project.group unless @project.group
......
...@@ -19,6 +19,11 @@ ...@@ -19,6 +19,11 @@
= f.label :gravatar_enabled, class: 'control-label' = f.label :gravatar_enabled, class: 'control-label'
.col-sm-10 .col-sm-10
= f.check_box :gravatar_enabled, class: 'checkbox' = f.check_box :gravatar_enabled, class: 'checkbox'
.form-group
= f.label :twitter_sharing_enabled, "Twitter enabled", class: 'control-label'
.col-sm-10
= f.check_box :twitter_sharing_enabled, class: 'checkbox'
%span.help-block Show users button to share their newly created public or internal projects on twitter
%fieldset %fieldset
%legend Misc %legend Misc
.form-group .form-group
......
...@@ -17,6 +17,6 @@ ...@@ -17,6 +17,6 @@
%tr{:id => "application_#{application.id}"} %tr{:id => "application_#{application.id}"}
%td= link_to application.name, admin_application_path(application) %td= link_to application.name, admin_application_path(application)
%td= application.redirect_uri %td= application.redirect_uri
%td= application.access_tokens.count %td= application.access_tokens.map(&:resource_owner_id).uniq.count
%td= link_to 'Edit', edit_admin_application_path(application), class: 'btn btn-link' %td= link_to 'Edit', edit_admin_application_path(application), class: 'btn btn-link'
%td= render 'delete_form', application: application %td= render 'delete_form', application: application
...@@ -13,15 +13,13 @@ ...@@ -13,15 +13,13 @@
.form-group .form-group
%strong Activity %strong Activity
.checkbox .checkbox
= label_tag :with_push, 'Not empty' = label_tag :with_push do
= check_box_tag :with_push, 1, params[:with_push] = check_box_tag :with_push, 1, params[:with_push]
&nbsp; %span Projects with push events
%span.light Projects with push events
.checkbox .checkbox
= label_tag :abandoned, 'Abandoned' = label_tag :abandoned do
= check_box_tag :abandoned, 1, params[:abandoned] = check_box_tag :abandoned, 1, params[:abandoned]
&nbsp; %span No activity over 6 month
%span.light No activity over 6 month
%fieldset %fieldset
%strong Visibility level: %strong Visibility level:
......
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
= render 'shared/event_filter' = render 'shared/event_filter'
.content_list
- if @events.any?
.content_list
- else
.nothing-here-block Projects activity will be displayed here
= spinner = spinner
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.input-group .input-group
= search_field_tag :filter_group, nil, placeholder: 'Filter by name', class: 'dash-filter form-control' = search_field_tag :filter_group, nil, placeholder: 'Filter by name', class: 'dash-filter form-control'
- if current_user.can_create_group? - if current_user.can_create_group?
.input-group-addon .input-group-addon.dash-new-group
= link_to new_group_path, class: "" do = link_to new_group_path, class: "" do
%strong New group %strong New group
%ul.well-list.dash-list %ul.well-list.dash-list
......
= link_to namespace_project_path(project.namespace, project), class: dom_class(project) do = link_to namespace_project_path(project.namespace, project), class: dom_class(project) do
.dash-project-avatar .dash-project-avatar
= project_icon("#{project.namespace.to_param}/#{project.to_param}", alt: '', class: 'avatar project-avatar s40') = project_icon(project, alt: '', class: 'avatar project-avatar s40')
.dash-project-access-icon .dash-project-access-icon
= visibility_level_icon(project.visibility_level) = visibility_level_icon(project.visibility_level)
%span.str-truncated %span.str-truncated
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
= f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus" = f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus"
= f.password_field :password, class: "form-control bottom", placeholder: "Password" = f.password_field :password, class: "form-control bottom", placeholder: "Password"
- if devise_mapping.rememberable? - if devise_mapping.rememberable?
.remember-me .remember-me.checkbox
%label.checkbox.remember_me{for: "user_remember_me"} %label{for: "user_remember_me"}
= f.check_box :remember_me = f.check_box :remember_me
%span Remember me %span Remember me
.pull-right .pull-right
= link_to "Forgot your password?", new_password_path(resource_name) = link_to "Forgot your password?", new_password_path(resource_name)
%div %div
= f.submit "Sign in", class: "btn btn-save" = f.submit "Sign in", class: "btn btn-save"
...@@ -3,12 +3,14 @@ ...@@ -3,12 +3,14 @@
.event-item-timestamp .event-item-timestamp
#{time_ago_with_tooltip(event.created_at)} #{time_ago_with_tooltip(event.created_at)}
= cache event do = cache [event, current_user] do
= image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:'' = image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
- if event.push? - if event.push?
= render "events/event/push", event: event = render "events/event/push", event: event
- elsif event.note? - elsif event.commented?
= render "events/event/note", event: event = render "events/event/note", event: event
- elsif event.created_project?
= render "events/event/created_project", event: event
- else - else
= render "events/event/common", event: event = render "events/event/common", event: event
\ No newline at end of file
.event-title .event-title
%span.author_name= link_to_author event %span.author_name= link_to_author event
%span.event_label{class: event.action_name}= event_action_name(event) %span.event_label{class: event.action_name}
= event_action_name(event)
- if event.target - if event.target
%strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target] %strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target]
- else at
%strong= gfm event.target_title
at
- if event.project - if event.project
= link_to_project event.project = link_to_project event.project
- else - else
= event.project_name = event.project_name
- if event.target.respond_to?(:title) - if event.target.respond_to?(:title)
.event-body .event-body
.event-note .event-note
......
.event-title
%span.author_name= link_to_author event
%span.event_label{class: event.action_name}
= event_action_name(event)
- if event.project
= link_to_project event.project
- else
= event.project_name
- if current_user == event.author && !event.project.private? && twitter_sharing_enabled?
.event-body
.event-note
.md
%p
Congratulations! Why not share your accomplishment with the world?
%a.twitter-share-button{ |
href: "https://twitter.com/share", |
"data-url" => event.project.web_url, |
"data-text" => "I just created a new project in GitLab! GitLab is version control on your server.", |
"data-size" => "medium", |
"data-related" => "gitlab", |
"data-hashtags" => "gitlab", |
"data-count" => "none"}
Tweet
%script{src: "//platform.twitter.com/widgets.js"}
\ No newline at end of file
.event-title .event-title
%span.author_name= link_to_author event %span.author_name= link_to_author event
%span.event_label commented on #{event_note_title_html(event)} at %span.event_label
= event.action_name
= event_note_title_html(event)
at
- if event.project - if event.project
= link_to_project event.project = link_to_project event.project
- else - else
......
.event-title .event-title
%span.author_name= link_to_author event %span.author_name= link_to_author event
%span.event_label.pushed #{event.push_action_name} #{event.ref_type} %span.event_label.pushed #{event.action_name} #{event.ref_type}
- if event.rm_ref? - if event.rm_ref?
%strong= event.ref_name %strong= event.ref_name
- else - else
......
...@@ -3,11 +3,9 @@ ...@@ -3,11 +3,9 @@
.project-access-icon .project-access-icon
= visibility_level_icon(project.visibility_level) = visibility_level_icon(project.visibility_level)
= link_to project.name_with_namespace, [project.namespace.becomes(Namespace), project] = link_to project.name_with_namespace, [project.namespace.becomes(Namespace), project]
%span.pull-right
- if current_page?(starred_explore_projects_path) %i.fa.fa-star
%strong.pull-right = project.star_count
%i.fa.fa-star
= pluralize project.star_count, 'star'
.project-info .project-info
- if project.description.present? - if project.description.present?
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
%li.project-row %li.project-row
= link_to namespace_project_path(project.namespace, project), class: dom_class(project) do = link_to namespace_project_path(project.namespace, project), class: dom_class(project) do
.dash-project-avatar .dash-project-avatar
= project_icon("#{project.namespace.to_param}/#{project.to_param}", alt: '', class: 'avatar s40') = project_icon(project, alt: '', class: 'avatar s40')
.dash-project-access-icon .dash-project-access-icon
= visibility_level_icon(project.visibility_level) = visibility_level_icon(project.visibility_level)
%span.str-truncated %span.str-truncated
......
...@@ -13,10 +13,7 @@ ...@@ -13,10 +13,7 @@
- if current_user - if current_user
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
= render 'shared/event_filter' = render 'shared/event_filter'
- if @events.any? .content_list
.content_list
- else
.nothing-here-block Project activity will be displayed here
= spinner = spinner
%aside.side.col-md-4 %aside.side.col-md-4
= render "projects", projects: @projects = render "projects", projects: @projects
...@@ -42,3 +42,9 @@ ...@@ -42,3 +42,9 @@
%li %li
Use Use
= link_to 'shortcuts', '#', onclick: 'Shortcuts.showHelp(event)' = link_to 'shortcuts', '#', onclick: 'Shortcuts.showHelp(event)'
%li
Get a support
= link_to 'subscription', 'https://about.gitlab.com/pricing/'
%li
= link_to 'Compare', 'https://about.gitlab.com/features/#compare'
GitLab editions
...@@ -49,8 +49,14 @@ ...@@ -49,8 +49,14 @@
%span %span
Graphs Graphs
= nav_link(controller: :milestones) do
= link_to project_milestones_path(@project), title: 'Milestones' do
%i.fa.fa-clock-o
%span
Milestones
- if project_nav_tab? :issues - if project_nav_tab? :issues
= nav_link(controller: %w(issues milestones labels)) do = nav_link(controller: :issues) do
= link_to url_for_project_issues, title: 'Issues', class: 'shortcuts-issues' do = link_to url_for_project_issues, title: 'Issues', class: 'shortcuts-issues' do
%i.fa.fa-exclamation-circle %i.fa.fa-exclamation-circle
%span %span
...@@ -66,6 +72,12 @@ ...@@ -66,6 +72,12 @@
Merge Requests Merge Requests
%span.count.merge_counter= @project.merge_requests.opened.count %span.count.merge_counter= @project.merge_requests.opened.count
= nav_link(controller: :labels) do
= link_to project_labels_path(@project), title: 'Labels' do
%i.fa.fa-tags
%span
Labels
- if project_nav_tab? :wiki - if project_nav_tab? :wiki
= nav_link(controller: :wikis) do = nav_link(controller: :wikis) do
= link_to namespace_project_wiki_path(@project.namespace, @project, :home), title: 'Wiki', class: 'shortcuts-wiki' do = link_to namespace_project_wiki_path(@project.namespace, @project, :home), title: 'Wiki', class: 'shortcuts-wiki' do
......
...@@ -36,12 +36,12 @@ ...@@ -36,12 +36,12 @@
%th Scope %th Scope
%th %th
%tbody %tbody
- @authorized_tokens.each do |token| - @authorized_apps.each do |app|
- application = token.application - token = app.authorized_tokens.order('created_at desc').first
%tr{:id => "application_#{application.id}"} %tr{:id => "application_#{app.id}"}
%td= application.name %td= app.name
%td= token.created_at %td= token.created_at
%td= token.scopes %td= token.scopes
%td= render 'doorkeeper/authorized_applications/delete_form', application: application %td= render 'doorkeeper/authorized_applications/delete_form', application: app
- else - else
%p.light You dont have any authorized applications %p.light You dont have any authorized applications
- empty_repo = @project.empty_repo? - empty_repo = @project.empty_repo?
.project-home-panel{:class => ("empty-project" if empty_repo)} .project-home-panel{:class => ("empty-project" if empty_repo)}
.project-identicon-holder .project-identicon-holder
= project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar') = project_icon(@project, alt: '', class: 'avatar project-avatar')
.project-home-row .project-home-row
.project-home-desc .project-home-desc
- if @project.description.present? - if @project.description.present?
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
= f.label :description, 'Description', class: 'control-label' = f.label :description, 'Description', class: 'control-label'
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do
= render 'projects/zen', f: f, attr: :description, = render 'projects/zen', f: f, attr: :description,
classes: 'description form-control' classes: 'description form-control'
.col-sm-12.hint .col-sm-12.hint
......
%ul.nav.nav-tabs
- if project_nav_tab? :issues
= nav_link(controller: :issues) do
= link_to namespace_project_issues_path(@project.namespace, @project), class: "tab" do
%i.fa.fa-exclamation-circle
Issues
- if project_nav_tab? :merge_requests
= nav_link(controller: :merge_requests) do
= link_to namespace_project_merge_requests_path(@project.namespace, @project), class: "tab" do
%i.fa.fa-tasks
Merge Requests
= nav_link(controller: :milestones) do
= link_to namespace_project_milestones_path(@project.namespace, @project), class: "tab" do
%i.fa.fa-clock-o
Milestones
= nav_link(controller: :labels) do
= link_to namespace_project_labels_path(@project.namespace, @project), class: "tab" do
%i.fa.fa-tags
Labels
- if current_controller?(:issues)
- if current_user
%li.hidden-xs
= link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }) do
%i.fa.fa-rss
%li.pull-right
.pull-right
.pull-left
= form_tag namespace_project_issues_path(@project.namespace, @project), method: :get, id: "issue_search_form", class: 'pull-left issue-search-form' do
.append-right-10.hidden-xs.hidden-sm
= search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' }
= hidden_field_tag :state, params['state']
= hidden_field_tag :scope, params['scope']
= hidden_field_tag :assignee_id, params['assignee_id']
= hidden_field_tag :milestone_id, params['milestone_id']
= hidden_field_tag :label_id, params['label_id']
- if can? current_user, :write_issue, @project
= link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-left", title: "New Issue", id: "new_issue_link" do
%i.fa.fa-plus
New Issue
- if current_controller?(:merge_requests)
%li.pull-right
.pull-right
- if can? current_user, :write_merge_request, @project
= link_to new_namespace_project_merge_request_path(@project.namespace, @project), class: "btn btn-new pull-left", title: "New Merge Request" do
%i.fa.fa-plus
New Merge Request
...@@ -10,4 +10,4 @@ ...@@ -10,4 +10,4 @@
.md-write-holder .md-write-holder
= yield = yield
.md-preview-holder.hide .md-preview-holder.hide
.js-md-preview .js-md-preview{class: (preview_class if defined?(preview_class))}
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
- Gitlab::VisibilityLevel.values.each do |level| - Gitlab::VisibilityLevel.values.each do |level|
.radio .radio
- restricted = restricted_visibility_levels.include?(level) - restricted = restricted_visibility_levels.include?(level)
= f.radio_button :visibility_level, level, checked: (visibility_level == level), disabled: restricted
= label :project_visibility_level, level do = label :project_visibility_level, level do
= f.radio_button :visibility_level, level, checked: (visibility_level == level), disabled: restricted
= visibility_level_icon(level) = visibility_level_icon(level)
.option-title .option-title
= visibility_level_label(level) = visibility_level_label(level)
......
...@@ -15,5 +15,5 @@ ...@@ -15,5 +15,5 @@
%p %p
To preserve performance only To preserve performance only
%strong #{allowed_diff_size} of #{diffs.size} %strong #{allowed_diff_size} of #{diffs.size}
files displayed. files are displayed.
...@@ -14,24 +14,24 @@ ...@@ -14,24 +14,24 @@
.voting_notes#notes= render "projects/notes/notes_with_form" .voting_notes#notes= render "projects/notes/notes_with_form"
.col-md-3 .col-md-3
%div .issuable-affix
.clearfix .clearfix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'} %span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
= cross_project_reference(@project, @issue) = cross_project_reference(@project, @issue)
%hr
.context
%cite.cgray
= render partial: 'issue_context', locals: { issue: @issue }
%hr
.clearfix
.votes-holder
%h6 Votes
#votes= render 'votes/votes_block', votable: @issue
- if @issue.labels.any?
%hr %hr
%h6 Labels .context
.issue-show-labels %cite.cgray
- @issue.labels.each do |label| = render partial: 'issue_context', locals: { issue: @issue }
= link_to namespace_project_issues_path(@project.namespace, @project, label_name: label.name) do %hr
%p= render_colored_label(label) .clearfix
.votes-holder
%h6 Votes
#votes= render 'votes/votes_block', votable: @issue
- if @issue.labels.any?
%hr
%h6 Labels
.issue-show-labels
- @issue.labels.each do |label|
= link_to namespace_project_issues_path(@project.namespace, @project, label_name: label.name) do
= render_colored_label(label)
.append-bottom-10
.check-all-holder
= check_box_tag "check_all_issues", nil, false, class: "check_all_issues left", disabled: !can?(current_user, :modify_issue, @project)
= render 'shared/issuable_filter'
.clearfix
.issues_bulk_update.hide
= form_tag bulk_update_namespace_project_issues_path(@project.namespace, @project), method: :post do
= select_tag('update[status]', options_for_select([['Open', 'open'], ['Closed', 'closed']]), prompt: "Status")
= project_users_select_tag('update[assignee_id]', placeholder: 'Assignee')
= select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone")
= hidden_field_tag 'update[issues_ids]', []
= hidden_field_tag :status, params[:status]
= button_tag "Update issues", class: "btn update_selected_issues btn-save"
.panel.panel-default .panel.panel-default
%ul.well-list.issues-list %ul.well-list.issues-list
= render @issues = render @issues
......
= render "projects/issues_nav" .append-bottom-10
.pull-right
.pull-left
- if current_user
.hidden-xs.pull-left
= link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do
%i.fa.fa-rss
= form_tag project_issues_path(@project), method: :get, id: "issue_search_form", class: 'pull-left issue-search-form' do
.append-right-10.hidden-xs.hidden-sm
= search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' }
= hidden_field_tag :state, params['state']
= hidden_field_tag :scope, params['scope']
= hidden_field_tag :assignee_id, params['assignee_id']
= hidden_field_tag :milestone_id, params['milestone_id']
= hidden_field_tag :label_id, params['label_id']
- if can? current_user, :write_issue, @project
= link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-left", title: "New Issue", id: "new_issue_link" do
%i.fa.fa-plus
New Issue
= render 'shared/issuable_filter'
.clearfix
.issues_bulk_update.hide
= form_tag bulk_update_project_issues_path(@project), method: :post do
= select_tag('update[status]', options_for_select([['Open', 'open'], ['Closed', 'closed']]), prompt: "Status")
= project_users_select_tag('update[assignee_id]', placeholder: 'Assignee')
= select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone")
= hidden_field_tag 'update[issues_ids]', []
= hidden_field_tag :status, params[:status]
= button_tag "Update issues", class: "btn update_selected_issues btn-save"
.issues-holder .issues-holder
= render "issues" = render "issues"
%h4.page-title .issue
.issue-box{ class: issue_box_class(@issue) } .issue-details
- if @issue.closed? %h4.page-title
Closed .issue-box{ class: issue_box_class(@issue) }
- else - if @issue.closed?
Open Closed
Issue ##{@issue.iid} - else
%small.creator Open
&middot; created by #{link_to_member(@project, @issue.author)} #{issue_timestamp(@issue)} Issue ##{@issue.iid}
%small.creator
&middot; created by #{link_to_member(@project, @issue.author)} #{issue_timestamp(@issue)}
.pull-right .pull-right
- if can?(current_user, :write_issue, @project) - if can?(current_user, :write_issue, @project)
= link_to new_namespace_project_issue_path(@project.namespace, @project), class: "btn btn-grouped new-issue-link", title: "New Issue", id: "new_issue_link" do = link_to new_namespace_project_issue_path(@project.namespace, @project), class: "btn btn-grouped new-issue-link", title: "New Issue", id: "new_issue_link" do
%i.fa.fa-plus %i.fa.fa-plus
New Issue New Issue
- if can?(current_user, :modify_issue, @issue) - if can?(current_user, :modify_issue, @issue)
- if @issue.closed? - if @issue.closed?
= link_to 'Reopen', namespace_project_issue_path(@project.namespace, @project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-grouped btn-reopen" = link_to 'Reopen', namespace_project_issue_path(@project.namespace, @project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-grouped btn-reopen"
- else - else
= link_to 'Close', namespace_project_issue_path(@project.namespace, @project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close", title: "Close Issue" = link_to 'Close', namespace_project_issue_path(@project.namespace, @project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close", title: "Close Issue"
= link_to edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: "btn btn-grouped issuable-edit" do = link_to edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: "btn btn-grouped issuable-edit" do
%i.fa.fa-pencil-square-o %i.fa.fa-pencil-square-o
Edit Edit
%hr %hr
%h3.issue-title %h3.issue-title
= gfm escape_once(@issue.title) = gfm escape_once(@issue.title)
%div %div
- if @issue.description.present? - if @issue.description.present?
.description .description
.wiki .wiki
= preserve do = preserve do
= markdown(@issue.description, parse_tasks: true) = markdown(@issue.description, parse_tasks: true)
%hr %hr
= render "projects/issues/discussion" .issue-discussion
= render "projects/issues/discussion"
= render "projects/issues_nav"
- if can? current_user, :admin_label, @project - if can? current_user, :admin_label, @project
= link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do = link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do
New label New label
......
...@@ -10,22 +10,23 @@ ...@@ -10,22 +10,23 @@
= render "projects/merge_requests/show/participants" = render "projects/merge_requests/show/participants"
= render "projects/notes/notes_with_form" = render "projects/notes/notes_with_form"
.col-md-3 .col-md-3
.clearfix .issuable-affix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'} .clearfix
= cross_project_reference(@project, @merge_request) %span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
%hr = cross_project_reference(@project, @merge_request)
.context %hr
%cite.cgray .context
= render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request } %cite.cgray
%hr = render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request }
.votes-holder
%h6 Votes
#votes= render 'votes/votes_block', votable: @merge_request
- if @merge_request.labels.any?
%hr %hr
%h6 Labels .votes-holder
.merge-request-show-labels %h6 Votes
- @merge_request.labels.each do |label| #votes= render 'votes/votes_block', votable: @merge_request
= link_to namespace_project_merge_requests_path(@project.namespace, @project, label_name: label.name) do
%p= render_colored_label(label) - if @merge_request.labels.any?
%hr
%h6 Labels
.merge-request-show-labels
- @merge_request.labels.each do |label|
= link_to namespace_project_merge_requests_path(@project.namespace, @project, label_name: label.name) do
= render_colored_label(label)
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
- if merge_request.assignee - if merge_request.assignee
assigned to #{link_to_member(merge_request.source_project, merge_request.assignee)} assigned to #{link_to_member(merge_request.source_project, merge_request.assignee)}
- else - else
Work In Progress Unassigned
- if merge_request.votes_count > 0 - if merge_request.votes_count > 0
= render 'votes/votes_inline', votable: merge_request = render 'votes/votes_inline', votable: merge_request
- if merge_request.notes.any? - if merge_request.notes.any?
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
.form-group.issuable-description .form-group.issuable-description
= f.label :description, 'Description', class: 'control-label' = f.label :description, 'Description', class: 'control-label'
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do
= render 'projects/zen', f: f, attr: :description, classes: 'description form-control' = render 'projects/zen', f: f, attr: :description, classes: 'description form-control'
.col-sm-12-hint .col-sm-12-hint
......
.merge-request{'data-url' => namespace_project_merge_request_path(@project.namespace, @project, @merge_request)} .merge-request{'data-url' => namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}
= render "projects/merge_requests/show/mr_title" .merge-request-details
%hr = render "projects/merge_requests/show/mr_title"
= render "projects/merge_requests/show/mr_box" %hr
%hr = render "projects/merge_requests/show/mr_box"
.append-bottom-20 %hr
.slead .append-bottom-20
%span From .slead
- if @merge_request.for_fork? %span From
%strong.label-branch< - if @merge_request.for_fork?
- if @merge_request.source_project %strong.label-branch<
= link_to @merge_request.source_project_namespace, namespace_project_path(@merge_request.source_project.namespace, @merge_request.source_project) - if @merge_request.source_project
- else = link_to @merge_request.source_project_namespace, namespace_project_path(@merge_request.source_project.namespace, @merge_request.source_project)
\ #{@merge_request.source_project_namespace} - else
\:#{@merge_request.source_branch} \ #{@merge_request.source_project_namespace}
%span into \:#{@merge_request.source_branch}
%strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch} %span into
- else %strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch}
%strong.label-branch #{@merge_request.source_branch} - else
%span into %strong.label-branch #{@merge_request.source_branch}
%strong.label-branch #{@merge_request.target_branch} %span into
- if @merge_request.open? %strong.label-branch #{@merge_request.target_branch}
%span.pull-right - if @merge_request.open?
.btn-group %span.pull-right
%a.btn.dropdown-toggle{ data: {toggle: :dropdown} } .btn-group
%i.fa.fa-download %a.btn.dropdown-toggle{ data: {toggle: :dropdown} }
Download as %i.fa.fa-download
%span.caret Download as
%ul.dropdown-menu %span.caret
%li= link_to "Email Patches", namespace_project_merge_request_path(@project.namespace, @project, @merge_request, format: :patch) %ul.dropdown-menu
%li= link_to "Plain Diff", namespace_project_merge_request_path(@project.namespace, @project, @merge_request, format: :diff) %li= link_to "Email Patches", namespace_project_merge_request_path(@project.namespace, @project, @merge_request, format: :patch)
%li= link_to "Plain Diff", namespace_project_merge_request_path(@project.namespace, @project, @merge_request, format: :diff)
= render "projects/merge_requests/show/how_to_merge" = render "projects/merge_requests/show/how_to_merge"
= render "projects/merge_requests/show/state_widget" = render "projects/merge_requests/show/state_widget"
- if @commits.present? - if @commits.present?
%ul.nav.nav-tabs.merge-request-tabs %ul.nav.nav-tabs.merge-request-tabs
......
= render "projects/issues_nav"
.merge-requests-holder .merge-requests-holder
.append-bottom-10 .append-bottom-10
.pull-right
- if can? current_user, :write_merge_request, @project
= link_to new_project_merge_request_path(@project), class: "btn btn-new pull-left", title: "New Merge Request" do
%i.fa.fa-plus
New Merge Request
= render 'shared/issuable_filter' = render 'shared/issuable_filter'
.panel.panel-default .panel.panel-default
%ul.well-list.mr-list %ul.well-list.mr-list
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
.accept-action .accept-action
= f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request"
- if can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && !@merge_request.for_fork? - if can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && !@merge_request.for_fork?
.accept-control .accept-control.checkbox
= label_tag :should_remove_source_branch, class: "remove_source_checkbox" do = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do
= check_box_tag :should_remove_source_branch = check_box_tag :should_remove_source_branch
Remove source-branch Remove source-branch
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
.form-group.milestone-description .form-group.milestone-description
= f.label :description, "Description", class: "control-label" = f.label :description, "Description", class: "control-label"
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do
= render 'projects/zen', f: f, attr: :description, classes: 'description form-control' = render 'projects/zen', f: f, attr: :description, classes: 'description form-control'
.hint .hint
.pull-left Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}. .pull-left Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}.
......
= render "projects/issues_nav" .pull-right
.milestones_content - if can? current_user, :admin_milestone, @project
%h3.page-title = link_to new_namespace_project_milestone_path(@project.namespace, @project), class: "pull-right btn btn-new", title: "New Milestone" do
Milestones %i.fa.fa-plus
- if can? current_user, :admin_milestone, @project New Milestone
= link_to new_namespace_project_milestone_path(@project.namespace, @project), class: "pull-right btn btn-new", title: "New Milestone" do
%i.fa.fa-plus
New Milestone
= render 'shared/milestones_filter' = render 'shared/milestones_filter'
.milestones .milestones
......
= render "projects/issues_nav"
%h4.page-title %h4.page-title
.issue-box{ class: issue_box_class(@milestone) } .issue-box{ class: issue_box_class(@milestone) }
- if @milestone.closed? - if @milestone.closed?
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
%i.fa.fa-github %i.fa.fa-github
Import projects from GitHub Import projects from GitHub
= render 'github_import_modal' = render 'github_import_modal'
.project-import.form-group .project-import.form-group
.col-sm-2 .col-sm-2
.col-sm-10 .col-sm-10
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
= link_to status_import_gitlab_path do = link_to status_import_gitlab_path do
%i.fa.fa-heart %i.fa.fa-heart
Import projects from GitLab.com Import projects from GitLab.com
- else - elsif request.host != 'gitlab.com'
= link_to '#', class: 'how_to_import_link light' do = link_to '#', class: 'how_to_import_link light' do
%i.fa.fa-heart %i.fa.fa-heart
Import projects from GitLab.com Import projects from GitLab.com
...@@ -99,4 +99,4 @@ ...@@ -99,4 +99,4 @@
e.preventDefault() e.preventDefault()
import_modal = $(this).parent().find(".modal").show() import_modal = $(this).parent().find(".modal").show()
$('.modal-header .close').bind 'click', -> $('.modal-header .close').bind 'click', ->
$(".modal").hide() $(".modal").hide()
\ No newline at end of file
.note-edit-form .note-edit-form
= form_for note, url: namespace_project_note_path(@project.namespace, @project, note), method: :put, remote: true, authenticity_token: true do |f| = form_for note, url: namespace_project_note_path(@project.namespace, @project, note), method: :put, remote: true, authenticity_token: true do |f|
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "note-text" } do
= render 'projects/zen', f: f, attr: :note, = render 'projects/zen', f: f, attr: :note,
classes: 'note_text js-note-text' classes: 'note_text js-note-text'
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
= f.hidden_field :noteable_id = f.hidden_field :noteable_id
= f.hidden_field :noteable_type = f.hidden_field :noteable_type
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "note-text" } do
= render 'projects/zen', f: f, attr: :note, = render 'projects/zen', f: f, attr: :note,
classes: 'note_text js-note-text' classes: 'note_text js-note-text'
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
.form-group.wiki-content .form-group.wiki-content
= f.label :content, class: 'control-label' = f.label :content, class: 'control-label'
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do
= render 'projects/zen', f: f, attr: :content, classes: 'description form-control' = render 'projects/zen', f: f, attr: :content, classes: 'description form-control'
.col-sm-12.hint .col-sm-12.hint
.pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'} .pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}
......
...@@ -7,4 +7,5 @@ ...@@ -7,4 +7,5 @@
= link_to "#L#{i}", id: "L#{i}", rel: "#L#{i}" do = link_to "#L#{i}", id: "L#{i}", rel: "#L#{i}" do
%i.fa.fa-link %i.fa.fa-link
= i = i
= highlight(blob.name, blob.data) :preserve
#{highlight(blob.name, blob.data)}
.issues-filters .issues-filters
.pull-left.append-right-20 .issues-state-filters
%ul.nav.nav-pills.nav-compact %ul.nav.nav-tabs
%li{class: ("active" if params[:state] == 'opened')} %li{class: ("active" if params[:state] == 'opened')}
= link_to page_filter_path(state: 'opened') do = link_to page_filter_path(state: 'opened') do
%i.fa.fa-exclamation-circle %i.fa.fa-exclamation-circle
...@@ -14,99 +14,106 @@ ...@@ -14,99 +14,106 @@
%i.fa.fa-compass %i.fa.fa-compass
All All
.dropdown.inline.assignee-filter %div
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - if controller.controller_name == 'issues'
%i.fa.fa-user .check-all-holder
%span.light assignee: = check_box_tag "check_all_issues", nil, false,
- if @assignee.present? class: "check_all_issues left",
%strong= @assignee.name disabled: !can?(current_user, :modify_issue, @project)
- elsif params[:assignee_id] == "0" .issues-other-filters
Unassigned .dropdown.inline.assignee-filter
- else %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
Any %i.fa.fa-user
%b.caret %span.light assignee:
%ul.dropdown-menu - if @assignee.present?
%li %strong= @assignee.name
= link_to page_filter_path(assignee_id: nil) do - elsif params[:assignee_id] == "0"
Any Unassigned
= link_to page_filter_path(assignee_id: 0) do - else
Unassigned Any
- @assignees.sort_by(&:name).each do |user| %b.caret
%li %ul.dropdown-menu
= link_to page_filter_path(assignee_id: user.id) do %li
= image_tag avatar_icon(user.email), class: "avatar s16", alt: '' = link_to page_filter_path(assignee_id: nil) do
= user.name Any
= link_to page_filter_path(assignee_id: 0) do
.dropdown.inline.prepend-left-10.author-filter Unassigned
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - @assignees.sort_by(&:name).each do |user|
%i.fa.fa-user %li
%span.light author: = link_to page_filter_path(assignee_id: user.id) do
- if @author.present? = image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
%strong= @author.name = user.name
- elsif params[:author_id] == "0"
Unassigned
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to page_filter_path(author_id: nil) do
Any
= link_to page_filter_path(author_id: 0) do
Unassigned
- @authors.sort_by(&:name).each do |user|
%li
= link_to page_filter_path(author_id: user.id) do
= image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
= user.name
.dropdown.inline.prepend-left-10.milestone-filter
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-clock-o
%span.light milestone:
- if @milestone.present?
%strong= @milestone.title
- elsif params[:milestone_id] == "0"
None (backlog)
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to page_filter_path(milestone_id: nil) do
Any
= link_to page_filter_path(milestone_id: 0) do
None (backlog)
- @milestones.each do |milestone|
%li
= link_to page_filter_path(milestone_id: milestone.id) do
%strong= milestone.title
%small.light= milestone.expires_at
- if @project .dropdown.inline.prepend-left-10.author-filter
.dropdown.inline.prepend-left-10.labels-filter %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %i.fa.fa-user
%i.fa.fa-tags %span.light author:
%span.light label: - if @author.present?
- if params[:label_name].present? %strong= @author.name
%strong= params[:label_name] - elsif params[:author_id] == "0"
- else Unassigned
Any - else
%b.caret
%ul.dropdown-menu
%li
= link_to page_filter_path(label_name: nil) do
Any Any
- if @project.labels.any? %b.caret
- @project.labels.each do |label| %ul.dropdown-menu
%li
= link_to page_filter_path(author_id: nil) do
Any
= link_to page_filter_path(author_id: 0) do
Unassigned
- @authors.sort_by(&:name).each do |user|
%li %li
= link_to page_filter_path(label_name: label.name) do = link_to page_filter_path(author_id: user.id) do
= render_colored_label(label) = image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
- else = user.name
.dropdown.inline.prepend-left-10.milestone-filter
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-clock-o
%span.light milestone:
- if @milestone.present?
%strong= @milestone.title
- elsif params[:milestone_id] == "0"
None (backlog)
- else
Any
%b.caret
%ul.dropdown-menu
%li %li
= link_to generate_namespace_project_labels_path(@project.namespace, @project, redirect: request.original_url), method: :post do = link_to page_filter_path(milestone_id: nil) do
%i.fa.fa-plus-circle Any
Create default labels = link_to page_filter_path(milestone_id: 0) do
None (backlog)
- @milestones.each do |milestone|
%li
= link_to page_filter_path(milestone_id: milestone.id) do
%strong= milestone.title
%small.light= milestone.expires_at
- if @project
.dropdown.inline.prepend-left-10.labels-filter
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-tags
%span.light label:
- if params[:label_name].present?
%strong= params[:label_name]
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to page_filter_path(label_name: nil) do
Any
- if @project.labels.any?
- @project.labels.each do |label|
%li
= link_to page_filter_path(label_name: label.name) do
= render_colored_label(label)
- else
%li
= link_to generate_namespace_project_labels_path(@project.namespace, @project, redirect: request.original_url), method: :post do
%i.fa.fa-plus-circle
Create default labels
.pull-right .pull-right
= render 'shared/sort_dropdown' = render 'shared/sort_dropdown'
.milestones-filters.append-bottom-10 .milestones-filters.append-bottom-10
%ul.nav.nav-pills.nav-compact %ul.nav.nav-tabs
%li{class: ("active" if params[:state].blank? || params[:state] == 'opened')} %li{class: ("active" if params[:state].blank? || params[:state] == 'opened')}
= link_to milestones_filter_path(state: 'opened') do = link_to milestones_filter_path(state: 'opened') do
%i.fa.fa-exclamation-circle %i.fa.fa-exclamation-circle
......
.panel.panel-default - if @contributed_projects.present?
.panel-heading Personal projects .panel.panel-default
%ul.well-list .panel-heading Projects contributed to
- projects.each do |project| %ul.well-list
%li - @contributed_projects.sort_by(&:star_count).reverse.each do |project|
= link_to_project project %li
= link_to_project project
%span.pull-right.light
%i.fa.fa-star
= project.star_count
- if @projects.present?
.panel.panel-default
.panel-heading Personal projects
%ul.well-list
- @projects.sort_by(&:star_count).reverse.each do |project|
%li
= link_to_project project
%span.pull-right.light
%i.fa.fa-star
= project.star_count
%h4 Calendar %h4 Commits calendar
#cal-heatmap.calendar #cal-heatmap.calendar
:javascript :javascript
new calendar( new calendar(
......
...@@ -35,9 +35,7 @@ ...@@ -35,9 +35,7 @@
= render @events = render @events
.col-md-4 .col-md-4
= render 'profile', user: @user = render 'profile', user: @user
- if @projects.present? = render 'projects'
= render 'projects', projects: @projects
:coffeescript :coffeescript
$ -> $ ->
......
...@@ -112,6 +112,7 @@ end ...@@ -112,6 +112,7 @@ end
Settings.gitlab['time_zone'] ||= nil Settings.gitlab['time_zone'] ||= nil
Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil? Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil?
Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled'].nil? Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled'].nil?
Settings.gitlab['twitter_sharing_enabled'] ||= true if Settings.gitlab['twitter_sharing_enabled'].nil?
Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], []) Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], [])
Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil? Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil?
Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' if Settings.gitlab['issue_closing_pattern'].nil? Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' if Settings.gitlab['issue_closing_pattern'].nil?
......
...@@ -3,6 +3,7 @@ Gitlab::Seeder.quiet do ...@@ -3,6 +3,7 @@ Gitlab::Seeder.quiet do
s.id = 1 s.id = 1
s.name = 'Administrator' s.name = 'Administrator'
s.email = 'admin@example.com' s.email = 'admin@example.com'
s.notification_email = 'admin@example.com'
s.username = 'root' s.username = 'root'
s.password = '5iveL!fe' s.password = '5iveL!fe'
s.admin = true s.admin = true
......
class AddTwitterSharingEnabledToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :twitter_sharing_enabled, :boolean, default: true
end
end
...@@ -10,10 +10,11 @@ ...@@ -10,10 +10,11 @@
- [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects. - [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects.
- [Web hooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project. - [Web hooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project.
- [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN. - [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN.
- [GitLab as OAuth2 authentication service provider](integration/oauth_provider.md). It allows you to login to other applications from GitLab.
## Administrator documentation ## Administrator documentation
- [Install](install/README.md) Requirements, directory structures and manual installation. - [Install](install/README.md) Requirements, directory structures and installation from source.
- [Integration](integration/README.md) How to integrate with systems such as JIRA, Redmine, LDAP and Twitter. - [Integration](integration/README.md) How to integrate with systems such as JIRA, Redmine, LDAP and Twitter.
- [Raketasks](raketasks/README.md) Backups, maintenance, automatic web hook setup and the importing of projects. - [Raketasks](raketasks/README.md) Backups, maintenance, automatic web hook setup and the importing of projects.
- [Custom git hooks](hooks/custom_hooks.md) Custom git hooks (on the filesystem) for when web hooks aren't enough. - [Custom git hooks](hooks/custom_hooks.md) Custom git hooks (on the filesystem) for when web hooks aren't enough.
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
## Clients ## Clients
Find API Clients for GitLab [on our website](https://about.gitlab.com/applications/#api-clients). Find API Clients for GitLab [on our website](https://about.gitlab.com/applications/#api-clients).
You can use [GitLab as an OAuth2 client](oauth2.md) to make API calls.
## Introduction ## Introduction
...@@ -67,7 +68,7 @@ curl https://localhost:3000/api/v3/user?access_token=OAUTH-TOKEN ...@@ -67,7 +68,7 @@ curl https://localhost:3000/api/v3/user?access_token=OAUTH-TOKEN
curl -H "Authorization: Bearer OAUTH-TOKEN" https://localhost:3000/api/v3/user curl -H "Authorization: Bearer OAUTH-TOKEN" https://localhost:3000/api/v3/user
``` ```
Read more about [OAuth2 in GitLab](oauth2.md). Read more about [GitLab as an OAuth2 client](oauth2.md).
## Status codes ## Status codes
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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