Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/issues.js2
-rw-r--r--app/assets/stylesheets/common.scss7
-rw-r--r--app/assets/stylesheets/jquery_ui.scss31
-rw-r--r--app/assets/stylesheets/main.scss6
-rw-r--r--app/controllers/issues_controller.rb15
-rw-r--r--app/controllers/milestones_controller.rb94
-rw-r--r--app/decorators/milestone_decorator.rb4
-rw-r--r--app/models/ability.rb2
-rw-r--r--app/models/issue.rb1
-rw-r--r--app/models/milestone.rb29
-rw-r--r--app/models/project.rb1
-rw-r--r--app/views/issues/_form.html.haml17
-rw-r--r--app/views/issues/_head.html.haml5
-rw-r--r--app/views/issues/_issues.html.haml3
-rw-r--r--app/views/issues/edit.html.haml1
-rw-r--r--app/views/issues/index.html.haml38
-rw-r--r--app/views/issues/new.html.haml1
-rw-r--r--app/views/milestones/_form.html.haml54
-rw-r--r--app/views/milestones/_milestone.html.haml21
-rw-r--r--app/views/milestones/edit.html.haml7
-rw-r--r--app/views/milestones/index.html.haml25
-rw-r--r--app/views/milestones/new.html.haml1
-rw-r--r--app/views/milestones/show.html.haml50
-rw-r--r--config/routes.rb1
-rw-r--r--db/migrate/20120408180246_create_milestones.rb12
-rw-r--r--db/migrate/20120408181910_add_milestone_id_to_issue.rb5
-rw-r--r--db/schema.rb22
-rw-r--r--spec/models/milestone_spec.rb5
28 files changed, 424 insertions, 36 deletions
diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js
index ded66b1c540..19de614fd62 100644
--- a/app/assets/javascripts/issues.js
+++ b/app/assets/javascripts/issues.js
@@ -2,6 +2,7 @@ function switchToNewIssue(form){
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){
$(".issues_content").after(form);
$('select#issue_assignee_id').chosen();
+ $('select#issue_milestone_id').chosen();
$("#new_issue_dialog").show("fade", { direction: "right" }, 150);
$('.top-tabs .add_new').hide();
});
@@ -11,6 +12,7 @@ function switchToEditIssue(form){
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){
$(".issues_content").after(form);
$('select#issue_assignee_id').chosen();
+ $('select#issue_milestone_id').chosen();
$("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
$('.add_new').hide();
});
diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss
index ee466348d7e..89729e5ca8f 100644
--- a/app/assets/stylesheets/common.scss
+++ b/app/assets/stylesheets/common.scss
@@ -45,6 +45,13 @@ a {
&:hover {
}
+
+ &.primary {
+ background:$link_color;
+ &:hover {
+ background:$blue_link;
+ }
+ }
}
a:focus {
diff --git a/app/assets/stylesheets/jquery_ui.scss b/app/assets/stylesheets/jquery_ui.scss
new file mode 100644
index 00000000000..70401539ac1
--- /dev/null
+++ b/app/assets/stylesheets/jquery_ui.scss
@@ -0,0 +1,31 @@
+/**
+ * JQUERY UI datepicker
+ *
+ */
+.ui-datepicker {
+ border-color:#eee;
+ padding:20px;
+
+ .ui-state-default {
+ background:#f1f1f1;
+ padding:5px;
+ }
+ .ui-state-active {
+ background:#fff;
+ }
+}
+
+/**
+ * JQUERY UI progressbar
+ *
+ */
+.ui-progressbar {
+ border:1px solid #ddd;
+ height:6px;
+
+ .ui-progressbar-value {
+ background-color: #62C462;//$blue_link;
+ margin:0;
+ }
+}
+
diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss
index 10388bcf223..4fec0633d86 100644
--- a/app/assets/stylesheets/main.scss
+++ b/app/assets/stylesheets/main.scss
@@ -116,3 +116,9 @@ $hover: #FDF5D9;
*
*/
@import "highlight.black.scss";
+
+/**
+ * JQUERY UI ext
+ *
+ */
+@import "jquery_ui.scss";
diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index 8736427873b..64be20ff503 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -15,7 +15,7 @@ class IssuesController < ApplicationController
before_filter :authorize_write_issue!, :only => [:new, :create]
# Allow modify issue
- before_filter :authorize_modify_issue!, :only => [:close, :edit, :update, :sort]
+ before_filter :authorize_modify_issue!, :only => [:close, :edit, :update]
# Allow destroy issue
before_filter :authorize_admin_issue!, :only => [:destroy]
@@ -28,8 +28,10 @@ class IssuesController < ApplicationController
when 2 then @project.issues.closed
when 3 then @project.issues.opened.assigned(current_user)
else @project.issues.opened
- end.page(params[:page]).per(20)
+ end
+ @issues = @issues.where(:milestone_id => params[:milestone_id]) if params[:milestone_id].present?
+ @issues = @issues.page(params[:page]).per(20)
@issues = @issues.includes(:author, :project).order("critical, updated_at")
respond_to do |format|
@@ -51,13 +53,6 @@ class IssuesController < ApplicationController
def show
@note = @project.notes.new(:noteable => @issue)
- @commits = if @issue.branch_name && @project.repo.heads.map(&:name).include?(@issue.branch_name)
- @project.repo.commits_between("master", @issue.branch_name)
- else
- []
- end
-
-
respond_to do |format|
format.html
format.js
@@ -102,6 +97,8 @@ class IssuesController < ApplicationController
end
def sort
+ return render_404 unless can?(current_user, :admin_issue, @project)
+
@issues = @project.issues.where(:id => params['issue'])
@issues.each do |issue|
issue.position = params['issue'].index(issue.id.to_s) + 1
diff --git a/app/controllers/milestones_controller.rb b/app/controllers/milestones_controller.rb
new file mode 100644
index 00000000000..5e23426f32b
--- /dev/null
+++ b/app/controllers/milestones_controller.rb
@@ -0,0 +1,94 @@
+class MilestonesController < ApplicationController
+ before_filter :authenticate_user!
+ before_filter :project
+ before_filter :module_enabled
+ before_filter :milestone, :only => [:edit, :update, :destroy, :show]
+ layout "project"
+
+ # Authorize
+ before_filter :add_project_abilities
+
+ # Allow read any milestone
+ before_filter :authorize_read_milestone!
+
+ # Allow admin milestone
+ before_filter :authorize_admin_milestone!, :except => [:index, :show]
+
+ respond_to :html
+
+ def index
+ @milestones = case params[:f].to_i
+ when 1; @project.milestones
+ else @project.milestones.active
+ end
+
+ @milestones = @milestones.includes(:project).order("due_date")
+ @milestones = @milestones.page(params[:page]).per(20)
+ end
+
+ def new
+ @milestone = @project.milestones.new
+ respond_with(@milestone)
+ end
+
+ def edit
+ respond_with(@milestone)
+ end
+
+ def show
+ respond_to do |format|
+ format.html
+ format.js
+ end
+ end
+
+ def create
+ @milestone = @project.milestones.new(params[:milestone])
+
+ if @milestone.save
+ redirect_to project_milestone_path(@project, @milestone)
+ else
+ render "new"
+ end
+ end
+
+ def update
+ @milestone.update_attributes(params[:milestone])
+
+ respond_to do |format|
+ format.js
+ format.html do
+ if @milestone.valid?
+ redirect_to [@project, @milestone]
+ else
+ render :edit
+ end
+ end
+ end
+ end
+
+ def destroy
+ return access_denied! unless can?(current_user, :admin_milestone, @milestone)
+
+ @milestone.destroy
+
+ respond_to do |format|
+ format.html { redirect_to project_milestones_path }
+ format.js { render :nothing => true }
+ end
+ end
+
+ protected
+
+ def milestone
+ @milestone ||= @project.milestones.find(params[:id])
+ end
+
+ def authorize_admin_milestone!
+ return render_404 unless can?(current_user, :admin_milestone, @project)
+ end
+
+ def module_enabled
+ return render_404 unless @project.issues_enabled
+ end
+end
diff --git a/app/decorators/milestone_decorator.rb b/app/decorators/milestone_decorator.rb
new file mode 100644
index 00000000000..c881da0e9ad
--- /dev/null
+++ b/app/decorators/milestone_decorator.rb
@@ -0,0 +1,4 @@
+class MilestoneDecorator < ApplicationDecorator
+ decorates :milestone
+
+end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index e97b662b8ce..5792948fa51 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -17,6 +17,7 @@ class Ability
:read_project,
:read_wiki,
:read_issue,
+ :read_milestone,
:read_snippet,
:read_team_member,
:read_merge_request,
@@ -42,6 +43,7 @@ class Ability
:modify_merge_request,
:admin_project,
:admin_issue,
+ :admin_milestone,
:admin_snippet,
:admin_team_member,
:admin_merge_request,
diff --git a/app/models/issue.rb b/app/models/issue.rb
index ce4944a60b7..5ca257960a2 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -1,5 +1,6 @@
class Issue < ActiveRecord::Base
belongs_to :project
+ belongs_to :milestone
belongs_to :author, :class_name => "User"
belongs_to :assignee, :class_name => "User"
has_many :notes, :as => :noteable, :dependent => :destroy
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
new file mode 100644
index 00000000000..20bc2486e2f
--- /dev/null
+++ b/app/models/milestone.rb
@@ -0,0 +1,29 @@
+class Milestone < ActiveRecord::Base
+ belongs_to :project
+ has_many :issues
+
+ validates_presence_of :project_id
+ validates_presence_of :title
+
+ def self.active
+ where("due_date > ? ", Date.today)
+ end
+
+ def percent_complete
+ @percent_complete ||= begin
+ total_i = self.issues.count
+ closed_i = self.issues.closed.count
+ if total_i > 0
+ (closed_i * 100) / total_i
+ else
+ 100
+ end
+ rescue => ex
+ 0
+ end
+ end
+
+ def expires_at
+ "expires at #{due_date.stamp("Aug 21, 2011")}" if due_date
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index e2646ead503..72cc833c253 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -12,6 +12,7 @@ class Project < ActiveRecord::Base
has_many :events, :dependent => :destroy
has_many :merge_requests, :dependent => :destroy
has_many :issues, :dependent => :destroy, :order => "position"
+ has_many :milestones, :dependent => :destroy
has_many :users_projects, :dependent => :destroy
has_many :notes, :dependent => :destroy
has_many :snippets, :dependent => :destroy
diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml
index 543bab1f7c0..4698bed21a5 100644
--- a/app/views/issues/_form.html.haml
+++ b/app/views/issues/_form.html.haml
@@ -9,18 +9,25 @@
%li= msg
.clearfix
- = f.label :title, "Issue Subject"
- .input= f.text_field :title, :maxlength => 255, :class => "xxlarge"
-
+ = f.label :title, "Issue Subject *"
+ .input
+ = f.text_field :title, :maxlength => 255, :class => "xxlarge"
+
+ .clearfix
+ = f.label :assignee_id, "Assign to *"
+ .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Assign to user" })
+
.clearfix
= f.label :description, "Issue Details"
.input
= f.text_area :description, :maxlength => 2000, :class => "xxlarge", :rows => 10
%p.hint Markdown is enabled.
+
.clearfix
- = f.label :assignee_id
- .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Assign to user" })
+ = f.label :milestone_id
+ .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { :include_blank => "Select milestone" })
+
.clearfix
= f.label :critical, "Critical"
diff --git a/app/views/issues/_head.html.haml b/app/views/issues/_head.html.haml
index d539025296a..9fede71d59f 100644
--- a/app/views/issues/_head.html.haml
+++ b/app/views/issues/_head.html.haml
@@ -1,4 +1,7 @@
.tabs
%li{:class => "#{'active' if current_page?(project_issues_path(@project))}"}
= link_to project_issues_path(@project), :class => "tab" do
- Issues
+ Browse Issues
+ %li{:class => "#{'active' if current_page?(project_milestones_path(@project))}"}
+ = link_to project_milestones_path(@project), :class => "tab" do
+ Milestones
diff --git a/app/views/issues/_issues.html.haml b/app/views/issues/_issues.html.haml
index f82aee94a8f..ee5dc79585f 100644
--- a/app/views/issues/_issues.html.haml
+++ b/app/views/issues/_issues.html.haml
@@ -10,3 +10,6 @@
.span10= paginate @issues, :remote => true, :theme => "gitlab"
.span4.right
%span.cgray.right #{@issues.total_count} issues for this filter
+- else
+ %li
+ %p.padded Nothing to show here
diff --git a/app/views/issues/edit.html.haml b/app/views/issues/edit.html.haml
index bada72459c9..aa0c931b34d 100644
--- a/app/views/issues/edit.html.haml
+++ b/app/views/issues/edit.html.haml
@@ -3,5 +3,6 @@
:javascript
$(function(){
$('select#issue_assignee_id').chosen();
+ $('select#issue_milestone_id').chosen();
});
diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml
index 7146027b1d5..e0afa71f4cd 100644
--- a/app/views/issues/index.html.haml
+++ b/app/views/issues/index.html.haml
@@ -1,3 +1,4 @@
+= render "issues/head"
.issues_content
%h3
Issues
@@ -5,14 +6,22 @@
= link_to project_issues_path(@project, :atom, { :private_token => current_user.private_token }) do
= image_tag "Rss-UI.PNG", :width => 16, :title => "feed"
- - if can? current_user, :write_issue, @project
- = link_to new_project_issue_path(@project), :class => "right btn small", :title => "New Issue", :remote => true do
- New Issue
+ .right
+ .span4.left
+ = form_tag search_project_issues_path(@project), :method => :get, :remote => true, :id => "issue_search_form", :class => :left do
+ = hidden_field_tag :project_id, @project.id, { :id => 'project_id' }
+ = hidden_field_tag :status, params[:f]
+ = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search' }
+
+ - if can? current_user, :write_issue, @project
+ .span2.left
+ = link_to new_project_issue_path(@project), :class => "right btn small", :title => "New Issue", :remote => true do
+ New Issue
%br
%div#issues-table-holder.ui-box
.title
.row
- .span8
+ .span6
%ul.pills.left
%li{:class => ("active" if (params[:f] == "0" || !params[:f]))}
= link_to project_issues_path(@project, :f => 0) do
@@ -27,17 +36,13 @@
= link_to project_issues_path(@project, :f => 1) do
All
- .span3.right
- = form_tag search_project_issues_path(@project), :method => :get, :remote => true, :id => "issue_search_form", :class => :right do
- = hidden_field_tag :project_id, @project.id, { :id => 'project_id' }
- = hidden_field_tag :status, params[:f]
- = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search' }
+ .span6.right
+ = form_tag project_issues_path(@project), :method => :get, :class => :right do
+ = select_tag(:milestone_id, options_from_collection_for_select(@project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), :prompt => "Select milestone")
%ul#issues-table.unstyled
= render "issues"
- - if @issues.blank?
- %li
- %p.padded Nothing to show here
+
:javascript
var href = $('.issue_search').parent().attr('action');
var last_terms = '';
@@ -65,9 +70,8 @@
$('#issues-table').sortable({
axis: 'y',
dropOnEmpty: false,
- handle: '.handle',
- cursor: 'crosshair',
- items: 'tr',
+ handle: '.avatar',
+ items: 'li',
opacity: 0.4,
scroll: true,
update: function(){
@@ -85,4 +89,8 @@
$(function(){
setSortable();
+ $("#milestone_id").chosen();
+ $("#milestone_id").live("change", function(){
+ $(this).closest("form").submit();
+ });
});
diff --git a/app/views/issues/new.html.haml b/app/views/issues/new.html.haml
index bada72459c9..aa0c931b34d 100644
--- a/app/views/issues/new.html.haml
+++ b/app/views/issues/new.html.haml
@@ -3,5 +3,6 @@
:javascript
$(function(){
$('select#issue_assignee_id').chosen();
+ $('select#issue_milestone_id').chosen();
});
diff --git a/app/views/milestones/_form.html.haml b/app/views/milestones/_form.html.haml
new file mode 100644
index 00000000000..6c3e37a79ff
--- /dev/null
+++ b/app/views/milestones/_form.html.haml
@@ -0,0 +1,54 @@
+%h3= @milestone.new_record? ? "New Milestone" : "Edit Milestone ##{@milestone.id}"
+.back_link
+ = link_to project_milestones_path(@project) do
+ &larr; To milestones
+
+%hr
+
+= form_for [@project, @milestone] do |f|
+ -if @milestone.errors.any?
+ .alert-message.block-message.error
+ %ul
+ - @milestone.errors.full_messages.each do |msg|
+ %li= msg
+ .row
+ .span7
+ .clearfix
+ = f.label :title, "Title"
+ .input
+ = f.text_field :title, :maxlength => 255, :class => "xlarge"
+ %p.hint Required
+ .clearfix
+ = f.label :description, "Description"
+ .input
+ = f.text_area :description, :maxlength => 2000, :class => "xlarge", :rows => 10
+ %p.hint Markdown is enabled.
+ .span8
+ .clearfix
+ = f.label :due_date, "Due Date"
+ .input= f.hidden_field :due_date
+ .input
+ .datepicker
+
+
+ .actions
+ - if @milestone.new_record?
+ = f.submit 'Create milestone', :class => "primary btn"
+ -else
+ = f.submit 'Save changes', :class => "primary btn"
+
+ - if request.xhr?
+ = link_to "Cancel", "#back", :onclick => "backToIssues();", :class => "btn"
+ - else
+ - if @milestone.new_record?
+ = link_to "Cancel", project_milestones_path(@project), :class => "btn"
+ - else
+ = link_to "Cancel", project_milestone_path(@project, @milestone), :class => "btn"
+
+:javascript
+ $(function() {
+ $( ".datepicker" ).datepicker({
+ dateFormat: "yy-mm-dd",
+ onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) }
+ });
+ });
diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml
new file mode 100644
index 00000000000..a21df7e2d51
--- /dev/null
+++ b/app/views/milestones/_milestone.html.haml
@@ -0,0 +1,21 @@
+%li{:class => "wll", :id => dom_id(milestone) }
+ .right
+ - if milestone.issues.count > 0
+ = link_to 'Browse Issues', project_issues_path(milestone.project, :milestone_id => milestone.id), :class => "btn small"
+ - if milestone.issues.any?
+ %span.btn.small.disabled.padded= pluralize milestone.issues.count, 'issues'
+ - if can? current_user, :admin_milestone, milestone.project
+ = link_to 'Edit', edit_project_milestone_path(milestone.project, milestone), :class => "btn small edit-milestone-link"
+ = link_to project_milestone_path(milestone.project, milestone) do
+ %h4.row_title
+ = truncate(milestone.title, :length => 100)
+ %small= milestone.expires_at
+
+ .progress.span4
+
+ :javascript
+ $(function() {
+ $( "##{dom_id(milestone)} .progress" ).progressbar({
+ value: #{milestone.percent_complete}
+ });
+ });
diff --git a/app/views/milestones/edit.html.haml b/app/views/milestones/edit.html.haml
new file mode 100644
index 00000000000..bada72459c9
--- /dev/null
+++ b/app/views/milestones/edit.html.haml
@@ -0,0 +1,7 @@
+= render "form"
+
+:javascript
+ $(function(){
+ $('select#issue_assignee_id').chosen();
+ });
+
diff --git a/app/views/milestones/index.html.haml b/app/views/milestones/index.html.haml
new file mode 100644
index 00000000000..e55e58b2f23
--- /dev/null
+++ b/app/views/milestones/index.html.haml
@@ -0,0 +1,25 @@
+= render "issues/head"
+.milestones_content
+ %h3
+ Milestones
+ - if can? current_user, :admin_milestone, @project
+ = link_to "New Milestone", new_project_milestone_path(@project), :class => "right btn small", :title => "New Milestone"
+ %br
+ %div.ui-box
+ .title
+ %ul.pills
+ %li{:class => ("active" if (params[:f] == "0" || !params[:f]))}
+ = link_to project_milestones_path(@project, :f => 0) do
+ Active
+ %li{:class => ("active" if params[:f] == "1")}
+ = link_to project_milestones_path(@project, :f => 1) do
+ All
+
+ %ul.unstyled
+ = render @milestones
+
+ - if @milestones.present?
+ %li.bottom= paginate @milestones, :remote => true, :theme => "gitlab"
+ - else
+ %li
+ %p.padded Nothing to show here
diff --git a/app/views/milestones/new.html.haml b/app/views/milestones/new.html.haml
new file mode 100644
index 00000000000..b1bc3ba0eba
--- /dev/null
+++ b/app/views/milestones/new.html.haml
@@ -0,0 +1 @@
+= render "form"
diff --git a/app/views/milestones/show.html.haml b/app/views/milestones/show.html.haml
new file mode 100644
index 00000000000..bac48aa54af
--- /dev/null
+++ b/app/views/milestones/show.html.haml
@@ -0,0 +1,50 @@
+%h3
+ Milestone ##{@milestone.id}
+ %small
+ = @milestone.expires_at
+
+ %span.right
+ - if can?(current_user, :admin_milestone, @project)
+ = link_to edit_project_milestone_path(@project, @milestone), :class => "btn" do
+ Edit
+
+.back_link
+ = link_to project_milestones_path(@project) do
+ &larr; To milestones list
+
+.main_box
+ .top_box_content
+ %h5
+ - if @milestone.closed
+ .alert-message.error.status_info Closed
+ - else
+ .alert-message.success.status_info Open
+ = @milestone.title
+
+ .middle_box_content
+ .row
+ .span2
+ = link_to 'Browse Issues', project_issues_path(@milestone.project, :milestone_id => @milestone.id), :class => "btn small edit-milestone-link"
+ .span4
+ %span
+ = @milestone.expires_at
+
+ .span4.right
+ .progress
+ %br
+ %span
+ #{@milestone.issues.opened.count} open
+ &ndash;
+ #{@milestone.issues.closed.count} closed
+
+ - if @milestone.description.present?
+ .bottom_box_content
+ = markdown @milestone.description
+
+
+:javascript
+ $(function() {
+ $( ".progress" ).progressbar({
+ value: #{@milestone.percent_complete}
+ });
+ });
diff --git a/config/routes.rb b/config/routes.rb
index eb999f26ba2..be146f170a7 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -122,6 +122,7 @@ Gitlab::Application.routes.draw do
end
end
resources :team_members
+ resources :milestones
resources :issues do
collection do
post :sort
diff --git a/db/migrate/20120408180246_create_milestones.rb b/db/migrate/20120408180246_create_milestones.rb
new file mode 100644
index 00000000000..ed3a510d660
--- /dev/null
+++ b/db/migrate/20120408180246_create_milestones.rb
@@ -0,0 +1,12 @@
+class CreateMilestones < ActiveRecord::Migration
+ def change
+ create_table :milestones do |t|
+ t.string :title, :null => false
+ t.integer :project_id, :null => false
+ t.text :description
+ t.date :due_date
+ t.boolean :closed, :default => false, :null => false
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20120408181910_add_milestone_id_to_issue.rb b/db/migrate/20120408181910_add_milestone_id_to_issue.rb
new file mode 100644
index 00000000000..a6b44090c1c
--- /dev/null
+++ b/db/migrate/20120408181910_add_milestone_id_to_issue.rb
@@ -0,0 +1,5 @@
+class AddMilestoneIdToIssue < ActiveRecord::Migration
+ def change
+ add_column :issues, :milestone_id, :integer, :null => true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4048227590d..51e78b76847 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120405211750) do
+ActiveRecord::Schema.define(:version => 20120408181910) do
create_table "events", :force => true do |t|
t.string "target_type"
@@ -30,13 +30,14 @@ ActiveRecord::Schema.define(:version => 20120405211750) do
t.integer "assignee_id"
t.integer "author_id"
t.integer "project_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.boolean "closed", :default => false, :null => false
- t.integer "position", :default => 0
- t.boolean "critical", :default => false, :null => false
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.boolean "closed", :default => false, :null => false
+ t.integer "position", :default => 0
+ t.boolean "critical", :default => false, :null => false
t.string "branch_name"
t.text "description"
+ t.integer "milestone_id"
end
add_index "issues", ["project_id"], :name => "index_issues_on_project_id"
@@ -69,6 +70,15 @@ ActiveRecord::Schema.define(:version => 20120405211750) do
add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id"
+ create_table "milestones", :force => true do |t|
+ t.string "title", :null => false
+ t.text "description"
+ t.date "due_date", :null => false
+ t.integer "project_id", :null => false
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
create_table "notes", :force => true do |t|
t.text "note"
t.string "noteable_id"
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
new file mode 100644
index 00000000000..326d908758b
--- /dev/null
+++ b/spec/models/milestone_spec.rb
@@ -0,0 +1,5 @@
+require 'spec_helper'
+
+describe Milestone do
+ pending "add some examples to (or delete) #{__FILE__}"
+end