Read about our upcoming Code of Conduct on this issue

This instance was upgraded to Heptapod 0.28.1 today

Commit 6d460aa2 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

merge request entity

parent 1439a8c75c25
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
......@@ -58,6 +58,8 @@
padding: 0;
}
body.project-page .merge-request-form-holder table.no-borders tr,
body.project-page .merge-request-form-holder table.no-borders td,
body.project-page .issue-form-holder table.no-borders tr,
body.project-page .issue-form-holder table.no-borders td,
body.project-page .new_snippet table tr,
......
// Place all the styles related to the MergeRequests controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.merge-request-form-holder {
select {
width:300px;
}
}
......@@ -155,6 +155,8 @@ input.ssh_project_url {
}
/** FORM INPUTS **/
.new_merge_request,
.edit_merge_request,
.user_new,
.new_key,
.new_issue,
......@@ -384,6 +386,19 @@ body.dashboard.project-page .news-feed .project-updates a.project-update span.up
body.dashboard.project-page .news-feed .project-updates a.project-update span.update-author strong{font-weight: bold; font-style: normal;}
/* eo Dashboard Page */
/** Merge requests */
body.project-page .merge-request-commits {margin-bottom: 20px; display: block; width: 100%;}
body.project-page .merge-request-commits .data{ padding: 0}
body.project-page .merge-request-commits a.commit {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
body.project-page .merge-request-commits a.commit:last-child{border-bottom: 0}
body.project-page .merge-request-commits a.commit img{float: left; margin-right: 10px;}
body.project-page .merge-request-commits a.commit span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
body.project-page .merge-request-commits a.commit span.update-title{margin-bottom: 10px}
body.project-page .merge-request-commits a.commit span.update-author{color: #999; font-weight: normal; font-style: italic;}
body.project-page .merge-request-commits a.commit span.update-author strong{font-weight: bold; font-style: normal;}
body.project-page .team_member_new .span-6, .team_member_edit .span-6{ padding:10px 0; }
body.projects-page input.text.git-url.project_list_url { width:165px; }
......
class MergeRequestsController < ApplicationController
before_filter :authenticate_user!
before_filter :project
before_filter :merge_request, :only => [:edit, :update, :destroy, :show]
layout "project"
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_project!
before_filter :authorize_write_project!, :only => [:new, :create, :edit, :update]
def index
@merge_requests = @project.merge_requests.all
end
def show
unless @project.repo.heads.map(&:name).include?(@merge_request.target_branch) &&
@project.repo.heads.map(&:name).include?(@merge_request.source_branch)
head(404)and return
end
@commits = @project.repo.commits_between(@merge_request.target_branch, @merge_request.source_branch).map {|c| Commit.new(c)}
end
def new
@merge_request = @project.merge_requests.new
end
def edit
end
def create
@merge_request = @project.merge_requests.new(params[:merge_request])
@merge_request.author = current_user
respond_to do |format|
if @merge_request.save
format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.' }
format.json { render json: @merge_request, status: :created, location: @merge_request }
else
format.html { render action: "new" }
format.json { render json: @merge_request.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @merge_request.update_attributes(params[:merge_request])
format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: @merge_request.errors, status: :unprocessable_entity }
end
end
end
def destroy
@merge_request.destroy
respond_to do |format|
format.html { redirect_to project_merge_requests_url(@project) }
format.json { head :ok }
end
end
protected
def merge_request
@merge_request ||= @project.merge_requests.find(params[:id])
end
end
module MergeRequestsHelper
end
......@@ -17,6 +17,7 @@ def self.project_abilities(user, project)
:read_issue,
:read_snippet,
:read_team_member,
:read_merge_request,
:read_note
] if project.readers.include?(user)
......@@ -24,6 +25,7 @@ def self.project_abilities(user, project)
:write_project,
:write_issue,
:write_snippet,
:write_merge_request,
:write_note
] if project.writers.include?(user)
......@@ -32,6 +34,7 @@ def self.project_abilities(user, project)
:admin_issue,
:admin_snippet,
:admin_team_member,
:admin_merge_request,
:admin_note
] if project.admins.include?(user)
......@@ -39,7 +42,7 @@ def self.project_abilities(user, project)
end
class << self
[:issue, :note, :snippet].each do |name|
[:issue, :note, :snippet, :merge_request].each do |name|
define_method "#{name}_abilities" do |user, subject|
if subject.author == user
[
......
class MergeRequest < ActiveRecord::Base
belongs_to :project
belongs_to :author, :class_name => "User"
belongs_to :assignee, :class_name => "User"
has_many :notes, :as => :noteable
attr_protected :author, :author_id, :project, :project_id
validates_presence_of :project_id
validates_presence_of :assignee_id
validates_presence_of :author_id
validates_presence_of :source_branch
validates_presence_of :target_branch
delegate :name,
:email,
:to => :author,
:prefix => true
delegate :name,
:email,
:to => :assignee,
:prefix => true
validates :title,
:presence => true,
:length => { :within => 0..255 }
scope :opened, where(:closed => false)
scope :closed, where(:closed => true)
scope :assigned, lambda { |u| where(:assignee_id => u.id)}
def new?
today? && created_at == updated_at
end
end
......@@ -3,6 +3,7 @@
class Project < ActiveRecord::Base
belongs_to :owner, :class_name => "User"
has_many :merge_requests, :dependent => :destroy
has_many :issues, :dependent => :destroy, :order => "position"
has_many :users_projects, :dependent => :destroy
has_many :users, :through => :users_projects
......
......@@ -39,6 +39,10 @@
Wall
- if @project.common_notes.today.count > 0
%span{ :class => "number" }= @project.common_notes.today.count
= link_to project_merge_requests_path(@project), :class => (controller.controller_name == "merge_requests") ? "current" : nil do
Merge Requests
- if @project.merge_requests.opened.count > 0
%span{ :class => "number" }= @project.merge_requests.opened.count
= link_to project_snippets_path(@project), :class => (controller.controller_name == "snippets") ? "current" : nil do
Snippets
- if @project.snippets.non_expired.count > 0
......
%div.merge-request-form-holder
.ui-box.width-100p
%h3
= @merge_request.new_record? ? "New Merge Request" : "Edit Merge Request ##{@merge_request.id}"
= form_for [@project, @merge_request] do |f|
.data
%table.no-borders
-if @merge_request.errors.any?
%tr
%td Errors
%td
#error_explanation
- @merge_request.errors.full_messages.each do |msg|
%span= msg
%br
%tr
%td= f.label :title
%td= f.text_field :title
%tr
%td= f.label :target_branch, "From"
%td= f.select(:target_branch, @project.heads.map(&:name), { :include_blank => "Select branch" })
%tr
%td= f.label :source_branch, "To"
%td= f.select(:source_branch, @project.heads.map(&:name), { :include_blank => "Select branch" })
%tr
%td= f.label :assignee_id, "Assign to"
%td= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" })
.buttons
= f.submit 'Save', :class => "grey-button"
.right= link_to 'Back', project_merge_requests_path(@project), :class => "grey-button"
:javascript
$(function(){
$('select#merge_request_assignee_id').chosen();
$('select#merge_request_source_branch').chosen();
$('select#merge_request_target_branch').chosen();
});
%table
%thead
%th Target branch
%th Source branch
%th Author
%th Assignee
%th Title
%th
%th
%th
- @merge_requests.each do |merge_request|
%tr
%td= merge_request.target_branch
%td= merge_request.source_branch
%td= merge_request.author_id
%td= merge_request.assignee_id
%td= merge_request.title
%td= link_to 'Show', [@project, merge_request]
%td= link_to 'Edit', edit_project_merge_request_path(@project, merge_request)
%td= link_to 'Destroy', [@project, merge_request], :confirm => 'Are you sure?', :method => :delete
%br
= link_to 'New Merge request', new_project_merge_request_path(@project)
.merge-request-show-holder.ui-box.width-100p
%h3
= "Merge Request ##{@merge_request.id}:"
&nbsp;
= "'#{@merge_request.source_branch}'"
&rarr;
= "'#{@merge_request.target_branch}'"
.right
- if @merge_request.closed
%span.tag.high Resolved
- else
%span.tag.today Open
.data
%p= @merge_request.title
- if @merge_request.author == @merge_request.assignee
= image_tag gravatar_icon(@merge_request.assignee_email), :width => 20, :style => "padding:0 5px;"
= @merge_request.assignee_name
- else
= image_tag gravatar_icon(@merge_request.author_email), :width => 20, :style => "padding:0 5px;"
= @merge_request.author_name
&rarr;
= image_tag gravatar_icon(@merge_request.assignee_email), :width => 20, :style => "padding:0 5px;"
= @merge_request.assignee_name
.right
%cite.cgray= @merge_request.created_at.stamp("21 Aug 2011, 11:15pm")
.clear
.buttons
- if can? current_user, :write_project, @project
- if @merge_request.closed
= link_to 'Reopen', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => false }, :status_only => true), :method => :put, :class => "grey-button"
- else
= link_to 'Resolve', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "grey-button"
.right
= link_to 'Edit', edit_project_merge_request_path(@project, @merge_request), :class => "grey-button positive"
.clear
%br
%br
- if @commits.size > 0
.merge-request-commits.ui-box.width-100p
- @commits.each do |commit|
%a{ :class => "commit", :href => project_commit_path(@project, :id => commit.id) }
- if commit.author_email
= image_tag gravatar_icon(commit.author_email), :class => "left", :width => 40, :style => "padding-right:5px;"
- else
= image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;"
%span.update-title
= commit.id.to_s
%span.update-author
%strong= commit.author_name
authored
= time_ago_in_words(commit.created_at)
ago
.clear
......@@ -59,6 +59,7 @@
end
end
resources :merge_requests
resources :snippets
resources :commits
resources :team_members
......
class CreateMergeRequests < ActiveRecord::Migration
def change
create_table :merge_requests do |t|
t.string :target_branch, :null => false
t.string :source_branch, :null => false
t.integer :project_id, :null => false
t.integer :author_id
t.integer :assignee_id
t.string :title
t.boolean :closed, :default => false, :null => false
t.timestamps
end
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20111124115339) do
ActiveRecord::Schema.define(:version => 20111127155345) do
create_table "features", :force => true do |t|
t.string "name"
......@@ -21,6 +21,8 @@
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "version"
t.integer "status", :default => 0, :null => false
end
create_table "issues", :force => true do |t|
......@@ -45,6 +47,18 @@
t.string "identifier"
end
create_table "merge_requests", :force => true do |t|
t.string "target_branch", :null => false
t.string "source_branch", :null => false
t.integer "project_id", :null => false
t.integer "author_id"
t.integer "assignee_id"
t.string "title"
t.boolean "closed", :default => false, :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "notes", :force => true do |t|
t.text "note"
t.string "noteable_id"
......
require 'spec_helper'
describe ApplicationHelper do
context ".gravatar_icon" do
context "over http" do
it "returns the correct URL to www.gravatar.com" do
expected = "http://www.gravatar.com/avatar/f7daa65b2aa96290bb47c4d68d11fe6a?s=40&d=identicon"
# Pretend we're running over HTTP
helper.stub(:request) do
request = double('request')
request.stub(:ssl?) { false }
request
end
helper.gravatar_icon("admin@local.host").should == expected
end
end
context "over https" do
it "returns the correct URL to secure.gravatar.com" do
expected = "https://secure.gravatar.com/avatar/f7daa65b2aa96290bb47c4d68d11fe6a?s=40&d=identicon"
# Pretend we're running over HTTPS
helper.stub(:request) do
request = double('request')
request.stub(:ssl?) { true }
request
end
helper.gravatar_icon("admin@local.host").should == expected
end
end
end
end
require 'spec_helper'
describe MergeRequest do
pending "add some examples to (or delete) #{__FILE__}"
end
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